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
disdrodb/l1/processing.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
@@ -18,35 +18,22 @@
18
18
 
19
19
  import xarray as xr
20
20
 
21
- from disdrodb.constants import DIAMETER_DIMENSION, VELOCITY_DIMENSION
22
- from disdrodb.l1.fall_velocity import get_raindrop_fall_velocity_from_ds
23
- from disdrodb.l1.filters import define_raindrop_spectrum_mask, filter_diameter_bins, filter_velocity_bins
21
+ from disdrodb.constants import DIAMETER_DIMENSION, METEOROLOGICAL_VARIABLES, VELOCITY_DIMENSION
22
+ from disdrodb.l1.classification import (
23
+ classify_raw_spectrum,
24
+ get_temperature,
25
+ map_precip_flag_to_precipitation_type,
26
+ )
24
27
  from disdrodb.l1.resampling import add_sample_interval
25
28
  from disdrodb.l1_env.routines import load_env_dataset
26
- from disdrodb.l2.empirical_dsd import ( # TODO: maybe move out of L2
27
- add_bins_metrics,
28
- get_min_max_diameter,
29
- )
29
+ from disdrodb.utils.manipulations import filter_diameter_bins
30
30
  from disdrodb.utils.time import ensure_sample_interval_in_seconds, infer_sample_interval
31
31
  from disdrodb.utils.writer import finalize_product
32
32
 
33
33
 
34
34
  def generate_l1(
35
35
  ds,
36
- # Fall velocity option
37
- fall_velocity_model="Beard1976",
38
- # Diameter-Velocity Filtering Options
39
- minimum_diameter=0,
40
- maximum_diameter=10,
41
- minimum_velocity=0,
42
- maximum_velocity=12,
43
- above_velocity_fraction=0.5,
44
- above_velocity_tolerance=None,
45
- below_velocity_fraction=0.5,
46
- below_velocity_tolerance=None,
47
- small_diameter_threshold=1, # 2
48
- small_velocity_threshold=2.5, # 3
49
- maintain_smallest_drops=True,
36
+ **kwargs, # noqa
50
37
  ):
