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
@@ -0,0 +1,81 @@
1
+ # -----------------------------------------------------------------------------.
2
+ # Copyright (c) 2021-2026 DISDRODB developers
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ # -----------------------------------------------------------------------------.
17
+ """Definition of pydantic validation custom class."""
18
+
19
+ from pydantic import BaseModel, ConfigDict, ValidationError
20
+
21
+
22
+ def format_validation_error(validation_error: Exception) -> str:
23
+ """Format a Pydantic ValidationError for better readability."""
24
+ if not isinstance(validation_error, ValidationError):
25
+ return str(validation_error)
26
+
27
+ def _shorten(value, max_len=200):
28
+ """Safely truncate long inputs."""
29
+ text = repr(value)
30
+ if len(text) > max_len:
31
+ return text[: max_len - 5] + " ...]"
32
+ return text
33
+
34
+ model_name_attr = getattr(validation_error, "title", None)
35
+ model_name = model_name_attr() if callable(model_name_attr) else model_name_attr or "UnknownModel"
36
+
37
+ formatted_errors = [f"Validation errors in {model_name}:"]
38
+
39
+ for err in validation_error.errors():
40
+ path = ".".join(str(loc) for loc in err["loc"]) or "<model root>"
41
+ msg = err["msg"]
42
+ err_type = err["type"]
43
+
44
+ # Handles both "Value error, ..." and "Value error: ..."
45
+ if msg.lower().startswith("value error"):
46
+ msg = msg.split(",", 1)[-1] if "," in msg else msg.split(":", 1)[-1]
47
+ msg = msg.strip()
48
+
49
+ # Model-level (root) errors (raise in after or before)
50
+ if path == "<model root>":
51
+ formatted = f" • {msg}"
52
+ elif err_type == "missing":
53
+ formatted = f" • Missing field '{path}': {msg}"
54
+ elif "input" in err:
55
+ formatted = f" • Field '{path}': {msg} (got: {_shorten(err['input'])})"
56
+ else:
57
+ formatted = f" • Field '{path}': {msg}"
58
+
59
+ formatted_errors.append(formatted)
60
+
61
+ return "\n".join(formatted_errors)
62
+
63
+
64
+ class CustomBaseModel(BaseModel):
65
+ """Custom pydantic BaseModel.
66
+
67
+ Forbid extra keys.
68
+ Hide URLs in error message.
69
+ Simplify error message.
70
+ """
71
+
72
+ model_config = ConfigDict(extra="forbid", hide_error_urls=True)
73
+
74
+ # Override the standard ValidationError print behavior
75
+ def __init__(self, **data):
76
+ try:
77
+ super().__init__(**data)
78
+ except ValidationError as e:
79
+ formatted = format_validation_error(e)
80
+ # Raise a new simplified exception
81
+ raise ValueError(formatted) from None
@@ -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
@@ -17,6 +15,7 @@
17
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
16
  # -----------------------------------------------------------------------------.
19
17
  """Utilities for DISDRODB processing routines."""
18
+
20
19
  import os
21
20
  import shutil
22
21
  import tempfile
@@ -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/utils/time.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
@@ -15,10 +15,10 @@
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
  # -----------------------------------------------------------------------------.
17
17
  """This module contains utilities related to the processing of temporal dataset."""
18
+
18
19
  import logging
19
20
  import numbers
20
21
  import re
21
- from typing import Optional
22
22
 
23
23
  import numpy as np
24
24
  import pandas as pd
@@ -233,12 +233,12 @@ def regularize_dataset(
233
233
  xr_obj,
234
234
  freq: str,
235
235
  time_dim: str = "time",
236
- method: Optional[str] = None,
236
+ method: str | None = None,
237
237
  fill_value=None,
238
238
  start_time=None,
239
239
  end_time=None,
240
240
  ):
241
- """Regularize a dataset across time dimension with uniform resolution.
241
+ """Regularize a xarray object across time dimension with uniform resolution.
242
242
 
243
243
  Parameters
244
244
  ----------
