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
disdrodb/metadata/geolocation.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
|
|
@@ -17,6 +15,7 @@
|
|
|
17
15
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
18
16
|
# -----------------------------------------------------------------------------.
|
|
19
17
|
"""Metadata tools to verify/complete geolocation information."""
|
|
18
|
+
|
|
20
19
|
import time
|
|
21
20
|
|
|
22
21
|
import numpy as np
|
|
@@ -126,7 +125,7 @@ def infer_altitudes(lats, lons, dem="aster30m"):
|
|
|
126
125
|
block_lons = lons[i : i + max_locations]
|
|
127
126
|
|
|
128
127
|
# Create the list_coords string in the format "lat1,lon1|lat2,lon2|..."
|
|
129
|
-
list_coords = "|".join([f"{lat},{lon}" for lat, lon in zip(block_lats, block_lons)])
|
|
128
|
+
list_coords = "|".join([f"{lat},{lon}" for lat, lon in zip(block_lats, block_lons, strict=True)])
|
|
130
129
|
|
|
131
130
|
# Define API URL
|
|
132
131
|
url = f"https://api.opentopodata.org/v1/{dem}?locations={list_coords}&interpolation=nearest"
|
disdrodb/metadata/info.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
|
|
@@ -17,8 +15,8 @@
|
|
|
17
15
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
18
16
|
# -----------------------------------------------------------------------------.
|
|
19
17
|
"""Test Metadata Info Extraction."""
|
|
18
|
+
|
|
20
19
|
import os
|
|
21
|
-
from typing import Optional
|
|
22
20
|
|
|
23
21
|
from disdrodb.api.info import (
|
|
24
22
|
infer_campaign_name_from_path,
|
|
@@ -29,7 +27,7 @@ from disdrodb.metadata.reader import read_station_metadata
|
|
|
29
27
|
from disdrodb.metadata.search import get_list_metadata
|
|
30
28
|
|
|
31
29
|
|
|
32
|
-
def get_archive_metadata_key_value(key: str, return_tuple: bool = True, metadata_archive_dir:
|
|
30
|
+
def get_archive_metadata_key_value(key: str, return_tuple: bool = True, metadata_archive_dir: str | None = None):
|
|
33
31
|
"""Return the values of a metadata key for all the archive.
|
|
34
32
|
|
|
35
33
|
Parameters
|
|
@@ -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
|
disdrodb/metadata/reader.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
|
disdrodb/metadata/search.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
|
|
@@ -18,7 +16,6 @@
|
|
|
18
16
|
# -----------------------------------------------------------------------------.
|
|
19
17
|
"""Routines to manipulate the DISDRODB Metadata Archive."""
|
|
20
18
|
|
|
21
|
-
|
|
22
19
|
from disdrodb.api.path import define_metadata_filepath
|
|
23
20
|
from disdrodb.api.search import available_stations
|
|
24
21
|
|
disdrodb/metadata/standards.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
|
disdrodb/metadata/writer.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
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|
+
"""DISDRODB physics module."""
|
|
@@ -0,0 +1,273 @@
|
|
|
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
|
+
"""DISDRODB atmospheric physics module."""
|
|
18
|
+
|
|
19
|
+
import numpy as np
|
|
20
|
+
import xarray as xr
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_gravitational_acceleration(latitude, altitude=0):
|
|
24
|
+
"""
|
|
25
|
+
Computes gravitational acceleration at a given altitude and latitude.
|
|
26
|
+
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
altitude : float
|
|
30
|
+
Altitude in meters. The default is 0 m (sea level).
|
|
31
|
+
latitude : float
|
|
32
|
+
Latitude in degrees.
|
|
33
|
+
|
|
34
|
+
Returns
|
|
35
|
+
-------
|
|
36
|
+
float
|
|
37
|
+
Gravitational acceleration in m/s^2.
|
|
38
|
+
"""
|
|
39
|
+
g0 = 9.806229 - 0.025889372 * np.cos(2 * np.deg2rad(latitude))
|
|
40
|
+
return g0 - 2.879513 * altitude / 1e6
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def get_air_pressure_at_height(
|
|
44
|
+
altitude,
|
|
45
|
+
latitude,
|
|
46
|
+
temperature,
|
|
47
|
+
sea_level_air_pressure=101_325,
|
|
48
|
+
lapse_rate=0.0065,
|
|
49
|
+
gas_constant_dry_air=287.04,
|
|
50
|
+
):
|
|
51
|
+
"""
|
|
52
|
+
Computes the air pressure at a given height in a standard atmosphere.
|
|
53
|
+
|
|
54
|
+
According to the hypsometric formula of Brutsaert 1982; Ulaby et al. 1981
|
|
55
|
+
|
|
56
|
+
Parameters
|
|
57
|
+
----------
|
|
58
|
+
altitude : float
|
|
59
|
+
Altitude in meters.
|
|
60
|
+
latitude : float
|
|
61
|
+
Latitude in degrees.
|
|
62
|
+
temperature : float
|
|
63
|
+
Temperature at altitude in Kelvin.
|
|
64
|
+
sea_level_air_pressure : float, optional
|
|
65
|
+
Standard atmospheric pressure at sea level in Pascals. The default is 101_325 Pascals.
|
|
66
|
+
lapse_rate : float, optional
|
|
67
|
+
Standard atmospheric lapse rate in K/m. The default is 0.0065 K/m.
|
|
68
|
+
gas_constant_dry_air : float, optional
|
|
69
|
+
Gas constant for dry air in J/(kg*K). The default is 287.04 J/(kg*K).
|
|
70
|
+
|
|
71
|
+
Returns
|
|
72
|
+
-------
|
|
73
|
+
float
|
|
74
|
+
Air pressure in Pascals.
|
|
75
|
+
"""
|
|
76
|
+
g = get_gravitational_acceleration(altitude=altitude, latitude=latitude)
|
|
77
|
+
return sea_level_air_pressure * np.exp(
|
|
78
|
+
-g / (lapse_rate * gas_constant_dry_air) * np.log(1 + lapse_rate * altitude / temperature),
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def get_air_temperature_at_height(altitude, sea_level_temperature, lapse_rate=0.0065):
|
|
83
|
+
"""
|
|
84
|
+
Computes the air temperature at a given height in a standard atmosphere.
|
|
85
|
+
|
|
86
|
+
Reference: Brutsaert 1982; Ulaby et al. 1981
|
|
87
|
+
|
|
88
|
+
Parameters
|
|
89
|
+
----------
|
|
90
|
+
altitude : float
|
|
91
|
+
Altitude in meters.
|
|
92
|
+
sea_level_temperature : float
|
|
93
|
+
Standard temperature at sea level in Kelvin.
|
|
94
|
+
lapse_rate : float, optional
|
|
95
|
+
Standard atmospheric lapse rate in K/m. The default is 0.0065 K/m.
|
|
96
|
+
|
|
97
|
+
Returns
|
|
98
|
+
-------
|
|
99
|
+
float
|
|
100
|
+
Air temperature in Kelvin.
|
|
101
|
+
"""
|
|
102
|
+
return sea_level_temperature - lapse_rate * altitude
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def get_air_dynamic_viscosity(temperature):
|
|
106
|
+
"""
|
|
107
|
+
Computes the dynamic viscosity of dry air.
|
|
108
|
+
|
|
109
|
+
Reference: Beard 1977; Pruppacher & Klett 1978
|
|
110
|
+
|
|
111
|
+
Parameters
|
|
112
|
+
----------
|
|
113
|
+
temperature : float
|
|
114
|
+
Temperature in Kelvin.
|
|
115
|
+
|
|
116
|
+
Returns
|
|
117
|
+
-------
|
|
118
|
+
float
|
|
119
|
+
Dynamic viscosity of dry air in kg/(m*s) (aka Pa*s).
|
|
120
|
+
"""
|
|
121
|
+
# Convert to Celsius
|
|
122
|
+
temperature = temperature - 273.15
|
|
123
|
+
|
|
124
|
+
# Define mask
|
|
125
|
+
above_freezing_mask = temperature > 0
|
|
126
|
+
|
|
127
|
+
# Compute viscosity above freezing temperature
|
|
128
|
+
viscosity_above_0 = (1.721 + 0.00487 * temperature) / 1e5
|
|
129
|
+
|
|
130
|
+
# Compute viscosity below freezing temperature
|
|
131
|
+
viscosity_below_0 = (1.718 + 0.0049 * temperature - 1.2 * temperature**2 / 1e5) / 1e5
|
|
132
|
+
|
|
133
|
+
# Define final viscosity
|
|
134
|
+
viscosity = xr.where(above_freezing_mask, viscosity_above_0, viscosity_below_0)
|
|
135
|
+
return viscosity
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def get_air_density(temperature, air_pressure, vapor_pressure, gas_constant_dry_air=287.04):
|
|
139
|
+
"""
|
|
140
|
+
Computes the air density according to the equation of state for moist air.
|
|
141
|
+
|
|
142
|
+
Reference: Brutsaert 1982
|
|
143
|
+
|
|
144
|
+
Parameters
|
|
145
|
+
----------
|
|
146
|
+
temperature : float
|
|
147
|
+
Temperature in Kelvin.
|
|
148
|
+
air_pressure : float
|
|
149
|
+
Air pressure in Pascals.
|
|
150
|
+
vapor_pressure : float
|
|
151
|
+
Vapor pressure in Pascals.
|
|
152
|
+
gas_constant_dry_air : float, optional
|
|
153
|
+
Gas constant for dry air in J/(kg*K). The default is 287.04 J/(kg*K).
|
|
154
|
+
|
|
155
|
+
Returns
|
|
156
|
+
-------
|
|
157
|
+
float
|
|
158
|
+
Air density in kg/m^3.
|
|
159
|
+
"""
|
|
160
|
+
# # Define constant for water vapor in J/(kg·K)
|
|
161
|
+
# gas_constant_water_vapor=461.5
|
|
162
|
+
|
|
163
|
+
# # Partial pressure of dry air (Pa)
|
|
164
|
+
# pressure_dry_air = air_pressure - vapor_pressure
|
|
165
|
+
|
|
166
|
+
# # Density of dry air (kg/m^3)
|
|
167
|
+
# density_dry_air = pressure_dry_air / (gas_constant_dry_air * temperature)
|
|
168
|
+
|
|
169
|
+
# # Density of water vapor (kg/m^3)
|
|
170
|
+
# density_water_vapor = vapor_pressure / (gas_constant_water_vapor * temperature)
|
|
171
|
+
|
|
172
|
+
# # Total air density (kg/m^3)
|
|
173
|
+
# air_density = density_dry_air + density_water_vapor
|
|
174
|
+
|
|
175
|
+
return air_pressure * (1 - 0.378 * vapor_pressure / air_pressure) / (gas_constant_dry_air * temperature)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def get_vapor_actual_pressure_at_height(
|
|
179
|
+
altitude,
|
|
180
|
+
sea_level_temperature,
|
|
181
|
+
sea_level_relative_humidity,
|
|
182
|
+
sea_level_air_pressure=101_325,
|
|
183
|
+
lapse_rate=0.0065,
|
|
184
|
+
):
|
|
185
|
+
"""
|
|
186
|
+
Computes the vapor pressure using Yamamoto's exponential relationship.
|
|
187
|
+
|
|
188
|
+
Reference: Brutsaert 1982
|
|
189
|
+
|
|
190
|
+
Parameters
|
|
191
|
+
----------
|
|
192
|
+
altitude : float
|
|
193
|
+
Altitude in meters.
|
|
194
|
+
sea_level_temperature : float
|
|
195
|
+
Standard temperature at sea level in Kelvin.
|
|
196
|
+
sea_level_relative_humidity : float
|
|
197
|
+
Relative humidity at sea level. A value between 0 and 1.
|
|
198
|
+
sea_level_air_pressure : float, optional
|
|
199
|
+
Standard atmospheric pressure at sea level in Pascals. The default is 101_325 Pascals.
|
|
200
|
+
lapse_rate : float, optional
|
|
201
|
+
Standard atmospheric lapse rate in K/m. The default is 0.0065 K/m.
|
|
202
|
+
|
|
203
|
+
Returns
|
|
204
|
+
-------
|
|
205
|
+
float
|
|
206
|
+
Vapor pressure in Pascals.
|
|
207
|
+
"""
|
|
208
|
+
temperature_at_altitude = get_air_temperature_at_height(
|
|
209
|
+
altitude=altitude,
|
|
210
|
+
sea_level_temperature=sea_level_temperature,
|
|
211
|
+
lapse_rate=lapse_rate,
|
|
212
|
+
)
|
|
213
|
+
esat = get_vapor_saturation_pressure(sea_level_temperature)
|
|
214
|
+
actual_vapor = sea_level_relative_humidity / (1 / esat - (1 - sea_level_relative_humidity) / sea_level_air_pressure)
|
|
215
|
+
return actual_vapor * np.exp(-(5.8e3 * lapse_rate / (temperature_at_altitude**2) + 5.5e-5) * altitude)
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def get_vapor_saturation_pressure(temperature):
|
|
219
|
+
"""
|
|
220
|
+
Computes the saturation vapor pressure over water as a function of temperature.
|
|
221
|
+
|
|
222
|
+
Use formulation and coefficients of Wexler (1976, 1977).
|
|
223
|
+
References: Brutsaert 1982; Pruppacher & Klett 1978; Flatau & al. 1992
|
|
224
|
+
|
|
225
|
+
Parameters
|
|
226
|
+
----------
|
|
227
|
+
temperature : float
|
|
228
|
+
Temperature in Kelvin.
|
|
229
|
+
|
|
230
|
+
Returns
|
|
231
|
+
-------
|
|
232
|
+
float
|
|
233
|
+
Saturation vapor pressure in Pascal.
|
|
234
|
+
"""
|
|
235
|
+
# Polynomial coefficients
|
|
236
|
+
g = [
|
|
237
|
+
-0.29912729e4,
|
|
238
|
+
-0.60170128e4,
|
|
239
|
+
0.1887643854e2,
|
|
240
|
+
-0.28354721e-1,
|
|
241
|
+
0.17838301e-4,
|
|
242
|
+
-0.84150417e-9,
|
|
243
|
+
0.44412543e-12,
|
|
244
|
+
0.2858487e1,
|
|
245
|
+
]
|
|
246
|
+
# Perform polynomial accumulation using Horner rule
|
|
247
|
+
esat = g[6]
|
|
248
|
+
for i in [5, 4, 3, 2]:
|
|
249
|
+
esat = esat * temperature + g[i]
|
|
250
|
+
esat = esat + g[7] * np.log(temperature)
|
|
251
|
+
for i in [1, 0]:
|
|
252
|
+
esat = esat * temperature + g[i]
|
|
253
|
+
return np.exp(esat / (temperature**2))
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def get_vapor_actual_pressure(relative_humidity, temperature):
|
|
257
|
+
"""
|
|
258
|
+
Computes the actual vapor pressure over water.
|
|
259
|
+
|
|
260
|
+
Parameters
|
|
261
|
+
----------
|
|
262
|
+
relative_humidity : float
|
|
263
|
+
Relative humidity. A value between 0 and 1.
|
|
264
|
+
temperature : float
|
|
265
|
+
Temperature in Kelvin.
|
|
266
|
+
|
|
267
|
+
Returns
|
|
268
|
+
-------
|
|
269
|
+
float
|
|
270
|
+
Actual vapor pressure in Pascal.
|
|
271
|
+
"""
|
|
272
|
+
esat = get_vapor_saturation_pressure(temperature)
|
|
273
|
+
return relative_humidity * esat
|
|
@@ -0,0 +1,131 @@
|
|
|
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
|
+
"""DISDRODB water physics module."""
|
|
18
|
+
|
|
19
|
+
import numpy as np
|
|
20
|
+
import xarray as xr
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_pure_water_density(temperature):
|
|
24
|
+
"""
|
|
25
|
+
Computes the density of pure water at standard pressure.
|
|
26
|
+
|
|
27
|
+
For temperatures above freezing uses Kell formulation.
|
|
28
|
+
For temperatures below freezing use Dorsch & Boyd formulation.
|
|
29
|
+
|
|
30
|
+
References: Pruppacher & Klett 1978; Weast & Astle 1980
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
temperature : float
|
|
35
|
+
Temperature in Kelvin.
|
|
36
|
+
|
|
37
|
+
Returns
|
|
38
|
+
-------
|
|
39
|
+
float
|
|
40
|
+
Density of pure water in kg/m^3.
|
|
41
|
+
"""
|
|
42
|
+
# Convert to Celsius
|
|
43
|
+
temperature = temperature - 273.15
|
|
44
|
+
|
|
45
|
+
# Define mask
|
|
46
|
+
above_freezing_mask = temperature > 0
|
|
47
|
+
|
|
48
|
+
# Compute density above freezing temperature
|
|
49
|
+
c = [9.9983952e2, 1.6945176e1, -7.9870401e-3, -4.6170461e-5, 1.0556302e-7, -2.8054253e-10, 1.6879850e-2]
|
|
50
|
+
density = c[0] + sum(c * temperature**i for i, c in enumerate(c[1:6], start=1))
|
|
51
|
+
density_above_0 = density / (1 + c[6] * temperature)
|
|
52
|
+
|
|
53
|
+
# Compute density below freezing temperature
|
|
54
|
+
c = [999.84, 0.086, -0.0108]
|
|
55
|
+
density_below_0 = c[0] + sum(c * temperature**i for i, c in enumerate(c[1:], start=1))
|
|
56
|
+
|
|
57
|
+
# Define final density
|
|
58
|
+
density = xr.where(above_freezing_mask, density_above_0, density_below_0)
|
|
59
|
+
return density
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def get_pure_water_compressibility(temperature):
|
|
63
|
+
"""
|
|
64
|
+
Computes the isothermal compressibility of pure ordinary water.
|
|
65
|
+
|
|
66
|
+
Reference: Kell, Weast & Astle 1980
|
|
67
|
+
|
|
68
|
+
Parameters
|
|
69
|
+
----------
|
|
70
|
+
temperature : float
|
|
71
|
+
Temperature in Kelvin.
|
|
72
|
+
|
|
73
|
+
Returns
|
|
74
|
+
-------
|
|
75
|
+
float
|
|
76
|
+
Compressibility of water in Pascals.
|
|
77
|
+
"""
|
|
78
|
+
# Convert to Celsius
|
|
79
|
+
temperature = temperature - 273.15
|
|
80
|
+
|
|
81
|
+
# Compute compressibility
|
|
82
|
+
c = [5.088496e1, 6.163813e-1, 1.459187e-3, 2.008438e-5, -5.857727e-8, 4.10411e-10, 1.967348e-2]
|
|
83
|
+
compressibility = c[0] + sum(c * temperature**i for i, c in enumerate(c[1:6], start=1))
|
|
84
|
+
compressibility = compressibility / (1 + c[6] * temperature) * 1e-11
|
|
85
|
+
return compressibility
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def get_pure_water_surface_tension(temperature):
|
|
89
|
+
"""
|
|
90
|
+
Computes the surface tension of pure ordinary water against air.
|
|
91
|
+
|
|
92
|
+
Reference: Pruppacher & Klett 1978
|
|
93
|
+
|
|
94
|
+
Parameters
|
|
95
|
+
----------
|
|
96
|
+
temperature : float
|
|
97
|
+
Temperature in Kelvin.
|
|
98
|
+
|
|
99
|
+
Returns
|
|
100
|
+
-------
|
|
101
|
+
float
|
|
102
|
+
Surface tension in N/m.
|
|
103
|
+
"""
|
|
104
|
+
sigma = 0.0761 - 0.000155 * (temperature - 273.15)
|
|
105
|
+
return sigma
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def get_water_density(temperature, air_pressure, sea_level_air_pressure=101_325):
|
|
109
|
+
"""
|
|
110
|
+
Computes the density of water according to Weast & Astle 1980.
|
|
111
|
+
|
|
112
|
+
Parameters
|
|
113
|
+
----------
|
|
114
|
+
temperature : float
|
|
115
|
+
Temperature in Kelvin.
|
|
116
|
+
air_pressure : float
|
|
117
|
+
Air pressure in Pascals.
|
|
118
|
+
sea_level_air_pressure : float
|
|
119
|
+
Standard atmospheric pressure at sea level in Pascals.
|
|
120
|
+
The default is 101_325 Pascal.
|
|
121
|
+
freezing_temperature : float, optional
|
|
122
|
+
Freezing temperature of water in Kelvin. The default is 273.15 K.
|
|
123
|
+
|
|
124
|
+
Returns
|
|
125
|
+
-------
|
|
126
|
+
float
|
|
127
|
+
Water density in kg/m^3.
|
|
128
|
+
"""
|
|
129
|
+
delta_pressure = sea_level_air_pressure - air_pressure
|
|
130
|
+
water_compressibility = get_pure_water_compressibility(temperature)
|
|
131
|
+
return get_pure_water_density(temperature) * np.exp(-1 * water_compressibility * delta_pressure)
|
|
@@ -0,0 +1,63 @@
|
|
|
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
|
+
"""DISDRODB physics wrapper functions."""
|
|
18
|
+
|
|
19
|
+
from disdrodb.physics.atmosphere import (
|
|
20
|
+
get_air_density,
|
|
21
|
+
get_air_dynamic_viscosity,
|
|
22
|
+
get_air_pressure_at_height,
|
|
23
|
+
get_vapor_actual_pressure,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
####---------------------------------------------------------------------------.
|
|
28
|
+
#### Wrappers
|
|
29
|
+
def retrieve_air_pressure(ds_env):
|
|
30
|
+
"""Retrieve air pressure."""
|
|
31
|
+
if "air_pressure" in ds_env:
|
|
32
|
+
return ds_env["air_pressure"]
|
|
33
|
+
air_pressure = get_air_pressure_at_height(
|
|
34
|
+
altitude=ds_env["altitude"],
|
|
35
|
+
latitude=ds_env["latitude"],
|
|
36
|
+
temperature=ds_env["temperature"],
|
|
37
|
+
sea_level_air_pressure=ds_env["sea_level_air_pressure"],
|
|
38
|
+
lapse_rate=ds_env["lapse_rate"],
|
|
39
|
+
)
|
|
40
|
+
return air_pressure
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def retrieve_air_dynamic_viscosity(ds_env):
|
|
44
|
+
"""Retrieve air dynamic viscosity."""
|
|
45
|
+
air_viscosity = get_air_dynamic_viscosity(ds_env["temperature"])
|
|
46
|
+
return air_viscosity
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def retrieve_air_density(ds_env):
|
|
50
|
+
"""Retrieve air density."""
|
|
51
|
+
temperature = ds_env["temperature"]
|
|
52
|
+
relative_humidity = ds_env["relative_humidity"]
|
|
53
|
+
air_pressure = retrieve_air_pressure(ds_env)
|
|
54
|
+
vapor_pressure = get_vapor_actual_pressure(
|
|
55
|
+
relative_humidity=relative_humidity,
|
|
56
|
+
temperature=temperature,
|
|
57
|
+
)
|
|
58
|
+
air_density = get_air_density(
|
|
59
|
+
temperature=temperature,
|
|
60
|
+
air_pressure=air_pressure,
|
|
61
|
+
vapor_pressure=vapor_pressure,
|
|
62
|
+
)
|
|
63
|
+
return air_density
|
disdrodb/psd/__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
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
# -----------------------------------------------------------------------------.
|
|
17
17
|
"""Implement PSD model and fitting routines."""
|
|
18
18
|
|
|
19
|
-
|
|
20
19
|
from disdrodb.psd.fitting import estimate_model_parameters
|
|
21
20
|
from disdrodb.psd.models import (
|
|
22
21
|
ExponentialPSD,
|
disdrodb/psd/fitting.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
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
16
|
# -----------------------------------------------------------------------------.
|
|
17
17
|
"""Routines for PSD fitting."""
|
|
18
|
+
|
|
18
19
|
import numpy as np
|
|
19
20
|
import scipy.stats as ss
|
|
20
21
|
import xarray as xr
|
|
@@ -23,7 +24,7 @@ from scipy.optimize import minimize
|
|
|
23
24
|
from scipy.special import gamma, gammaln # Regularized lower incomplete gamma function
|
|
24
25
|
|
|
25
26
|
from disdrodb.constants import DIAMETER_DIMENSION
|
|
26
|
-
from disdrodb.
|
|
27
|
+
from disdrodb.fall_velocity import get_rain_fall_velocity_from_ds
|
|
27
28
|
from disdrodb.l2.empirical_dsd import (
|
|
28
29
|
get_median_volume_drop_diameter,
|
|
29
30
|
get_moment,
|
|
@@ -1056,14 +1057,26 @@ def _compute_z(ND, D, dD):
|
|
|
1056
1057
|
return Z
|
|
1057
1058
|
|
|
1058
1059
|
|
|
1059
|
-
def _compute_target_variable_error(target, ND_obs, ND_preds, D, dD, V):
|
|
1060
|
+
def _compute_target_variable_error(target, ND_obs, ND_preds, D, dD, V, relative=False, eps=1e-12):
|
|
1061
|
+
# Compute observed and predicted target variables
|
|
1060
1062
|
if target == "Z":
|
|
1061
|
-
|
|
1063
|
+
obs = _compute_z(ND_obs, D, dD)
|
|
1064
|
+
pred = _compute_z(ND_preds, D, dD)
|
|
1062
1065
|
elif target == "R":
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1066
|
+
obs = _compute_rain_rate(ND_obs, D, dD, V)
|
|
1067
|
+
pred = _compute_rain_rate(ND_preds, D, dD, V)
|
|
1068
|
+
else: # "LWC"
|
|
1069
|
+
obs = _compute_lwc(ND_obs, D, dD)
|
|
1070
|
+
pred = _compute_lwc(ND_preds, D, dD)
|
|
1071
|
+
|
|
1072
|
+
# Absolute error
|
|
1073
|
+
abs_error = np.abs(obs - pred)
|
|
1074
|
+
|
|
1075
|
+
# Return relative error if requested
|
|
1076
|
+
if relative:
|
|
1077
|
+
return abs_error / (np.abs(obs) + eps)
|
|
1078
|
+
|
|
1079
|
+
return abs_error
|
|
1067
1080
|
|
|
1068
1081
|
|
|
1069
1082
|
def _compute_cost_function(ND_obs, ND_preds, D, dD, V, target, transformation, error_order):
|
|
@@ -1992,6 +2005,7 @@ ATTRS_PARAMS_DICT = {
|
|
|
1992
2005
|
},
|
|
1993
2006
|
}
|
|
1994
2007
|
|
|
2008
|
+
PSD_MODELS = list(ATTRS_PARAMS_DICT)
|
|
1995
2009
|
|
|
1996
2010
|
MOM_METHODS_DICT = {
|
|
1997
2011
|
"GammaPSD": {
|
|
@@ -2356,7 +2370,7 @@ def get_gs_parameters(ds, psd_model, target="ND", transformation="log", error_or
|
|
|
2356
2370
|
|
|
2357
2371
|
# Check fall velocity is available if target R
|
|
2358
2372
|
if "fall_velocity" not in ds:
|
|
2359
|
-
ds["fall_velocity"] =
|
|
2373
|
+
ds["fall_velocity"] = get_rain_fall_velocity_from_ds(ds)
|
|
2360
2374
|
|
|
2361
2375
|
# Retrieve estimation function
|
|
2362
2376
|
func = OPTIMIZATION_ROUTINES_DICT["GS"][psd_model]
|