51
38
  """Generate DISDRODB L1 Dataset from DISDRODB L0C Dataset.
52
39
 
@@ -54,31 +41,6 @@ def generate_l1(
54
41
  ----------
55
42
  ds : xarray.Dataset
56
43
  DISDRODB L0C dataset.
57
- fall_velocity_model : str, optional
58
- Method to compute fall velocity.
59
- The default method is ``"Beard1976"``.
60
- minimum_diameter : float, optional
61
- Minimum diameter for filtering. The default value is 0 mm.
62
- maximum_diameter : float, optional
63
- Maximum diameter for filtering. The default value is 10 mm.
64
- minimum_velocity : float, optional
65
- Minimum velocity for filtering. The default value is 0 m/s.
66
- maximum_velocity : float, optional
67
- Maximum velocity for filtering. The default value is 12 m/s.
68
- above_velocity_fraction : float, optional
69
- Fraction of drops above velocity threshold. The default value is 0.5.
70
- above_velocity_tolerance : float or None, optional
71
- Tolerance for above velocity filtering. The default value is ``None``.
72
- below_velocity_fraction : float, optional
73
- Fraction of drops below velocity threshold. The default value is 0.5.
74
- below_velocity_tolerance : float or None, optional
75
- Tolerance for below velocity filtering. The default value is ``None``.
76
- small_diameter_threshold : float, optional
77
- Threshold for small diameter drops. The default value is 1.
78
- small_velocity_threshold : float, optional
79
- Threshold for small velocity drops. The default value is 2.5.
80
- maintain_smallest_drops : bool, optional
81
- Whether to maintain the smallest drops. The default value is ``True``.
82
44
 
83
45
  Returns
84
46
  -------
@@ -95,7 +57,7 @@ def generate_l1(
95
57
  # - If not present, don't drop Parsivels first two bins
96
58
  sensor_name = attrs.get("sensor_name", "")
97
59
 
98
- # ---------------------------------------------------------------------------
60
+ # --------------------------------------------------------------------------
99
61
  # Retrieve sample interval
100
62
  # --> sample_interval is a coordinate of L0C products
101
63
  if "sample_interval" in ds:
@@ -104,14 +66,14 @@ def generate_l1(
104
66
  # This line is not called in the DISDRODB processing chain !
105
67
  sample_interval = infer_sample_interval(ds, verbose=False)
106
68
 
107
- # ---------------------------------------------------------------------------
69
+ # --------------------------------------------------------------------------
108
70
  # Retrieve ENV dataset or take defaults
109
71
  # - Used only for Beard fall velocity currently !
110
72
  # - It checks and includes default geolocation if missing
111
73
  # - For mobile disdrometer, infill missing geolocation with backward and forward filling
112
74
  ds_env = load_env_dataset(ds)
113
75
 
114
- # ---------------------------------------------------------------------------
76
+ # --------------------------------------------------------------------------
115
77
  # Initialize L1 dataset
116
78
  ds_l1 = xr.Dataset()
117
79
 
@@ -122,77 +84,45 @@ def generate_l1(
122
84
  ds_l1 = add_sample_interval(ds_l1, sample_interval=sample_interval)
123
85
 
124
86
  # Add optional variables to L1 dataset
125
- optional_variables = ["time_qc", "qc_resampling"]
87
+ optional_variables = ["qc_time", "qc_resampling", *METEOROLOGICAL_VARIABLES]
126
88
  for var in optional_variables:
127
89
  if var in ds:
128
90
  ds_l1[var] = ds[var]
129
91
 
130
- # -------------------------------------------------------------------------------------------
92
+ # --------------------------------------------------------------------------
131
93
  # Filter dataset by diameter and velocity bins
132
94
  if sensor_name in ["PARSIVEL", "PARSIVEL2"]:
133
95
  # - Remove first two bins because never reports data !
96
+ # - Could be removed also in L2E, but we save disk space here
134
97
  # - If not removed, can alter e.g. L2M model fitting
135
98
  ds_l1 = filter_diameter_bins(ds=ds_l1, minimum_diameter=0.2495) # it includes the 0.2495-0.3745 bin
136
99
 
137
- # - Filter diameter bins
138
- ds_l1 = filter_diameter_bins(ds=ds_l1, minimum_diameter=minimum_diameter, maximum_diameter=maximum_diameter)
139
- # - Filter velocity bins
140
- if has_velocity_dimension:
141
- ds_l1 = filter_velocity_bins(ds=ds_l1, minimum_velocity=minimum_velocity, maximum_velocity=maximum_velocity)
142
-
143
- # -------------------------------------------------------------------------------------------
144
- # Compute fall velocity
145
- ds_l1["fall_velocity"] = get_raindrop_fall_velocity_from_ds(ds=ds_l1, ds_env=ds_env, model=fall_velocity_model)
146
-
147
- # -------------------------------------------------------------------------------------------
148
- # Define filtering mask according to fall velocity
100
+ # --------------------------------------------------------------------------
101
+ # If (diameter, velocity) spectrum is available, run hydrometeor classification
149
102
  if has_velocity_dimension:
150
- mask = define_raindrop_spectrum_mask(
151
- drop_number=ds_l1["raw_drop_number"],
152
- fall_velocity=ds_l1["fall_velocity"],
153
- above_velocity_fraction=above_velocity_fraction,
154
- above_velocity_tolerance=above_velocity_tolerance,
155
- below_velocity_fraction=below_velocity_fraction,
156
- below_velocity_tolerance=below_velocity_tolerance,
157
- small_diameter_threshold=small_diameter_threshold,
158
- small_velocity_threshold=small_velocity_threshold,
159
- maintain_smallest_drops=maintain_smallest_drops,
103
+ temperature, snow_temperature_upper_limit = get_temperature(ds)
104
+ temperature = temperature.compute() if temperature is not None else None
105
+ ds_hc = classify_raw_spectrum(
106
+ ds=ds_l1,
107
+ ds_env=ds_env,
108
+ sensor_name=sensor_name,
109
+ sample_interval=sample_interval,
110
+ temperature=temperature,
111
+ rain_temperature_lower_limit=-5,
112
+ snow_temperature_upper_limit=snow_temperature_upper_limit,
160
113
  )
114
+ ds_l1.update(ds_hc)
161
115
 
162
- # -------------------------------------------------------------------------------------------
163
- # Retrieve drop number and drop_counts arrays
164
- if has_velocity_dimension:
165
- drop_number = ds_l1["raw_drop_number"].where(mask, 0) # 2D (diameter, velocity)
166
- drop_counts = drop_number.sum(dim=VELOCITY_DIMENSION) # 1D (diameter)
167
- drop_counts_raw = ds_l1["raw_drop_number"].sum(dim=VELOCITY_DIMENSION) # 1D (diameter)
116
+ # Otherwise, if no 2D spectrum, do nothing (temporary)
117
+ # --> Specialized QC for RD-80 or ODM-470 not yet implemented
168
118
  else:
169
- drop_number = ds_l1["raw_drop_number"] # 1D (diameter)
170
- drop_counts = ds_l1["raw_drop_number"] # 1D (diameter)
171
- drop_counts_raw = ds_l1["raw_drop_number"]
172
-
173
- # Add drop number and drop_counts
174
- ds_l1["drop_number"] = drop_number
175
- ds_l1["drop_counts"] = drop_counts
176
-
177
- # -------------------------------------------------------------------------------------------
178
- # Compute minimum and max drop diameter observed
179
- min_drop_diameter, max_drop_diameter = get_min_max_diameter(drop_counts)
180
-
181
- # Add drop statistics
182
- ds_l1["Dmin"] = min_drop_diameter
183
- ds_l1["Dmax"] = max_drop_diameter
184
- ds_l1["N"] = drop_counts.sum(dim=DIAMETER_DIMENSION)
185
- ds_l1["Nraw"] = drop_counts_raw.sum(dim=DIAMETER_DIMENSION)
186
- ds_l1["Nremoved"] = ds_l1["Nraw"] - ds_l1["N"]
187
-
188
- # Add bins statistics
189
- ds_l1 = add_bins_metrics(ds_l1)
190
-
191
- # -------------------------------------------------------------------------------------------
192
- # Add quality flags
193
- # TODO: snow_flags, insects_flag, ...
119
+ # If OceanRain ODM470 data, translate precip_flag to precipitation_type
120
+ if sensor_name == "ODM470" and "precip_flag" in ds:
121
+ ds_l1["precipitation_type"] = map_precip_flag_to_precipitation_type(ds["precip_flag"])
122
+ ds_l1["n_particles"] = ds_l1["raw_drop_number"].sum(dim=DIAMETER_DIMENSION)
123
+ pass
194
124
 
195
- #### ----------------------------------------------------------------------------.
125
+ #### ----------------------------------------------------------------------.
196
126
  #### Finalize dataset
197
127
  # Add global attributes
198
128
  ds_l1.attrs = attrs
disdrodb/l1/resampling.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,6 +15,7 @@
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
  # -----------------------------------------------------------------------------.
17
17
  """Utilities for temporal resampling."""
18
+
18
19
  import numpy as np
19
20
  import pandas as pd
20
21
  import xarray as xr
@@ -170,6 +171,9 @@ def resample_dataset(ds, sample_interval, temporal_resolution):
170
171
  - The function updates the dataset attributes and the sample_interval coordinate.
171
172
 
172
173
  """
