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/l1.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
|
|
@@ -42,6 +40,8 @@ from disdrodb.configs import (
|
|
|
42
40
|
get_folder_partitioning,
|
|
43
41
|
get_metadata_archive_dir,
|
|
44
42
|
)
|
|
43
|
+
from disdrodb.constants import METEOROLOGICAL_VARIABLES
|
|
44
|
+
from disdrodb.l1.classification import TEMPERATURE_VARIABLES
|
|
45
45
|
from disdrodb.l1.processing import generate_l1
|
|
46
46
|
from disdrodb.l1.resampling import resample_dataset
|
|
47
47
|
from disdrodb.metadata.reader import read_station_metadata
|
|
@@ -145,11 +145,14 @@ def _generate_l1(
|
|
|
145
145
|
):
|
|
146
146
|
"""Define L1 product processing."""
|
|
147
147
|
# Open the L0C netCDF files
|
|
148
|
+
# - precip_flag used for OceanRain ODM470 data only
|
|
149
|
+
# - Missing variables in dataset are simply not selected
|
|
150
|
+
variables = ["raw_drop_number", "qc_time", "precip_flag", *TEMPERATURE_VARIABLES, *METEOROLOGICAL_VARIABLES]
|
|
148
151
|
ds = open_netcdf_files(
|
|
149
152
|
filepaths,
|
|
150
153
|
start_time=start_time,
|
|
151
154
|
end_time=end_time,
|
|
152
|
-
variables=
|
|
155
|
+
variables=variables,
|
|
153
156
|
parallel=False,
|
|
154
157
|
compute=True,
|
|
155
158
|
)
|
|
@@ -313,7 +316,7 @@ def run_l1_station(
|
|
|
313
316
|
return
|
|
314
317
|
|
|
315
318
|
# -------------------------------------------------------------------------.
|
|
316
|
-
# Read station metadata and
|
|
319
|
+
# Read station metadata and sensor name
|
|
317
320
|
metadata = read_station_metadata(
|
|
318
321
|
metadata_archive_dir=metadata_archive_dir,
|
|
319
322
|
data_source=data_source,
|
|
@@ -347,7 +350,6 @@ def run_l1_station(
|
|
|
347
350
|
|
|
348
351
|
# Retrieve product options
|
|
349
352
|
product_options = l1_processing_options.get_product_options(temporal_resolution)
|
|
350
|
-
product_options = product_options.get("product_options")
|
|
351
353
|
|
|
352
354
|
# ------------------------------------------------------------------.
|
|
353
355
|
# Create product directory
|
disdrodb/routines/l2.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
|
|
@@ -297,6 +297,7 @@ def run_l2e_station(
|
|
|
297
297
|
campaign_name=campaign_name,
|
|
298
298
|
station_name=station_name,
|
|
299
299
|
)
|
|
300
|
+
sensor_name = metadata["sensor_name"]
|
|
300
301
|
sample_interval = metadata["measurement_interval"]
|
|
301
302
|
if isinstance(sample_interval, list):
|
|
302
303
|
sample_interval = min(sample_interval)
|
|
@@ -305,7 +306,7 @@ def run_l2e_station(
|
|
|
305
306
|
# Generate products for each temporal resolution
|
|
306
307
|
# temporal_resolution = "1MIN"
|
|
307
308
|
# temporal_resolution = "10MIN"
|
|
308
|
-
temporal_resolutions = get_product_temporal_resolutions(product)
|
|
309
|
+
temporal_resolutions = get_product_temporal_resolutions(product=product, sensor_name=sensor_name)
|
|
309
310
|
for temporal_resolution in temporal_resolutions:
|
|
310
311
|
|
|
311
312
|
# ------------------------------------------------------------------.
|
|
@@ -339,6 +340,7 @@ def run_l2e_station(
|
|
|
339
340
|
l2e_processing_options = L2ProcessingOptions(
|
|
340
341
|
product=product,
|
|
341
342
|
temporal_resolution=temporal_resolution,
|
|
343
|
+
sensor_name=sensor_name,
|
|
342
344
|
filepaths=filepaths,
|
|
343
345
|
parallel=parallel,
|
|
344
346
|
)
|
|
@@ -692,6 +694,7 @@ def run_l2m_station(
|
|
|
692
694
|
campaign_name=campaign_name,
|
|
693
695
|
station_name=station_name,
|
|
694
696
|
)
|
|
697
|
+
sensor_name = metadata["sensor_name"]
|
|
695
698
|
sample_interval = metadata["measurement_interval"]
|
|
696
699
|
if isinstance(sample_interval, list):
|
|
697
700
|
sample_interval = min(sample_interval)
|
|
@@ -700,7 +703,7 @@ def run_l2m_station(
|
|
|
700
703
|
# Loop
|
|
701
704
|
# temporal_resolution = "1MIN"
|
|
702
705
|
# temporal_resolution = "10MIN"
|
|
703
|
-
temporal_resolutions = get_product_temporal_resolutions(product)
|
|
706
|
+
temporal_resolutions = get_product_temporal_resolutions(product=product, sensor_name=sensor_name)
|
|
704
707
|
for temporal_resolution in temporal_resolutions:
|
|
705
708
|
|
|
706
709
|
# ------------------------------------------------------------------.
|
|
@@ -734,6 +737,7 @@ def run_l2m_station(
|
|
|
734
737
|
l2m_processing_options = L2ProcessingOptions(
|
|
735
738
|
product=product,
|
|
736
739
|
temporal_resolution=temporal_resolution,
|
|
740
|
+
sensor_name=sensor_name,
|
|
737
741
|
filepaths=filepaths,
|
|
738
742
|
parallel=parallel,
|
|
739
743
|
)
|
|
@@ -766,7 +770,7 @@ def run_l2m_station(
|
|
|
766
770
|
# -----------------------------------------------------------------.
|
|
767
771
|
# Retrieve product-model options
|
|
768
772
|
product_options = copy.deepcopy(global_product_options)
|
|
769
|
-
model_options = get_model_options(
|
|
773
|
+
model_options = get_model_options(model_name=model_name)
|
|
770
774
|
product_options["product_options"].update(model_options)
|
|
771
775
|
|
|
772
776
|
psd_model = model_options["psd_model"]
|
disdrodb/routines/options.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
|
|
@@ -17,9 +17,10 @@
|
|
|
17
17
|
"""Implements ProcessingOption class for DISDRODB routines."""
|
|
18
18
|
import json
|
|
19
19
|
import os
|
|
20
|
+
from pathlib import Path
|
|
20
21
|
|
|
21
22
|
import disdrodb
|
|
22
|
-
from disdrodb.api.checks import check_product,
|
|
23
|
+
from disdrodb.api.checks import check_product, check_temporal_resolution
|
|
23
24
|
from disdrodb.api.info import group_filepaths
|
|
24
25
|
from disdrodb.configs import get_products_configs_dir
|
|
25
26
|
from disdrodb.utils.archiving import define_temporal_partitions, group_files_by_temporal_partitions
|
|
@@ -28,22 +29,68 @@ from disdrodb.utils.routines import is_possible_product
|
|
|
28
29
|
from disdrodb.utils.time import ensure_timedelta_seconds, get_sampling_information
|
|
29
30
|
from disdrodb.utils.yaml import read_yaml
|
|
30
31
|
|
|
31
|
-
# TODO: Test ensure recursive update for product_options key, do not replace just "product_options" dict !
|
|
32
|
-
# get_product_options(product="L2E", temporal_resolution="10MIN")
|
|
33
|
-
# get_product_options(product="L2M", temporal_resolution="10MIN")
|
|
34
|
-
# get_product_options(product="L1")
|
|
35
|
-
# get_product_options(product="L1", temporal_resolution="1MIN")
|
|
36
|
-
# get_product_options(product="L1", temporal_resolution="1MIN", sensor_name="PARSIVEL")
|
|
37
32
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
#
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def
|
|
33
|
+
def get_product_options_directory(products_configs_dir, product, sensor_name=None):
|
|
34
|
+
"""Retrieve path to the product options directory."""
|
|
35
|
+
products_configs_dir = str(products_configs_dir) # convert pathlib to str
|
|
36
|
+
if sensor_name is None:
|
|
37
|
+
return os.path.join(products_configs_dir, product)
|
|
38
|
+
return os.path.join(products_configs_dir, product, sensor_name)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def get_l2m_model_settings_directory(products_configs_dir):
|
|
42
|
+
"""Retrieve path to the product options directory."""
|
|
43
|
+
return os.path.join(products_configs_dir, "L2M", "MODELS")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def get_l2m_model_settings_files(products_configs_dir):
|
|
47
|
+
"""Retrieve path to the product options directory."""
|
|
48
|
+
models_dir = Path(get_l2m_model_settings_directory(products_configs_dir))
|
|
49
|
+
models_files = list(models_dir.glob("*.yaml")) + list(models_dir.glob("*.yml"))
|
|
50
|
+
return models_files
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def get_product_global_options_path(products_configs_dir, product, sensor_name=None):
|
|
54
|
+
"""Retrieve path to the product global options."""
|
|
55
|
+
product_options_dir = get_product_options_directory(
|
|
56
|
+
products_configs_dir=products_configs_dir,
|
|
57
|
+
product=product,
|
|
58
|
+
sensor_name=sensor_name,
|
|
59
|
+
)
|
|
60
|
+
product_global_options_path = os.path.join(product_options_dir, "global.yaml")
|
|
61
|
+
if os.path.exists(product_global_options_path):
|
|
62
|
+
return product_global_options_path
|
|
63
|
+
|
|
64
|
+
product_options_dir = get_product_options_directory(
|
|
65
|
+
products_configs_dir=products_configs_dir,
|
|
66
|
+
product=product,
|
|
67
|
+
sensor_name=None,
|
|
68
|
+
)
|
|
69
|
+
global_options_path = os.path.join(product_options_dir, "global.yaml") # this must exists
|
|
70
|
+
return global_options_path
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def get_product_custom_options_path(products_configs_dir, product, temporal_resolution, sensor_name=None):
|
|
74
|
+
"""Retrieve path to the product temporal resolution custom options."""
|
|
75
|
+
product_options_dir = get_product_options_directory(
|
|
76
|
+
products_configs_dir=products_configs_dir,
|
|
77
|
+
product=product,
|
|
78
|
+
sensor_name=sensor_name,
|
|
79
|
+
)
|
|
80
|
+
product_global_options_path = os.path.join(product_options_dir, f"{temporal_resolution}.yaml")
|
|
81
|
+
if os.path.exists(product_global_options_path):
|
|
82
|
+
return product_global_options_path
|
|
83
|
+
|
|
84
|
+
product_options_dir = get_product_options_directory(
|
|
85
|
+
products_configs_dir=products_configs_dir,
|
|
86
|
+
product=product,
|
|
87
|
+
sensor_name=None,
|
|
88
|
+
)
|
|
89
|
+
custom_options_path = os.path.join(product_options_dir, f"{temporal_resolution}.yaml") # this might not exists
|
|
90
|
+
return custom_options_path
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def get_product_options(product, temporal_resolution=None, sensor_name=None, products_configs_dir=None):
|
|
47
94
|
"""Return DISDRODB product options.
|
|
48
95
|
|
|
49
96
|
If temporal resolution is not provided, it returns the global product option.
|
|
@@ -51,16 +98,20 @@ def get_product_options(product, temporal_resolution=None, sensor_name=None):
|
|
|
51
98
|
If product="L1" and sensor_name is specified, it customize product options also by sensor.
|
|
52
99
|
"""
|
|
53
100
|
# Retrieve products configuration directory
|
|
54
|
-
products_configs_dir = get_products_configs_dir()
|
|
55
|
-
|
|
56
|
-
# Validate DISDRODB products configuration
|
|
57
|
-
validate_product_configuration(products_configs_dir)
|
|
101
|
+
products_configs_dir = get_products_configs_dir(products_configs_dir=products_configs_dir)
|
|
58
102
|
|
|
59
103
|
# Check product
|
|
60
104
|
check_product(product)
|
|
61
105
|
|
|
106
|
+
# Get product global options path
|
|
107
|
+
global_options_path = get_product_global_options_path(
|
|
108
|
+
products_configs_dir=products_configs_dir,
|
|
109
|
+
product=product,
|
|
110
|
+
sensor_name=sensor_name,
|
|
111
|
+
)
|
|
112
|
+
|
|
62
113
|
# Retrieve global product options (when no temporal resolution !)
|
|
63
|
-
global_options = read_yaml(
|
|
114
|
+
global_options = read_yaml(global_options_path)
|
|
64
115
|
if temporal_resolution is None:
|
|
65
116
|
global_options = check_availability_radar_simulations(global_options)
|
|
66
117
|
return global_options
|
|
@@ -72,43 +123,44 @@ def get_product_options(product, temporal_resolution=None, sensor_name=None):
|
|
|
72
123
|
global_options.pop("temporal_resolutions", None)
|
|
73
124
|
|
|
74
125
|
# Read custom options for specific temporal resolution
|
|
75
|
-
custom_options_path =
|
|
126
|
+
custom_options_path = get_product_custom_options_path(
|
|
127
|
+
products_configs_dir=products_configs_dir,
|
|
128
|
+
product=product,
|
|
129
|
+
sensor_name=sensor_name,
|
|
130
|
+
temporal_resolution=temporal_resolution,
|
|
131
|
+
)
|
|
76
132
|
if not os.path.exists(custom_options_path):
|
|
77
133
|
return global_options
|
|
78
134
|
custom_options = read_yaml(custom_options_path)
|
|
79
135
|
|
|
80
|
-
#
|
|
136
|
+
# Update global options with the custom options specified
|
|
81
137
|
options = global_options.copy()
|
|
82
|
-
|
|
83
|
-
|
|
138
|
+
keys_options = ["archive_options", "product_options", "radar_options"]
|
|
139
|
+
for key in keys_options:
|
|
140
|
+
if key in custom_options:
|
|
141
|
+
options[key].update(custom_options.pop(key)) # Update with only one
|
|
142
|
+
|
|
143
|
+
# Update remaining flat keys
|
|
84
144
|
options.update(custom_options)
|
|
85
145
|
|
|
86
146
|
# Check availability of radar simulations
|
|
87
147
|
options = check_availability_radar_simulations(options)
|
|
88
148
|
|
|
89
|
-
# Customize product options by sensor if L1 product
|
|
90
|
-
if product == "L1" and sensor_name is not None:
|
|
91
|
-
check_sensor_name(sensor_name)
|
|
92
|
-
custom_options_path = os.path.join(products_configs_dir, product, sensor_name, f"{temporal_resolution}.yaml")
|
|
93
|
-
if not os.path.exists(custom_options_path):
|
|
94
|
-
return options
|
|
95
|
-
custom_options = read_yaml(custom_options_path)
|
|
96
|
-
if "product_options" in custom_options:
|
|
97
|
-
options["product_options"].update(custom_options.pop("product_options"))
|
|
98
149
|
return options
|
|
99
150
|
|
|
100
151
|
|
|
101
|
-
def get_product_temporal_resolutions(product):
|
|
152
|
+
def get_product_temporal_resolutions(product, sensor_name=None):
|
|
102
153
|
"""Return DISDRODB products temporal resolutions."""
|
|
103
154
|
# Check only L2E and L2M
|
|
104
|
-
return get_product_options(product)["temporal_resolutions"]
|
|
155
|
+
return get_product_options(product, sensor_name=sensor_name)["temporal_resolutions"]
|
|
105
156
|
|
|
106
157
|
|
|
107
|
-
def get_model_options(
|
|
158
|
+
def get_model_options(model_name, products_configs_dir=None):
|
|
108
159
|
"""Return DISDRODB L2M product model options."""
|
|
109
160
|
# Retrieve products configuration directory
|
|
110
|
-
products_configs_dir = get_products_configs_dir()
|
|
111
|
-
|
|
161
|
+
products_configs_dir = get_products_configs_dir(products_configs_dir=products_configs_dir)
|
|
162
|
+
models_settings_dir = get_l2m_model_settings_directory(products_configs_dir)
|
|
163
|
+
model_options_path = os.path.join(models_settings_dir, f"{model_name}.yaml")
|
|
112
164
|
model_options = read_yaml(model_options_path)
|
|
113
165
|
return model_options
|
|
114
166
|
|
|
@@ -120,19 +172,6 @@ def check_availability_radar_simulations(options):
|
|
|
120
172
|
return options
|
|
121
173
|
|
|
122
174
|
|
|
123
|
-
def validate_product_configuration(products_configs_dir):
|
|
124
|
-
"""Validate the DISDRODB products configuration files."""
|
|
125
|
-
# TODO: Implement validation of DISDRODB products configuration files with pydantic
|
|
126
|
-
# TODO: Raise warning if L1 temporal resolutions does not includes all temporal resolutions of L2 products.
|
|
127
|
-
# TODO: Raise warning if L2E temporal resolutions does not includes all temporal resolutions of L2M products.
|
|
128
|
-
# if stategy_event, check neighbor_time_interval >= sample_interval !
|
|
129
|
-
# if temporal_resolution_to_seconds(neighbor_time_interval) < temporal_resolution_to_seconds(sample_interval):
|
|
130
|
-
# msg = "'neighbor_time_interval' must be at least equal to the dataset sample interval ({sample_interval})"
|
|
131
|
-
# raise ValueError(msg)
|
|
132
|
-
|
|
133
|
-
pass
|
|
134
|
-
|
|
135
|
-
|
|
136
175
|
def _define_blocks_offsets(sample_interval, temporal_resolution):
|
|
137
176
|
"""Define blocks offset for resampling logic."""
|
|
138
177
|
# Retrieve accumulation_interval and rolling option
|
|
@@ -152,6 +191,19 @@ def _define_blocks_offsets(sample_interval, temporal_resolution):
|
|
|
152
191
|
return block_starts_offset, block_ends_offset
|
|
153
192
|
|
|
154
193
|
|
|
194
|
+
class L0CProcessingOptions:
|
|
195
|
+
"""Define L0C product processing options."""
|
|
196
|
+
|
|
197
|
+
def __init__(self, sensor_name):
|
|
198
|
+
"""Define DISDRODB L0C product processing options."""
|
|
199
|
+
product = "L0C"
|
|
200
|
+
options = get_product_options(product=product, sensor_name=sensor_name)["archive_options"]
|
|
201
|
+
|
|
202
|
+
self.product = product
|
|
203
|
+
self.folder_partitioning = options["folder_partitioning"]
|
|
204
|
+
self.product_frequency = options["strategy_options"]["freq"]
|
|
205
|
+
|
|
206
|
+
|
|
155
207
|
class L1ProcessingOptions:
|
|
156
208
|
"""Define L1 product processing options."""
|
|
157
209
|
|
|
@@ -162,7 +214,7 @@ class L1ProcessingOptions:
|
|
|
162
214
|
# ---------------------------------------------------------------------.
|
|
163
215
|
# Define temporal resolutions for which to retrieve processing options
|
|
164
216
|
if temporal_resolutions is None:
|
|
165
|
-
temporal_resolutions = get_product_temporal_resolutions(product)
|
|
217
|
+
temporal_resolutions = get_product_temporal_resolutions(product, sensor_name=sensor_name)
|
|
166
218
|
elif isinstance(temporal_resolutions, str):
|
|
167
219
|
temporal_resolutions = [temporal_resolutions]
|
|
168
220
|
_ = [check_temporal_resolution(temporal_resolution) for temporal_resolution in temporal_resolutions]
|
|
@@ -202,12 +254,9 @@ class L1ProcessingOptions:
|
|
|
202
254
|
archive_options = product_options.pop("archive_options")
|
|
203
255
|
|
|
204
256
|
dict_product_options[temporal_resolution] = product_options
|
|
205
|
-
|
|
257
|
+
|
|
206
258
|
# Define folder partitioning
|
|
207
|
-
|
|
208
|
-
dict_folder_partitioning[temporal_resolution] = disdrodb.config.get("folder_partitioning")
|
|
209
|
-
else:
|
|
210
|
-
dict_folder_partitioning[temporal_resolution] = archive_options.pop("folder_partitioning")
|
|
259
|
+
dict_folder_partitioning[temporal_resolution] = archive_options.pop("folder_partitioning")
|
|
211
260
|
|
|
212
261
|
# -------------------------------------------------------------------------.
|
|
213
262
|
# Define list of temporal partitions
|
|
@@ -284,40 +333,34 @@ class L1ProcessingOptions:
|
|
|
284
333
|
self.dict_folder_partitioning = dict_folder_partitioning
|
|
285
334
|
|
|
286
335
|
def group_files_by_temporal_partitions(self, temporal_resolution):
|
|
287
|
-
"""Return files partitions dictionary for a specific
|
|
336
|
+
"""Return files partitions dictionary for a specific L1 product."""
|
|
288
337
|
return self.dict_files_partitions[temporal_resolution]
|
|
289
338
|
|
|
290
|
-
def get_product_options(self, temporal_resolution):
|
|
291
|
-
"""Return product options dictionary for a specific
|
|
292
|
-
return self.dict_product_options[temporal_resolution]
|
|
339
|
+
def get_product_options(self, temporal_resolution): # noqa
|
|
340
|
+
"""Return product options dictionary for a specific L1 product."""
|
|
341
|
+
return {} # self.dict_product_options[temporal_resolution]
|
|
293
342
|
|
|
294
343
|
def get_folder_partitioning(self, temporal_resolution):
|
|
295
|
-
"""Return the folder partitioning for a specific
|
|
296
|
-
# to be used for logs and files !
|
|
344
|
+
"""Return the folder partitioning for a specific L1 product."""
|
|
297
345
|
return self.dict_folder_partitioning[temporal_resolution]
|
|
298
346
|
|
|
299
347
|
|
|
300
348
|
class L2ProcessingOptions:
|
|
301
349
|
"""Define L2 products processing options."""
|
|
302
350
|
|
|
303
|
-
def __init__(self, product, filepaths, parallel, temporal_resolution):
|
|
351
|
+
def __init__(self, product, filepaths, parallel, temporal_resolution, sensor_name):
|
|
304
352
|
"""Define DISDRODB L2 products processing options."""
|
|
305
|
-
import disdrodb
|
|
306
|
-
|
|
307
353
|
# Check temporal resolution
|
|
308
354
|
check_temporal_resolution(temporal_resolution)
|
|
309
355
|
|
|
310
356
|
# Get product options
|
|
311
|
-
product_options = get_product_options(product, temporal_resolution=temporal_resolution)
|
|
357
|
+
product_options = get_product_options(product, temporal_resolution=temporal_resolution, sensor_name=sensor_name)
|
|
312
358
|
|
|
313
359
|
# Extract processing options
|
|
314
360
|
archive_options = product_options.pop("archive_options")
|
|
315
361
|
|
|
316
362
|
# Define folder partitioning
|
|
317
|
-
|
|
318
|
-
folder_partitioning = disdrodb.config.get("folder_partitioning")
|
|
319
|
-
else:
|
|
320
|
-
folder_partitioning = archive_options.pop("folder_partitioning")
|
|
363
|
+
folder_partitioning = archive_options.pop("folder_partitioning")
|
|
321
364
|
|
|
322
365
|
# Define files temporal partitions
|
|
323
366
|
# - [{start_time: np.datetime64, end_time: np.datetime64}, ....]
|