disdrodb 0.0.21__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.
Files changed (264) hide show
  1. disdrodb/__init__.py +132 -15
  2. disdrodb/_config.py +4 -2
  3. disdrodb/_version.py +9 -4
  4. disdrodb/api/checks.py +264 -237
  5. disdrodb/api/configs.py +4 -8
  6. disdrodb/api/create_directories.py +235 -290
  7. disdrodb/api/info.py +217 -26
  8. disdrodb/api/io.py +295 -269
  9. disdrodb/api/path.py +597 -173
  10. disdrodb/api/search.py +486 -0
  11. disdrodb/{metadata/scripts → cli}/disdrodb_check_metadata_archive.py +12 -7
  12. disdrodb/{utils/pandas.py → cli/disdrodb_data_archive_directory.py} +9 -18
  13. disdrodb/cli/disdrodb_download_archive.py +86 -0
  14. disdrodb/cli/disdrodb_download_metadata_archive.py +53 -0
  15. disdrodb/cli/disdrodb_download_station.py +84 -0
  16. disdrodb/{api/scripts → cli}/disdrodb_initialize_station.py +22 -10
  17. disdrodb/cli/disdrodb_metadata_archive_directory.py +32 -0
  18. disdrodb/{data_transfer/scripts/disdrodb_download_station.py → cli/disdrodb_open_data_archive.py} +22 -22
  19. disdrodb/cli/disdrodb_open_logs_directory.py +69 -0
  20. disdrodb/{data_transfer/scripts/disdrodb_upload_station.py → cli/disdrodb_open_metadata_archive.py} +22 -24
  21. disdrodb/cli/disdrodb_open_metadata_directory.py +71 -0
  22. disdrodb/cli/disdrodb_open_product_directory.py +74 -0
  23. disdrodb/cli/disdrodb_open_readers_directory.py +32 -0
  24. disdrodb/{l0/scripts → cli}/disdrodb_run_l0.py +38 -31
  25. disdrodb/{l0/scripts → cli}/disdrodb_run_l0_station.py +32 -30
  26. disdrodb/{l0/scripts → cli}/disdrodb_run_l0a.py +30 -21
  27. disdrodb/{l0/scripts → cli}/disdrodb_run_l0a_station.py +24 -33
  28. disdrodb/{l0/scripts → cli}/disdrodb_run_l0b.py +30 -21
  29. disdrodb/{l0/scripts → cli}/disdrodb_run_l0b_station.py +25 -34
  30. disdrodb/cli/disdrodb_run_l0c.py +130 -0
  31. disdrodb/cli/disdrodb_run_l0c_station.py +129 -0
  32. disdrodb/cli/disdrodb_run_l1.py +122 -0
  33. disdrodb/cli/disdrodb_run_l1_station.py +121 -0
  34. disdrodb/cli/disdrodb_run_l2e.py +122 -0
  35. disdrodb/cli/disdrodb_run_l2e_station.py +122 -0
  36. disdrodb/cli/disdrodb_run_l2m.py +122 -0
  37. disdrodb/cli/disdrodb_run_l2m_station.py +122 -0
  38. disdrodb/cli/disdrodb_upload_archive.py +105 -0
  39. disdrodb/cli/disdrodb_upload_station.py +98 -0
  40. disdrodb/configs.py +90 -25
  41. disdrodb/data_transfer/__init__.py +22 -0
  42. disdrodb/data_transfer/download_data.py +87 -90
  43. disdrodb/data_transfer/upload_data.py +64 -37
  44. disdrodb/data_transfer/zenodo.py +15 -18
  45. disdrodb/docs.py +1 -1
  46. disdrodb/issue/__init__.py +17 -4
  47. disdrodb/issue/checks.py +10 -23
  48. disdrodb/issue/reader.py +9 -12
  49. disdrodb/issue/writer.py +14 -17
  50. disdrodb/l0/__init__.py +17 -26
  51. disdrodb/l0/check_configs.py +35 -23
  52. disdrodb/l0/check_standards.py +32 -42
  53. disdrodb/l0/configs/{Thies_LPM → LPM}/bins_diameter.yml +44 -44
  54. disdrodb/l0/configs/{Thies_LPM → LPM}/bins_velocity.yml +40 -40
  55. disdrodb/l0/configs/LPM/l0a_encodings.yml +80 -0
  56. disdrodb/l0/configs/{Thies_LPM → LPM}/l0b_cf_attrs.yml +62 -59
  57. disdrodb/l0/configs/{Thies_LPM → LPM}/l0b_encodings.yml +9 -9
  58. disdrodb/l0/configs/{Thies_LPM → LPM}/raw_data_format.yml +245 -245
  59. disdrodb/l0/configs/{OTT_Parsivel → PARSIVEL}/bins_diameter.yml +66 -66
  60. disdrodb/l0/configs/{OTT_Parsivel → PARSIVEL}/bins_velocity.yml +64 -64
  61. disdrodb/l0/configs/PARSIVEL/l0a_encodings.yml +32 -0
  62. disdrodb/l0/configs/{OTT_Parsivel → PARSIVEL}/l0b_cf_attrs.yml +22 -20
  63. disdrodb/l0/configs/{OTT_Parsivel → PARSIVEL}/l0b_encodings.yml +17 -17
  64. disdrodb/l0/configs/{OTT_Parsivel → PARSIVEL}/raw_data_format.yml +77 -77
  65. disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/bins_diameter.yml +64 -64
  66. disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/bins_velocity.yml +64 -64
  67. disdrodb/l0/configs/PARSIVEL2/l0a_encodings.yml +39 -0
  68. disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/l0b_cf_attrs.yml +24 -22
  69. disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/l0b_encodings.yml +20 -20
  70. disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/raw_data_format.yml +98 -98
  71. disdrodb/l0/configs/{RD_80 → RD80}/bins_diameter.yml +40 -40
  72. disdrodb/l0/configs/RD80/l0a_encodings.yml +16 -0
  73. disdrodb/l0/configs/{RD_80 → RD80}/l0b_cf_attrs.yml +3 -3
  74. disdrodb/l0/configs/RD80/l0b_encodings.yml +135 -0
  75. disdrodb/l0/configs/{RD_80 → RD80}/raw_data_format.yml +48 -48
  76. disdrodb/l0/l0_reader.py +216 -340
  77. disdrodb/l0/l0a_processing.py +237 -208
  78. disdrodb/l0/l0b_nc_processing.py +227 -80
  79. disdrodb/l0/l0b_processing.py +93 -173
  80. disdrodb/l0/l0c_processing.py +627 -0
  81. disdrodb/l0/readers/{ARM → LPM/ARM}/ARM_LPM.py +36 -58
  82. disdrodb/l0/readers/LPM/AUSTRALIA/MELBOURNE_2007_LPM.py +226 -0
  83. disdrodb/l0/readers/LPM/BRAZIL/CHUVA_LPM.py +185 -0
  84. disdrodb/l0/readers/LPM/BRAZIL/GOAMAZON_LPM.py +183 -0
  85. disdrodb/l0/readers/LPM/ITALY/GID_LPM.py +179 -0
  86. disdrodb/l0/readers/{UK → LPM/UK}/DIVEN.py +14 -35
  87. disdrodb/l0/readers/PARSIVEL/AUSTRALIA/MELBOURNE_2007_PARSIVEL.py +157 -0
  88. disdrodb/l0/readers/PARSIVEL/CHINA/CHONGQING.py +113 -0
  89. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/ARCTIC_2021.py +40 -57
  90. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/COMMON_2011.py +37 -54
  91. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/DAVOS_2009_2011.py +34 -51
  92. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/EPFL_2009.py +34 -51
  93. disdrodb/l0/readers/{EPFL/PARADISO_2014.py → PARSIVEL/EPFL/EPFL_ROOF_2008.py} +38 -50
  94. disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2010.py +105 -0
  95. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/EPFL_ROOF_2011.py +34 -51
  96. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/EPFL_ROOF_2012.py +33 -51
  97. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/GENEPI_2007.py +25 -44
  98. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/GRAND_ST_BERNARD_2007.py +25 -44
  99. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/GRAND_ST_BERNARD_2007_2.py +25 -44
  100. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/HPICONET_2010.py +34 -51
  101. disdrodb/l0/readers/{EPFL/EPFL_ROOF_2010.py → PARSIVEL/EPFL/HYMEX_LTE_SOP2.py} +37 -50
  102. disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP3.py +111 -0
  103. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/HYMEX_LTE_SOP4.py +36 -54
  104. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/LOCARNO_2018.py +34 -52
  105. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/LOCARNO_2019.py +38 -56
  106. disdrodb/l0/readers/PARSIVEL/EPFL/PARADISO_2014.py +105 -0
  107. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/PARSIVEL_2007.py +27 -45
  108. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/PLATO_2019.py +24 -44
  109. disdrodb/l0/readers/PARSIVEL/EPFL/RACLETS_2019.py +140 -0
  110. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/RACLETS_2019_WJF.py +41 -59
  111. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/RIETHOLZBACH_2011.py +34 -51
  112. disdrodb/l0/readers/PARSIVEL/EPFL/SAMOYLOV_2017.py +117 -0
  113. disdrodb/l0/readers/PARSIVEL/EPFL/SAMOYLOV_2019.py +137 -0
  114. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/UNIL_2022.py +42 -55
  115. disdrodb/l0/readers/PARSIVEL/GPM/IFLOODS.py +104 -0
  116. disdrodb/l0/readers/{GPM → PARSIVEL/GPM}/LPVEX.py +29 -48
  117. disdrodb/l0/readers/PARSIVEL/GPM/MC3E.py +184 -0
  118. disdrodb/l0/readers/PARSIVEL/NCAR/CCOPE_2015.py +113 -0
  119. disdrodb/l0/readers/{NCAR/VORTEX_SE_2016_P1.py → PARSIVEL/NCAR/OWLES_MIPS.py} +46 -72
  120. disdrodb/l0/readers/PARSIVEL/NCAR/PECAN_MOBILE.py +125 -0
  121. disdrodb/l0/readers/{NCAR/OWLES_MIPS.py → PARSIVEL/NCAR/PLOWS_MIPS.py} +45 -64
  122. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2009.py +114 -0
  123. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2010.py +176 -0
  124. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2010_UF.py +183 -0
  125. disdrodb/l0/readers/{ARM/ARM_LD.py → PARSIVEL2/ARM/ARM_PARSIVEL2.py} +27 -50
  126. disdrodb/l0/readers/PARSIVEL2/BRAZIL/CHUVA_PARSIVEL2.py +163 -0
  127. disdrodb/l0/readers/PARSIVEL2/BRAZIL/GOAMAZON_PARSIVEL2.py +163 -0
  128. disdrodb/l0/readers/{DENMARK → PARSIVEL2/DENMARK}/EROSION_nc.py +14 -35
  129. disdrodb/l0/readers/PARSIVEL2/FRANCE/SIRTA_PARSIVEL2.py +119 -0
  130. disdrodb/l0/readers/PARSIVEL2/GPM/GCPEX.py +104 -0
  131. disdrodb/l0/readers/PARSIVEL2/GPM/NSSTC.py +176 -0
  132. disdrodb/l0/readers/PARSIVEL2/ITALY/GID_PARSIVEL2.py +32 -0
  133. disdrodb/l0/readers/PARSIVEL2/MEXICO/OH_IIUNAM_nc.py +56 -0
  134. disdrodb/l0/readers/PARSIVEL2/NCAR/PECAN_FP3.py +120 -0
  135. disdrodb/l0/readers/{NCAR → PARSIVEL2/NCAR}/PECAN_MIPS.py +45 -64
  136. disdrodb/l0/readers/PARSIVEL2/NCAR/RELAMPAGO_PARSIVEL2.py +181 -0
  137. disdrodb/l0/readers/PARSIVEL2/NCAR/SNOWIE_PJ.py +160 -0
  138. disdrodb/l0/readers/PARSIVEL2/NCAR/SNOWIE_SB.py +160 -0
  139. disdrodb/l0/readers/{NCAR/PLOWS_MIPS.py → PARSIVEL2/NCAR/VORTEX_SE_2016_P1.py} +49 -66
  140. disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_P2.py +118 -0
  141. disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_PIPS.py +152 -0
  142. disdrodb/l0/readers/PARSIVEL2/NETHERLANDS/DELFT.py +166 -0
  143. disdrodb/l0/readers/{NCAR/RELAMPAGO_RD80.py → RD80/BRAZIL/CHUVA_RD80.py} +36 -60
  144. disdrodb/l0/readers/{BRAZIL → RD80/BRAZIL}/GOAMAZON_RD80.py +36 -55
  145. disdrodb/l0/readers/{NCAR → RD80/NCAR}/CINDY_2011_RD80.py +35 -54
  146. disdrodb/l0/readers/{BRAZIL/CHUVA_RD80.py → RD80/NCAR/RELAMPAGO_RD80.py} +40 -54
  147. disdrodb/l0/readers/template_reader_raw_netcdf_data.py +62 -0
  148. disdrodb/l0/readers/{reader_template.py → template_reader_raw_text_data.py} +20 -44
  149. disdrodb/l0/routines.py +885 -581
  150. disdrodb/l0/standards.py +72 -236
  151. disdrodb/l0/template_tools.py +104 -109
  152. disdrodb/l1/__init__.py +17 -0
  153. disdrodb/l1/beard_model.py +716 -0
  154. disdrodb/l1/encoding_attrs.py +620 -0
  155. disdrodb/l1/fall_velocity.py +260 -0
  156. disdrodb/l1/filters.py +192 -0
  157. disdrodb/l1/processing.py +200 -0
  158. disdrodb/l1/resampling.py +236 -0
  159. disdrodb/l1/routines.py +357 -0
  160. disdrodb/l1_env/__init__.py +17 -0
  161. disdrodb/l1_env/routines.py +38 -0
  162. disdrodb/l2/__init__.py +17 -0
  163. disdrodb/l2/empirical_dsd.py +1735 -0
  164. disdrodb/l2/event.py +388 -0
  165. disdrodb/l2/processing.py +519 -0
  166. disdrodb/l2/processing_options.py +213 -0
  167. disdrodb/l2/routines.py +868 -0
  168. disdrodb/metadata/__init__.py +9 -2
  169. disdrodb/metadata/checks.py +165 -118
  170. disdrodb/metadata/download.py +81 -0
  171. disdrodb/metadata/geolocation.py +146 -0
  172. disdrodb/metadata/info.py +20 -13
  173. disdrodb/metadata/manipulation.py +1 -1
  174. disdrodb/metadata/reader.py +59 -8
  175. disdrodb/metadata/search.py +77 -144
  176. disdrodb/metadata/standards.py +7 -8
  177. disdrodb/metadata/writer.py +8 -14
  178. disdrodb/psd/__init__.py +38 -0
  179. disdrodb/psd/fitting.py +2146 -0
  180. disdrodb/psd/models.py +774 -0
  181. disdrodb/routines.py +1176 -0
  182. disdrodb/scattering/__init__.py +28 -0
  183. disdrodb/scattering/axis_ratio.py +344 -0
  184. disdrodb/scattering/routines.py +456 -0
  185. disdrodb/utils/__init__.py +17 -0
  186. disdrodb/utils/attrs.py +208 -0
  187. disdrodb/utils/cli.py +269 -0
  188. disdrodb/utils/compression.py +60 -42
  189. disdrodb/utils/dask.py +62 -0
  190. disdrodb/utils/decorators.py +110 -0
  191. disdrodb/utils/directories.py +107 -46
  192. disdrodb/utils/encoding.py +127 -0
  193. disdrodb/utils/list.py +29 -0
  194. disdrodb/utils/logger.py +168 -46
  195. disdrodb/utils/time.py +657 -0
  196. disdrodb/utils/warnings.py +30 -0
  197. disdrodb/utils/writer.py +57 -0
  198. disdrodb/utils/xarray.py +138 -47
  199. disdrodb/utils/yaml.py +0 -1
  200. disdrodb/viz/__init__.py +17 -0
  201. disdrodb/viz/plots.py +17 -0
  202. disdrodb-0.1.0.dist-info/METADATA +321 -0
  203. disdrodb-0.1.0.dist-info/RECORD +216 -0
  204. {disdrodb-0.0.21.dist-info → disdrodb-0.1.0.dist-info}/WHEEL +1 -1
  205. disdrodb-0.1.0.dist-info/entry_points.txt +30 -0
  206. disdrodb/data_transfer/scripts/disdrodb_download_archive.py +0 -53
  207. disdrodb/data_transfer/scripts/disdrodb_upload_archive.py +0 -57
  208. disdrodb/l0/configs/OTT_Parsivel/l0a_encodings.yml +0 -32
  209. disdrodb/l0/configs/OTT_Parsivel2/l0a_encodings.yml +0 -39
  210. disdrodb/l0/configs/RD_80/l0a_encodings.yml +0 -16
  211. disdrodb/l0/configs/RD_80/l0b_encodings.yml +0 -135
  212. disdrodb/l0/configs/Thies_LPM/l0a_encodings.yml +0 -80
  213. disdrodb/l0/io.py +0 -257
  214. disdrodb/l0/l0_processing.py +0 -1091
  215. disdrodb/l0/readers/AUSTRALIA/MELBOURNE_2007_OTT.py +0 -178
  216. disdrodb/l0/readers/AUSTRALIA/MELBOURNE_2007_THIES.py +0 -247
  217. disdrodb/l0/readers/BRAZIL/CHUVA_LPM.py +0 -204
  218. disdrodb/l0/readers/BRAZIL/CHUVA_OTT.py +0 -183
  219. disdrodb/l0/readers/BRAZIL/GOAMAZON_LPM.py +0 -204
  220. disdrodb/l0/readers/BRAZIL/GOAMAZON_OTT.py +0 -183
  221. disdrodb/l0/readers/CHINA/CHONGQING.py +0 -131
  222. disdrodb/l0/readers/EPFL/EPFL_ROOF_2008.py +0 -128
  223. disdrodb/l0/readers/EPFL/HYMEX_LTE_SOP2.py +0 -127
  224. disdrodb/l0/readers/EPFL/HYMEX_LTE_SOP3.py +0 -129
  225. disdrodb/l0/readers/EPFL/RACLETS_2019.py +0 -158
  226. disdrodb/l0/readers/EPFL/SAMOYLOV_2017.py +0 -136
  227. disdrodb/l0/readers/EPFL/SAMOYLOV_2019.py +0 -158
  228. disdrodb/l0/readers/FRANCE/SIRTA_OTT2.py +0 -138
  229. disdrodb/l0/readers/GPM/GCPEX.py +0 -123
  230. disdrodb/l0/readers/GPM/IFLOODS.py +0 -123
  231. disdrodb/l0/readers/GPM/MC3E.py +0 -123
  232. disdrodb/l0/readers/GPM/NSSTC.py +0 -164
  233. disdrodb/l0/readers/ITALY/GID.py +0 -199
  234. disdrodb/l0/readers/MEXICO/OH_IIUNAM_nc.py +0 -92
  235. disdrodb/l0/readers/NCAR/CCOPE_2015.py +0 -133
  236. disdrodb/l0/readers/NCAR/PECAN_FP3.py +0 -137
  237. disdrodb/l0/readers/NCAR/PECAN_MOBILE.py +0 -144
  238. disdrodb/l0/readers/NCAR/RELAMPAGO_OTT.py +0 -195
  239. disdrodb/l0/readers/NCAR/SNOWIE_PJ.py +0 -172
  240. disdrodb/l0/readers/NCAR/SNOWIE_SB.py +0 -179
  241. disdrodb/l0/readers/NCAR/VORTEX2_2009.py +0 -133
  242. disdrodb/l0/readers/NCAR/VORTEX2_2010.py +0 -188
  243. disdrodb/l0/readers/NCAR/VORTEX2_2010_UF.py +0 -191
  244. disdrodb/l0/readers/NCAR/VORTEX_SE_2016_P2.py +0 -135
  245. disdrodb/l0/readers/NCAR/VORTEX_SE_2016_PIPS.py +0 -170
  246. disdrodb/l0/readers/NETHERLANDS/DELFT.py +0 -187
  247. disdrodb/l0/readers/SPAIN/SBEGUERIA.py +0 -179
  248. disdrodb/l0/scripts/disdrodb_run_l0b_concat.py +0 -93
  249. disdrodb/l0/scripts/disdrodb_run_l0b_concat_station.py +0 -85
  250. disdrodb/utils/netcdf.py +0 -452
  251. disdrodb/utils/scripts.py +0 -102
  252. disdrodb-0.0.21.dist-info/AUTHORS.md +0 -18
  253. disdrodb-0.0.21.dist-info/METADATA +0 -186
  254. disdrodb-0.0.21.dist-info/RECORD +0 -168
  255. disdrodb-0.0.21.dist-info/entry_points.txt +0 -15
  256. /disdrodb/l0/configs/{RD_80 → RD80}/bins_velocity.yml +0 -0
  257. /disdrodb/l0/manuals/{Thies_LPM.pdf → LPM.pdf} +0 -0
  258. /disdrodb/l0/manuals/{ODM_470.pdf → ODM470.pdf} +0 -0
  259. /disdrodb/l0/manuals/{OTT_Parsivel.pdf → PARSIVEL.pdf} +0 -0
  260. /disdrodb/l0/manuals/{OTT_Parsivel2.pdf → PARSIVEL2.pdf} +0 -0
  261. /disdrodb/l0/manuals/{PWS_100.pdf → PWS100.pdf} +0 -0
  262. /disdrodb/l0/manuals/{RD_80.pdf → RD80.pdf} +0 -0
  263. {disdrodb-0.0.21.dist-info → disdrodb-0.1.0.dist-info/licenses}/LICENSE +0 -0
  264. {disdrodb-0.0.21.dist-info → disdrodb-0.1.0.dist-info}/top_level.txt +0 -0
