disdrodb 0.2.1__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 +9 -9
- disdrodb/api/checks.py +1 -3
- disdrodb/api/configs.py +1 -3
- disdrodb/api/create_directories.py +4 -6
- disdrodb/api/info.py +1 -3
- disdrodb/api/io.py +9 -8
- 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 +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 +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} +264 -44
- disdrodb/issue/__init__.py +1 -3
- disdrodb/issue/checks.py +1 -3
- disdrodb/issue/reader.py +1 -3
- disdrodb/issue/writer.py +1 -3
- disdrodb/l0/__init__.py +1 -1
- disdrodb/l0/check_configs.py +25 -16
- disdrodb/l0/check_standards.py +1 -3
- 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 +1 -3
- disdrodb/l0/l0a_processing.py +1 -3
- disdrodb/l0/l0b_nc_processing.py +2 -4
- disdrodb/l0/l0b_processing.py +1 -3
- disdrodb/l0/l0c_processing.py +27 -11
- 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 +47 -6
- disdrodb/l0/readers/LPM/ITALY/GID_LPM_PI.py +1 -1
- disdrodb/l0/readers/LPM/ITALY/GID_LPM_T.py +5 -2
- disdrodb/l0/readers/LPM/ITALY/GID_LPM_W.py +1 -3
- 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 +1 -1
- disdrodb/l0/readers/LPM/NORWAY/HAUKELISETER_LPM.py +1 -3
- disdrodb/l0/readers/LPM/NORWAY/NMBU_LPM.py +1 -3
- 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 +1 -3
- disdrodb/l0/readers/LPM/USA/CHARLESTON.py +1 -3
- disdrodb/l0/readers/LPM_V0/BELGIUM/ULIEGE.py +1 -3
- disdrodb/l0/readers/LPM_V0/ITALY/GID_LPM_V0.py +1 -1
- 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 +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 +1 -1
- disdrodb/l0/readers/PARSIVEL2/ARM/ARM_PARSIVEL2.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/BASQUECOUNTRY/EUSKALMET_OTT2.py +1 -1
- 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 +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 +1 -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 +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 +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 +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/PARSIVEL2/NORWAY/UIB.py +10 -2
- disdrodb/l0/readers/PARSIVEL2/PHILIPPINES/PAGASA.py +1 -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 +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 +1 -1
- disdrodb/l0/readers/PARSIVEL2/USA/CW3E.py +1 -1
- 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/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 +1 -3
- disdrodb/l0/readers/SWS250/BELGIUM/KMI.py +1 -3
- 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 +57 -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 +26 -16
- disdrodb/routines/l1.py +8 -6
- disdrodb/routines/l2.py +8 -4
- disdrodb/routines/options.py +116 -73
- disdrodb/routines/options_validation.py +728 -0
- disdrodb/routines/wrappers.py +431 -11
- disdrodb/scattering/__init__.py +1 -1
- disdrodb/scattering/axis_ratio.py +6 -6
- disdrodb/scattering/permittivity.py +8 -8
- disdrodb/scattering/routines.py +31 -13
- disdrodb/summary/__init__.py +1 -1
- disdrodb/summary/routines.py +83 -25
- 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 +9 -11
- disdrodb/utils/dask.py +2 -3
- 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 +175 -5
- 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 +192 -18
- {disdrodb-0.2.1.dist-info → disdrodb-0.3.0.dist-info}/METADATA +2 -2
- disdrodb-0.3.0.dist-info/RECORD +358 -0
- {disdrodb-0.2.1.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/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.3.0.dist-info}/WHEEL +0 -0
- {disdrodb-0.2.1.dist-info → disdrodb-0.3.0.dist-info}/licenses/LICENSE +0 -0
- {disdrodb-0.2.1.dist-info → disdrodb-0.3.0.dist-info}/top_level.txt +0 -0
disdrodb/routines/wrappers.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
|
|
@@ -22,6 +22,75 @@ from typing import Optional
|
|
|
22
22
|
from disdrodb.api.search import available_stations, get_required_product
|
|
23
23
|
from disdrodb.utils.cli import execute_cmd
|
|
24
24
|
|
|
25
|
+
|
|
26
|
+
def validate_processing_flags_and_get_required_product(**processing_flags):
|
|
27
|
+
"""Validate processing flags and determine the required input product.
|
|
28
|
+
|
|
29
|
+
Validates that the processing chain is logically consistent and returns
|
|
30
|
+
the product needed as input for the earliest requested processing step.
|
|
31
|
+
|
|
32
|
+
The processing chain must be contiguous - you cannot skip intermediate levels.
|
|
33
|
+
For example: l1_processing=True, l2e_processing=False, l2m_processing=True is invalid.
|
|
34
|
+
|
|
35
|
+
Raises
|
|
36
|
+
------
|
|
37
|
+
ValueError
|
|
38
|
+
If no processing levels are enabled or if the processing chain has gaps.
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
str
|
|
43
|
+
The required input product for the processing chain.
|
|
44
|
+
"""
|
|
45
|
+
# Define processing chain order and their required inputs
|
|
46
|
+
PROCESSING_CHAIN = [
|
|
47
|
+
("l0a_processing", "L0A"),
|
|
48
|
+
("l0b_processing", "L0B"),
|
|
49
|
+
("l0c_processing", "L0C"),
|
|
50
|
+
("l1_processing", "L1"),
|
|
51
|
+
("l2e_processing", "L2E"),
|
|
52
|
+
("l2m_processing", "L2M"),
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
# Filter only the processing flags we care about and get enabled levels
|
|
56
|
+
enabled_levels = []
|
|
57
|
+
for level, product in PROCESSING_CHAIN:
|
|
58
|
+
if processing_flags.get(level, False):
|
|
59
|
+
enabled_levels.append((level, product))
|
|
60
|
+
|
|
61
|
+
# Check if at least one processing level is enabled
|
|
62
|
+
if not enabled_levels:
|
|
63
|
+
raise ValueError("At least one processing level must be enabled.")
|
|
64
|
+
|
|
65
|
+
# Get indices of enabled levels in the original chain
|
|
66
|
+
enabled_indices = []
|
|
67
|
+
for level, _ in enabled_levels:
|
|
68
|
+
for i, (chain_level, _) in enumerate(PROCESSING_CHAIN):
|
|
69
|
+
if level == chain_level:
|
|
70
|
+
enabled_indices.append(i)
|
|
71
|
+
break
|
|
72
|
+
|
|
73
|
+
# Check for gaps: all indices between first and last enabled should be present
|
|
74
|
+
first_idx = min(enabled_indices)
|
|
75
|
+
last_idx = max(enabled_indices)
|
|
76
|
+
|
|
77
|
+
expected_indices = set(range(first_idx, last_idx + 1))
|
|
78
|
+
actual_indices = set(enabled_indices)
|
|
79
|
+
|
|
80
|
+
missing_indices = expected_indices - actual_indices
|
|
81
|
+
if missing_indices:
|
|
82
|
+
missing_levels = [PROCESSING_CHAIN[i][0] for i in missing_indices]
|
|
83
|
+
enabled_level_names = [level for level, _ in enabled_levels]
|
|
84
|
+
raise ValueError(
|
|
85
|
+
f"Processing chain has gaps. Enabled levels: {enabled_level_names}. "
|
|
86
|
+
f"Missing intermediate levels: {missing_levels}. "
|
|
87
|
+
f"All levels between the first and last enabled level must be enabled.",
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# Return the required input product for the earliest enabled level
|
|
91
|
+
return get_required_product(enabled_levels[0][1])
|
|
92
|
+
|
|
93
|
+
|
|
25
94
|
####--------------------------------------------------------------------------.
|
|
26
95
|
#### Run DISDRODB Station Processing
|
|
27
96
|
|
|
@@ -100,6 +169,13 @@ def run_l0_station(
|
|
|
100
169
|
in the DISDRODB active configuration.
|
|
101
170
|
"""
|
|
102
171
|
# ---------------------------------------------------------------------.
|
|
172
|
+
# Validate processing flags
|
|
173
|
+
_ = validate_processing_flags_and_get_required_product(
|
|
174
|
+
l0a_processing=l0a_processing,
|
|
175
|
+
l0b_processing=l0b_processing,
|
|
176
|
+
l0c_processing=l0c_processing,
|
|
177
|
+
)
|
|
178
|
+
# ---------------------------------------------------------------------.
|
|
103
179
|
t_i = time.time()
|
|
104
180
|
print(f"L0 processing of station {station_name} has started.")
|
|
105
181
|
|
|
@@ -1075,13 +1151,12 @@ def run_l0(
|
|
|
1075
1151
|
If ``None``, it uses the ``metadata_archive_dir`` path specified
|
|
1076
1152
|
in the DISDRODB active configuration.
|
|
1077
1153
|
"""
|
|
1078
|
-
#
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
required_product = get_required_product("L0A")
|
|
1154
|
+
# Determine required product based on the lowest level processing requested
|
|
1155
|
+
required_product = validate_processing_flags_and_get_required_product(
|
|
1156
|
+
l0a_processing=l0a_processing,
|
|
1157
|
+
l0b_processing=l0b_processing,
|
|
1158
|
+
l0c_processing=l0c_processing,
|
|
1159
|
+
)
|
|
1085
1160
|
|
|
1086
1161
|
# Get list of available stations
|
|
1087
1162
|
list_info = available_stations(
|
|
@@ -1438,6 +1513,354 @@ def run_l2m(
|
|
|
1438
1513
|
print(f"{product} processing of {data_source} {campaign_name} {station_name} station ended.")
|
|
1439
1514
|
|
|
1440
1515
|
|
|
1516
|
+
####--------------------------------------------------------------------------.
|
|
1517
|
+
#### Full Processing Wrappers
|
|
1518
|
+
def run_station(
|
|
1519
|
+
data_source,
|
|
1520
|
+
campaign_name,
|
|
1521
|
+
station_name,
|
|
1522
|
+
# L0 archive options
|
|
1523
|
+
l0a_processing: bool = True,
|
|
1524
|
+
l0b_processing: bool = True,
|
|
1525
|
+
l0c_processing: bool = True,
|
|
1526
|
+
remove_l0a: bool = False,
|
|
1527
|
+
remove_l0b: bool = False,
|
|
1528
|
+
# Higher level processing options
|
|
1529
|
+
l1_processing: bool = True,
|
|
1530
|
+
l2e_processing: bool = True,
|
|
1531
|
+
l2m_processing: bool = True,
|
|
1532
|
+
# Processing options
|
|
1533
|
+
force: bool = False,
|
|
1534
|
+
verbose: bool = False,
|
|
1535
|
+
debugging_mode: bool = False,
|
|
1536
|
+
parallel: bool = True,
|
|
1537
|
+
# DISDRODB root directories
|
|
1538
|
+
data_archive_dir: Optional[str] = None,
|
|
1539
|
+
metadata_archive_dir: Optional[str] = None,
|
|
1540
|
+
):
|
|
1541
|
+
"""Run the complete processing chain of a specific DISDRODB station from the terminal.
|
|
1542
|
+
|
|
1543
|
+
Parameters
|
|
1544
|
+
----------
|
|
1545
|
+
data_source : str
|
|
1546
|
+
Institution name (when campaign data spans more than 1 country),
|
|
1547
|
+
or country (when all campaigns (or sensor networks) are inside a given country).
|
|
1548
|
+
Must be UPPER CASE.
|
|
1549
|
+
campaign_name : str
|
|
1550
|
+
Campaign name. Must be UPPER CASE.
|
|
1551
|
+
station_name : str
|
|
1552
|
+
Station name
|
|
1553
|
+
l0a_processing : bool
|
|
1554
|
+
Whether to launch processing to generate L0A Apache Parquet file(s) from raw data.
|
|
1555
|
+
The default value is ``True``.
|
|
1556
|
+
l0b_processing : bool
|
|
1557
|
+
Whether to launch processing to generate L0B netCDF4 file(s) from L0A data.
|
|
1558
|
+
The default value is ``True``.
|
|
1559
|
+
l0c_processing : bool
|
|
1560
|
+
Whether to launch processing to generate L0C netCDF4 file(s) from L0B data.
|
|
1561
|
+
The default value is ``True``.
|
|
1562
|
+
remove_l0a : bool
|
|
1563
|
+
Whether to keep the L0A files after having generated the L0B netCDF products.
|
|
1564
|
+
The default value is ``False``.
|
|
1565
|
+
remove_l0b : bool
|
|
1566
|
+
Whether to remove the L0B files after having produced L0C netCDF files.
|
|
1567
|
+
The default is False.
|
|
1568
|
+
l1_processing : bool
|
|
1569
|
+
Whether to launch processing to generate L1 netCDF4 file(s) from L0C data.
|
|
1570
|
+
The default value is ``True``.
|
|
1571
|
+
l2e_processing : bool
|
|
1572
|
+
Whether to launch processing to generate L2E netCDF4 file(s) from L1 data.
|
|
1573
|
+
The default value is ``True``.
|
|
1574
|
+
l2m_processing : bool
|
|
1575
|
+
Whether to launch processing to generate L2M netCDF4 file(s) from L1 data.
|
|
1576
|
+
The default value is ``True``.
|
|
1577
|
+
force : bool
|
|
1578
|
+
If ``True``, overwrite existing data into destination directories.
|
|
1579
|
+
If ``False``, raise an error if there are already data into destination directories.
|
|
1580
|
+
The default value is ``False``.
|
|
1581
|
+
verbose : bool
|
|
1582
|
+
Whether to print detailed processing information into terminal.
|
|
1583
|
+
The default value is ``True``.
|
|
1584
|
+
parallel : bool
|
|
1585
|
+
If ``True``, the files are processed simultaneously in multiple processes.
|
|
1586
|
+
Each process will use a single thread to avoid issues with the HDF/netCDF library.
|
|
1587
|
+
By default, the number of process is defined with ``os.cpu_count()``.
|
|
1588
|
+
If ``False``, the files are processed sequentially in a single process.
|
|
1589
|
+
If ``False``, multi-threading is automatically exploited to speed up I/0 tasks.
|
|
1590
|
+
debugging_mode : bool
|
|
1591
|
+
If ``True``, it reduces the amount of data to process.
|
|
1592
|
+
For L0A, it processes just the first 3 raw data files for each station.
|
|
1593
|
+
For L0B, it processes 100 rows sampled from 3 L0A files for each station.
|
|
1594
|
+
The default value is ``False``.
|
|
1595
|
+
data_archive_dir : str (optional)
|
|
1596
|
+
The directory path where the DISDRODB Data Archive is located.
|
|
1597
|
+
The directory path must end with ``<...>/DISDRODB``.
|
|
1598
|
+
If ``None``, it uses the ``data_archive_dir`` path specified
|
|
1599
|
+
in the DISDRODB active configuration.
|
|
1600
|
+
metadata_archive_dir : str (optional)
|
|
1601
|
+
The directory path where the DISDRODB Metadata Archive is located.
|
|
1602
|
+
The directory path must end with ``<...>/DISDRODB-METADATA/DISDRODB``.
|
|
1603
|
+
If ``None``, it uses the ``metadata_archive_dir`` path specified
|
|
1604
|
+
in the DISDRODB active configuration.
|
|
1605
|
+
"""
|
|
1606
|
+
# ---------------------------------------------------------------------.
|
|
1607
|
+
# Validate processing flags
|
|
1608
|
+
_ = validate_processing_flags_and_get_required_product(
|
|
1609
|
+
l0a_processing=l0a_processing,
|
|
1610
|
+
l0b_processing=l0b_processing,
|
|
1611
|
+
l0c_processing=l0c_processing,
|
|
1612
|
+
l1_processing=l1_processing,
|
|
1613
|
+
l2e_processing=l2e_processing,
|
|
1614
|
+
l2m_processing=l2m_processing,
|
|
1615
|
+
)
|
|
1616
|
+
|
|
1617
|
+
# ---------------------------------------------------------------------.
|
|
1618
|
+
t_i = time.time()
|
|
1619
|
+
print(f"Complete processing of station {station_name} has started.")
|
|
1620
|
+
|
|
1621
|
+
# ------------------------------------------------------------------.
|
|
1622
|
+
# L0 processing (L0A, L0B, L0C)
|
|
1623
|
+
if l0a_processing or l0b_processing or l0c_processing:
|
|
1624
|
+
run_l0_station(
|
|
1625
|
+
# DISDRODB root directories
|
|
1626
|
+
data_archive_dir=data_archive_dir,
|
|
1627
|
+
metadata_archive_dir=metadata_archive_dir,
|
|
1628
|
+
# Station arguments
|
|
1629
|
+
data_source=data_source,
|
|
1630
|
+
campaign_name=campaign_name,
|
|
1631
|
+
station_name=station_name,
|
|
1632
|
+
# L0 archive options
|
|
1633
|
+
l0a_processing=l0a_processing,
|
|
1634
|
+
l0b_processing=l0b_processing,
|
|
1635
|
+
l0c_processing=l0c_processing,
|
|
1636
|
+
remove_l0a=remove_l0a,
|
|
1637
|
+
remove_l0b=remove_l0b,
|
|
1638
|
+
# Processing options
|
|
1639
|
+
force=force,
|
|
1640
|
+
verbose=verbose,
|
|
1641
|
+
debugging_mode=debugging_mode,
|
|
1642
|
+
parallel=parallel,
|
|
1643
|
+
)
|
|
1644
|
+
|
|
1645
|
+
# ------------------------------------------------------------------.
|
|
1646
|
+
# L1 processing
|
|
1647
|
+
if l1_processing:
|
|
1648
|
+
run_l1_station(
|
|
1649
|
+
# DISDRODB root directories
|
|
1650
|
+
data_archive_dir=data_archive_dir,
|
|
1651
|
+
metadata_archive_dir=metadata_archive_dir,
|
|
1652
|
+
# Station arguments
|
|
1653
|
+
data_source=data_source,
|
|
1654
|
+
campaign_name=campaign_name,
|
|
1655
|
+
station_name=station_name,
|
|
1656
|
+
# Processing options
|
|
1657
|
+
force=force,
|
|
1658
|
+
verbose=verbose,
|
|
1659
|
+
debugging_mode=debugging_mode,
|
|
1660
|
+
parallel=parallel,
|
|
1661
|
+
)
|
|
1662
|
+
|
|
1663
|
+
# ------------------------------------------------------------------.
|
|
1664
|
+
# L2E processing
|
|
1665
|
+
if l2e_processing:
|
|
1666
|
+
run_l2e_station(
|
|
1667
|
+
# DISDRODB root directories
|
|
1668
|
+
data_archive_dir=data_archive_dir,
|
|
1669
|
+
metadata_archive_dir=metadata_archive_dir,
|
|
1670
|
+
# Station arguments
|
|
1671
|
+
data_source=data_source,
|
|
1672
|
+
campaign_name=campaign_name,
|
|
1673
|
+
station_name=station_name,
|
|
1674
|
+
# Processing options
|
|
1675
|
+
force=force,
|
|
1676
|
+
verbose=verbose,
|
|
1677
|
+
debugging_mode=debugging_mode,
|
|
1678
|
+
parallel=parallel,
|
|
1679
|
+
)
|
|
1680
|
+
|
|
1681
|
+
# ------------------------------------------------------------------.
|
|
1682
|
+
# L2M processing
|
|
1683
|
+
if l2m_processing:
|
|
1684
|
+
run_l2m_station(
|
|
1685
|
+
# DISDRODB root directories
|
|
1686
|
+
data_archive_dir=data_archive_dir,
|
|
1687
|
+
metadata_archive_dir=metadata_archive_dir,
|
|
1688
|
+
# Station arguments
|
|
1689
|
+
data_source=data_source,
|
|
1690
|
+
campaign_name=campaign_name,
|
|
1691
|
+
station_name=station_name,
|
|
1692
|
+
# Processing options
|
|
1693
|
+
force=force,
|
|
1694
|
+
verbose=verbose,
|
|
1695
|
+
debugging_mode=debugging_mode,
|
|
1696
|
+
parallel=parallel,
|
|
1697
|
+
)
|
|
1698
|
+
|
|
1699
|
+
# -------------------------------------------------------------------------.
|
|
1700
|
+
# End of complete processing for station
|
|
1701
|
+
timedelta_str = str(datetime.timedelta(seconds=round(time.time() - t_i)))
|
|
1702
|
+
print(f"Complete processing of station {station_name} completed in {timedelta_str}")
|
|
1703
|
+
|
|
1704
|
+
|
|
1705
|
+
def run(
|
|
1706
|
+
data_sources=None,
|
|
1707
|
+
campaign_names=None,
|
|
1708
|
+
station_names=None,
|
|
1709
|
+
# L0 archive options
|
|
1710
|
+
l0a_processing: bool = True,
|
|
1711
|
+
l0b_processing: bool = True,
|
|
1712
|
+
l0c_processing: bool = True,
|
|
1713
|
+
remove_l0a: bool = False,
|
|
1714
|
+
remove_l0b: bool = False,
|
|
1715
|
+
# Higher level processing options
|
|
1716
|
+
l1_processing: bool = True,
|
|
1717
|
+
l2e_processing: bool = True,
|
|
1718
|
+
l2m_processing: bool = True,
|
|
1719
|
+
# Processing options
|
|
1720
|
+
force: bool = False,
|
|
1721
|
+
verbose: bool = False,
|
|
1722
|
+
debugging_mode: bool = False,
|
|
1723
|
+
parallel: bool = True,
|
|
1724
|
+
# DISDRODB root directories
|
|
1725
|
+
data_archive_dir: Optional[str] = None,
|
|
1726
|
+
metadata_archive_dir: Optional[str] = None,
|
|
1727
|
+
):
|
|
1728
|
+
"""Run the complete processing chain of DISDRODB stations.
|
|
1729
|
+
|
|
1730
|
+
This function allows to launch the complete processing of many DISDRODB stations with a single command.
|
|
1731
|
+
From the list of all available DISDRODB stations, it runs the processing of the
|
|
1732
|
+
stations matching the provided data_sources, campaign_names and station_names.
|
|
1733
|
+
|
|
1734
|
+
Parameters
|
|
1735
|
+
----------
|
|
1736
|
+
data_sources : list
|
|
1737
|
+
Name of data source(s) to process.
|
|
1738
|
+
The name(s) must be UPPER CASE.
|
|
1739
|
+
If campaign_names and station are not specified, process all stations.
|
|
1740
|
+
The default value is ``None``.
|
|
1741
|
+
campaign_names : list
|
|
1742
|
+
Name of the campaign(s) to process.
|
|
1743
|
+
The name(s) must be UPPER CASE.
|
|
1744
|
+
The default value is ``None``.
|
|
1745
|
+
station_names : list
|
|
1746
|
+
Station names to process.
|
|
1747
|
+
The default value is ``None``.
|
|
1748
|
+
l0a_processing : bool
|
|
1749
|
+
Whether to launch processing to generate L0A Apache Parquet file(s) from raw data.
|
|
1750
|
+
The default value is ``True``.
|
|
1751
|
+
l0b_processing : bool
|
|
1752
|
+
Whether to launch processing to generate L0B netCDF4 file(s) from L0A data.
|
|
1753
|
+
The default value is ``True``.
|
|
1754
|
+
l0c_processing : bool
|
|
1755
|
+
Whether to launch processing to generate L0C netCDF4 file(s) from L0B data.
|
|
1756
|
+
The default value is ``True``.
|
|
1757
|
+
remove_l0a : bool
|
|
1758
|
+
Whether to keep the L0A files after having generated the L0B netCDF products.
|
|
1759
|
+
The default value is ``False``.
|
|
1760
|
+
remove_l0b : bool
|
|
1761
|
+
Whether to remove the L0B files after having produced L0C netCDF files.
|
|
1762
|
+
The default value is ``False``.
|
|
1763
|
+
l1_processing : bool
|
|
1764
|
+
Whether to launch processing to generate L1 netCDF4 file(s) from L0C data.
|
|
1765
|
+
The default value is ``True``.
|
|
1766
|
+
l2e_processing : bool
|
|
1767
|
+
Whether to launch processing to generate L2E netCDF4 file(s) from L1 data.
|
|
1768
|
+
The default value is ``True``.
|
|
1769
|
+
l2m_processing : bool
|
|
1770
|
+
Whether to launch processing to generate L2M netCDF4 file(s) from L1 data.
|
|
1771
|
+
The default value is ``True``.
|
|
1772
|
+
force : bool
|
|
1773
|
+
If ``True``, overwrite existing data into destination directories.
|
|
1774
|
+
If ``False``, raise an error if there are already data into destination directories.
|
|
1775
|
+
The default value is ``False``.
|
|
1776
|
+
verbose : bool
|
|
1777
|
+
Whether to print detailed processing information into terminal.
|
|
1778
|
+
The default value is ``False``.
|
|
1779
|
+
parallel : bool
|
|
1780
|
+
If ``True``, the files are processed simultaneously in multiple processes.
|
|
1781
|
+
Each process will use a single thread to avoid issues with the HDF/netCDF library.
|
|
1782
|
+
By default, the number of process is defined with ``os.cpu_count()``.
|
|
1783
|
+
If ``False``, the files are processed sequentially in a single process.
|
|
1784
|
+
If ``False``, multi-threading is automatically exploited to speed up I/0 tasks.
|
|
1785
|
+
debugging_mode : bool
|
|
1786
|
+
If ``True``, it reduces the amount of data to process.
|
|
1787
|
+
For L0A, it processes just the first 3 raw data files.
|
|
1788
|
+
For L0B, it processes 100 rows sampled from 3 L0A files.
|
|
1789
|
+
The default value is ``False``.
|
|
1790
|
+
data_archive_dir : str (optional)
|
|
1791
|
+
The directory path where the DISDRODB Data Archive is located.
|
|
1792
|
+
The directory path must end with ``<...>/DISDRODB``.
|
|
1793
|
+
If ``None``, it uses the ``data_archive_dir`` path specified
|
|
1794
|
+
in the DISDRODB active configuration.
|
|
1795
|
+
metadata_archive_dir : str (optional)
|
|
1796
|
+
The directory path where the DISDRODB Metadata Archive is located.
|
|
1797
|
+
The directory path must end with ``<...>/DISDRODB-METADATA/DISDRODB``.
|
|
1798
|
+
If ``None``, it uses the ``metadata_archive_dir`` path specified
|
|
1799
|
+
in the DISDRODB active configuration.
|
|
1800
|
+
"""
|
|
1801
|
+
# Determine required product based on the lowest level processing requested
|
|
1802
|
+
required_product = validate_processing_flags_and_get_required_product(
|
|
1803
|
+
l0a_processing=l0a_processing,
|
|
1804
|
+
l0b_processing=l0b_processing,
|
|
1805
|
+
l0c_processing=l0c_processing,
|
|
1806
|
+
l1_processing=l1_processing,
|
|
1807
|
+
l2e_processing=l2e_processing,
|
|
1808
|
+
l2m_processing=l2m_processing,
|
|
1809
|
+
)
|
|
1810
|
+
|
|
1811
|
+
# Get list of available stations
|
|
1812
|
+
list_info = available_stations(
|
|
1813
|
+
# DISDRODB root directories
|
|
1814
|
+
data_archive_dir=data_archive_dir,
|
|
1815
|
+
metadata_archive_dir=metadata_archive_dir,
|
|
1816
|
+
# Stations arguments
|
|
1817
|
+
data_sources=data_sources,
|
|
1818
|
+
campaign_names=campaign_names,
|
|
1819
|
+
station_names=station_names,
|
|
1820
|
+
# Search options
|
|
1821
|
+
product=required_product,
|
|
1822
|
+
raise_error_if_empty=True,
|
|
1823
|
+
)
|
|
1824
|
+
|
|
1825
|
+
# Print message
|
|
1826
|
+
n_stations = len(list_info)
|
|
1827
|
+
print(f"Complete processing of {n_stations} stations started.")
|
|
1828
|
+
|
|
1829
|
+
# Loop over stations
|
|
1830
|
+
for data_source, campaign_name, station_name in list_info:
|
|
1831
|
+
print(f"Complete processing of {data_source} {campaign_name} {station_name} station started.")
|
|
1832
|
+
# Run processing
|
|
1833
|
+
run_station(
|
|
1834
|
+
# DISDRODB root directories
|
|
1835
|
+
data_archive_dir=data_archive_dir,
|
|
1836
|
+
metadata_archive_dir=metadata_archive_dir,
|
|
1837
|
+
# Station arguments
|
|
1838
|
+
data_source=data_source,
|
|
1839
|
+
campaign_name=campaign_name,
|
|
1840
|
+
station_name=station_name,
|
|
1841
|
+
# L0 archive options
|
|
1842
|
+
l0a_processing=l0a_processing,
|
|
1843
|
+
l0b_processing=l0b_processing,
|
|
1844
|
+
l0c_processing=l0c_processing,
|
|
1845
|
+
remove_l0a=remove_l0a,
|
|
1846
|
+
remove_l0b=remove_l0b,
|
|
1847
|
+
# Higher level processing options
|
|
1848
|
+
l1_processing=l1_processing,
|
|
1849
|
+
l2e_processing=l2e_processing,
|
|
1850
|
+
l2m_processing=l2m_processing,
|
|
1851
|
+
# Process options
|
|
1852
|
+
force=force,
|
|
1853
|
+
verbose=verbose,
|
|
1854
|
+
debugging_mode=debugging_mode,
|
|
1855
|
+
parallel=parallel,
|
|
1856
|
+
)
|
|
1857
|
+
print(f"Complete processing of {data_source} {campaign_name} {station_name} station ended.")
|
|
1858
|
+
|
|
1859
|
+
print(f"Complete processing of {n_stations} stations completed.")
|
|
1860
|
+
|
|
1861
|
+
|
|
1862
|
+
####--------------------------------------------------------------------------.
|
|
1863
|
+
#### Summary Wrappers
|
|
1441
1864
|
def create_summary(
|
|
1442
1865
|
data_sources=None,
|
|
1443
1866
|
campaign_names=None,
|
|
@@ -1508,6 +1931,3 @@ def create_summary(
|
|
|
1508
1931
|
temporal_resolution=temporal_resolution,
|
|
1509
1932
|
)
|
|
1510
1933
|
print("Creation of station summaries has terminated.")
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
####--------------------------------------------------------------------------.
|
disdrodb/scattering/__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
|
|
@@ -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
|
|
@@ -79,9 +79,9 @@ def get_axis_ratio_andsager_1999(diameter):
|
|
|
79
79
|
return axis_ratio
|
|
80
80
|
|
|
81
81
|
|
|
82
|
-
def
|
|
82
|
+
def get_axis_ratio_parsivel(diameter):
|
|
83
83
|
"""
|
|
84
|
-
Compute the axis ratio of raindrops
|
|
84
|
+
Compute the axis ratio of raindrops as used by OTT Parsivel sensors.
|
|
85
85
|
|
|
86
86
|
This axis ratio is assumed by OTT Parsivel sensors internally to compute the
|
|
87
87
|
reported particle size (Deq).
|
|
@@ -279,7 +279,7 @@ def get_axis_ratio_thurai_2007(diameter):
|
|
|
279
279
|
AXIS_RATIO_MODELS = {
|
|
280
280
|
"Thurai2005": get_axis_ratio_thurai_2005,
|
|
281
281
|
"Thurai2007": get_axis_ratio_thurai_2007,
|
|
282
|
-
"
|
|
282
|
+
"Parsivel": get_axis_ratio_parsivel,
|
|
283
283
|
"Brandes2002": get_axis_ratio_brandes_2002,
|
|
284
284
|
"Pruppacher1970": get_axis_ratio_pruppacher_1970,
|
|
285
285
|
"Beard1987": get_axis_ratio_beard_1987,
|
|
@@ -307,7 +307,7 @@ def get_axis_ratio_model(model):
|
|
|
307
307
|
----------
|
|
308
308
|
model : str
|
|
309
309
|
The model to use for calculating the axis ratio. Available models are:
|
|
310
|
-
'Thurai2005', 'Thurai2007', '
|
|
310
|
+
'Thurai2005', 'Thurai2007', 'Parsivel', 'Brandes2002',
|
|
311
311
|
'Pruppacher1970', 'Beard1987', 'Andsager1999'.
|
|
312
312
|
|
|
313
313
|
Returns
|
|
@@ -339,7 +339,7 @@ def get_axis_ratio(diameter, model):
|
|
|
339
339
|
Raindrops diameter in mm.
|
|
340
340
|
model : str
|
|
341
341
|
The axis ratio model to use for calculating the axis ratio. Available models are:
|
|
342
|
-
'Thurai2005', 'Thurai2007', '
|
|
342
|
+
'Thurai2005', 'Thurai2007', 'Parsivel', 'Brandes2002',
|
|
343
343
|
'Pruppacher1970', 'Beard1987', 'Andsager1999'.
|
|
344
344
|
|
|
345
345
|
Returns
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -----------------------------------------------------------------------------.
|
|
2
|
-
# Copyright (c) 2021-
|
|
2
|
+
# Copyright (c) 2021-2026 DISDRODB developers
|
|
3
3
|
#
|
|
4
4
|
# temperaturehis 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
|
|
@@ -56,7 +56,7 @@ def get_refractive_index_function(permittivity_model):
|
|
|
56
56
|
----------
|
|
57
57
|
model : str
|
|
58
58
|
The model to use for calculating the complex refractive index. Available models are:
|
|
59
|
-
'Liebe1991', 'Liebe1991v2', '
|
|
59
|
+
'Liebe1991', 'Liebe1991v2', 'Ellison2007', 'Turner2016', 'Turner2016SLC'.
|
|
60
60
|
|
|
61
61
|
Returns
|
|
62
62
|
-------
|
|
@@ -104,7 +104,7 @@ def get_refractive_index(temperature, frequency, permittivity_model):
|
|
|
104
104
|
Frequency in GHz.
|
|
105
105
|
permittivity_model : str
|
|
106
106
|
The permittivity model to use for calculating the complex refractive index.
|
|
107
|
-
Available models are: 'Liebe1991', 'Liebe1991v2', '
|
|
107
|
+
Available models are: 'Liebe1991', 'Liebe1991v2', 'Ellison2007', 'Turner2016', 'Turner2016SLC'.
|
|
108
108
|
See available models with ``disdrodb.scattering.available_permittivity_models()``.
|
|
109
109
|
|
|
110
110
|
Returns
|
|
@@ -309,7 +309,7 @@ def get_rain_refractive_index_liebe1991(temperature, frequency):
|
|
|
309
309
|
return m
|
|
310
310
|
|
|
311
311
|
|
|
312
|
-
def
|
|
312
|
+
def get_rain_refractive_index_ellison2007(temperature, frequency):
|
|
313
313
|
"""Compute the complex refractive index according to Ellison (2005) model.
|
|
314
314
|
|
|
315
315
|
Parameters
|
|
@@ -343,8 +343,8 @@ def get_rain_refractive_index_ellison2005(temperature, frequency):
|
|
|
343
343
|
temperature = ensure_array(temperature)
|
|
344
344
|
|
|
345
345
|
# Check frequency and temperature within validity range
|
|
346
|
-
temperature = check_temperature_validity_range(temperature, vmin=0, vmax=100, permittivity_model="
|
|
347
|
-
frequency = check_frequency_validity_range(frequency, vmin=0, vmax=1000, permittivity_model="
|
|
346
|
+
temperature = check_temperature_validity_range(temperature, vmin=0, vmax=100, permittivity_model="Ellison2007")
|
|
347
|
+
frequency = check_frequency_validity_range(frequency, vmin=0, vmax=1000, permittivity_model="Ellison2007")
|
|
348
348
|
|
|
349
349
|
# Conversion of frequency to Hz
|
|
350
350
|
frequency = frequency / 1e-9
|
|
@@ -479,7 +479,7 @@ def get_rain_refractive_index_turner2016(frequency, temperature):
|
|
|
479
479
|
def get_rayleigh_dielectric_factor(m):
|
|
480
480
|
"""Compute the Rayleigh dielectric factor |K|**2 from the complex refractive index.
|
|
481
481
|
|
|
482
|
-
The magnitude squared of the complex dielectric
|
|
482
|
+
The magnitude squared of the complex dielectric constant factor for liquid water,
|
|
483
483
|
relative to the surrounding medium (typically air).
|
|
484
484
|
|
|
485
485
|
This factor is used to compute the radar reflectivity.
|
|
@@ -505,6 +505,6 @@ def get_rayleigh_dielectric_factor(m):
|
|
|
505
505
|
REFRACTIVE_INDEX_MODELS = {
|
|
506
506
|
"Liebe1991": get_rain_refractive_index_liebe1991,
|
|
507
507
|
"Liebe1991single": get_rain_refractive_index_liebe1991_single,
|
|
508
|
-
"
|
|
508
|
+
"Ellison2007": get_rain_refractive_index_ellison2007,
|
|
509
509
|
"Turner2016": get_rain_refractive_index_turner2016,
|
|
510
510
|
}
|
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):
|