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
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env python3
2
+
3
+ # -----------------------------------------------------------------------------.
4
+ # Copyright (c) 2021-2023 DISDRODB developers
5
+ #
6
+ # This program is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
+ # -----------------------------------------------------------------------------.
19
+ """Routine to download the DISDRODB Metadata Archive from GitHub."""
20
+ import io
21
+ import os
22
+ import shutil
23
+ import urllib.request
24
+ import zipfile
25
+
26
+
27
+ def download_metadata_archive(directory_path, force=False):
28
+ """Download the DISDRODB Metadata Archive to the specified directory.
29
+
30
+ Parameters
31
+ ----------
32
+ directory_path : str
33
+ The directory path where the DISDRODB-METADATA directory will be downloaded.
34
+ force : bool, optional
35
+ If ``True``, the existing DISDRODB-METADATA directory will be removed
36
+ and a new one will be downloaded. The default value is ``False``.
37
+
38
+ Returns
39
+ -------
40
+ metadata_archive_dir
41
+ The DISDRODB Metadata Archive directory path.
42
+ """
43
+ # Define DISDRODB Metadata Archive GitHub URL
44
+ archive_zip_url = "https://github.com/ltelab/DISDRODB-METADATA/archive/refs/heads/main.zip"
45
+
46
+ # Download archive to disk
47
+ resp = urllib.request.urlopen(archive_zip_url)
48
+ archive_data = resp.read()
49
+
50
+ # Unpack archive
51
+ with zipfile.ZipFile(io.BytesIO(archive_data)) as zf:
52
+ zf.extractall(directory_path)
53
+
54
+ # Check the archive has been download
55
+ extracted_dir = os.path.join(directory_path, "DISDRODB-METADATA-main")
56
+ if not os.path.isdir(extracted_dir):
57
+ raise ValueError(
58
+ "The DISDRODB Metadata Archive hosted on GitHub could not be downloaded!",
59
+ )
60
+
61
+ # Define target directory for the metadata archive
62
+ target_dir = os.path.join(directory_path, "DISDRODB-METADATA")
63
+
64
+ # Handle existing target directory
65
+ if os.path.exists(target_dir):
66
+ if force:
67
+ shutil.rmtree(target_dir)
68
+ else:
69
+ raise FileExistsError(
70
+ f"A DISDRODB Metadata Archive already exists at '{target_dir}'. Use force=True to update it.",
71
+ )
72
+
73
+ # Rename extracted directory to target
74
+ shutil.move(extracted_dir, target_dir)
75
+
76
+ # Define metadata archive directory
77
+ metadata_archive_dir = os.path.join(target_dir, "DISDRODB")
78
+
79
+ print("The DISDRODB Metadata Archive has been download successfully.")
80
+ print(f"The DISDRODB Metadata Archive directory path is {metadata_archive_dir}")
81
+ return metadata_archive_dir
@@ -0,0 +1,146 @@
1
+ #!/usr/bin/env python3
2
+
3
+ # -----------------------------------------------------------------------------.
4
+ # Copyright (c) 2021-2023 DISDRODB developers
5
+ #
6
+ # This program is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
+ # -----------------------------------------------------------------------------.
19
+ """Metadata tools to verify/complete geolocation information."""
20
+ import time
21
+
22
+ import numpy as np
23
+ import requests
24
+
25
+
26
+ def infer_altitude(latitude, longitude, dem="aster30m"):
27
+ """Infer station altitude using a Digital Elevation Model (DEM).
28
+
29
+ This function uses the OpenTopoData API to infer the altitude of a given
30
+ location specified by latitude and longitude.
31
+ By default, it uses the ASTER DEM at 30m resolution.
32
+
33
+ Parameters
34
+ ----------
35
+ latitude : float
36
+ The latitude of the location for which to infer the altitude.
37
+ longitude : float
38
+ The longitude of the location for which to infer the altitude.
39
+ dem : str, optional
40
+ The DEM to use for altitude inference. Options are "aster30m" (default),
41
+ "srtm30", and "mapzen".
42
+
43
+ Returns
44
+ -------
45
+ elevation : float
46
+ The inferred altitude of the specified location.
47
+
48
+ Raises
49
+ ------
50
+ ValueError
51
+ If the altitude retrieval fails.
52
+
53
+ Notes
54
+ -----
55
+ - The OpenTopoData API has a limit of 1000 calls per day.
56
+ - Each request can include up to 100 locations.
57
+ - The API allows a maximum of 1 call per second.
58
+
59
+ References
60
+ ----------
61
+ https://www.opentopodata.org/api/
62
+ """
63
+ import requests
64
+
65
+ url = f"https://api.opentopodata.org/v1/{dem}?locations={latitude},{longitude}"
66
+ r = requests.get(url)
67
+
68
+ data = r.json()
69
+ if data["status"] == "OK":
70
+ elevation = data["results"][0]["elevation"]
71
+ else:
72
+ raise ValueError("Altitude retrieval failed.")
73
+ return elevation
74
+
75
+
76
+ def infer_altitudes(lats, lons, dem="aster30m"):
77
+ """
78
+ Infer altitude of a given location using OpenTopoData API.
79
+
80
+ Parameters
81
+ ----------
82
+ lats : list or array-like
83
+ List or array of latitude coordinates.
84
+ lons : list or array-like
85
+ List or array of longitude coordinates.
86
+ dem : str, optional
87
+ Digital Elevation Model (DEM) to use for altitude inference.
88
+ The default DEM is "aster30m".
89
+
90
+ Returns
91
+ -------
92
+ elevations : numpy.ndarray
93
+ Array of inferred altitudes corresponding to the input coordinates.
94
+
95
+ Raises
96
+ ------
97
+ ValueError
98
+ If the latitude and longitude arrays do not have the same length.
99
+ If altitude retrieval fails for any block of coordinates.
100
+
101
+ Notes
102
+ -----
103
+ - The OpenTopoData API has a limit of 1000 calls per day.
104
+ - Each request can include up to 100 locations.
105
+ - The API allows a maximum of 1 call per second.
106
+ - The API requests are made in blocks of up to 100 coordinates,
107
+ with a 2-second delay between requests.
108
+ """
109
+ # Check that lats and lons have the same length
110
+ if len(lats) != len(lons):
111
+ raise ValueError("Latitude and longitude arrays must have the same length.")
112
+
113
+ # Maximum number of locations per API request
114
+ max_locations = 100
115
+ elevations = []
116
+
117
+ # Total number of coordinates
118
+ total_coords = len(lats)
119
+
120
+ # Loop over the coordinates in blocks of max_locations
121
+ for i in range(0, total_coords, max_locations):
122
+
123
+ # Wait 2 seconds before another API request
124
+ time.sleep(2)
125
+
126
+ # Get the block of coordinates
127
+ block_lats = lats[i : i + max_locations]
128
+ block_lons = lons[i : i + max_locations]
129
+
130
+ # Create the list_coords string in the format "lat1,lon1|lat2,lon2|..."
131
+ list_coords = "|".join([f"{lat},{lon}" for lat, lon in zip(block_lats, block_lons)])
132
+
133
+ # Define API URL
134
+ url = f"https://api.opentopodata.org/v1/{dem}?locations={list_coords}&interpolation=nearest"
135
+
136
+ # Retrieve info
137
+ r = requests.get(url)
138
+ data = r.json()
139
+
140
+ # Parse info
141
+ if data.get("status") == "OK":
142
+ elevations.extend([result["elevation"] for result in data["results"]])
143
+ else:
144
+ raise ValueError(f"Altitude retrieval failed for block starting at index {i}.")
145
+ elevations = np.array(elevations).astype(float)
146
+ return elevations
disdrodb/metadata/info.py CHANGED
@@ -18,41 +18,49 @@
18
18
  # -----------------------------------------------------------------------------.