disdrodb/configs.py CHANGED
@@ -1,11 +1,25 @@
1
1
  #!/usr/bin/env python3
2
- """
3
- Created on Thu Nov 2 15:39:01 2023
4
2
 
5
- @author: ghiggi
6
- """
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
+ """DISDRODB Configuration File functions."""
20
+
7
21
  import os
8
- from typing import Dict
22
+ from typing import Optional
9
23
 
10
24
  from disdrodb.utils.yaml import read_yaml, write_yaml
11
25
 
@@ -18,14 +32,31 @@ def _define_config_filepath():
18
32
  return filepath
19
33
 
20
34
 
21
- def define_disdrodb_configs(base_dir: str = None, zenodo_token: str = None, zenodo_sandbox_token: str = None):
35
+ def define_disdrodb_configs(
36
+ data_archive_dir: Optional[str] = None,
37
+ metadata_archive_dir: Optional[str] = None,
38
+ folder_partitioning: Optional[str] = None,
39
+ zenodo_token: Optional[str] = None,
40
+ zenodo_sandbox_token: Optional[str] = None,
41
+ ):
22
42
  """
23
43
  Defines the DISDRODB configuration file with the given credentials and base directory.
24
44
 
25
45
  Parameters
26
46
  ----------
27
- base_dir : str
28
- The base directory where DISDRODB Metadata Archive is located.
47
+ data_archive_dir : str
48
+ The directory path where the DISDRODB Data Archive is located.
49
+ metadata_archive_dir : str
50
+ The directory path where the DISDRODB Metadata Archive is located.
51
+ folder_partitioning : str
52
+ The folder partitioning scheme used in the DISDRODB Data Archive.
53
+ Allowed values are:
54
+ - "": No additional subdirectories, files are saved directly in <station_dir>.
55
+ - "year": Files are stored under a subdirectory for the year (<station_dir>/2025).
56
+ - "year/month": Files are stored under subdirectories by year and month (<station_dir>/2025/04).
57
+ - "year/month/day": Files are stored under subdirectories by year, month and day (<station_dir>/2025/04/01).
58
+ - "year/month_name": Files are stored under subdirectories by year and month name (<station_dir>/2025/April).
59
+ - "year/quarter": Files are stored under subdirectories by year and quarter (<station_dir>/2025/Q2).
29
60
  zenodo__token: str
30
61
  Zenodo Access Token. It is required to upload stations data to Zenodo.
31
62
  zenodo_sandbox_token: str
@@ -33,11 +64,13 @@ def define_disdrodb_configs(base_dir: str = None, zenodo_token: str = None, zeno
33
64
 
34
65
  Notes
35
66
  -----
36
- This function write or update the DISDRODB config YAML file
37
- The DISDRODB config YAML file is located in the user's home directory at ~/.config_disdrodb.yml
67
+ This function write or update the DISDRODB config YAML file.
68
+ The DISDRODB config YAML file is located in the user's home directory at ``~/.config_disdrodb.yml``.
38
69
  The configuration file is used to run the various DISDRODB operations.
39
70
 
40
71
  """