174
+ from disdrodb.constants import METEOROLOGICAL_VARIABLES
175
+ from disdrodb.l1.classification import TEMPERATURE_VARIABLES
176
+
173
177
  # --------------------------------------------------------------------------.
174
178
  # Ensure sample interval in seconds
175
179
  sample_interval = int(ensure_sample_interval_in_seconds(sample_interval))
@@ -244,6 +248,7 @@ def resample_dataset(ds, sample_interval, temporal_resolution):
244
248
 
245
249
  # Retrieve variables to average/sum
246
250
  # - ATTENTION: it will not resample non-dimensional time coordinates of the dataset !
251
+ # - precip_flag used for OceanRain ODM470 data
247
252
  var_to_average = ["fall_velocity"]
248
253
  var_to_cumulate = [
249
254
  "raw_drop_number",
@@ -255,8 +260,9 @@ def resample_dataset(ds, sample_interval, temporal_resolution):
255
260
  "Nremoved",
256
261
  "qc_resampling",
257
262
  ]
258
- var_to_min = ["Dmin"]
259
- var_to_max = ["Dmax", "time_qc"]
263
+ var_to_min = ["Dmin", *TEMPERATURE_VARIABLES]
264
+ met_vars = set(METEOROLOGICAL_VARIABLES) - set(TEMPERATURE_VARIABLES) # exclude air_temperature variable
265
+ var_to_max = ["Dmax", "qc_time", "precip_flag", *met_vars]
260
266
 
