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/scattering/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
|
|
@@ -26,7 +26,6 @@ import xarray as xr
|
|
|
26
26
|
|
|
27
27
|
from disdrodb.configs import get_scattering_table_dir
|
|
28
28
|
from disdrodb.constants import DIAMETER_DIMENSION
|
|
29
|
-
from disdrodb.l1.filters import filter_diameter_bins
|
|
30
29
|
from disdrodb.psd.models import BinnedPSD, create_psd, get_required_parameters
|
|
31
30
|
from disdrodb.scattering.axis_ratio import check_axis_ratio_model, get_axis_ratio_model
|
|
32
31
|
from disdrodb.scattering.permittivity import (
|
|
@@ -35,7 +34,7 @@ from disdrodb.scattering.permittivity import (
|
|
|
35
34
|
get_refractive_index,
|
|
36
35
|
)
|
|
37
36
|
from disdrodb.utils.logger import log_info
|
|
38
|
-
from disdrodb.utils.manipulations import get_diameter_bin_edges
|
|
37
|
+
from disdrodb.utils.manipulations import filter_diameter_bins, get_diameter_bin_edges
|
|
39
38
|
from disdrodb.utils.warnings import suppress_warnings
|
|
40
39
|
|
|
41
40
|
logger = logging.getLogger(__name__)
|
|
@@ -76,15 +75,26 @@ def check_radar_band(radar_band):
|
|
|
76
75
|
return radar_band
|
|
77
76
|
|
|
78
77
|
|
|
78
|
+
def _is_valid_numeric_frequency(frequency):
|
|
79
|
+
numeric_value = float(frequency)
|
|
80
|
+
if numeric_value <= 0:
|
|
81
|
+
raise ValueError(f"Frequency must be positive, got {numeric_value}")
|
|
82
|
+
return numeric_value
|
|
83
|
+
|
|
84
|
+
|
|
79
85
|
def _check_frequency(frequency):
|
|
80
86
|
"""Check the validity of the specified frequency."""
|
|
81
87
|
if isinstance(frequency, str):
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
try:
|
|
89
|
+
frequency = float(frequency)
|
|
90
|
+
|
|
91
|
+
except ValueError:
|
|
92
|
+
# Not numeric, assume radar band name
|
|
93
|
+
frequency = check_radar_band(frequency)
|
|
94
|
+
frequency = frequency_dict[frequency]
|
|
95
|
+
if isinstance(frequency, (int, float)):
|
|
96
|
+
return _is_valid_numeric_frequency(frequency)
|
|
97
|
+
raise TypeError(f"Frequency {frequency} must be a string or a number.")
|
|
88
98
|
|
|
89
99
|
|
|
90
100
|
def ensure_numerical_frequency(frequency):
|
|
@@ -476,6 +486,11 @@ def compute_radar_variables(scatterer):
|
|
|
476
486
|
|
|
477
487
|
To speed up computations, this function should input a scatterer object with
|
|
478
488
|
a preinitialized scattering table.
|
|
489
|
+
|
|
490
|
+
Note
|
|
491
|
+
----
|
|
492
|
+
If this function is modified to compute additional radar variables, the global
|
|
493
|
+
variable RADAR_VARIABLES must be updated accordingly !
|
|
479
494
|
"""
|
|
480
495
|
from pytmatrix import radar
|
|
481
496
|
|
|
@@ -495,10 +510,13 @@ def compute_radar_variables(scatterer):
|
|
|
495
510
|
radar_vars["ZDR"] = 10 * np.log10(radar.Zdr(scatterer)) # dB
|
|
496
511
|
radar_vars["ZDR"] = np.where(np.isfinite(radar_vars["ZDR"]), radar_vars["ZDR"], np.nan)
|
|
497
512
|
|
|
498
|
-
radar_vars["
|
|
499
|
-
radar_vars["
|
|
513
|
+
radar_vars["LDRH"] = 10 * np.log10(radar.ldr(scatterer, h_pol=True)) # dBZ
|
|
514
|
+
radar_vars["LDRH"] = np.where(np.isfinite(radar_vars["LDRH"]), radar_vars["LDRH"], np.nan)
|
|
515
|
+
|
|
516
|
+
radar_vars["LDRV"] = 10 * np.log10(radar.ldr(scatterer, h_pol=False)) # dBZ
|
|
517
|
+
radar_vars["LDRV"] = np.where(np.isfinite(radar_vars["LDRV"]), radar_vars["LDRV"], np.nan)
|
|
500
518
|
|
|
501
|
-
radar_vars["RHOHV"] = radar.rho_hv(scatterer) #
|
|
519
|
+
radar_vars["RHOHV"] = radar.rho_hv(scatterer) # [-]
|
|
502
520
|
radar_vars["DELTAHV"] = radar.delta_hv(scatterer) * 180.0 / np.pi # [deg]
|
|
503
521
|
|
|
504
522
|
# Set forward scattering for attenuation and phase calculations
|
|
@@ -512,7 +530,7 @@ def compute_radar_variables(scatterer):
|
|
|
512
530
|
|
|
513
531
|
# Radar variables computed by DISDRODB
|
|
514
532
|
# - Must reflect dictionary order output of compute_radar_variables
|
|
515
|
-
RADAR_VARIABLES = ["DBZH", "DBZV", "ZDR", "
|
|
533
|
+
RADAR_VARIABLES = ["DBZH", "DBZV", "ZDR", "LDRH", "LDRV", "RHOHV", "DELTAHV", "KDP", "AH", "AV", "ADP"]
|
|
516
534
|
|
|
517
535
|
|
|
518
536
|
def _try_compute_radar_variables(scatterer):
|
|
@@ -973,7 +991,7 @@ def get_radar_parameters(
|
|
|
973
991
|
list_ds = [func(ds_subset, **params) for params in list_params]
|
|
974
992
|
|
|
975
993
|
# Merge into a single dataset
|
|
976
|
-
ds_radar = xr.merge(list_ds)
|
|
994
|
+
ds_radar = xr.merge(list_ds, compat="no_conflicts", join="outer")
|
|
977
995
|
|
|
978
996
|
# Order frequency from lowest to highest
|
|
979
997
|
# --> ['S', 'C', 'X', 'Ku', 'K', 'Ka', 'W']
|
disdrodb/summary/__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/summary/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
|
|
@@ -223,6 +223,11 @@ def create_table_rain_summary(df, temporal_resolution):
|
|
|
223
223
|
table["n_minutes_Dmax_>7"] = np.sum(df["Dmax"] > 7).item() * accumulation_interval_minutes
|
|
224
224
|
table["n_minutes_Dmax_>8"] = np.sum(df["Dmax"] > 8).item() * accumulation_interval_minutes
|
|
225
225
|
table["n_minutes_Dmax_>9"] = np.sum(df["Dmax"] > 9).item() * accumulation_interval_minutes
|
|
226
|
+
|
|
227
|
+
# Convert all minutes columns to integer
|
|
228
|
+
for key in table:
|
|
229
|
+
if "minutes" in key:
|
|
230
|
+
table[key] = int(table[key])
|
|
226
231
|
return table
|
|
227
232
|
|
|
228
233
|
|
|
@@ -233,7 +238,7 @@ def create_table_dsd_summary(df):
|
|
|
233
238
|
df["log10(Nt)"] = np.log10(df["Nt"])
|
|
234
239
|
|
|
235
240
|
# List of variables to summarize
|
|
236
|
-
variables = ["
|
|
241
|
+
variables = ["LWC", "R", "Z", "D50", "Dm", "sigma_m", "Dmax", "Nw", "log10(Nw)", "Nt", "log10(Nt)"]
|
|
237
242
|
|
|
238
243
|
# Define subset dataframe
|
|
239
244
|
df_subset = df[variables]
|
|
@@ -356,9 +361,9 @@ def create_table_events_summary(df, temporal_resolution):
|
|
|
356
361
|
"mean_sigma_m": df_event["sigma_m"].mean(),
|
|
357
362
|
"median_sigma_m": df_event["sigma_m"].median(),
|
|
358
363
|
"max_sigma_m": df_event["sigma_m"].max(),
|
|
359
|
-
"
|
|
360
|
-
"
|
|
361
|
-
"
|
|
364
|
+
"mean_LWC": df_event["LWC"].mean(),
|
|
365
|
+
"median_LWC": df_event["LWC"].median(),
|
|
366
|
+
"max_LWC": df_event["LWC"].max(),
|
|
362
367
|
"max_Z": df_event["Z"].max(),
|
|
363
368
|
"mean_Nbins": int(df_event["Nbins"].mean()),
|
|
364
369
|
"max_Nbins": int(df_event["Nbins"].max()),
|
|
@@ -371,9 +376,22 @@ def create_table_events_summary(df, temporal_resolution):
|
|
|
371
376
|
|
|
372
377
|
df_events = pd.DataFrame.from_records(events_stats)
|
|
373
378
|
|
|
374
|
-
# Round
|
|
375
|
-
|
|
376
|
-
df_events[
|
|
379
|
+
# Round and cast columns
|
|
380
|
+
# - Round to 3 decimals
|
|
381
|
+
df_events["P_total"] = df_events["P_total"].round(decimals=3)
|
|
382
|
+
|
|
383
|
+
lwc_columns = [c for c in df_events.columns if "LWC" in c]
|
|
384
|
+
df_events[lwc_columns] = df_events[lwc_columns].round(decimals=3)
|
|
385
|
+
|
|
386
|
+
# - Cast to integer
|
|
387
|
+
df_events["duration"] = df_events["duration"].astype(int)
|
|
388
|
+
minutes_columns = [c for c in df_events.columns if "minutes" in c]
|
|
389
|
+
df_events[minutes_columns] = df_events[minutes_columns].astype(int)
|
|
390
|
+
|
|
391
|
+
# - Round to 2 decimals
|
|
392
|
+
for var in ["Dmax", "Dm", "sigma_m", "R", "Z"]:
|
|
393
|
+
names = [c for c in df_events.columns if var in c]
|
|
394
|
+
df_events[names] = df_events[names].round(decimals=2)
|
|
377
395
|
return df_events
|
|
378
396
|
|
|
379
397
|
|
|
@@ -385,7 +403,7 @@ def prepare_latex_table_dsd_summary(df):
|
|
|
385
403
|
df[numeric_cols] = df[numeric_cols].astype(str)
|
|
386
404
|
# Rename
|
|
387
405
|
rename_dict = {
|
|
388
|
-
"
|
|
406
|
+
"LWC": r"$LWC\,[\mathrm{g}\,\mathrm{m}^{-3}]$", # [g/m3]
|
|
389
407
|
"R": r"$R\,[\mathrm{mm}\,\mathrm{h}^{-1}]$", # [mm/hr]
|
|
390
408
|
"Z": r"$Z\,[\mathrm{dBZ}]$", # [dBZ]
|
|
391
409
|
"D50": r"$D_{50}\,[\mathrm{mm}]$", # [mm]
|
|
@@ -433,9 +451,9 @@ def prepare_latex_table_events_summary(df):
|
|
|
433
451
|
"mean_sigma_m": r"$\sigma_{m,\mathrm{mean}}$",
|
|
434
452
|
"median_sigma_m": r"$\sigma_{m,\mathrm{median}}$",
|
|
435
453
|
"max_sigma_m": r"$\sigma_{m,\max}$",
|
|
436
|
-
"
|
|
437
|
-
"
|
|
438
|
-
"
|
|
454
|
+
"mean_LWC": r"$LWC_{\mathrm{mean}}$",
|
|
455
|
+
"median_LWC": r"$LWC_{\mathrm{median}}$",
|
|
456
|
+
"max_LWC": r"$LWC_{\max}$",
|
|
439
457
|
"max_Z": r"$Z_{\max}$",
|
|
440
458
|
"mean_Nbins": r"$N_{\mathrm{bins},\mathrm{mean}}$",
|
|
441
459
|
"max_Nbins": r"$N_{\mathrm{bins},\max}$",
|
|
@@ -716,7 +734,7 @@ def create_nd_dataframe(ds, variables=None):
|
|
|
716
734
|
"sample_interval",
|
|
717
735
|
*RADAR_OPTIONS,
|
|
718
736
|
]
|
|
719
|
-
df_nd = ds_stack.
|
|
737
|
+
df_nd = ds_stack.to_dask_dataframe().drop(columns=coords_to_drop, errors="ignore").compute()
|
|
720
738
|
df_nd["D"] = df_nd["diameter_bin_center"]
|
|
721
739
|
df_nd["N(D)"] = df_nd["drop_number_concentration"]
|
|
722
740
|
df_nd = df_nd[df_nd["R"] != 0]
|
|
@@ -918,7 +936,7 @@ def plot_dsd_params_relationships(df, add_nt=False, dpi=300):
|
|
|
918
936
|
df,
|
|
919
937
|
x="Dm",
|
|
920
938
|
y="Nw",
|
|
921
|
-
variables=["R", "
|
|
939
|
+
variables=["R", "LWC", "Nt"],
|
|
922
940
|
x_bins=np.arange(0, 8, 0.1),
|
|
923
941
|
y_bins=log_arange(10, 1_000_000, log_step=0.05, base=10),
|
|
924
942
|
)
|
|
@@ -927,7 +945,7 @@ def plot_dsd_params_relationships(df, add_nt=False, dpi=300):
|
|
|
927
945
|
ds_Dm_LWC_stats = compute_2d_histogram(
|
|
928
946
|
df,
|
|
929
947
|
x="Dm",
|
|
930
|
-
y="
|
|
948
|
+
y="LWC",
|
|
931
949
|
variables=["R", "Nw", "Nt"],
|
|
932
950
|
x_bins=np.arange(0, 8, 0.1),
|
|
933
951
|
y_bins=log_arange(0.01, 10, log_step=0.05, base=10),
|
|
@@ -938,7 +956,7 @@ def plot_dsd_params_relationships(df, add_nt=False, dpi=300):
|
|
|
938
956
|
df,
|
|
939
957
|
x="Dm",
|
|
940
958
|
y="R",
|
|
941
|
-
variables=["Nw", "
|
|
959
|
+
variables=["Nw", "LWC", "Nt"],
|
|
942
960
|
x_bins=np.arange(0, 8, 0.1),
|
|
943
961
|
y_bins=log_arange(0.1, 500, log_step=0.05, base=10),
|
|
944
962
|
)
|
|
@@ -948,7 +966,7 @@ def plot_dsd_params_relationships(df, add_nt=False, dpi=300):
|
|
|
948
966
|
df,
|
|
949
967
|
x="Dm",
|
|
950
968
|
y="Nt",
|
|
951
|
-
variables=["R", "
|
|
969
|
+
variables=["R", "LWC", "Nw"],
|
|
952
970
|
x_bins=np.arange(0, 8, 0.1),
|
|
953
971
|
y_bins=log_arange(1, 100_000, log_step=0.05, base=10),
|
|
954
972
|
)
|
|
@@ -1019,7 +1037,7 @@ def plot_dsd_params_relationships(df, add_nt=False, dpi=300):
|
|
|
1019
1037
|
axes[1, 0].set_ylim(nw_lim)
|
|
1020
1038
|
|
|
1021
1039
|
#### - LWC
|
|
1022
|
-
im_lwc = ds_Dm_Nw_stats["
|
|
1040
|
+
im_lwc = ds_Dm_Nw_stats["LWC_median"].plot.pcolormesh(
|
|
1023
1041
|
x="Dm",
|
|
1024
1042
|
y="Nw",
|
|
1025
1043
|
cmap=cmap_lwc,
|
|
@@ -1067,7 +1085,7 @@ def plot_dsd_params_relationships(df, add_nt=False, dpi=300):
|
|
|
1067
1085
|
#### - Counts
|
|
1068
1086
|
ds_Dm_LWC_stats["count"].plot.pcolormesh(
|
|
1069
1087
|
x="Dm",
|
|
1070
|
-
y="
|
|
1088
|
+
y="LWC",
|
|
1071
1089
|
cmap=cmap_counts,
|
|
1072
1090
|
norm=norm_counts,
|
|
1073
1091
|
extend="max",
|
|
@@ -1083,7 +1101,7 @@ def plot_dsd_params_relationships(df, add_nt=False, dpi=300):
|
|
|
1083
1101
|
# - Empty (diagonal where y-axis is W) - handled above in the loop
|
|
1084
1102
|
ds_Dm_LWC_stats["R_median"].plot.pcolormesh(
|
|
1085
1103
|
x="Dm",
|
|
1086
|
-
y="
|
|
1104
|
+
y="LWC",
|
|
1087
1105
|
cmap=cmap_r,
|
|
1088
1106
|
norm=norm_r,
|
|
1089
1107
|
alpha=0, # fully transparent
|
|
@@ -1099,7 +1117,7 @@ def plot_dsd_params_relationships(df, add_nt=False, dpi=300):
|
|
|
1099
1117
|
#### - R
|
|
1100
1118
|
ds_Dm_LWC_stats["R_median"].plot.pcolormesh(
|
|
1101
1119
|
x="Dm",
|
|
1102
|
-
y="
|
|
1120
|
+
y="LWC",
|
|
1103
1121
|
cmap=cmap_r,
|
|
1104
1122
|
norm=norm_r,
|
|
1105
1123
|
extend="both",
|
|
@@ -1114,7 +1132,7 @@ def plot_dsd_params_relationships(df, add_nt=False, dpi=300):
|
|
|
1114
1132
|
#### - Nt
|
|
1115
1133
|
im_nt = ds_Dm_LWC_stats["Nt_median"].plot.pcolormesh(
|
|
1116
1134
|
x="Dm",
|
|
1117
|
-
y="
|
|
1135
|
+
y="LWC",
|
|
1118
1136
|
cmap=cmap_nt,
|
|
1119
1137
|
norm=norm_nt,
|
|
1120
1138
|
extend="both",
|
|
@@ -1144,7 +1162,7 @@ def plot_dsd_params_relationships(df, add_nt=False, dpi=300):
|
|
|
1144
1162
|
axes[3, 0].set_ylim(r_lim)
|
|
1145
1163
|
|
|
1146
1164
|
#### - LWC
|
|
1147
|
-
im_lwc = ds_Dm_R_stats["
|
|
1165
|
+
im_lwc = ds_Dm_R_stats["LWC_median"].plot.pcolormesh(
|
|
1148
1166
|
x="Dm",
|
|
1149
1167
|
y="R",
|
|
1150
1168
|
cmap=cmap_lwc,
|
|
@@ -1211,7 +1229,7 @@ def plot_dsd_params_relationships(df, add_nt=False, dpi=300):
|
|
|
1211
1229
|
axes[4, 0].set_ylim(nt_lim)
|
|
1212
1230
|
|
|
1213
1231
|
#### - LWC
|
|
1214
|
-
ds_Dm_Nt_stats["
|
|
1232
|
+
ds_Dm_Nt_stats["LWC_median"].plot.pcolormesh(
|
|
1215
1233
|
x="Dm",
|
|
1216
1234
|
y="Nt",
|
|
1217
1235
|
cmap=cmap_lwc,
|
|
@@ -1336,7 +1354,7 @@ def plot_dsd_params_density(df, log_dm=False, lwc=True, log_normalize=False, fig
|
|
|
1336
1354
|
norm = Normalize(0, 1) # Normalized data goes from 0 to 1
|
|
1337
1355
|
|
|
1338
1356
|
# Define the water variable based on lwc flag
|
|
1339
|
-
df["LWC"] = df["
|
|
1357
|
+
df["LWC"] = df["LWC"]
|
|
1340
1358
|
water_var = "LWC" if lwc else "R"
|
|
1341
1359
|
water_label = "LWC [g/m³]" if lwc else "R [mm/h]"
|
|
1342
1360
|
|
|
@@ -3742,7 +3760,7 @@ def create_l2_dataframe(ds):
|
|
|
3742
3760
|
return df
|
|
3743
3761
|
|
|
3744
3762
|
|
|
3745
|
-
def prepare_summary_dataset(ds, velocity_method="
|
|
3763
|
+
def prepare_summary_dataset(ds, velocity_method="theoretical_velocity", source="drop_number"):
|
|
3746
3764
|
"""Prepare the L2E or L2M dataset to be converted to a dataframe."""
|
|
3747
3765
|
# Select fall velocity method
|
|
3748
3766
|
if "velocity_method" in ds.dims:
|
|
@@ -3789,70 +3807,72 @@ def generate_station_summary(ds, summary_dir_path, data_source, campaign_name, s
|
|
|
3789
3807
|
|
|
3790
3808
|
####---------------------------------------------------------------------.
|
|
3791
3809
|
#### Create drop spectrum figures and statistics
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3810
|
+
if VELOCITY_DIMENSION in ds.dims:
|
|
3811
|
+
# Compute sum of raw and filtered spectrum over time
|
|
3812
|
+
raw_drop_number = ds["raw_drop_number"].sum(dim="time")
|
|
3813
|
+
drop_number = ds["drop_number"].sum(dim="time")
|
|
3814
|
+
|
|
3815
|
+
# Define theoretical and measured average velocity
|
|
3816
|
+
theoretical_average_velocity = ds["fall_velocity"].mean(dim="time")
|
|
3817
|
+
measured_average_velocity = get_drop_average_velocity(drop_number)
|
|
3818
|
+
|
|
3819
|
+
# Save raw and filtered spectrum over time & theoretical and measured average fall velocity
|
|
3820
|
+
ds_stats = xr.Dataset()
|
|
3821
|
+
ds_stats["raw_drop_number"] = raw_drop_number
|
|
3822
|
+
ds_stats["drop_number"] = raw_drop_number
|
|
3823
|
+
ds_stats["theoretical_average_velocity"] = theoretical_average_velocity
|
|
3824
|
+
if measured_average_velocity is not None:
|
|
3825
|
+
ds_stats["measured_average_velocity"] = measured_average_velocity
|
|
3826
|
+
filename = define_filename(
|
|
3827
|
+
prefix="SpectrumStats",
|
|
3828
|
+
extension="nc",
|
|
3829
|
+
data_source=data_source,
|
|
3830
|
+
campaign_name=campaign_name,
|
|
3831
|
+
station_name=station_name,
|
|
3832
|
+
temporal_resolution=temporal_resolution,
|
|
3833
|
+
)
|
|
3834
|
+
ds_stats.to_netcdf(os.path.join(summary_dir_path, filename))
|
|
3815
3835
|
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3836
|
+
# Create figures with raw and filtered spectrum
|
|
3837
|
+
# - Raw
|
|
3838
|
+
filename = define_filename(
|
|
3839
|
+
prefix="SpectrumRaw",
|
|
3840
|
+
extension="png",
|
|
3841
|
+
data_source=data_source,
|
|
3842
|
+
campaign_name=campaign_name,
|
|
3843
|
+
station_name=station_name,
|
|
3844
|
+
temporal_resolution=temporal_resolution,
|
|
3845
|
+
)
|
|
3846
|
+
p = plot_spectrum(raw_drop_number, title="Raw Drop Spectrum")
|
|
3847
|
+
p.figure.savefig(os.path.join(summary_dir_path, filename))
|
|
3848
|
+
plt.close()
|
|
3829
3849
|
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3850
|
+
# - Filtered
|
|
3851
|
+
filename = define_filename(
|
|
3852
|
+
prefix="SpectrumFiltered",
|
|
3853
|
+
extension="png",
|
|
3854
|
+
data_source=data_source,
|
|
3855
|
+
campaign_name=campaign_name,
|
|
3856
|
+
station_name=station_name,
|
|
3857
|
+
temporal_resolution=temporal_resolution,
|
|
3858
|
+
)
|
|
3859
|
+
p = plot_spectrum(drop_number, title="Filtered Drop Spectrum")
|
|
3860
|
+
p.figure.savefig(os.path.join(summary_dir_path, filename))
|
|
3861
|
+
plt.close()
|
|
3842
3862
|
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3863
|
+
# Create figure comparing raw and filtered spectrum
|
|
3864
|
+
filename = define_filename(
|
|
3865
|
+
prefix="SpectrumSummary",
|
|
3866
|
+
extension="png",
|
|
3867
|
+
data_source=data_source,
|
|
3868
|
+
campaign_name=campaign_name,
|
|
3869
|
+
station_name=station_name,
|
|
3870
|
+
temporal_resolution=temporal_resolution,
|
|
3871
|
+
)
|
|
3852
3872
|
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3873
|
+
fig = plot_raw_and_filtered_spectra(ds)
|
|
3874
|
+
fig.savefig(os.path.join(summary_dir_path, filename))
|
|
3875
|
+
plt.close()
|
|
3856
3876
|
|
|
3857
3877
|
####---------------------------------------------------------------------.
|
|
3858
3878
|
#### Create L2E dataframe
|
|
@@ -3907,6 +3927,7 @@ def generate_station_summary(ds, summary_dir_path, data_source, campaign_name, s
|
|
|
3907
3927
|
table_events_summary.to_csv(table_events_summary_csv_filepath)
|
|
3908
3928
|
# - Save table as pdf
|
|
3909
3929
|
if is_latex_engine_available():
|
|
3930
|
+
# Sorted by time
|
|
3910
3931
|
table_events_summary_pdf_filename = table_events_summary_csv_filename.replace(".csv", ".pdf")
|
|
3911
3932
|
table_events_summary_pdf_filepath = os.path.join(summary_dir_path, table_events_summary_pdf_filename)
|
|
3912
3933
|
save_table_to_pdf(
|
|
@@ -3917,6 +3938,45 @@ def generate_station_summary(ds, summary_dir_path, data_source, campaign_name, s
|
|
|
3917
3938
|
orientation="landscape",
|
|
3918
3939
|
)
|
|
3919
3940
|
|
|
3941
|
+
# Sorted by maximum rain intensity
|
|
3942
|
+
table_events_summary = table_events_summary.sort_values(by="max_R", ascending=False)
|
|
3943
|
+
table_events_summary = table_events_summary.reset_index(drop=True)
|
|
3944
|
+
table_events_summary_pdf_filename = define_filename(
|
|
3945
|
+
prefix="Events_Summary_Sorted_By_Rmax",
|
|
3946
|
+
extension="pdf",
|
|
3947
|
+
data_source=data_source,
|
|
3948
|
+
campaign_name=campaign_name,
|
|
3949
|
+
station_name=station_name,
|
|
3950
|
+
temporal_resolution=temporal_resolution,
|
|
3951
|
+
)
|
|
3952
|
+
table_events_summary_pdf_filepath = os.path.join(summary_dir_path, table_events_summary_pdf_filename)
|
|
3953
|
+
save_table_to_pdf(
|
|
3954
|
+
df=prepare_latex_table_events_summary(table_events_summary),
|
|
3955
|
+
filepath=table_events_summary_pdf_filepath,
|
|
3956
|
+
index=True,
|
|
3957
|
+
caption="Events Summary",
|
|
3958
|
+
orientation="landscape",
|
|
3959
|
+
)
|
|
3960
|
+
# Sorted by Ptotal
|
|
3961
|
+
table_events_summary = table_events_summary.sort_values(by="P_total", ascending=False)
|
|
3962
|
+
table_events_summary = table_events_summary.reset_index(drop=True)
|
|
3963
|
+
table_events_summary_pdf_filename = define_filename(
|
|
3964
|
+
prefix="Events_Summary_Sorted_By_Ptot",
|
|
3965
|
+
extension="pdf",
|
|
3966
|
+
data_source=data_source,
|
|
3967
|
+
campaign_name=campaign_name,
|
|
3968
|
+
station_name=station_name,
|
|
3969
|
+
temporal_resolution=temporal_resolution,
|
|
3970
|
+
)
|
|
3971
|
+
table_events_summary_pdf_filepath = os.path.join(summary_dir_path, table_events_summary_pdf_filename)
|
|
3972
|
+
save_table_to_pdf(
|
|
3973
|
+
df=prepare_latex_table_events_summary(table_events_summary),
|
|
3974
|
+
filepath=table_events_summary_pdf_filepath,
|
|
3975
|
+
index=True,
|
|
3976
|
+
caption="Events Summary",
|
|
3977
|
+
orientation="landscape",
|
|
3978
|
+
)
|
|
3979
|
+
|
|
3920
3980
|
# ---------------------------------------------------------------------.
|
|
3921
3981
|
#### Create table with integral DSD parameters statistics
|
|
3922
3982
|
table_dsd_summary = create_table_dsd_summary(df)
|
disdrodb/utils/__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/utils/archiving.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
|
|
@@ -111,17 +111,18 @@ def generate_time_blocks(
|
|
|
111
111
|
def identify_events(
|
|
112
112
|
filepaths,
|
|
113
113
|
parallel=False,
|
|
114
|
-
|
|
114
|
+
variable="N",
|
|
115
|
+
detection_threshold=5,
|
|
115
116
|
neighbor_min_size=2,
|
|
116
117
|
neighbor_time_interval="5MIN",
|
|
117
118
|
event_max_time_gap="6H",
|
|
118
119
|
event_min_duration="5MIN",
|
|
119
120
|
event_min_size=3,
|
|
120
121
|
):
|
|
121
|
-
"""Return a list of
|
|
122
|
+
"""Return a list of precipitating events.
|
|
122
123
|
|
|
123
|
-
|
|
124
|
-
Any
|
|
124
|
+
Precipitating events are defined when 'variable' > detection_threshold.
|
|
125
|
+
Any isolated timesteps with precipitation (based on neighborhood criteria) is removed.
|
|
125
126
|
Then, consecutive rainy timesteps are grouped into the same event if the time gap between them does not
|
|
126
127
|
exceed `event_max_time_gap`. Finally, events that do not meet minimum size or duration
|
|
127
128
|
requirements are filtered out.
|
|
@@ -130,6 +131,11 @@ def identify_events(
|
|
|
130
131
|
----------
|
|
131
132
|
filepaths: list
|
|
132
133
|
List of L1C file paths.
|
|
134
|
+
variable : str
|
|
135
|
+
Name of the variable to use to apply the event detection.
|
|
136
|
+
The default is "N".
|
|
137
|
+
detection_threshold : int
|
|
138
|
+
Minimum value of 'variable' to consider an event timestep.
|
|
133
139
|
parallel: bool
|
|
134
140
|
Whether to load the files in parallel.
|
|
135
141
|
Set parallel=True only in a multiprocessing environment.
|
|
@@ -163,11 +169,11 @@ def identify_events(
|
|
|
163
169
|
- "n_timesteps": int, number of valid timesteps in the event
|
|
164
170
|
"""
|
|
165
171
|
# Open datasets in parallel
|
|
166
|
-
ds = open_netcdf_files(filepaths, variables=["time",
|
|
172
|
+
ds = open_netcdf_files(filepaths, variables=["time", variable], parallel=parallel, compute=True)
|
|
167
173
|
# Sort dataset by time
|
|
168
174
|
ds = ensure_sorted_by_time(ds)
|
|
169
175
|
# Define candidate timesteps to group into events
|
|
170
|
-
idx_valid = ds[
|
|
176
|
+
idx_valid = ds[variable].to_numpy() > detection_threshold
|
|
171
177
|
timesteps = ds["time"].to_numpy()[idx_valid]
|
|
172
178
|
if "sample_interval" in ds:
|
|
173
179
|
sample_interval = ds["sample_interval"].compute().item()
|
|
@@ -263,8 +269,9 @@ def define_temporal_partitions(filepaths, strategy, parallel, strategy_options):
|
|
|
263
269
|
See identify_time_partitions for more information.
|
|
264
270
|
|
|
265
271
|
If ``strategy == 'event'``, supported options are:
|
|
266
|
-
|
|
267
|
-
|
|
272
|
+
- ``variable`` : str
|
|
273
|
+
Name of the variable to use to apply the event detection.
|
|
274
|
+
- ``detection_threshold`` : int
|
|
268
275
|
Minimum number of drops to consider a timestep.
|
|
269
276
|
- ``neighbor_min_size`` : int
|
|
270
277
|
Minimum cluster size for merging neighboring events.
|
disdrodb/utils/attrs.py
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
|
|
3
1
|
# -----------------------------------------------------------------------------.
|
|
4
|
-
# Copyright (c) 2021-
|
|
2
|
+
# Copyright (c) 2021-2026 DISDRODB developers
|
|
5
3
|
#
|
|
6
4
|
# This program is free software: you can redistribute it and/or modify
|
|
7
5
|
# it under the terms of the GNU General Public License as published by
|
|
@@ -95,8 +93,11 @@ def update_disdrodb_attrs(ds, product: str):
|
|
|
95
93
|
# ----------------------------------------------
|
|
96
94
|
# Add time_coverage_start and time_coverage_end
|
|
97
95
|
if "time" in ds.dims:
|
|
96
|
+
encoding = ds["time"].encoding
|
|
98
97
|
ds["time"] = ds["time"].dt.floor("s") # ensure no sub-second values
|
|
99
98
|
ds["time"] = ds["time"].astype("datetime64[s]")
|
|
99
|
+
ds["time"].encoding = encoding # otherwise time encoding get lost !
|
|
100
|
+
|
|
100
101
|
attrs["time_coverage_start"] = str(ds["time"].data[0])
|
|
101
102
|
attrs["time_coverage_end"] = str(ds["time"].data[-1])
|
|
102
103
|
|