72
+ from disdrodb.api.checks import check_data_archive_dir, check_folder_partitioning, check_metadata_archive_dir
73
+
41
74
  # Define path to .config_disdrodb.yaml file
42
75
  filepath = _define_config_filepath()
43
76
 
@@ -49,9 +82,15 @@ def define_disdrodb_configs(base_dir: str = None, zenodo_token: str = None, zeno
49
82
  config_dict = {}
50
83
  action_msg = "written"
51
84
 
52
- # Add DISDRODB Base Directory
53
- if base_dir is not None:
54
- config_dict["base_dir"] = base_dir
85
+ # Add DISDRODB Data Archive Directory
86
+ if data_archive_dir is not None:
87
+ config_dict["data_archive_dir"] = check_data_archive_dir(data_archive_dir)
88
+ # Add DISDRODB Metadata Archive Directory
89
+ if metadata_archive_dir is not None:
90
+ config_dict["metadata_archive_dir"] = check_metadata_archive_dir(metadata_archive_dir)
91
+ # Add DISDRODB Folder Partitioning
92
+ if folder_partitioning is not None:
93
+ config_dict["folder_partitioning"] = check_folder_partitioning(folder_partitioning)
55
94
 
56
95
  # Add Zenodo Access Tokens
57
96
  if zenodo_token is not None:
@@ -63,10 +102,9 @@ def define_disdrodb_configs(base_dir: str = None, zenodo_token: str = None, zeno
63
102
  write_yaml(config_dict, filepath, sort_keys=False)
64
103
 
65
104
  print(f"The DISDRODB config file has been {action_msg} successfully!")
66
- return
67
105
 
68
106
 
69
- def read_disdrodb_configs() -> Dict[str, str]:
107
+ def read_disdrodb_configs() -> dict[str, str]:
70
108
  """
71
109
  Reads the DISDRODB configuration file and returns a dictionary with the configuration settings.
72
110
 
@@ -78,12 +116,12 @@ def read_disdrodb_configs() -> Dict[str, str]:
78
116
  Raises
79
117
  ------
80
118
  ValueError
81
- If the configuration file has not been defined yet. Use `disdrodb.define_configs()` to
119
+ If the configuration file has not been defined yet. Use ``disdrodb.define_configs()`` to
82
120
  specify the configuration file path and settings.
83
121
 
84
122
  Notes
85
123
  -----
86
- This function reads the YAML configuration file located at ~/.config_disdrodb.yml.
124
+ This function reads the YAML configuration file located at ``~/.config_disdrodb.yml``.
87
125
  """
88
126
  # Define path where .config_disdrodb.yaml file should be located
89
127
  filepath = _define_config_filepath()
@@ -94,20 +132,47 @@ def read_disdrodb_configs() -> Dict[str, str]:
94
132
  return config_dict
95
133
 
96
134
 
97
- def get_base_dir(base_dir=None):
135
+ def get_data_archive_dir(data_archive_dir=None):
98
136
  """Return the DISDRODB base directory."""
99
137
  import disdrodb
138
+ from disdrodb.api.checks import check_data_archive_dir
139
+
140
+ if data_archive_dir is None:
141
+ data_archive_dir = disdrodb.config.get("data_archive_dir", None)
142
+ if data_archive_dir is None:
143
+ raise ValueError("The DISDRODB Data Archive Directory is not specified.")
144
+ data_archive_dir = check_data_archive_dir(data_archive_dir) # ensure Path converted to str
145
+ return data_archive_dir
146
+
147
+
148
+ def get_metadata_archive_dir(metadata_archive_dir=None):
149
+ """Return the DISDRODB Metadata Archive Directory."""
150
+ import disdrodb
151
+ from disdrodb.api.checks import check_metadata_archive_dir
152
+
153
+ if metadata_archive_dir is None:
154
+ metadata_archive_dir = disdrodb.config.get("metadata_archive_dir", None)
155
+ if metadata_archive_dir is None:
156
+ raise ValueError("The DISDRODB Metadata Archive Directory is not specified.")
157
+ metadata_archive_dir = check_metadata_archive_dir(metadata_archive_dir) # ensure Path converted to str
158
+ return metadata_archive_dir
159
+
160
+
161
+ def get_folder_partitioning():
162
+ """Return the folder partitioning."""
163
+ import disdrodb
164
+ from disdrodb.api.checks import check_folder_partitioning
100
165
 
101
- if base_dir is None:
102
- base_dir = disdrodb.config.get("base_dir", None)
103
- if base_dir is None:
104
- raise ValueError("The DISDRODB Base Directory is not specified.")
105
- base_dir = str(base_dir) # convert Path to str
106
- return base_dir
166
+ # Get the folder partitioning
167
+ folder_partitioning = disdrodb.config.get("folder_partitioning", None)
168
+ if folder_partitioning is None:
169
+ raise ValueError("The folder partitioning is not specified.")
170
+ check_folder_partitioning(folder_partitioning)
171
+ return folder_partitioning
107
172
 
108
173
 
109
174
  def get_zenodo_token(sandbox: bool):
110
- """Return the Zenodo Access Token."""
175
+ """Return the Zenodo access token."""
111
176
  import disdrodb
112
177
 
113
178
  if sandbox:
@@ -0,0 +1,22 @@
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
+ """Routines to download and upload data to the DISDRODB Decentralized Data Archive."""
20
+
21
+ from disdrodb.data_transfer.upload_data import upload_station, upload_archive # noqa
22
+ from disdrodb.data_transfer.download_data import download_station, download_archive # noqa
@@ -18,16 +18,17 @@
18
18
  # -----------------------------------------------------------------------------.
19
19
  """Routines to download data from the DISDRODB Decentralized Data Archive."""
20
20
 
21
+ import logging
21
22
  import os
22
23
  import shutil
23
- from typing import List, Optional, Union
24
+ from typing import Optional, Union
24
25
 
25
26
  import click
26
27
  import pooch
27
28
  import tqdm
28
29
 
29
- from disdrodb.api.path import define_metadata_filepath
30
- from disdrodb.configs import get_base_dir
30
+ from disdrodb.api.path import define_metadata_filepath, define_station_dir
31
+ from disdrodb.configs import get_data_archive_dir, get_metadata_archive_dir
31
32
  from disdrodb.metadata import get_list_metadata
32
33
  from disdrodb.utils.compression import unzip_file
33
34
  from disdrodb.utils.directories import is_empty_directory
@@ -83,7 +84,6 @@ def click_download_options(function: object):
83
84
  function : object
84
85
  Function.
85
86
  """
86
-
87
87
  function = click.option(
88
88
  "-f",
89
89
  "--force",
@@ -97,51 +97,56 @@ def click_download_options(function: object):
97
97
 
98
98
 
99
99
  def download_archive(
100
- data_sources: Optional[Union[str, List[str]]] = None,
101
- campaign_names: Optional[Union[str, List[str]]] = None,
102
- station_names: Optional[Union[str, List[str]]] = None,
100
+ data_sources: Optional[Union[str, list[str]]] = None,
101
+ campaign_names: Optional[Union[str, list[str]]] = None,
102
+ station_names: Optional[Union[str, list[str]]] = None,
103
103
  force: bool = False,
104
- base_dir: Optional[str] = None,
104
+ data_archive_dir: Optional[str] = None,
105
+ metadata_archive_dir: Optional[str] = None,
105
106
  ):
106
- """Get all YAML files that contain the 'disdrodb_data_url' key
107
- and download the data locally.
107
+ """Download DISDRODB stations with the ``disdrodb_data_url`` in the metadata.
108
108
 
109
109
  Parameters
110
110
  ----------
111
111
  data_sources : str or list of str, optional
112
112
  Data source name (eg : EPFL).
113
- If not provided (None), all data sources will be downloaded.
114
- The default is data_source=None.
113
+ If not provided (``None``), all data sources will be downloaded.
114
+ The default value is ``data_source=None``.
115
115
  campaign_names : str or list of str, optional
116
116
  Campaign name (eg : EPFL_ROOF_2012).
117
- If not provided (None), all campaigns will be downloaded.
118
- The default is campaign_name=None.
117
+ If not provided (``None``), all campaigns will be downloaded.
118
+ The default value is ``campaign_name=None``.
119
119
  station_names : str or list of str, optional
120
120
  Station name.
121
- If not provided (None), all stations will be downloaded.
122
- The default is station_name=None.
121
+ If not provided (``None``), all stations will be downloaded.
122
+ The default value is ``station_name=None``.
123
123
  force : bool, optional
124
- If True, overwrite the already existing raw data file.
125
- The default is False.
126
- base_dir : str (optional)
127
- Base directory of DISDRODB. Format: <...>/DISDRODB
128
- If None (the default), the disdrodb config variable 'dir' is used.
124
+ If ``True``, overwrite the already existing raw data file.
125
+ The default value is ``False``.
126
+ data_archive_dir : str (optional)
127
+ DISDRODB Data Archive directory. Format: ``<...>/DISDRODB``.
128
+ If ``None`` (the default), the disdrodb config variable ``data_archive_dir`` is used.
129
129
  """
130
- # Retrieve the requested metadata
131
- base_dir = get_base_dir(base_dir)
130
+ # Retrieve the DISDRODB Metadata and Data Archive Directories
131
+ data_archive_dir = get_data_archive_dir(data_archive_dir)
132
+ metadata_archive_dir = get_metadata_archive_dir(metadata_archive_dir)
133
+
134
+ # Select only metadata_filepaths with specified disdrodb_data_url
132
135
  metadata_filepaths = get_list_metadata(
133
- base_dir=base_dir,
136
+ metadata_archive_dir=metadata_archive_dir,
134
137
  data_sources=data_sources,
135
138
  campaign_names=campaign_names,
136
139
  station_names=station_names,
137
- with_stations_data=False,
140
+ product=None, # --> Search in DISDRODB Metadata Archive
141
+ available_data=True, # --> Select only metadata with disdrodb_data_url
142
+ raise_error_if_empty=False, # Do not raise error if no matching metadata file found
143
+ invalid_fields_policy="raise", # Raise error if invalid filtering criteria are specified
138
144
  )
139
145
 
140
- # Select only metadata_filepaths with disdrodb_data_url
141
- metadata_filepaths = _select_metadata_with_remote_data_url(metadata_filepaths)
146
+ # Return early if no data to download
142
147
  if len(metadata_filepaths) == 0:
143
- print("No available remote data to download.")
144
- return None
148
+ print("No available data to download from the online DISDRODB Decentralized Archive.")
149
+ return
145
150
 
146
151
  # Try to download the data
147
152
  # - It will download data only if the disdrodb_data_url is specified !
@@ -155,11 +160,12 @@ def download_archive(
155
160
  data_source=data_source,
156
161
  campaign_name=campaign_name,
157
162
  station_name=station_name,
158
- base_dir=base_dir,
163
+ data_archive_dir=data_archive_dir,
164
+ metadata_archive_dir=metadata_archive_dir,
159
165
  force=force,
160
166
  )
161
- except Exception as e:
162
- print(f" - Download error: {e}")
167
+ except Exception:
168
+ print(" - Download error: {e}")
163
169
  print(" ")
164
170
 
165
171
 
@@ -168,7 +174,8 @@ def download_station(
168
174
  campaign_name: str,
169
175
  station_name: str,
170
176
  force: bool = False,
171
- base_dir: Optional[str] = None,
177
+ data_archive_dir: Optional[str] = None,
178
+ metadata_archive_dir: Optional[str] = None,
172
179
  ) -> None:
173
180
  """
174
181
  Download data of a single DISDRODB station from the DISDRODB remote repository.
@@ -183,48 +190,35 @@ def download_station(
183
190
  The name of the campaign. Must be provided in UPPER CASE.
184
191
  station_name : str
185
192
  The name of the station.
186
- base_dir : str, optional
193
+ data_archive_dir : str, optional
187
194
  The base directory of DISDRODB, expected in the format ``<...>/DISDRODB``.
188
195
  If not specified, the path specified in the DISDRODB active configuration will be used.
189
196
  force: bool, optional
190
- If True, overwrite the already existing raw data file.
191
- The default is False.
192
- base_dir : str (optional)
193
- Base directory of DISDRODB. Format: <...>/DISDRODB
194
- If None (the default), the disdrodb config variable 'dir' is used.
197
+ If ``True``, overwrite the already existing raw data file.
198
+ The default value is ``False``.
199
+ data_archive_dir : str (optional)
200
+ DISDRODB Data Archive directory. Format: ``<...>/DISDRODB``.
201
+ If ``None`` (the default), the disdrodb config variable ``data_archive_dir`` is used.
195
202
  """
196
203
  print(f"Start download of {data_source} {campaign_name} {station_name} station data")
204
+ # Retrieve the DISDRODB Metadata and Data Archive Directories
205
+ data_archive_dir = get_data_archive_dir(data_archive_dir)
206
+ metadata_archive_dir = get_metadata_archive_dir(metadata_archive_dir)
197
207
  # Define metadata_filepath
198
208
  metadata_filepath = define_metadata_filepath(
209
+ metadata_archive_dir=metadata_archive_dir,
199
210
  data_source=data_source,
200
211
  campaign_name=campaign_name,
201
212
  station_name=station_name,
202
- base_dir=base_dir,
203
- product="RAW",
204
213
  check_exists=True,
205
214
  )
206
215
  # Download data
207
- _download_station_data(metadata_filepath, force=force)
216
+ _download_station_data(metadata_filepath, data_archive_dir=data_archive_dir, force=force)
208
217
 
209
218
 
210
219
  def _is_valid_disdrodb_data_url(disdrodb_data_url):
211
220
  """Check if it is a valid disdrodb_data_url."""
212
- if isinstance(disdrodb_data_url, str) and len(disdrodb_data_url) > 10:
213
- return True
214
- else:
215
- return False
216
-
217
-
218
- def _has_disdrodb_data_url(metadata_filepath):
219
- """Check the metadata has a valid disdrodb_data_url."""
220
- metadata_dict = read_yaml(metadata_filepath)
221
- disdrodb_data_url = metadata_dict.get("disdrodb_data_url", "")
222
- return _is_valid_disdrodb_data_url(disdrodb_data_url)
223
-
224
-
225
- def _select_metadata_with_remote_data_url(metadata_filepaths: List[str]) -> List[str]:
226
- """Select metadata files that have a remote data url specified."""
227
- return [fpath for fpath in metadata_filepaths if _has_disdrodb_data_url(fpath)]
221
+ return isinstance(disdrodb_data_url, str) and len(disdrodb_data_url) > 10
228
222
 
229
223
 
230
224
  def _extract_station_files(zip_filepath, station_dir):
@@ -234,7 +228,7 @@ def _extract_station_files(zip_filepath, station_dir):
234
228
  os.remove(zip_filepath)
235
229
 
236
230
 
237
- def _download_station_data(metadata_filepath: str, force: bool = False) -> None:
231
+ def _download_station_data(metadata_filepath: str, data_archive_dir: str, force: bool = False) -> None:
238
232
  """Download and unzip the station data .
239
233
 
240
234
  Parameters
@@ -242,50 +236,44 @@ def _download_station_data(metadata_filepath: str, force: bool = False) -> None:
242
236
  metadata_filepaths : str
243
237
  Metadata file path.
244
238
  force : bool, optional
245
- force download, by default False
239
+ If ``True``, delete existing files and redownload it. The default value is ``False``.
246
240
 
247
241
  """
248
- disdrodb_data_url, station_dir = _get_station_url_and_dir_path(metadata_filepath)
242
+ # Open metadata file
243
+ metadata_dict = read_yaml(metadata_filepath)
244
+ # Retrieve station information
245
+ data_archive_dir = get_data_archive_dir(data_archive_dir)
246
+ data_source = metadata_dict["data_source"]
247
+ campaign_name = metadata_dict["campaign_name"]
248
+ station_name = metadata_dict["station_name"]
249
+ station_name = check_consistent_station_name(metadata_filepath, station_name)
250
+ # Define the destination local filepath path
251
+ station_dir = define_station_dir(
252
+ data_archive_dir=data_archive_dir,
253
+ data_source=data_source,
254
+ campaign_name=campaign_name,
255
+ station_name=station_name,
256
+ product="RAW",
257
+ )
258
+ # Check DISDRODB data url
259
+ disdrodb_data_url = metadata_dict.get("disdrodb_data_url", None)
260
+ if not _is_valid_disdrodb_data_url(disdrodb_data_url):
261
+ raise ValueError(f"Invalid disdrodb_data_url '{disdrodb_data_url}' for station {station_name}")
249
262
  # Download file
250
263
  zip_filepath = _download_file_from_url(disdrodb_data_url, dst_dir=station_dir, force=force)
251
264
  # Extract the stations files from the downloaded station.zip file
252
265
  _extract_station_files(zip_filepath, station_dir=station_dir)
253
266
 
254
267
 
255
- def _get_valid_station_name(metadata_filepath, metadata_dict):
268
+ def check_consistent_station_name(metadata_filepath, station_name):
256
269
  """Check consistent station_name between YAML file name and metadata key."""
257
270
  # Check consistent station name
258
271
  expected_station_name = os.path.basename(metadata_filepath).replace(".yml", "")
259
- station_name = metadata_dict.get("station_name")
260
272
  if station_name and str(station_name) != str(expected_station_name):
261
273
  raise ValueError(f"Inconsistent station_name values in the {metadata_filepath} file. Download aborted.")
262
274
  return station_name
263
275
 
264
276
 
265
- def _get_station_url_and_dir_path(metadata_filepath: str) -> tuple:
266
- """Return the station's remote url and the local destination directory path.
267
-
268
- Parameters
269
- ----------
270
- metadata_filepath : str
271
- Path to the metadata YAML file.
272
-
273
- Returns
274
- -------
275
- disdrodb_data_url, station_dir
276
- Tuple containing the remote url and the DISDRODB station directory path.
277
- """
278
- metadata_dict = read_yaml(metadata_filepath)
279
- station_name = _get_valid_station_name(metadata_filepath, metadata_dict)
280
- disdrodb_data_url = metadata_dict.get("disdrodb_data_url", None)
281
- if not _is_valid_disdrodb_data_url(disdrodb_data_url):
282
- raise ValueError(f"Invalid disdrodb_data_url '{disdrodb_data_url}' for station {station_name}")
283
- # Define the destination local filepath path
284
- data_dir = os.path.dirname(metadata_filepath).replace("metadata", "data")
285
- station_dir = os.path.join(data_dir, station_name)
286
- return disdrodb_data_url, station_dir
287
-
288
-
289
277
  def _download_file_from_url(url: str, dst_dir: str, force: bool = False) -> str:
290
278
  """Download station zip file into the DISDRODB station data directory.
291
279
 
@@ -296,7 +284,7 @@ def _download_file_from_url(url: str, dst_dir: str, force: bool = False) -> str:
296
284
  dst_dir : str
297
285
  Local directory where to download the file (DISDRODB station data directory).
298
286
  force : bool, optional
299
- Overwrite the raw data file if already existing, by default False.
287
+ Overwrite the raw data file if already existing. The default value is ``False``.
300
288
 
301
289
  Returns
302
290
  -------
@@ -314,12 +302,21 @@ def _download_file_from_url(url: str, dst_dir: str, force: bool = False) -> str:
314
302
  os.makedirs(dst_dir) # station directory
315
303
  else:
316
304
  raise ValueError(
317
- f"There are already raw files within {dst_dir}. Download is suspended. "
318
- "Use force=True to force the download and overwrite existing raw files."
305
+ f"There are already raw files within the DISDRODB Data Archive at {dst_dir}. Download is suspended. "
306
+ "Use force=True to force the download and overwrite existing raw files.",
319
307
  )
320
308
 
321
309
  os.makedirs(dst_dir, exist_ok=True)
322
310
 
311
+ # Grab Pooch's logger and remember its current level
312
+ logger = pooch.get_logger()
313
+ orig_level = logger.level
314
+ # Silence INFO messages (including the SHA256 print)
315
+ logger.setLevel(logging.WARNING)
316
+ # Define pooch downloader
323
317
  downloader = pooch.HTTPDownloader(progressbar=True)
318
+ # Download the file
324
319
  pooch.retrieve(url=url, known_hash=None, path=dst_dir, fname=dst_filename, downloader=downloader, progressbar=tqdm)
320
+ # Restore the previous logging level
321
+ logger.setLevel(orig_level)
325
322
  return dst_filepath