disdrodb 0.2.0__py3-none-any.whl → 0.3.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 +1 -1
- disdrodb/_config.py +1 -3
- disdrodb/_version.py +2 -2
- disdrodb/accessor/__init__.py +1 -1
- disdrodb/accessor/methods.py +18 -11
- disdrodb/api/checks.py +2 -4
- disdrodb/api/configs.py +1 -3
- disdrodb/api/create_directories.py +4 -6
- disdrodb/api/info.py +1 -3
- disdrodb/api/io.py +15 -9
- disdrodb/api/path.py +1 -3
- disdrodb/cli/disdrodb_check_metadata_archive.py +2 -2
- disdrodb/cli/disdrodb_check_products_options.py +44 -0
- disdrodb/cli/disdrodb_create_summary.py +48 -22
- disdrodb/cli/disdrodb_create_summary_station.py +39 -18
- disdrodb/cli/disdrodb_data_archive_directory.py +1 -3
- disdrodb/cli/disdrodb_download_archive.py +45 -24
- disdrodb/cli/disdrodb_download_metadata_archive.py +27 -16
- disdrodb/cli/disdrodb_download_station.py +56 -26
- disdrodb/cli/disdrodb_initialize_station.py +40 -20
- disdrodb/cli/disdrodb_metadata_archive_directory.py +1 -3
- disdrodb/cli/disdrodb_open_data_archive.py +16 -11
- disdrodb/cli/disdrodb_open_logs_directory.py +29 -18
- disdrodb/cli/disdrodb_open_metadata_archive.py +25 -11
- disdrodb/cli/disdrodb_open_metadata_directory.py +32 -20
- disdrodb/cli/disdrodb_open_product_directory.py +38 -21
- disdrodb/cli/disdrodb_open_readers_directory.py +1 -3
- disdrodb/cli/disdrodb_run.py +189 -0
- disdrodb/cli/disdrodb_run_l0.py +55 -64
- disdrodb/cli/disdrodb_run_l0_station.py +47 -52
- disdrodb/cli/disdrodb_run_l0a.py +47 -45
- disdrodb/cli/disdrodb_run_l0a_station.py +38 -37
- disdrodb/cli/disdrodb_run_l0b.py +45 -45
- disdrodb/cli/disdrodb_run_l0b_station.py +37 -36
- disdrodb/cli/disdrodb_run_l0c.py +50 -47
- disdrodb/cli/disdrodb_run_l0c_station.py +41 -38
- disdrodb/cli/disdrodb_run_l1.py +49 -45
- disdrodb/cli/disdrodb_run_l1_station.py +40 -37
- disdrodb/cli/disdrodb_run_l2e.py +50 -45
- disdrodb/cli/disdrodb_run_l2e_station.py +41 -37
- disdrodb/cli/disdrodb_run_l2m.py +49 -45
- disdrodb/cli/disdrodb_run_l2m_station.py +40 -37
- disdrodb/cli/disdrodb_run_station.py +184 -0
- disdrodb/cli/disdrodb_upload_archive.py +45 -35
- disdrodb/cli/disdrodb_upload_station.py +39 -32
- disdrodb/configs.py +13 -8
- disdrodb/constants.py +4 -2
- disdrodb/data_transfer/__init__.py +1 -3
- disdrodb/data_transfer/download_data.py +38 -54
- disdrodb/data_transfer/upload_data.py +1 -3
- disdrodb/data_transfer/zenodo.py +1 -3
- 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 +1 -14
- 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 +17 -3
- disdrodb/etc/products/L2M/global.yaml +1 -1
- disdrodb/fall_velocity/__init__.py +46 -0
- disdrodb/fall_velocity/graupel.py +483 -0
- disdrodb/fall_velocity/hail.py +287 -0
- disdrodb/{l1/fall_velocity.py → fall_velocity/rain.py} +265 -50
- disdrodb/issue/__init__.py +1 -3
- disdrodb/issue/checks.py +3 -5
- disdrodb/issue/reader.py +1 -3
- disdrodb/issue/writer.py +1 -3
- disdrodb/l0/__init__.py +1 -1
- disdrodb/l0/check_configs.py +26 -17
- disdrodb/l0/check_standards.py +1 -3
- disdrodb/l0/configs/LPM/l0a_encodings.yml +0 -1
- disdrodb/l0/configs/LPM/l0b_cf_attrs.yml +0 -4
- disdrodb/l0/configs/LPM/l0b_encodings.yml +9 -9
- disdrodb/l0/configs/LPM/raw_data_format.yml +11 -11
- disdrodb/l0/configs/LPM_V0/bins_diameter.yml +103 -0
- disdrodb/l0/configs/LPM_V0/bins_velocity.yml +103 -0
- disdrodb/l0/configs/LPM_V0/l0a_encodings.yml +45 -0
- disdrodb/l0/configs/LPM_V0/l0b_cf_attrs.yml +180 -0
- disdrodb/l0/configs/LPM_V0/l0b_encodings.yml +410 -0
- disdrodb/l0/configs/LPM_V0/raw_data_format.yml +474 -0
- 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/configs/PARSIVEL/raw_data_format.yml +8 -8
- disdrodb/l0/configs/PARSIVEL2/raw_data_format.yml +9 -9
- disdrodb/l0/l0_reader.py +1 -3
- disdrodb/l0/l0a_processing.py +7 -5
- disdrodb/l0/l0b_nc_processing.py +2 -4
- disdrodb/l0/l0b_processing.py +27 -22
- disdrodb/l0/l0c_processing.py +37 -11
- disdrodb/l0/manuals/LPM_V0.pdf +0 -0
- disdrodb/l0/readers/LPM/ARM/ARM_LPM.py +1 -1
- disdrodb/l0/readers/LPM/AUSTRALIA/MELBOURNE_2007_LPM.py +1 -1
- disdrodb/l0/readers/LPM/BRAZIL/CHUVA_LPM.py +1 -1
- disdrodb/l0/readers/LPM/BRAZIL/GOAMAZON_LPM.py +1 -1
- disdrodb/l0/readers/LPM/GERMANY/DWD.py +190 -12
- disdrodb/l0/readers/LPM/ITALY/GID_LPM.py +63 -14
- disdrodb/l0/readers/LPM/ITALY/GID_LPM_PI.py +279 -0
- disdrodb/l0/readers/LPM/ITALY/GID_LPM_T.py +279 -0
- disdrodb/l0/readers/LPM/ITALY/GID_LPM_W.py +3 -5
- disdrodb/l0/readers/LPM/KIT/CHWALA.py +1 -3
- disdrodb/l0/readers/LPM/NETHERLANDS/DELFT_LPM_NC.py +1 -1
- disdrodb/l0/readers/LPM/NETHERLANDS/DELFT_RWANDA_LPM_NC.py +103 -0
- disdrodb/l0/readers/LPM/NORWAY/HAUKELISETER_LPM.py +214 -0
- disdrodb/l0/readers/LPM/NORWAY/NMBU_LPM.py +206 -0
- disdrodb/l0/readers/LPM/SLOVENIA/ARSO.py +1 -3
- disdrodb/l0/readers/LPM/SLOVENIA/UL.py +1 -3
- disdrodb/l0/readers/LPM/SWITZERLAND/INNERERIZ_LPM.py +1 -3
- disdrodb/l0/readers/LPM/UK/DIVEN.py +1 -1
- disdrodb/l0/readers/LPM/UK/WITHWORTH_LPM.py +217 -0
- disdrodb/l0/readers/LPM/USA/CHARLESTON.py +227 -0
- disdrodb/l0/readers/{LPM → LPM_V0}/BELGIUM/ULIEGE.py +34 -52
- disdrodb/l0/readers/LPM_V0/ITALY/GID_LPM_V0.py +240 -0
- disdrodb/l0/readers/ODM470/OCEAN/OCEANRAIN.py +123 -0
- disdrodb/l0/readers/PARSIVEL/AUSTRALIA/MELBOURNE_2007_PARSIVEL.py +1 -1
- disdrodb/l0/readers/PARSIVEL/BASQUECOUNTRY/EUSKALMET_OTT.py +1 -1
- disdrodb/l0/readers/PARSIVEL/CHINA/CHONGQING.py +1 -3
- disdrodb/l0/readers/PARSIVEL/EPFL/ARCTIC_2021.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/COMMON_2011.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/DAVOS_2009_2011.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_2009.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2008.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2010.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2011.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2012.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/GENEPI_2007.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/GRAND_ST_BERNARD_2007.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/GRAND_ST_BERNARD_2007_2.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/HPICONET_2010.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP2.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP3.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP4.py +1 -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 +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/PARSIVEL_2007.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/PLATO_2019.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/RACLETS_2019.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/RACLETS_2019_WJF.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/RIETHOLZBACH_2011.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/SAMOYLOV_2017.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/SAMOYLOV_2019.py +1 -1
- disdrodb/l0/readers/PARSIVEL/EPFL/UNIL_2022.py +1 -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 +26 -14
- disdrodb/l0/readers/PARSIVEL/NASA/MC3E.py +2 -2
- 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 +1 -1
- disdrodb/l0/readers/PARSIVEL2/ARM/ARM_PARSIVEL2.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/BASQUECOUNTRY/EUSKALMET_OTT2.py +2 -2
- disdrodb/l0/readers/PARSIVEL2/BELGIUM/ILVO.py +1 -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 +1 -1
- disdrodb/l0/readers/PARSIVEL2/DENMARK/EROSION_raw.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/FINLAND/FMI_PARSIVEL2.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/FRANCE/ENPC_PARSIVEL2.py +1 -3
- disdrodb/l0/readers/PARSIVEL2/FRANCE/OSUG.py +1 -1
- 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 +5 -3
- disdrodb/l0/readers/PARSIVEL2/JAPAN/PRECIP.py +155 -0
- 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/{NASA/GCPEX.py → KOREA/ICEPOP_UCLM.py} +51 -31
- disdrodb/l0/readers/PARSIVEL2/MEXICO/OH_IIUNAM_nc.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/MPI/BCO_PARSIVEL2.py +15 -8
- disdrodb/l0/readers/PARSIVEL2/MPI/BOWTIE.py +9 -4
- disdrodb/l0/readers/PARSIVEL2/NASA/APU.py +31 -6
- disdrodb/l0/readers/PARSIVEL2/NASA/NSSTC.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/NCAR/FARM_PARSIVEL2.py +1 -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 +1 -1
- disdrodb/l0/readers/PARSIVEL2/NCAR/PERILS_PIPS.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/NCAR/RELAMPAGO_PARSIVEL2.py +2 -2
- 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 +1 -3
- disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_P2.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_PIPS.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/NETHERLANDS/DELFT_NC.py +1 -1
- disdrodb/l0/readers/{PARSIVEL/NASA/PIERS.py → PARSIVEL2/NORWAY/UIB.py} +65 -31
- disdrodb/l0/readers/PARSIVEL2/PHILIPPINES/PAGASA.py +7 -6
- 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 +1 -3
- disdrodb/l0/readers/PARSIVEL2/SPAIN/LIAISE.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/SWEDEN/SMHI.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/USA/CSU.py +138 -0
- disdrodb/l0/readers/PARSIVEL2/USA/CW3E.py +49 -22
- disdrodb/l0/readers/PWS100/AUSTRIA/HOAL.py +1 -3
- disdrodb/l0/readers/PWS100/FRANCE/ENPC_PWS100.py +1 -3
- disdrodb/l0/readers/PWS100/FRANCE/ENPC_PWS100_SIRTA.py +1 -1
- disdrodb/l0/readers/{PARSIVEL/NASA/IFLOODS.py → RD80/BRAZIL/ATTO_RD80.py} +50 -36
- 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 +1 -3
- disdrodb/l0/readers/{SW250 → SWS250}/BELGIUM/KMI.py +2 -4
- disdrodb/l0/readers/template_reader_raw_netcdf_data.py +1 -3
- disdrodb/l0/readers/template_reader_raw_text_data.py +1 -3
- disdrodb/l0/standards.py +4 -5
- disdrodb/l0/template_tools.py +1 -3
- disdrodb/l1/__init__.py +1 -1
- disdrodb/l1/classification.py +913 -0
- disdrodb/l1/processing.py +36 -106
- disdrodb/l1/resampling.py +8 -3
- disdrodb/l1_env/__init__.py +1 -1
- disdrodb/l1_env/routines.py +6 -6
- disdrodb/l2/__init__.py +1 -1
- disdrodb/l2/empirical_dsd.py +61 -31
- disdrodb/l2/processing.py +327 -62
- disdrodb/metadata/checks.py +1 -3
- disdrodb/metadata/download.py +4 -4
- disdrodb/metadata/geolocation.py +1 -3
- disdrodb/metadata/info.py +1 -3
- disdrodb/metadata/manipulation.py +1 -3
- disdrodb/metadata/reader.py +1 -3
- disdrodb/metadata/search.py +1 -3
- disdrodb/metadata/standards.py +1 -3
- disdrodb/metadata/writer.py +1 -3
- disdrodb/physics/__init__.py +17 -0
- disdrodb/physics/atmosphere.py +272 -0
- disdrodb/physics/water.py +130 -0
- disdrodb/physics/wrappers.py +62 -0
- disdrodb/psd/__init__.py +1 -1
- disdrodb/psd/fitting.py +22 -9
- disdrodb/psd/models.py +1 -1
- disdrodb/routines/__init__.py +5 -1
- disdrodb/routines/l0.py +28 -18
- disdrodb/routines/l1.py +8 -6
- disdrodb/routines/l2.py +8 -4
- disdrodb/routines/options.py +116 -71
- disdrodb/routines/options_validation.py +728 -0
- disdrodb/routines/wrappers.py +431 -11
- disdrodb/scattering/__init__.py +1 -1
- disdrodb/scattering/axis_ratio.py +9 -6
- disdrodb/scattering/permittivity.py +8 -8
- disdrodb/scattering/routines.py +32 -14
- disdrodb/summary/__init__.py +1 -1
- disdrodb/summary/routines.py +146 -86
- disdrodb/utils/__init__.py +1 -1
- disdrodb/utils/archiving.py +16 -9
- disdrodb/utils/attrs.py +4 -3
- disdrodb/utils/cli.py +8 -10
- disdrodb/utils/compression.py +13 -13
- disdrodb/utils/dask.py +33 -14
- disdrodb/utils/dataframe.py +1 -3
- disdrodb/utils/decorators.py +1 -3
- disdrodb/utils/dict.py +1 -1
- disdrodb/utils/directories.py +3 -5
- disdrodb/utils/encoding.py +2 -4
- disdrodb/utils/event.py +1 -1
- disdrodb/utils/list.py +1 -3
- disdrodb/utils/logger.py +1 -3
- disdrodb/utils/manipulations.py +182 -6
- disdrodb/utils/pydantic.py +80 -0
- disdrodb/utils/routines.py +1 -3
- disdrodb/utils/subsetting.py +1 -1
- disdrodb/utils/time.py +3 -2
- disdrodb/utils/warnings.py +1 -3
- disdrodb/utils/writer.py +1 -3
- disdrodb/utils/xarray.py +30 -3
- disdrodb/utils/yaml.py +1 -3
- disdrodb/viz/__init__.py +1 -1
- disdrodb/viz/plots.py +197 -21
- {disdrodb-0.2.0.dist-info → disdrodb-0.3.0.dist-info}/METADATA +2 -2
- disdrodb-0.3.0.dist-info/RECORD +358 -0
- {disdrodb-0.2.0.dist-info → disdrodb-0.3.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/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 -618
- disdrodb/l1/filters.py +0 -203
- disdrodb-0.2.0.dist-info/RECORD +0 -312
- {disdrodb-0.2.0.dist-info → disdrodb-0.3.0.dist-info}/WHEEL +0 -0
- {disdrodb-0.2.0.dist-info → disdrodb-0.3.0.dist-info}/licenses/LICENSE +0 -0
- {disdrodb-0.2.0.dist-info → disdrodb-0.3.0.dist-info}/top_level.txt +0 -0
disdrodb/l1/processing.py
CHANGED
|
@@ -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
|
|
@@ -18,35 +18,22 @@
|
|
|
18
18
|
|
|
19
19
|
import xarray as xr
|
|
20
20
|
|
|
21
|
-
from disdrodb.constants import DIAMETER_DIMENSION, VELOCITY_DIMENSION
|
|
22
|
-
from disdrodb.l1.
|
|
23
|
-
|
|
21
|
+
from disdrodb.constants import DIAMETER_DIMENSION, METEOROLOGICAL_VARIABLES, VELOCITY_DIMENSION
|
|
22
|
+
from disdrodb.l1.classification import (
|
|
23
|
+
classify_raw_spectrum,
|
|
24
|
+
get_temperature,
|
|
25
|
+
map_precip_flag_to_precipitation_type,
|
|
26
|
+
)
|
|
24
27
|
from disdrodb.l1.resampling import add_sample_interval
|
|
25
28
|
from disdrodb.l1_env.routines import load_env_dataset
|
|
26
|
-
from disdrodb.
|
|
27
|
-
add_bins_metrics,
|
|
28
|
-
get_min_max_diameter,
|
|
29
|
-
)
|
|
29
|
+
from disdrodb.utils.manipulations import filter_diameter_bins
|
|
30
30
|
from disdrodb.utils.time import ensure_sample_interval_in_seconds, infer_sample_interval
|
|
31
31
|
from disdrodb.utils.writer import finalize_product
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
def generate_l1(
|
|
35
35
|
ds,
|
|
36
|
-
#
|
|
37
|
-
fall_velocity_model="Beard1976",
|
|
38
|
-
# Diameter-Velocity Filtering Options
|
|
39
|
-
minimum_diameter=0,
|
|
40
|
-
maximum_diameter=10,
|
|
41
|
-
minimum_velocity=0,
|
|
42
|
-
maximum_velocity=12,
|
|
43
|
-
above_velocity_fraction=0.5,
|
|
44
|
-
above_velocity_tolerance=None,
|
|
45
|
-
below_velocity_fraction=0.5,
|
|
46
|
-
below_velocity_tolerance=None,
|
|
47
|
-
small_diameter_threshold=1, # 2
|
|
48
|
-
small_velocity_threshold=2.5, # 3
|
|
49
|
-
maintain_smallest_drops=True,
|
|
36
|
+
**kwargs, # noqa
|
|
50
37
|
):
|
|
51
38
|
"""Generate DISDRODB L1 Dataset from DISDRODB L0C Dataset.
|
|
52
39
|
|
|
@@ -54,31 +41,6 @@ def generate_l1(
|
|
|
54
41
|
----------
|
|
55
42
|
ds : xarray.Dataset
|
|
56
43
|
DISDRODB L0C dataset.
|
|
57
|
-
fall_velocity_model : str, optional
|
|
58
|
-
Method to compute fall velocity.
|
|
59
|
-
The default method is ``"Beard1976"``.
|
|
60
|
-
minimum_diameter : float, optional
|
|
61
|
-
Minimum diameter for filtering. The default value is 0 mm.
|
|
62
|
-
maximum_diameter : float, optional
|
|
63
|
-
Maximum diameter for filtering. The default value is 10 mm.
|
|
64
|
-
minimum_velocity : float, optional
|
|
65
|
-
Minimum velocity for filtering. The default value is 0 m/s.
|
|
66
|
-
maximum_velocity : float, optional
|
|
67
|
-
Maximum velocity for filtering. The default value is 12 m/s.
|
|
68
|
-
above_velocity_fraction : float, optional
|
|
69
|
-
Fraction of drops above velocity threshold. The default value is 0.5.
|
|
70
|
-
above_velocity_tolerance : float or None, optional
|
|
71
|
-
Tolerance for above velocity filtering. The default value is ``None``.
|
|
72
|
-
below_velocity_fraction : float, optional
|
|
73
|
-
Fraction of drops below velocity threshold. The default value is 0.5.
|
|
74
|
-
below_velocity_tolerance : float or None, optional
|
|
75
|
-
Tolerance for below velocity filtering. The default value is ``None``.
|
|
76
|
-
small_diameter_threshold : float, optional
|
|
77
|
-
Threshold for small diameter drops. The default value is 1.
|
|
78
|
-
small_velocity_threshold : float, optional
|
|
79
|
-
Threshold for small velocity drops. The default value is 2.5.
|
|
80
|
-
maintain_smallest_drops : bool, optional
|
|
81
|
-
Whether to maintain the smallest drops. The default value is ``True``.
|
|
82
44
|
|
|
83
45
|
Returns
|
|
84
46
|
-------
|
|
@@ -95,7 +57,7 @@ def generate_l1(
|
|
|
95
57
|
# - If not present, don't drop Parsivels first two bins
|
|
96
58
|
sensor_name = attrs.get("sensor_name", "")
|
|
97
59
|
|
|
98
|
-
#
|
|
60
|
+
# --------------------------------------------------------------------------
|
|
99
61
|
# Retrieve sample interval
|
|
100
62
|
# --> sample_interval is a coordinate of L0C products
|
|
101
63
|
if "sample_interval" in ds:
|
|
@@ -104,14 +66,14 @@ def generate_l1(
|
|
|
104
66
|
# This line is not called in the DISDRODB processing chain !
|
|
105
67
|
sample_interval = infer_sample_interval(ds, verbose=False)
|
|
106
68
|
|
|
107
|
-
#
|
|
69
|
+
# --------------------------------------------------------------------------
|
|
108
70
|
# Retrieve ENV dataset or take defaults
|
|
109
71
|
# - Used only for Beard fall velocity currently !
|
|
110
72
|
# - It checks and includes default geolocation if missing
|
|
111
73
|
# - For mobile disdrometer, infill missing geolocation with backward and forward filling
|
|
112
74
|
ds_env = load_env_dataset(ds)
|
|
113
75
|
|
|
114
|
-
#
|
|
76
|
+
# --------------------------------------------------------------------------
|
|
115
77
|
# Initialize L1 dataset
|
|
116
78
|
ds_l1 = xr.Dataset()
|
|
117
79
|
|
|
@@ -122,77 +84,45 @@ def generate_l1(
|
|
|
122
84
|
ds_l1 = add_sample_interval(ds_l1, sample_interval=sample_interval)
|
|
123
85
|
|
|
124
86
|
# Add optional variables to L1 dataset
|
|
125
|
-
optional_variables = ["
|
|
87
|
+
optional_variables = ["qc_time", "qc_resampling", *METEOROLOGICAL_VARIABLES]
|
|
126
88
|
for var in optional_variables:
|
|
127
89
|
if var in ds:
|
|
128
90
|
ds_l1[var] = ds[var]
|
|
129
91
|
|
|
130
|
-
#
|
|
92
|
+
# --------------------------------------------------------------------------
|
|
131
93
|
# Filter dataset by diameter and velocity bins
|
|
132
94
|
if sensor_name in ["PARSIVEL", "PARSIVEL2"]:
|
|
133
95
|
# - Remove first two bins because never reports data !
|
|
96
|
+
# - Could be removed also in L2E, but we save disk space here
|
|
134
97
|
# - If not removed, can alter e.g. L2M model fitting
|
|
135
98
|
ds_l1 = filter_diameter_bins(ds=ds_l1, minimum_diameter=0.2495) # it includes the 0.2495-0.3745 bin
|
|
136
99
|
|
|
137
|
-
#
|
|
138
|
-
|
|
139
|
-
# - Filter velocity bins
|
|
140
|
-
if has_velocity_dimension:
|
|
141
|
-
ds_l1 = filter_velocity_bins(ds=ds_l1, minimum_velocity=minimum_velocity, maximum_velocity=maximum_velocity)
|
|
142
|
-
|
|
143
|
-
# -------------------------------------------------------------------------------------------
|
|
144
|
-
# Compute fall velocity
|
|
145
|
-
ds_l1["fall_velocity"] = get_raindrop_fall_velocity_from_ds(ds=ds_l1, ds_env=ds_env, model=fall_velocity_model)
|
|
146
|
-
|
|
147
|
-
# -------------------------------------------------------------------------------------------
|
|
148
|
-
# Define filtering mask according to fall velocity
|
|
100
|
+
# --------------------------------------------------------------------------
|
|
101
|
+
# If (diameter, velocity) spectrum is available, run hydrometeor classification
|
|
149
102
|
if has_velocity_dimension:
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
103
|
+
temperature, snow_temperature_upper_limit = get_temperature(ds)
|
|
104
|
+
temperature = temperature.compute() if temperature is not None else None
|
|
105
|
+
ds_hc = classify_raw_spectrum(
|
|
106
|
+
ds=ds_l1,
|
|
107
|
+
ds_env=ds_env,
|
|
108
|
+
sensor_name=sensor_name,
|
|
109
|
+
sample_interval=sample_interval,
|
|
110
|
+
temperature=temperature,
|
|
111
|
+
rain_temperature_lower_limit=-5,
|
|
112
|
+
snow_temperature_upper_limit=snow_temperature_upper_limit,
|
|
160
113
|
)
|
|
114
|
+
ds_l1.update(ds_hc)
|
|
161
115
|
|
|
162
|
-
#
|
|
163
|
-
#
|
|
164
|
-
if has_velocity_dimension:
|
|
165
|
-
drop_number = ds_l1["raw_drop_number"].where(mask, 0) # 2D (diameter, velocity)
|
|
166
|
-
drop_counts = drop_number.sum(dim=VELOCITY_DIMENSION) # 1D (diameter)
|
|
167
|
-
drop_counts_raw = ds_l1["raw_drop_number"].sum(dim=VELOCITY_DIMENSION) # 1D (diameter)
|
|
116
|
+
# Otherwise, if no 2D spectrum, do nothing (temporary)
|
|
117
|
+
# --> Specialized QC for RD-80 or ODM-470 not yet implemented
|
|
168
118
|
else:
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
ds_l1["drop_number"] = drop_number
|
|
175
|
-
ds_l1["drop_counts"] = drop_counts
|
|
176
|
-
|
|
177
|
-
# -------------------------------------------------------------------------------------------
|
|
178
|
-
# Compute minimum and max drop diameter observed
|
|
179
|
-
min_drop_diameter, max_drop_diameter = get_min_max_diameter(drop_counts)
|
|
180
|
-
|
|
181
|
-
# Add drop statistics
|
|
182
|
-
ds_l1["Dmin"] = min_drop_diameter
|
|
183
|
-
ds_l1["Dmax"] = max_drop_diameter
|
|
184
|
-
ds_l1["N"] = drop_counts.sum(dim=DIAMETER_DIMENSION)
|
|
185
|
-
ds_l1["Nraw"] = drop_counts_raw.sum(dim=DIAMETER_DIMENSION)
|
|
186
|
-
ds_l1["Nremoved"] = ds_l1["Nraw"] - ds_l1["N"]
|
|
187
|
-
|
|
188
|
-
# Add bins statistics
|
|
189
|
-
ds_l1 = add_bins_metrics(ds_l1)
|
|
190
|
-
|
|
191
|
-
# -------------------------------------------------------------------------------------------
|
|
192
|
-
# Add quality flags
|
|
193
|
-
# TODO: snow_flags, insects_flag, ...
|
|
119
|
+
# If OceanRain ODM470 data, translate precip_flag to precipitation_type
|
|
120
|
+
if sensor_name == "ODM470" and "precip_flag" in ds:
|
|
121
|
+
ds_l1["precipitation_type"] = map_precip_flag_to_precipitation_type(ds["precip_flag"])
|
|
122
|
+
ds_l1["n_particles"] = ds_l1["raw_drop_number"].sum(dim=DIAMETER_DIMENSION)
|
|
123
|
+
pass
|
|
194
124
|
|
|
195
|
-
####
|
|
125
|
+
#### ----------------------------------------------------------------------.
|
|
196
126
|
#### Finalize dataset
|
|
197
127
|
# Add global attributes
|
|
198
128
|
ds_l1.attrs = attrs
|
disdrodb/l1/resampling.py
CHANGED
|
@@ -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
|
|
@@ -170,6 +170,9 @@ def resample_dataset(ds, sample_interval, temporal_resolution):
|
|
|
170
170
|
- The function updates the dataset attributes and the sample_interval coordinate.
|
|
171
171
|
|
|
172
172
|
"""
|
|
173
|
+
from disdrodb.constants import METEOROLOGICAL_VARIABLES
|
|
174
|
+
from disdrodb.l1.classification import TEMPERATURE_VARIABLES
|
|
175
|
+
|
|
173
176
|
# --------------------------------------------------------------------------.
|
|
174
177
|
# Ensure sample interval in seconds
|
|
175
178
|
sample_interval = int(ensure_sample_interval_in_seconds(sample_interval))
|
|
@@ -244,6 +247,7 @@ def resample_dataset(ds, sample_interval, temporal_resolution):
|
|
|
244
247
|
|
|
245
248
|
# Retrieve variables to average/sum
|
|
246
249
|
# - ATTENTION: it will not resample non-dimensional time coordinates of the dataset !
|
|
250
|
+
# - precip_flag used for OceanRain ODM470 data
|
|
247
251
|
var_to_average = ["fall_velocity"]
|
|
248
252
|
var_to_cumulate = [
|
|
249
253
|
"raw_drop_number",
|
|
@@ -255,8 +259,9 @@ def resample_dataset(ds, sample_interval, temporal_resolution):
|
|
|
255
259
|
"Nremoved",
|
|
256
260
|
"qc_resampling",
|
|
257
261
|
]
|
|
258
|
-
var_to_min = ["Dmin"]
|
|
259
|
-
|
|
262
|
+
var_to_min = ["Dmin", *TEMPERATURE_VARIABLES]
|
|
263
|
+
met_vars = set(METEOROLOGICAL_VARIABLES) - set(TEMPERATURE_VARIABLES) # exclude air_temperature variable
|
|
264
|
+
var_to_max = ["Dmax", "qc_time", "precip_flag", *met_vars]
|
|
260
265
|
|
|
261
266
|
# Retrieve available variables
|
|
262
267
|
var_to_average = [var for var in var_to_average if var in ds]
|
disdrodb/l1_env/__init__.py
CHANGED
|
@@ -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
|
disdrodb/l1_env/routines.py
CHANGED
|
@@ -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
|
|
@@ -30,15 +30,15 @@ DEFAULT_GEOLOCATION = {
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
def get_default_environment_dataset():
|
|
33
|
-
"""
|
|
33
|
+
"""Set International Standard Atmosphere values for the default ENV dataset."""
|
|
34
34
|
ds_env = xr.Dataset()
|
|
35
|
-
ds_env["sea_level_air_pressure"] = 101_325 # Pa
|
|
35
|
+
ds_env["sea_level_air_pressure"] = 101_325 # Pa # sea level
|
|
36
36
|
ds_env["gas_constant_dry_air"] = 287.04 # J kg⁻¹ K⁻¹
|
|
37
|
-
ds_env["lapse_rate"] = 0.0065 # K m⁻¹
|
|
37
|
+
ds_env["lapse_rate"] = 0.0065 # K m⁻¹ (6.5 deg/km)
|
|
38
38
|
ds_env["relative_humidity"] = 0.95 # 0-1 !
|
|
39
|
-
ds_env["temperature"] =
|
|
39
|
+
ds_env["temperature"] = 15 + 273.15 # K
|
|
40
40
|
ds_env["water_density"] = 1000 # kg m⁻³ (T == 10 --> 999.7, T == 20 --> 998.2)
|
|
41
|
-
#
|
|
41
|
+
# air density = 1.225 kg m⁻³ (if RH = 0) using retrieve_air_density(ds_env)
|
|
42
42
|
return ds_env
|
|
43
43
|
|
|
44
44
|
|
disdrodb/l2/__init__.py
CHANGED
|
@@ -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
|
disdrodb/l2/empirical_dsd.py
CHANGED
|
@@ -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
|
|
@@ -25,6 +25,7 @@ import xarray as xr
|
|
|
25
25
|
|
|
26
26
|
from disdrodb.api.checks import check_sensor_name
|
|
27
27
|
from disdrodb.constants import DIAMETER_DIMENSION, VELOCITY_DIMENSION
|
|
28
|
+
from disdrodb.utils.time import ensure_sample_interval_in_seconds
|
|
28
29
|
from disdrodb.utils.xarray import (
|
|
29
30
|
remove_diameter_coordinates,
|
|
30
31
|
remove_velocity_coordinates,
|
|
@@ -208,8 +209,26 @@ def add_bins_metrics(ds):
|
|
|
208
209
|
return ds
|
|
209
210
|
|
|
210
211
|
|
|
211
|
-
|
|
212
|
-
####
|
|
212
|
+
####------------------------------------------------------------------------------------------.
|
|
213
|
+
#### Sampling area and measurement interval
|
|
214
|
+
def get_sampling_area(sensor_name):
|
|
215
|
+
"""Return the sampling area in m2 of the disdrometer."""
|
|
216
|
+
check_sensor_name(sensor_name)
|
|
217
|
+
area_dict = {
|
|
218
|
+
"PARSIVEL": 0.0054, # 54 cm2
|
|
219
|
+
"PARSIVEL2": 0.0054, # 54 cm2
|
|
220
|
+
"LPM": 0.0045, # 45 cm2
|
|
221
|
+
"LPM_V0": 0.0045, # 45 cm2
|
|
222
|
+
"ODM470": 0.00264, # 26.4 cm2
|
|
223
|
+
"PWS100": 0.004, # 40 cm2
|
|
224
|
+
"RD80": 0.005, # 50 cm2
|
|
225
|
+
"SWS250": 0.006504, # 65.04 cm2 (Ricardo Reinoso Rondinel, personal communication)
|
|
226
|
+
}
|
|
227
|
+
# SWS250
|
|
228
|
+
# - Table 29 of the manual that the sample volume is 400cm3, path length?
|
|
229
|
+
# - Distance between the end of the hood heaters is 291 mm.
|
|
230
|
+
# - Adding a factor of 1.5 for better representation of the Tx-Rx distance: L= 436 mm.
|
|
231
|
+
return area_dict[sensor_name]
|
|
213
232
|
|
|
214
233
|
|
|
215
234
|
def get_effective_sampling_area(sensor_name, diameter):
|
|
@@ -220,29 +239,29 @@ def get_effective_sampling_area(sensor_name, diameter):
|
|
|
220
239
|
check_sensor_name(sensor_name)
|
|
221
240
|
if sensor_name in ["PARSIVEL", "PARSIVEL2"]:
|
|
222
241
|
# Calculate sampling area for each diameter bin (S_i)
|
|
242
|
+
# - Parsivel remove margin fallers !
|
|
243
|
+
# - The effective sampling area decreases with increasing drop diameter
|
|
244
|
+
# sampling_area = 0.0054 # m2
|
|
223
245
|
L = 180 / 1000 # Length of the Parsivel beam in m (180 mm)
|
|
224
246
|
B = 30 / 1000 # Width of the Parsivel beam in m (30mm)
|
|
225
|
-
sampling_area = L * (B - diameter / 2)
|
|
226
|
-
return sampling_area
|
|
227
|
-
if sensor_name == "LPM":
|
|
228
|
-
# Calculate sampling area for each diameter bin (S_i)
|
|
229
|
-
L = 228 / 1000 # Length of the Parsivel beam in m (228 mm)
|
|
230
|
-
B = 20 / 1000 # Width of the Parsivel beam in m (20 mm)
|
|
231
|
-
sampling_area = L * (B - diameter / 2)
|
|
247
|
+
sampling_area = L * (B - diameter / 2) # d_eq
|
|
232
248
|
return sampling_area
|
|
249
|
+
return get_sampling_area(sensor_name)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def get_effective_sampling_interval(ds, sensor_name):
|
|
253
|
+
"""Return the effective sample interval in seconds of the disdrometer."""
|
|
254
|
+
sample_interval = ensure_sample_interval_in_seconds(ds["sample_interval"]) # s
|
|
255
|
+
# Adapt sample interval for sensor duty cycle
|
|
233
256
|
if sensor_name == "PWS100":
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
# Adding a factor of 1.5 for better representation of the Tx-Rx distance: L= 436 mm.
|
|
243
|
-
sampling_area = 0.0091 # m2
|
|
244
|
-
return sampling_area
|
|
245
|
-
raise NotImplementedError(f"Effective sampling area for {sensor_name} must yet to be specified in the software.")
|
|
257
|
+
# PWS100 has a duty cycle of 9s on, 1s off
|
|
258
|
+
# - 9 seconds out of 10 are used for counting drops, 1 second is used to process data
|
|
259
|
+
sample_interval = sample_interval * (9 / 10)
|
|
260
|
+
return sample_interval
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
####-------------------------------------------------------------------------------------------------------------------.
|
|
264
|
+
#### DSD Spectrum, Concentration, Moments
|
|
246
265
|
|
|
247
266
|
|
|
248
267
|
def get_bin_dimensions(xr_obj):
|
|
@@ -303,15 +322,19 @@ def get_drop_number_concentration(drop_number, velocity, diameter_bin_width, sam
|
|
|
303
322
|
# Ensure velocity is 2D (diameter, velocity)
|
|
304
323
|
velocity = xr.ones_like(drop_number) * velocity
|
|
305
324
|
|
|
325
|
+
# Create a safe ratio: drop_number / velocity, but 0 where velocity is 0 or NaN
|
|
326
|
+
safe_ratio = drop_number / velocity
|
|
327
|
+
safe_ratio = safe_ratio.where((velocity != 0) & (~np.isnan(velocity)), 0)
|
|
328
|
+
|
|
306
329
|
# Compute drop number concentration
|
|
307
330
|
# - For disdrometer with velocity bins
|
|
308
331
|
if VELOCITY_DIMENSION in drop_number.dims:
|
|
309
|
-
drop_number_concentration =
|
|
332
|
+
drop_number_concentration = safe_ratio.sum(dim=VELOCITY_DIMENSION, skipna=False) / (
|
|
310
333
|
sampling_area * diameter_bin_width * sample_interval
|
|
311
334
|
)
|
|
312
335
|
# - For impact disdrometers
|
|
313
336
|
else:
|
|
314
|
-
drop_number_concentration =
|
|
337
|
+
drop_number_concentration = safe_ratio / (sampling_area * diameter_bin_width * sample_interval)
|
|
315
338
|
return drop_number_concentration
|
|
316
339
|
|
|
317
340
|
|
|
@@ -1665,8 +1688,7 @@ def get_kinetic_energy_variables_from_drop_number(
|
|
|
1665
1688
|
KEF = TKE / sample_interval * 3600
|
|
1666
1689
|
|
|
1667
1690
|
# Compute Kinetic Energy per Rainfall Depth [J/m2/mm]
|
|
1668
|
-
KED = KEF / R
|
|
1669
|
-
KED = xr.where(R == 0, 0, KED) # Ensure KED is 0 when R (and thus drop number is 0)
|
|
1691
|
+
KED = xr.where(R == 0, 0, KEF / R) # Ensure KED is 0 when R (and thus drop number is 0)
|
|
1670
1692
|
|
|
1671
1693
|
# Create dataset
|
|
1672
1694
|
dict_vars = {
|
|
@@ -1731,6 +1753,10 @@ def compute_integral_parameters(
|
|
|
1731
1753
|
- KED: Kinetic Energy per unit rainfall Depth [J·m⁻²·mm⁻¹].
|
|
1732
1754
|
- KEF: Kinetic Energy Flux [J·m⁻²·h⁻¹].
|
|
1733
1755
|
"""
|
|
1756
|
+
# Ensure velocity does not contain NaN
|
|
1757
|
+
# --> e.g. when D > 10 mm --> Replace to 0
|
|
1758
|
+
velocity = velocity.fillna(0)
|
|
1759
|
+
|
|
1734
1760
|
# Initialize dataset
|
|
1735
1761
|
ds = xr.Dataset()
|
|
1736
1762
|
|
|
@@ -1760,15 +1786,15 @@ def compute_integral_parameters(
|
|
|
1760
1786
|
moment=moment,
|
|
1761
1787
|
)
|
|
1762
1788
|
|
|
1763
|
-
# Compute Liquid Water Content (LWC)
|
|
1764
|
-
# ds["
|
|
1789
|
+
# Compute Liquid Water Content (LWC) [g/m3]
|
|
1790
|
+
# ds["LWC"] = get_liquid_water_content(
|
|
1765
1791
|
# drop_number_concentration=drop_number_concentration,
|
|
1766
1792
|
# diameter=diameter,
|
|
1767
1793
|
# diameter_bin_width=diameter_bin_width,
|
|
1768
1794
|
# water_density=water_density,
|
|
1769
1795
|
# )
|
|
1770
1796
|
|
|
1771
|
-
ds["
|
|
1797
|
+
ds["LWC"] = get_liquid_water_content_from_moments(moment_3=ds["M3"], water_density=water_density)
|
|
1772
1798
|
|
|
1773
1799
|
# Compute reflectivity in dBZ
|
|
1774
1800
|
ds["Z"] = get_equivalent_reflectivity_factor(
|
|
@@ -1865,9 +1891,13 @@ def compute_spectrum_parameters(
|
|
|
1865
1891
|
Dataset containing the following spectrum:
|
|
1866
1892
|
- KE_spectrum : Kinetic Energy spectrum [J/m2/mm]
|
|
1867
1893
|
- R_spectrum : Rain Rate spectrum [mm/h/mm]
|
|
1868
|
-
-
|
|
1894
|
+
- LWC_spectrum : Mass spectrum [g/m3/mm]
|
|
1869
1895
|
- Z_spectrum : Reflectivity spectrum [dBZ of mm6/m3/mm]
|
|
1870
1896
|
"""
|
|
1897
|
+
# Ensure velocity does not contain NaN
|
|
1898
|
+
# --> e.g. when D > 10 mm --> Replace to 0
|
|
1899
|
+
velocity = velocity.fillna(0)
|
|
1900
|
+
|
|
1871
1901
|
# Initialize dataset
|
|
1872
1902
|
ds = xr.Dataset()
|
|
1873
1903
|
ds["KE_spectrum"] = get_kinetic_energy_spectrum(
|
|
@@ -1878,7 +1908,7 @@ def compute_spectrum_parameters(
|
|
|
1878
1908
|
water_density=water_density,
|
|
1879
1909
|
)
|
|
1880
1910
|
ds["R_spectrum"] = get_rain_rate_spectrum(drop_number_concentration, velocity=velocity, diameter=diameter)
|
|
1881
|
-
ds["
|
|
1911
|
+
ds["LWC_spectrum"] = get_liquid_water_spectrum(
|
|
1882
1912
|
drop_number_concentration,
|
|
1883
1913
|
diameter=diameter,
|
|
1884
1914
|
water_density=water_density,
|