disdrodb 0.0.21__py3-none-any.whl → 0.1.1__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 +132 -15
- disdrodb/_config.py +4 -2
- disdrodb/_version.py +9 -4
- disdrodb/api/checks.py +264 -237
- disdrodb/api/configs.py +4 -8
- disdrodb/api/create_directories.py +235 -290
- disdrodb/api/info.py +217 -26
- disdrodb/api/io.py +306 -270
- disdrodb/api/path.py +597 -173
- disdrodb/api/search.py +486 -0
- disdrodb/{metadata/scripts → cli}/disdrodb_check_metadata_archive.py +12 -7
- disdrodb/{utils/pandas.py → cli/disdrodb_data_archive_directory.py} +9 -18
- disdrodb/cli/disdrodb_download_archive.py +86 -0
- disdrodb/cli/disdrodb_download_metadata_archive.py +53 -0
- disdrodb/cli/disdrodb_download_station.py +84 -0
- disdrodb/{api/scripts → cli}/disdrodb_initialize_station.py +22 -10
- disdrodb/cli/disdrodb_metadata_archive_directory.py +32 -0
- disdrodb/{data_transfer/scripts/disdrodb_download_station.py → cli/disdrodb_open_data_archive.py} +22 -22
- disdrodb/cli/disdrodb_open_logs_directory.py +69 -0
- disdrodb/{data_transfer/scripts/disdrodb_upload_station.py → cli/disdrodb_open_metadata_archive.py} +22 -24
- disdrodb/cli/disdrodb_open_metadata_directory.py +71 -0
- disdrodb/cli/disdrodb_open_product_directory.py +74 -0
- disdrodb/cli/disdrodb_open_readers_directory.py +32 -0
- disdrodb/{l0/scripts → cli}/disdrodb_run_l0.py +38 -31
- disdrodb/{l0/scripts → cli}/disdrodb_run_l0_station.py +32 -30
- disdrodb/{l0/scripts → cli}/disdrodb_run_l0a.py +30 -21
- disdrodb/{l0/scripts → cli}/disdrodb_run_l0a_station.py +24 -33
- disdrodb/{l0/scripts → cli}/disdrodb_run_l0b.py +30 -21
- disdrodb/{l0/scripts → cli}/disdrodb_run_l0b_station.py +25 -34
- disdrodb/cli/disdrodb_run_l0c.py +130 -0
- disdrodb/cli/disdrodb_run_l0c_station.py +129 -0
- disdrodb/cli/disdrodb_run_l1.py +122 -0
- disdrodb/cli/disdrodb_run_l1_station.py +121 -0
- disdrodb/cli/disdrodb_run_l2e.py +122 -0
- disdrodb/cli/disdrodb_run_l2e_station.py +122 -0
- disdrodb/cli/disdrodb_run_l2m.py +122 -0
- disdrodb/cli/disdrodb_run_l2m_station.py +122 -0
- disdrodb/cli/disdrodb_upload_archive.py +105 -0
- disdrodb/cli/disdrodb_upload_station.py +98 -0
- disdrodb/configs.py +90 -25
- disdrodb/data_transfer/__init__.py +22 -0
- disdrodb/data_transfer/download_data.py +87 -90
- disdrodb/data_transfer/upload_data.py +64 -37
- disdrodb/data_transfer/zenodo.py +15 -18
- disdrodb/docs.py +1 -1
- disdrodb/issue/__init__.py +17 -4
- disdrodb/issue/checks.py +10 -23
- disdrodb/issue/reader.py +9 -12
- disdrodb/issue/writer.py +14 -17
- disdrodb/l0/__init__.py +17 -26
- disdrodb/l0/check_configs.py +35 -23
- disdrodb/l0/check_standards.py +46 -51
- disdrodb/l0/configs/{Thies_LPM → LPM}/bins_diameter.yml +44 -44
- disdrodb/l0/configs/{Thies_LPM → LPM}/bins_velocity.yml +40 -40
- disdrodb/l0/configs/LPM/l0a_encodings.yml +80 -0
- disdrodb/l0/configs/{Thies_LPM → LPM}/l0b_cf_attrs.yml +84 -65
- disdrodb/l0/configs/{Thies_LPM → LPM}/l0b_encodings.yml +50 -9
- disdrodb/l0/configs/{Thies_LPM → LPM}/raw_data_format.yml +285 -245
- disdrodb/l0/configs/{OTT_Parsivel → PARSIVEL}/bins_diameter.yml +66 -66
- disdrodb/l0/configs/{OTT_Parsivel → PARSIVEL}/bins_velocity.yml +64 -64
- disdrodb/l0/configs/PARSIVEL/l0a_encodings.yml +32 -0
- disdrodb/l0/configs/{OTT_Parsivel → PARSIVEL}/l0b_cf_attrs.yml +23 -21
- disdrodb/l0/configs/{OTT_Parsivel → PARSIVEL}/l0b_encodings.yml +17 -17
- disdrodb/l0/configs/{OTT_Parsivel → PARSIVEL}/raw_data_format.yml +77 -77
- disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/bins_diameter.yml +64 -64
- disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/bins_velocity.yml +64 -64
- disdrodb/l0/configs/PARSIVEL2/l0a_encodings.yml +39 -0
- disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/l0b_cf_attrs.yml +28 -26
- disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/l0b_encodings.yml +20 -20
- disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/raw_data_format.yml +107 -107
- disdrodb/l0/configs/PWS100/bins_diameter.yml +173 -0
- disdrodb/l0/configs/PWS100/bins_velocity.yml +173 -0
- disdrodb/l0/configs/PWS100/l0a_encodings.yml +19 -0
- disdrodb/l0/configs/PWS100/l0b_cf_attrs.yml +76 -0
- disdrodb/l0/configs/PWS100/l0b_encodings.yml +176 -0
- disdrodb/l0/configs/PWS100/raw_data_format.yml +182 -0
- disdrodb/l0/configs/{RD_80 → RD80}/bins_diameter.yml +40 -40
- disdrodb/l0/configs/RD80/l0a_encodings.yml +16 -0
- disdrodb/l0/configs/{RD_80 → RD80}/l0b_cf_attrs.yml +3 -3
- disdrodb/l0/configs/RD80/l0b_encodings.yml +135 -0
- disdrodb/l0/configs/{RD_80 → RD80}/raw_data_format.yml +46 -50
- disdrodb/l0/l0_reader.py +216 -340
- disdrodb/l0/l0a_processing.py +237 -208
- disdrodb/l0/l0b_nc_processing.py +227 -80
- disdrodb/l0/l0b_processing.py +96 -174
- disdrodb/l0/l0c_processing.py +627 -0
- disdrodb/l0/readers/{ARM → LPM/ARM}/ARM_LPM.py +36 -58
- disdrodb/l0/readers/LPM/AUSTRALIA/MELBOURNE_2007_LPM.py +236 -0
- disdrodb/l0/readers/LPM/BRAZIL/CHUVA_LPM.py +185 -0
- disdrodb/l0/readers/LPM/BRAZIL/GOAMAZON_LPM.py +185 -0
- disdrodb/l0/readers/LPM/ITALY/GID_LPM.py +195 -0
- disdrodb/l0/readers/LPM/ITALY/GID_LPM_W.py +210 -0
- disdrodb/l0/readers/{BRAZIL/GOAMAZON_LPM.py → LPM/KIT/CHWALA.py} +97 -76
- disdrodb/l0/readers/LPM/SLOVENIA/ARSO.py +197 -0
- disdrodb/l0/readers/LPM/SLOVENIA/CRNI_VRH.py +197 -0
- disdrodb/l0/readers/{UK → LPM/UK}/DIVEN.py +14 -35
- disdrodb/l0/readers/PARSIVEL/AUSTRALIA/MELBOURNE_2007_PARSIVEL.py +157 -0
- disdrodb/l0/readers/PARSIVEL/CHINA/CHONGQING.py +113 -0
- disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/ARCTIC_2021.py +40 -57
- disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/COMMON_2011.py +37 -54
- disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/DAVOS_2009_2011.py +34 -51
- disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/EPFL_2009.py +34 -51
- disdrodb/l0/readers/{EPFL/PARADISO_2014.py → PARSIVEL/EPFL/EPFL_ROOF_2008.py} +38 -50
- disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2010.py +105 -0
- disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/EPFL_ROOF_2011.py +34 -51
- disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/EPFL_ROOF_2012.py +33 -51
- disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/GENEPI_2007.py +25 -44
- disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/GRAND_ST_BERNARD_2007.py +25 -44
- disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/GRAND_ST_BERNARD_2007_2.py +25 -44
- disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/HPICONET_2010.py +34 -51
- disdrodb/l0/readers/{EPFL/EPFL_ROOF_2010.py → PARSIVEL/EPFL/HYMEX_LTE_SOP2.py} +37 -50
- disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP3.py +111 -0
- disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/HYMEX_LTE_SOP4.py +36 -54
- disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/LOCARNO_2018.py +34 -52
- disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/LOCARNO_2019.py +38 -56
- disdrodb/l0/readers/PARSIVEL/EPFL/PARADISO_2014.py +105 -0
- disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/PARSIVEL_2007.py +27 -45
- disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/PLATO_2019.py +24 -44
- disdrodb/l0/readers/PARSIVEL/EPFL/RACLETS_2019.py +140 -0
- disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/RACLETS_2019_WJF.py +41 -59
- disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/RIETHOLZBACH_2011.py +34 -51
- disdrodb/l0/readers/PARSIVEL/EPFL/SAMOYLOV_2017.py +117 -0
- disdrodb/l0/readers/PARSIVEL/EPFL/SAMOYLOV_2019.py +137 -0
- disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/UNIL_2022.py +42 -55
- disdrodb/l0/readers/PARSIVEL/GPM/IFLOODS.py +104 -0
- disdrodb/l0/readers/{GPM → PARSIVEL/GPM}/LPVEX.py +29 -48
- disdrodb/l0/readers/PARSIVEL/GPM/MC3E.py +184 -0
- disdrodb/l0/readers/PARSIVEL/KIT/BURKINA_FASO.py +133 -0
- disdrodb/l0/readers/PARSIVEL/NCAR/CCOPE_2015.py +113 -0
- disdrodb/l0/readers/{NCAR/VORTEX_SE_2016_P1.py → PARSIVEL/NCAR/OWLES_MIPS.py} +46 -72
- disdrodb/l0/readers/PARSIVEL/NCAR/PECAN_MOBILE.py +125 -0
- disdrodb/l0/readers/{NCAR/OWLES_MIPS.py → PARSIVEL/NCAR/PLOWS_MIPS.py} +45 -64
- disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2009.py +114 -0
- disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2010.py +176 -0
- disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2010_UF.py +183 -0
- disdrodb/l0/readers/PARSIVEL/SLOVENIA/UL_FGG.py +121 -0
- disdrodb/l0/readers/{ARM/ARM_LD.py → PARSIVEL2/ARM/ARM_PARSIVEL2.py} +27 -50
- disdrodb/l0/readers/PARSIVEL2/BRAZIL/CHUVA_PARSIVEL2.py +163 -0
- disdrodb/l0/readers/PARSIVEL2/BRAZIL/GOAMAZON_PARSIVEL2.py +163 -0
- disdrodb/l0/readers/{DENMARK → PARSIVEL2/DENMARK}/EROSION_nc.py +14 -35
- disdrodb/l0/readers/PARSIVEL2/FRANCE/ENPC_PARSIVEL2.py +189 -0
- disdrodb/l0/readers/PARSIVEL2/FRANCE/SIRTA_PARSIVEL2.py +119 -0
- disdrodb/l0/readers/PARSIVEL2/GPM/GCPEX.py +104 -0
- disdrodb/l0/readers/PARSIVEL2/GPM/NSSTC.py +176 -0
- disdrodb/l0/readers/PARSIVEL2/ITALY/GID_PARSIVEL2.py +32 -0
- disdrodb/l0/readers/PARSIVEL2/MEXICO/OH_IIUNAM_nc.py +56 -0
- disdrodb/l0/readers/PARSIVEL2/NCAR/PECAN_FP3.py +120 -0
- disdrodb/l0/readers/{NCAR → PARSIVEL2/NCAR}/PECAN_MIPS.py +45 -64
- disdrodb/l0/readers/PARSIVEL2/NCAR/RELAMPAGO_PARSIVEL2.py +181 -0
- disdrodb/l0/readers/PARSIVEL2/NCAR/SNOWIE_PJ.py +160 -0
- disdrodb/l0/readers/PARSIVEL2/NCAR/SNOWIE_SB.py +160 -0
- disdrodb/l0/readers/{NCAR/PLOWS_MIPS.py → PARSIVEL2/NCAR/VORTEX_SE_2016_P1.py} +49 -66
- disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_P2.py +118 -0
- disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_PIPS.py +152 -0
- disdrodb/l0/readers/PARSIVEL2/NETHERLANDS/DELFT.py +166 -0
- disdrodb/l0/readers/PWS100/FRANCE/ENPC_PWS100.py +150 -0
- disdrodb/l0/readers/{NCAR/RELAMPAGO_RD80.py → RD80/BRAZIL/CHUVA_RD80.py} +36 -60
- disdrodb/l0/readers/{BRAZIL → RD80/BRAZIL}/GOAMAZON_RD80.py +36 -55
- disdrodb/l0/readers/{NCAR → RD80/NCAR}/CINDY_2011_RD80.py +35 -54
- disdrodb/l0/readers/{BRAZIL/CHUVA_RD80.py → RD80/NCAR/RELAMPAGO_RD80.py} +40 -54
- disdrodb/l0/readers/RD80/NOAA/PSL_RD80.py +274 -0
- disdrodb/l0/readers/template_reader_raw_netcdf_data.py +62 -0
- disdrodb/l0/readers/{reader_template.py → template_reader_raw_text_data.py} +20 -44
- disdrodb/l0/routines.py +885 -581
- disdrodb/l0/standards.py +77 -238
- disdrodb/l0/template_tools.py +105 -110
- disdrodb/l1/__init__.py +17 -0
- disdrodb/l1/beard_model.py +716 -0
- disdrodb/l1/encoding_attrs.py +635 -0
- disdrodb/l1/fall_velocity.py +260 -0
- disdrodb/l1/filters.py +192 -0
- disdrodb/l1/processing.py +202 -0
- disdrodb/l1/resampling.py +236 -0
- disdrodb/l1/routines.py +358 -0
- disdrodb/l1_env/__init__.py +17 -0
- disdrodb/l1_env/routines.py +38 -0
- disdrodb/l2/__init__.py +17 -0
- disdrodb/l2/empirical_dsd.py +1833 -0
- disdrodb/l2/event.py +388 -0
- disdrodb/l2/processing.py +528 -0
- disdrodb/l2/processing_options.py +213 -0
- disdrodb/l2/routines.py +868 -0
- disdrodb/metadata/__init__.py +9 -2
- disdrodb/metadata/checks.py +180 -124
- disdrodb/metadata/download.py +81 -0
- disdrodb/metadata/geolocation.py +146 -0
- disdrodb/metadata/info.py +20 -13
- disdrodb/metadata/manipulation.py +3 -3
- disdrodb/metadata/reader.py +59 -8
- disdrodb/metadata/search.py +77 -144
- disdrodb/metadata/standards.py +83 -80
- disdrodb/metadata/writer.py +10 -16
- disdrodb/psd/__init__.py +38 -0
- disdrodb/psd/fitting.py +2146 -0
- disdrodb/psd/models.py +774 -0
- disdrodb/routines.py +1412 -0
- disdrodb/scattering/__init__.py +28 -0
- disdrodb/scattering/axis_ratio.py +344 -0
- disdrodb/scattering/routines.py +456 -0
- disdrodb/utils/__init__.py +17 -0
- disdrodb/utils/attrs.py +208 -0
- disdrodb/utils/cli.py +269 -0
- disdrodb/utils/compression.py +60 -42
- disdrodb/utils/dask.py +62 -0
- disdrodb/utils/dataframe.py +342 -0
- disdrodb/utils/decorators.py +110 -0
- disdrodb/utils/directories.py +107 -46
- disdrodb/utils/encoding.py +127 -0
- disdrodb/utils/list.py +29 -0
- disdrodb/utils/logger.py +168 -46
- disdrodb/utils/time.py +657 -0
- disdrodb/utils/warnings.py +30 -0
- disdrodb/utils/writer.py +57 -0
- disdrodb/utils/xarray.py +138 -47
- disdrodb/utils/yaml.py +0 -1
- disdrodb/viz/__init__.py +17 -0
- disdrodb/viz/plots.py +17 -0
- disdrodb-0.1.1.dist-info/METADATA +294 -0
- disdrodb-0.1.1.dist-info/RECORD +232 -0
- {disdrodb-0.0.21.dist-info → disdrodb-0.1.1.dist-info}/WHEEL +1 -1
- disdrodb-0.1.1.dist-info/entry_points.txt +30 -0
- disdrodb/data_transfer/scripts/disdrodb_download_archive.py +0 -53
- disdrodb/data_transfer/scripts/disdrodb_upload_archive.py +0 -57
- disdrodb/l0/configs/OTT_Parsivel/l0a_encodings.yml +0 -32
- disdrodb/l0/configs/OTT_Parsivel2/l0a_encodings.yml +0 -39
- disdrodb/l0/configs/RD_80/l0a_encodings.yml +0 -16
- disdrodb/l0/configs/RD_80/l0b_encodings.yml +0 -135
- disdrodb/l0/configs/Thies_LPM/l0a_encodings.yml +0 -80
- disdrodb/l0/io.py +0 -257
- disdrodb/l0/l0_processing.py +0 -1091
- disdrodb/l0/readers/AUSTRALIA/MELBOURNE_2007_OTT.py +0 -178
- disdrodb/l0/readers/AUSTRALIA/MELBOURNE_2007_THIES.py +0 -247
- disdrodb/l0/readers/BRAZIL/CHUVA_LPM.py +0 -204
- disdrodb/l0/readers/BRAZIL/CHUVA_OTT.py +0 -183
- disdrodb/l0/readers/BRAZIL/GOAMAZON_OTT.py +0 -183
- disdrodb/l0/readers/CHINA/CHONGQING.py +0 -131
- disdrodb/l0/readers/EPFL/EPFL_ROOF_2008.py +0 -128
- disdrodb/l0/readers/EPFL/HYMEX_LTE_SOP2.py +0 -127
- disdrodb/l0/readers/EPFL/HYMEX_LTE_SOP3.py +0 -129
- disdrodb/l0/readers/EPFL/RACLETS_2019.py +0 -158
- disdrodb/l0/readers/EPFL/SAMOYLOV_2017.py +0 -136
- disdrodb/l0/readers/EPFL/SAMOYLOV_2019.py +0 -158
- disdrodb/l0/readers/FRANCE/SIRTA_OTT2.py +0 -138
- disdrodb/l0/readers/GPM/GCPEX.py +0 -123
- disdrodb/l0/readers/GPM/IFLOODS.py +0 -123
- disdrodb/l0/readers/GPM/MC3E.py +0 -123
- disdrodb/l0/readers/GPM/NSSTC.py +0 -164
- disdrodb/l0/readers/ITALY/GID.py +0 -199
- disdrodb/l0/readers/MEXICO/OH_IIUNAM_nc.py +0 -92
- disdrodb/l0/readers/NCAR/CCOPE_2015.py +0 -133
- disdrodb/l0/readers/NCAR/PECAN_FP3.py +0 -137
- disdrodb/l0/readers/NCAR/PECAN_MOBILE.py +0 -144
- disdrodb/l0/readers/NCAR/RELAMPAGO_OTT.py +0 -195
- disdrodb/l0/readers/NCAR/SNOWIE_PJ.py +0 -172
- disdrodb/l0/readers/NCAR/SNOWIE_SB.py +0 -179
- disdrodb/l0/readers/NCAR/VORTEX2_2009.py +0 -133
- disdrodb/l0/readers/NCAR/VORTEX2_2010.py +0 -188
- disdrodb/l0/readers/NCAR/VORTEX2_2010_UF.py +0 -191
- disdrodb/l0/readers/NCAR/VORTEX_SE_2016_P2.py +0 -135
- disdrodb/l0/readers/NCAR/VORTEX_SE_2016_PIPS.py +0 -170
- disdrodb/l0/readers/NETHERLANDS/DELFT.py +0 -187
- disdrodb/l0/readers/SPAIN/SBEGUERIA.py +0 -179
- disdrodb/l0/scripts/disdrodb_run_l0b_concat.py +0 -93
- disdrodb/l0/scripts/disdrodb_run_l0b_concat_station.py +0 -85
- disdrodb/utils/netcdf.py +0 -452
- disdrodb/utils/scripts.py +0 -102
- disdrodb-0.0.21.dist-info/AUTHORS.md +0 -18
- disdrodb-0.0.21.dist-info/METADATA +0 -186
- disdrodb-0.0.21.dist-info/RECORD +0 -168
- disdrodb-0.0.21.dist-info/entry_points.txt +0 -15
- /disdrodb/l0/configs/{RD_80 → RD80}/bins_velocity.yml +0 -0
- /disdrodb/l0/manuals/{Thies_LPM.pdf → LPM.pdf} +0 -0
- /disdrodb/l0/manuals/{ODM_470.pdf → ODM470.pdf} +0 -0
- /disdrodb/l0/manuals/{OTT_Parsivel.pdf → PARSIVEL.pdf} +0 -0
- /disdrodb/l0/manuals/{OTT_Parsivel2.pdf → PARSIVEL2.pdf} +0 -0
- /disdrodb/l0/manuals/{PWS_100.pdf → PWS100.pdf} +0 -0
- /disdrodb/l0/manuals/{RD_80.pdf → RD80.pdf} +0 -0
- {disdrodb-0.0.21.dist-info → disdrodb-0.1.1.dist-info/licenses}/LICENSE +0 -0
- {disdrodb-0.0.21.dist-info → disdrodb-0.1.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# -----------------------------------------------------------------------------.
|
|
4
|
+
# Copyright (c) 2021-2023 DISDRODB developers
|
|
5
|
+
#
|
|
6
|
+
# This program is free software: you can redistribute it and/or modify
|
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
# (at your option) any later version.
|
|
10
|
+
#
|
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU General Public License for more details.
|
|
15
|
+
#
|
|
16
|
+
# You should have received a copy of the GNU General Public License
|
|
17
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
# -----------------------------------------------------------------------------.
|
|
19
|
+
"""Routine to download the DISDRODB Metadata Archive from GitHub."""
|
|
20
|
+
import io
|
|
21
|
+
import os
|
|
22
|
+
import shutil
|
|
23
|
+
import urllib.request
|
|
24
|
+
import zipfile
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def download_metadata_archive(directory_path, force=False):
|
|
28
|
+
"""Download the DISDRODB Metadata Archive to the specified directory.
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
directory_path : str
|
|
33
|
+
The directory path where the DISDRODB-METADATA directory will be downloaded.
|
|
34
|
+
force : bool, optional
|
|
35
|
+
If ``True``, the existing DISDRODB-METADATA directory will be removed
|
|
36
|
+
and a new one will be downloaded. The default value is ``False``.
|
|
37
|
+
|
|
38
|
+
Returns
|
|
39
|
+
-------
|
|
40
|
+
metadata_archive_dir
|
|
41
|
+
The DISDRODB Metadata Archive directory path.
|
|
42
|
+
"""
|
|
43
|
+
# Define DISDRODB Metadata Archive GitHub URL
|
|
44
|
+
archive_zip_url = "https://github.com/ltelab/DISDRODB-METADATA/archive/refs/heads/main.zip"
|
|
45
|
+
|
|
46
|
+
# Download archive to disk
|
|
47
|
+
resp = urllib.request.urlopen(archive_zip_url)
|
|
48
|
+
archive_data = resp.read()
|
|
49
|
+
|
|
50
|
+
# Unpack archive
|
|
51
|
+
with zipfile.ZipFile(io.BytesIO(archive_data)) as zf:
|
|
52
|
+
zf.extractall(directory_path)
|
|
53
|
+
|
|
54
|
+
# Check the archive has been download
|
|
55
|
+
extracted_dir = os.path.join(directory_path, "DISDRODB-METADATA-main")
|
|
56
|
+
if not os.path.isdir(extracted_dir):
|
|
57
|
+
raise ValueError(
|
|
58
|
+
"The DISDRODB Metadata Archive hosted on GitHub could not be downloaded!",
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
# Define target directory for the metadata archive
|
|
62
|
+
target_dir = os.path.join(directory_path, "DISDRODB-METADATA")
|
|
63
|
+
|
|
64
|
+
# Handle existing target directory
|
|
65
|
+
if os.path.exists(target_dir):
|
|
66
|
+
if force:
|
|
67
|
+
shutil.rmtree(target_dir)
|
|
68
|
+
else:
|
|
69
|
+
raise FileExistsError(
|
|
70
|
+
f"A DISDRODB Metadata Archive already exists at '{target_dir}'. Use force=True to update it.",
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# Rename extracted directory to target
|
|
74
|
+
shutil.move(extracted_dir, target_dir)
|
|
75
|
+
|
|
76
|
+
# Define metadata archive directory
|
|
77
|
+
metadata_archive_dir = os.path.join(target_dir, "DISDRODB")
|
|
78
|
+
|
|
79
|
+
print("The DISDRODB Metadata Archive has been download successfully.")
|
|
80
|
+
print(f"The DISDRODB Metadata Archive directory path is {metadata_archive_dir}")
|
|
81
|
+
return metadata_archive_dir
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# -----------------------------------------------------------------------------.
|
|
4
|
+
# Copyright (c) 2021-2023 DISDRODB developers
|
|
5
|
+
#
|
|
6
|
+
# This program is free software: you can redistribute it and/or modify
|
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
# (at your option) any later version.
|
|
10
|
+
#
|
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU General Public License for more details.
|
|
15
|
+
#
|
|
16
|
+
# You should have received a copy of the GNU General Public License
|
|
17
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
# -----------------------------------------------------------------------------.
|
|
19
|
+
"""Metadata tools to verify/complete geolocation information."""
|
|
20
|
+
import time
|
|
21
|
+
|
|
22
|
+
import numpy as np
|
|
23
|
+
import requests
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def infer_altitude(latitude, longitude, dem="aster30m"):
|
|
27
|
+
"""Infer station altitude using a Digital Elevation Model (DEM).
|
|
28
|
+
|
|
29
|
+
This function uses the OpenTopoData API to infer the altitude of a given
|
|
30
|
+
location specified by latitude and longitude.
|
|
31
|
+
By default, it uses the ASTER DEM at 30m resolution.
|
|
32
|
+
|
|
33
|
+
Parameters
|
|
34
|
+
----------
|
|
35
|
+
latitude : float
|
|
36
|
+
The latitude of the location for which to infer the altitude.
|
|
37
|
+
longitude : float
|
|
38
|
+
The longitude of the location for which to infer the altitude.
|
|
39
|
+
dem : str, optional
|
|
40
|
+
The DEM to use for altitude inference. Options are "aster30m" (default),
|
|
41
|
+
"srtm30", and "mapzen".
|
|
42
|
+
|
|
43
|
+
Returns
|
|
44
|
+
-------
|
|
45
|
+
elevation : float
|
|
46
|
+
The inferred altitude of the specified location.
|
|
47
|
+
|
|
48
|
+
Raises
|
|
49
|
+
------
|
|
50
|
+
ValueError
|
|
51
|
+
If the altitude retrieval fails.
|
|
52
|
+
|
|
53
|
+
Notes
|
|
54
|
+
-----
|
|
55
|
+
- The OpenTopoData API has a limit of 1000 calls per day.
|
|
56
|
+
- Each request can include up to 100 locations.
|
|
57
|
+
- The API allows a maximum of 1 call per second.
|
|
58
|
+
|
|
59
|
+
References
|
|
60
|
+
----------
|
|
61
|
+
https://www.opentopodata.org/api/
|
|
62
|
+
"""
|
|
63
|
+
import requests
|
|
64
|
+
|
|
65
|
+
url = f"https://api.opentopodata.org/v1/{dem}?locations={latitude},{longitude}"
|
|
66
|
+
r = requests.get(url)
|
|
67
|
+
|
|
68
|
+
data = r.json()
|
|
69
|
+
if data["status"] == "OK":
|
|
70
|
+
elevation = data["results"][0]["elevation"]
|
|
71
|
+
else:
|
|
72
|
+
raise ValueError("Altitude retrieval failed.")
|
|
73
|
+
return elevation
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def infer_altitudes(lats, lons, dem="aster30m"):
|
|
77
|
+
"""
|
|
78
|
+
Infer altitude of a given location using OpenTopoData API.
|
|
79
|
+
|
|
80
|
+
Parameters
|
|
81
|
+
----------
|
|
82
|
+
lats : list or array-like
|
|
83
|
+
List or array of latitude coordinates.
|
|
84
|
+
lons : list or array-like
|
|
85
|
+
List or array of longitude coordinates.
|
|
86
|
+
dem : str, optional
|
|
87
|
+
Digital Elevation Model (DEM) to use for altitude inference.
|
|
88
|
+
The default DEM is "aster30m".
|
|
89
|
+
|
|
90
|
+
Returns
|
|
91
|
+
-------
|
|
92
|
+
elevations : numpy.ndarray
|
|
93
|
+
Array of inferred altitudes corresponding to the input coordinates.
|
|
94
|
+
|
|
95
|
+
Raises
|
|
96
|
+
------
|
|
97
|
+
ValueError
|
|
98
|
+
If the latitude and longitude arrays do not have the same length.
|
|
99
|
+
If altitude retrieval fails for any block of coordinates.
|
|
100
|
+
|
|
101
|
+
Notes
|
|
102
|
+
-----
|
|
103
|
+
- The OpenTopoData API has a limit of 1000 calls per day.
|
|
104
|
+
- Each request can include up to 100 locations.
|
|
105
|
+
- The API allows a maximum of 1 call per second.
|
|
106
|
+
- The API requests are made in blocks of up to 100 coordinates,
|
|
107
|
+
with a 2-second delay between requests.
|
|
108
|
+
"""
|
|
109
|
+
# Check that lats and lons have the same length
|
|
110
|
+
if len(lats) != len(lons):
|
|
111
|
+
raise ValueError("Latitude and longitude arrays must have the same length.")
|
|
112
|
+
|
|
113
|
+
# Maximum number of locations per API request
|
|
114
|
+
max_locations = 100
|
|
115
|
+
elevations = []
|
|
116
|
+
|
|
117
|
+
# Total number of coordinates
|
|
118
|
+
total_coords = len(lats)
|
|
119
|
+
|
|
120
|
+
# Loop over the coordinates in blocks of max_locations
|
|
121
|
+
for i in range(0, total_coords, max_locations):
|
|
122
|
+
|
|
123
|
+
# Wait 2 seconds before another API request
|
|
124
|
+
time.sleep(2)
|
|
125
|
+
|
|
126
|
+
# Get the block of coordinates
|
|
127
|
+
block_lats = lats[i : i + max_locations]
|
|
128
|
+
block_lons = lons[i : i + max_locations]
|
|
129
|
+
|
|
130
|
+
# Create the list_coords string in the format "lat1,lon1|lat2,lon2|..."
|
|
131
|
+
list_coords = "|".join([f"{lat},{lon}" for lat, lon in zip(block_lats, block_lons)])
|
|
132
|
+
|
|
133
|
+
# Define API URL
|
|
134
|
+
url = f"https://api.opentopodata.org/v1/{dem}?locations={list_coords}&interpolation=nearest"
|
|
135
|
+
|
|
136
|
+
# Retrieve info
|
|
137
|
+
r = requests.get(url)
|
|
138
|
+
data = r.json()
|
|
139
|
+
|
|
140
|
+
# Parse info
|
|
141
|
+
if data.get("status") == "OK":
|
|
142
|
+
elevations.extend([result["elevation"] for result in data["results"]])
|
|
143
|
+
else:
|
|
144
|
+
raise ValueError(f"Altitude retrieval failed for block starting at index {i}.")
|
|
145
|
+
elevations = np.array(elevations).astype(float)
|
|
146
|
+
return elevations
|
disdrodb/metadata/info.py
CHANGED
|
@@ -18,41 +18,49 @@
|
|
|
18
18
|
# -----------------------------------------------------------------------------.
|
|
19
19
|
"""Test Metadata Info Extraction."""
|
|
20
20
|
import os
|
|
21
|
+
from typing import Optional
|
|
21
22
|
|
|
22
23
|
from disdrodb.api.info import (
|
|
23
24
|
infer_campaign_name_from_path,
|
|
24
25
|
infer_data_source_from_path,
|
|
25
26
|
)
|
|
26
|
-
from disdrodb.configs import
|
|
27
|
+
from disdrodb.configs import get_metadata_archive_dir
|
|
27
28
|
from disdrodb.metadata.reader import read_station_metadata
|
|
28
29
|
from disdrodb.metadata.search import get_list_metadata
|
|
29
30
|
|
|
30
31
|
|
|
31
|
-
def get_archive_metadata_key_value(key: str, return_tuple: bool = True,
|
|
32
|
+
def get_archive_metadata_key_value(key: str, return_tuple: bool = True, metadata_archive_dir: Optional[str] = None):
|
|
32
33
|
"""Return the values of a metadata key for all the archive.
|
|
33
34
|
|
|
34
35
|
Parameters
|
|
35
36
|
----------
|
|
36
|
-
|
|
37
|
+
data_archive_dir : str
|
|
37
38
|
Path to the disdrodb directory.
|
|
38
39
|
key : str
|
|
39
40
|
Metadata key.
|
|
40
41
|
return_tuple : bool, optional
|
|
41
|
-
If True
|
|
42
|
-
If False
|
|
43
|
-
The default is True
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
If ``True``, returns a tuple (``data_source``,``campaign_name``,``station_name``, ``key_value``)
|
|
43
|
+
If ``False``, returns a list of the key values.
|
|
44
|
+
The default value is ``True``.
|
|
45
|
+
metadata_archive_dir : str (optional)
|
|
46
|
+
The directory path where the DISDRODB Metadata Archive is located.
|
|
47
|
+
The directory path must end with ``<...>/DISDRODB``.
|
|
48
|
+
If ``None``, it uses the ``metadata_archive_dir`` path specified
|
|
49
|
+
in the DISDRODB active configuration.
|
|
47
50
|
|
|
48
51
|
Returns
|
|
49
52
|
-------
|
|
50
53
|
list or tuple
|
|
51
54
|
List or tuple of values of the metadata key.
|
|
52
55
|
"""
|
|
53
|
-
|
|
56
|
+
metadata_archive_dir = get_metadata_archive_dir(metadata_archive_dir)
|
|
54
57
|
list_metadata_paths = get_list_metadata(
|
|
55
|
-
|
|
58
|
+
metadata_archive_dir=metadata_archive_dir,
|
|
59
|
+
data_sources=None,
|
|
60
|
+
campaign_names=None,
|
|
61
|
+
station_names=None,
|
|
62
|
+
product=None, # --> Search in DISDRODB Metadata Archive
|
|
63
|
+
available_data=False, # --> Select all metadata matching the filtering criteria
|
|
56
64
|
)
|
|
57
65
|
list_info = []
|
|
58
66
|
for filepath in list_metadata_paths:
|
|
@@ -60,8 +68,7 @@ def get_archive_metadata_key_value(key: str, return_tuple: bool = True, base_dir
|
|
|
60
68
|
campaign_name = infer_campaign_name_from_path(filepath)
|
|
61
69
|
station_name = os.path.basename(filepath).replace(".yml", "")
|
|
62
70
|
metadata = read_station_metadata(
|
|
63
|
-
|
|
64
|
-
product="RAW",
|
|
71
|
+
metadata_archive_dir=metadata_archive_dir,
|
|
65
72
|
data_source=data_source,
|
|
66
73
|
campaign_name=campaign_name,
|
|
67
74
|
station_name=station_name,
|
|
@@ -40,9 +40,9 @@ def add_missing_metadata_keys(metadata):
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
def sort_metadata_dictionary(metadata):
|
|
43
|
-
"""Sort the keys of the metadata dictionary by valid_metadata_keys list order."""
|
|
44
|
-
from disdrodb.metadata.standards import
|
|
43
|
+
"""Sort the keys of the metadata dictionary by ``valid_metadata_keys`` list order."""
|
|
44
|
+
from disdrodb.metadata.standards import METADATA_KEYS
|
|
45
45
|
|
|
46
|
-
list_metadata_keys =
|
|
46
|
+
list_metadata_keys = METADATA_KEYS
|
|
47
47
|
metadata = {k: metadata[k] for k in list_metadata_keys}
|
|
48
48
|
return metadata
|
disdrodb/metadata/reader.py
CHANGED
|
@@ -18,12 +18,13 @@
|
|
|
18
18
|
# -----------------------------------------------------------------------------.
|
|
19
19
|
"""Routines to read the DISDRODB Metadata."""
|
|
20
20
|
|
|
21
|
+
import pandas as pd
|
|
21
22
|
|
|
22
23
|
from disdrodb.api.path import define_metadata_filepath
|
|
23
24
|
from disdrodb.utils.yaml import read_yaml
|
|
24
25
|
|
|
25
26
|
|
|
26
|
-
def read_station_metadata(data_source, campaign_name, station_name,
|
|
27
|
+
def read_station_metadata(data_source, campaign_name, station_name, metadata_archive_dir=None):
|
|
27
28
|
"""Open the station metadata YAML file into a dictionary.
|
|
28
29
|
|
|
29
30
|
Parameters
|
|
@@ -36,12 +37,10 @@ def read_station_metadata(data_source, campaign_name, station_name, base_dir=Non
|
|
|
36
37
|
The name of the campaign. Must be provided in UPPER CASE.
|
|
37
38
|
station_name : str
|
|
38
39
|
The name of the station.
|
|
39
|
-
|
|
40
|
-
The
|
|
40
|
+
metadata_archive_dir : str, optional
|
|
41
|
+
The directory path where the DISDRODB Metadata Archive is located.
|
|
41
42
|
If not specified, the path specified in the DISDRODB active configuration will be used.
|
|
42
|
-
|
|
43
|
-
The DISDRODB product in which to search for the metadata file.
|
|
44
|
-
The default is "RAW".
|
|
43
|
+
Expected path format: ``<...>/DISDRODB``.
|
|
45
44
|
|
|
46
45
|
Returns
|
|
47
46
|
-------
|
|
@@ -51,12 +50,64 @@ def read_station_metadata(data_source, campaign_name, station_name, base_dir=Non
|
|
|
51
50
|
"""
|
|
52
51
|
# Retrieve metadata filepath
|
|
53
52
|
metadata_filepath = define_metadata_filepath(
|
|
54
|
-
|
|
53
|
+
metadata_archive_dir=metadata_archive_dir,
|
|
55
54
|
data_source=data_source,
|
|
56
55
|
campaign_name=campaign_name,
|
|
57
56
|
station_name=station_name,
|
|
58
|
-
product=product,
|
|
59
57
|
check_exists=True,
|
|
60
58
|
)
|
|
59
|
+
# Open the metadata file
|
|
61
60
|
metadata_dict = read_yaml(metadata_filepath)
|
|
62
61
|
return metadata_dict
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def read_metadata_archive(
|
|
65
|
+
metadata_archive_dir=None,
|
|
66
|
+
data_sources=None,
|
|
67
|
+
campaign_names=None,
|
|
68
|
+
station_names=None,
|
|
69
|
+
available_data=False,
|
|
70
|
+
):
|
|
71
|
+
"""Read the DISDRODB Metadata Archive Database.
|
|
72
|
+
|
|
73
|
+
Parameters
|
|
74
|
+
----------
|
|
75
|
+
metadata_archive_dir : str or Path-like, optional
|
|
76
|
+
Path to the root of the DISDRODB Metadata Archive. If None, the
|
|
77
|
+
default metadata base directory is used. Default is None.
|
|
78
|
+
data_sources : str or sequence of str, optional
|
|
79
|
+
One or more data source identifiers to filter stations by. If None,
|
|
80
|
+
no filtering on data source is applied. The default is is None.
|
|
81
|
+
campaign_names : str or sequence of str, optional
|
|
82
|
+
One or more campaign names to filter stations by. If None, no filtering
|
|
83
|
+
on campaign is applied. The default is is None.
|
|
84
|
+
station_names : str or sequence of str, optional
|
|
85
|
+
One or more station names to include. If None, all stations matching
|
|
86
|
+
other filters are considered. The default is is None.
|
|
87
|
+
available_data: bool, optional
|
|
88
|
+
If True, only information of stations with data available in the online
|
|
89
|
+
DISDRODB Decentralized Data Archive are returned.
|
|
90
|
+
If False (the default), all stations present in the DISDRODB Metadata Archive
|
|
91
|
+
matching the filtering criteria are returned,
|
|
92
|
+
|
|
93
|
+
Returns
|
|
94
|
+
-------
|
|
95
|
+
pandas.DataFrame
|
|
96
|
+
|
|
97
|
+
"""
|
|
98
|
+
from disdrodb.configs import get_metadata_archive_dir
|
|
99
|
+
from disdrodb.metadata.search import get_list_metadata
|
|
100
|
+
|
|
101
|
+
metadata_archive_dir = get_metadata_archive_dir(metadata_archive_dir=metadata_archive_dir)
|
|
102
|
+
|
|
103
|
+
list_metadata_paths = get_list_metadata(
|
|
104
|
+
metadata_archive_dir=metadata_archive_dir,
|
|
105
|
+
data_sources=data_sources,
|
|
106
|
+
campaign_names=campaign_names,
|
|
107
|
+
station_names=station_names,
|
|
108
|
+
product=None, # --> Search in DISDRODB Metadata Archive
|
|
109
|
+
available_data=available_data,
|
|
110
|
+
)
|
|
111
|
+
list_metadata = [read_yaml(fpath) for fpath in list_metadata_paths]
|
|
112
|
+
df = pd.DataFrame(list_metadata)
|
|
113
|
+
return df
|
disdrodb/metadata/search.py
CHANGED
|
@@ -18,150 +18,94 @@
|
|
|
18
18
|
# -----------------------------------------------------------------------------.
|
|
19
19
|
"""Routines to manipulate the DISDRODB Metadata Archive."""
|
|
20
20
|
|
|
21
|
-
import glob
|
|
22
|
-
import os
|
|
23
21
|
|
|
24
22
|
from disdrodb.api.path import define_metadata_filepath
|
|
25
|
-
from disdrodb.
|
|
23
|
+
from disdrodb.api.search import available_stations
|
|
26
24
|
|
|
27
25
|
|
|
28
26
|
def get_list_metadata(
|
|
29
27
|
data_sources=None,
|
|
30
28
|
campaign_names=None,
|
|
31
29
|
station_names=None,
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
product=None,
|
|
31
|
+
available_data=False,
|
|
32
|
+
raise_error_if_empty=False,
|
|
33
|
+
invalid_fields_policy="raise",
|
|
34
|
+
data_archive_dir=None,
|
|
35
|
+
metadata_archive_dir=None,
|
|
36
|
+
**product_kwargs,
|
|
34
37
|
):
|
|
35
38
|
"""
|
|
36
|
-
Get
|
|
39
|
+
Get station metadata filepaths.
|
|
40
|
+
|
|
41
|
+
By default, it returns the metadata file paths of stations present in the DISDRODB Metadata Archive matching
|
|
42
|
+
the filtering criteria.
|
|
43
|
+
|
|
44
|
+
If the DISDRODB product is specified, it lists only metadata file paths of stations with the specified product
|
|
45
|
+
present in the local DISDRODB Data Archive.
|
|
37
46
|
|
|
38
47
|
Parameters
|
|
39
48
|
----------
|
|
40
|
-
|
|
41
|
-
Name of
|
|
42
|
-
The name(s) must be UPPER CASE.
|
|
43
|
-
The default is None
|
|
44
|
-
campaign_names : str or list of str
|
|
45
|
-
Name of the campaign(s) of interest.
|
|
46
|
-
The name(s) must be UPPER CASE.
|
|
47
|
-
The default is None
|
|
48
|
-
station_names : str or list of str
|
|
49
|
-
Station names of interest.
|
|
50
|
-
The default is None
|
|
51
|
-
with_stations_data : bool
|
|
52
|
-
If True, only return metadata filepaths that have corresponding data in the local DISDRODB raw archive.
|
|
53
|
-
The default is True
|
|
54
|
-
base_dir : str (optional)
|
|
55
|
-
Base directory of DISDRODB. Format: <...>/DISDRODB
|
|
56
|
-
If None (the default), the disdrodb config variable 'dir' is used.
|
|
49
|
+
product : str or None, optional
|
|
50
|
+
Name of the product to filter on (e.g., "RAW", "L0A", "L1").
|
|
57
51
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
List of metadata YAML file paths
|
|
52
|
+
If the DISDRODB product is not specified (default),
|
|
53
|
+
it returns the metadata file paths of stations present in the DISDRODB Metadata Archive matching
|
|
54
|
+
the filtering criteria.
|
|
62
55
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if with_stations_data:
|
|
66
|
-
list_metadata = _get_list_metadata_with_data(
|
|
67
|
-
base_dir=base_dir,
|
|
68
|
-
data_sources=data_sources,
|
|
69
|
-
campaign_names=campaign_names,
|
|
70
|
-
station_names=station_names,
|
|
71
|
-
)
|
|
72
|
-
else:
|
|
73
|
-
list_metadata = _get_list_all_metadata(
|
|
74
|
-
base_dir=base_dir,
|
|
75
|
-
data_sources=data_sources,
|
|
76
|
-
campaign_names=campaign_names,
|
|
77
|
-
station_names=station_names,
|
|
78
|
-
)
|
|
79
|
-
return list_metadata
|
|
56
|
+
If the DISDRODB product is specified, it lists only metadata file paths of stations with the specified product
|
|
57
|
+
present in the local DISDRODB Data Archive.
|
|
80
58
|
|
|
59
|
+
available_data : bool, optional
|
|
81
60
|
|
|
82
|
-
|
|
83
|
-
"""
|
|
84
|
-
Get the list of metadata filepaths in the DISDRODB raw archive.
|
|
61
|
+
If ``product`` is not specified:
|
|
85
62
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
Base directory of DISDRODB
|
|
90
|
-
Format: <...>/DISDRODB
|
|
91
|
-
data_sources : str or list of str
|
|
92
|
-
Name of data source(s) of interest.
|
|
93
|
-
The name(s) must be UPPER CASE.
|
|
94
|
-
The default is None
|
|
95
|
-
campaign_names : str or list of str
|
|
96
|
-
Name of the campaign(s) of interest.
|
|
97
|
-
The name(s) must be UPPER CASE.
|
|
98
|
-
The default is None
|
|
99
|
-
station_names : str or list of str
|
|
100
|
-
Station names of interest.
|
|
101
|
-
The default is None
|
|
102
|
-
with_stations_data : bool
|
|
103
|
-
If True, only return metadata filepaths that have corresponding data in the local DISDRODB raw archive.
|
|
104
|
-
The default is True
|
|
63
|
+
- if available_data is False, return metadata filepaths of stations present in the DISDRODB Metadata Archive
|
|
64
|
+
- if available_data is True, return metadata filepaths of stations with data available on the
|
|
65
|
+
online DISDRODB Decentralized Data Archive (i.e., stations with the disdrodb_data_url in the metadata).
|
|
105
66
|
|
|
106
|
-
|
|
107
|
-
-------
|
|
108
|
-
metadata_filepaths: list
|
|
109
|
-
List of metadata YAML file paths
|
|
67
|
+
If ``product`` is specified:
|
|
110
68
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
data_sources = [data_sources]
|
|
117
|
-
else:
|
|
118
|
-
data_sources = ["**"]
|
|
119
|
-
if campaign_names:
|
|
120
|
-
if isinstance(campaign_names, str):
|
|
121
|
-
campaign_names = [campaign_names]
|
|
122
|
-
else:
|
|
123
|
-
campaign_names = ["**"]
|
|
124
|
-
|
|
125
|
-
for data_source in data_sources:
|
|
126
|
-
for campaign_name in campaign_names:
|
|
127
|
-
base_path = os.path.join(base_dir, "Raw", data_source, campaign_name)
|
|
128
|
-
list_of_base_path.append(base_path)
|
|
129
|
-
|
|
130
|
-
metadata_filepaths = []
|
|
131
|
-
for base_path in list_of_base_path:
|
|
132
|
-
if station_names:
|
|
133
|
-
if isinstance(station_names, str):
|
|
134
|
-
station_names = [station_names]
|
|
135
|
-
for station_name in station_names:
|
|
136
|
-
metadata_path = os.path.join(base_path, "**", "metadata", f"{station_name}.yml")
|
|
137
|
-
metadata_filepaths += glob.glob(metadata_path, recursive=True)
|
|
138
|
-
else:
|
|
139
|
-
metadata_path = os.path.join(base_path, "**", "metadata", "*.yml")
|
|
140
|
-
metadata_filepaths += glob.glob(metadata_path, recursive=True)
|
|
141
|
-
|
|
142
|
-
return list(set(metadata_filepaths))
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
def _get_list_metadata_with_data(base_dir, data_sources=None, campaign_names=None, station_names=None):
|
|
146
|
-
"""
|
|
147
|
-
Get the list of metadata filepaths that have corresponding data in the DISDRODB raw archive.
|
|
69
|
+
- if available_data is False, return metadata filepaths of stations where
|
|
70
|
+
the product directory exists in the in the local DISDRODB Data Archive
|
|
71
|
+
- if available_data is True, return metadata filepaths of stations where product data exists in the
|
|
72
|
+
in the local DISDRODB Data Archive.
|
|
73
|
+
The default is is False.
|
|
148
74
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
base_dir : str
|
|
152
|
-
Base directory of DISDRODB
|
|
153
|
-
Format: <...>/DISDRODB
|
|
154
|
-
data_sources : str or list of str
|
|
155
|
-
Name of data source(s) of interest.
|
|
75
|
+
data_sources : str or sequence of str, optional
|
|
76
|
+
One or more data source identifiers to filter stations by.
|
|
156
77
|
The name(s) must be UPPER CASE.
|
|
157
|
-
The default is None
|
|
158
|
-
campaign_names : str or
|
|
159
|
-
|
|
78
|
+
If None, no filtering on data source is applied. The default is is ``None``.
|
|
79
|
+
campaign_names : str or sequence of str, optional
|
|
80
|
+
One or more campaign names to filter stations by.
|
|
160
81
|
The name(s) must be UPPER CASE.
|
|
161
|
-
The default is None
|
|
162
|
-
station_names : str or
|
|
163
|
-
|
|
164
|
-
The default is None
|
|
82
|
+
If None, no filtering on campaign is applied. The default is is ``None``.
|
|
83
|
+
station_names : str or sequence of str, optional
|
|
84
|
+
One or more station names to include.
|
|
85
|
+
If None, all stations matching other filters are considered. The default is is ``None``.
|
|
86
|
+
raise_error_if_empty : bool, optional
|
|
87
|
+
If True and no stations satisfy the criteria, raise a ``ValueError``.
|
|
88
|
+
If False, return an empty list/tuple. The default is False.
|
|
89
|
+
invalid_fields_policy : {'raise', 'warn', 'ignore'}, optional
|
|
90
|
+
How to handle invalid filter values for ``data_sources``, ``campaign_names``,
|
|
91
|
+
or ``station_names`` that are not present in the metadata archive:
|
|
92
|
+
|
|
93
|
+
- 'raise' : raise a ``ValueError`` (default)
|
|
94
|
+
- 'warn' : emit a warning, then ignore invalid entries
|
|
95
|
+
- 'ignore': silently drop invalid entries
|
|
96
|
+
data_archive_dir : str or Path-like, optional
|
|
97
|
+
Path to the root of the local DISDRODB Data Archive. Format: ``<...>/DISDRODB``
|
|
98
|
+
Required only if ``product``is specified.
|
|
99
|
+
If None, the``data_archive_dir`` path specified in the DISDRODB active configuration file is used.
|
|
100
|
+
The default is None.
|
|
101
|
+
metadata_archive_dir : str or Path-like, optional
|
|
102
|
+
Path to the root of the DISDRODB Metadata Archive. Format: ``<...>/DISDRODB``
|
|
103
|
+
If None, the``metadata_archive_dir`` path specified in the DISDRODB active configuratio. The default is None.
|
|
104
|
+
**product_kwargs : dict, optional
|
|
105
|
+
Additional arguments required for some products.
|
|
106
|
+
For example, for the "L2E" product, you need to specify ``rolling`` and
|
|
107
|
+
``sample_interval``. For the "L2M" product, you need to specify also
|
|
108
|
+
the ``model_name``.
|
|
165
109
|
|
|
166
110
|
Returns
|
|
167
111
|
-------
|
|
@@ -169,39 +113,28 @@ def _get_list_metadata_with_data(base_dir, data_sources=None, campaign_names=Non
|
|
|
169
113
|
List of metadata YAML file paths
|
|
170
114
|
|
|
171
115
|
"""
|
|
172
|
-
from disdrodb.api.io import available_stations
|
|
173
|
-
|
|
174
|
-
# Check inputs
|
|
175
|
-
if isinstance(data_sources, str):
|
|
176
|
-
data_sources = [data_sources]
|
|
177
|
-
if isinstance(campaign_names, str):
|
|
178
|
-
campaign_names = [campaign_names]
|
|
179
|
-
|
|
180
|
-
# Retrieve information of requested stations
|
|
181
|
-
# --> (data_source, campaign_name, station_name)
|
|
182
|
-
|
|
183
116
|
list_info = available_stations(
|
|
184
|
-
base_dir=base_dir,
|
|
185
|
-
product="RAW",
|
|
186
117
|
data_sources=data_sources,
|
|
187
118
|
campaign_names=campaign_names,
|
|
119
|
+
station_names=station_names,
|
|
120
|
+
product=product,
|
|
121
|
+
available_data=available_data,
|
|
122
|
+
raise_error_if_empty=raise_error_if_empty,
|
|
123
|
+
invalid_fields_policy=invalid_fields_policy,
|
|
124
|
+
metadata_archive_dir=metadata_archive_dir,
|
|
125
|
+
data_archive_dir=data_archive_dir,
|
|
126
|
+
return_tuple=True,
|
|
127
|
+
**product_kwargs,
|
|
188
128
|
)
|
|
189
129
|
|
|
190
|
-
#
|
|
191
|
-
if len(list_info) == 0:
|
|
192
|
-
raise ValueError("No stations are available !")
|
|
193
|
-
|
|
194
|
-
# Get metadata filepaths
|
|
130
|
+
# Define metadata filepath
|
|
195
131
|
metadata_filepaths = [
|
|
196
132
|
define_metadata_filepath(
|
|
197
|
-
|
|
133
|
+
metadata_archive_dir=metadata_archive_dir,
|
|
198
134
|
data_source=data_source,
|
|
199
135
|
campaign_name=campaign_name,
|
|
200
136
|
station_name=station_name,
|
|
201
|
-
base_dir=base_dir,
|
|
202
|
-
check_exists=False,
|
|
203
137
|
)
|
|
204
138
|
for data_source, campaign_name, station_name in list_info
|
|
205
139
|
]
|
|
206
|
-
|
|
207
|
-
return metadata_filepaths
|
|
140
|
+
return sorted(set(metadata_filepaths))
|