disdrodb 0.2.1__py3-none-any.whl → 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- disdrodb/__init__.py +3 -1
- disdrodb/_config.py +2 -3
- disdrodb/_version.py +2 -2
- disdrodb/accessor/__init__.py +2 -1
- disdrodb/accessor/methods.py +10 -9
- disdrodb/api/checks.py +3 -7
- disdrodb/api/configs.py +1 -3
- disdrodb/api/create_directories.py +4 -6
- disdrodb/api/info.py +1 -3
- disdrodb/api/io.py +233 -32
- disdrodb/api/path.py +3 -7
- disdrodb/cli/disdrodb_check_metadata_archive.py +3 -2
- disdrodb/cli/disdrodb_check_products_options.py +45 -0
- disdrodb/cli/disdrodb_create_summary.py +54 -28
- disdrodb/cli/disdrodb_create_summary_station.py +41 -20
- disdrodb/cli/disdrodb_data_archive_directory.py +2 -3
- disdrodb/cli/disdrodb_download_archive.py +50 -30
- disdrodb/cli/disdrodb_download_metadata_archive.py +28 -16
- disdrodb/cli/disdrodb_download_station.py +58 -29
- disdrodb/cli/disdrodb_initialize_station.py +43 -23
- disdrodb/cli/disdrodb_metadata_archive_directory.py +2 -3
- disdrodb/cli/disdrodb_open_data_archive.py +17 -13
- disdrodb/cli/disdrodb_open_logs_directory.py +31 -21
- disdrodb/cli/disdrodb_open_metadata_archive.py +26 -13
- disdrodb/cli/disdrodb_open_metadata_directory.py +34 -23
- disdrodb/cli/disdrodb_open_product_directory.py +39 -23
- disdrodb/cli/disdrodb_open_readers_directory.py +2 -3
- disdrodb/cli/disdrodb_run.py +189 -0
- disdrodb/cli/disdrodb_run_l0.py +61 -70
- disdrodb/cli/disdrodb_run_l0_station.py +50 -55
- disdrodb/cli/disdrodb_run_l0a.py +53 -51
- disdrodb/cli/disdrodb_run_l0a_station.py +41 -40
- disdrodb/cli/disdrodb_run_l0b.py +51 -51
- disdrodb/cli/disdrodb_run_l0b_station.py +40 -39
- disdrodb/cli/disdrodb_run_l0c.py +56 -53
- disdrodb/cli/disdrodb_run_l0c_station.py +44 -41
- disdrodb/cli/disdrodb_run_l1.py +55 -51
- disdrodb/cli/disdrodb_run_l1_station.py +43 -40
- disdrodb/cli/disdrodb_run_l2e.py +56 -51
- disdrodb/cli/disdrodb_run_l2e_station.py +44 -40
- disdrodb/cli/disdrodb_run_l2m.py +55 -51
- disdrodb/cli/disdrodb_run_l2m_station.py +43 -40
- disdrodb/cli/disdrodb_run_station.py +184 -0
- disdrodb/cli/disdrodb_upload_archive.py +51 -42
- disdrodb/cli/disdrodb_upload_station.py +42 -36
- disdrodb/configs.py +20 -16
- disdrodb/constants.py +5 -2
- disdrodb/data_transfer/__init__.py +1 -3
- disdrodb/data_transfer/download_data.py +45 -61
- disdrodb/data_transfer/upload_data.py +7 -11
- disdrodb/data_transfer/zenodo.py +2 -4
- disdrodb/docs.py +1 -3
- disdrodb/etc/configs/attributes.yaml +52 -2
- disdrodb/etc/configs/encodings.yaml +45 -1
- disdrodb/etc/products/L0C/ODM470/global.yaml +5 -0
- disdrodb/etc/products/L0C/global.yaml +5 -0
- disdrodb/etc/products/L1/ODM470/global.yaml +6 -0
- disdrodb/etc/products/L1/global.yaml +0 -13
- disdrodb/etc/products/L2E/LPM/1MIN.yaml +1 -0
- disdrodb/etc/products/L2E/LPM/global.yaml +36 -0
- disdrodb/etc/products/L2E/LPM_V0/1MIN.yaml +1 -0
- disdrodb/etc/products/L2E/LPM_V0/global.yaml +36 -0
- disdrodb/etc/products/L2E/ODM470/1MIN.yaml +1 -0
- disdrodb/etc/products/L2E/ODM470/global.yaml +36 -0
- disdrodb/etc/products/L2E/PARSIVEL/1MIN.yaml +1 -0
- disdrodb/etc/products/L2E/PARSIVEL/global.yaml +36 -0
- disdrodb/etc/products/L2E/PARSIVEL2/1MIN.yaml +1 -0
- disdrodb/etc/products/L2E/PARSIVEL2/global.yaml +36 -0
- disdrodb/etc/products/L2E/PWS100/1MIN.yaml +1 -0
- disdrodb/etc/products/L2E/PWS100/global.yaml +36 -0
- disdrodb/etc/products/L2E/RD80/1MIN.yaml +19 -0
- disdrodb/etc/products/L2E/SWS250/1MIN.yaml +19 -0
- disdrodb/etc/products/L2E/global.yaml +16 -2
- disdrodb/fall_velocity/__init__.py +47 -0
- disdrodb/fall_velocity/graupel.py +484 -0
- disdrodb/fall_velocity/hail.py +288 -0
- disdrodb/{l1/fall_velocity.py → fall_velocity/rain.py} +265 -44
- disdrodb/issue/__init__.py +1 -3
- disdrodb/issue/checks.py +2 -3
- disdrodb/issue/reader.py +2 -3
- disdrodb/issue/writer.py +2 -5
- disdrodb/l0/__init__.py +2 -1
- disdrodb/l0/check_configs.py +36 -29
- disdrodb/l0/check_standards.py +1 -4
- disdrodb/l0/configs/LPM/l0a_encodings.yml +17 -17
- disdrodb/l0/configs/LPM/l0b_cf_attrs.yml +55 -55
- disdrodb/l0/configs/LPM/l0b_encodings.yml +17 -17
- disdrodb/l0/configs/LPM/raw_data_format.yml +17 -17
- disdrodb/l0/configs/LPM_V0/l0a_encodings.yml +2 -2
- disdrodb/l0/configs/LPM_V0/l0b_cf_attrs.yml +2 -2
- disdrodb/l0/configs/LPM_V0/l0b_encodings.yml +2 -2
- disdrodb/l0/configs/LPM_V0/raw_data_format.yml +2 -2
- disdrodb/l0/configs/ODM470/bins_diameter.yml +643 -0
- disdrodb/l0/configs/ODM470/bins_velocity.yml +0 -0
- disdrodb/l0/configs/ODM470/l0a_encodings.yml +11 -0
- disdrodb/l0/configs/ODM470/l0b_cf_attrs.yml +46 -0
- disdrodb/l0/configs/ODM470/l0b_encodings.yml +106 -0
- disdrodb/l0/configs/ODM470/raw_data_format.yml +111 -0
- disdrodb/l0/configs/PARSIVEL/l0b_cf_attrs.yml +1 -1
- disdrodb/l0/l0_reader.py +2 -3
- disdrodb/l0/l0a_processing.py +6 -8
- disdrodb/l0/l0b_nc_processing.py +3 -6
- disdrodb/l0/l0b_processing.py +2 -16
- disdrodb/l0/l0c_processing.py +29 -12
- disdrodb/l0/readers/LPM/ARM/ARM_LPM.py +2 -1
- disdrodb/l0/readers/LPM/AUSTRALIA/MELBOURNE_2007_LPM.py +18 -18
- disdrodb/l0/readers/LPM/BRAZIL/CHUVA_LPM.py +18 -18
- disdrodb/l0/readers/LPM/BRAZIL/GOAMAZON_LPM.py +18 -18
- disdrodb/l0/readers/LPM/GERMANY/DWD.py +244 -63
- disdrodb/l0/readers/LPM/ITALY/GID_LPM.py +65 -23
- disdrodb/l0/readers/LPM/ITALY/GID_LPM_AQ.py +277 -0
- disdrodb/l0/readers/LPM/ITALY/GID_LPM_PI.py +19 -18
- disdrodb/l0/readers/LPM/ITALY/GID_LPM_T.py +23 -19
- disdrodb/l0/readers/LPM/ITALY/GID_LPM_W.py +19 -21
- disdrodb/l0/readers/LPM/KIT/CHWALA.py +19 -20
- disdrodb/l0/readers/LPM/NETHERLANDS/DELFT_LPM_NC.py +1 -1
- disdrodb/l0/readers/LPM/NETHERLANDS/DELFT_RWANDA_LPM_NC.py +18 -18
- disdrodb/l0/readers/LPM/NORWAY/HAUKELISETER_LPM.py +19 -20
- disdrodb/l0/readers/LPM/NORWAY/NMBU_LPM.py +19 -20
- disdrodb/l0/readers/LPM/SLOVENIA/ARSO.py +19 -20
- disdrodb/l0/readers/LPM/SLOVENIA/UL.py +19 -20
- disdrodb/l0/readers/LPM/SWITZERLAND/INNERERIZ_LPM.py +19 -20
- disdrodb/l0/readers/LPM/UK/DIVEN.py +1 -1
- disdrodb/l0/readers/LPM/UK/WITHWORTH_LPM.py +19 -20
- disdrodb/l0/readers/LPM/USA/CHARLESTON.py +19 -20
- disdrodb/l0/readers/LPM/USA/DEVEX.py +255 -0
- disdrodb/l0/readers/LPM_V0/BELGIUM/ULIEGE.py +3 -5
- disdrodb/l0/readers/LPM_V0/ITALY/GID_LPM_V0.py +4 -3
- disdrodb/l0/readers/ODM470/OCEAN/OCEANRAIN.py +124 -0
- disdrodb/l0/readers/PARSIVEL/AUSTRALIA/MELBOURNE_2007_PARSIVEL.py +1 -1
- disdrodb/l0/readers/PARSIVEL/BASQUECOUNTRY/EUSKALMET_OTT.py +2 -1
- disdrodb/l0/readers/PARSIVEL/CHINA/CHONGQING.py +2 -3
- disdrodb/l0/readers/PARSIVEL/EPFL/ARCTIC_2021.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/COMMON_2011.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/DAVOS_2009_2011.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_2009.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2008.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2010.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2011.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2012.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/GENEPI_2007.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/GRAND_ST_BERNARD_2007.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/GRAND_ST_BERNARD_2007_2.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/HPICONET_2010.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP2.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP3.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP4.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/LOCARNO_2018.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/LOCARNO_2019.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/PARADISO_2014.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/PARSIVEL_2007.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/PLATO_2019.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/RACLETS_2019.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/RACLETS_2019_WJF.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/RIETHOLZBACH_2011.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/SAMOYLOV_2017.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/SAMOYLOV_2019.py +2 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/UNIL_2022.py +2 -1
- disdrodb/l0/readers/PARSIVEL/JAPAN/JMA.py +1 -1
- disdrodb/l0/readers/PARSIVEL/KOREA/ICEPOP_MSC.py +159 -0
- disdrodb/l0/readers/PARSIVEL/NASA/LPVEX.py +1 -1
- disdrodb/l0/readers/PARSIVEL/NASA/MC3E.py +1 -1
- disdrodb/l0/readers/PARSIVEL/NCAR/CCOPE_2015.py +1 -1
- disdrodb/l0/readers/PARSIVEL/NCAR/OWLES_MIPS.py +1 -1
- disdrodb/l0/readers/PARSIVEL/NCAR/PECAN_MOBILE.py +1 -1
- disdrodb/l0/readers/PARSIVEL/NCAR/PLOWS_MIPS.py +1 -1
- disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2009.py +1 -1
- disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2010.py +1 -3
- disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2010_UF.py +1 -3
- disdrodb/l0/readers/PARSIVEL/SLOVENIA/UL.py +2 -1
- disdrodb/l0/readers/PARSIVEL2/ARM/ARM_PARSIVEL2.py +2 -1
- disdrodb/l0/readers/PARSIVEL2/BASQUECOUNTRY/EUSKALMET_OTT2.py +2 -1
- disdrodb/l0/readers/PARSIVEL2/BELGIUM/ILVO.py +2 -3
- disdrodb/l0/readers/PARSIVEL2/BRAZIL/CHUVA_PARSIVEL2.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/BRAZIL/GOAMAZON_PARSIVEL2.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/CANADA/UQAM_NC.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/DENMARK/DTU.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/DENMARK/EROSION_nc.py +2 -1
- disdrodb/l0/readers/PARSIVEL2/DENMARK/EROSION_raw.py +2 -1
- disdrodb/l0/readers/PARSIVEL2/FINLAND/FMI_PARSIVEL2.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/FRANCE/ENPC_PARSIVEL2.py +2 -3
- disdrodb/l0/readers/PARSIVEL2/FRANCE/OSUG.py +2 -2
- disdrodb/l0/readers/PARSIVEL2/FRANCE/SIRTA_PARSIVEL2.py +1 -3
- disdrodb/l0/readers/PARSIVEL2/GREECE/NOA.py +4 -3
- disdrodb/l0/readers/PARSIVEL2/ITALY/GID_PARSIVEL2.py +1 -3
- disdrodb/l0/readers/PARSIVEL2/ITALY/HYDROX.py +6 -3
- disdrodb/l0/readers/PARSIVEL2/JAPAN/PRECIP.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/KIT/BURKINA_FASO.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/KIT/TEAMX.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/KOREA/ICEPOP_MSC.py +161 -0
- disdrodb/l0/readers/PARSIVEL2/KOREA/ICEPOP_UCLM.py +126 -0
- disdrodb/l0/readers/PARSIVEL2/MEXICO/OH_IIUNAM_nc.py +2 -1
- disdrodb/l0/readers/PARSIVEL2/MPI/BCO_PARSIVEL2.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/MPI/BOWTIE.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/NASA/APU.py +3 -1
- disdrodb/l0/readers/PARSIVEL2/NASA/NSSTC.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/NCAR/FARM_PARSIVEL2.py +2 -1
- disdrodb/l0/readers/PARSIVEL2/NCAR/PECAN_FP3.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/NCAR/PECAN_MIPS.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/NCAR/PERILS_MIPS.py +2 -1
- disdrodb/l0/readers/PARSIVEL2/NCAR/PERILS_PIPS.py +2 -1
- disdrodb/l0/readers/PARSIVEL2/NCAR/RELAMPAGO_PARSIVEL2.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/NCAR/SNOWIE_PJ.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/NCAR/SNOWIE_SB.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_P1.py +2 -3
- disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_P2.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_PIPS.py +2 -1
- disdrodb/l0/readers/PARSIVEL2/NETHERLANDS/DELFT_NC.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/NORWAY/UIB.py +10 -2
- disdrodb/l0/readers/PARSIVEL2/PHILIPPINES/PAGASA.py +2 -3
- disdrodb/l0/readers/PARSIVEL2/SPAIN/CENER.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/SPAIN/CR1000DL.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/SPAIN/GRANADA.py +2 -3
- disdrodb/l0/readers/PARSIVEL2/SPAIN/LIAISE.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/SWEDEN/SMHI.py +2 -1
- disdrodb/l0/readers/PARSIVEL2/USA/CSU.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/USA/CW3E.py +2 -1
- disdrodb/l0/readers/PWS100/AUSTRIA/HOAL.py +2 -3
- disdrodb/l0/readers/PWS100/FRANCE/ENPC_PWS100.py +2 -3
- disdrodb/l0/readers/PWS100/FRANCE/ENPC_PWS100_SIRTA.py +2 -1
- disdrodb/l0/readers/RD80/BRAZIL/ATTO_RD80.py +1 -3
- disdrodb/l0/readers/RD80/BRAZIL/CHUVA_RD80.py +1 -3
- disdrodb/l0/readers/RD80/BRAZIL/GOAMAZON_RD80.py +1 -3
- disdrodb/l0/readers/RD80/NCAR/CINDY_2011_RD80.py +1 -3
- disdrodb/l0/readers/RD80/NCAR/RELAMPAGO_RD80.py +1 -3
- disdrodb/l0/readers/RD80/NOAA/PSL_RD80.py +2 -3
- disdrodb/l0/readers/SWS250/BELGIUM/KMI.py +2 -3
- disdrodb/l0/readers/template_reader_raw_netcdf_data.py +2 -3
- disdrodb/l0/readers/template_reader_raw_text_data.py +2 -3
- disdrodb/l0/standards.py +4 -5
- disdrodb/l0/template_tools.py +7 -11
- disdrodb/l1/__init__.py +2 -1
- disdrodb/l1/classification.py +914 -0
- disdrodb/l1/processing.py +36 -106
- disdrodb/l1/resampling.py +13 -3
- disdrodb/l1_env/__init__.py +1 -1
- disdrodb/l1_env/routines.py +7 -6
- disdrodb/l2/__init__.py +2 -1
- disdrodb/l2/empirical_dsd.py +58 -31
- disdrodb/l2/processing.py +327 -61
- disdrodb/metadata/checks.py +10 -13
- disdrodb/metadata/download.py +5 -4
- disdrodb/metadata/geolocation.py +3 -4
- disdrodb/metadata/info.py +3 -5
- disdrodb/metadata/manipulation.py +1 -3
- disdrodb/metadata/reader.py +1 -3
- disdrodb/metadata/search.py +1 -4
- disdrodb/metadata/standards.py +1 -3
- disdrodb/metadata/writer.py +1 -3
- disdrodb/physics/__init__.py +17 -0
- disdrodb/physics/atmosphere.py +273 -0
- disdrodb/physics/water.py +131 -0
- disdrodb/physics/wrappers.py +63 -0
- disdrodb/psd/__init__.py +1 -2
- disdrodb/psd/fitting.py +23 -9
- disdrodb/psd/models.py +2 -1
- disdrodb/routines/__init__.py +6 -1
- disdrodb/routines/l0.py +39 -25
- disdrodb/routines/l1.py +23 -16
- disdrodb/routines/l2.py +12 -9
- disdrodb/routines/options.py +117 -73
- disdrodb/routines/options_validation.py +728 -0
- disdrodb/routines/wrappers.py +460 -40
- disdrodb/scattering/__init__.py +1 -2
- disdrodb/scattering/axis_ratio.py +6 -6
- disdrodb/scattering/permittivity.py +9 -8
- disdrodb/scattering/routines.py +33 -15
- disdrodb/summary/__init__.py +1 -1
- disdrodb/summary/routines.py +95 -30
- disdrodb/utils/__init__.py +1 -1
- disdrodb/utils/archiving.py +18 -10
- disdrodb/utils/attrs.py +7 -5
- disdrodb/utils/cli.py +8 -10
- disdrodb/utils/compression.py +10 -13
- disdrodb/utils/coords.py +45 -0
- disdrodb/utils/dask.py +7 -5
- disdrodb/utils/dataframe.py +5 -6
- disdrodb/utils/decorators.py +3 -4
- disdrodb/utils/dict.py +1 -1
- disdrodb/utils/directories.py +5 -7
- disdrodb/utils/encoding.py +4 -5
- disdrodb/utils/event.py +1 -1
- disdrodb/utils/list.py +1 -3
- disdrodb/utils/logger.py +1 -3
- disdrodb/utils/manipulations.py +175 -4
- disdrodb/utils/pydantic.py +81 -0
- disdrodb/utils/routines.py +2 -3
- disdrodb/utils/subsetting.py +1 -1
- disdrodb/utils/time.py +6 -4
- disdrodb/utils/warnings.py +2 -3
- disdrodb/utils/writer.py +5 -3
- disdrodb/utils/xarray.py +31 -3
- disdrodb/utils/yaml.py +1 -3
- disdrodb/viz/__init__.py +1 -1
- disdrodb/viz/plots.py +193 -18
- {disdrodb-0.2.1.dist-info → disdrodb-0.4.0.dist-info}/METADATA +5 -4
- disdrodb-0.4.0.dist-info/RECORD +361 -0
- {disdrodb-0.2.1.dist-info → disdrodb-0.4.0.dist-info}/entry_points.txt +3 -0
- disdrodb/etc/products/L1/1MIN.yaml +0 -13
- disdrodb/etc/products/L1/LPM/1MIN.yaml +0 -13
- disdrodb/etc/products/L1/LPM_V0/1MIN.yaml +0 -13
- disdrodb/etc/products/L1/PARSIVEL/1MIN.yaml +0 -13
- disdrodb/etc/products/L1/PARSIVEL2/1MIN.yaml +0 -13
- disdrodb/etc/products/L1/PWS100/1MIN.yaml +0 -13
- disdrodb/etc/products/L1/RD80/1MIN.yaml +0 -13
- disdrodb/etc/products/L1/SWS250/1MIN.yaml +0 -13
- disdrodb/etc/products/L2M/10MIN.yaml +0 -12
- disdrodb/l1/beard_model.py +0 -662
- disdrodb/l1/filters.py +0 -205
- disdrodb-0.2.1.dist-info/RECORD +0 -329
- {disdrodb-0.2.1.dist-info → disdrodb-0.4.0.dist-info}/WHEEL +0 -0
- {disdrodb-0.2.1.dist-info → disdrodb-0.4.0.dist-info}/licenses/LICENSE +0 -0
- {disdrodb-0.2.1.dist-info → disdrodb-0.4.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------.
|
|
2
|
+
# Copyright (c) 2021-2026 DISDRODB developers
|
|
3
|
+
#
|
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
#
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU General Public License
|
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
# -----------------------------------------------------------------------------.
|
|
17
|
+
"""Theoretical models to estimate hailstones fall velocity based on particle maximum diameter in mm."""
|
|
18
|
+
|
|
19
|
+
import numpy as np
|
|
20
|
+
import xarray as xr
|
|
21
|
+
|
|
22
|
+
from disdrodb.constants import DIAMETER_DIMENSION
|
|
23
|
+
from disdrodb.l0.l0b_processing import ensure_valid_geolocation
|
|
24
|
+
from disdrodb.l1_env.routines import load_env_dataset
|
|
25
|
+
from disdrodb.physics.wrappers import retrieve_air_pressure
|
|
26
|
+
from disdrodb.utils.warnings import suppress_warnings
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def get_fall_velocity_laurie_1960(diameter):
|
|
30
|
+
"""Get hailstones fall velocity based on Laurie 1960 data.
|
|
31
|
+
|
|
32
|
+
The parametrizazion is reported in Table 3 of Heymsfield et al., 2018.
|
|
33
|
+
|
|
34
|
+
Parameters
|
|
35
|
+
----------
|
|
36
|
+
diameter : array-like or float
|
|
37
|
+
Particle maximum diameter in millimeters [mm].
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
fall_velocity : array-like or float
|
|
43
|
+
Terminal fall velocity [m s⁻¹].
|
|
44
|
+
|
|
45
|
+
References
|
|
46
|
+
----------
|
|
47
|
+
Heymsfield, A., M. Szakáll, A. Jost, I. Giammanco, and R. Wright, 2018.
|
|
48
|
+
A Comprehensive Observational Study of Graupel and Hail Terminal Velocity, Mass Flux, and Kinetic Energy.
|
|
49
|
+
J. Atmos. Sci., 75, 3861-3885, https://doi.org/10.1175/JAS-D-18-0035.1.
|
|
50
|
+
"""
|
|
51
|
+
fall_velocity = 13.95 * (0.1 * diameter) ** 0.51
|
|
52
|
+
return fall_velocity
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def get_fall_velocity_knight_1983_low_density(diameter):
|
|
56
|
+
"""Get low-density hailstones fall velocity based on Knight et al. 1983.
|
|
57
|
+
|
|
58
|
+
The parametrization is reported in Figure 3 of Knight et al. 1983.
|
|
59
|
+
It's valid for hail stone density between 0.31 and 0.61 g cm-3.
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
diameter : array-like or float
|
|
64
|
+
Particle maximum diameter in millimeters [mm].
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
Returns
|
|
68
|
+
-------
|
|
69
|
+
fall_velocity : array-like or float
|
|
70
|
+
Terminal fall velocity [m s⁻¹].
|
|
71
|
+
|
|
72
|
+
References
|
|
73
|
+
----------
|
|
74
|
+
Knight, N. C., and A. J. Heymsfield, 1983.
|
|
75
|
+
Measurement and Interpretation of Hailstone Density and Terminal Velocity.
|
|
76
|
+
J. Atmos. Sci., 40, 1510-1516. https://doi.org/10.1175/1520-0469(1983)040<1510:MAIOHD>2.0.CO;2.
|
|
77
|
+
"""
|
|
78
|
+
fall_velocity = 8.445 * (0.1 * diameter) ** 0.553
|
|
79
|
+
return fall_velocity
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def get_fall_velocity_knight_1983_high_density(diameter):
|
|
83
|
+
"""Get low-density hailstones fall velocity based on Knight et al. 1983.
|
|
84
|
+
|
|
85
|
+
The parametrization is reported in Figure 6 of Knight et al. 1983.
|
|
86
|
+
It's valid for hail stone density around 0.82 g cm-3.
|
|
87
|
+
|
|
88
|
+
Parameters
|
|
89
|
+
----------
|
|
90
|
+
diameter : array-like or float
|
|
91
|
+
Particle maximum diameter in millimeters [mm].
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
Returns
|
|
95
|
+
-------
|
|
96
|
+
fall_velocity : array-like or float
|
|
97
|
+
Terminal fall velocity [m s⁻¹].
|
|
98
|
+
|
|
99
|
+
References
|
|
100
|
+
----------
|
|
101
|
+
Knight, N. C., and A. J. Heymsfield, 1983.
|
|
102
|
+
Measurement and Interpretation of Hailstone Density and Terminal Velocity.
|
|
103
|
+
J. Atmos. Sci., 40, 1510-1516. https://doi.org/10.1175/1520-0469(1983)040<1510:MAIOHD>2.0.CO;2.
|
|
104
|
+
"""
|
|
105
|
+
fall_velocity = 10.58 * (0.1 * diameter) ** 0.267
|
|
106
|
+
return fall_velocity
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def get_fall_velocity_heymsfield_2014(diameter):
|
|
110
|
+
"""Get hail fall velocity from Heymsfield et al., 2014.
|
|
111
|
+
|
|
112
|
+
Use the Heymsfield et al., 2014 parameterization.
|
|
113
|
+
|
|
114
|
+
Parameters
|
|
115
|
+
----------
|
|
116
|
+
diameter : array-like or float
|
|
117
|
+
Maximum Particle maximum diameter in millimeters [mm].
|
|
118
|
+
|
|
119
|
+
Returns
|
|
120
|
+
-------
|
|
121
|
+
fall_velocity : xarray.DataArray or numpy.ndarray
|
|
122
|
+
Terminal fall velocity [m s⁻¹].
|
|
123
|
+
|
|
124
|
+
References
|
|
125
|
+
----------
|
|
126
|
+
Heymsfield, A. J., I. M. Giammanco, and R. Wright (2014).
|
|
127
|
+
Terminal velocities and kinetic energies of natural hailstones.
|
|
128
|
+
Geophys. Res. Lett., 41, 8666-8672, https://doi.org/10.1002/2014GL062324
|
|
129
|
+
"""
|
|
130
|
+
fall_velocity = 12.28 * (0.1 * diameter) ** 0.57 # Dmax > 1.3 mm
|
|
131
|
+
return fall_velocity
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def get_fall_velocity_heymsfield_2018(diameter):
|
|
135
|
+
"""Get hailstones fall velocity from Heymsfield et al., 2018.
|
|
136
|
+
|
|
137
|
+
Parameters
|
|
138
|
+
----------
|
|
139
|
+
diameter : array-like or float
|
|
140
|
+
Particle maximum diameter in millimeters [mm].
|
|
141
|
+
|
|
142
|
+
Returns
|
|
143
|
+
-------
|
|
144
|
+
fall_velocity : array-like or float
|
|
145
|
+
Terminal fall velocity [m s⁻¹].
|
|
146
|
+
|
|
147
|
+
References
|
|
148
|
+
----------
|
|
149
|
+
Heymsfield, A., M. Szakáll, A. Jost, I. Giammanco, and R. Wright, 2018.
|
|
150
|
+
A Comprehensive Observational Study of Graupel and Hail Terminal Velocity, Mass Flux, and Kinetic Energy.
|
|
151
|
+
J. Atmos. Sci., 75, 3861-3885, https://doi.org/10.1175/JAS-D-18-0035.1.
|
|
152
|
+
|
|
153
|
+
Heymsfield, A., M. Szakáll, A. Jost, I. Giammanco, R. Wright, and J. Brimelow, 2020.
|
|
154
|
+
CORRIGENDUM.
|
|
155
|
+
J. Atmos. Sci., 77, 405-412, https://doi.org/10.1175/JAS-D-19-0185.1.
|
|
156
|
+
"""
|
|
157
|
+
# Original incorrect formula from Heymsfield et al., 2018
|
|
158
|
+
# fall_velocity = 6.1 * (0.1 * diameter) ** 0.72 # eq 7 and 15
|
|
159
|
+
|
|
160
|
+
# Corrected formula from Heymsfield et al., 2020 (Corrigendum)
|
|
161
|
+
fall_velocity = 8.39 * (0.1 * diameter) ** 0.67
|
|
162
|
+
return fall_velocity
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def get_fall_velocity_fehlmann_2020(diameter):
|
|
166
|
+
"""Get hailstones fall velocity from Fehlmann et al., 2020."""
|
|
167
|
+
fall_velocity = 3.74 * diameter**0.5
|
|
168
|
+
return fall_velocity
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
####------------------------------------------------------------------------------------
|
|
172
|
+
#### Wrappers
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
HAIL_FALL_VELOCITY_MODELS = {
|
|
176
|
+
"Laurie1960": get_fall_velocity_laurie_1960,
|
|
177
|
+
"Knight1983LD": get_fall_velocity_knight_1983_low_density,
|
|
178
|
+
"Knight1983HD": get_fall_velocity_knight_1983_high_density,
|
|
179
|
+
"Heymsfield2014": get_fall_velocity_heymsfield_2014,
|
|
180
|
+
"Heymsfield2018": get_fall_velocity_heymsfield_2018,
|
|
181
|
+
"Fehlmann2020": get_fall_velocity_fehlmann_2020,
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def available_hail_fall_velocity_models():
|
|
186
|
+
"""Return a list of the available hail fall velocity models."""
|
|
187
|
+
return list(HAIL_FALL_VELOCITY_MODELS)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def check_hail_fall_velocity_model(model):
|
|
191
|
+
"""Check validity of the specified hail fall velocity model."""
|
|
192
|
+
available_models = available_hail_fall_velocity_models()
|
|
193
|
+
if model not in available_models:
|
|
194
|
+
raise ValueError(f"{model} is an invalid hail fall velocity model. Valid models: {available_models}.")
|
|
195
|
+
return model
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def get_hail_fall_velocity_model(model):
|
|
199
|
+
"""Return the specified hail fall velocity model.
|
|
200
|
+
|
|
201
|
+
Parameters
|
|
202
|
+
----------
|
|
203
|
+
model : str
|
|
204
|
+
The model to use for calculating the rain drop fall velocity. Available models are:
|
|
205
|
+
'Laurie1960', 'Knight1983LD', 'Knight1983HD', 'Heymsfield2014', 'Heymsfield2018', 'Fehlmann2020'.
|
|
206
|
+
|
|
207
|
+
Returns
|
|
208
|
+
-------
|
|
209
|
+
callable
|
|
210
|
+
A function which compute the hail fall velocity model
|
|
211
|
+
given the rain drop diameter in mm.
|
|
212
|
+
|
|
213
|
+
Notes
|
|
214
|
+
-----
|
|
215
|
+
This function serves as a wrapper to various hail fall velocity models.
|
|
216
|
+
It returns the appropriate model based on the `model` parameter.
|
|
217
|
+
"""
|
|
218
|
+
model = check_hail_fall_velocity_model(model)
|
|
219
|
+
return HAIL_FALL_VELOCITY_MODELS[model]
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def get_hail_fall_velocity(diameter, model, ds_env=None, minimum_diameter=4):
|
|
223
|
+
"""Calculate the fall velocity of hails based on their diameter.
|
|
224
|
+
|
|
225
|
+
Parameters
|
|
226
|
+
----------
|
|
227
|
+
diameter : array-like
|
|
228
|
+
The diameter of the hails in millimeters.
|
|
229
|
+
model : str
|
|
230
|
+
The model to use for calculating the hail fall velocity. Must be one of the following:
|
|
231
|
+
'Laurie1960', 'Knight1983LD', 'Knight1983HD', 'Heymsfield2014', 'Heymsfield2018', 'Fehlmann2020'.
|
|
232
|
+
ds_env : xr.Dataset, optional
|
|
233
|
+
A dataset containing the following environmental variables:
|
|
234
|
+
- 'altitude' (m)
|
|
235
|
+
- 'latitude' (°)
|
|
236
|
+
- 'temperature' : Temperature in degrees Kelvin (K).
|
|
237
|
+
- 'relative_humidity' : Relative humidity. A value between 0 and 1.
|
|
238
|
+
- 'sea_level_air_pressure' : Sea level air pressure in Pascals (Pa).
|
|
239
|
+
- 'lapse_rate' : Lapse rate in degrees Celsius per meter (°C/m).
|
|
240
|
+
If not specified, sensible default values are used.
|
|
241
|
+
|
|
242
|
+
Returns
|
|
243
|
+
-------
|
|
244
|
+
fall_velocity : xr.DataArray
|
|
245
|
+
The calculated hail fall velocities per diameter.
|
|
246
|
+
|
|
247
|
+
"""
|
|
248
|
+
# Check valid method
|
|
249
|
+
model = check_hail_fall_velocity_model(model)
|
|
250
|
+
|
|
251
|
+
# Copy diameter
|
|
252
|
+
if isinstance(diameter, xr.DataArray):
|
|
253
|
+
diameter = diameter.copy()
|
|
254
|
+
else:
|
|
255
|
+
diameter = np.atleast_1d(diameter)
|
|
256
|
+
diameter = xr.DataArray(diameter, dims=DIAMETER_DIMENSION, coords={DIAMETER_DIMENSION: diameter.copy()})
|
|
257
|
+
|
|
258
|
+
# Initialize ds_env if None
|
|
259
|
+
# --> Ensure valid altitude and geolocation
|
|
260
|
+
# - altitude requiredto correct for elevation (air_density)
|
|
261
|
+
# - latitude required for gravity
|
|
262
|
+
if ds_env is None:
|
|
263
|
+
ds_env = load_env_dataset()
|
|
264
|
+
for coord in ["altitude", "latitude"]:
|
|
265
|
+
ds_env = ensure_valid_geolocation(ds_env, coord=coord, errors="raise")
|
|
266
|
+
|
|
267
|
+
# Retrieve fall velocity
|
|
268
|
+
func = get_hail_fall_velocity_model(model)
|
|
269
|
+
with suppress_warnings(): # e.g. when diameter = 0
|
|
270
|
+
fall_velocity = func(diameter)
|
|
271
|
+
|
|
272
|
+
# Correct for altitude
|
|
273
|
+
air_pressure = retrieve_air_pressure(ds_env)
|
|
274
|
+
correction_factor = (101325 / air_pressure) ** 0.545
|
|
275
|
+
fall_velocity = fall_velocity * correction_factor
|
|
276
|
+
|
|
277
|
+
# Set to NaN for diameter outside [5, ...)
|
|
278
|
+
fall_velocity = fall_velocity.where(diameter > minimum_diameter)
|
|
279
|
+
|
|
280
|
+
# Ensure fall velocity is > 0 to avoid division by zero
|
|
281
|
+
# - Some models, at small diameter, can return negative/zero fall velocity
|
|
282
|
+
fall_velocity = fall_velocity.where(fall_velocity > 0)
|
|
283
|
+
|
|
284
|
+
# Add attributes
|
|
285
|
+
fall_velocity.name = "fall_velocity"
|
|
286
|
+
fall_velocity.attrs["units"] = "m/s"
|
|
287
|
+
fall_velocity.attrs["model"] = model
|
|
288
|
+
return fall_velocity.squeeze()
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -----------------------------------------------------------------------------.
|
|
2
|
-
# Copyright (c) 2021-
|
|
2
|
+
# Copyright (c) 2021-2026 DISDRODB developers
|
|
3
3
|
#
|
|
4
4
|
# This program is free software: you can redistribute it and/or modify
|
|
5
5
|
# it under the terms of the GNU General Public License as published by
|
|
@@ -15,12 +15,14 @@
|
|
|
15
15
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
16
|
# -----------------------------------------------------------------------------.
|
|
17
17
|
"""Theoretical models to estimate the raindrop fall velocity based on drop diameter in mm."""
|
|
18
|
+
|
|
18
19
|
import numpy as np
|
|
19
20
|
import xarray as xr
|
|
20
21
|
|
|
21
22
|
from disdrodb.constants import DIAMETER_DIMENSION
|
|
22
23
|
from disdrodb.l0.l0b_processing import ensure_valid_geolocation
|
|
23
24
|
from disdrodb.l1_env.routines import load_env_dataset
|
|
25
|
+
from disdrodb.physics.wrappers import retrieve_air_density
|
|
24
26
|
from disdrodb.utils.warnings import suppress_warnings
|
|
25
27
|
|
|
26
28
|
|
|
@@ -138,8 +140,159 @@ def get_fall_velocity_van_dijk_2002(diameter):
|
|
|
138
140
|
return fall_velocity
|
|
139
141
|
|
|
140
142
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
+
####---------------------------------------------------------------------------.
|
|
144
|
+
#### Beard model
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def get_raindrop_reynolds_number(diameter, temperature, air_density, water_density, g):
|
|
148
|
+
"""Compute raindrop Reynolds number.
|
|
149
|
+
|
|
150
|
+
It quantifies the relative strength of the convective inertia and linear viscous
|
|
151
|
+
forces acting on the drop at terminal velocity.
|
|
152
|
+
|
|
153
|
+
Estimates Reynolds number for drops with diameter between 19 um and 7 mm.
|
|
154
|
+
Coefficients are taken from Table 1 of Beard 1976.
|
|
155
|
+
|
|
156
|
+
Reference: Beard 1976; Pruppacher & Klett 1978
|
|
157
|
+
See also Table A1 in Rahman et al., 2020.
|
|
158
|
+
|
|
159
|
+
Parameters
|
|
160
|
+
----------
|
|
161
|
+
diameter : float
|
|
162
|
+
Diameter of the raindrop in meters.
|
|
163
|
+
temperature : float
|
|
164
|
+
Temperature in Kelvin.
|
|
165
|
+
air_density : float
|
|
166
|
+
Density of air in kg/m^3.
|
|
167
|
+
water_density : float
|
|
168
|
+
Density of water in kg/m^3.
|
|
169
|
+
g : float
|
|
170
|
+
Gravitational acceleration in m/s^2.
|
|
171
|
+
|
|
172
|
+
Returns
|
|
173
|
+
-------
|
|
174
|
+
float
|
|
175
|
+
Reynolds number for the raindrop.
|
|
176
|
+
"""
|
|
177
|
+
from disdrodb.physics.atmosphere import get_air_dynamic_viscosity
|
|
178
|
+
from disdrodb.physics.water import get_pure_water_surface_tension
|
|
179
|
+
|
|
180
|
+
# Define mask for small and large particles
|
|
181
|
+
small_diam_mask = diameter < 1.07e-3 # < 1mm
|
|
182
|
+
|
|
183
|
+
# Compute properties
|
|
184
|
+
pure_water_surface_tension = get_pure_water_surface_tension(temperature) # N/m
|
|
185
|
+
air_viscosity = get_air_dynamic_viscosity(temperature) # kg/(m*s) (aka Pa*s).
|
|
186
|
+
delta_density = water_density - air_density
|
|
187
|
+
|
|
188
|
+
# Compute Davies number for small droplets
|
|
189
|
+
davis_number = 4 * air_density * delta_density * g * diameter**3 / (3 * air_viscosity**2)
|
|
190
|
+
|
|
191
|
+
# Compute the slip correction (is approx 1 and can be discarded)
|
|
192
|
+
# l0 = 6.62*1e-8 # m
|
|
193
|
+
# v0 = 0.01818 # g / m / s
|
|
194
|
+
# p0 = 101_325_25 # Pa
|
|
195
|
+
# t0 = 293.15 # K
|
|
196
|
+
# c_sc = 1 + 2.51*l0*(air_viscosity/v0)*(air_pressure/p0)*((temperature/t0)**3)/diameter
|
|
197
|
+
|
|
198
|
+
# Compute modified Bond and physical property numbers for large droplets
|
|
199
|
+
bond_number = 4 * delta_density * g * diameter**2 / (3 * pure_water_surface_tension)
|
|
200
|
+
property_number = pure_water_surface_tension**3 * air_density**2 / (air_viscosity**4 * delta_density * g)
|
|
201
|
+
|
|
202
|
+
# Compute Reynolds_number_for small particles (diameter < 0.00107) (1 mm)
|
|
203
|
+
b = [-3.18657, 0.992696, -0.00153193, -0.000987059, -0.000578878, 0.0000855176, -0.00000327815]
|
|
204
|
+
x = np.log(davis_number)
|
|
205
|
+
y = b[0] + sum(b * x**i for i, b in enumerate(b[1:], start=1))
|
|
206
|
+
reynolds_number_small = np.exp(y) # TODO: miss C_sc = slip correction factor ?
|
|
207
|
+
|
|
208
|
+
# Compute Reynolds_number_for large particles (diameter >= 0.00107)
|
|
209
|
+
b = [-5.00015, 5.23778, -2.04914, 0.475294, -0.0542819, 0.00238449]
|
|
210
|
+
log_property_number = np.log(property_number) / 6
|
|
211
|
+
x = np.log(bond_number) + log_property_number
|
|
212
|
+
y = b[0] + sum(b * x**i for i, b in enumerate(b[1:], start=1))
|
|
213
|
+
reynolds_number_large = np.exp(log_property_number + y)
|
|
214
|
+
|
|
215
|
+
# Define final reynolds number
|
|
216
|
+
reynolds_number = xr.where(small_diam_mask, reynolds_number_small, reynolds_number_large)
|
|
217
|
+
return reynolds_number
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def get_drag_coefficient(diameter, air_density, water_density, fall_velocity, g=9.81):
|
|
221
|
+
"""
|
|
222
|
+
Computes the drag coefficient for a raindrop.
|
|
223
|
+
|
|
224
|
+
Parameters
|
|
225
|
+
----------
|
|
226
|
+
diameter : float
|
|
227
|
+
Diameter of the raindrop in meters.
|
|
228
|
+
air_density : float
|
|
229
|
+
Density of air in kg/m^3.
|
|
230
|
+
water_density : float
|
|
231
|
+
Density of water in kg/m^3.
|
|
232
|
+
fall_velocity : float
|
|
233
|
+
Terminal fall velocity of the raindrop in m/s.
|
|
234
|
+
g : float
|
|
235
|
+
Gravitational acceleration in m/s^2.
|
|
236
|
+
|
|
237
|
+
Returns
|
|
238
|
+
-------
|
|
239
|
+
float
|
|
240
|
+
Drag coefficient of the raindrop.
|
|
241
|
+
"""
|
|
242
|
+
delta_density = water_density - air_density
|
|
243
|
+
drag_coefficient = 4 * delta_density * g * diameter / (3 * air_density * fall_velocity**2)
|
|
244
|
+
return drag_coefficient
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def get_raindrop_beard1976_fall_velocity(diameter, temperature, air_density, water_density, g):
|
|
248
|
+
"""
|
|
249
|
+
Computes the terminal fall velocity of a raindrop in still air.
|
|
250
|
+
|
|
251
|
+
Reference: Beard 1976; Pruppacher & Klett 1978
|
|
252
|
+
|
|
253
|
+
Parameters
|
|
254
|
+
----------
|
|
255
|
+
diameter : float
|
|
256
|
+
Diameter of the raindrop in millimeters.
|
|
257
|
+
temperature : float
|
|
258
|
+
Temperature in Kelvin.
|
|
259
|
+
air_density : float
|
|
260
|
+
Density of air in kg/m^3.
|
|
261
|
+
water_density : float
|
|
262
|
+
Density of water in kg/m^3.
|
|
263
|
+
g : float
|
|
264
|
+
Gravitational acceleration in m/s^2.
|
|
265
|
+
|
|
266
|
+
Returns
|
|
267
|
+
-------
|
|
268
|
+
float
|
|
269
|
+
Terminal fall velocity of the raindrop in m/s.
|
|
270
|
+
"""
|
|
271
|
+
from disdrodb.physics.atmosphere import get_air_dynamic_viscosity
|
|
272
|
+
|
|
273
|
+
# Convert diameter to meter
|
|
274
|
+
diameter = diameter / 1000
|
|
275
|
+
|
|
276
|
+
# Compute air viscotiy and reynolds number
|
|
277
|
+
air_viscosity = get_air_dynamic_viscosity(temperature)
|
|
278
|
+
reynolds_number = get_raindrop_reynolds_number(
|
|
279
|
+
diameter=diameter,
|
|
280
|
+
temperature=temperature,
|
|
281
|
+
air_density=air_density,
|
|
282
|
+
water_density=water_density,
|
|
283
|
+
g=g,
|
|
284
|
+
)
|
|
285
|
+
# Compute fall velocity
|
|
286
|
+
fall_velocity = air_viscosity * reynolds_number / (air_density * diameter)
|
|
287
|
+
return fall_velocity
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def retrieve_raindrop_beard_fall_velocity(
|
|
291
|
+
diameter,
|
|
292
|
+
ds_env,
|
|
293
|
+
):
|
|
294
|
+
"""
|
|
295
|
+
Computes the terminal fall velocity for liquid raindrops using the Beard (1976) model.
|
|
143
296
|
|
|
144
297
|
Parameters
|
|
145
298
|
----------
|
|
@@ -150,56 +303,118 @@ def get_fall_velocity_beard_1976(diameter, ds_env):
|
|
|
150
303
|
- 'altitude' : Altitude in meters (m).
|
|
151
304
|
- 'latitude' : Latitude in degrees.
|
|
152
305
|
- 'temperature' : Temperature in degrees Kelvin (K).
|
|
153
|
-
- 'relative_humidity' : Relative humidity
|
|
154
|
-
- 'sea_level_air_pressure' :
|
|
155
|
-
|
|
156
|
-
- '
|
|
306
|
+
- 'relative_humidity' : Relative humidity between 0 and 1.
|
|
307
|
+
- 'sea_level_air_pressure' : Standard atmospheric pressure at sea level in Pascals (Pa).
|
|
308
|
+
The default is 101_325 Pa.
|
|
309
|
+
- 'air_pressure': Air pressure in Pascals (Pa). If None, air_pressure at altitude is inferred.
|
|
310
|
+
- 'lapse_rate' : Atmospheric lapse rate in degrees Celsius or Kelvin per meter (°C/m).
|
|
311
|
+
The default is 0.0065 K/m.
|
|
312
|
+
- 'gas_constant_dry_air': Gas constant for dry air in J/(kg*K).
|
|
313
|
+
The default is 287.04 is J/(kg*K).
|
|
157
314
|
|
|
158
315
|
Returns
|
|
159
316
|
-------
|
|
160
317
|
fall_velocity : array-like
|
|
161
|
-
|
|
318
|
+
Terminal fall velocity for liquid raindrops.
|
|
162
319
|
"""
|
|
163
|
-
from disdrodb.
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
320
|
+
from disdrodb.physics.atmosphere import (
|
|
321
|
+
get_air_density,
|
|
322
|
+
get_air_pressure_at_height,
|
|
323
|
+
get_gravitational_acceleration,
|
|
324
|
+
get_vapor_actual_pressure,
|
|
325
|
+
)
|
|
326
|
+
from disdrodb.physics.water import get_water_density
|
|
327
|
+
|
|
328
|
+
# Retrieve relevant variables from ENV dataset
|
|
329
|
+
altitude = ds_env["altitude"]
|
|
330
|
+
latitude = ds_env["latitude"]
|
|
331
|
+
temperature = ds_env["temperature"]
|
|
332
|
+
relative_humidity = ds_env["relative_humidity"]
|
|
333
|
+
air_pressure = ds_env.get("air_pressure", None)
|
|
334
|
+
sea_level_air_pressure = ds_env.get("sea_level_air_pressure", 101_325)
|
|
335
|
+
gas_constant_dry_air = ds_env.get("gas_constant_dry_air", 287.04)
|
|
336
|
+
lapse_rate = ds_env.get("lapse_rate", 0.0065)
|
|
337
|
+
|
|
338
|
+
# Retrieve air pressure at altitude if not specified
|
|
339
|
+
if air_pressure is None:
|
|
340
|
+
air_pressure = get_air_pressure_at_height(
|
|
341
|
+
altitude=altitude,
|
|
342
|
+
latitude=latitude,
|
|
343
|
+
temperature=temperature,
|
|
344
|
+
sea_level_air_pressure=sea_level_air_pressure,
|
|
345
|
+
lapse_rate=lapse_rate,
|
|
346
|
+
gas_constant_dry_air=gas_constant_dry_air,
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
# Retrieve vapour pressure (from relative humidity)
|
|
350
|
+
vapor_pressure = get_vapor_actual_pressure(
|
|
351
|
+
relative_humidity=relative_humidity,
|
|
352
|
+
temperature=temperature,
|
|
175
353
|
)
|
|
354
|
+
|
|
355
|
+
# Retrieve air density
|
|
356
|
+
air_density = get_air_density(
|
|
357
|
+
temperature=temperature,
|
|
358
|
+
air_pressure=air_pressure,
|
|
359
|
+
vapor_pressure=vapor_pressure,
|
|
360
|
+
gas_constant_dry_air=gas_constant_dry_air,
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
# Retrieve water density
|
|
364
|
+
water_density = get_water_density(
|
|
365
|
+
temperature=temperature,
|
|
366
|
+
air_pressure=air_pressure,
|
|
367
|
+
sea_level_air_pressure=sea_level_air_pressure,
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
# Retrieve accurate gravitational_acceleration
|
|
371
|
+
g = get_gravitational_acceleration(altitude=altitude, latitude=latitude)
|
|
372
|
+
|
|
373
|
+
# Compute fall velocity
|
|
374
|
+
fall_velocity = get_raindrop_beard1976_fall_velocity(
|
|
375
|
+
diameter=diameter,
|
|
376
|
+
temperature=temperature,
|
|
377
|
+
air_density=air_density,
|
|
378
|
+
water_density=water_density,
|
|
379
|
+
g=g,
|
|
380
|
+
)
|
|
381
|
+
|
|
382
|
+
# drag_coefficient = get_drag_coefficient(diameter=diameter,
|
|
383
|
+
# air_density=air_density,
|
|
384
|
+
# water_density=water_density,
|
|
385
|
+
# g=g.
|
|
386
|
+
# fall_velocity=fall_velocity)
|
|
387
|
+
|
|
388
|
+
# Clip output
|
|
176
389
|
fall_velocity = fall_velocity.clip(min=0, max=None)
|
|
177
390
|
return fall_velocity
|
|
178
391
|
|
|
179
392
|
|
|
180
|
-
|
|
393
|
+
#### --------------------------------------------------------------------------------------
|
|
394
|
+
#### WRAPPERS
|
|
395
|
+
RAIN_FALL_VELOCITY_MODELS = {
|
|
181
396
|
"Atlas1973": get_fall_velocity_atlas_1973,
|
|
182
|
-
"Beard1976":
|
|
397
|
+
"Beard1976": retrieve_raindrop_beard_fall_velocity,
|
|
183
398
|
"Brandes2002": get_fall_velocity_brandes_2002,
|
|
184
399
|
"Uplinger1981": get_fall_velocity_uplinger_1981,
|
|
185
400
|
"VanDijk2002": get_fall_velocity_van_dijk_2002,
|
|
186
401
|
}
|
|
187
402
|
|
|
188
403
|
|
|
189
|
-
def
|
|
404
|
+
def available_rain_fall_velocity_models():
|
|
190
405
|
"""Return a list of the available raindrop fall velocity models."""
|
|
191
|
-
return list(
|
|
406
|
+
return list(RAIN_FALL_VELOCITY_MODELS)
|
|
192
407
|
|
|
193
408
|
|
|
194
|
-
def
|
|
409
|
+
def check_rain_fall_velocity_model(model):
|
|
195
410
|
"""Check validity of the specified raindrop fall velocity model."""
|
|
196
|
-
available_models =
|
|
411
|
+
available_models = available_rain_fall_velocity_models()
|
|
197
412
|
if model not in available_models:
|
|
198
413
|
raise ValueError(f"{model} is an invalid raindrop fall velocity model. Valid models: {available_models}.")
|
|
199
414
|
return model
|
|
200
415
|
|
|
201
416
|
|
|
202
|
-
def
|
|
417
|
+
def get_rain_fall_velocity_model(model):
|
|
203
418
|
"""Return the specified raindrop fall velocity model.
|
|
204
419
|
|
|
205
420
|
Parameters
|
|
@@ -219,11 +434,11 @@ def get_raindrop_fall_velocity_model(model):
|
|
|
219
434
|
This function serves as a wrapper to various raindrop fall velocity models.
|
|
220
435
|
It returns the appropriate model based on the `model` parameter.
|
|
221
436
|
"""
|
|
222
|
-
model =
|
|
223
|
-
return
|
|
437
|
+
model = check_rain_fall_velocity_model(model)
|
|
438
|
+
return RAIN_FALL_VELOCITY_MODELS[model]
|
|
224
439
|
|
|
225
440
|
|
|
226
|
-
def
|
|
441
|
+
def get_rain_fall_velocity(diameter, model, ds_env=None):
|
|
227
442
|
"""Calculate the fall velocity of raindrops based on their diameter.
|
|
228
443
|
|
|
229
444
|
Parameters
|
|
@@ -261,7 +476,7 @@ def get_raindrop_fall_velocity(diameter, model, ds_env=None):
|
|
|
261
476
|
|
|
262
477
|
"""
|
|
263
478
|
# Check valid method
|
|
264
|
-
model =
|
|
479
|
+
model = check_rain_fall_velocity_model(model)
|
|
265
480
|
|
|
266
481
|
# Copy diameter
|
|
267
482
|
if isinstance(diameter, xr.DataArray):
|
|
@@ -270,24 +485,31 @@ def get_raindrop_fall_velocity(diameter, model, ds_env=None):
|
|
|
270
485
|
diameter = np.atleast_1d(diameter)
|
|
271
486
|
diameter = xr.DataArray(diameter, dims=DIAMETER_DIMENSION, coords={DIAMETER_DIMENSION: diameter.copy()})
|
|
272
487
|
|
|
273
|
-
# Initialize ds_env
|
|
274
|
-
if
|
|
275
|
-
|
|
276
|
-
ds_env = load_env_dataset()
|
|
488
|
+
# Initialize ds_env
|
|
489
|
+
if ds_env is None:
|
|
490
|
+
ds_env = load_env_dataset()
|
|
277
491
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
492
|
+
# Ensure valid altitude and geolocation
|
|
493
|
+
# - altitude required by Beard
|
|
494
|
+
# - latitude required for gravity
|
|
495
|
+
for coord in ["altitude", "latitude"]:
|
|
496
|
+
ds_env = ensure_valid_geolocation(ds_env, coord=coord, errors="raise")
|
|
283
497
|
|
|
284
498
|
# Retrieve fall velocity
|
|
285
|
-
func =
|
|
499
|
+
func = get_rain_fall_velocity_model(model)
|
|
286
500
|
with suppress_warnings(): # e.g. when diameter = 0 for Beard1976
|
|
287
501
|
fall_velocity = func(diameter, ds_env=ds_env) if model == "Beard1976" else func(diameter)
|
|
288
502
|
|
|
503
|
+
# Correct for altitude
|
|
504
|
+
if model != "Beard1976":
|
|
505
|
+
air_density_height = retrieve_air_density(ds_env)
|
|
506
|
+
air_density_sea_surface = 1.225 # kg/m3 (International Standard Atmosphere air density at sea level)
|
|
507
|
+
correction_factor = (air_density_sea_surface / air_density_height) ** (diameter * 0.025 + 0.375)
|
|
508
|
+
fall_velocity = fall_velocity * correction_factor
|
|
509
|
+
|
|
289
510
|
# Set to NaN for diameter outside [0, 10)
|
|
290
511
|
fall_velocity = fall_velocity.where(diameter < 10).where(diameter > 0)
|
|
512
|
+
|
|
291
513
|
# Ensure fall velocity is > 0 to avoid division by zero
|
|
292
514
|
# - Some models, at small diameter, can return negative/zero fall velocity
|
|
293
515
|
fall_velocity = fall_velocity.where(fall_velocity > 0)
|
|
@@ -299,7 +521,7 @@ def get_raindrop_fall_velocity(diameter, model, ds_env=None):
|
|
|
299
521
|
return fall_velocity.squeeze()
|
|
300
522
|
|
|
301
523
|
|
|
302
|
-
def
|
|
524
|
+
def get_rain_fall_velocity_from_ds(ds, ds_env=None, model="Beard1976", diameter="diameter_bin_center"):
|
|
303
525
|
"""Compute the raindrop fall velocity.
|
|
304
526
|
|
|
305
527
|
Parameters
|
|
@@ -349,6 +571,5 @@ def get_raindrop_fall_velocity_from_ds(ds, ds_env=None, model="Beard1976"):
|
|
|
349
571
|
ds_env = load_env_dataset(ds)
|
|
350
572
|
|
|
351
573
|
# Compute raindrop fall velocity
|
|
352
|
-
fall_velocity =
|
|
353
|
-
|
|
574
|
+
fall_velocity = get_rain_fall_velocity(diameter=ds[diameter], model=model, ds_env=ds_env) # mn
|
|
354
575
|
return fall_velocity
|