disdrodb 0.2.1__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 (302) 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 +9 -9
  6. disdrodb/api/checks.py +1 -3
  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 +9 -8
  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 +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 +46 -0
  75. disdrodb/fall_velocity/graupel.py +483 -0
  76. disdrodb/fall_velocity/hail.py +287 -0
  77. disdrodb/{l1/fall_velocity.py → fall_velocity/rain.py} +264 -44
  78. disdrodb/issue/__init__.py +1 -3
  79. disdrodb/issue/checks.py +1 -3
  80. disdrodb/issue/reader.py +1 -3
  81. disdrodb/issue/writer.py +1 -3
  82. disdrodb/l0/__init__.py +1 -1
  83. disdrodb/l0/check_configs.py +25 -16
  84. disdrodb/l0/check_standards.py +1 -3
  85. disdrodb/l0/configs/ODM470/bins_diameter.yml +643 -0
  86. disdrodb/l0/configs/ODM470/bins_velocity.yml +0 -0
  87. disdrodb/l0/configs/ODM470/l0a_encodings.yml +11 -0
  88. disdrodb/l0/configs/ODM470/l0b_cf_attrs.yml +46 -0
  89. disdrodb/l0/configs/ODM470/l0b_encodings.yml +106 -0
  90. disdrodb/l0/configs/ODM470/raw_data_format.yml +111 -0
  91. disdrodb/l0/configs/PARSIVEL/l0b_cf_attrs.yml +1 -1
  92. disdrodb/l0/l0_reader.py +1 -3
  93. disdrodb/l0/l0a_processing.py +1 -3
  94. disdrodb/l0/l0b_nc_processing.py +2 -4
  95. disdrodb/l0/l0b_processing.py +1 -3
  96. disdrodb/l0/l0c_processing.py +27 -11
  97. disdrodb/l0/readers/LPM/ARM/ARM_LPM.py +1 -1
  98. disdrodb/l0/readers/LPM/AUSTRALIA/MELBOURNE_2007_LPM.py +1 -1
  99. disdrodb/l0/readers/LPM/BRAZIL/CHUVA_LPM.py +1 -1
  100. disdrodb/l0/readers/LPM/BRAZIL/GOAMAZON_LPM.py +1 -1
  101. disdrodb/l0/readers/LPM/GERMANY/DWD.py +190 -12
  102. disdrodb/l0/readers/LPM/ITALY/GID_LPM.py +47 -6
  103. disdrodb/l0/readers/LPM/ITALY/GID_LPM_PI.py +1 -1
  104. disdrodb/l0/readers/LPM/ITALY/GID_LPM_T.py +5 -2
  105. disdrodb/l0/readers/LPM/ITALY/GID_LPM_W.py +1 -3
  106. disdrodb/l0/readers/LPM/KIT/CHWALA.py +1 -3
  107. disdrodb/l0/readers/LPM/NETHERLANDS/DELFT_LPM_NC.py +1 -1
  108. disdrodb/l0/readers/LPM/NETHERLANDS/DELFT_RWANDA_LPM_NC.py +1 -1
  109. disdrodb/l0/readers/LPM/NORWAY/HAUKELISETER_LPM.py +1 -3
  110. disdrodb/l0/readers/LPM/NORWAY/NMBU_LPM.py +1 -3
  111. disdrodb/l0/readers/LPM/SLOVENIA/ARSO.py +1 -3
  112. disdrodb/l0/readers/LPM/SLOVENIA/UL.py +1 -3
  113. disdrodb/l0/readers/LPM/SWITZERLAND/INNERERIZ_LPM.py +1 -3
  114. disdrodb/l0/readers/LPM/UK/DIVEN.py +1 -1
  115. disdrodb/l0/readers/LPM/UK/WITHWORTH_LPM.py +1 -3
  116. disdrodb/l0/readers/LPM/USA/CHARLESTON.py +1 -3
  117. disdrodb/l0/readers/LPM_V0/BELGIUM/ULIEGE.py +1 -3
  118. disdrodb/l0/readers/LPM_V0/ITALY/GID_LPM_V0.py +1 -1
  119. disdrodb/l0/readers/ODM470/OCEAN/OCEANRAIN.py +123 -0
  120. disdrodb/l0/readers/PARSIVEL/AUSTRALIA/MELBOURNE_2007_PARSIVEL.py +1 -1
  121. disdrodb/l0/readers/PARSIVEL/BASQUECOUNTRY/EUSKALMET_OTT.py +1 -1
  122. disdrodb/l0/readers/PARSIVEL/CHINA/CHONGQING.py +1 -3
  123. disdrodb/l0/readers/PARSIVEL/EPFL/ARCTIC_2021.py +1 -1
  124. disdrodb/l0/readers/PARSIVEL/EPFL/COMMON_2011.py +1 -1
  125. disdrodb/l0/readers/PARSIVEL/EPFL/DAVOS_2009_2011.py +1 -1
  126. disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_2009.py +1 -1
  127. disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2008.py +1 -1
  128. disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2010.py +1 -1
  129. disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2011.py +1 -1
  130. disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2012.py +1 -1
  131. disdrodb/l0/readers/PARSIVEL/EPFL/GENEPI_2007.py +1 -1
  132. disdrodb/l0/readers/PARSIVEL/EPFL/GRAND_ST_BERNARD_2007.py +1 -1
  133. disdrodb/l0/readers/PARSIVEL/EPFL/GRAND_ST_BERNARD_2007_2.py +1 -1
  134. disdrodb/l0/readers/PARSIVEL/EPFL/HPICONET_2010.py +1 -1
  135. disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP2.py +1 -1
  136. disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP3.py +1 -1
  137. disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP4.py +1 -1
  138. disdrodb/l0/readers/PARSIVEL/EPFL/LOCARNO_2018.py +1 -1
  139. disdrodb/l0/readers/PARSIVEL/EPFL/LOCARNO_2019.py +1 -1
  140. disdrodb/l0/readers/PARSIVEL/EPFL/PARADISO_2014.py +1 -1
  141. disdrodb/l0/readers/PARSIVEL/EPFL/PARSIVEL_2007.py +1 -1
  142. disdrodb/l0/readers/PARSIVEL/EPFL/PLATO_2019.py +1 -1
  143. disdrodb/l0/readers/PARSIVEL/EPFL/RACLETS_2019.py +1 -1
  144. disdrodb/l0/readers/PARSIVEL/EPFL/RACLETS_2019_WJF.py +1 -1
  145. disdrodb/l0/readers/PARSIVEL/EPFL/RIETHOLZBACH_2011.py +1 -1
  146. disdrodb/l0/readers/PARSIVEL/EPFL/SAMOYLOV_2017.py +1 -1
  147. disdrodb/l0/readers/PARSIVEL/EPFL/SAMOYLOV_2019.py +1 -1
  148. disdrodb/l0/readers/PARSIVEL/EPFL/UNIL_2022.py +1 -1
  149. disdrodb/l0/readers/PARSIVEL/JAPAN/JMA.py +1 -1
  150. disdrodb/l0/readers/PARSIVEL/KOREA/ICEPOP_MSC.py +159 -0
  151. disdrodb/l0/readers/PARSIVEL/NASA/LPVEX.py +1 -1
  152. disdrodb/l0/readers/PARSIVEL/NASA/MC3E.py +1 -1
  153. disdrodb/l0/readers/PARSIVEL/NCAR/CCOPE_2015.py +1 -1
  154. disdrodb/l0/readers/PARSIVEL/NCAR/OWLES_MIPS.py +1 -1
  155. disdrodb/l0/readers/PARSIVEL/NCAR/PECAN_MOBILE.py +1 -1
  156. disdrodb/l0/readers/PARSIVEL/NCAR/PLOWS_MIPS.py +1 -1
  157. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2009.py +1 -1
  158. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2010.py +1 -3
  159. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2010_UF.py +1 -3
  160. disdrodb/l0/readers/PARSIVEL/SLOVENIA/UL.py +1 -1
  161. disdrodb/l0/readers/PARSIVEL2/ARM/ARM_PARSIVEL2.py +1 -1
  162. disdrodb/l0/readers/PARSIVEL2/BASQUECOUNTRY/EUSKALMET_OTT2.py +1 -1
  163. disdrodb/l0/readers/PARSIVEL2/BELGIUM/ILVO.py +1 -3
  164. disdrodb/l0/readers/PARSIVEL2/BRAZIL/CHUVA_PARSIVEL2.py +1 -1
  165. disdrodb/l0/readers/PARSIVEL2/BRAZIL/GOAMAZON_PARSIVEL2.py +1 -1
  166. disdrodb/l0/readers/PARSIVEL2/CANADA/UQAM_NC.py +1 -1
  167. disdrodb/l0/readers/PARSIVEL2/DENMARK/DTU.py +1 -1
  168. disdrodb/l0/readers/PARSIVEL2/DENMARK/EROSION_nc.py +1 -1
  169. disdrodb/l0/readers/PARSIVEL2/DENMARK/EROSION_raw.py +1 -1
  170. disdrodb/l0/readers/PARSIVEL2/FINLAND/FMI_PARSIVEL2.py +1 -1
  171. disdrodb/l0/readers/PARSIVEL2/FRANCE/ENPC_PARSIVEL2.py +1 -3
  172. disdrodb/l0/readers/PARSIVEL2/FRANCE/OSUG.py +1 -1
  173. disdrodb/l0/readers/PARSIVEL2/FRANCE/SIRTA_PARSIVEL2.py +1 -3
  174. disdrodb/l0/readers/PARSIVEL2/GREECE/NOA.py +4 -3
  175. disdrodb/l0/readers/PARSIVEL2/ITALY/GID_PARSIVEL2.py +1 -3
  176. disdrodb/l0/readers/PARSIVEL2/ITALY/HYDROX.py +5 -3
  177. disdrodb/l0/readers/PARSIVEL2/JAPAN/PRECIP.py +1 -1
  178. disdrodb/l0/readers/PARSIVEL2/KIT/BURKINA_FASO.py +1 -1
  179. disdrodb/l0/readers/PARSIVEL2/KIT/TEAMX.py +1 -1
  180. disdrodb/l0/readers/PARSIVEL2/KOREA/ICEPOP_MSC.py +161 -0
  181. disdrodb/l0/readers/PARSIVEL2/KOREA/ICEPOP_UCLM.py +126 -0
  182. disdrodb/l0/readers/PARSIVEL2/MEXICO/OH_IIUNAM_nc.py +1 -1
  183. disdrodb/l0/readers/PARSIVEL2/MPI/BCO_PARSIVEL2.py +1 -1
  184. disdrodb/l0/readers/PARSIVEL2/MPI/BOWTIE.py +1 -1
  185. disdrodb/l0/readers/PARSIVEL2/NASA/APU.py +3 -1
  186. disdrodb/l0/readers/PARSIVEL2/NASA/NSSTC.py +1 -1
  187. disdrodb/l0/readers/PARSIVEL2/NCAR/FARM_PARSIVEL2.py +1 -1
  188. disdrodb/l0/readers/PARSIVEL2/NCAR/PECAN_FP3.py +1 -1
  189. disdrodb/l0/readers/PARSIVEL2/NCAR/PECAN_MIPS.py +1 -1
  190. disdrodb/l0/readers/PARSIVEL2/NCAR/PERILS_MIPS.py +1 -1
  191. disdrodb/l0/readers/PARSIVEL2/NCAR/PERILS_PIPS.py +1 -1
  192. disdrodb/l0/readers/PARSIVEL2/NCAR/RELAMPAGO_PARSIVEL2.py +1 -1
  193. disdrodb/l0/readers/PARSIVEL2/NCAR/SNOWIE_PJ.py +1 -1
  194. disdrodb/l0/readers/PARSIVEL2/NCAR/SNOWIE_SB.py +1 -1
  195. disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_P1.py +1 -3
  196. disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_P2.py +1 -1
  197. disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_PIPS.py +1 -1
  198. disdrodb/l0/readers/PARSIVEL2/NETHERLANDS/DELFT_NC.py +1 -1
  199. disdrodb/l0/readers/PARSIVEL2/NORWAY/UIB.py +10 -2
  200. disdrodb/l0/readers/PARSIVEL2/PHILIPPINES/PAGASA.py +1 -3
  201. disdrodb/l0/readers/PARSIVEL2/SPAIN/CENER.py +1 -1
  202. disdrodb/l0/readers/PARSIVEL2/SPAIN/CR1000DL.py +1 -1
  203. disdrodb/l0/readers/PARSIVEL2/SPAIN/GRANADA.py +1 -3
  204. disdrodb/l0/readers/PARSIVEL2/SPAIN/LIAISE.py +1 -1
  205. disdrodb/l0/readers/PARSIVEL2/SWEDEN/SMHI.py +1 -1
  206. disdrodb/l0/readers/PARSIVEL2/USA/CSU.py +1 -1
  207. disdrodb/l0/readers/PARSIVEL2/USA/CW3E.py +1 -1
  208. disdrodb/l0/readers/PWS100/AUSTRIA/HOAL.py +1 -3
  209. disdrodb/l0/readers/PWS100/FRANCE/ENPC_PWS100.py +1 -3
  210. disdrodb/l0/readers/PWS100/FRANCE/ENPC_PWS100_SIRTA.py +1 -1
  211. disdrodb/l0/readers/RD80/BRAZIL/ATTO_RD80.py +1 -3
  212. disdrodb/l0/readers/RD80/BRAZIL/CHUVA_RD80.py +1 -3
  213. disdrodb/l0/readers/RD80/BRAZIL/GOAMAZON_RD80.py +1 -3
  214. disdrodb/l0/readers/RD80/NCAR/CINDY_2011_RD80.py +1 -3
  215. disdrodb/l0/readers/RD80/NCAR/RELAMPAGO_RD80.py +1 -3
  216. disdrodb/l0/readers/RD80/NOAA/PSL_RD80.py +1 -3
  217. disdrodb/l0/readers/SWS250/BELGIUM/KMI.py +1 -3
  218. disdrodb/l0/readers/template_reader_raw_netcdf_data.py +1 -3
  219. disdrodb/l0/readers/template_reader_raw_text_data.py +1 -3
  220. disdrodb/l0/standards.py +4 -5
  221. disdrodb/l0/template_tools.py +1 -3
  222. disdrodb/l1/__init__.py +1 -1
  223. disdrodb/l1/classification.py +913 -0
  224. disdrodb/l1/processing.py +36 -106
  225. disdrodb/l1/resampling.py +8 -3
  226. disdrodb/l1_env/__init__.py +1 -1
  227. disdrodb/l1_env/routines.py +6 -6
  228. disdrodb/l2/__init__.py +1 -1
  229. disdrodb/l2/empirical_dsd.py +57 -31
  230. disdrodb/l2/processing.py +327 -62
  231. disdrodb/metadata/checks.py +1 -3
  232. disdrodb/metadata/download.py +4 -4
  233. disdrodb/metadata/geolocation.py +1 -3
  234. disdrodb/metadata/info.py +1 -3
  235. disdrodb/metadata/manipulation.py +1 -3
  236. disdrodb/metadata/reader.py +1 -3
  237. disdrodb/metadata/search.py +1 -3
  238. disdrodb/metadata/standards.py +1 -3
  239. disdrodb/metadata/writer.py +1 -3
  240. disdrodb/physics/__init__.py +17 -0
  241. disdrodb/physics/atmosphere.py +272 -0
  242. disdrodb/physics/water.py +130 -0
  243. disdrodb/physics/wrappers.py +62 -0
  244. disdrodb/psd/__init__.py +1 -1
  245. disdrodb/psd/fitting.py +22 -9
  246. disdrodb/psd/models.py +1 -1
  247. disdrodb/routines/__init__.py +5 -1
  248. disdrodb/routines/l0.py +26 -16
  249. disdrodb/routines/l1.py +8 -6
  250. disdrodb/routines/l2.py +8 -4
  251. disdrodb/routines/options.py +116 -73
  252. disdrodb/routines/options_validation.py +728 -0
  253. disdrodb/routines/wrappers.py +431 -11
  254. disdrodb/scattering/__init__.py +1 -1
  255. disdrodb/scattering/axis_ratio.py +6 -6
  256. disdrodb/scattering/permittivity.py +8 -8
  257. disdrodb/scattering/routines.py +31 -13
  258. disdrodb/summary/__init__.py +1 -1
  259. disdrodb/summary/routines.py +83 -25
  260. disdrodb/utils/__init__.py +1 -1
  261. disdrodb/utils/archiving.py +16 -9
  262. disdrodb/utils/attrs.py +4 -3
  263. disdrodb/utils/cli.py +8 -10
  264. disdrodb/utils/compression.py +9 -11
  265. disdrodb/utils/dask.py +2 -3
  266. disdrodb/utils/dataframe.py +1 -3
  267. disdrodb/utils/decorators.py +1 -3
  268. disdrodb/utils/dict.py +1 -1
  269. disdrodb/utils/directories.py +3 -5
  270. disdrodb/utils/encoding.py +2 -4
  271. disdrodb/utils/event.py +1 -1
  272. disdrodb/utils/list.py +1 -3
  273. disdrodb/utils/logger.py +1 -3
  274. disdrodb/utils/manipulations.py +175 -5
  275. disdrodb/utils/pydantic.py +80 -0
  276. disdrodb/utils/routines.py +1 -3
  277. disdrodb/utils/subsetting.py +1 -1
  278. disdrodb/utils/time.py +3 -2
  279. disdrodb/utils/warnings.py +1 -3
  280. disdrodb/utils/writer.py +1 -3
  281. disdrodb/utils/xarray.py +30 -3
  282. disdrodb/utils/yaml.py +1 -3
  283. disdrodb/viz/__init__.py +1 -1
  284. disdrodb/viz/plots.py +192 -18
  285. {disdrodb-0.2.1.dist-info → disdrodb-0.3.0.dist-info}/METADATA +2 -2
  286. disdrodb-0.3.0.dist-info/RECORD +358 -0
  287. {disdrodb-0.2.1.dist-info → disdrodb-0.3.0.dist-info}/entry_points.txt +3 -0
  288. disdrodb/etc/products/L1/1MIN.yaml +0 -13
  289. disdrodb/etc/products/L1/LPM/1MIN.yaml +0 -13
  290. disdrodb/etc/products/L1/LPM_V0/1MIN.yaml +0 -13
  291. disdrodb/etc/products/L1/PARSIVEL/1MIN.yaml +0 -13
  292. disdrodb/etc/products/L1/PARSIVEL2/1MIN.yaml +0 -13
  293. disdrodb/etc/products/L1/PWS100/1MIN.yaml +0 -13
  294. disdrodb/etc/products/L1/RD80/1MIN.yaml +0 -13
  295. disdrodb/etc/products/L1/SWS250/1MIN.yaml +0 -13
  296. disdrodb/etc/products/L2M/10MIN.yaml +0 -12
  297. disdrodb/l1/beard_model.py +0 -662
  298. disdrodb/l1/filters.py +0 -205
  299. disdrodb-0.2.1.dist-info/RECORD +0 -329
  300. {disdrodb-0.2.1.dist-info → disdrodb-0.3.0.dist-info}/WHEEL +0 -0
  301. {disdrodb-0.2.1.dist-info → disdrodb-0.3.0.dist-info}/licenses/LICENSE +0 -0
  302. {disdrodb-0.2.1.dist-info → disdrodb-0.3.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
@@ -170,6 +170,9 @@ def resample_dataset(ds, sample_interval, temporal_resolution):
170
170
  - The function updates the dataset attributes and the sample_interval coordinate.
171
171
 
172
172
  """
173
+ from disdrodb.constants import METEOROLOGICAL_VARIABLES
174
+ from disdrodb.l1.classification import TEMPERATURE_VARIABLES
175
+
173
176
  # --------------------------------------------------------------------------.
174
177
  # Ensure sample interval in seconds
175
178
  sample_interval = int(ensure_sample_interval_in_seconds(sample_interval))
@@ -244,6 +247,7 @@ def resample_dataset(ds, sample_interval, temporal_resolution):
244
247
 
245
248
  # Retrieve variables to average/sum
246
249
  # - ATTENTION: it will not resample non-dimensional time coordinates of the dataset !
250
+ # - precip_flag used for OceanRain ODM470 data
247
251
  var_to_average = ["fall_velocity"]
248
252
  var_to_cumulate = [
249
253
  "raw_drop_number",
@@ -255,8 +259,9 @@ def resample_dataset(ds, sample_interval, temporal_resolution):
255
259
  "Nremoved",
256
260
  "qc_resampling",
257
261
  ]
258
- var_to_min = ["Dmin"]
259
- var_to_max = ["Dmax", "time_qc"]
262
+ var_to_min = ["Dmin", *TEMPERATURE_VARIABLES]
263
+ met_vars = set(METEOROLOGICAL_VARIABLES) - set(TEMPERATURE_VARIABLES) # exclude air_temperature variable
264
+ var_to_max = ["Dmax", "qc_time", "precip_flag", *met_vars]
260
265
 
261
266
  # Retrieve available variables
262
267
  var_to_average = [var for var in var_to_average if var in ds]
@@ -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
@@ -30,15 +30,15 @@ DEFAULT_GEOLOCATION = {
30
30
 
31
31
 
32
32
  def get_default_environment_dataset():
33
- """Define defaults values for the ENV dataset."""
33
+ """Set International Standard Atmosphere values for the default ENV dataset."""
34
34
  ds_env = xr.Dataset()
35
- ds_env["sea_level_air_pressure"] = 101_325 # Pa
35
+ ds_env["sea_level_air_pressure"] = 101_325 # Pa # sea level
36
36
  ds_env["gas_constant_dry_air"] = 287.04 # J kg⁻¹ K⁻¹
37
- ds_env["lapse_rate"] = 0.0065 # K m⁻¹
37
+ ds_env["lapse_rate"] = 0.0065 # K m⁻¹ (6.5 deg/km)
38
38
  ds_env["relative_humidity"] = 0.95 # 0-1 !
39
- ds_env["temperature"] = 20 + 273.15 # K
39
+ ds_env["temperature"] = 15 + 273.15 # K
40
40
  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
41
+ # air density = 1.225 kg m⁻³ (if RH = 0) using retrieve_air_density(ds_env)
42
42
  return ds_env
43
43
 
44
44
 
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
@@ -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
@@ -25,6 +25,7 @@ import xarray as xr
25
25
 
26
26
  from disdrodb.api.checks import check_sensor_name
27
27
  from disdrodb.constants import DIAMETER_DIMENSION, VELOCITY_DIMENSION
28
+ from disdrodb.utils.time import ensure_sample_interval_in_seconds
28
29
  from disdrodb.utils.xarray import (
29
30
  remove_diameter_coordinates,
30
31
  remove_velocity_coordinates,
@@ -208,8 +209,26 @@ def add_bins_metrics(ds):
208
209
  return ds
209
210
 
210
211
 
211
- ####-------------------------------------------------------------------------------------------------------------------.
212
- #### DSD Spectrum, Concentration, Moments
212
+ ####------------------------------------------------------------------------------------------.
213
+ #### Sampling area and measurement interval
214
+ def get_sampling_area(sensor_name):
215
+ """Return the sampling area in m2 of the disdrometer."""
216
+ check_sensor_name(sensor_name)
217
+ area_dict = {
218
+ "PARSIVEL": 0.0054, # 54 cm2
219
+ "PARSIVEL2": 0.0054, # 54 cm2
220
+ "LPM": 0.0045, # 45 cm2
221
+ "LPM_V0": 0.0045, # 45 cm2
222
+ "ODM470": 0.00264, # 26.4 cm2
223
+ "PWS100": 0.004, # 40 cm2
224
+ "RD80": 0.005, # 50 cm2
225
+ "SWS250": 0.006504, # 65.04 cm2 (Ricardo Reinoso Rondinel, personal communication)
226
+ }
227
+ # SWS250
228
+ # - Table 29 of the manual that the sample volume is 400cm3, path length?
229
+ # - Distance between the end of the hood heaters is 291 mm.
230
+ # - Adding a factor of 1.5 for better representation of the Tx-Rx distance: L= 436 mm.
231
+ return area_dict[sensor_name]
213
232
 
214
233
 
215
234
  def get_effective_sampling_area(sensor_name, diameter):
@@ -227,26 +246,22 @@ def get_effective_sampling_area(sensor_name, diameter):
227
246
  B = 30 / 1000 # Width of the Parsivel beam in m (30mm)
228
247
  sampling_area = L * (B - diameter / 2) # d_eq
229
248
  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
249
+ return get_sampling_area(sensor_name)
250
+
251
+
252
+ def get_effective_sampling_interval(ds, sensor_name):
253
+ """Return the effective sample interval in seconds of the disdrometer."""
254
+ sample_interval = ensure_sample_interval_in_seconds(ds["sample_interval"]) # s
255
+ # Adapt sample interval for sensor duty cycle
237
256
  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.")
257
+ # PWS100 has a duty cycle of 9s on, 1s off
258
+ # - 9 seconds out of 10 are used for counting drops, 1 second is used to process data
259
+ sample_interval = sample_interval * (9 / 10)
260
+ return sample_interval
261
+
262
+
263
+ ####-------------------------------------------------------------------------------------------------------------------.
264
+ #### DSD Spectrum, Concentration, Moments
250
265
 
251
266
 
252
267
  def get_bin_dimensions(xr_obj):
@@ -307,15 +322,19 @@ def get_drop_number_concentration(drop_number, velocity, diameter_bin_width, sam
307
322
  # Ensure velocity is 2D (diameter, velocity)
308
323
  velocity = xr.ones_like(drop_number) * velocity
309
324
 
325
+ # Create a safe ratio: drop_number / velocity, but 0 where velocity is 0 or NaN
326
+ safe_ratio = drop_number / velocity
327
+ safe_ratio = safe_ratio.where((velocity != 0) & (~np.isnan(velocity)), 0)
328
+
310
329
  # Compute drop number concentration
311
330
  # - For disdrometer with velocity bins
312
331
  if VELOCITY_DIMENSION in drop_number.dims:
313
- drop_number_concentration = (drop_number / velocity).sum(dim=VELOCITY_DIMENSION, skipna=False) / (
332
+ drop_number_concentration = safe_ratio.sum(dim=VELOCITY_DIMENSION, skipna=False) / (
314
333
  sampling_area * diameter_bin_width * sample_interval
315
334
  )
316
335
  # - For impact disdrometers
317
336
  else:
318
- drop_number_concentration = (drop_number / velocity) / (sampling_area * diameter_bin_width * sample_interval)
337
+ drop_number_concentration = safe_ratio / (sampling_area * diameter_bin_width * sample_interval)
319
338
  return drop_number_concentration
320
339
 
321
340
 
@@ -1669,8 +1688,7 @@ def get_kinetic_energy_variables_from_drop_number(
1669
1688
  KEF = TKE / sample_interval * 3600
1670
1689
 
1671
1690
  # 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)
1691
+ KED = xr.where(R == 0, 0, KEF / R) # Ensure KED is 0 when R (and thus drop number is 0)
1674
1692
 
1675
1693
  # Create dataset
1676
1694
  dict_vars = {
@@ -1735,6 +1753,10 @@ def compute_integral_parameters(
1735
1753
  - KED: Kinetic Energy per unit rainfall Depth [J·m⁻²·mm⁻¹].
1736
1754
  - KEF: Kinetic Energy Flux [J·m⁻²·h⁻¹].
1737
1755
  """
1756
+ # Ensure velocity does not contain NaN
1757
+ # --> e.g. when D > 10 mm --> Replace to 0
1758
+ velocity = velocity.fillna(0)
1759
+
1738
1760
  # Initialize dataset
1739
1761
  ds = xr.Dataset()
1740
1762
 
@@ -1764,15 +1786,15 @@ def compute_integral_parameters(
1764
1786
  moment=moment,
1765
1787
  )
1766
1788
 
1767
- # Compute Liquid Water Content (LWC) (W) [g/m3]
1768
- # ds["W"] = get_liquid_water_content(
1789
+ # Compute Liquid Water Content (LWC) [g/m3]
1790
+ # ds["LWC"] = get_liquid_water_content(
1769
1791
  # drop_number_concentration=drop_number_concentration,
1770
1792
  # diameter=diameter,
1771
1793
  # diameter_bin_width=diameter_bin_width,
1772
1794
  # water_density=water_density,
1773
1795
  # )
1774
1796
 
1775
- ds["W"] = get_liquid_water_content_from_moments(moment_3=ds["M3"], water_density=water_density)
1797
+ ds["LWC"] = get_liquid_water_content_from_moments(moment_3=ds["M3"], water_density=water_density)
1776
1798
 
1777
1799
  # Compute reflectivity in dBZ
1778
1800
  ds["Z"] = get_equivalent_reflectivity_factor(
@@ -1869,9 +1891,13 @@ def compute_spectrum_parameters(
1869
1891
  Dataset containing the following spectrum:
1870
1892
  - KE_spectrum : Kinetic Energy spectrum [J/m2/mm]
1871
1893
  - R_spectrum : Rain Rate spectrum [mm/h/mm]
1872
- - W_spectrum : Mass spectrum [g/m3/mm]
1894
+ - LWC_spectrum : Mass spectrum [g/m3/mm]
1873
1895
  - Z_spectrum : Reflectivity spectrum [dBZ of mm6/m3/mm]
1874
1896
  """
1897
+ # Ensure velocity does not contain NaN
1898
+ # --> e.g. when D > 10 mm --> Replace to 0
1899
+ velocity = velocity.fillna(0)
1900
+
1875
1901
  # Initialize dataset
1876
1902
  ds = xr.Dataset()
1877
1903
  ds["KE_spectrum"] = get_kinetic_energy_spectrum(
@@ -1882,7 +1908,7 @@ def compute_spectrum_parameters(
1882
1908
  water_density=water_density,
1883
1909
  )
1884
1910
  ds["R_spectrum"] = get_rain_rate_spectrum(drop_number_concentration, velocity=velocity, diameter=diameter)
1885
- ds["W_spectrum"] = get_liquid_water_spectrum(
1911
+ ds["LWC_spectrum"] = get_liquid_water_spectrum(
1886
1912
  drop_number_concentration,
1887
1913
  diameter=diameter,
1888
1914
  water_density=water_density,