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
@@ -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
@@ -22,6 +22,75 @@ from typing import Optional
22
22
  from disdrodb.api.search import available_stations, get_required_product
23
23
  from disdrodb.utils.cli import execute_cmd
24
24
 
25
+
26
+ def validate_processing_flags_and_get_required_product(**processing_flags):
27
+ """Validate processing flags and determine the required input product.
28
+
29
+ Validates that the processing chain is logically consistent and returns
30
+ the product needed as input for the earliest requested processing step.
31
+
32
+ The processing chain must be contiguous - you cannot skip intermediate levels.
33
+ For example: l1_processing=True, l2e_processing=False, l2m_processing=True is invalid.
34
+
35
+ Raises
36
+ ------
37
+ ValueError
38
+ If no processing levels are enabled or if the processing chain has gaps.
39
+
40
+ Returns
41
+ -------
42
+ str
43
+ The required input product for the processing chain.
44
+ """
45
+ # Define processing chain order and their required inputs
46
+ PROCESSING_CHAIN = [
47
+ ("l0a_processing", "L0A"),
48
+ ("l0b_processing", "L0B"),
49
+ ("l0c_processing", "L0C"),
50
+ ("l1_processing", "L1"),
51
+ ("l2e_processing", "L2E"),
52
+ ("l2m_processing", "L2M"),
53
+ ]
54
+
55
+ # Filter only the processing flags we care about and get enabled levels
56
+ enabled_levels = []
57
+ for level, product in PROCESSING_CHAIN:
58
+ if processing_flags.get(level, False):
59
+ enabled_levels.append((level, product))
60
+
61
+ # Check if at least one processing level is enabled
62
+ if not enabled_levels:
63
+ raise ValueError("At least one processing level must be enabled.")
64
+
65
+ # Get indices of enabled levels in the original chain
66
+ enabled_indices = []
67
+ for level, _ in enabled_levels:
68
+ for i, (chain_level, _) in enumerate(PROCESSING_CHAIN):
69
+ if level == chain_level:
70
+ enabled_indices.append(i)
71
+ break
72
+
73
+ # Check for gaps: all indices between first and last enabled should be present
74
+ first_idx = min(enabled_indices)
75
+ last_idx = max(enabled_indices)
76
+
77
+ expected_indices = set(range(first_idx, last_idx + 1))
78
+ actual_indices = set(enabled_indices)
79
+
80
+ missing_indices = expected_indices - actual_indices
81
+ if missing_indices:
82
+ missing_levels = [PROCESSING_CHAIN[i][0] for i in missing_indices]
83
+ enabled_level_names = [level for level, _ in enabled_levels]
84
+ raise ValueError(
85
+ f"Processing chain has gaps. Enabled levels: {enabled_level_names}. "
86
+ f"Missing intermediate levels: {missing_levels}. "
87
+ f"All levels between the first and last enabled level must be enabled.",
88
+ )
89
+
90
+ # Return the required input product for the earliest enabled level
91
+ return get_required_product(enabled_levels[0][1])
92
+
93
+
25
94
  ####--------------------------------------------------------------------------.
26
95
  #### Run DISDRODB Station Processing
27
96
 