19
19
  """Test Metadata Info Extraction."""
20
20
  import os
21
+ from typing import Optional
21
22
 
22
23
  from disdrodb.api.info import (
23
24
  infer_campaign_name_from_path,
24
25
  infer_data_source_from_path,
25
26
  )
26
- from disdrodb.configs import get_base_dir
27
+ from disdrodb.configs import get_metadata_archive_dir
27
28
  from disdrodb.metadata.reader import read_station_metadata
28
29
  from disdrodb.metadata.search import get_list_metadata
29
30
 
30
31
 
31
- def get_archive_metadata_key_value(key: str, return_tuple: bool = True, base_dir: str = None):
32
+ def get_archive_metadata_key_value(key: str, return_tuple: bool = True, metadata_archive_dir: Optional[str] = None):
32
33
  """Return the values of a metadata key for all the archive.
33
34
 
34
35
  Parameters
35
36
  ----------
36
- base_dir : str
37
+ data_archive_dir : str
37
38
  Path to the disdrodb directory.
38
39
  key : str
39
40
  Metadata key.
40
41
  return_tuple : bool, optional
41
- If True, returns a tuple of values with station, campaign and data source name.
42
- If False, returns a list of values without station, campaign and data source name.
43
- The default is True.
44
- base_dir : str (optional)
45
- Base directory of DISDRODB. Format: <...>/DISDRODB
46
- If None (the default), the disdrodb config variable 'dir' is used.
42
+ If ``True``, returns a tuple (``data_source``,``campaign_name``,``station_name``, ``key_value``)
43
+ If ``False``, returns a list of the key values.
44
+ The default value is ``True``.
45
+ metadata_archive_dir : str (optional)
46
+ The directory path where the DISDRODB Metadata Archive is located.
47
+ The directory path must end with ``<...>/DISDRODB``.
48
+ If ``None``, it uses the ``metadata_archive_dir`` path specified
49
+ in the DISDRODB active configuration.
47
50
 
48
51
  Returns
49
52
  -------
50
53
  list or tuple
51
54
  List or tuple of values of the metadata key.
52
55
  """
