disdrodb 0.2.1__py3-none-any.whl → 0.4.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 (313) hide show
  1. disdrodb/__init__.py +3 -1
  2. disdrodb/_config.py +2 -3
  3. disdrodb/_version.py +2 -2
  4. disdrodb/accessor/__init__.py +2 -1
  5. disdrodb/accessor/methods.py +10 -9
  6. disdrodb/api/checks.py +3 -7
  7. disdrodb/api/configs.py +1 -3
  8. disdrodb/api/create_directories.py +4 -6
  9. disdrodb/api/info.py +1 -3
  10. disdrodb/api/io.py +233 -32
  11. disdrodb/api/path.py +3 -7
  12. disdrodb/cli/disdrodb_check_metadata_archive.py +3 -2
  13. disdrodb/cli/disdrodb_check_products_options.py +45 -0
  14. disdrodb/cli/disdrodb_create_summary.py +54 -28
  15. disdrodb/cli/disdrodb_create_summary_station.py +41 -20
  16. disdrodb/cli/disdrodb_data_archive_directory.py +2 -3
  17. disdrodb/cli/disdrodb_download_archive.py +50 -30
  18. disdrodb/cli/disdrodb_download_metadata_archive.py +28 -16
  19. disdrodb/cli/disdrodb_download_station.py +58 -29
  20. disdrodb/cli/disdrodb_initialize_station.py +43 -23
  21. disdrodb/cli/disdrodb_metadata_archive_directory.py +2 -3
  22. disdrodb/cli/disdrodb_open_data_archive.py +17 -13
  23. disdrodb/cli/disdrodb_open_logs_directory.py +31 -21
  24. disdrodb/cli/disdrodb_open_metadata_archive.py +26 -13
  25. disdrodb/cli/disdrodb_open_metadata_directory.py +34 -23
  26. disdrodb/cli/disdrodb_open_product_directory.py +39 -23
  27. disdrodb/cli/disdrodb_open_readers_directory.py +2 -3
  28. disdrodb/cli/disdrodb_run.py +189 -0
  29. disdrodb/cli/disdrodb_run_l0.py +61 -70
  30. disdrodb/cli/disdrodb_run_l0_station.py +50 -55
  31. disdrodb/cli/disdrodb_run_l0a.py +53 -51
  32. disdrodb/cli/disdrodb_run_l0a_station.py +41 -40
  33. disdrodb/cli/disdrodb_run_l0b.py +51 -51
  34. disdrodb/cli/disdrodb_run_l0b_station.py +40 -39
  35. disdrodb/cli/disdrodb_run_l0c.py +56 -53
  36. disdrodb/cli/disdrodb_run_l0c_station.py +44 -41
  37. disdrodb/cli/disdrodb_run_l1.py +55 -51
  38. disdrodb/cli/disdrodb_run_l1_station.py +43 -40
  39. disdrodb/cli/disdrodb_run_l2e.py +56 -51
  40. disdrodb/cli/disdrodb_run_l2e_station.py +44 -40
  41. disdrodb/cli/disdrodb_run_l2m.py +55 -51
  42. disdrodb/cli/disdrodb_run_l2m_station.py +43 -40
  43. disdrodb/cli/disdrodb_run_station.py +184 -0
  44. disdrodb/cli/disdrodb_upload_archive.py +51 -42
  45. disdrodb/cli/disdrodb_upload_station.py +42 -36
  46. disdrodb/configs.py +20 -16
  47. disdrodb/constants.py +5 -2
  48. disdrodb/data_transfer/__init__.py +1 -3
  49. disdrodb/data_transfer/download_data.py +45 -61
  50. disdrodb/data_transfer/upload_data.py +7 -11
  51. disdrodb/data_transfer/zenodo.py +2 -4
  52. disdrodb/docs.py +1 -3
  53. disdrodb/etc/configs/attributes.yaml +52 -2
  54. disdrodb/etc/configs/encodings.yaml +45 -1
  55. disdrodb/etc/products/L0C/ODM470/global.yaml +5 -0
  56. disdrodb/etc/products/L0C/global.yaml +5 -0
  57. disdrodb/etc/products/L1/ODM470/global.yaml +6 -0
  58. disdrodb/etc/products/L1/global.yaml +0 -13
  59. disdrodb/etc/products/L2E/LPM/1MIN.yaml +1 -0
  60. disdrodb/etc/products/L2E/LPM/global.yaml +36 -0
  61. disdrodb/etc/products/L2E/LPM_V0/1MIN.yaml +1 -0
  62. disdrodb/etc/products/L2E/LPM_V0/global.yaml +36 -0
  63. disdrodb/etc/products/L2E/ODM470/1MIN.yaml +1 -0
  64. disdrodb/etc/products/L2E/ODM470/global.yaml +36 -0
  65. disdrodb/etc/products/L2E/PARSIVEL/1MIN.yaml +1 -0
  66. disdrodb/etc/products/L2E/PARSIVEL/global.yaml +36 -0
  67. disdrodb/etc/products/L2E/PARSIVEL2/1MIN.yaml +1 -0
  68. disdrodb/etc/products/L2E/PARSIVEL2/global.yaml +36 -0
  69. disdrodb/etc/products/L2E/PWS100/1MIN.yaml +1 -0
  70. disdrodb/etc/products/L2E/PWS100/global.yaml +36 -0
  71. disdrodb/etc/products/L2E/RD80/1MIN.yaml +19 -0
  72. disdrodb/etc/products/L2E/SWS250/1MIN.yaml +19 -0
  73. disdrodb/etc/products/L2E/global.yaml +16 -2
  74. disdrodb/fall_velocity/__init__.py +47 -0
  75. disdrodb/fall_velocity/graupel.py +484 -0
  76. disdrodb/fall_velocity/hail.py +288 -0
  77. disdrodb/{l1/fall_velocity.py → fall_velocity/rain.py} +265 -44
  78. disdrodb/issue/__init__.py +1 -3
  79. disdrodb/issue/checks.py +2 -3
  80. disdrodb/issue/reader.py +2 -3
  81. disdrodb/issue/writer.py +2 -5
  82. disdrodb/l0/__init__.py +2 -1
  83. disdrodb/l0/check_configs.py +36 -29
  84. disdrodb/l0/check_standards.py +1 -4
  85. disdrodb/l0/configs/LPM/l0a_encodings.yml +17 -17
  86. disdrodb/l0/configs/LPM/l0b_cf_attrs.yml +55 -55
  87. disdrodb/l0/configs/LPM/l0b_encodings.yml +17 -17
  88. disdrodb/l0/configs/LPM/raw_data_format.yml +17 -17
  89. disdrodb/l0/configs/LPM_V0/l0a_encodings.yml +2 -2
  90. disdrodb/l0/configs/LPM_V0/l0b_cf_attrs.yml +2 -2
  91. disdrodb/l0/configs/LPM_V0/l0b_encodings.yml +2 -2
  92. disdrodb/l0/configs/LPM_V0/raw_data_format.yml +2 -2
  93. disdrodb/l0/configs/ODM470/bins_diameter.yml +643 -0
  94. disdrodb/l0/configs/ODM470/bins_velocity.yml +0 -0
  95. disdrodb/l0/configs/ODM470/l0a_encodings.yml +11 -0
  96. disdrodb/l0/configs/ODM470/l0b_cf_attrs.yml +46 -0
  97. disdrodb/l0/configs/ODM470/l0b_encodings.yml +106 -0
  98. disdrodb/l0/configs/ODM470/raw_data_format.yml +111 -0
  99. disdrodb/l0/configs/PARSIVEL/l0b_cf_attrs.yml +1 -1
  100. disdrodb/l0/l0_reader.py +2 -3
  101. disdrodb/l0/l0a_processing.py +6 -8
  102. disdrodb/l0/l0b_nc_processing.py +3 -6
  103. disdrodb/l0/l0b_processing.py +2 -16
  104. disdrodb/l0/l0c_processing.py +29 -12
  105. disdrodb/l0/readers/LPM/ARM/ARM_LPM.py +2 -1
  106. disdrodb/l0/readers/LPM/AUSTRALIA/MELBOURNE_2007_LPM.py +18 -18
  107. disdrodb/l0/readers/LPM/BRAZIL/CHUVA_LPM.py +18 -18
  108. disdrodb/l0/readers/LPM/BRAZIL/GOAMAZON_LPM.py +18 -18
  109. disdrodb/l0/readers/LPM/GERMANY/DWD.py +244 -63
  110. disdrodb/l0/readers/LPM/ITALY/GID_LPM.py +65 -23
  111. disdrodb/l0/readers/LPM/ITALY/GID_LPM_AQ.py +277 -0
  112. disdrodb/l0/readers/LPM/ITALY/GID_LPM_PI.py +19 -18
  113. disdrodb/l0/readers/LPM/ITALY/GID_LPM_T.py +23 -19
  114. disdrodb/l0/readers/LPM/ITALY/GID_LPM_W.py +19 -21
  115. disdrodb/l0/readers/LPM/KIT/CHWALA.py +19 -20
  116. disdrodb/l0/readers/LPM/NETHERLANDS/DELFT_LPM_NC.py +1 -1
  117. disdrodb/l0/readers/LPM/NETHERLANDS/DELFT_RWANDA_LPM_NC.py +18 -18
  118. disdrodb/l0/readers/LPM/NORWAY/HAUKELISETER_LPM.py +19 -20
  119. disdrodb/l0/readers/LPM/NORWAY/NMBU_LPM.py +19 -20
  120. disdrodb/l0/readers/LPM/SLOVENIA/ARSO.py +19 -20
  121. disdrodb/l0/readers/LPM/SLOVENIA/UL.py +19 -20
  122. disdrodb/l0/readers/LPM/SWITZERLAND/INNERERIZ_LPM.py +19 -20
  123. disdrodb/l0/readers/LPM/UK/DIVEN.py +1 -1
  124. disdrodb/l0/readers/LPM/UK/WITHWORTH_LPM.py +19 -20
  125. disdrodb/l0/readers/LPM/USA/CHARLESTON.py +19 -20
  126. disdrodb/l0/readers/LPM/USA/DEVEX.py +255 -0
  127. disdrodb/l0/readers/LPM_V0/BELGIUM/ULIEGE.py +3 -5
  128. disdrodb/l0/readers/LPM_V0/ITALY/GID_LPM_V0.py +4 -3
  129. disdrodb/l0/readers/ODM470/OCEAN/OCEANRAIN.py +124 -0
  130. disdrodb/l0/readers/PARSIVEL/AUSTRALIA/MELBOURNE_2007_PARSIVEL.py +1 -1
  131. disdrodb/l0/readers/PARSIVEL/BASQUECOUNTRY/EUSKALMET_OTT.py +2 -1
  132. disdrodb/l0/readers/PARSIVEL/CHINA/CHONGQING.py +2 -3
  133. disdrodb/l0/readers/PARSIVEL/EPFL/ARCTIC_2021.py +2 -1
  134. disdrodb/l0/readers/PARSIVEL/EPFL/COMMON_2011.py +2 -1
  135. disdrodb/l0/readers/PARSIVEL/EPFL/DAVOS_2009_2011.py +2 -1
  136. disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_2009.py +2 -1
  137. disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2008.py +2 -1
  138. disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2010.py +2 -1
  139. disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2011.py +2 -1
  140. disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2012.py +2 -1
  141. disdrodb/l0/readers/PARSIVEL/EPFL/GENEPI_2007.py +2 -1
  142. disdrodb/l0/readers/PARSIVEL/EPFL/GRAND_ST_BERNARD_2007.py +2 -1
  143. disdrodb/l0/readers/PARSIVEL/EPFL/GRAND_ST_BERNARD_2007_2.py +2 -1
  144. disdrodb/l0/readers/PARSIVEL/EPFL/HPICONET_2010.py +2 -1
  145. disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP2.py +2 -1
  146. disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP3.py +2 -1
  147. disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP4.py +2 -1
  148. disdrodb/l0/readers/PARSIVEL/EPFL/LOCARNO_2018.py +1 -1
  149. disdrodb/l0/readers/PARSIVEL/EPFL/LOCARNO_2019.py +1 -1
  150. disdrodb/l0/readers/PARSIVEL/EPFL/PARADISO_2014.py +2 -1
  151. disdrodb/l0/readers/PARSIVEL/EPFL/PARSIVEL_2007.py +2 -1
  152. disdrodb/l0/readers/PARSIVEL/EPFL/PLATO_2019.py +1 -1
  153. disdrodb/l0/readers/PARSIVEL/EPFL/RACLETS_2019.py +2 -1
  154. disdrodb/l0/readers/PARSIVEL/EPFL/RACLETS_2019_WJF.py +2 -1
  155. disdrodb/l0/readers/PARSIVEL/EPFL/RIETHOLZBACH_2011.py +2 -1
  156. disdrodb/l0/readers/PARSIVEL/EPFL/SAMOYLOV_2017.py +2 -1
  157. disdrodb/l0/readers/PARSIVEL/EPFL/SAMOYLOV_2019.py +2 -1
  158. disdrodb/l0/readers/PARSIVEL/EPFL/UNIL_2022.py +2 -1
  159. disdrodb/l0/readers/PARSIVEL/JAPAN/JMA.py +1 -1
  160. disdrodb/l0/readers/PARSIVEL/KOREA/ICEPOP_MSC.py +159 -0
  161. disdrodb/l0/readers/PARSIVEL/NASA/LPVEX.py +1 -1
  162. disdrodb/l0/readers/PARSIVEL/NASA/MC3E.py +1 -1
  163. disdrodb/l0/readers/PARSIVEL/NCAR/CCOPE_2015.py +1 -1
  164. disdrodb/l0/readers/PARSIVEL/NCAR/OWLES_MIPS.py +1 -1
  165. disdrodb/l0/readers/PARSIVEL/NCAR/PECAN_MOBILE.py +1 -1
  166. disdrodb/l0/readers/PARSIVEL/NCAR/PLOWS_MIPS.py +1 -1
  167. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2009.py +1 -1
  168. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2010.py +1 -3
  169. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2010_UF.py +1 -3
  170. disdrodb/l0/readers/PARSIVEL/SLOVENIA/UL.py +2 -1
  171. disdrodb/l0/readers/PARSIVEL2/ARM/ARM_PARSIVEL2.py +2 -1
  172. disdrodb/l0/readers/PARSIVEL2/BASQUECOUNTRY/EUSKALMET_OTT2.py +2 -1
  173. disdrodb/l0/readers/PARSIVEL2/BELGIUM/ILVO.py +2 -3
  174. disdrodb/l0/readers/PARSIVEL2/BRAZIL/CHUVA_PARSIVEL2.py +1 -1
  175. disdrodb/l0/readers/PARSIVEL2/BRAZIL/GOAMAZON_PARSIVEL2.py +1 -1
  176. disdrodb/l0/readers/PARSIVEL2/CANADA/UQAM_NC.py +1 -1
  177. disdrodb/l0/readers/PARSIVEL2/DENMARK/DTU.py +1 -1
  178. disdrodb/l0/readers/PARSIVEL2/DENMARK/EROSION_nc.py +2 -1
  179. disdrodb/l0/readers/PARSIVEL2/DENMARK/EROSION_raw.py +2 -1
  180. disdrodb/l0/readers/PARSIVEL2/FINLAND/FMI_PARSIVEL2.py +1 -1
  181. disdrodb/l0/readers/PARSIVEL2/FRANCE/ENPC_PARSIVEL2.py +2 -3
  182. disdrodb/l0/readers/PARSIVEL2/FRANCE/OSUG.py +2 -2
  183. disdrodb/l0/readers/PARSIVEL2/FRANCE/SIRTA_PARSIVEL2.py +1 -3
  184. disdrodb/l0/readers/PARSIVEL2/GREECE/NOA.py +4 -3
  185. disdrodb/l0/readers/PARSIVEL2/ITALY/GID_PARSIVEL2.py +1 -3
  186. disdrodb/l0/readers/PARSIVEL2/ITALY/HYDROX.py +6 -3
  187. disdrodb/l0/readers/PARSIVEL2/JAPAN/PRECIP.py +1 -1
  188. disdrodb/l0/readers/PARSIVEL2/KIT/BURKINA_FASO.py +1 -1
  189. disdrodb/l0/readers/PARSIVEL2/KIT/TEAMX.py +1 -1
  190. disdrodb/l0/readers/PARSIVEL2/KOREA/ICEPOP_MSC.py +161 -0
  191. disdrodb/l0/readers/PARSIVEL2/KOREA/ICEPOP_UCLM.py +126 -0
  192. disdrodb/l0/readers/PARSIVEL2/MEXICO/OH_IIUNAM_nc.py +2 -1
  193. disdrodb/l0/readers/PARSIVEL2/MPI/BCO_PARSIVEL2.py +1 -1
  194. disdrodb/l0/readers/PARSIVEL2/MPI/BOWTIE.py +1 -1
  195. disdrodb/l0/readers/PARSIVEL2/NASA/APU.py +3 -1
  196. disdrodb/l0/readers/PARSIVEL2/NASA/NSSTC.py +1 -1
  197. disdrodb/l0/readers/PARSIVEL2/NCAR/FARM_PARSIVEL2.py +2 -1
  198. disdrodb/l0/readers/PARSIVEL2/NCAR/PECAN_FP3.py +1 -1
  199. disdrodb/l0/readers/PARSIVEL2/NCAR/PECAN_MIPS.py +1 -1
  200. disdrodb/l0/readers/PARSIVEL2/NCAR/PERILS_MIPS.py +2 -1
  201. disdrodb/l0/readers/PARSIVEL2/NCAR/PERILS_PIPS.py +2 -1
  202. disdrodb/l0/readers/PARSIVEL2/NCAR/RELAMPAGO_PARSIVEL2.py +1 -1
  203. disdrodb/l0/readers/PARSIVEL2/NCAR/SNOWIE_PJ.py +1 -1
  204. disdrodb/l0/readers/PARSIVEL2/NCAR/SNOWIE_SB.py +1 -1
  205. disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_P1.py +2 -3
  206. disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_P2.py +1 -1
  207. disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_PIPS.py +2 -1
  208. disdrodb/l0/readers/PARSIVEL2/NETHERLANDS/DELFT_NC.py +1 -1
  209. disdrodb/l0/readers/PARSIVEL2/NORWAY/UIB.py +10 -2
  210. disdrodb/l0/readers/PARSIVEL2/PHILIPPINES/PAGASA.py +2 -3
  211. disdrodb/l0/readers/PARSIVEL2/SPAIN/CENER.py +1 -1
  212. disdrodb/l0/readers/PARSIVEL2/SPAIN/CR1000DL.py +1 -1
  213. disdrodb/l0/readers/PARSIVEL2/SPAIN/GRANADA.py +2 -3
  214. disdrodb/l0/readers/PARSIVEL2/SPAIN/LIAISE.py +1 -1
  215. disdrodb/l0/readers/PARSIVEL2/SWEDEN/SMHI.py +2 -1
  216. disdrodb/l0/readers/PARSIVEL2/USA/CSU.py +1 -1
  217. disdrodb/l0/readers/PARSIVEL2/USA/CW3E.py +2 -1
  218. disdrodb/l0/readers/PWS100/AUSTRIA/HOAL.py +2 -3
  219. disdrodb/l0/readers/PWS100/FRANCE/ENPC_PWS100.py +2 -3
  220. disdrodb/l0/readers/PWS100/FRANCE/ENPC_PWS100_SIRTA.py +2 -1
  221. disdrodb/l0/readers/RD80/BRAZIL/ATTO_RD80.py +1 -3
  222. disdrodb/l0/readers/RD80/BRAZIL/CHUVA_RD80.py +1 -3
  223. disdrodb/l0/readers/RD80/BRAZIL/GOAMAZON_RD80.py +1 -3
  224. disdrodb/l0/readers/RD80/NCAR/CINDY_2011_RD80.py +1 -3
  225. disdrodb/l0/readers/RD80/NCAR/RELAMPAGO_RD80.py +1 -3
  226. disdrodb/l0/readers/RD80/NOAA/PSL_RD80.py +2 -3
  227. disdrodb/l0/readers/SWS250/BELGIUM/KMI.py +2 -3
  228. disdrodb/l0/readers/template_reader_raw_netcdf_data.py +2 -3
  229. disdrodb/l0/readers/template_reader_raw_text_data.py +2 -3
  230. disdrodb/l0/standards.py +4 -5
  231. disdrodb/l0/template_tools.py +7 -11
  232. disdrodb/l1/__init__.py +2 -1
  233. disdrodb/l1/classification.py +914 -0
  234. disdrodb/l1/processing.py +36 -106
  235. disdrodb/l1/resampling.py +13 -3
  236. disdrodb/l1_env/__init__.py +1 -1
  237. disdrodb/l1_env/routines.py +7 -6
  238. disdrodb/l2/__init__.py +2 -1
  239. disdrodb/l2/empirical_dsd.py +58 -31
  240. disdrodb/l2/processing.py +327 -61
  241. disdrodb/metadata/checks.py +10 -13
  242. disdrodb/metadata/download.py +5 -4
  243. disdrodb/metadata/geolocation.py +3 -4
  244. disdrodb/metadata/info.py +3 -5
  245. disdrodb/metadata/manipulation.py +1 -3
  246. disdrodb/metadata/reader.py +1 -3
  247. disdrodb/metadata/search.py +1 -4
  248. disdrodb/metadata/standards.py +1 -3
  249. disdrodb/metadata/writer.py +1 -3
  250. disdrodb/physics/__init__.py +17 -0
  251. disdrodb/physics/atmosphere.py +273 -0
  252. disdrodb/physics/water.py +131 -0
  253. disdrodb/physics/wrappers.py +63 -0
  254. disdrodb/psd/__init__.py +1 -2
  255. disdrodb/psd/fitting.py +23 -9
  256. disdrodb/psd/models.py +2 -1
  257. disdrodb/routines/__init__.py +6 -1
  258. disdrodb/routines/l0.py +39 -25
  259. disdrodb/routines/l1.py +23 -16
  260. disdrodb/routines/l2.py +12 -9
  261. disdrodb/routines/options.py +117 -73
  262. disdrodb/routines/options_validation.py +728 -0
  263. disdrodb/routines/wrappers.py +460 -40
  264. disdrodb/scattering/__init__.py +1 -2
  265. disdrodb/scattering/axis_ratio.py +6 -6
  266. disdrodb/scattering/permittivity.py +9 -8
  267. disdrodb/scattering/routines.py +33 -15
  268. disdrodb/summary/__init__.py +1 -1
  269. disdrodb/summary/routines.py +95 -30
  270. disdrodb/utils/__init__.py +1 -1
  271. disdrodb/utils/archiving.py +18 -10
  272. disdrodb/utils/attrs.py +7 -5
  273. disdrodb/utils/cli.py +8 -10
  274. disdrodb/utils/compression.py +10 -13
  275. disdrodb/utils/coords.py +45 -0
  276. disdrodb/utils/dask.py +7 -5
  277. disdrodb/utils/dataframe.py +5 -6
  278. disdrodb/utils/decorators.py +3 -4
  279. disdrodb/utils/dict.py +1 -1
  280. disdrodb/utils/directories.py +5 -7
  281. disdrodb/utils/encoding.py +4 -5
  282. disdrodb/utils/event.py +1 -1
  283. disdrodb/utils/list.py +1 -3
  284. disdrodb/utils/logger.py +1 -3
  285. disdrodb/utils/manipulations.py +175 -4
  286. disdrodb/utils/pydantic.py +81 -0
  287. disdrodb/utils/routines.py +2 -3
  288. disdrodb/utils/subsetting.py +1 -1
  289. disdrodb/utils/time.py +6 -4
  290. disdrodb/utils/warnings.py +2 -3
  291. disdrodb/utils/writer.py +5 -3
  292. disdrodb/utils/xarray.py +31 -3
  293. disdrodb/utils/yaml.py +1 -3
  294. disdrodb/viz/__init__.py +1 -1
  295. disdrodb/viz/plots.py +193 -18
  296. {disdrodb-0.2.1.dist-info → disdrodb-0.4.0.dist-info}/METADATA +5 -4
  297. disdrodb-0.4.0.dist-info/RECORD +361 -0
  298. {disdrodb-0.2.1.dist-info → disdrodb-0.4.0.dist-info}/entry_points.txt +3 -0
  299. disdrodb/etc/products/L1/1MIN.yaml +0 -13
  300. disdrodb/etc/products/L1/LPM/1MIN.yaml +0 -13
  301. disdrodb/etc/products/L1/LPM_V0/1MIN.yaml +0 -13
  302. disdrodb/etc/products/L1/PARSIVEL/1MIN.yaml +0 -13
  303. disdrodb/etc/products/L1/PARSIVEL2/1MIN.yaml +0 -13
  304. disdrodb/etc/products/L1/PWS100/1MIN.yaml +0 -13
  305. disdrodb/etc/products/L1/RD80/1MIN.yaml +0 -13
  306. disdrodb/etc/products/L1/SWS250/1MIN.yaml +0 -13
  307. disdrodb/etc/products/L2M/10MIN.yaml +0 -12
  308. disdrodb/l1/beard_model.py +0 -662
  309. disdrodb/l1/filters.py +0 -205
  310. disdrodb-0.2.1.dist-info/RECORD +0 -329
  311. {disdrodb-0.2.1.dist-info → disdrodb-0.4.0.dist-info}/WHEEL +0 -0
  312. {disdrodb-0.2.1.dist-info → disdrodb-0.4.0.dist-info}/licenses/LICENSE +0 -0
  313. {disdrodb-0.2.1.dist-info → disdrodb-0.4.0.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
1
1
  # -----------------------------------------------------------------------------.
2
- # Copyright (c) 2021-2023 DISDRODB developers
2
+ # Copyright (c) 2021-2026 DISDRODB developers
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify
5
5
  # it under the terms of the GNU General Public License as published by
@@ -15,11 +15,13 @@
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
  # -----------------------------------------------------------------------------.
17
17
  """Implements ProcessingOption class for DISDRODB routines."""
18
+
18
19
  import json
19
20
  import os
21
+ from pathlib import Path
20
22
 
21
23
  import disdrodb
22
- from disdrodb.api.checks import check_product, check_sensor_name, check_temporal_resolution
24
+ from disdrodb.api.checks import check_product, check_temporal_resolution
23
25
  from disdrodb.api.info import group_filepaths
24
26
  from disdrodb.configs import get_products_configs_dir
25
27
  from disdrodb.utils.archiving import define_temporal_partitions, group_files_by_temporal_partitions
@@ -28,22 +30,68 @@ from disdrodb.utils.routines import is_possible_product
28
30
  from disdrodb.utils.time import ensure_timedelta_seconds, get_sampling_information
29
31
  from disdrodb.utils.yaml import read_yaml
30
32
 
31
- # TODO: Test ensure recursive update for product_options key, do not replace just "product_options" dict !
32
- # get_product_options(product="L2E", temporal_resolution="10MIN")
33
- # get_product_options(product="L2M", temporal_resolution="10MIN")
34
- # get_product_options(product="L1")
35
- # get_product_options(product="L1", temporal_resolution="1MIN")
36
- # get_product_options(product="L1", temporal_resolution="1MIN", sensor_name="PARSIVEL")
37
-
38
- # test temporal_resolutions are unique
39
-
40
- # TODO: test return list
41
- # get_product_temporal_resolutions(product="L1")
42
- # get_product_temporal_resolutions(product="L2E")
43
- # get_product_temporal_resolutions(product="L2M")
44
33
 
45
-
46
- def get_product_options(product, temporal_resolution=None, sensor_name=None):
34
+ def get_product_options_directory(products_configs_dir, product, sensor_name=None):
35
+ """Retrieve path to the product options directory."""
36
+ products_configs_dir = str(products_configs_dir) # convert pathlib to str
37
+ if sensor_name is None:
38
+ return os.path.join(products_configs_dir, product)
39
+ return os.path.join(products_configs_dir, product, sensor_name)
40
+
41
+
42
+ def get_l2m_model_settings_directory(products_configs_dir):
43
+ """Retrieve path to the product options directory."""
44
+ return os.path.join(products_configs_dir, "L2M", "MODELS")
45
+
46
+
47
+ def get_l2m_model_settings_files(products_configs_dir):
48
+ """Retrieve path to the product options directory."""
49
+ models_dir = Path(get_l2m_model_settings_directory(products_configs_dir))
50
+ models_files = list(models_dir.glob("*.yaml")) + list(models_dir.glob("*.yml"))
51
+ return models_files
52
+
53
+
54
+ def get_product_global_options_path(products_configs_dir, product, sensor_name=None):
55
+ """Retrieve path to the product global options."""
56
+ product_options_dir = get_product_options_directory(
57
+ products_configs_dir=products_configs_dir,
58
+ product=product,
59
+ sensor_name=sensor_name,
60
+ )
61
+ product_global_options_path = os.path.join(product_options_dir, "global.yaml")
62
+ if os.path.exists(product_global_options_path):
63
+ return product_global_options_path
64
+
65
+ product_options_dir = get_product_options_directory(
66
+ products_configs_dir=products_configs_dir,
67
+ product=product,
68
+ sensor_name=None,
69
+ )
70
+ global_options_path = os.path.join(product_options_dir, "global.yaml") # this must exists
71
+ return global_options_path
72
+
73
+
74
+ def get_product_custom_options_path(products_configs_dir, product, temporal_resolution, sensor_name=None):
75
+ """Retrieve path to the product temporal resolution custom options."""
76
+ product_options_dir = get_product_options_directory(
77
+ products_configs_dir=products_configs_dir,
78
+ product=product,
79
+ sensor_name=sensor_name,
80
+ )
81
+ product_global_options_path = os.path.join(product_options_dir, f"{temporal_resolution}.yaml")
82
+ if os.path.exists(product_global_options_path):
83
+ return product_global_options_path
84
+
85
+ product_options_dir = get_product_options_directory(
86
+ products_configs_dir=products_configs_dir,
87
+ product=product,
88
+ sensor_name=None,
89
+ )
90
+ custom_options_path = os.path.join(product_options_dir, f"{temporal_resolution}.yaml") # this might not exists
91
+ return custom_options_path
92
+
93
+
94
+ def get_product_options(product, temporal_resolution=None, sensor_name=None, products_configs_dir=None):
47
95
  """Return DISDRODB product options.
48
96
 
49
97
  If temporal resolution is not provided, it returns the global product option.
@@ -51,16 +99,20 @@ def get_product_options(product, temporal_resolution=None, sensor_name=None):
51
99
  If product="L1" and sensor_name is specified, it customize product options also by sensor.
52
100
  """
53
101
  # Retrieve products configuration directory
54
- products_configs_dir = get_products_configs_dir()
55
-
56
- # Validate DISDRODB products configuration
57
- validate_product_configuration(products_configs_dir)
102
+ products_configs_dir = get_products_configs_dir(products_configs_dir=products_configs_dir)
58
103
 
59
104
  # Check product
60
105
  check_product(product)
61
106
 
107
+ # Get product global options path
108
+ global_options_path = get_product_global_options_path(
109
+ products_configs_dir=products_configs_dir,
110
+ product=product,
111
+ sensor_name=sensor_name,
112
+ )
113
+
62
114
  # Retrieve global product options (when no temporal resolution !)
63
- global_options = read_yaml(os.path.join(products_configs_dir, product, "global.yaml"))
115
+ global_options = read_yaml(global_options_path)
64
116
  if temporal_resolution is None:
65
117
  global_options = check_availability_radar_simulations(global_options)
66
118
  return global_options
@@ -72,43 +124,44 @@ def get_product_options(product, temporal_resolution=None, sensor_name=None):
72
124
  global_options.pop("temporal_resolutions", None)
73
125
 
74
126
  # Read custom options for specific temporal resolution
75
- custom_options_path = os.path.join(products_configs_dir, product, f"{temporal_resolution}.yaml")
127
+ custom_options_path = get_product_custom_options_path(
128
+ products_configs_dir=products_configs_dir,
129
+ product=product,
130
+ sensor_name=sensor_name,
131
+ temporal_resolution=temporal_resolution,
132
+ )
76
133
  if not os.path.exists(custom_options_path):
77
134
  return global_options
78
135
  custom_options = read_yaml(custom_options_path)
79
136
 
80
- # Define product options
137
+ # Update global options with the custom options specified
81
138
  options = global_options.copy()
82
- if "product_options" in custom_options:
83
- options["product_options"].update(custom_options.pop("product_options"))
139
+ keys_options = ["archive_options", "product_options", "radar_options"]
140
+ for key in keys_options:
141
+ if key in custom_options:
142
+ options[key].update(custom_options.pop(key)) # Update with only one
143
+
144
+ # Update remaining flat keys
84
145
  options.update(custom_options)
85
146
 
86
147
  # Check availability of radar simulations
87
148
  options = check_availability_radar_simulations(options)
88
149
 
89
- # Customize product options by sensor if L1 product
90
- if product == "L1" and sensor_name is not None:
91
- check_sensor_name(sensor_name)
92
- custom_options_path = os.path.join(products_configs_dir, product, sensor_name, f"{temporal_resolution}.yaml")
93
- if not os.path.exists(custom_options_path):
94
- return options
95
- custom_options = read_yaml(custom_options_path)
96
- if "product_options" in custom_options:
97
- options["product_options"].update(custom_options.pop("product_options"))
98
150
  return options
99
151
 
100
152
 
101
- def get_product_temporal_resolutions(product):
153
+ def get_product_temporal_resolutions(product, sensor_name=None):
102
154
  """Return DISDRODB products temporal resolutions."""
103
155
  # Check only L2E and L2M
104
- return get_product_options(product)["temporal_resolutions"]
156
+ return get_product_options(product, sensor_name=sensor_name)["temporal_resolutions"]
105
157
 
106
158
 
107
- def get_model_options(product, model_name):
159
+ def get_model_options(model_name, products_configs_dir=None):
108
160
  """Return DISDRODB L2M product model options."""
109
161
  # Retrieve products configuration directory
110
- products_configs_dir = get_products_configs_dir()
111
- model_options_path = os.path.join(products_configs_dir, product, "MODELS", f"{model_name}.yaml")
162
+ products_configs_dir = get_products_configs_dir(products_configs_dir=products_configs_dir)
163
+ models_settings_dir = get_l2m_model_settings_directory(products_configs_dir)
164
+ model_options_path = os.path.join(models_settings_dir, f"{model_name}.yaml")
112
165
  model_options = read_yaml(model_options_path)
113
166
  return model_options
114
167
 
@@ -120,19 +173,6 @@ def check_availability_radar_simulations(options):
120
173
  return options
121
174
 
122
175
 
123
- def validate_product_configuration(products_configs_dir):
124
- """Validate the DISDRODB products configuration files."""
125
- # TODO: Implement validation of DISDRODB products configuration files with pydantic
126
- # TODO: Raise warning if L1 temporal resolutions does not includes all temporal resolutions of L2 products.
127
- # TODO: Raise warning if L2E temporal resolutions does not includes all temporal resolutions of L2M products.
128
- # if stategy_event, check neighbor_time_interval >= sample_interval !
129
- # if temporal_resolution_to_seconds(neighbor_time_interval) < temporal_resolution_to_seconds(sample_interval):
130
- # msg = "'neighbor_time_interval' must be at least equal to the dataset sample interval ({sample_interval})"
131
- # raise ValueError(msg)
132
-
133
- pass
134
-
135
-
136
176
  def _define_blocks_offsets(sample_interval, temporal_resolution):
137
177
  """Define blocks offset for resampling logic."""
138
178
  # Retrieve accumulation_interval and rolling option
@@ -152,6 +192,19 @@ def _define_blocks_offsets(sample_interval, temporal_resolution):
152
192
  return block_starts_offset, block_ends_offset
153
193
 
154
194
 
195
+ class L0CProcessingOptions:
196
+ """Define L0C product processing options."""
197
+
198
+ def __init__(self, sensor_name):
199
+ """Define DISDRODB L0C product processing options."""
200
+ product = "L0C"
201
+ options = get_product_options(product=product, sensor_name=sensor_name)["archive_options"]
202
+
203
+ self.product = product
204
+ self.folder_partitioning = options["folder_partitioning"]
205
+ self.product_frequency = options["strategy_options"]["freq"]
206
+
207
+
155
208
  class L1ProcessingOptions:
156
209
  """Define L1 product processing options."""
157
210
 
@@ -162,7 +215,7 @@ class L1ProcessingOptions:
162
215
  # ---------------------------------------------------------------------.
163
216
  # Define temporal resolutions for which to retrieve processing options
164
217
  if temporal_resolutions is None:
165
- temporal_resolutions = get_product_temporal_resolutions(product)
218
+ temporal_resolutions = get_product_temporal_resolutions(product, sensor_name=sensor_name)
166
219
  elif isinstance(temporal_resolutions, str):
167
220
  temporal_resolutions = [temporal_resolutions]
168
221
  _ = [check_temporal_resolution(temporal_resolution) for temporal_resolution in temporal_resolutions]
@@ -202,12 +255,9 @@ class L1ProcessingOptions:
202
255
  archive_options = product_options.pop("archive_options")
203
256
 
204
257
  dict_product_options[temporal_resolution] = product_options
205
- # -------------------------------------------------------------------------.
258
+
206
259
  # Define folder partitioning
207
- if "folder_partitioning" not in archive_options:
208
- dict_folder_partitioning[temporal_resolution] = disdrodb.config.get("folder_partitioning")
209
- else:
210
- dict_folder_partitioning[temporal_resolution] = archive_options.pop("folder_partitioning")
260
+ dict_folder_partitioning[temporal_resolution] = archive_options.pop("folder_partitioning")
211
261
 
212
262
  # -------------------------------------------------------------------------.
213
263
  # Define list of temporal partitions
@@ -284,40 +334,34 @@ class L1ProcessingOptions:
284
334
  self.dict_folder_partitioning = dict_folder_partitioning
285
335
 
286
336
  def group_files_by_temporal_partitions(self, temporal_resolution):
287
- """Return files partitions dictionary for a specific L2E product."""
337
+ """Return files partitions dictionary for a specific L1 product."""
288
338
  return self.dict_files_partitions[temporal_resolution]
289
339
 
290
- def get_product_options(self, temporal_resolution):
291
- """Return product options dictionary for a specific L2E product."""
292
- return self.dict_product_options[temporal_resolution]
340
+ def get_product_options(self, temporal_resolution): # noqa
341
+ """Return product options dictionary for a specific L1 product."""
342
+ return {} # self.dict_product_options[temporal_resolution]
293
343
 
294
344
  def get_folder_partitioning(self, temporal_resolution):
295
- """Return the folder partitioning for a specific L2E product."""
296
- # to be used for logs and files !
345
+ """Return the folder partitioning for a specific L1 product."""
297
346
  return self.dict_folder_partitioning[temporal_resolution]
298
347
 
299
348
 
300
349
  class L2ProcessingOptions:
301
350
  """Define L2 products processing options."""
302
351
 
303
- def __init__(self, product, filepaths, parallel, temporal_resolution):
352
+ def __init__(self, product, filepaths, parallel, temporal_resolution, sensor_name):
304
353
  """Define DISDRODB L2 products processing options."""
305
- import disdrodb
306
-
307
354
  # Check temporal resolution
308
355
  check_temporal_resolution(temporal_resolution)
309
356
 
310
357
  # Get product options
311
- product_options = get_product_options(product, temporal_resolution=temporal_resolution)
358
+ product_options = get_product_options(product, temporal_resolution=temporal_resolution, sensor_name=sensor_name)
312
359
 
313
360
  # Extract processing options
314
361
  archive_options = product_options.pop("archive_options")
315
362
 
316
363
  # Define folder partitioning
317
- if "folder_partitioning" not in archive_options:
318
- folder_partitioning = disdrodb.config.get("folder_partitioning")
319
- else:
320
- folder_partitioning = archive_options.pop("folder_partitioning")
364
+ folder_partitioning = archive_options.pop("folder_partitioning")
321
365
 
322
366
  # Define files temporal partitions
323
367
  # - [{start_time: np.datetime64, end_time: np.datetime64}, ....]