@@ -274,6 +274,7 @@ def regularize_dataset(
274
274
  start_time = start
275
275
  if end_time is None:
276
276
  end_time = end
277
+ xr_obj = xr_obj.sel({time_dim: slice(start_time, end_time)})
277
278
 
278
279
  # Define new time index
279
280
  new_time_index = pd.date_range(
@@ -483,6 +484,7 @@ def infer_sample_interval(ds, robust=False, verbose=False, logger=None):
483
484
  unexpected_intervals,
484
485
  unexpected_intervals_counts,
485
486
  unexpected_intervals_fractions,
487
+ strict=True,
486
488
  ):
487
489
  msg = f"--> Interval: {interval} seconds, Occurrence: {count}, Frequency: {fraction} %"
488
490
  log_info(logger=logger, msg=msg, verbose=verbose)
@@ -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
@@ -17,6 +15,7 @@
17
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
16
  # -----------------------------------------------------------------------------.
19
17
  """Warning utilities."""
18
+
20
19
  import warnings
21
20
  from contextlib import contextmanager
22
21
 
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
@@ -23,6 +21,7 @@ import os
23
21
  import xarray as xr
24
22
 
25
23
  from disdrodb.utils.attrs import get_attrs_dict, set_attrs, set_disdrodb_attrs
24
+ from disdrodb.utils.coords import add_dataset_crs_coords
26
25
  from disdrodb.utils.directories import create_directory, remove_if_exists
27
26
  from disdrodb.utils.encoding import get_encodings_dict, set_encodings
28
27
 
@@ -37,6 +36,9 @@ def finalize_product(ds, product=None) -> xr.Dataset:
37
36
  encodings_dict = get_encodings_dict()
38
37
  ds = set_encodings(ds, encodings_dict=encodings_dict)
39
38
 
39
+ # Add dataset CRS
40
+ ds = add_dataset_crs_coords(ds)
41
+
40
42
  # Add DISDRODB global attributes
41
43
  # - e.g. in generate_l2_radar it inherit from input dataset !
42
44
  if product is not None:
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
@@ -17,6 +15,7 @@
17
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
16
  # -----------------------------------------------------------------------------.
19
17
  """Xarray utilities."""
18
+
20
19
  import numpy as np
21
20
  import xarray as xr
22
21
  from xarray.core import dtypes
@@ -99,6 +98,35 @@ def xr_get_last_valid_idx(da_condition, dim, fill_value=None):
99
98
  return last_idx
100
99
 
101
100
 
101
+ def _np_remap_numeric_array(arr, remapping_dict, fill_value=np.nan):
102
+ # Define conditions
103
+ conditions = [arr == i for i in remapping_dict]
104
+ # Define choices corresponding to conditions
105
+ choices = remapping_dict.values()
106
+ # Apply np.select to transform the array
107
+ return np.select(conditions, choices, default=fill_value)
108
+
109
+
110
+ def _dask_remap_numeric_array(arr, remapping_dict, fill_value=np.nan):
111
+ import dask.array
112
+
113
+ return dask.array.map_blocks(_np_remap_numeric_array, arr, remapping_dict, fill_value, dtype=arr.dtype)
114
+
115
+
116
+ def remap_numeric_array(arr, remapping_dict, fill_value=np.nan):
117
+ """Remap the values of a numeric array."""
118
+ if hasattr(arr, "chunks"):
119
+ return _dask_remap_numeric_array(arr, remapping_dict, fill_value=fill_value)
120
+ return _np_remap_numeric_array(arr, remapping_dict, fill_value=fill_value)
121
+
122
+
123
+ def xr_remap_numeric_array(da, remapping_dict, fill_value=np.nan):
124
+ """Remap values of a xr.DataArray."""
125
+ output = da.copy()
126
+ output.data = remap_numeric_array(da.data, remapping_dict, fill_value=fill_value)
127
+ return output
128
+
129
+
102
130
  ####-------------------------------------------------------------------
103
131
  #### Unstacking dimension
104
132
 
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
@@ -15,8 +15,10 @@
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
  # -----------------------------------------------------------------------------.
17
17
  """DISDRODB Plotting Tools."""
18
+
18
19
  import matplotlib.pyplot as plt
19
20
  import numpy as np
21
+ import pandas as pd
20
22
  import psutil
21
23
  import xarray as xr
22
24
  from matplotlib.colors import LogNorm, Normalize
@@ -24,6 +26,7 @@ from matplotlib.gridspec import GridSpec
24
26
 
25
27
  from disdrodb.constants import DIAMETER_DIMENSION, VELOCITY_DIMENSION
26
28
  from disdrodb.l2.empirical_dsd import get_drop_average_velocity
29
+ from disdrodb.utils.time import ensure_sample_interval_in_seconds, regularize_dataset
27
30
 
28
31
  ####-------------------------------------------------------------------------------------------------------
29
32
  #### N(D) visualizations
@@ -45,44 +48,216 @@ def _single_plot_nd_distribution(drop_number_concentration, diameter, diameter_b
45
48
  return ax
46
49
 
47
50
 
48
- def plot_nd(ds, var="drop_number_concentration", cmap=None, norm=None):
51
+ def _check_has_diameter_dims(da):
52
+ if DIAMETER_DIMENSION not in da.dims:
53
+ raise ValueError(f"The DataArray must have dimension '{DIAMETER_DIMENSION}'.")
54
+ if "diameter_bin_width" not in da.coords:
55
+ raise ValueError("The DataArray must have coordinate 'diameter_bin_width'.")
56
+ return da
57
+
58
+
59
+ def _get_nd_variable(xr_obj, variable):
60
+ if not isinstance(xr_obj, (xr.Dataset, xr.DataArray)):
61
+ raise TypeError("Expecting xarray object as input.")
62
+ if isinstance(xr_obj, xr.Dataset):
63
+ if variable not in xr_obj:
64
+ raise ValueError(f"The dataset do not include {variable=}.")
65
+ xr_obj = xr_obj[variable]
66
+ if VELOCITY_DIMENSION in xr_obj.dims:
67
+ raise ValueError("N(D) must no have the velocity dimension.")
68
+ xr_obj = _check_has_diameter_dims(xr_obj)
69
+ return xr_obj
70
+
71
+
72
+ def plot_nd(xr_obj, variable="drop_number_concentration", cmap=None, norm=None):
49
73
  """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!")
74
+ da_nd = _get_nd_variable(xr_obj, variable=variable)
53
75
 
54
76
  # Check only time and diameter dimensions are specified
55
- if "time" not in ds.dims:
77
+ if "time" not in da_nd.dims:
56
78
  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"],
79
+ drop_number_concentration=da_nd.isel(velocity_method=0, missing_dims="ignore"),
80
+ diameter=xr_obj["diameter_bin_center"],
81
+ diameter_bin_width=xr_obj["diameter_bin_width"],
60
82
  )
61
83
  return ax
62
84
 
63
- # Select N(D)
64
- ds_var = ds[[var]].compute()
65
-
66
85
  # Regularize input
67
- ds_var = ds_var.disdrodb.regularize()
86
+ da_nd = da_nd.compute()
87
+ da_nd = da_nd.disdrodb.regularize()
68
88
 
69
89
  # Set 0 values to np.nan
70
- ds_var = ds_var.where(ds_var[var] > 0)
90
+ da_nd = da_nd.where(da_nd > 0)
71
91
 
72
92
  # Define cmap an norm
73
93
  if cmap is None:
74
94
  cmap = plt.get_cmap("Spectral_r").copy()
75
95
 
76
- vmin = ds_var[var].min().item()
96
+ vmin = da_nd.min().item()
77
97
  norm = LogNorm(vmin, None) if norm is None else norm
78
98
 
79
99
  # 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))")
100
+ cbar_kwargs = {"label": "N(D) [m-3 mm-1]"}
101
+ p = da_nd.plot.pcolormesh(x="time", norm=norm, cmap=cmap, extend="max", cbar_kwargs=cbar_kwargs)
102
+ p.axes.set_title("Drop number concentration N(D)")
82
103
  p.axes.set_ylabel("Drop diameter (mm)")
83
104
  return p
84
105
 
85
106
 
107
+ def plot_nd_quicklook(
108
+ ds,
109
+ # Plot layout
110
+ hours_per_slice=5,
111
+ max_rows=6,
112
+ aligned=True,
113
+ verbose=True,
114
+ # Spectrum options
115
+ variable="drop_number_concentration",
116
+ cbar_label="N(D) [# m⁻³ mm⁻¹]",
117
+ cmap=None,
118
+ norm=None,
119
+ d_lim=(0.3, 5),
120
+ # R options
121
+ add_r=True,
122
+ r_lim=(0.1, 50),
123
+ r_scale="log",
124
+ r_color="tab:blue",
125
+ r_linewidth=1.2,
126
+ ):
127
+ """Display multi-rows quicklook of N(D)."""
128
+ # Colormap & normalization
129
+ if cmap is None:
130
+ cmap = plt.get_cmap("Spectral_r").copy()
131
+ cmap.set_under("none")
132
+ if norm is None:
133
+ norm = LogNorm(vmin=1, vmax=10_000)
134
+
135
+ # ---------------------------
136
+ # Define temporal slices
137
+ # - Align to closest <hours_per_slice> time
138
+ # - For hours_per_slice=3 --> 00, 03, 06, ...
139
+ time = ds["time"].to_index()
140
+ t_start = time[0]
141
+ t_end = time[-1]
142
+ if aligned:
143
+ aligned_start = t_start.floor(f"{hours_per_slice}h")
144
+ aligned_end = t_end.ceil(f"{hours_per_slice}h")
145
+ # Create time bins
146
+ time_bins = pd.date_range(
147
+ start=aligned_start,
148
+ end=aligned_end,
149
+ freq=f"{hours_per_slice}h",
150
+ )
151
+ else:
152
+ # Create time bins
153
+ time_bins = pd.date_range(
154
+ start=t_start,
155
+ end=t_end + pd.Timedelta(f"{hours_per_slice}h"),
156
+ freq=f"{hours_per_slice}h",
157
+ )
158
+
159
+ n_total_slices = len(time_bins) - 1
160
+ n_slices = min(n_total_slices, max_rows)
161
+
162
+ # Print info on event quicklook
163
+ if verbose:
164
+ print("=== N(D) Event Quicklook ===")
165
+ print(f"Dataset time span : {t_start} → {t_end}")
166
+ print(f"Slice length : {hours_per_slice} h")
167
+ print(f"Plotted slices : {n_slices}/{n_total_slices}")
168
+ if n_total_slices > max_rows:
169
+ last_plotted_end = time_bins[max_rows]
170
+ print(f"Unplotted period : {last_plotted_end} → {aligned_end}")
171
+
172
+ # Regularize dataset to match bin start_time and end_time
173
+ sample_interval = ensure_sample_interval_in_seconds(ds["sample_interval"].to_numpy()).item()
174
+ ds = regularize_dataset(ds, freq=f"{sample_interval}s", start_time=time_bins[0], end_time=time_bins[-1])
175
+
176
+ # Define figure
177
+ fig, axes = plt.subplots(
178
+ nrows=n_slices,
179
+ ncols=1,
180
+ figsize=(14, 2.8 * n_slices),
181
+ sharex=False,
182
+ constrained_layout=True,
183
+ )
184
+
185
+ if n_slices == 1:
186
+ axes = [axes]
187
+
188
+ # Plot each slice
189
+ for i in range(n_slices):
190
+ # Extract dataset slice
191
+ t0 = time_bins[i]
192
+ t1 = time_bins[i + 1]
193
+ ds_slice = ds.sel(time=slice(t0, t1))
194
+ da_nd = ds_slice[variable]
195
+
196
+ # Define plot ax
197
+ ax = axes[i]
198
+
199
+ # Plot N(D)
200
+ p = da_nd.plot.pcolormesh(
201
+ ax=ax,
202
+ x="time",
203
+ y="diameter_bin_center",
204
+ norm=norm,
205
+ cmap=cmap,
206
+ shading="auto",
207
+ add_colorbar=False,
208
+ )
209
+
210
+ # Overlay Dm
211
+ ds_slice["Dm"].plot(
212
+ ax=ax,
213
+ x="time",
214
+ color="black",
215
+ linestyle="--",
216
+ linewidth=1.2,
217
+ label="Dm",
218
+ )
219
+
220
+ # Add axis labels and title
221
+ ax.set_xlabel("")
222
+ ax.set_ylabel("Diameter [mm]")
223
+ ax.set_title(f"{t0:%H:%M} - {t1:%H:%M} UTC")
224
+
225
+ if i == 0:
226
+ ax.legend(loc="upper right")
227
+
228
+ # Add rain rate on secondary axis
229
+ if add_r:
230
+ ax_r = ax.twinx()
231
+ ds_slice["R"].plot(
232
+ ax=ax_r,
233
+ x="time",
234
+ color=r_color,
235
+ linewidth=r_linewidth,
236
+ label="R",
237
+ )
238
+ ax_r.set_ylim(r_lim)
239
+ ax_r.set_yscale(r_scale)
240
+ ax_r.set_ylabel("Rain rate [mm h$^{-1}$]", color="tab:blue")
241
+ ax_r.tick_params(axis="y", labelcolor="tab:blue")
242
+ ax_r.set_title("")
243
+
244
+ ax.set_ylim(*d_lim)
245
+
246
+ axes[-1].set_xlabel("Time (UTC)")
247
+ # ---------------------------
248
+ # Shared colorbar
249
+ # ---------------------------
250
+ cbar = fig.colorbar(
251
+ p,
252
+ ax=axes,
253
+ orientation="horizontal",
254
+ pad=0.02,
255
+ fraction=0.03,
256
+ extend="max",
257
+ )
258
+ cbar.set_label(cbar_label)
259
+
260
+
86
261
  ####-------------------------------------------------------------------------------------------------------
87
262
  #### Spectra visualizations
88
263
 
@@ -590,7 +765,7 @@ def compute_dense_lines(
590
765
  if len(other_dims) == 1:
591
766
  arr = da.transpose(*other_dims, x_dim).to_numpy()
592
767
  else:
593
- arr = da.stack({"sample": other_dims}).transpose("sample", x_dim).to_numpy()
768
+ arr = da.stack({"sample": other_dims}).transpose("sample", x_dim).to_numpy() # noqa PD013
594
769
 
595
770
  # Define y bins center
596
771
  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.1
3
+ Version: 0.4.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,13 +10,13 @@ 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
17
17
  Classifier: Operating System :: MacOS :: MacOS X
18
18
  Classifier: Operating System :: Microsoft :: Windows
19
- Requires-Python: >=3.9
19
+ Requires-Python: >=3.11
20
20
  Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
22
  Requires-Dist: click
@@ -34,6 +34,7 @@ Requires-Dist: scipy
34
34
  Requires-Dist: dask[distributed]
35
35
  Requires-Dist: xarray
36
36
  Requires-Dist: bottleneck
37
+ Requires-Dist: flox
37
38
  Requires-Dist: matplotlib
38
39
  Provides-Extra: dev
39
40
  Requires-Dist: jupyter; extra == "dev"
@@ -55,7 +56,7 @@ Dynamic: license-file
55
56
  | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
56
57
  | Deployment | [![PyPI](https://badge.fury.io/py/disdrodb.svg?style=flat)](https://pypi.org/project/disdrodb/) [![Conda](https://img.shields.io/conda/vn/conda-forge/disdrodb.svg?logo=conda-forge&logoColor=white&style=flat)](https://anaconda.org/conda-forge/disdrodb) |
57
58
  | Activity | [![PyPI Downloads](https://img.shields.io/pypi/dm/disdrodb.svg?label=PyPI%20downloads&style=flat)](https://pypi.org/project/disdrodb/) [![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/disdrodb.svg?label=Conda%20downloads&style=flat)](https://anaconda.org/conda-forge/disdrodb) |
58
- | Python Versions | [![Python Versions](https://img.shields.io/badge/Python-3.10%20%203.11%20%203.12-blue?style=flat)](https://www.python.org/downloads/) |
59
+ | Python Versions | [![Python Versions](https://img.shields.io/badge/Python-3.11%20%203.12%20%203.13%20%203.14-blue?style=flat)](https://www.python.org/downloads/) |
59
60
  | Supported Systems | [![Linux](https://img.shields.io/github/actions/workflow/status/ltelab/disdrodb/.github/workflows/tests.yml?label=Linux&style=flat)](https://github.com/ltelab/disdrodb/actions/workflows/tests.yml) [![macOS](https://img.shields.io/github/actions/workflow/status/ltelab/disdrodb/.github/workflows/tests.yml?label=macOS&style=flat)](https://github.com/ltelab/disdrodb/actions/workflows/tests.yml) [![Windows](https://img.shields.io/github/actions/workflow/status/ltelab/disdrodb/.github/workflows/tests_windows.yml?label=Windows&style=flat)](https://github.com/ltelab/disdrodb/actions/workflows/tests_windows.yml) |
60
61
  | Project Status | [![Project Status](https://www.repostatus.org/badges/latest/active.svg?style=flat)](https://www.repostatus.org/#active) |
61
62
  | Build Status | [![Tests](https://github.com/ltelab/disdrodb/actions/workflows/tests.yml/badge.svg?style=flat)](https://github.com/ltelab/disdrodb/actions/workflows/tests.yml) [![Lint](https://github.com/ltelab/disdrodb/actions/workflows/lint.yml/badge.svg?style=flat)](https://github.com/ltelab/disdrodb/actions/workflows/lint.yml) [![Docs](https://readthedocs.org/projects/disdrodb/badge/?version=latest&style=flat)](https://disdrodb.readthedocs.io/en/latest/) |