53
- base_dir = get_base_dir(base_dir)
56
+ metadata_archive_dir = get_metadata_archive_dir(metadata_archive_dir)
54
57
  list_metadata_paths = get_list_metadata(
55
- base_dir=base_dir, data_sources=None, campaign_names=None, station_names=None, with_stations_data=False
58
+ metadata_archive_dir=metadata_archive_dir,
59
+ data_sources=None,
60
+ campaign_names=None,
61
+ station_names=None,
62
+ product=None, # --> Search in DISDRODB Metadata Archive
63
+ available_data=False, # --> Select all metadata matching the filtering criteria
56
64
  )
57
65
  list_info = []
58
66
  for filepath in list_metadata_paths:
@@ -60,8 +68,7 @@ def get_archive_metadata_key_value(key: str, return_tuple: bool = True, base_dir
60
68
  campaign_name = infer_campaign_name_from_path(filepath)
61
69
  station_name = os.path.basename(filepath).replace(".yml", "")
62
70
  metadata = read_station_metadata(
63
- base_dir=base_dir,
64
- product="RAW",
71
+ metadata_archive_dir=metadata_archive_dir,
65
72
  data_source=data_source,
66
73
  campaign_name=campaign_name,
67
74
  station_name=station_name,
@@ -40,7 +40,7 @@ def add_missing_metadata_keys(metadata):
40
40
 
41
41
 
42
42
  def sort_metadata_dictionary(metadata):
43
- """Sort the keys of the metadata dictionary by valid_metadata_keys list order."""
43
+ """Sort the keys of the metadata dictionary by ``valid_metadata_keys`` list order."""
44
44
  from disdrodb.metadata.standards import get_valid_metadata_keys
45
45
 
46
46
  list_metadata_keys = get_valid_metadata_keys()
@@ -18,12 +18,13 @@
18
18
  # -----------------------------------------------------------------------------.
19
19
  """Routines to read the DISDRODB Metadata."""
20
20
 
21
+ import pandas as pd
21
22
 
22
23
  from disdrodb.api.path import define_metadata_filepath
23
24
  from disdrodb.utils.yaml import read_yaml
24
25
 
25
26
 
26
- def read_station_metadata(data_source, campaign_name, station_name, base_dir=None, product="RAW"):
27
+ def read_station_metadata(data_source, campaign_name, station_name, metadata_archive_dir=None):
27
28
  """Open the station metadata YAML file into a dictionary.
28
29
 
29
30
  Parameters
@@ -36,12 +37,10 @@ def read_station_metadata(data_source, campaign_name, station_name, base_dir=Non
36
37
  The name of the campaign. Must be provided in UPPER CASE.
37
38
  station_name : str
38
39
  The name of the station.
39
- base_dir : str, optional
40
- The base directory of DISDRODB, expected in the format ``<...>/DISDRODB``.
40
+ metadata_archive_dir : str, optional
41
+ The directory path where the DISDRODB Metadata Archive is located.
41
42
  If not specified, the path specified in the DISDRODB active configuration will be used.
42
- product : str, optional
43
- The DISDRODB product in which to search for the metadata file.
44
- The default is "RAW".
43
+ Expected path format: ``<...>/DISDRODB``.
45
44
 
46
45
  Returns
47
46
  -------
@@ -51,12 +50,64 @@ def read_station_metadata(data_source, campaign_name, station_name, base_dir=Non
51
50
  """
52
51
  # Retrieve metadata filepath
53
52
  metadata_filepath = define_metadata_filepath(
54
- base_dir=base_dir,
53
+ metadata_archive_dir=metadata_archive_dir,
55
54
  data_source=data_source,
56
55
  campaign_name=campaign_name,
57
56
  station_name=station_name,
58
- product=product,
59
57
  check_exists=True,
60
58
  )
59
+ # Open the metadata file
61
60
  metadata_dict = read_yaml(metadata_filepath)
62
61
  return metadata_dict
62
+
63
+
64
+ def read_metadata_archive(
65
+ metadata_archive_dir=None,
66
+ data_sources=None,
67
+ campaign_names=None,
68
+ station_names=None,
69
+ available_data=False,
70
+ ):
71
+ """Read the DISDRODB Metadata Archive Database.
72
+
73
+ Parameters
74
+ ----------
75
+ metadata_archive_dir : str or Path-like, optional
76
+ Path to the root of the DISDRODB Metadata Archive. If None, the
77
+ default metadata base directory is used. Default is None.
78
+ data_sources : str or sequence of str, optional
79
+ One or more data source identifiers to filter stations by. If None,
80
+ no filtering on data source is applied. The default is is None.
81
+ campaign_names : str or sequence of str, optional
82
+ One or more campaign names to filter stations by. If None, no filtering
83
+ on campaign is applied. The default is is None.
84
+ station_names : str or sequence of str, optional
85
+ One or more station names to include. If None, all stations matching
86
+ other filters are considered. The default is is None.
87
+ available_data: bool, optional
88
+ If True, only information of stations with data available in the online
89
+ DISDRODB Decentralized Data Archive are returned.
90
+ If False (the default), all stations present in the DISDRODB Metadata Archive
91
+ matching the filtering criteria are returned,
92
+
93
+ Returns
94
+ -------
95
+ pandas.DataFrame
96
+
97
+ """
98
+ from disdrodb.configs import get_metadata_archive_dir
99
+ from disdrodb.metadata.search import get_list_metadata
100
+
101
+ metadata_archive_dir = get_metadata_archive_dir(metadata_archive_dir=metadata_archive_dir)
102
+
103
+ list_metadata_paths = get_list_metadata(
104
+ metadata_archive_dir=metadata_archive_dir,
105
+ data_sources=data_sources,
106
+ campaign_names=campaign_names,
107
+ station_names=station_names,
108
+ product=None, # --> Search in DISDRODB Metadata Archive
109
+ available_data=available_data,
110
+ )
111
+ list_metadata = [read_yaml(fpath) for fpath in list_metadata_paths]
112
+ df = pd.DataFrame(list_metadata)
113
+ return df
@@ -18,150 +18,94 @@
18
18
  # -----------------------------------------------------------------------------.
19
19
  """Routines to manipulate the DISDRODB Metadata Archive."""
20
20
 
21
- import glob
22
- import os
23
21
 
24
22
  from disdrodb.api.path import define_metadata_filepath
25
- from disdrodb.configs import get_base_dir
23
+ from disdrodb.api.search import available_stations
26
24
 
27
25
 
28
26
  def get_list_metadata(
29
27
  data_sources=None,
30
28
  campaign_names=None,
31
29
  station_names=None,
32
- with_stations_data=True,
33
- base_dir=None,
30
+ product=None,
31
+ available_data=False,
32
+ raise_error_if_empty=False,
33
+ invalid_fields_policy="raise",
34
+ data_archive_dir=None,
35
+ metadata_archive_dir=None,
36
+ **product_kwargs,
34
37
  ):
35
38
  """
36
- Get the list of metadata filepaths in the DISDRODB raw archive.
39
+ Get station metadata filepaths.
40
+
41
+ By default, it returns the metadata file paths of stations present in the DISDRODB Metadata Archive matching
42
+ the filtering criteria.
43
+
44
+ If the DISDRODB product is specified, it lists only metadata file paths of stations with the specified product
45
+ present in the local DISDRODB Data Archive.
37
46
 
38
47
  Parameters
39
48
  ----------
40
- data_sources : str or list of str
41
- Name of data source(s) of interest.
42
- The name(s) must be UPPER CASE.
43
- The default is None
44
- campaign_names : str or list of str
45
- Name of the campaign(s) of interest.
46
- The name(s) must be UPPER CASE.
47
- The default is None
48
- station_names : str or list of str
49
- Station names of interest.
50
- The default is None
51
- with_stations_data : bool
52
- If True, only return metadata filepaths that have corresponding data in the local DISDRODB raw archive.
53
- The default is True
54
- base_dir : str (optional)
55
- Base directory of DISDRODB. Format: <...>/DISDRODB
56
- If None (the default), the disdrodb config variable 'dir' is used.
49
+ product : str or None, optional
50
+ Name of the product to filter on (e.g., "RAW", "L0A", "L1").
57
51
 
58
- Returns
59
- -------
60
- metadata_filepaths: list
61
- List of metadata YAML file paths
52
+ If the DISDRODB product is not specified (default),
53
+ it returns the metadata file paths of stations present in the DISDRODB Metadata Archive matching
54
+ the filtering criteria.
62
55
 
63
- """
64
- base_dir = get_base_dir(base_dir)
65
- if with_stations_data:
66
- list_metadata = _get_list_metadata_with_data(
67
- base_dir=base_dir,
68
- data_sources=data_sources,
69
- campaign_names=campaign_names,
70
- station_names=station_names,
71
- )
72
- else:
73
- list_metadata = _get_list_all_metadata(
74
- base_dir=base_dir,
75
- data_sources=data_sources,
76
- campaign_names=campaign_names,
77
- station_names=station_names,
78
- )
79
- return list_metadata
56
+ If the DISDRODB product is specified, it lists only metadata file paths of stations with the specified product
57
+ present in the local DISDRODB Data Archive.
80
58
 
59
+ available_data : bool, optional
81
60
 
82
- def _get_list_all_metadata(base_dir, data_sources=None, campaign_names=None, station_names=None):
83
- """
84
- Get the list of metadata filepaths in the DISDRODB raw archive.
61
+ If ``product`` is not specified:
85
62
 
86
- Parameters
87
- ----------
88
- base_dir : str
89
- Base directory of DISDRODB
90
- Format: <...>/DISDRODB
91
- data_sources : str or list of str
92
- Name of data source(s) of interest.
93
- The name(s) must be UPPER CASE.
94
- The default is None
95
- campaign_names : str or list of str
96
- Name of the campaign(s) of interest.
97
- The name(s) must be UPPER CASE.
98
- The default is None
99
- station_names : str or list of str
100
- Station names of interest.
101
- The default is None
102
- with_stations_data : bool
103
- If True, only return metadata filepaths that have corresponding data in the local DISDRODB raw archive.
104
- The default is True
63
+ - if available_data is False, return metadata filepaths of stations present in the DISDRODB Metadata Archive
64
+ - if available_data is True, return metadata filepaths of stations with data available on the
65
+ online DISDRODB Decentralized Data Archive (i.e., stations with the disdrodb_data_url in the metadata).
105
66
 
106
- Returns
107
- -------
108
- metadata_filepaths: list
109
- List of metadata YAML file paths
67
+ If ``product`` is specified:
110
68
 
111
- """
112
- # Get all config files from the metadata directories
113
- list_of_base_path = []
114
- if data_sources:
115
- if isinstance(data_sources, str):
116
- data_sources = [data_sources]
117
- else:
118
- data_sources = ["**"]
119
- if campaign_names:
120
- if isinstance(campaign_names, str):
121
- campaign_names = [campaign_names]
122
- else:
123
- campaign_names = ["**"]
124
-
125
- for data_source in data_sources:
126
- for campaign_name in campaign_names:
127
- base_path = os.path.join(base_dir, "Raw", data_source, campaign_name)
128
- list_of_base_path.append(base_path)
129
-
130
- metadata_filepaths = []
131
- for base_path in list_of_base_path:
132
- if station_names:
133
- if isinstance(station_names, str):
134
- station_names = [station_names]
135
- for station_name in station_names:
136
- metadata_path = os.path.join(base_path, "**", "metadata", f"{station_name}.yml")
137
- metadata_filepaths += glob.glob(metadata_path, recursive=True)
138
- else:
139
- metadata_path = os.path.join(base_path, "**", "metadata", "*.yml")
140
- metadata_filepaths += glob.glob(metadata_path, recursive=True)
141
-
142
- return list(set(metadata_filepaths))
143
-
144
-
145
- def _get_list_metadata_with_data(base_dir, data_sources=None, campaign_names=None, station_names=None):
146
- """
147
- Get the list of metadata filepaths that have corresponding data in the DISDRODB raw archive.
69
+ - if available_data is False, return metadata filepaths of stations where
70
+ the product directory exists in the in the local DISDRODB Data Archive
71
+ - if available_data is True, return metadata filepaths of stations where product data exists in the
72
+ in the local DISDRODB Data Archive.
73
+ The default is is False.
148
74
 
149
- Parameters
150
- ----------
151
- base_dir : str
152
- Base directory of DISDRODB
153
- Format: <...>/DISDRODB
154
- data_sources : str or list of str
155
- Name of data source(s) of interest.
75
+ data_sources : str or sequence of str, optional
76
+ One or more data source identifiers to filter stations by.
156
77
  The name(s) must be UPPER CASE.
157
- The default is None
158
- campaign_names : str or list of str
159
- Name of the campaign(s) of interest.
78
+ If None, no filtering on data source is applied. The default is is ``None``.
79
+ campaign_names : str or sequence of str, optional
80
+ One or more campaign names to filter stations by.
160
81
  The name(s) must be UPPER CASE.
161
- The default is None
162
- station_names : str or list of str
163
- Station names of interest.
164
- The default is None
82
+ If None, no filtering on campaign is applied. The default is is ``None``.
83
+ station_names : str or sequence of str, optional
84
+ One or more station names to include.
85
+ If None, all stations matching other filters are considered. The default is is ``None``.
86
+ raise_error_if_empty : bool, optional
87
+ If True and no stations satisfy the criteria, raise a ``ValueError``.
88
+ If False, return an empty list/tuple. The default is False.
89
+ invalid_fields_policy : {'raise', 'warn', 'ignore'}, optional
90
+ How to handle invalid filter values for ``data_sources``, ``campaign_names``,
91
+ or ``station_names`` that are not present in the metadata archive:
92
+
93
+ - 'raise' : raise a ``ValueError`` (default)
94
+ - 'warn' : emit a warning, then ignore invalid entries
95
+ - 'ignore': silently drop invalid entries
96
+ data_archive_dir : str or Path-like, optional
97
+ Path to the root of the local DISDRODB Data Archive. Format: ``<...>/DISDRODB``
98
+ Required only if ``product``is specified.
99
+ If None, the``data_archive_dir`` path specified in the DISDRODB active configuration file is used.
100
+ The default is None.
101
+ metadata_archive_dir : str or Path-like, optional
102
+ Path to the root of the DISDRODB Metadata Archive. Format: ``<...>/DISDRODB``
103
+ If None, the``metadata_archive_dir`` path specified in the DISDRODB active configuratio. The default is None.
104
+ **product_kwargs : dict, optional
105
+ Additional arguments required for some products.
106
+ For example, for the "L2E" product, you need to specify ``rolling`` and
107
+ ``sample_interval``. For the "L2M" product, you need to specify also
108
+ the ``model_name``.
165
109
 
166
110
  Returns
167
111
  -------
@@ -169,39 +113,28 @@ def _get_list_metadata_with_data(base_dir, data_sources=None, campaign_names=Non
169
113
  List of metadata YAML file paths
170
114
 
171
115
  """
172
- from disdrodb.api.io import available_stations
173
-
174
- # Check inputs
175
- if isinstance(data_sources, str):
176
- data_sources = [data_sources]
177
- if isinstance(campaign_names, str):
178
- campaign_names = [campaign_names]
179
-
180
- # Retrieve information of requested stations
181
- # --> (data_source, campaign_name, station_name)
182
-
183
116
  list_info = available_stations(
184
- base_dir=base_dir,
185
- product="RAW",
186
117
  data_sources=data_sources,
187
118
  campaign_names=campaign_names,
119
+ station_names=station_names,
120
+ product=product,
121
+ available_data=available_data,
122
+ raise_error_if_empty=raise_error_if_empty,
123
+ invalid_fields_policy=invalid_fields_policy,
124
+ metadata_archive_dir=metadata_archive_dir,
125
+ data_archive_dir=data_archive_dir,
126
+ return_tuple=True,
127
+ **product_kwargs,
188
128
  )
189
129
 
190
- # If no stations available, raise an error
191
- if len(list_info) == 0:
192
- raise ValueError("No stations are available !")
193
-
194
- # Get metadata filepaths
130
+ # Define metadata filepath
195
131
  metadata_filepaths = [
196
132
  define_metadata_filepath(
197
- product="Raw",
133
+ metadata_archive_dir=metadata_archive_dir,
198
134
  data_source=data_source,
199
135
  campaign_name=campaign_name,
200
136
  station_name=station_name,
201
- base_dir=base_dir,
202
- check_exists=False,
203
137
  )
204
138
  for data_source, campaign_name, station_name in list_info
205
139
  ]
206
-
207
- return metadata_filepaths
140
+ return sorted(set(metadata_filepaths))