disdrodb 0.0.20__py3-none-any.whl → 0.1.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 +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 +295 -269
- 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 +32 -42
- 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 +62 -59
- disdrodb/l0/configs/{Thies_LPM → LPM}/l0b_encodings.yml +9 -9
- disdrodb/l0/configs/{Thies_LPM → LPM}/raw_data_format.yml +245 -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 +22 -20
- 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 +24 -22
- disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/l0b_encodings.yml +20 -20
- disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/raw_data_format.yml +98 -98
- 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 +48 -48
- 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 +93 -173
- 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 +226 -0
- disdrodb/l0/readers/LPM/BRAZIL/CHUVA_LPM.py +185 -0
- disdrodb/l0/readers/LPM/BRAZIL/GOAMAZON_LPM.py +183 -0
- disdrodb/l0/readers/LPM/ITALY/GID_LPM.py +179 -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/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/{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/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/{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/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 +72 -236
- disdrodb/l0/template_tools.py +104 -109
- disdrodb/l1/__init__.py +17 -0
- disdrodb/l1/beard_model.py +716 -0
- disdrodb/l1/encoding_attrs.py +620 -0
- disdrodb/l1/fall_velocity.py +260 -0
- disdrodb/l1/filters.py +192 -0
- disdrodb/l1/processing.py +200 -0
- disdrodb/l1/resampling.py +236 -0
- disdrodb/l1/routines.py +357 -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 +1735 -0
- disdrodb/l2/event.py +388 -0
- disdrodb/l2/processing.py +519 -0
- disdrodb/l2/processing_options.py +213 -0
- disdrodb/l2/routines.py +868 -0
- disdrodb/metadata/__init__.py +9 -2
- disdrodb/metadata/checks.py +165 -118
- disdrodb/metadata/download.py +81 -0
- disdrodb/metadata/geolocation.py +146 -0
- disdrodb/metadata/info.py +20 -13
- disdrodb/metadata/manipulation.py +1 -1
- disdrodb/metadata/reader.py +59 -8
- disdrodb/metadata/search.py +77 -144
- disdrodb/metadata/standards.py +7 -8
- disdrodb/metadata/writer.py +8 -14
- disdrodb/psd/__init__.py +38 -0
- disdrodb/psd/fitting.py +2146 -0
- disdrodb/psd/models.py +774 -0
- disdrodb/routines.py +1176 -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/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.0.dist-info/METADATA +321 -0
- disdrodb-0.1.0.dist-info/RECORD +216 -0
- {disdrodb-0.0.20.dist-info → disdrodb-0.1.0.dist-info}/WHEEL +1 -1
- disdrodb-0.1.0.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_LPM.py +0 -204
- 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.20.dist-info/AUTHORS.md +0 -18
- disdrodb-0.0.20.dist-info/METADATA +0 -186
- disdrodb-0.0.20.dist-info/RECORD +0 -168
- disdrodb-0.0.20.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.20.dist-info → disdrodb-0.1.0.dist-info/licenses}/LICENSE +0 -0
- {disdrodb-0.0.20.dist-info → disdrodb-0.1.0.dist-info}/top_level.txt +0 -0
disdrodb/l0/l0_reader.py
CHANGED
|
@@ -17,344 +17,277 @@
|
|
|
17
17
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
18
18
|
# -----------------------------------------------------------------------------.
|
|
19
19
|
"""Define DISDRODB L0 readers routines."""
|
|
20
|
-
|
|
20
|
+
import inspect
|
|
21
21
|
import logging
|
|
22
22
|
import os
|
|
23
|
+
from collections import defaultdict
|
|
24
|
+
|
|
25
|
+
from disdrodb.api.checks import check_data_sources, check_sensor_name
|
|
26
|
+
from disdrodb.utils.directories import list_files
|
|
27
|
+
from disdrodb.utils.list import flatten_list
|
|
23
28
|
|
|
24
29
|
logger = logging.getLogger(__name__)
|
|
25
30
|
|
|
26
31
|
|
|
27
32
|
####--------------------------------------------------------------------------.
|
|
33
|
+
#### Search readers
|
|
28
34
|
|
|
29
35
|
|
|
30
|
-
def
|
|
31
|
-
"""Returns the path to the disdrodb.l0.readers directory within the disdrodb package."""
|
|
36
|
+
def define_readers_directory(sensor_name="") -> str:
|
|
37
|
+
"""Returns the path to the ``disdrodb.l0.readers`` directory within the disdrodb package."""
|
|
32
38
|
from disdrodb import __root_path__
|
|
33
39
|
|
|
34
|
-
reader_dir = os.path.join(__root_path__, "disdrodb", "l0", "readers")
|
|
40
|
+
reader_dir = os.path.join(__root_path__, "disdrodb", "l0", "readers", sensor_name)
|
|
35
41
|
return reader_dir
|
|
36
42
|
|
|
37
43
|
|
|
38
|
-
def
|
|
39
|
-
"""
|
|
40
|
-
#
|
|
41
|
-
reader_dir =
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
# Retrieve reader data source directory
|
|
68
|
-
reader_dir = _get_readers_directory()
|
|
69
|
-
reader_data_source_path = os.path.join(reader_dir, data_source)
|
|
70
|
-
if not os.path.isdir(reader_data_source_path):
|
|
71
|
-
raise ValueError(f"No {data_source} directory in disdrodb.l0.readers")
|
|
72
|
-
# Retrieve list of available readers paths
|
|
73
|
-
list_readers_paths = [f.path for f in os.scandir(reader_data_source_path) if f.is_file() and f.path.endswith(".py")]
|
|
74
|
-
return list_readers_paths
|
|
75
|
-
|
|
44
|
+
def define_reader_path(sensor_name, reader_reference):
|
|
45
|
+
"""Define the reader path based on the reader reference name."""
|
|
46
|
+
# Retrieve path to directory with sensor readers
|
|
47
|
+
reader_dir = define_readers_directory(sensor_name)
|
|
48
|
+
# Define reader path
|
|
49
|
+
reader_path = os.path.join(reader_dir, *reader_reference.split("/")) + ".py"
|
|
50
|
+
return reader_path
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def list_readers_paths(sensor_name) -> list:
|
|
54
|
+
"""Returns the file paths of the available readers for a given sensor in ``disdrodb.l0.readers.{sensor_name}``."""
|
|
55
|
+
# Retrieve path to directory with sensor readers
|
|
56
|
+
reader_dir = define_readers_directory(sensor_name)
|
|
57
|
+
# List readers
|
|
58
|
+
readers_paths = list_files(reader_dir, glob_pattern="*.py", recursive=True)
|
|
59
|
+
return readers_paths
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def list_readers_references(sensor_name):
|
|
63
|
+
"""Returns the readers references available for a given sensor in ``disdrodb.l0.readers.{sensor_name}``."""
|
|
64
|
+
# Retrieve path to directory with sensor readers
|
|
65
|
+
reader_dir = define_readers_directory(sensor_name)
|
|
66
|
+
# List readers paths
|
|
67
|
+
readers_paths = list_readers_paths(sensor_name)
|
|
68
|
+
# Derive readers references
|
|
69
|
+
readers_references = [
|
|
70
|
+
path.replace(reader_dir, "").lstrip(os.path.sep).rstrip(".py").replace("\\", "/") for path in readers_paths
|
|
71
|
+
]
|
|
72
|
+
return readers_references
|
|
76
73
|
|
|
77
|
-
def _get_readers_names_by_data_source(data_source):
|
|
78
|
-
"""Return the reader available for a given data_source.
|
|
79
74
|
|
|
80
|
-
|
|
81
|
-
"""
|
|
82
|
-
#
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
75
|
+
def get_specific_readers_references(sensor_name):
|
|
76
|
+
"""Returns a dictionary with the readers references available for each data source."""
|
|
77
|
+
# List reader references
|
|
78
|
+
readers_references = list_readers_references(sensor_name)
|
|
79
|
+
# Group reader by data source
|
|
80
|
+
# - Discard generic readers references
|
|
81
|
+
specific_reader_references = [
|
|
82
|
+
reader_reference.split("/") for reader_reference in readers_references if len(reader_reference.split("/")) == 2
|
|
83
|
+
]
|
|
84
|
+
data_sources_readers_dict = defaultdict(list)
|
|
85
|
+
for data_source, reader_name in specific_reader_references:
|
|
86
|
+
data_sources_readers_dict[data_source].append(f"{data_source}/{reader_name}")
|
|
87
|
+
data_sources_readers_dict = dict(data_sources_readers_dict)
|
|
88
|
+
return data_sources_readers_dict
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def get_specific_readers_path(sensor_name):
|
|
92
|
+
"""Returns a dictionary with the file paths of the available readers for each data source."""
|
|
93
|
+
data_sources_readers_dict = get_specific_readers_references(sensor_name)
|
|
94
|
+
data_sources_readers_dict = {
|
|
95
|
+
data_source: [
|
|
96
|
+
define_reader_path(sensor_name=sensor_name, reader_reference=reader_reference)
|
|
97
|
+
for reader_reference in readers_references
|
|
98
|
+
]
|
|
99
|
+
for data_source, readers_references in data_sources_readers_dict.items()
|
|
100
|
+
}
|
|
101
|
+
return data_sources_readers_dict
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def available_readers(sensor_name, data_sources=None, return_path=False):
|
|
105
|
+
"""Retrieve available readers information."""
|
|
106
|
+
check_sensor_name(sensor_name)
|
|
107
|
+
# Return all available readers for a specific sensor_name
|
|
108
|
+
if data_sources is None and not return_path:
|
|
109
|
+
return list_readers_references(sensor_name)
|
|
110
|
+
if data_sources is None and return_path:
|
|
111
|
+
return list_readers_paths(sensor_name)
|
|
112
|
+
# Return all available readers for a specific sensor_name and set of data sources
|
|
113
|
+
data_sources = check_data_sources(data_sources)
|
|
114
|
+
if return_path:
|
|
115
|
+
dict_readers_paths = get_specific_readers_path(sensor_name)
|
|
116
|
+
dict_readers_paths = {data_source: dict_readers_paths[data_source] for data_source in data_sources}
|
|
117
|
+
return flatten_list(list(dict_readers_paths.values()))
|
|
118
|
+
# Return dictionary of paths otherwise
|
|
119
|
+
dict_readers_references = get_specific_readers_references(sensor_name)
|
|
120
|
+
dict_readers_references = {data_source: dict_readers_references[data_source] for data_source in data_sources}
|
|
121
|
+
return flatten_list(list(dict_readers_references.values()))
|
|
86
122
|
|
|
87
123
|
|
|
88
124
|
####--------------------------------------------------------------------------.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
# List available readers data sources
|
|
114
|
-
available_reader_data_sources = _get_readers_data_sources()
|
|
115
|
-
# If not valid data_source, raise error
|
|
116
|
-
if reader_data_source not in available_reader_data_sources:
|
|
117
|
-
msg = f"Reader data source {reader_data_source} is not a directory inside the disdrodb.l0.readers directory."
|
|
118
|
-
logger.error(msg)
|
|
125
|
+
#### Reader Function Checks
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def check_reader_reference(reader_reference):
|
|
129
|
+
"""Check the reader_reference value."""
|
|
130
|
+
if isinstance(reader_reference, type(None)):
|
|
131
|
+
raise TypeError("`reader_reference` is None. Specify the reader reference name !")
|
|
132
|
+
if not isinstance(reader_reference, str):
|
|
133
|
+
raise TypeError(f"`reader_reference` must be a string. Got type {type(reader_reference)}.")
|
|
134
|
+
if reader_reference == "":
|
|
135
|
+
raise ValueError("`reader_reference` is an empty string. Specify the reader reference name !")
|
|
136
|
+
if len(reader_reference.split("/")) > 2:
|
|
137
|
+
raise ValueError("`reader_reference` expects to be composed by maximum one `/` (<DATA_SOURCE>/<CUSTOM_NAME>).")
|
|
138
|
+
return reader_reference
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def check_reader_exists(reader_reference, sensor_name):
|
|
142
|
+
"""Check the reader exists."""
|
|
143
|
+
valid_readers_references = available_readers(sensor_name)
|
|
144
|
+
if reader_reference not in valid_readers_references:
|
|
145
|
+
msg = (
|
|
146
|
+
f"{sensor_name} reader '{reader_reference}' does not exists. Valid readers are {valid_readers_references}."
|
|
147
|
+
)
|
|
119
148
|
raise ValueError(msg)
|
|
120
|
-
return reader_data_source
|
|
121
149
|
|
|
122
150
|
|
|
123
|
-
def
|
|
124
|
-
"""Check
|
|
125
|
-
|
|
126
|
-
|
|
151
|
+
def check_reader_arguments(reader):
|
|
152
|
+
"""Check the reader function have the expected input arguments."""
|
|
153
|
+
expected_arguments = ["filepath", "logger"]
|
|
154
|
+
signature = inspect.signature(reader)
|
|
155
|
+
reader_arguments = sorted(signature.parameters.keys())
|
|
156
|
+
if reader_arguments != expected_arguments:
|
|
157
|
+
raise ValueError(f"The reader must be defined with the following arguments: {expected_arguments}")
|
|
158
|
+
# Verify 'logger' default
|
|
159
|
+
logger_param = signature.parameters.get("logger")
|
|
160
|
+
if logger_param.default is inspect._empty:
|
|
161
|
+
raise ValueError(
|
|
162
|
+
"The 'logger' argument must have a default value (None).",
|
|
163
|
+
)
|
|
164
|
+
if logger_param.default is not None:
|
|
165
|
+
raise ValueError(
|
|
166
|
+
f"The default value for 'logger' must be None, got {logger_param.default!r}.",
|
|
167
|
+
)
|
|
127
168
|
|
|
128
|
-
Parameters
|
|
129
|
-
----------
|
|
130
|
-
reader_data_source : str
|
|
131
|
-
The directory within which the reader_name is located in the
|
|
132
|
-
disdrodb.l0.readers directory.
|
|
133
|
-
reader_name : str
|
|
134
|
-
Campaign name
|
|
135
169
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
170
|
+
def check_metadata_reader(metadata):
|
|
171
|
+
"""Check the metadata ``reader`` key is available and points to an existing disdrodb reader."""
|
|
172
|
+
data_source = metadata.get("data_source", "")
|
|
173
|
+
campaign_name = metadata.get("campaign_name", "")
|
|
174
|
+
station_name = metadata.get("station_name", "")
|
|
175
|
+
# Check the reader is specified
|
|
176
|
+
if "reader" not in metadata:
|
|
177
|
+
raise ValueError(
|
|
178
|
+
"The `reader` key is not specified in the metadata of the"
|
|
179
|
+
f" {data_source} {campaign_name} {station_name} station.",
|
|
180
|
+
)
|
|
181
|
+
if "sensor_name" not in metadata:
|
|
182
|
+
raise ValueError(
|
|
183
|
+
"The `sensor_name` is not specified in the metadata of the"
|
|
184
|
+
f" {data_source} {campaign_name} {station_name} station.",
|
|
185
|
+
)
|
|
186
|
+
# If the reader name is specified, test it is valid.
|
|
187
|
+
# --> Reader location: disdrodb.l0.readers.{sensor_name}.{reader_reference}
|
|
188
|
+
# --> reader_reference typically defined as "{DATA_SOURCE}"/"{CAMPAIGN_NAME}_{OPTIONAL_SUFFIX}"
|
|
189
|
+
reader_reference = metadata["reader"]
|
|
190
|
+
sensor_name = metadata["sensor_name"]
|
|
191
|
+
_ = get_reader(reader_reference, sensor_name=sensor_name)
|
|
157
192
|
|
|
158
193
|
|
|
159
|
-
def
|
|
160
|
-
"""
|
|
194
|
+
def check_software_readers():
|
|
195
|
+
"""Check the validity of all readers included in disdrodb software ."""
|
|
196
|
+
import disdrodb
|
|
161
197
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
# }
|
|
171
|
-
# Get list of reader data sources
|
|
172
|
-
list_reader_data_sources = _get_readers_data_sources()
|
|
173
|
-
|
|
174
|
-
# Build dictionary
|
|
175
|
-
dict_reader = {}
|
|
176
|
-
for data_source in list_reader_data_sources:
|
|
177
|
-
# Retrieve the filepath of the available readers
|
|
178
|
-
list_readers_paths = _get_readers_paths_by_data_source(data_source)
|
|
179
|
-
# Initialize the data_source dictionary
|
|
180
|
-
dict_reader[data_source] = {}
|
|
181
|
-
for reader_path in list_readers_paths:
|
|
182
|
-
reader_name = os.path.basename(reader_path).replace(".py", "")
|
|
183
|
-
dict_reader[data_source][reader_name] = reader_path
|
|
184
|
-
# Return available dictionary
|
|
185
|
-
return dict_reader
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
def available_readers(data_sources=None, reader_path=False):
|
|
189
|
-
"""Retrieve available readers information."""
|
|
190
|
-
# Get available readers dictionary
|
|
191
|
-
dict_readers = _get_available_readers_dict()
|
|
192
|
-
# If data sources is not None, subset the dictionary
|
|
193
|
-
if data_sources is not None:
|
|
194
|
-
# Check valid data sources
|
|
195
|
-
if isinstance(data_sources, str):
|
|
196
|
-
data_sources = [data_sources]
|
|
197
|
-
data_sources = [_check_reader_data_source(data_source) for data_source in data_sources]
|
|
198
|
-
# Create new dictionary
|
|
199
|
-
dict_readers = {data_source: dict_readers[data_source] for data_source in data_sources}
|
|
200
|
-
# If reader_path=False, provide {data_source: [list_reader_names]}
|
|
201
|
-
if not reader_path:
|
|
202
|
-
dict_readers = {data_source: list(dict_readers.keys()) for data_source, dict_readers in dict_readers.items()}
|
|
203
|
-
return dict_readers
|
|
198
|
+
sensors_names = disdrodb.available_sensor_names()
|
|
199
|
+
for sensor_name in sensors_names:
|
|
200
|
+
readers_references = available_readers(sensor_name=sensor_name, return_path=False)
|
|
201
|
+
for reader_reference in readers_references:
|
|
202
|
+
try:
|
|
203
|
+
_ = get_reader(reader_reference=reader_reference, sensor_name=sensor_name)
|
|
204
|
+
except Exception as e:
|
|
205
|
+
raise ValueError(f"Invalid {sensor_name} {reader_reference}.py reader: {e}")
|
|
204
206
|
|
|
205
207
|
|
|
206
208
|
####--------------------------------------------------------------------------.
|
|
209
|
+
#### Reader Retrieval
|
|
207
210
|
|
|
208
211
|
|
|
209
|
-
def
|
|
210
|
-
"""
|
|
212
|
+
def get_reader(reader_reference, sensor_name):
|
|
213
|
+
"""Retrieve the reader function.
|
|
211
214
|
|
|
212
215
|
Parameters
|
|
213
216
|
----------
|
|
214
|
-
|
|
215
|
-
The
|
|
216
|
-
disdrodb.l0.readers
|
|
217
|
-
|
|
218
|
-
|
|
217
|
+
reader_reference : str
|
|
218
|
+
The reader reference name.
|
|
219
|
+
The reader is located at ``disdrodb.l0.readers.{sensor_name}.{reader_reference}``.
|
|
220
|
+
The reader_reference naming convention is ``"{DATA_SOURCE}"/"{CAMPAIGN_NAME}_{OPTIONAL_SUFFIX}"``.
|
|
221
|
+
sensor_name : str
|
|
222
|
+
The sensor name.
|
|
219
223
|
|
|
220
224
|
Returns
|
|
221
225
|
-------
|
|
222
|
-
|
|
223
|
-
The reader() function
|
|
226
|
+
callable
|
|
227
|
+
The ``reader()`` function.
|
|
224
228
|
|
|
225
229
|
"""
|
|
226
|
-
# Check
|
|
227
|
-
|
|
228
|
-
reader_name = _check_reader_exists(reader_data_source=reader_data_source, reader_name=reader_name)
|
|
229
|
-
# Retrieve reader function
|
|
230
|
-
if reader_name:
|
|
231
|
-
full_name = f"disdrodb.l0.readers.{reader_data_source}.{reader_name}.reader"
|
|
232
|
-
module_name, unit_name = full_name.rsplit(".", 1)
|
|
233
|
-
my_reader = getattr(__import__(module_name, fromlist=[""]), unit_name)
|
|
234
|
-
|
|
235
|
-
return my_reader
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
####--------------------------------------------------------------------------.
|
|
239
|
-
#### Checks for reader args
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
def _get_expected_reader_arguments():
|
|
243
|
-
"""Return a list with the expected reader arguments."""
|
|
244
|
-
expected_arguments = [
|
|
245
|
-
"raw_dir",
|
|
246
|
-
"processed_dir",
|
|
247
|
-
"station_name",
|
|
248
|
-
"force",
|
|
249
|
-
"verbose",
|
|
250
|
-
"parallel",
|
|
251
|
-
"debugging_mode",
|
|
252
|
-
]
|
|
253
|
-
return expected_arguments
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
def _check_reader_arguments(reader):
|
|
257
|
-
"""Check the reader have the expected input arguments."""
|
|
258
|
-
import inspect
|
|
259
|
-
|
|
260
|
-
signature = inspect.signature(reader)
|
|
261
|
-
reader_arguments = sorted(list(signature.parameters.keys()))
|
|
262
|
-
expected_arguments = sorted(_get_expected_reader_arguments())
|
|
263
|
-
if reader_arguments != expected_arguments:
|
|
264
|
-
raise ValueError(f"The reader must be defined with the following arguments: {expected_arguments}")
|
|
265
|
-
return None
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
####--------------------------------------------------------------------------.
|
|
269
|
-
#### Checks for metadata reader key
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
def _check_metadata_reader(metadata):
|
|
273
|
-
"""Check reader key is available and there is the associated reader."""
|
|
274
|
-
# Check the reader is specified
|
|
275
|
-
if "reader" not in metadata:
|
|
276
|
-
raise ValueError("The reader is not specified in the metadata.")
|
|
277
|
-
# If the reader name is specified, test it is valid.
|
|
278
|
-
# - Convention: reader: "<DATA_SOURCE>/<READER_NAME>" in disdrodb.l0.readers
|
|
279
|
-
reader_reference = metadata.get("reader")
|
|
280
|
-
# - Check it contains /
|
|
281
|
-
if "/" not in reader_reference:
|
|
282
|
-
raise ValueError(
|
|
283
|
-
f"The reader '{reader_reference}' reported in the metadata is not valid. Must have"
|
|
284
|
-
" '<DATA_SOURCE>/<READER_NAME>' pattern."
|
|
285
|
-
)
|
|
286
|
-
# - Get the reader_reference component list
|
|
287
|
-
reader_components = reader_reference.split("/")
|
|
288
|
-
# - Check composed by two elements
|
|
289
|
-
if len(reader_components) != 2:
|
|
290
|
-
raise ValueError("Expecting the reader reference to be composed of <DATA_SOURCE>/<READER_NAME>.")
|
|
291
|
-
# - Retrieve reader data source and reader name
|
|
292
|
-
reader_data_source = reader_components[0]
|
|
293
|
-
reader_name = reader_components[1]
|
|
230
|
+
# Check reader reference value
|
|
231
|
+
reader_reference = check_reader_reference(reader_reference)
|
|
294
232
|
|
|
295
|
-
#
|
|
296
|
-
|
|
233
|
+
# Check reader exists
|
|
234
|
+
check_reader_exists(reader_reference=reader_reference, sensor_name=sensor_name)
|
|
297
235
|
|
|
298
|
-
|
|
236
|
+
# Replace "/" with "." to define reader reference path
|
|
237
|
+
reader_reference = reader_reference.replace("/", ".")
|
|
299
238
|
|
|
239
|
+
# Import reader function
|
|
240
|
+
# --> This will not raise error if check_reader_exists pass !
|
|
241
|
+
full_name = f"disdrodb.l0.readers.{sensor_name}.{reader_reference}.reader"
|
|
242
|
+
module_name, unit_name = full_name.rsplit(".", 1)
|
|
243
|
+
reader = getattr(__import__(module_name, fromlist=[""]), unit_name)
|
|
300
244
|
|
|
301
|
-
|
|
302
|
-
|
|
245
|
+
# Check reader function validity
|
|
246
|
+
check_reader_arguments(reader)
|
|
303
247
|
|
|
304
|
-
|
|
305
|
-
"""
|
|
306
|
-
reader_data_source = reader_data_source_name.split("/")[0]
|
|
307
|
-
reader_name = reader_data_source_name.split("/")[1]
|
|
308
|
-
reader = get_reader_function(reader_data_source=reader_data_source, reader_name=reader_name)
|
|
248
|
+
# Return readere function
|
|
309
249
|
return reader
|
|
310
250
|
|
|
311
251
|
|
|
312
|
-
def
|
|
313
|
-
"""Retrieve the reader
|
|
314
|
-
|
|
315
|
-
The convention for metadata reader key: <data_source/reader_name> in disdrodb.l0.readers
|
|
316
|
-
"""
|
|
317
|
-
reader_data_source_name = metadata.get("reader")
|
|
318
|
-
return get_reader_function_from_metadata_key(reader_data_source_name)
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
def get_station_reader_function(data_source, campaign_name, station_name, base_dir=None):
|
|
322
|
-
"""Retrieve the reader function from the station metadata."""
|
|
252
|
+
def get_station_reader(data_source, campaign_name, station_name, metadata_archive_dir=None):
|
|
253
|
+
"""Retrieve the reader function of a specific DISDRODB station."""
|
|
323
254
|
from disdrodb.metadata import read_station_metadata
|
|
324
255
|
|
|
325
256
|
# Get metadata
|
|
326
257
|
metadata = read_station_metadata(
|
|
327
|
-
|
|
328
|
-
product="RAW",
|
|
258
|
+
metadata_archive_dir=metadata_archive_dir,
|
|
329
259
|
data_source=data_source,
|
|
330
260
|
campaign_name=campaign_name,
|
|
331
261
|
station_name=station_name,
|
|
332
262
|
)
|
|
333
|
-
# ------------------------------------------------------------------------.
|
|
334
|
-
# Check reader key is within the dictionary
|
|
335
|
-
if "reader" not in metadata:
|
|
336
|
-
raise ValueError(
|
|
337
|
-
"The `reader` key is not available in the metadata of the"
|
|
338
|
-
f" {data_source} {campaign_name} {station_name} station."
|
|
339
|
-
)
|
|
340
263
|
|
|
341
|
-
#
|
|
342
|
-
|
|
343
|
-
|
|
264
|
+
# Retrieve reader function using metadata information
|
|
265
|
+
reader = get_reader_from_metadata(metadata)
|
|
266
|
+
|
|
267
|
+
# Return the reader function
|
|
268
|
+
return reader
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def get_reader_from_metadata(metadata):
|
|
272
|
+
"""Retrieve the reader function based on the metadata information.
|
|
344
273
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
274
|
+
The reader_reference naming convention is ``"{DATA_SOURCE}"/"{CAMPAIGN_NAME}_{OPTIONAL_SUFFIX}"``.
|
|
275
|
+
The reader is located at ``disdrodb.l0.readers.{sensor_name}.{reader_reference}``.
|
|
276
|
+
"""
|
|
277
|
+
# Check validity of metadata reader key
|
|
278
|
+
check_metadata_reader(metadata)
|
|
348
279
|
|
|
349
|
-
#
|
|
350
|
-
|
|
351
|
-
|
|
280
|
+
# Extract reader information from metadata
|
|
281
|
+
reader_reference = metadata.get("reader")
|
|
282
|
+
sensor_name = metadata.get("sensor_name")
|
|
352
283
|
|
|
284
|
+
# Retrieve reader function
|
|
285
|
+
reader = get_reader(reader_reference=reader_reference, sensor_name=sensor_name)
|
|
353
286
|
return reader
|
|
354
287
|
|
|
355
288
|
|
|
356
289
|
####--------------------------------------------------------------------------.
|
|
357
|
-
#### Readers
|
|
290
|
+
#### Readers Docstring
|
|
358
291
|
|
|
359
292
|
|
|
360
293
|
def is_documented_by(original):
|
|
@@ -374,73 +307,16 @@ def is_documented_by(original):
|
|
|
374
307
|
|
|
375
308
|
|
|
376
309
|
def reader_generic_docstring():
|
|
377
|
-
"""
|
|
310
|
+
"""Reader to convert a raw data file to DISDRODB L0A or L0B format.
|
|
311
|
+
|
|
312
|
+
Raw text files are read and converted to a ``pandas.DataFrame`` (L0A format).
|
|
313
|
+
Raw netCDF files are read and converted to a ``xarray.Dataset`` (L0B format).
|
|
378
314
|
|
|
379
315
|
Parameters
|
|
380
316
|
----------
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
- ``/data/<station_name>/<raw_files>``
|
|
387
|
-
- ``/metadata/<station_name>.yml``
|
|
388
|
-
|
|
389
|
-
**Important points:**
|
|
390
|
-
|
|
391
|
-
- For each ``<station_name>``, there must be a corresponding YAML file in the metadata subdirectory.
|
|
392
|
-
- The ``<CAMPAIGN_NAME>`` are expected to be UPPER CASE.
|
|
393
|
-
- The ``<CAMPAIGN_NAME>`` must semantically match between:
|
|
394
|
-
|
|
395
|
-
- the ``raw_dir`` and ``processed_dir`` directory paths;
|
|
396
|
-
- with the key ``campaign_name`` within the metadata YAML files.
|
|
397
|
-
|
|
398
|
-
processed_dir : str
|
|
399
|
-
The desired directory path for the processed DISDRODB L0A and L0B products.
|
|
400
|
-
The path should have the following structure ``<...>/DISDRODB/Processed/<DATA_SOURCE>/<CAMPAIGN_NAME>``
|
|
401
|
-
For testing purposes, this function exceptionally accepts also a directory path simply ending
|
|
402
|
-
with ``<CAMPAIGN_NAME>`` (e.g., ``/tmp/<CAMPAIGN_NAME>``).
|
|
403
|
-
|
|
404
|
-
station_name : str
|
|
405
|
-
The name of the station.
|
|
406
|
-
|
|
407
|
-
force : bool, optional
|
|
408
|
-
If ``True``, overwrite existing data in destination directories.
|
|
409
|
-
If ``False``, raise an error if data already exists in destination directories.
|
|
410
|
-
Default is ``False``.
|
|
411
|
-
|
|
412
|
-
verbose : bool, optional
|
|
413
|
-
If ``True``, print detailed processing information to the terminal.
|
|
414
|
-
Default is ``True``.
|
|
415
|
-
|
|
416
|
-
parallel : bool, optional
|
|
417
|
-
If ``True``, process the files simultaneously in multiple processes.
|
|
418
|
-
The number of simultaneous processes can be customized using the ``dask.distributed.LocalCluster``.
|
|
419
|
-
If ``False``, process the files sequentially in a single process.
|
|
420
|
-
Default is ``False``.
|
|
421
|
-
|
|
422
|
-
debugging_mode : bool, optional
|
|
423
|
-
If ``True``, reduce the amount of data to process.
|
|
424
|
-
Only the first 3 raw data files will be processed.
|
|
425
|
-
Default is ``False``.
|
|
317
|
+
filepath : str
|
|
318
|
+
Filepath of the raw data file to be processed.
|
|
319
|
+
logger: logging.Logger, optional
|
|
320
|
+
Logger to use for logging messages.
|
|
321
|
+
Default is ``None``, which means no logger is used.
|
|
426
322
|
"""
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
####--------------------------------------------------------------------------.
|
|
430
|
-
#### Check DISDRODB readers
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
def check_available_readers():
|
|
434
|
-
"""Check the readers arguments of all package."""
|
|
435
|
-
dict_all_readers = available_readers(data_sources=None, reader_path=False)
|
|
436
|
-
for reader_data_source, list_reader_name in dict_all_readers.items():
|
|
437
|
-
for reader_name in list_reader_name:
|
|
438
|
-
try:
|
|
439
|
-
reader = get_reader_function(reader_data_source=reader_data_source, reader_name=reader_name)
|
|
440
|
-
_check_reader_arguments(reader)
|
|
441
|
-
except Exception as e:
|
|
442
|
-
raise ValueError(f"Invalid reader for {reader_data_source}/{reader_name}.py. The error is {e}")
|
|
443
|
-
return None
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
####--------------------------------------------------------------------------.
|