disdrodb 0.2.0__py3-none-any.whl → 0.3.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 (315) hide show
  1. disdrodb/__init__.py +1 -1
  2. disdrodb/_config.py +1 -3
  3. disdrodb/_version.py +2 -2
  4. disdrodb/accessor/__init__.py +1 -1
  5. disdrodb/accessor/methods.py +18 -11
  6. disdrodb/api/checks.py +2 -4
  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 +15 -9
  11. disdrodb/api/path.py +1 -3
  12. disdrodb/cli/disdrodb_check_metadata_archive.py +2 -2
  13. disdrodb/cli/disdrodb_check_products_options.py +44 -0
  14. disdrodb/cli/disdrodb_create_summary.py +48 -22
  15. disdrodb/cli/disdrodb_create_summary_station.py +39 -18
  16. disdrodb/cli/disdrodb_data_archive_directory.py +1 -3
  17. disdrodb/cli/disdrodb_download_archive.py +45 -24
  18. disdrodb/cli/disdrodb_download_metadata_archive.py +27 -16
  19. disdrodb/cli/disdrodb_download_station.py +56 -26
  20. disdrodb/cli/disdrodb_initialize_station.py +40 -20
  21. disdrodb/cli/disdrodb_metadata_archive_directory.py +1 -3
  22. disdrodb/cli/disdrodb_open_data_archive.py +16 -11
  23. disdrodb/cli/disdrodb_open_logs_directory.py +29 -18
  24. disdrodb/cli/disdrodb_open_metadata_archive.py +25 -11
  25. disdrodb/cli/disdrodb_open_metadata_directory.py +32 -20
  26. disdrodb/cli/disdrodb_open_product_directory.py +38 -21
  27. disdrodb/cli/disdrodb_open_readers_directory.py +1 -3
  28. disdrodb/cli/disdrodb_run.py +189 -0
  29. disdrodb/cli/disdrodb_run_l0.py +55 -64
  30. disdrodb/cli/disdrodb_run_l0_station.py +47 -52
  31. disdrodb/cli/disdrodb_run_l0a.py +47 -45
  32. disdrodb/cli/disdrodb_run_l0a_station.py +38 -37
  33. disdrodb/cli/disdrodb_run_l0b.py +45 -45
  34. disdrodb/cli/disdrodb_run_l0b_station.py +37 -36
  35. disdrodb/cli/disdrodb_run_l0c.py +50 -47
  36. disdrodb/cli/disdrodb_run_l0c_station.py +41 -38
  37. disdrodb/cli/disdrodb_run_l1.py +49 -45
  38. disdrodb/cli/disdrodb_run_l1_station.py +40 -37
  39. disdrodb/cli/disdrodb_run_l2e.py +50 -45
  40. disdrodb/cli/disdrodb_run_l2e_station.py +41 -37
  41. disdrodb/cli/disdrodb_run_l2m.py +49 -45
  42. disdrodb/cli/disdrodb_run_l2m_station.py +40 -37
  43. disdrodb/cli/disdrodb_run_station.py +184 -0
  44. disdrodb/cli/disdrodb_upload_archive.py +45 -35
  45. disdrodb/cli/disdrodb_upload_station.py +39 -32
  46. disdrodb/configs.py +13 -8
  47. disdrodb/constants.py +4 -2
  48. disdrodb/data_transfer/__init__.py +1 -3
  49. disdrodb/data_transfer/download_data.py +38 -54
  50. disdrodb/data_transfer/upload_data.py +1 -3
  51. disdrodb/data_transfer/zenodo.py +1 -3
  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 +1 -14
  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 +17 -3
  74. disdrodb/etc/products/L2M/global.yaml +1 -1
  75. disdrodb/fall_velocity/__init__.py +46 -0
  76. disdrodb/fall_velocity/graupel.py +483 -0
  77. disdrodb/fall_velocity/hail.py +287 -0
  78. disdrodb/{l1/fall_velocity.py → fall_velocity/rain.py} +265 -50
  79. disdrodb/issue/__init__.py +1 -3
  80. disdrodb/issue/checks.py +3 -5
  81. disdrodb/issue/reader.py +1 -3
  82. disdrodb/issue/writer.py +1 -3
  83. disdrodb/l0/__init__.py +1 -1
  84. disdrodb/l0/check_configs.py +26 -17
  85. disdrodb/l0/check_standards.py +1 -3
  86. disdrodb/l0/configs/LPM/l0a_encodings.yml +0 -1
  87. disdrodb/l0/configs/LPM/l0b_cf_attrs.yml +0 -4
  88. disdrodb/l0/configs/LPM/l0b_encodings.yml +9 -9
  89. disdrodb/l0/configs/LPM/raw_data_format.yml +11 -11
  90. disdrodb/l0/configs/LPM_V0/bins_diameter.yml +103 -0
  91. disdrodb/l0/configs/LPM_V0/bins_velocity.yml +103 -0
  92. disdrodb/l0/configs/LPM_V0/l0a_encodings.yml +45 -0
  93. disdrodb/l0/configs/LPM_V0/l0b_cf_attrs.yml +180 -0
  94. disdrodb/l0/configs/LPM_V0/l0b_encodings.yml +410 -0
  95. disdrodb/l0/configs/LPM_V0/raw_data_format.yml +474 -0
  96. disdrodb/l0/configs/ODM470/bins_diameter.yml +643 -0
  97. disdrodb/l0/configs/ODM470/bins_velocity.yml +0 -0
  98. disdrodb/l0/configs/ODM470/l0a_encodings.yml +11 -0
  99. disdrodb/l0/configs/ODM470/l0b_cf_attrs.yml +46 -0
  100. disdrodb/l0/configs/ODM470/l0b_encodings.yml +106 -0
  101. disdrodb/l0/configs/ODM470/raw_data_format.yml +111 -0
  102. disdrodb/l0/configs/PARSIVEL/l0b_cf_attrs.yml +1 -1
  103. disdrodb/l0/configs/PARSIVEL/raw_data_format.yml +8 -8
  104. disdrodb/l0/configs/PARSIVEL2/raw_data_format.yml +9 -9
  105. disdrodb/l0/l0_reader.py +1 -3
  106. disdrodb/l0/l0a_processing.py +7 -5
  107. disdrodb/l0/l0b_nc_processing.py +2 -4
  108. disdrodb/l0/l0b_processing.py +27 -22
  109. disdrodb/l0/l0c_processing.py +37 -11
  110. disdrodb/l0/manuals/LPM_V0.pdf +0 -0
  111. disdrodb/l0/readers/LPM/ARM/ARM_LPM.py +1 -1
  112. disdrodb/l0/readers/LPM/AUSTRALIA/MELBOURNE_2007_LPM.py +1 -1
  113. disdrodb/l0/readers/LPM/BRAZIL/CHUVA_LPM.py +1 -1
  114. disdrodb/l0/readers/LPM/BRAZIL/GOAMAZON_LPM.py +1 -1
  115. disdrodb/l0/readers/LPM/GERMANY/DWD.py +190 -12
  116. disdrodb/l0/readers/LPM/ITALY/GID_LPM.py +63 -14
  117. disdrodb/l0/readers/LPM/ITALY/GID_LPM_PI.py +279 -0
  118. disdrodb/l0/readers/LPM/ITALY/GID_LPM_T.py +279 -0
  119. disdrodb/l0/readers/LPM/ITALY/GID_LPM_W.py +3 -5
  120. disdrodb/l0/readers/LPM/KIT/CHWALA.py +1 -3
  121. disdrodb/l0/readers/LPM/NETHERLANDS/DELFT_LPM_NC.py +1 -1
  122. disdrodb/l0/readers/LPM/NETHERLANDS/DELFT_RWANDA_LPM_NC.py +103 -0
  123. disdrodb/l0/readers/LPM/NORWAY/HAUKELISETER_LPM.py +214 -0
  124. disdrodb/l0/readers/LPM/NORWAY/NMBU_LPM.py +206 -0
  125. disdrodb/l0/readers/LPM/SLOVENIA/ARSO.py +1 -3
  126. disdrodb/l0/readers/LPM/SLOVENIA/UL.py +1 -3
  127. disdrodb/l0/readers/LPM/SWITZERLAND/INNERERIZ_LPM.py +1 -3
  128. disdrodb/l0/readers/LPM/UK/DIVEN.py +1 -1
  129. disdrodb/l0/readers/LPM/UK/WITHWORTH_LPM.py +217 -0
  130. disdrodb/l0/readers/LPM/USA/CHARLESTON.py +227 -0
  131. disdrodb/l0/readers/{LPM → LPM_V0}/BELGIUM/ULIEGE.py +34 -52
  132. disdrodb/l0/readers/LPM_V0/ITALY/GID_LPM_V0.py +240 -0
  133. disdrodb/l0/readers/ODM470/OCEAN/OCEANRAIN.py +123 -0
  134. disdrodb/l0/readers/PARSIVEL/AUSTRALIA/MELBOURNE_2007_PARSIVEL.py +1 -1
  135. disdrodb/l0/readers/PARSIVEL/BASQUECOUNTRY/EUSKALMET_OTT.py +1 -1
  136. disdrodb/l0/readers/PARSIVEL/CHINA/CHONGQING.py +1 -3
  137. disdrodb/l0/readers/PARSIVEL/EPFL/ARCTIC_2021.py +1 -1
  138. disdrodb/l0/readers/PARSIVEL/EPFL/COMMON_2011.py +1 -1
  139. disdrodb/l0/readers/PARSIVEL/EPFL/DAVOS_2009_2011.py +1 -1
  140. disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_2009.py +1 -1
  141. disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2008.py +1 -1
  142. disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2010.py +1 -1
  143. disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2011.py +1 -1
  144. disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2012.py +1 -1
  145. disdrodb/l0/readers/PARSIVEL/EPFL/GENEPI_2007.py +1 -1
  146. disdrodb/l0/readers/PARSIVEL/EPFL/GRAND_ST_BERNARD_2007.py +1 -1
  147. disdrodb/l0/readers/PARSIVEL/EPFL/GRAND_ST_BERNARD_2007_2.py +1 -1
  148. disdrodb/l0/readers/PARSIVEL/EPFL/HPICONET_2010.py +1 -1
  149. disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP2.py +1 -1
  150. disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP3.py +1 -1
  151. disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP4.py +1 -1
  152. disdrodb/l0/readers/PARSIVEL/EPFL/LOCARNO_2018.py +1 -1
  153. disdrodb/l0/readers/PARSIVEL/EPFL/LOCARNO_2019.py +1 -1
  154. disdrodb/l0/readers/PARSIVEL/EPFL/PARADISO_2014.py +1 -1
  155. disdrodb/l0/readers/PARSIVEL/EPFL/PARSIVEL_2007.py +1 -1
  156. disdrodb/l0/readers/PARSIVEL/EPFL/PLATO_2019.py +1 -1
  157. disdrodb/l0/readers/PARSIVEL/EPFL/RACLETS_2019.py +1 -1
  158. disdrodb/l0/readers/PARSIVEL/EPFL/RACLETS_2019_WJF.py +1 -1
  159. disdrodb/l0/readers/PARSIVEL/EPFL/RIETHOLZBACH_2011.py +1 -1
  160. disdrodb/l0/readers/PARSIVEL/EPFL/SAMOYLOV_2017.py +1 -1
  161. disdrodb/l0/readers/PARSIVEL/EPFL/SAMOYLOV_2019.py +1 -1
  162. disdrodb/l0/readers/PARSIVEL/EPFL/UNIL_2022.py +1 -1
  163. disdrodb/l0/readers/PARSIVEL/JAPAN/JMA.py +1 -1
  164. disdrodb/l0/readers/PARSIVEL/KOREA/ICEPOP_MSC.py +159 -0
  165. disdrodb/l0/readers/PARSIVEL/NASA/LPVEX.py +26 -14
  166. disdrodb/l0/readers/PARSIVEL/NASA/MC3E.py +2 -2
  167. disdrodb/l0/readers/PARSIVEL/NCAR/CCOPE_2015.py +1 -1
  168. disdrodb/l0/readers/PARSIVEL/NCAR/OWLES_MIPS.py +1 -1
  169. disdrodb/l0/readers/PARSIVEL/NCAR/PECAN_MOBILE.py +1 -1
  170. disdrodb/l0/readers/PARSIVEL/NCAR/PLOWS_MIPS.py +1 -1
  171. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2009.py +1 -1
  172. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2010.py +1 -3
  173. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2010_UF.py +1 -3
  174. disdrodb/l0/readers/PARSIVEL/SLOVENIA/UL.py +1 -1
  175. disdrodb/l0/readers/PARSIVEL2/ARM/ARM_PARSIVEL2.py +1 -1
  176. disdrodb/l0/readers/PARSIVEL2/BASQUECOUNTRY/EUSKALMET_OTT2.py +2 -2
  177. disdrodb/l0/readers/PARSIVEL2/BELGIUM/ILVO.py +1 -3
  178. disdrodb/l0/readers/PARSIVEL2/BRAZIL/CHUVA_PARSIVEL2.py +1 -1
  179. disdrodb/l0/readers/PARSIVEL2/BRAZIL/GOAMAZON_PARSIVEL2.py +1 -1
  180. disdrodb/l0/readers/PARSIVEL2/CANADA/UQAM_NC.py +1 -1
  181. disdrodb/l0/readers/PARSIVEL2/DENMARK/DTU.py +1 -1
  182. disdrodb/l0/readers/PARSIVEL2/DENMARK/EROSION_nc.py +1 -1
  183. disdrodb/l0/readers/PARSIVEL2/DENMARK/EROSION_raw.py +1 -1
  184. disdrodb/l0/readers/PARSIVEL2/FINLAND/FMI_PARSIVEL2.py +1 -1
  185. disdrodb/l0/readers/PARSIVEL2/FRANCE/ENPC_PARSIVEL2.py +1 -3
  186. disdrodb/l0/readers/PARSIVEL2/FRANCE/OSUG.py +1 -1
  187. disdrodb/l0/readers/PARSIVEL2/FRANCE/SIRTA_PARSIVEL2.py +1 -3
  188. disdrodb/l0/readers/PARSIVEL2/GREECE/NOA.py +4 -3
  189. disdrodb/l0/readers/PARSIVEL2/ITALY/GID_PARSIVEL2.py +1 -3
  190. disdrodb/l0/readers/PARSIVEL2/ITALY/HYDROX.py +5 -3
  191. disdrodb/l0/readers/PARSIVEL2/JAPAN/PRECIP.py +155 -0
  192. disdrodb/l0/readers/PARSIVEL2/KIT/BURKINA_FASO.py +1 -1
  193. disdrodb/l0/readers/PARSIVEL2/KIT/TEAMX.py +1 -1
  194. disdrodb/l0/readers/PARSIVEL2/KOREA/ICEPOP_MSC.py +161 -0
  195. disdrodb/l0/readers/PARSIVEL2/{NASA/GCPEX.py → KOREA/ICEPOP_UCLM.py} +51 -31
  196. disdrodb/l0/readers/PARSIVEL2/MEXICO/OH_IIUNAM_nc.py +1 -1
  197. disdrodb/l0/readers/PARSIVEL2/MPI/BCO_PARSIVEL2.py +15 -8
  198. disdrodb/l0/readers/PARSIVEL2/MPI/BOWTIE.py +9 -4
  199. disdrodb/l0/readers/PARSIVEL2/NASA/APU.py +31 -6
  200. disdrodb/l0/readers/PARSIVEL2/NASA/NSSTC.py +1 -1
  201. disdrodb/l0/readers/PARSIVEL2/NCAR/FARM_PARSIVEL2.py +1 -1
  202. disdrodb/l0/readers/PARSIVEL2/NCAR/PECAN_FP3.py +1 -1
  203. disdrodb/l0/readers/PARSIVEL2/NCAR/PECAN_MIPS.py +1 -1
  204. disdrodb/l0/readers/PARSIVEL2/NCAR/PERILS_MIPS.py +1 -1
  205. disdrodb/l0/readers/PARSIVEL2/NCAR/PERILS_PIPS.py +1 -1
  206. disdrodb/l0/readers/PARSIVEL2/NCAR/RELAMPAGO_PARSIVEL2.py +2 -2
  207. disdrodb/l0/readers/PARSIVEL2/NCAR/SNOWIE_PJ.py +1 -1
  208. disdrodb/l0/readers/PARSIVEL2/NCAR/SNOWIE_SB.py +1 -1
  209. disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_P1.py +1 -3
  210. disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_P2.py +1 -1
  211. disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_PIPS.py +1 -1
  212. disdrodb/l0/readers/PARSIVEL2/NETHERLANDS/DELFT_NC.py +1 -1
  213. disdrodb/l0/readers/{PARSIVEL/NASA/PIERS.py → PARSIVEL2/NORWAY/UIB.py} +65 -31
  214. disdrodb/l0/readers/PARSIVEL2/PHILIPPINES/PAGASA.py +7 -6
  215. disdrodb/l0/readers/PARSIVEL2/SPAIN/CENER.py +1 -1
  216. disdrodb/l0/readers/PARSIVEL2/SPAIN/CR1000DL.py +1 -1
  217. disdrodb/l0/readers/PARSIVEL2/SPAIN/GRANADA.py +1 -3
  218. disdrodb/l0/readers/PARSIVEL2/SPAIN/LIAISE.py +1 -1
  219. disdrodb/l0/readers/PARSIVEL2/SWEDEN/SMHI.py +1 -1
  220. disdrodb/l0/readers/PARSIVEL2/USA/CSU.py +138 -0
  221. disdrodb/l0/readers/PARSIVEL2/USA/CW3E.py +49 -22
  222. disdrodb/l0/readers/PWS100/AUSTRIA/HOAL.py +1 -3
  223. disdrodb/l0/readers/PWS100/FRANCE/ENPC_PWS100.py +1 -3
  224. disdrodb/l0/readers/PWS100/FRANCE/ENPC_PWS100_SIRTA.py +1 -1
  225. disdrodb/l0/readers/{PARSIVEL/NASA/IFLOODS.py → RD80/BRAZIL/ATTO_RD80.py} +50 -36
  226. disdrodb/l0/readers/RD80/BRAZIL/CHUVA_RD80.py +1 -3
  227. disdrodb/l0/readers/RD80/BRAZIL/GOAMAZON_RD80.py +1 -3
  228. disdrodb/l0/readers/RD80/NCAR/CINDY_2011_RD80.py +1 -3
  229. disdrodb/l0/readers/RD80/NCAR/RELAMPAGO_RD80.py +1 -3
  230. disdrodb/l0/readers/RD80/NOAA/PSL_RD80.py +1 -3
  231. disdrodb/l0/readers/{SW250 → SWS250}/BELGIUM/KMI.py +2 -4
  232. disdrodb/l0/readers/template_reader_raw_netcdf_data.py +1 -3
  233. disdrodb/l0/readers/template_reader_raw_text_data.py +1 -3
  234. disdrodb/l0/standards.py +4 -5
  235. disdrodb/l0/template_tools.py +1 -3
  236. disdrodb/l1/__init__.py +1 -1
  237. disdrodb/l1/classification.py +913 -0
  238. disdrodb/l1/processing.py +36 -106
  239. disdrodb/l1/resampling.py +8 -3
  240. disdrodb/l1_env/__init__.py +1 -1
  241. disdrodb/l1_env/routines.py +6 -6
  242. disdrodb/l2/__init__.py +1 -1
  243. disdrodb/l2/empirical_dsd.py +61 -31
  244. disdrodb/l2/processing.py +327 -62
  245. disdrodb/metadata/checks.py +1 -3
  246. disdrodb/metadata/download.py +4 -4
  247. disdrodb/metadata/geolocation.py +1 -3
  248. disdrodb/metadata/info.py +1 -3
  249. disdrodb/metadata/manipulation.py +1 -3
  250. disdrodb/metadata/reader.py +1 -3
  251. disdrodb/metadata/search.py +1 -3
  252. disdrodb/metadata/standards.py +1 -3
  253. disdrodb/metadata/writer.py +1 -3
  254. disdrodb/physics/__init__.py +17 -0
  255. disdrodb/physics/atmosphere.py +272 -0
  256. disdrodb/physics/water.py +130 -0
  257. disdrodb/physics/wrappers.py +62 -0
  258. disdrodb/psd/__init__.py +1 -1
  259. disdrodb/psd/fitting.py +22 -9
  260. disdrodb/psd/models.py +1 -1
  261. disdrodb/routines/__init__.py +5 -1
  262. disdrodb/routines/l0.py +28 -18
  263. disdrodb/routines/l1.py +8 -6
  264. disdrodb/routines/l2.py +8 -4
  265. disdrodb/routines/options.py +116 -71
  266. disdrodb/routines/options_validation.py +728 -0
  267. disdrodb/routines/wrappers.py +431 -11
  268. disdrodb/scattering/__init__.py +1 -1
  269. disdrodb/scattering/axis_ratio.py +9 -6
  270. disdrodb/scattering/permittivity.py +8 -8
  271. disdrodb/scattering/routines.py +32 -14
  272. disdrodb/summary/__init__.py +1 -1
  273. disdrodb/summary/routines.py +146 -86
  274. disdrodb/utils/__init__.py +1 -1
  275. disdrodb/utils/archiving.py +16 -9
  276. disdrodb/utils/attrs.py +4 -3
  277. disdrodb/utils/cli.py +8 -10
  278. disdrodb/utils/compression.py +13 -13
  279. disdrodb/utils/dask.py +33 -14
  280. disdrodb/utils/dataframe.py +1 -3
  281. disdrodb/utils/decorators.py +1 -3
  282. disdrodb/utils/dict.py +1 -1
  283. disdrodb/utils/directories.py +3 -5
  284. disdrodb/utils/encoding.py +2 -4
  285. disdrodb/utils/event.py +1 -1
  286. disdrodb/utils/list.py +1 -3
  287. disdrodb/utils/logger.py +1 -3
  288. disdrodb/utils/manipulations.py +182 -6
  289. disdrodb/utils/pydantic.py +80 -0
  290. disdrodb/utils/routines.py +1 -3
  291. disdrodb/utils/subsetting.py +1 -1
  292. disdrodb/utils/time.py +3 -2
  293. disdrodb/utils/warnings.py +1 -3
  294. disdrodb/utils/writer.py +1 -3
  295. disdrodb/utils/xarray.py +30 -3
  296. disdrodb/utils/yaml.py +1 -3
  297. disdrodb/viz/__init__.py +1 -1
  298. disdrodb/viz/plots.py +197 -21
  299. {disdrodb-0.2.0.dist-info → disdrodb-0.3.0.dist-info}/METADATA +2 -2
  300. disdrodb-0.3.0.dist-info/RECORD +358 -0
  301. {disdrodb-0.2.0.dist-info → disdrodb-0.3.0.dist-info}/entry_points.txt +3 -0
  302. disdrodb/etc/products/L1/1MIN.yaml +0 -13
  303. disdrodb/etc/products/L1/LPM/1MIN.yaml +0 -13
  304. disdrodb/etc/products/L1/PARSIVEL/1MIN.yaml +0 -13
  305. disdrodb/etc/products/L1/PARSIVEL2/1MIN.yaml +0 -13
  306. disdrodb/etc/products/L1/PWS100/1MIN.yaml +0 -13
  307. disdrodb/etc/products/L1/RD80/1MIN.yaml +0 -13
  308. disdrodb/etc/products/L1/SWS250/1MIN.yaml +0 -13
  309. disdrodb/etc/products/L2M/10MIN.yaml +0 -12
  310. disdrodb/l1/beard_model.py +0 -618
  311. disdrodb/l1/filters.py +0 -203
  312. disdrodb-0.2.0.dist-info/RECORD +0 -312
  313. {disdrodb-0.2.0.dist-info → disdrodb-0.3.0.dist-info}/WHEEL +0 -0
  314. {disdrodb-0.2.0.dist-info → disdrodb-0.3.0.dist-info}/licenses/LICENSE +0 -0
  315. {disdrodb-0.2.0.dist-info → disdrodb-0.3.0.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,5 @@
1
- #!/usr/bin/env python3
2
-
3
1
  # -----------------------------------------------------------------------------.
4
- # Copyright (c) 2021-2023 DISDRODB developers
2
+ # Copyright (c) 2021-2026 DISDRODB developers
5
3
  #
6
4
  # This program is free software: you can redistribute it and/or modify
7
5
  # it under the terms of the GNU General Public License as published by
disdrodb/utils/writer.py CHANGED
@@ -1,7 +1,5 @@
1
- #!/usr/bin/env python3
2
-
3
1
  # -----------------------------------------------------------------------------.
4
- # Copyright (c) 2021-2023 DISDRODB developers
2
+ # Copyright (c) 2021-2026 DISDRODB developers
5
3
  #
6
4
  # This program is free software: you can redistribute it and/or modify
7
5
  # it under the terms of the GNU General Public License as published by
disdrodb/utils/xarray.py CHANGED
@@ -1,7 +1,5 @@
1
- #!/usr/bin/env python3
2
-
3
1
  # -----------------------------------------------------------------------------.
4
- # Copyright (c) 2021-2023 DISDRODB developers
2
+ # Copyright (c) 2021-2026 DISDRODB developers
5
3
  #
6
4
  # This program is free software: you can redistribute it and/or modify
7
5
  # it under the terms of the GNU General Public License as published by
@@ -99,6 +97,35 @@ def xr_get_last_valid_idx(da_condition, dim, fill_value=None):
99
97
  return last_idx
100
98
 
101
99
 
100
+ def _np_remap_numeric_array(arr, remapping_dict, fill_value=np.nan):
101
+ # Define conditions
102
+ conditions = [arr == i for i in remapping_dict]
103
+ # Define choices corresponding to conditions
104
+ choices = remapping_dict.values()
105
+ # Apply np.select to transform the array
106
+ return np.select(conditions, choices, default=fill_value)
107
+
108
+
109
+ def _dask_remap_numeric_array(arr, remapping_dict, fill_value=np.nan):
110
+ import dask.array
111
+
112
+ return dask.array.map_blocks(_np_remap_numeric_array, arr, remapping_dict, fill_value, dtype=arr.dtype)
113
+
114
+
115
+ def remap_numeric_array(arr, remapping_dict, fill_value=np.nan):
116
+ """Remap the values of a numeric array."""
117
+ if hasattr(arr, "chunks"):
118
+ return _dask_remap_numeric_array(arr, remapping_dict, fill_value=fill_value)
119
+ return _np_remap_numeric_array(arr, remapping_dict, fill_value=fill_value)
120
+
121
+
122
+ def xr_remap_numeric_array(da, remapping_dict, fill_value=np.nan):
123
+ """Remap values of a xr.DataArray."""
124
+ output = da.copy()
125
+ output.data = remap_numeric_array(da.data, remapping_dict, fill_value=fill_value)
126
+ return output
127
+
128
+
102
129
  ####-------------------------------------------------------------------
103
130
  #### Unstacking dimension
104
131
 
disdrodb/utils/yaml.py CHANGED
@@ -1,7 +1,5 @@
1
- #!/usr/bin/env python3
2
-
3
1
  # -----------------------------------------------------------------------------.
4
- # Copyright (c) 2021-2023 DISDRODB developers
2
+ # Copyright (c) 2021-2026 DISDRODB developers
5
3
  #
6
4
  # This program is free software: you can redistribute it and/or modify
7
5
  # it under the terms of the GNU General Public License as published by
disdrodb/viz/__init__.py CHANGED
@@ -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
disdrodb/viz/plots.py CHANGED
@@ -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
@@ -17,6 +17,7 @@
17
17
  """DISDRODB Plotting Tools."""
18
18
  import matplotlib.pyplot as plt
19
19
  import numpy as np
20
+ import pandas as pd
20
21
  import psutil
21
22
  import xarray as xr
22
23
  from matplotlib.colors import LogNorm, Normalize
@@ -24,6 +25,7 @@ from matplotlib.gridspec import GridSpec
24
25
 
25
26
  from disdrodb.constants import DIAMETER_DIMENSION, VELOCITY_DIMENSION
26
27
  from disdrodb.l2.empirical_dsd import get_drop_average_velocity
28
+ from disdrodb.utils.time import ensure_sample_interval_in_seconds, regularize_dataset
27
29
 
28
30
  ####-------------------------------------------------------------------------------------------------------
29
31
  #### N(D) visualizations
@@ -45,44 +47,216 @@ def _single_plot_nd_distribution(drop_number_concentration, diameter, diameter_b
45
47
  return ax
46
48
 
47
49
 
48
- def plot_nd(ds, var="drop_number_concentration", cmap=None, norm=None):
50
+ def _check_has_diameter_dims(da):
51
+ if DIAMETER_DIMENSION not in da.dims:
52
+ raise ValueError(f"The DataArray must have dimension '{DIAMETER_DIMENSION}'.")
53
+ if "diameter_bin_width" not in da.coords:
54
+ raise ValueError("The DataArray must have coordinate 'diameter_bin_width'.")
55
+ return da
56
+
57
+
58
+ def _get_nd_variable(xr_obj, variable):
59
+ if not isinstance(xr_obj, (xr.Dataset, xr.DataArray)):
60
+ raise TypeError("Expecting xarray object as input.")
61
+ if isinstance(xr_obj, xr.Dataset):
62
+ if variable not in xr_obj:
63
+ raise ValueError(f"The dataset do not include {variable=}.")
64
+ xr_obj = xr_obj[variable]
65
+ if VELOCITY_DIMENSION in xr_obj.dims:
66
+ raise ValueError("N(D) must no have the velocity dimension.")
67
+ xr_obj = _check_has_diameter_dims(xr_obj)
68
+ return xr_obj
69
+
70
+
71
+ def plot_nd(xr_obj, variable="drop_number_concentration", cmap=None, norm=None):
49
72
  """Plot drop number concentration N(D) timeseries."""
50
- # Check inputs
51
- if var not in ds:
52
- raise ValueError(f"{var} is not a xarray Dataset variable!")
73
+ da_nd = _get_nd_variable(xr_obj, variable=variable)
53
74
 
54
75
  # Check only time and diameter dimensions are specified
55
- if "time" not in ds.dims:
76
+ if "time" not in da_nd.dims:
56
77
  ax = _single_plot_nd_distribution(
57
- drop_number_concentration=ds[var],
58
- diameter=ds["diameter_bin_center"],
59
- diameter_bin_width=ds["diameter_bin_width"],
78
+ drop_number_concentration=da_nd.isel(velocity_method=0, missing_dims="ignore"),
79
+ diameter=xr_obj["diameter_bin_center"],
80
+ diameter_bin_width=xr_obj["diameter_bin_width"],
60
81
  )
61
82
  return ax
62
83
 
63
- # Select N(D)
64
- ds_var = ds[[var]].compute()
65
-
66
84
  # Regularize input
67
- ds_var = ds_var.disdrodb.regularize()
85
+ da_nd = da_nd.compute()
86
+ da_nd = da_nd.disdrodb.regularize()
68
87
 
69
88
  # Set 0 values to np.nan
70
- ds_var = ds_var.where(ds_var[var] > 0)
89
+ da_nd = da_nd.where(da_nd > 0)
71
90
 
72
91
  # Define cmap an norm
73
92
  if cmap is None:
74
93
  cmap = plt.get_cmap("Spectral_r").copy()
75
94
 
76
- vmin = ds_var[var].min().item()
95
+ vmin = da_nd.min().item()
77
96
  norm = LogNorm(vmin, None) if norm is None else norm
78
97
 
79
98
  # Plot N(D)
80
- p = ds_var[var].plot.pcolormesh(x="time", norm=norm, cmap=cmap)
81
- p.axes.set_title("Drop number concentration (N(D))")
99
+ cbar_kwargs = {"label": "N(D) [m-3 mm-1]"}
100
+ p = da_nd.plot.pcolormesh(x="time", norm=norm, cmap=cmap, extend="max", cbar_kwargs=cbar_kwargs)
101
+ p.axes.set_title("Drop number concentration N(D)")
82
102
  p.axes.set_ylabel("Drop diameter (mm)")
83
103
  return p
84
104
 
85
105
 
106
+ def plot_nd_quicklook(
107
+ ds,
108
+ # Plot layout
109
+ hours_per_slice=5,
110
+ max_rows=6,
111
+ aligned=True,
112
+ verbose=True,
113
+ # Spectrum options
114
+ variable="drop_number_concentration",
115
+ cbar_label="N(D) [# m⁻³ mm⁻¹]",
116
+ cmap=None,
117
+ norm=None,
118
+ d_lim=(0.3, 5),
119
+ # R options
120
+ add_r=True,
121
+ r_lim=(0.1, 50),
122
+ r_scale="log",
123
+ r_color="tab:blue",
124
+ r_linewidth=1.2,
125
+ ):
126
+ """Display multi-rows quicklook of N(D)."""
127
+ # Colormap & normalization
128
+ if cmap is None:
129
+ cmap = plt.get_cmap("Spectral_r").copy()
130
+ cmap.set_under("none")
131
+ if norm is None:
132
+ norm = LogNorm(vmin=1, vmax=10_000)
133
+
134
+ # ---------------------------
135
+ # Define temporal slices
136
+ # - Align to closest <hours_per_slice> time
137
+ # - For hours_per_slice=3 --> 00, 03, 06, ...
138
+ time = ds["time"].to_index()
139
+ t_start = time[0]
140
+ t_end = time[-1]
141
+ if aligned:
142
+ aligned_start = t_start.floor(f"{hours_per_slice}h")
143
+ aligned_end = t_end.ceil(f"{hours_per_slice}h")
144
+ # Create time bins
145
+ time_bins = pd.date_range(
146
+ start=aligned_start,
147
+ end=aligned_end,
148
+ freq=f"{hours_per_slice}h",
149
+ )
150
+ else:
151
+ # Create time bins
152
+ time_bins = pd.date_range(
153
+ start=t_start,
154
+ end=t_end + pd.Timedelta(f"{hours_per_slice}h"),
155
+ freq=f"{hours_per_slice}h",
156
+ )
157
+
158
+ n_total_slices = len(time_bins) - 1
159
+ n_slices = min(n_total_slices, max_rows)
160
+
161
+ # Print info on event quicklook
162
+ if verbose:
163
+ print("=== N(D) Event Quicklook ===")
164
+ print(f"Dataset time span : {t_start} → {t_end}")
165
+ print(f"Slice length : {hours_per_slice} h")
166
+ print(f"Plotted slices : {n_slices}/{n_total_slices}")
167
+ if n_total_slices > max_rows:
168
+ last_plotted_end = time_bins[max_rows]
169
+ print(f"Unplotted period : {last_plotted_end} → {aligned_end}")
170
+
171
+ # Regularize dataset to match bin start_time and end_time
172
+ sample_interval = ensure_sample_interval_in_seconds(ds["sample_interval"].to_numpy()).item()
173
+ ds = regularize_dataset(ds, freq=f"{sample_interval}s", start_time=time_bins[0], end_time=time_bins[-1])
174
+
175
+ # Define figure
176
+ fig, axes = plt.subplots(
177
+ nrows=n_slices,
178
+ ncols=1,
179
+ figsize=(14, 2.8 * n_slices),
180
+ sharex=False,
181
+ constrained_layout=True,
182
+ )
183
+
184
+ if n_slices == 1:
185
+ axes = [axes]
186
+
187
+ # Plot each slice
188
+ for i in range(n_slices):
189
+ # Extract dataset slice
190
+ t0 = time_bins[i]
191
+ t1 = time_bins[i + 1]
192
+ ds_slice = ds.sel(time=slice(t0, t1))
193
+ da_nd = ds_slice[variable]
194
+
195
+ # Define plot ax
196
+ ax = axes[i]
197
+
198
+ # Plot N(D)
199
+ p = da_nd.plot.pcolormesh(
200
+ ax=ax,
201
+ x="time",
202
+ y="diameter_bin_center",
203
+ norm=norm,
204
+ cmap=cmap,
205
+ shading="auto",
206
+ add_colorbar=False,
207
+ )
208
+
209
+ # Overlay Dm
210
+ ds_slice["Dm"].plot(
211
+ ax=ax,
212
+ x="time",
213
+ color="black",
214
+ linestyle="--",
215
+ linewidth=1.2,
216
+ label="Dm",
217
+ )
218
+
219
+ # Add axis labels and title
220
+ ax.set_xlabel("")
221
+ ax.set_ylabel("Diameter [mm]")
222
+ ax.set_title(f"{t0:%H:%M} - {t1:%H:%M} UTC")
223
+
224
+ if i == 0:
225
+ ax.legend(loc="upper right")
226
+
227
+ # Add rain rate on secondary axis
228
+ if add_r:
229
+ ax_r = ax.twinx()
230
+ ds_slice["R"].plot(
231
+ ax=ax_r,
232
+ x="time",
233
+ color=r_color,
234
+ linewidth=r_linewidth,
235
+ label="R",
236
+ )
237
+ ax_r.set_ylim(r_lim)
238
+ ax_r.set_yscale(r_scale)
239
+ ax_r.set_ylabel("Rain rate [mm h$^{-1}$]", color="tab:blue")
240
+ ax_r.tick_params(axis="y", labelcolor="tab:blue")
241
+ ax_r.set_title("")
242
+
243
+ ax.set_ylim(*d_lim)
244
+
245
+ axes[-1].set_xlabel("Time (UTC)")
246
+ # ---------------------------
247
+ # Shared colorbar
248
+ # ---------------------------
249
+ cbar = fig.colorbar(
250
+ p,
251
+ ax=axes,
252
+ orientation="horizontal",
253
+ pad=0.02,
254
+ fraction=0.03,
255
+ extend="max",
256
+ )
257
+ cbar.set_label(cbar_label)
258
+
259
+
86
260
  ####-------------------------------------------------------------------------------------------------------
87
261
  #### Spectra visualizations
88
262
 
@@ -96,6 +270,8 @@ def _check_has_diameter_and_velocity_dims(da):
96
270
  def _get_spectrum_variable(xr_obj, variable):
97
271
  if not isinstance(xr_obj, (xr.Dataset, xr.DataArray)):
98
272
  raise TypeError("Expecting xarray object as input.")
273
+ if VELOCITY_DIMENSION not in xr_obj.dims:
274
+ raise ValueError("2D spectrum not available.")
99
275
  if isinstance(xr_obj, xr.Dataset):
100
276
  if variable not in xr_obj:
101
277
  raise ValueError(f"The dataset do not include {variable=}.")
@@ -229,7 +405,7 @@ def plot_raw_and_filtered_spectra(
229
405
  theoretical_average_velocity = ds["fall_velocity"]
230
406
  if "time" in theoretical_average_velocity.dims:
231
407
  theoretical_average_velocity = theoretical_average_velocity.mean(dim="time")
232
- if add_measured_average_velocity:
408
+ if add_measured_average_velocity and VELOCITY_DIMENSION in drop_number.dims:
233
409
  measured_average_velocity = get_drop_average_velocity(drop_number)
234
410
 
235
411
  # Define norm if not specified
@@ -248,7 +424,7 @@ def plot_raw_and_filtered_spectra(
248
424
  # Add velocities if asked
249
425
  if add_theoretical_average_velocity:
250
426
  theoretical_average_velocity.plot(ax=ax1, c="k", linestyle="dashed")
251
- if add_measured_average_velocity:
427
+ if add_measured_average_velocity and VELOCITY_DIMENSION in drop_number.dims:
252
428
  measured_average_velocity.plot(ax=ax1, c="k", linestyle="dotted")
253
429
 
254
430
  # Improve plot appearance
@@ -262,7 +438,7 @@ def plot_raw_and_filtered_spectra(
262
438
  # Add velocities if asked
263
439
  if add_theoretical_average_velocity:
264
440
  theoretical_average_velocity.plot(ax=ax2, c="k", linestyle="dashed", label="Theoretical velocity")
265
- if add_measured_average_velocity:
441
+ if add_measured_average_velocity and VELOCITY_DIMENSION in drop_number.dims:
266
442
  measured_average_velocity.plot(ax=ax2, c="k", linestyle="dotted", label="Measured average velocity")
267
443
 
268
444
  # Improve plot appearance
@@ -588,7 +764,7 @@ def compute_dense_lines(
588
764
  if len(other_dims) == 1:
589
765
  arr = da.transpose(*other_dims, x_dim).to_numpy()
590
766
  else:
591
- arr = da.stack({"sample": other_dims}).transpose("sample", x_dim).to_numpy()
767
+ arr = da.stack({"sample": other_dims}).transpose("sample", x_dim).to_numpy() # noqa PD013
592
768
 
593
769
  # Define y bins center
594
770
  y_center = (y_bins[0:-1] + y_bins[1:]) / 2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: disdrodb
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: disdrodb provides tools to download, standardize, share and analyze global disdrometer data.
5
5
  Author: Gionata Ghiggi
6
6
  Project-URL: homepage, https://github.com/ltelab/disdrodb
@@ -10,7 +10,7 @@ Project-URL: tracker, https://github.com/ltelab/disdrodb/issues
10
10
  Project-URL: documentation, https://disdrodb.readthedocs.io
11
11
  Project-URL: changelog, https://github.com/ltelab/disdrodb/blob/main/CHANGELOG.md
12
12
  Keywords: python,disdrometer,parsivel,drop size distribution
13
- Classifier: Development Status :: 1 - Planning
13
+ Classifier: Development Status :: 5 - Production/Stable
14
14
  Classifier: Intended Audience :: Developers
15
15
  Classifier: Programming Language :: Python :: 3
16
16
  Classifier: Operating System :: Unix