261
267
  # Retrieve available variables
262
268
  var_to_average = [var for var in var_to_average if var in ds]
@@ -305,6 +311,10 @@ def resample_dataset(ds, sample_interval, temporal_resolution):
305
311
  # Add attributes
306
312
  ds_resampled.attrs = attrs
307
313
 
314
+ # Add back crs coordinate
315
+ if "crs" in ds:
316
+ ds_resampled = ds_resampled.assign_coords({"crs": ds["crs"]})
317
+
308
318
  # Add accumulation_interval as new sample_interval coordinate
309
319
  ds_resampled = add_sample_interval(ds_resampled, sample_interval=accumulation_interval)
310
320
  return ds_resampled
@@ -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
@@ -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,6 +15,7 @@
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
  # -----------------------------------------------------------------------------.
17
17
  """Core functions for DISDRODB ENV production."""
18
+
18
19
  import numpy as np
19
20
  import xarray as xr
20
21
 
@@ -30,15 +31,15 @@ DEFAULT_GEOLOCATION = {
30
31
 
31
32
 
32
33
  def get_default_environment_dataset():
33
- """Define defaults values for the ENV dataset."""
34
+ """Set International Standard Atmosphere values for the default ENV dataset."""
34
35
  ds_env = xr.Dataset()
35
- ds_env["sea_level_air_pressure"] = 101_325 # Pa
36
+ ds_env["sea_level_air_pressure"] = 101_325 # Pa # sea level
36
37
  ds_env["gas_constant_dry_air"] = 287.04 # J kg⁻¹ K⁻¹
37
- ds_env["lapse_rate"] = 0.0065 # K m⁻¹
38
+ ds_env["lapse_rate"] = 0.0065 # K m⁻¹ (6.5 deg/km)
38
39
  ds_env["relative_humidity"] = 0.95 # 0-1 !
39
- ds_env["temperature"] = 20 + 273.15 # K
40
+ ds_env["temperature"] = 15 + 273.15 # K
40
41
  ds_env["water_density"] = 1000 # kg m⁻³ (T == 10 --> 999.7, T == 20 --> 998.2)
41
- # get_water_density(temperature=temperature, air_pressure=air_pressure
42
+ # air density = 1.225 kg m⁻³ (if RH = 0) using retrieve_air_density(ds_env)
42
43
  return ds_env
43
44
 
44
45
 
disdrodb/l2/__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
@@ -15,6 +15,7 @@
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
  # -----------------------------------------------------------------------------.
17
17
  """Module for DISDRODB L2 production."""
18
+
18
19
  from disdrodb.l2.processing import generate_l2_radar, generate_l2e, generate_l2m
19
20
 
20
21
  __all__ = [
@@ -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
@@ -20,11 +20,13 @@ The functions of this module expects xarray.DataArray objects as input.
20
20
  Zeros and NaN values input arrays are correctly processed.
21
21
  Infinite values should be removed beforehand or otherwise are propagated throughout the computations.
22
22
  """
23
+
23
24
  import numpy as np
24
25
  import xarray as xr
25
26
 
26
27
  from disdrodb.api.checks import check_sensor_name
27
28
  from disdrodb.constants import DIAMETER_DIMENSION, VELOCITY_DIMENSION
29
+ from disdrodb.utils.time import ensure_sample_interval_in_seconds
28
30
  from disdrodb.utils.xarray import (
29
31
  remove_diameter_coordinates,
30
32
  remove_velocity_coordinates,
@@ -208,8 +210,26 @@ def add_bins_metrics(ds):
208
210
  return ds
209
211
 
210
212
 
211
- ####-------------------------------------------------------------------------------------------------------------------.
212
- #### DSD Spectrum, Concentration, Moments
213
+ ####------------------------------------------------------------------------------------------.
214
+ #### Sampling area and measurement interval
215
+ def get_sampling_area(sensor_name):
216
+ """Return the sampling area in m2 of the disdrometer."""
217
+ check_sensor_name(sensor_name)
218
+ area_dict = {
219
+ "PARSIVEL": 0.0054, # 54 cm2
220
+ "PARSIVEL2": 0.0054, # 54 cm2
221
+ "LPM": 0.0045, # 45 cm2
222
+ "LPM_V0": 0.0045, # 45 cm2
223
+ "ODM470": 0.00264, # 26.4 cm2
224
+ "PWS100": 0.004, # 40 cm2
225
+ "RD80": 0.005, # 50 cm2
226
+ "SWS250": 0.006504, # 65.04 cm2 (Ricardo Reinoso Rondinel, personal communication)
227
+ }
228
+ # SWS250
229
+ # - Table 29 of the manual that the sample volume is 400cm3, path length?
230
+ # - Distance between the end of the hood heaters is 291 mm.
231
+ # - Adding a factor of 1.5 for better representation of the Tx-Rx distance: L= 436 mm.
232
+ return area_dict[sensor_name]
213
233
 
214
234
 
215
235
  def get_effective_sampling_area(sensor_name, diameter):
@@ -227,26 +247,22 @@ def get_effective_sampling_area(sensor_name, diameter):
227
247
  B = 30 / 1000 # Width of the Parsivel beam in m (30mm)
228
248
  sampling_area = L * (B - diameter / 2) # d_eq
229
249
  return sampling_area
230
- if sensor_name in ["LPM", "LPM_V0"]:
231
- # Calculate sampling area for each diameter bin (S_i)
232
- # L = 228 / 1000 # Length of the beam in m (228 mm)
233
- # B = 20 / 1000 # Width of the beam in m (20 mm)
234
- # sampling_area = L * (B - diameter / 2)
235
- sampling_area = 0.0045 # m2
236
- return sampling_area
250
+ return get_sampling_area(sensor_name)
251
+
252
+
253
+ def get_effective_sampling_interval(ds, sensor_name):
254
+ """Return the effective sample interval in seconds of the disdrometer."""
255
+ sample_interval = ensure_sample_interval_in_seconds(ds["sample_interval"]) # s
256
+ # Adapt sample interval for sensor duty cycle
237
257
  if sensor_name == "PWS100":
238
- sampling_area = 0.004 # m2
239
- return sampling_area
240
- if sensor_name == "RD80":
241
- sampling_area = 0.005 # m2
242
- return sampling_area
243
- if sensor_name == "SWS250":
244
- # Table 29 of the manual that the sample volume is 400cm3, path length?
245
- # Distance between the end of the hood heaters is 291 mm.
246
- # Adding a factor of 1.5 for better representation of the Tx-Rx distance: L= 436 mm.
247
- sampling_area = 0.0091 # m2 # 0.006504 m2 maybe?
248
- return sampling_area
249
- raise NotImplementedError(f"Effective sampling area for {sensor_name} must yet to be specified in the software.")
258
+ # PWS100 has a duty cycle of 9s on, 1s off
259
+ # - 9 seconds out of 10 are used for counting drops, 1 second is used to process data
260
+ sample_interval = sample_interval * (9 / 10)
261
+ return sample_interval
262
+
263
+
264
+ ####-------------------------------------------------------------------------------------------------------------------.
265
+ #### DSD Spectrum, Concentration, Moments
250
266
 
251
267
 
252
268
  def get_bin_dimensions(xr_obj):
@@ -307,15 +323,19 @@ def get_drop_number_concentration(drop_number, velocity, diameter_bin_width, sam
307
323
  # Ensure velocity is 2D (diameter, velocity)
308
324
  velocity = xr.ones_like(drop_number) * velocity
309
325
 
326
+ # Create a safe ratio: drop_number / velocity, but 0 where velocity is 0 or NaN
327
+ safe_ratio = drop_number / velocity
328
+ safe_ratio = safe_ratio.where((velocity != 0) & (~np.isnan(velocity)), 0)
329
+
310
330
  # Compute drop number concentration
311
331
  # - For disdrometer with velocity bins
312
332
  if VELOCITY_DIMENSION in drop_number.dims:
313
- drop_number_concentration = (drop_number / velocity).sum(dim=VELOCITY_DIMENSION, skipna=False) / (
333
+ drop_number_concentration = safe_ratio.sum(dim=VELOCITY_DIMENSION, skipna=False) / (
314
334
  sampling_area * diameter_bin_width * sample_interval
315
335
  )
316
336
  # - For impact disdrometers
317
337
  else:
318
- drop_number_concentration = (drop_number / velocity) / (sampling_area * diameter_bin_width * sample_interval)
338
+ drop_number_concentration = safe_ratio / (sampling_area * diameter_bin_width * sample_interval)
319
339
  return drop_number_concentration
320
340
 
321
341
 
@@ -1669,8 +1689,7 @@ def get_kinetic_energy_variables_from_drop_number(
1669
1689
  KEF = TKE / sample_interval * 3600
1670
1690
 
1671
1691
  # Compute Kinetic Energy per Rainfall Depth [J/m2/mm]
1672
- KED = KEF / R
1673
- KED = xr.where(R == 0, 0, KED) # Ensure KED is 0 when R (and thus drop number is 0)
1692
+ KED = xr.where(R == 0, 0, KEF / R) # Ensure KED is 0 when R (and thus drop number is 0)
1674
1693
 
1675
1694
  # Create dataset
1676
1695
  dict_vars = {
@@ -1735,6 +1754,10 @@ def compute_integral_parameters(
1735
1754
  - KED: Kinetic Energy per unit rainfall Depth [J·m⁻²·mm⁻¹].
1736
1755
  - KEF: Kinetic Energy Flux [J·m⁻²·h⁻¹].
1737
1756
  """
1757
+ # Ensure velocity does not contain NaN
1758
+ # --> e.g. when D > 10 mm --> Replace to 0
1759
+ velocity = velocity.fillna(0)
1760
+
1738
1761
  # Initialize dataset
1739
1762
  ds = xr.Dataset()
1740
1763
 
@@ -1764,15 +1787,15 @@ def compute_integral_parameters(
1764
1787
  moment=moment,
1765
1788
  )
1766
1789
 
1767
- # Compute Liquid Water Content (LWC) (W) [g/m3]
1768
- # ds["W"] = get_liquid_water_content(
1790
+ # Compute Liquid Water Content (LWC) [g/m3]
1791
+ # ds["LWC"] = get_liquid_water_content(
1769
1792
  # drop_number_concentration=drop_number_concentration,
1770
1793
  # diameter=diameter,
1771
1794
  # diameter_bin_width=diameter_bin_width,
1772
1795
  # water_density=water_density,
1773
1796
  # )
1774
1797
 
1775
- ds["W"] = get_liquid_water_content_from_moments(moment_3=ds["M3"], water_density=water_density)
1798
+ ds["LWC"] = get_liquid_water_content_from_moments(moment_3=ds["M3"], water_density=water_density)
1776
1799
 
1777
1800
  # Compute reflectivity in dBZ
1778
1801
  ds["Z"] = get_equivalent_reflectivity_factor(
@@ -1869,9 +1892,13 @@ def compute_spectrum_parameters(
1869
1892
  Dataset containing the following spectrum:
1870
1893
  - KE_spectrum : Kinetic Energy spectrum [J/m2/mm]
1871
1894
  - R_spectrum : Rain Rate spectrum [mm/h/mm]
1872
- - W_spectrum : Mass spectrum [g/m3/mm]
1895
+ - LWC_spectrum : Mass spectrum [g/m3/mm]
1873
1896
  - Z_spectrum : Reflectivity spectrum [dBZ of mm6/m3/mm]
1874
1897
  """
1898
+ # Ensure velocity does not contain NaN
1899
+ # --> e.g. when D > 10 mm --> Replace to 0
1900
+ velocity = velocity.fillna(0)
1901
+
1875
1902
  # Initialize dataset
1876
1903
  ds = xr.Dataset()
1877
1904
  ds["KE_spectrum"] = get_kinetic_energy_spectrum(
@@ -1882,7 +1909,7 @@ def compute_spectrum_parameters(
1882
1909
  water_density=water_density,
1883
1910
  )
1884
1911
  ds["R_spectrum"] = get_rain_rate_spectrum(drop_number_concentration, velocity=velocity, diameter=diameter)
1885
- ds["W_spectrum"] = get_liquid_water_spectrum(
1912
+ ds["LWC_spectrum"] = get_liquid_water_spectrum(
1886
1913
  drop_number_concentration,
1887
1914
  diameter=diameter,
1888
1915
  water_density=water_density,