@@ -100,6 +169,13 @@ def run_l0_station(
100
169
  in the DISDRODB active configuration.
101
170
  """
102
171
  # ---------------------------------------------------------------------.
172
+ # Validate processing flags
173
+ _ = validate_processing_flags_and_get_required_product(
174
+ l0a_processing=l0a_processing,
175
+ l0b_processing=l0b_processing,
176
+ l0c_processing=l0c_processing,
177
+ )
178
+ # ---------------------------------------------------------------------.
103
179
  t_i = time.time()
104
180
  print(f"L0 processing of station {station_name} has started.")
105
181
 
@@ -1075,13 +1151,12 @@ def run_l0(
1075
1151
  If ``None``, it uses the ``metadata_archive_dir`` path specified
1076
1152
  in the DISDRODB active configuration.
1077
1153
  """
1078
- # Define starting product
1079
- if l0c_processing:
1080
- required_product = get_required_product("L0C")
1081
- if l0b_processing:
1082
- required_product = get_required_product("L0B")
1083
- if l0a_processing:
1084
- required_product = get_required_product("L0A")
1154
+ # Determine required product based on the lowest level processing requested
1155
+ required_product = validate_processing_flags_and_get_required_product(
1156
+ l0a_processing=l0a_processing,
1157
+ l0b_processing=l0b_processing,
1158
+ l0c_processing=l0c_processing,
1159
+ )
1085
1160
 
1086
1161
  # Get list of available stations
1087
1162
  list_info = available_stations(
@@ -1438,6 +1513,354 @@ def run_l2m(
1438
1513
  print(f"{product} processing of {data_source} {campaign_name} {station_name} station ended.")
1439
1514
 
1440
1515
 
1516
+ ####--------------------------------------------------------------------------.
1517
+ #### Full Processing Wrappers
1518
+ def run_station(
1519
+ data_source,
1520
+ campaign_name,
1521
+ station_name,
1522
+ # L0 archive options
1523
+ l0a_processing: bool = True,
1524
+ l0b_processing: bool = True,
1525
+ l0c_processing: bool = True,
1526
+ remove_l0a: bool = False,
1527
+ remove_l0b: bool = False,
1528
+ # Higher level processing options
1529
+ l1_processing: bool = True,
1530
+ l2e_processing: bool = True,
1531
+ l2m_processing: bool = True,
1532
+ # Processing options
1533
+ force: bool = False,
1534
+ verbose: bool = False,
1535
+ debugging_mode: bool = False,
1536
+ parallel: bool = True,
1537
+ # DISDRODB root directories
1538
+ data_archive_dir: Optional[str] = None,
1539
+ metadata_archive_dir: Optional[str] = None,
1540
+ ):
1541
+ """Run the complete processing chain of a specific DISDRODB station from the terminal.
1542
+
1543
+ Parameters
1544
+ ----------
1545
+ data_source : str
1546
+ Institution name (when campaign data spans more than 1 country),
1547
+ or country (when all campaigns (or sensor networks) are inside a given country).
1548
+ Must be UPPER CASE.
1549
+ campaign_name : str
1550
+ Campaign name. Must be UPPER CASE.
1551
+ station_name : str
1552
+ Station name
1553
+ l0a_processing : bool
1554
+ Whether to launch processing to generate L0A Apache Parquet file(s) from raw data.
1555
+ The default value is ``True``.
1556
+ l0b_processing : bool
1557
+ Whether to launch processing to generate L0B netCDF4 file(s) from L0A data.
1558
+ The default value is ``True``.
1559
+ l0c_processing : bool
1560
+ Whether to launch processing to generate L0C netCDF4 file(s) from L0B data.
1561
+ The default value is ``True``.
1562
+ remove_l0a : bool
1563
+ Whether to keep the L0A files after having generated the L0B netCDF products.
1564
+ The default value is ``False``.
1565
+ remove_l0b : bool
1566
+ Whether to remove the L0B files after having produced L0C netCDF files.
1567
+ The default is False.
1568
+ l1_processing : bool
1569
+ Whether to launch processing to generate L1 netCDF4 file(s) from L0C data.
1570
+ The default value is ``True``.
1571
+ l2e_processing : bool
1572
+ Whether to launch processing to generate L2E netCDF4 file(s) from L1 data.
1573
+ The default value is ``True``.
1574
+ l2m_processing : bool
1575
+ Whether to launch processing to generate L2M netCDF4 file(s) from L1 data.
1576
+ The default value is ``True``.
1577
+ force : bool
1578
+ If ``True``, overwrite existing data into destination directories.
1579
+ If ``False``, raise an error if there are already data into destination directories.
1580
+ The default value is ``False``.
1581
+ verbose : bool
1582
+ Whether to print detailed processing information into terminal.
1583
+ The default value is ``True``.
1584
+ parallel : bool
1585
+ If ``True``, the files are processed simultaneously in multiple processes.
1586
+ Each process will use a single thread to avoid issues with the HDF/netCDF library.
1587
+ By default, the number of process is defined with ``os.cpu_count()``.
1588
+ If ``False``, the files are processed sequentially in a single process.
1589
+ If ``False``, multi-threading is automatically exploited to speed up I/0 tasks.
1590
+ debugging_mode : bool
1591
+ If ``True``, it reduces the amount of data to process.
1592
+ For L0A, it processes just the first 3 raw data files for each station.
1593
+ For L0B, it processes 100 rows sampled from 3 L0A files for each station.
1594
+ The default value is ``False``.
1595
+ data_archive_dir : str (optional)
1596
+ The directory path where the DISDRODB Data Archive is located.
1597
+ The directory path must end with ``<...>/DISDRODB``.
1598
+ If ``None``, it uses the ``data_archive_dir`` path specified
1599
+ in the DISDRODB active configuration.
1600
+ metadata_archive_dir : str (optional)
1601
+ The directory path where the DISDRODB Metadata Archive is located.
1602
+ The directory path must end with ``<...>/DISDRODB-METADATA/DISDRODB``.
1603
+ If ``None``, it uses the ``metadata_archive_dir`` path specified
1604
+ in the DISDRODB active configuration.
1605
+ """
1606
+ # ---------------------------------------------------------------------.
1607
+ # Validate processing flags
1608
+ _ = validate_processing_flags_and_get_required_product(
1609
+ l0a_processing=l0a_processing,
1610
+ l0b_processing=l0b_processing,
1611
+ l0c_processing=l0c_processing,
1612
+ l1_processing=l1_processing,
1613
+ l2e_processing=l2e_processing,
1614
+ l2m_processing=l2m_processing,
1615
+ )
1616
+
1617
+ # ---------------------------------------------------------------------.
1618
+ t_i = time.time()
1619
+ print(f"Complete processing of station {station_name} has started.")
1620
+
1621
+ # ------------------------------------------------------------------.
1622
+ # L0 processing (L0A, L0B, L0C)
1623
+ if l0a_processing or l0b_processing or l0c_processing:
1624
+ run_l0_station(
1625
+ # DISDRODB root directories
1626
+ data_archive_dir=data_archive_dir,
1627
+ metadata_archive_dir=metadata_archive_dir,
1628
+ # Station arguments
1629
+ data_source=data_source,
1630
+ campaign_name=campaign_name,
1631
+ station_name=station_name,
1632
+ # L0 archive options
1633
+ l0a_processing=l0a_processing,
1634
+ l0b_processing=l0b_processing,
1635
+ l0c_processing=l0c_processing,
1636
+ remove_l0a=remove_l0a,
1637
+ remove_l0b=remove_l0b,
1638
+ # Processing options
1639
+ force=force,
1640
+ verbose=verbose,
1641
+ debugging_mode=debugging_mode,
1642
+ parallel=parallel,
1643
+ )
1644
+
1645
+ # ------------------------------------------------------------------.
1646
+ # L1 processing
1647
+ if l1_processing:
1648
+ run_l1_station(
1649
+ # DISDRODB root directories
1650
+ data_archive_dir=data_archive_dir,
1651
+ metadata_archive_dir=metadata_archive_dir,
1652
+ # Station arguments
1653
+ data_source=data_source,
1654
+ campaign_name=campaign_name,
1655
+ station_name=station_name,
1656
+ # Processing options
1657
+ force=force,
1658
+ verbose=verbose,
1659
+ debugging_mode=debugging_mode,
1660
+ parallel=parallel,
1661
+ )
1662
+
1663
+ # ------------------------------------------------------------------.
1664
+ # L2E processing
1665
+ if l2e_processing:
1666
+ run_l2e_station(
1667
+ # DISDRODB root directories
1668
+ data_archive_dir=data_archive_dir,
1669
+ metadata_archive_dir=metadata_archive_dir,
1670
+ # Station arguments
1671
+ data_source=data_source,
1672
+ campaign_name=campaign_name,
1673
+ station_name=station_name,
1674
+ # Processing options
1675
+ force=force,
1676
+ verbose=verbose,
1677
+ debugging_mode=debugging_mode,
1678
+ parallel=parallel,
1679
+ )
1680
+
1681
+ # ------------------------------------------------------------------.
1682
+ # L2M processing
1683
+ if l2m_processing:
1684
+ run_l2m_station(
1685
+ # DISDRODB root directories
1686
+ data_archive_dir=data_archive_dir,
1687
+ metadata_archive_dir=metadata_archive_dir,
1688
+ # Station arguments
1689
+ data_source=data_source,
1690
+ campaign_name=campaign_name,
1691
+ station_name=station_name,
1692
+ # Processing options
1693
+ force=force,
1694
+ verbose=verbose,
1695
+ debugging_mode=debugging_mode,
1696
+ parallel=parallel,
1697
+ )
1698
+
1699
+ # -------------------------------------------------------------------------.
1700
+ # End of complete processing for station
1701
+ timedelta_str = str(datetime.timedelta(seconds=round(time.time() - t_i)))
1702
+ print(f"Complete processing of station {station_name} completed in {timedelta_str}")
1703
+
1704
+
1705
+ def run(
1706
+ data_sources=None,
1707
+ campaign_names=None,
1708
+ station_names=None,
1709
+ # L0 archive options
1710
+ l0a_processing: bool = True,
1711
+ l0b_processing: bool = True,
1712
+ l0c_processing: bool = True,
1713
+ remove_l0a: bool = False,
1714
+ remove_l0b: bool = False,
1715
+ # Higher level processing options
1716
+ l1_processing: bool = True,
1717
+ l2e_processing: bool = True,
1718
+ l2m_processing: bool = True,
1719
+ # Processing options
1720
+ force: bool = False,
1721
+ verbose: bool = False,
1722
+ debugging_mode: bool = False,
1723
+ parallel: bool = True,
1724
+ # DISDRODB root directories
1725
+ data_archive_dir: Optional[str] = None,
1726
+ metadata_archive_dir: Optional[str] = None,
1727
+ ):
1728
+ """Run the complete processing chain of DISDRODB stations.
1729
+
1730
+ This function allows to launch the complete processing of many DISDRODB stations with a single command.
1731
+ From the list of all available DISDRODB stations, it runs the processing of the
1732
+ stations matching the provided data_sources, campaign_names and station_names.
1733
+
1734
+ Parameters
1735
+ ----------
1736
+ data_sources : list
1737
+ Name of data source(s) to process.
1738
+ The name(s) must be UPPER CASE.
1739
+ If campaign_names and station are not specified, process all stations.
1740
+ The default value is ``None``.
1741
+ campaign_names : list
1742
+ Name of the campaign(s) to process.
1743
+ The name(s) must be UPPER CASE.
1744
+ The default value is ``None``.
1745
+ station_names : list
1746
+ Station names to process.
1747
+ The default value is ``None``.
1748
+ l0a_processing : bool
1749
+ Whether to launch processing to generate L0A Apache Parquet file(s) from raw data.
1750
+ The default value is ``True``.
1751
+ l0b_processing : bool
1752
+ Whether to launch processing to generate L0B netCDF4 file(s) from L0A data.
1753
+ The default value is ``True``.
1754
+ l0c_processing : bool
1755
+ Whether to launch processing to generate L0C netCDF4 file(s) from L0B data.
1756
+ The default value is ``True``.
1757
+ remove_l0a : bool
1758
+ Whether to keep the L0A files after having generated the L0B netCDF products.
1759
+ The default value is ``False``.
1760
+ remove_l0b : bool
1761
+ Whether to remove the L0B files after having produced L0C netCDF files.
1762
+ The default value is ``False``.
1763
+ l1_processing : bool
1764
+ Whether to launch processing to generate L1 netCDF4 file(s) from L0C data.
1765
+ The default value is ``True``.
1766
+ l2e_processing : bool
1767
+ Whether to launch processing to generate L2E netCDF4 file(s) from L1 data.
1768
+ The default value is ``True``.
1769
+ l2m_processing : bool
1770
+ Whether to launch processing to generate L2M netCDF4 file(s) from L1 data.
1771
+ The default value is ``True``.
1772
+ force : bool
1773
+ If ``True``, overwrite existing data into destination directories.
1774
+ If ``False``, raise an error if there are already data into destination directories.
1775
+ The default value is ``False``.
1776
+ verbose : bool
1777
+ Whether to print detailed processing information into terminal.
1778
+ The default value is ``False``.
1779
+ parallel : bool
1780
+ If ``True``, the files are processed simultaneously in multiple processes.
1781
+ Each process will use a single thread to avoid issues with the HDF/netCDF library.
1782
+ By default, the number of process is defined with ``os.cpu_count()``.
1783
+ If ``False``, the files are processed sequentially in a single process.
1784
+ If ``False``, multi-threading is automatically exploited to speed up I/0 tasks.
1785
+ debugging_mode : bool
1786
+ If ``True``, it reduces the amount of data to process.
1787
+ For L0A, it processes just the first 3 raw data files.
1788
+ For L0B, it processes 100 rows sampled from 3 L0A files.
1789
+ The default value is ``False``.
1790
+ data_archive_dir : str (optional)
1791
+ The directory path where the DISDRODB Data Archive is located.
1792
+ The directory path must end with ``<...>/DISDRODB``.
1793
+ If ``None``, it uses the ``data_archive_dir`` path specified
1794
+ in the DISDRODB active configuration.
1795
+ metadata_archive_dir : str (optional)
1796
+ The directory path where the DISDRODB Metadata Archive is located.
1797
+ The directory path must end with ``<...>/DISDRODB-METADATA/DISDRODB``.
1798
+ If ``None``, it uses the ``metadata_archive_dir`` path specified
1799
+ in the DISDRODB active configuration.
1800
+ """
1801
+ # Determine required product based on the lowest level processing requested
1802
+ required_product = validate_processing_flags_and_get_required_product(
1803
+ l0a_processing=l0a_processing,
1804
+ l0b_processing=l0b_processing,
1805
+ l0c_processing=l0c_processing,
1806
+ l1_processing=l1_processing,
1807
+ l2e_processing=l2e_processing,
1808
+ l2m_processing=l2m_processing,
1809
+ )
1810
+
1811
+ # Get list of available stations
1812
+ list_info = available_stations(
1813
+ # DISDRODB root directories
1814
+ data_archive_dir=data_archive_dir,
1815
+ metadata_archive_dir=metadata_archive_dir,
1816
+ # Stations arguments
1817
+ data_sources=data_sources,
1818
+ campaign_names=campaign_names,
1819
+ station_names=station_names,
1820
+ # Search options
1821
+ product=required_product,
1822
+ raise_error_if_empty=True,
1823
+ )
1824
+
1825
+ # Print message
1826
+ n_stations = len(list_info)
1827
+ print(f"Complete processing of {n_stations} stations started.")
1828
+
1829
+ # Loop over stations
1830
+ for data_source, campaign_name, station_name in list_info:
1831
+ print(f"Complete processing of {data_source} {campaign_name} {station_name} station started.")
1832
+ # Run processing
1833
+ run_station(
1834
+ # DISDRODB root directories
1835
+ data_archive_dir=data_archive_dir,
1836
+ metadata_archive_dir=metadata_archive_dir,
1837
+ # Station arguments
1838
+ data_source=data_source,
1839
+ campaign_name=campaign_name,
1840
+ station_name=station_name,
1841
+ # L0 archive options
1842
+ l0a_processing=l0a_processing,
1843
+ l0b_processing=l0b_processing,
1844
+ l0c_processing=l0c_processing,
1845
+ remove_l0a=remove_l0a,
1846
+ remove_l0b=remove_l0b,
1847
+ # Higher level processing options
1848
+ l1_processing=l1_processing,
1849
+ l2e_processing=l2e_processing,
1850
+ l2m_processing=l2m_processing,
1851
+ # Process options
1852
+ force=force,
1853
+ verbose=verbose,
1854
+ debugging_mode=debugging_mode,
1855
+ parallel=parallel,
1856
+ )
1857
+ print(f"Complete processing of {data_source} {campaign_name} {station_name} station ended.")
1858
+
1859
+ print(f"Complete processing of {n_stations} stations completed.")
1860
+
1861
+
1862
+ ####--------------------------------------------------------------------------.
1863
+ #### Summary Wrappers
1441
1864
  def create_summary(
1442
1865
  data_sources=None,
1443
1866
  campaign_names=None,
@@ -1508,6 +1931,3 @@ def create_summary(
1508
1931
  temporal_resolution=temporal_resolution,
1509
1932
  )
1510
1933
  print("Creation of station summaries has terminated.")
1511
-
1512
-
1513
- ####--------------------------------------------------------------------------.
@@ -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
@@ -79,9 +79,9 @@ def get_axis_ratio_andsager_1999(diameter):
79
79
  return axis_ratio
80
80
 
81
81
 
82
- def get_axis_ratio_battaglia_2010(diameter):
82
+ def get_axis_ratio_parsivel(diameter):
83
83
  """
84
- Compute the axis ratio of raindrops using the Battaglia et al. (2010) model.
84
+ Compute the axis ratio of raindrops as used by OTT Parsivel sensors.
85
85
 
86
86
  This axis ratio is assumed by OTT Parsivel sensors internally to compute the
87
87
  reported particle size (Deq).
@@ -279,7 +279,7 @@ def get_axis_ratio_thurai_2007(diameter):
279
279
  AXIS_RATIO_MODELS = {
280
280
  "Thurai2005": get_axis_ratio_thurai_2005,
281
281
  "Thurai2007": get_axis_ratio_thurai_2007,
282
- "Battaglia2010": get_axis_ratio_battaglia_2010,
282
+ "Parsivel": get_axis_ratio_parsivel,
283
283
  "Brandes2002": get_axis_ratio_brandes_2002,
284
284
  "Pruppacher1970": get_axis_ratio_pruppacher_1970,
285
285
  "Beard1987": get_axis_ratio_beard_1987,
@@ -307,7 +307,7 @@ def get_axis_ratio_model(model):
307
307
  ----------
308
308
  model : str
309
309
  The model to use for calculating the axis ratio. Available models are:
310
- 'Thurai2005', 'Thurai2007', 'Battaglia2010', 'Brandes2002',
310
+ 'Thurai2005', 'Thurai2007', 'Parsivel', 'Brandes2002',
311
311
  'Pruppacher1970', 'Beard1987', 'Andsager1999'.
312
312
 
313
313
  Returns
@@ -339,7 +339,7 @@ def get_axis_ratio(diameter, model):
339
339
  Raindrops diameter in mm.
340
340
  model : str
341
341
  The axis ratio model to use for calculating the axis ratio. Available models are:
342
- 'Thurai2005', 'Thurai2007', 'Battaglia2010', 'Brandes2002',
342
+ 'Thurai2005', 'Thurai2007', 'Parsivel', 'Brandes2002',
343
343
  'Pruppacher1970', 'Beard1987', 'Andsager1999'.
344
344
 
345
345
  Returns
@@ -1,5 +1,5 @@
1
1
  # -----------------------------------------------------------------------------.
2
- # Copyright (c) 2021-2023 DISDRODB developers
2
+ # Copyright (c) 2021-2026 DISDRODB developers
3
3
  #
4
4
  # temperaturehis 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
@@ -56,7 +56,7 @@ def get_refractive_index_function(permittivity_model):
56
56
  ----------
57
57
  model : str
58
58
  The model to use for calculating the complex refractive index. Available models are:
59
- 'Liebe1991', 'Liebe1991v2', 'Ellison2005', 'Turner2016', 'Turner2016SLC'.
59
+ 'Liebe1991', 'Liebe1991v2', 'Ellison2007', 'Turner2016', 'Turner2016SLC'.
60
60
 
61
61
  Returns
62
62
  -------
@@ -104,7 +104,7 @@ def get_refractive_index(temperature, frequency, permittivity_model):
104
104
  Frequency in GHz.
105
105
  permittivity_model : str
106
106
  The permittivity model to use for calculating the complex refractive index.
107
- Available models are: 'Liebe1991', 'Liebe1991v2', 'Ellison2005', 'Turner2016', 'Turner2016SLC'.
107
+ Available models are: 'Liebe1991', 'Liebe1991v2', 'Ellison2007', 'Turner2016', 'Turner2016SLC'.
108
108
  See available models with ``disdrodb.scattering.available_permittivity_models()``.
109
109
 
110
110
  Returns
@@ -309,7 +309,7 @@ def get_rain_refractive_index_liebe1991(temperature, frequency):
309
309
  return m
310
310
 
311
311
 
312
- def get_rain_refractive_index_ellison2005(temperature, frequency):
312
+ def get_rain_refractive_index_ellison2007(temperature, frequency):
313
313
  """Compute the complex refractive index according to Ellison (2005) model.
314
314
 
315
315
  Parameters
@@ -343,8 +343,8 @@ def get_rain_refractive_index_ellison2005(temperature, frequency):
343
343
  temperature = ensure_array(temperature)
344
344
 
345
345
  # Check frequency and temperature within validity range
346
- temperature = check_temperature_validity_range(temperature, vmin=0, vmax=100, permittivity_model="Ellison2005")
347
- frequency = check_frequency_validity_range(frequency, vmin=0, vmax=1000, permittivity_model="Ellison2005")
346
+ temperature = check_temperature_validity_range(temperature, vmin=0, vmax=100, permittivity_model="Ellison2007")
347
+ frequency = check_frequency_validity_range(frequency, vmin=0, vmax=1000, permittivity_model="Ellison2007")
348
348
 
349
349
  # Conversion of frequency to Hz
350
350
  frequency = frequency / 1e-9
@@ -479,7 +479,7 @@ def get_rain_refractive_index_turner2016(frequency, temperature):
479
479
  def get_rayleigh_dielectric_factor(m):
480
480
  """Compute the Rayleigh dielectric factor |K|**2 from the complex refractive index.
481
481
 
482
- The magnitude squared of the complex dielectric contrast factor for liquid water,
482
+ The magnitude squared of the complex dielectric constant factor for liquid water,
483
483
  relative to the surrounding medium (typically air).
484
484
 
485
485
  This factor is used to compute the radar reflectivity.
@@ -505,6 +505,6 @@ def get_rayleigh_dielectric_factor(m):
505
505
  REFRACTIVE_INDEX_MODELS = {
506
506
  "Liebe1991": get_rain_refractive_index_liebe1991,
507
507
  "Liebe1991single": get_rain_refractive_index_liebe1991_single,
508
- "Ellison2005": get_rain_refractive_index_ellison2005,
508
+ "Ellison2007": get_rain_refractive_index_ellison2007,
509
509
  "Turner2016": get_rain_refractive_index_turner2016,
510
510
  }
@@ -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
@@ -26,7 +26,6 @@ import xarray as xr
26
26
 
27
27
  from disdrodb.configs import get_scattering_table_dir
28
28
  from disdrodb.constants import DIAMETER_DIMENSION
29
- from disdrodb.l1.filters import filter_diameter_bins
30
29
  from disdrodb.psd.models import BinnedPSD, create_psd, get_required_parameters
31
30
  from disdrodb.scattering.axis_ratio import check_axis_ratio_model, get_axis_ratio_model
32
31
  from disdrodb.scattering.permittivity import (
@@ -35,7 +34,7 @@ from disdrodb.scattering.permittivity import (
35
34
  get_refractive_index,
36
35
  )
37
36
  from disdrodb.utils.logger import log_info
38
- from disdrodb.utils.manipulations import get_diameter_bin_edges
37
+ from disdrodb.utils.manipulations import filter_diameter_bins, get_diameter_bin_edges
39
38
  from disdrodb.utils.warnings import suppress_warnings
40
39
 
41
40
  logger = logging.getLogger(__name__)
@@ -76,15 +75,26 @@ def check_radar_band(radar_band):
76
75
  return radar_band
77
76
 
78
77
 
78
+ def _is_valid_numeric_frequency(frequency):
79
+ numeric_value = float(frequency)
80
+ if numeric_value <= 0:
81
+ raise ValueError(f"Frequency must be positive, got {numeric_value}")
82
+ return numeric_value
83
+
84
+
79
85
  def _check_frequency(frequency):
80
86
  """Check the validity of the specified frequency."""
81
87
  if isinstance(frequency, str):
82
- frequency = check_radar_band(frequency)
83
- frequency = frequency_dict[frequency]
84
- return frequency
85
- if not isinstance(frequency, (int, float)):
86
- raise TypeError(f"Frequency {frequency} must be a string or a number.")
87
- return frequency
88
+ try:
89
+ frequency = float(frequency)
90
+
91
+ except ValueError:
92
+ # Not numeric, assume radar band name
93
+ frequency = check_radar_band(frequency)
94
+ frequency = frequency_dict[frequency]
95
+ if isinstance(frequency, (int, float)):
96
+ return _is_valid_numeric_frequency(frequency)
97
+ raise TypeError(f"Frequency {frequency} must be a string or a number.")
88
98
 
89
99
 
90
100
  def ensure_numerical_frequency(frequency):
@@ -476,6 +486,11 @@ def compute_radar_variables(scatterer):
476
486
 
477
487
  To speed up computations, this function should input a scatterer object with
478
488
  a preinitialized scattering table.
489
+
490
+ Note
491
+ ----
492
+ If this function is modified to compute additional radar variables, the global
493
+ variable RADAR_VARIABLES must be updated accordingly !
479
494
  """
480
495
  from pytmatrix import radar
481
496
 
@@ -495,10 +510,13 @@ def compute_radar_variables(scatterer):
495
510
  radar_vars["ZDR"] = 10 * np.log10(radar.Zdr(scatterer)) # dB
496
511
  radar_vars["ZDR"] = np.where(np.isfinite(radar_vars["ZDR"]), radar_vars["ZDR"], np.nan)
497
512
 
498
- radar_vars["LDR"] = 10 * np.log10(radar.ldr(scatterer)) # dBZ
499
- radar_vars["LDR"] = np.where(np.isfinite(radar_vars["LDR"]), radar_vars["LDR"], np.nan)
513
+ radar_vars["LDRH"] = 10 * np.log10(radar.ldr(scatterer, h_pol=True)) # dBZ
514
+ radar_vars["LDRH"] = np.where(np.isfinite(radar_vars["LDRH"]), radar_vars["LDRH"], np.nan)
515
+
516
+ radar_vars["LDRV"] = 10 * np.log10(radar.ldr(scatterer, h_pol=False)) # dBZ
517
+ radar_vars["LDRV"] = np.where(np.isfinite(radar_vars["LDRV"]), radar_vars["LDRV"], np.nan)
500
518
 
501
- radar_vars["RHOHV"] = radar.rho_hv(scatterer) # deg/km
519
+ radar_vars["RHOHV"] = radar.rho_hv(scatterer) # [-]
502
520
  radar_vars["DELTAHV"] = radar.delta_hv(scatterer) * 180.0 / np.pi # [deg]
503
521
 
504
522
  # Set forward scattering for attenuation and phase calculations
@@ -512,7 +530,7 @@ def compute_radar_variables(scatterer):
512
530
 
513
531
  # Radar variables computed by DISDRODB
514
532
  # - Must reflect dictionary order output of compute_radar_variables
515
- RADAR_VARIABLES = ["DBZH", "DBZV", "ZDR", "LDR", "RHOHV", "DELTAHV", "KDP", "AH", "AV", "ADP"]
533
+ RADAR_VARIABLES = ["DBZH", "DBZV", "ZDR", "LDRH", "LDRV", "RHOHV", "DELTAHV", "KDP", "AH", "AV", "ADP"]
516
534
 
517
535
 
518
536
  def _try_compute_radar_variables(scatterer):