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,484 @@
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
+ """Theoretical models to estimate the graupel fall velocity based on particle maximum diameter in mm."""
18
+
19
+ import numpy as np
20
+ import xarray as xr
21
+
22
+ from disdrodb.constants import DIAMETER_DIMENSION
23
+ from disdrodb.l0.l0b_processing import ensure_valid_geolocation
24
+ from disdrodb.l1_env.routines import load_env_dataset
25
+ from disdrodb.physics.wrappers import retrieve_air_density, retrieve_air_dynamic_viscosity, retrieve_air_pressure
26
+ from disdrodb.utils.warnings import suppress_warnings
27
+
28
+
29
+ def get_graupel_density(diameter):
30
+ """Estimate the graupel particle density.
31
+
32
+ Use the Heymsfield & Wright (2014) parameterization.
33
+
34
+ At 5mm, graupel density only 140 kg/m3 ...
35
+
36
+ Parameters
37
+ ----------
38
+ diameter : array-like or float
39
+ Particle maximum diameter in millimeters [mm].
40
+
41
+ Returns
42
+ -------
43
+ graupel_density : xarray.DataArray or numpy.ndarray
44
+ Graupel density [kg/m3].
45
+
46
+ References
47
+ ----------
48
+ Heymsfield, A. J., and Wright, R., 2014.
49
+ Graupel and Hail Terminal Velocities: Does a Supercritical Reynolds Number Apply?
50
+ J. Atmos. Sci., 71, 3392-3403, https://doi.org/10.1175/JAS-D-14-0034.1.
51
+ """
52
+ graupel_density = 0.18 * (diameter * 0.1) ** 0.33 * 1000
53
+ return graupel_density
54
+
55
+
56
+ def get_fall_velocity_lee_2015(diameter):
57
+ """
58
+ Compute terminal fall velocity of lump graupel.
59
+
60
+ Use Lee et al., 2015 empirical formula.
61
+
62
+ Parameters
63
+ ----------
64
+ diameter : array-like or float
65
+ Particle maximum diameter in millimeters [mm].
66
+
67
+ Returns
68
+ -------
69
+ fall_velocity : ndarray or xarray.DataArray
70
+ Terminal fall velocity [m s⁻¹].
71
+ """
72
+ fall_velocity = 1.10 * diameter**0.28
73
+ return fall_velocity
74
+
75
+
76
+ def get_fall_velocity_locatelli_1974_lump(diameter):
77
+ """
78
+ Compute terminal fall velocity of lump graupel.
79
+
80
+ Use Locatelli and Hobbs 1974 empirical formula.
81
+
82
+ Parameters
83
+ ----------
84
+ diameter : array-like or float
85
+ Particle maximum diameter in millimeters [mm].
86
+
87
+ Returns
88
+ -------
89
+ fall_velocity : ndarray or xarray.DataArray
90
+ Terminal fall velocity [m s⁻¹].
91
+
92
+ Reference
93
+ ---------
94
+ Locatelli, J. D., and P. V. Hobbs (1974).
95
+ Fall speeds and masses of solid precipitation particles
96
+ J. Geophys. Res., 79(15), 2185-2197, doi:10.1029/JC079i015p02185.
97
+ """
98
+ fall_velocity = 1.3 * diameter**0.66 # Dmax [0.5-3]
99
+ # fall_velocity = 1.16*diameter**0.46, # Dmax [0.5-2]
100
+ # fall_velocity = 1.5*diameter**0.37 # Dmax [0.5-1]
101
+ return fall_velocity
102
+
103
+
104
+ def get_fall_velocity_locatelli_1974_conical(diameter):
105
+ """
106
+ Compute terminal fall velocity of cone-shaped graupel.
107
+
108
+ Use Locatelli and Hobbs 1974 empirical formula.
109
+
110
+ Parameters
111
+ ----------
112
+ diameter : array-like or float
113
+ Particle maximum diameter in millimeters [mm].
114
+
115
+ Returns
116
+ -------
117
+ fall_velocity : ndarray or xarray.DataArray
118
+ Terminal fall velocity [m s⁻¹].
119
+
120
+ Reference
121
+ ---------
122
+ Locatelli, J. D., and P. V. Hobbs (1974).
123
+ Fall speeds and masses of solid precipitation particles
124
+ J. Geophys. Res., 79(15), 2185-2197, doi:10.1029/JC079i015p02185.
125
+ """
126
+ fall_velocity = 1.20 * diameter**0.65
127
+ return fall_velocity
128
+
129
+
130
+ def get_fall_velocity_locatelli_1974_hexagonal(diameter):
131
+ """
132
+ Compute terminal fall velocity of hexagonal graupel.
133
+
134
+ Use Locatelli and Hobbs 1974 empirical formula.
135
+
136
+ Parameters
137
+ ----------
138
+ diameter : array-like or float
139
+ Particle maximum diameter in millimeters [mm].
140
+
141
+ Returns
142
+ -------
143
+ fall_velocity : ndarray or xarray.DataArray
144
+ Terminal fall velocity [m s⁻¹].
145
+
146
+ Reference
147
+ ---------
148
+ Locatelli, J. D., and P. V. Hobbs (1974).
149
+ Fall speeds and masses of solid precipitation particles
150
+ J. Geophys. Res., 79(15), 2185-2197, doi:10.1029/JC079i015p02185.
151
+ """
152
+ fall_velocity = 1.10 * diameter**0.57
153
+ return fall_velocity
154
+
155
+
156
+ def get_fall_velocity_heymsfield_2014(diameter):
157
+ """
158
+ Compute terminal velocity of graupel and small hail.
159
+
160
+ Use Heymsfield & Wright (2014) empirical formula.
161
+
162
+ Parameters
163
+ ----------
164
+ diameter : array-like or float
165
+ Particle maximum diameter in millimeters [mm].
166
+
167
+ Returns
168
+ -------
169
+ fall_velocity : ndarray or xarray.DataArray
170
+ Terminal fall velocity [m s⁻¹].
171
+ Reference
172
+ ---------
173
+ Heymsfield, A. J., and Wright, R., 2014.
174
+ Graupel and hail terminal velocities: Observations and theory.
175
+ Journal of the Atmospheric Sciences* , 71(1), 339-353.
176
+ """
177
+ fall_velocity = 4.88 * (0.1 * diameter) ** 0.84
178
+ return fall_velocity
179
+
180
+
181
+ def get_fall_velocity_heymsfield_2018(diameter):
182
+ """Get graupel fall velocity from Heymsfield et al., 2018.
183
+
184
+ Use the Heymsfield et al., 2018 parameterization.
185
+
186
+ Parameters
187
+ ----------
188
+ diameter : array-like or float
189
+ Particle maximum diameter in millimeters [mm].
190
+
191
+
192
+ Returns
193
+ -------
194
+ fall_velocity : xarray.DataArray or numpy.ndarray
195
+ Terminal fall velocity [m s⁻¹].
196
+
197
+ References
198
+ ----------
199
+ Heymsfield, A., M. Szakáll, A. Jost, I. Giammanco, and R. Wright, 2018.
200
+ A Comprehensive Observational Study of Graupel and Hail Terminal Velocity, Mass Flux, and Kinetic Energy.
201
+ J. Atmos. Sci., 75, 3861-3885, https://doi.org/10.1175/JAS-D-18-0035.1.
202
+
203
+ Heymsfield, A., M. Szakáll, A. Jost, I. Giammanco, R. Wright, and J. Brimelow, 2020.
204
+ CORRIGENDUM.
205
+ J. Atmos. Sci., 77, 405-412, https://doi.org/10.1175/JAS-D-19-0185.1.
206
+ """
207
+ # Original incorrect formula from Heymsfield et al., 2018
208
+ # fall_velocity = 6.35 * (0.1 * diameter) ** 0.87 # 0.87 in Table 3. 0.97 in Eq 8
209
+
210
+ # Corrected formula from Heymsfield et al., 2020 (Corrigendum)
211
+ fall_velocity = 7.59 * (0.1 * diameter) ** 0.89
212
+ return fall_velocity
213
+
214
+
215
+ ####----------------------------------------------------------------------
216
+ #### Heymsfield_2014 graupel model
217
+
218
+
219
+ def get_graupel_heymsfield_2014_fall_velocity(
220
+ diameter,
221
+ graupel_density=500.0,
222
+ air_density=1.225,
223
+ air_dynamic_viscosity=1.81e-5,
224
+ g=9.81,
225
+ ):
226
+ r"""
227
+ Compute the terminal fall velocity of sleet, graupel and small hail particles.
228
+
229
+ Use the Heymsfield & Wright (2014) parameterization.
230
+
231
+ Parameters
232
+ ----------
233
+ diameter : array-like or float
234
+ Particle maximum diameter in millimeters [mm].
235
+ air_density : float, optional
236
+ Air density [kg m⁻³]. Default is 1.225 (typical at sea level, 15°C).
237
+ graupel_density : float, optional
238
+ Bulk density of the ice particle [kg m⁻³].
239
+ Defaults to 500 kg m⁻³ (typical for graupel; hail can be ~900).
240
+ air_dynamic_viscosity : float, optional
241
+ Dynamic viscosity of air [kg m⁻¹ s⁻¹].
242
+ Default is 1.81e-5 (air at 15°C, 1 atm).
243
+ g : float, optional
244
+ Acceleration due to gravity [m s⁻²]. Default is 9.81.
245
+
246
+ Returns
247
+ -------
248
+ fall_velocity : xarray.DataArray
249
+ Terminal fall velocity [m s⁻¹].
250
+
251
+ Notes
252
+ -----
253
+ The relationship is based on empirical fits to the Reynolds number (Re)
254
+ as a function of a dimensionless variable X:
255
+
256
+ .. math::
257
+
258
+ X = \\frac{4}{3} D^3 \\rho_b g \\frac{\\rho_a}{\\eta_a^2}
259
+
260
+ Two regimes are used to compute the Reynolds number :math:`Re` as a function of
261
+ the dimensionless parameter :math:`X`:
262
+
263
+ .. math::
264
+
265
+ Re =
266
+ \\begin{cases}
267
+ 0.106\\, X^{0.693}, & \\text{for } X < 6.77 \\times 10^{4} \\\\
268
+ 0.55\\, X^{0.545}, & \\text{for } X \\ge 6.77 \\times 10^{4}
269
+ \\end{cases}
270
+
271
+ The terminal fall velocity :math:`v_t` is then obtained as:
272
+
273
+ .. math::
274
+
275
+ v_t = \\frac{Re\\, \\eta_a}{\\rho_a\\, D}
276
+
277
+ where:
278
+
279
+
280
+ - :math:`Re` — Reynolds number (dimensionless)
281
+ - :math:`\\eta_a` — dynamic viscosity of air [kg m⁻¹ s⁻¹]
282
+ - :math:`\\rho_a` — air density [kg m⁻³]
283
+ - :math:`D` — particle diameter [m]
284
+ - :math:`\\rho_b` — bulk density of the particle [kg m⁻³]
285
+ - :math:`g` — gravitational acceleration [m s⁻²]
286
+
287
+ References
288
+ ----------
289
+ Heymsfield, A. J., and Wright, R., 2014.
290
+ Graupel and Hail Terminal Velocities: Does a Supercritical Reynolds Number Apply?
291
+ J. Atmos. Sci., 71, 3392-3403, https://doi.org/10.1175/JAS-D-14-0034.1.
292
+ """
293
+ diameter = xr.DataArray(diameter / 1000)
294
+
295
+ # Compute Davies (or Best) number
296
+ X = (4 / 3) * diameter**3 * graupel_density * g * air_density / air_dynamic_viscosity**2
297
+
298
+ Re = xr.where(
299
+ X < 6.77e4,
300
+ 0.106 * X**0.693,
301
+ 0.55 * X**0.545,
302
+ )
303
+
304
+ fall_velocity = Re * air_dynamic_viscosity / (air_density * diameter)
305
+ return fall_velocity
306
+
307
+
308
+ def retrieve_graupel_heymsfield2014_fall_velocity(
309
+ diameter,
310
+ ds_env,
311
+ graupel_density=500.0,
312
+ ):
313
+ """
314
+ Compute the terminal fall velocity of sleet, graupel and small hail particles.
315
+
316
+ Use the Heymsfield & Wright (2014) parameterization.
317
+
318
+ Parameters
319
+ ----------
320
+ diameter : array-like
321
+ Diameter of the graupel particles in millimeters.
322
+ ds_env : xr.Dataset
323
+ A dataset containing the following environmental variables:
324
+ - 'altitude' : Altitude in meters (m).
325
+ - 'latitude' : Latitude in degrees.
326
+ - 'temperature' : Temperature in degrees Kelvin (K).
327
+ - 'relative_humidity' : Relative humidity between 0 and 1.
328
+ - 'sea_level_air_pressure' : Standard atmospheric pressure at sea level in Pascals (Pa).
329
+ The default is 101_325 Pa.
330
+ - 'air_pressure': Air pressure in Pascals (Pa). If None, air_pressure at altitude is inferred.
331
+ - 'lapse_rate' : Atmospheric lapse rate in degrees Celsius or Kelvin per meter (°C/m).
332
+ The default is 0.0065 K/m.
333
+ - 'gas_constant_dry_air': Gas constant for dry air in J/(kg*K). The default is 287.04 is J/(kg*K).
334
+ graupel_density : float, optional
335
+ Bulk density of the ice particle [kg m⁻³].
336
+ Defaults to 500 kg m⁻³ (typical for graupel; hail can be ~900).
337
+
338
+ Returns
339
+ -------
340
+ fall_velocity : array-like
341
+ Terminal fall velocity for the graupel particles.
342
+ """
343
+ air_viscosity = retrieve_air_dynamic_viscosity(ds_env)
344
+ air_density = retrieve_air_density(ds_env)
345
+ fall_velocity = get_graupel_heymsfield_2014_fall_velocity(
346
+ diameter=diameter,
347
+ graupel_density=graupel_density,
348
+ air_density=air_density,
349
+ air_dynamic_viscosity=air_viscosity,
350
+ )
351
+ return fall_velocity
352
+
353
+
354
+ ####------------------------------------------------------------------------------------
355
+ #### Wrappers
356
+
357
+
358
+ GRAUPEL_FALL_VELOCITY_MODELS = {
359
+ "Lee2015": get_fall_velocity_lee_2015,
360
+ "Locatelli1974Lump": get_fall_velocity_locatelli_1974_lump,
361
+ "Locatelli1974Conical": get_fall_velocity_locatelli_1974_conical,
362
+ "Locatelli1974Hexagonal": get_fall_velocity_locatelli_1974_hexagonal,
363
+ "Heymsfield2014": get_fall_velocity_heymsfield_2014,
364
+ "Heymsfield2018": get_fall_velocity_heymsfield_2018,
365
+ }
366
+
367
+
368
+ def available_graupel_fall_velocity_models():
369
+ """Return a list of the available graupel fall velocity models."""
370
+ return list(GRAUPEL_FALL_VELOCITY_MODELS)
371
+
372
+
373
+ def check_graupel_fall_velocity_model(model):
374
+ """Check validity of the specified graupel fall velocity model."""
375
+ available_models = available_graupel_fall_velocity_models()
376
+ if model not in available_models:
377
+ raise ValueError(f"{model} is an invalid graupel fall velocity model. Valid models: {available_models}.")
378
+ return model
379
+
380
+
381
+ def get_graupel_fall_velocity_model(model):
382
+ """Return the specified graupel fall velocity model.
383
+
384
+ Parameters
385
+ ----------
386
+ model : str
387
+ The model to use for calculating the rain drop fall velocity. Available models are:
388
+ 'Lee2015', 'Locatelli1974Lump', 'Locatelli1974Conical', 'Locatelli1974Hexagonal',
389
+ 'Heymsfield2014', 'Heymsfield2018'.
390
+
391
+ Returns
392
+ -------
393
+ callable
394
+ A function which compute the graupel fall velocity model
395
+ given the rain drop diameter in mm.
396
+
397
+ Notes
398
+ -----
399
+ This function serves as a wrapper to various graupel fall velocity models.
400
+ It returns the appropriate model based on the `model` parameter.
401
+ """
402
+ model = check_graupel_fall_velocity_model(model)
403
+ return GRAUPEL_FALL_VELOCITY_MODELS[model]
404
+
405
+
406
+ def get_graupel_fall_velocity(diameter, model, ds_env=None, minimum_diameter=0.5, maximum_diameter=5):
407
+ """Calculate the fall velocity of graupel based on their diameter.
408
+
409
+ Parameters
410
+ ----------
411
+ diameter : array-like
412
+ The diameter of the graupel in millimeters.
413
+ model : str
414
+ The model to use for calculating the graupel fall velocity. Must be one of the following:
415
+ 'Lee2015', 'Locatelli1974Lump', 'Locatelli1974Conical', 'Locatelli1974Hexagonal',
416
+ 'Heymsfield2014', 'Heymsfield2018'.
417
+ ds_env : xr.Dataset, optional
418
+ A dataset containing the following environmental variables:
419
+ - 'altitude' (m)
420
+ - 'latitude' (°)
421
+ - 'temperature' : Temperature in degrees Kelvin (K).
422
+ - 'relative_humidity' : Relative humidity. A value between 0 and 1.
423
+ - 'sea_level_air_pressure' : Sea level air pressure in Pascals (Pa).
424
+ - 'lapse_rate' : Lapse rate in degrees Celsius per meter (°C/m).
425
+ If not specified, sensible default values are used.
426
+
427
+ Returns
428
+ -------
429
+ fall_velocity : xr.DataArray
430
+ The calculated graupel fall velocities per diameter.
431
+
432
+ Notes
433
+ -----
434
+ The 'Beard1976' model requires additional environmental parameters.
435
+ These parameters can be provided through the `ds_env` argument.
436
+ If not provided, default values are be used.
437
+
438
+ For D < 0.12, Atlas1973 relationship results output V = 0 m/s !
439
+ For D < 0.05, VanDijk2002 relationship results output V = 0 m/s !
440
+ For D < 0.02, Brandes relationship results output V = 0 m/s !
441
+
442
+ """
443
+ # Check valid method
444
+ model = check_graupel_fall_velocity_model(model)
445
+
446
+ # Copy diameter
447
+ if isinstance(diameter, xr.DataArray):
448
+ diameter = diameter.copy()
449
+ else:
450
+ diameter = np.atleast_1d(diameter)
451
+ diameter = xr.DataArray(diameter, dims=DIAMETER_DIMENSION, coords={DIAMETER_DIMENSION: diameter.copy()})
452
+
453
+ # Initialize ds_env if None
454
+ # --> Ensure valid altitude and geolocation
455
+ # - altitude requiredto correct for elevation (air_density)
456
+ # - latitude required for gravity
457
+ if ds_env is None:
458
+ ds_env = load_env_dataset()
459
+ for coord in ["altitude", "latitude"]:
460
+ ds_env = ensure_valid_geolocation(ds_env, coord=coord, errors="raise")
461
+
462
+ # Retrieve fall velocity
463
+ func = get_graupel_fall_velocity_model(model)
464
+ with suppress_warnings(): # e.g. when diameter = 0 for Beard1976
465
+ fall_velocity = func(diameter, ds_env=ds_env) if model == "Beard1976" else func(diameter)
466
+
467
+ # Correct for altitude
468
+ air_pressure = retrieve_air_pressure(ds_env)
469
+ correction_factor = (101325 / air_pressure) ** 0.545
470
+ fall_velocity = fall_velocity * correction_factor
471
+
472
+ # Set to NaN for diameter outside [0.5, 5]
473
+ fall_velocity = fall_velocity.where(fall_velocity["diameter_bin_lower"] >= minimum_diameter)
474
+ fall_velocity = fall_velocity.where(fall_velocity["diameter_bin_upper"] <= maximum_diameter)
475
+
476
+ # Ensure fall velocity is > 0 to avoid division by zero
477
+ # - Some models, at small diameter, can return negative/zero fall velocity
478
+ fall_velocity = fall_velocity.where(fall_velocity > 0)
479
+
480
+ # Add attributes
481
+ fall_velocity.name = "fall_velocity"
482
+ fall_velocity.attrs["units"] = "m/s"
483
+ fall_velocity.attrs["model"] = model
484
+ return fall_velocity.squeeze()