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
disdrodb/utils/logger.py
CHANGED
|
@@ -24,10 +24,9 @@ import re
|
|
|
24
24
|
from asyncio.log import logger
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def
|
|
28
|
-
"""Create file
|
|
27
|
+
def create_logger_file(logs_dir, filename, parallel):
|
|
28
|
+
"""Create logger file."""
|
|
29
29
|
# Create logs directory
|
|
30
|
-
logs_dir = os.path.join(processed_dir, "logs", product, station_name)
|
|
31
30
|
os.makedirs(logs_dir, exist_ok=True)
|
|
32
31
|
|
|
33
32
|
# Define logger filepath
|
|
@@ -35,25 +34,28 @@ def create_file_logger(processed_dir, product, station_name, filename, parallel)
|
|
|
35
34
|
logger_filepath = os.path.join(logs_dir, logger_filename)
|
|
36
35
|
|
|
37
36
|
# Set logger
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
else
|
|
41
|
-
logger = logging.getLogger() # root logger
|
|
37
|
+
# - getLogger() # root logger
|
|
38
|
+
# - getLogger(filename) does not log submodules logs
|
|
39
|
+
logger = logging.getLogger(filename) if parallel else logging.getLogger()
|
|
42
40
|
|
|
43
41
|
handler = logging.FileHandler(logger_filepath, mode="w")
|
|
44
42
|
format_type = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
45
43
|
handler.setFormatter(logging.Formatter(format_type))
|
|
46
44
|
logger.addHandler(handler)
|
|
47
45
|
logger.setLevel(logging.DEBUG)
|
|
48
|
-
|
|
46
|
+
|
|
47
|
+
# Define logger filepath
|
|
48
|
+
# - LogCaptureHandler of pytest does not have baseFilename attribute --> So set None
|
|
49
|
+
logger_filepath = logger.handlers[0].baseFilename if not os.environ.get("PYTEST_CURRENT_TEST") else None
|
|
50
|
+
return logger, logger_filepath
|
|
49
51
|
|
|
50
52
|
|
|
51
|
-
def close_logger(logger
|
|
52
|
-
"""Close the logger
|
|
53
|
+
def close_logger(logger) -> None:
|
|
54
|
+
"""Close the logger.
|
|
53
55
|
|
|
54
56
|
Parameters
|
|
55
57
|
----------
|
|
56
|
-
logger :
|
|
58
|
+
logger : logging.Logger
|
|
57
59
|
Logger object.
|
|
58
60
|
"""
|
|
59
61
|
handlers = logger.handlers[:]
|
|
@@ -71,17 +73,18 @@ def log_debug(logger: logger, msg: str, verbose: bool = False) -> None:
|
|
|
71
73
|
|
|
72
74
|
Parameters
|
|
73
75
|
----------
|
|
74
|
-
logger :
|
|
76
|
+
logger : logging.Logger
|
|
75
77
|
Log object.
|
|
76
78
|
msg : str
|
|
77
79
|
Message.
|
|
78
80
|
verbose : bool, optional
|
|
79
81
|
Whether to verbose the processing.
|
|
80
|
-
The default is False
|
|
82
|
+
The default value is ``False``.
|
|
81
83
|
"""
|
|
82
84
|
if verbose:
|
|
83
85
|
print(" - " + msg)
|
|
84
|
-
logger
|
|
86
|
+
if logger is not None:
|
|
87
|
+
logger.debug(msg)
|
|
85
88
|
|
|
86
89
|
|
|
87
90
|
def log_info(logger: logger, msg: str, verbose: bool = False) -> None:
|
|
@@ -89,17 +92,18 @@ def log_info(logger: logger, msg: str, verbose: bool = False) -> None:
|
|
|
89
92
|
|
|
90
93
|
Parameters
|
|
91
94
|
----------
|
|
92
|
-
logger :
|
|
95
|
+
logger : logging.Logger
|
|
93
96
|
Log object.
|
|
94
97
|
msg : str
|
|
95
98
|
Message.
|
|
96
99
|
verbose : bool, optional
|
|
97
100
|
Whether to verbose the processing.
|
|
98
|
-
The default is False
|
|
101
|
+
The default value is ``False``.
|
|
99
102
|
"""
|
|
100
103
|
if verbose:
|
|
101
104
|
print(" - " + msg)
|
|
102
|
-
logger
|
|
105
|
+
if logger is not None:
|
|
106
|
+
logger.info(msg)
|
|
103
107
|
|
|
104
108
|
|
|
105
109
|
def log_warning(logger: logger, msg: str, verbose: bool = False) -> None:
|
|
@@ -107,17 +111,18 @@ def log_warning(logger: logger, msg: str, verbose: bool = False) -> None:
|
|
|
107
111
|
|
|
108
112
|
Parameters
|
|
109
113
|
----------
|
|
110
|
-
logger :
|
|
114
|
+
logger : logging.Logger
|
|
111
115
|
Log object.
|
|
112
116
|
msg : str
|
|
113
117
|
Message.
|
|
114
118
|
verbose : bool, optional
|
|
115
119
|
Whether to verbose the processing.
|
|
116
|
-
The default is False
|
|
120
|
+
The default value is ``False``.
|
|
117
121
|
"""
|
|
118
122
|
if verbose:
|
|
119
123
|
print(" - " + msg)
|
|
120
|
-
logger
|
|
124
|
+
if logger is not None:
|
|
125
|
+
logger.warning(msg)
|
|
121
126
|
|
|
122
127
|
|
|
123
128
|
def log_error(logger: logger, msg: str, verbose: bool = False) -> None:
|
|
@@ -125,25 +130,22 @@ def log_error(logger: logger, msg: str, verbose: bool = False) -> None:
|
|
|
125
130
|
|
|
126
131
|
Parameters
|
|
127
132
|
----------
|
|
128
|
-
logger :
|
|
133
|
+
logger : logging.Logger
|
|
129
134
|
Log object.
|
|
130
135
|
msg : str
|
|
131
136
|
Message.
|
|
132
137
|
verbose : bool, optional
|
|
133
138
|
Whether to verbose the processing.
|
|
134
|
-
The default is False
|
|
139
|
+
The default value is ``False``.
|
|
135
140
|
"""
|
|
136
141
|
if verbose:
|
|
137
142
|
print(" - " + msg)
|
|
138
|
-
logger
|
|
143
|
+
if logger is not None:
|
|
144
|
+
logger.error(msg)
|
|
139
145
|
|
|
140
146
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
station_logs_dir = os.path.dirname(list_logs[0])
|
|
144
|
-
station_name = station_logs_dir.split(os.path.sep)[-1]
|
|
145
|
-
logs_dir = os.path.dirname(station_logs_dir)
|
|
146
|
-
return station_name, logs_dir
|
|
147
|
+
####---------------------------------------------------------------------------.
|
|
148
|
+
#### SUMMARY LOGS
|
|
147
149
|
|
|
148
150
|
|
|
149
151
|
def _define_station_summary_log_file(list_logs, summary_filepath):
|
|
@@ -164,16 +166,27 @@ def _define_station_summary_log_file(list_logs, summary_filepath):
|
|
|
164
166
|
def _define_station_problem_log_file(list_logs, problem_filepath):
|
|
165
167
|
# - Copy the log of files with warnings and error
|
|
166
168
|
list_keywords = ["ERROR"] # "WARNING"
|
|
169
|
+
list_patterns = ["ValueError: Less than 5 timesteps available for day"]
|
|
167
170
|
re_keyword = re.compile("|".join(list_keywords))
|
|
171
|
+
# Compile patterns to ignore, escaping any special regex characters
|
|
172
|
+
re_patterns = re.compile("|".join(map(re.escape, list_patterns))) if list_patterns else None
|
|
173
|
+
# Initialize problem log file
|
|
168
174
|
any_problem = False
|
|
175
|
+
n_files = len(list_logs)
|
|
176
|
+
n_files_with_problems = 0
|
|
169
177
|
with open(problem_filepath, "w") as output_file:
|
|
178
|
+
# Loop over log files and collect problems
|
|
170
179
|
for log_filepath in list_logs:
|
|
171
180
|
log_with_problem = False
|
|
172
181
|
# Check if an error is reported
|
|
173
182
|
with open(log_filepath) as input_file:
|
|
174
183
|
for line in input_file:
|
|
175
184
|
if re_keyword.search(line):
|
|
185
|
+
# If the line matches an ignore pattern, skip it
|
|
186
|
+
if re_patterns and re_patterns.search(line):
|
|
187
|
+
continue
|
|
176
188
|
log_with_problem = True
|
|
189
|
+
n_files_with_problems += 1
|
|
177
190
|
any_problem = True
|
|
178
191
|
break
|
|
179
192
|
# If it is reported, copy the log file in the logs_problem file
|
|
@@ -181,34 +194,143 @@ def _define_station_problem_log_file(list_logs, problem_filepath):
|
|
|
181
194
|
with open(log_filepath) as input_file:
|
|
182
195
|
output_file.write(input_file.read())
|
|
183
196
|
|
|
197
|
+
# Add number of files with problems
|
|
198
|
+
msg = f"SUMMARY: {n_files_with_problems} of {n_files} files had problems."
|
|
199
|
+
output_file.write(msg)
|
|
200
|
+
|
|
184
201
|
# If no problems occurred, remove the logs_problem_<station_name>.log file
|
|
185
202
|
if not any_problem:
|
|
186
203
|
os.remove(problem_filepath)
|
|
187
204
|
|
|
188
205
|
|
|
189
|
-
def
|
|
190
|
-
|
|
206
|
+
def create_product_logs(
|
|
207
|
+
product,
|
|
208
|
+
data_source,
|
|
209
|
+
campaign_name,
|
|
210
|
+
station_name,
|
|
211
|
+
data_archive_dir=None,
|
|
212
|
+
# Logs list
|
|
213
|
+
list_logs=None, # If none, list it !
|
|
214
|
+
# Product options
|
|
215
|
+
**product_kwargs,
|
|
216
|
+
):
|
|
217
|
+
"""Create station summary and station problems log files.
|
|
218
|
+
|
|
219
|
+
The summary log selects only logged lines with ``root``, ``WARNING``, and ``ERROR`` keywords.
|
|
220
|
+
The problems log file selects only logged lines with the ``ERROR`` keyword.
|
|
221
|
+
|
|
222
|
+
The logs directory structure is the follow:
|
|
223
|
+
/logs
|
|
224
|
+
- /files/<product_acronym>/<station> (same structure as data ... a log for each processed file)
|
|
225
|
+
- /summary
|
|
226
|
+
--> SUMMARY.<PRODUCT_ACRONYM>.<CAMPAIGN_NAME>.<STATION_NAME>.log
|
|
227
|
+
- /problems
|
|
228
|
+
--> PROBLEMS.<PRODUCT_ACRONYM>.<CAMPAIGN_NAME>.<STATION_NAME>.log
|
|
191
229
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
230
|
+
Parameters
|
|
231
|
+
----------
|
|
232
|
+
product : str
|
|
233
|
+
The DISDRODB product.
|
|
234
|
+
data_source : str
|
|
235
|
+
The data source name.
|
|
236
|
+
campaign_name : str
|
|
237
|
+
The campaign name.
|
|
238
|
+
station_name : str
|
|
239
|
+
The station name.
|
|
240
|
+
data_archive_dir : str, optional
|
|
241
|
+
The base directory path. Default is None.
|
|
242
|
+
sample_interval : str, optional
|
|
243
|
+
The sample interval for L2E option. Default is None.
|
|
244
|
+
rolling : str, optional
|
|
245
|
+
The rolling option for L2E. Default is None.
|
|
246
|
+
model_name : str, optional
|
|
247
|
+
The model name for L2M. Default is None.
|
|
248
|
+
list_logs : list, optional
|
|
249
|
+
List of log file paths. If None, the function will list the log files.
|
|
250
|
+
|
|
251
|
+
Returns
|
|
252
|
+
-------
|
|
253
|
+
None
|
|
199
254
|
|
|
200
255
|
"""
|
|
256
|
+
from disdrodb.api.path import define_campaign_dir, define_filename, define_logs_dir
|
|
257
|
+
from disdrodb.utils.directories import list_files
|
|
258
|
+
|
|
259
|
+
# --------------------------------------------------------.
|
|
260
|
+
# Search for logs file
|
|
261
|
+
if list_logs is None:
|
|
262
|
+
# Define product logs directory within /files/....
|
|
263
|
+
logs_dir = define_logs_dir(
|
|
264
|
+
product=product,
|
|
265
|
+
data_archive_dir=data_archive_dir,
|
|
266
|
+
data_source=data_source,
|
|
267
|
+
campaign_name=campaign_name,
|
|
268
|
+
station_name=station_name,
|
|
269
|
+
# Product options
|
|
270
|
+
**product_kwargs,
|
|
271
|
+
)
|
|
272
|
+
list_logs = list_files(logs_dir, glob_pattern="*", recursive=True)
|
|
273
|
+
|
|
274
|
+
# --------------------------------------------------------.
|
|
201
275
|
# LogCaptureHandler of pytest does not have baseFilename attribute, so it returns None
|
|
202
276
|
if list_logs[0] is None:
|
|
203
|
-
return
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
277
|
+
return
|
|
278
|
+
|
|
279
|
+
# --------------------------------------------------------.
|
|
280
|
+
# Define /summary and /problem directory
|
|
281
|
+
campaign_dir = define_campaign_dir(
|
|
282
|
+
archive_dir=data_archive_dir,
|
|
283
|
+
product=product,
|
|
284
|
+
data_source=data_source,
|
|
285
|
+
campaign_name=campaign_name,
|
|
286
|
+
)
|
|
287
|
+
logs_summary_dir = os.path.join(campaign_dir, "logs", "summary")
|
|
288
|
+
logs_problem_dir = os.path.join(campaign_dir, "logs", "problems")
|
|
289
|
+
|
|
290
|
+
os.makedirs(logs_summary_dir, exist_ok=True)
|
|
291
|
+
os.makedirs(logs_problem_dir, exist_ok=True)
|
|
292
|
+
|
|
293
|
+
# --------------------------------------------------------.
|
|
207
294
|
# Define station summary log file name
|
|
208
|
-
|
|
295
|
+
summary_filename = define_filename(
|
|
296
|
+
product=product,
|
|
297
|
+
campaign_name=campaign_name,
|
|
298
|
+
station_name=station_name,
|
|
299
|
+
# Filename options
|
|
300
|
+
add_version=False,
|
|
301
|
+
add_time_period=False,
|
|
302
|
+
add_extension=False,
|
|
303
|
+
prefix="SUMMARY",
|
|
304
|
+
suffix="log",
|
|
305
|
+
# Product options
|
|
306
|
+
**product_kwargs,
|
|
307
|
+
)
|
|
308
|
+
summary_filepath = os.path.join(logs_summary_dir, summary_filename)
|
|
309
|
+
|
|
209
310
|
# Define station problem logs file name
|
|
210
|
-
|
|
211
|
-
|
|
311
|
+
problem_filename = define_filename(
|
|
312
|
+
product=product,
|
|
313
|
+
campaign_name=campaign_name,
|
|
314
|
+
station_name=station_name,
|
|
315
|
+
# Filename options
|
|
316
|
+
add_version=False,
|
|
317
|
+
add_time_period=False,
|
|
318
|
+
add_extension=False,
|
|
319
|
+
prefix="PROBLEMS",
|
|
320
|
+
suffix="log",
|
|
321
|
+
# Product options
|
|
322
|
+
**product_kwargs,
|
|
323
|
+
)
|
|
324
|
+
problem_filepath = os.path.join(logs_problem_dir, problem_filename)
|
|
325
|
+
|
|
326
|
+
# --------------------------------------------------------.
|
|
327
|
+
# Create summary log file
|
|
212
328
|
_define_station_summary_log_file(list_logs, summary_filepath)
|
|
213
|
-
|
|
329
|
+
|
|
330
|
+
# Create problem log file (if no problems, no file created)
|
|
214
331
|
_define_station_problem_log_file(list_logs, problem_filepath)
|
|
332
|
+
|
|
333
|
+
# --------------------------------------------------------.
|
|
334
|
+
# Remove /problem directory if empty !
|
|
335
|
+
if len(os.listdir(logs_problem_dir)) == 0:
|
|
336
|
+
os.rmdir(logs_problem_dir)
|