disdrodb 0.0.21__py3-none-any.whl → 0.1.1__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 (279) hide show
  1. disdrodb/__init__.py +132 -15
  2. disdrodb/_config.py +4 -2
  3. disdrodb/_version.py +9 -4
  4. disdrodb/api/checks.py +264 -237
  5. disdrodb/api/configs.py +4 -8
  6. disdrodb/api/create_directories.py +235 -290
  7. disdrodb/api/info.py +217 -26
  8. disdrodb/api/io.py +306 -270
  9. disdrodb/api/path.py +597 -173
  10. disdrodb/api/search.py +486 -0
  11. disdrodb/{metadata/scripts → cli}/disdrodb_check_metadata_archive.py +12 -7
  12. disdrodb/{utils/pandas.py → cli/disdrodb_data_archive_directory.py} +9 -18
  13. disdrodb/cli/disdrodb_download_archive.py +86 -0
  14. disdrodb/cli/disdrodb_download_metadata_archive.py +53 -0
  15. disdrodb/cli/disdrodb_download_station.py +84 -0
  16. disdrodb/{api/scripts → cli}/disdrodb_initialize_station.py +22 -10
  17. disdrodb/cli/disdrodb_metadata_archive_directory.py +32 -0
  18. disdrodb/{data_transfer/scripts/disdrodb_download_station.py → cli/disdrodb_open_data_archive.py} +22 -22
  19. disdrodb/cli/disdrodb_open_logs_directory.py +69 -0
  20. disdrodb/{data_transfer/scripts/disdrodb_upload_station.py → cli/disdrodb_open_metadata_archive.py} +22 -24
  21. disdrodb/cli/disdrodb_open_metadata_directory.py +71 -0
  22. disdrodb/cli/disdrodb_open_product_directory.py +74 -0
  23. disdrodb/cli/disdrodb_open_readers_directory.py +32 -0
  24. disdrodb/{l0/scripts → cli}/disdrodb_run_l0.py +38 -31
  25. disdrodb/{l0/scripts → cli}/disdrodb_run_l0_station.py +32 -30
  26. disdrodb/{l0/scripts → cli}/disdrodb_run_l0a.py +30 -21
  27. disdrodb/{l0/scripts → cli}/disdrodb_run_l0a_station.py +24 -33
  28. disdrodb/{l0/scripts → cli}/disdrodb_run_l0b.py +30 -21
  29. disdrodb/{l0/scripts → cli}/disdrodb_run_l0b_station.py +25 -34
  30. disdrodb/cli/disdrodb_run_l0c.py +130 -0
  31. disdrodb/cli/disdrodb_run_l0c_station.py +129 -0
  32. disdrodb/cli/disdrodb_run_l1.py +122 -0
  33. disdrodb/cli/disdrodb_run_l1_station.py +121 -0
  34. disdrodb/cli/disdrodb_run_l2e.py +122 -0
  35. disdrodb/cli/disdrodb_run_l2e_station.py +122 -0
  36. disdrodb/cli/disdrodb_run_l2m.py +122 -0
  37. disdrodb/cli/disdrodb_run_l2m_station.py +122 -0
  38. disdrodb/cli/disdrodb_upload_archive.py +105 -0
  39. disdrodb/cli/disdrodb_upload_station.py +98 -0
  40. disdrodb/configs.py +90 -25
  41. disdrodb/data_transfer/__init__.py +22 -0
  42. disdrodb/data_transfer/download_data.py +87 -90
  43. disdrodb/data_transfer/upload_data.py +64 -37
  44. disdrodb/data_transfer/zenodo.py +15 -18
  45. disdrodb/docs.py +1 -1
  46. disdrodb/issue/__init__.py +17 -4
  47. disdrodb/issue/checks.py +10 -23
  48. disdrodb/issue/reader.py +9 -12
  49. disdrodb/issue/writer.py +14 -17
  50. disdrodb/l0/__init__.py +17 -26
  51. disdrodb/l0/check_configs.py +35 -23
  52. disdrodb/l0/check_standards.py +46 -51
  53. disdrodb/l0/configs/{Thies_LPM → LPM}/bins_diameter.yml +44 -44
  54. disdrodb/l0/configs/{Thies_LPM → LPM}/bins_velocity.yml +40 -40
  55. disdrodb/l0/configs/LPM/l0a_encodings.yml +80 -0
  56. disdrodb/l0/configs/{Thies_LPM → LPM}/l0b_cf_attrs.yml +84 -65
  57. disdrodb/l0/configs/{Thies_LPM → LPM}/l0b_encodings.yml +50 -9
  58. disdrodb/l0/configs/{Thies_LPM → LPM}/raw_data_format.yml +285 -245
  59. disdrodb/l0/configs/{OTT_Parsivel → PARSIVEL}/bins_diameter.yml +66 -66
  60. disdrodb/l0/configs/{OTT_Parsivel → PARSIVEL}/bins_velocity.yml +64 -64
  61. disdrodb/l0/configs/PARSIVEL/l0a_encodings.yml +32 -0
  62. disdrodb/l0/configs/{OTT_Parsivel → PARSIVEL}/l0b_cf_attrs.yml +23 -21
  63. disdrodb/l0/configs/{OTT_Parsivel → PARSIVEL}/l0b_encodings.yml +17 -17
  64. disdrodb/l0/configs/{OTT_Parsivel → PARSIVEL}/raw_data_format.yml +77 -77
  65. disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/bins_diameter.yml +64 -64
  66. disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/bins_velocity.yml +64 -64
  67. disdrodb/l0/configs/PARSIVEL2/l0a_encodings.yml +39 -0
  68. disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/l0b_cf_attrs.yml +28 -26
  69. disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/l0b_encodings.yml +20 -20
  70. disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/raw_data_format.yml +107 -107
  71. disdrodb/l0/configs/PWS100/bins_diameter.yml +173 -0
  72. disdrodb/l0/configs/PWS100/bins_velocity.yml +173 -0
  73. disdrodb/l0/configs/PWS100/l0a_encodings.yml +19 -0
  74. disdrodb/l0/configs/PWS100/l0b_cf_attrs.yml +76 -0
  75. disdrodb/l0/configs/PWS100/l0b_encodings.yml +176 -0
  76. disdrodb/l0/configs/PWS100/raw_data_format.yml +182 -0
  77. disdrodb/l0/configs/{RD_80 → RD80}/bins_diameter.yml +40 -40
  78. disdrodb/l0/configs/RD80/l0a_encodings.yml +16 -0
  79. disdrodb/l0/configs/{RD_80 → RD80}/l0b_cf_attrs.yml +3 -3
  80. disdrodb/l0/configs/RD80/l0b_encodings.yml +135 -0
  81. disdrodb/l0/configs/{RD_80 → RD80}/raw_data_format.yml +46 -50
  82. disdrodb/l0/l0_reader.py +216 -340
  83. disdrodb/l0/l0a_processing.py +237 -208
  84. disdrodb/l0/l0b_nc_processing.py +227 -80
  85. disdrodb/l0/l0b_processing.py +96 -174
  86. disdrodb/l0/l0c_processing.py +627 -0
  87. disdrodb/l0/readers/{ARM → LPM/ARM}/ARM_LPM.py +36 -58
  88. disdrodb/l0/readers/LPM/AUSTRALIA/MELBOURNE_2007_LPM.py +236 -0
  89. disdrodb/l0/readers/LPM/BRAZIL/CHUVA_LPM.py +185 -0
  90. disdrodb/l0/readers/LPM/BRAZIL/GOAMAZON_LPM.py +185 -0
  91. disdrodb/l0/readers/LPM/ITALY/GID_LPM.py +195 -0
  92. disdrodb/l0/readers/LPM/ITALY/GID_LPM_W.py +210 -0
  93. disdrodb/l0/readers/{BRAZIL/GOAMAZON_LPM.py → LPM/KIT/CHWALA.py} +97 -76
  94. disdrodb/l0/readers/LPM/SLOVENIA/ARSO.py +197 -0
  95. disdrodb/l0/readers/LPM/SLOVENIA/CRNI_VRH.py +197 -0
  96. disdrodb/l0/readers/{UK → LPM/UK}/DIVEN.py +14 -35
  97. disdrodb/l0/readers/PARSIVEL/AUSTRALIA/MELBOURNE_2007_PARSIVEL.py +157 -0
  98. disdrodb/l0/readers/PARSIVEL/CHINA/CHONGQING.py +113 -0
  99. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/ARCTIC_2021.py +40 -57
  100. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/COMMON_2011.py +37 -54
  101. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/DAVOS_2009_2011.py +34 -51
  102. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/EPFL_2009.py +34 -51
  103. disdrodb/l0/readers/{EPFL/PARADISO_2014.py → PARSIVEL/EPFL/EPFL_ROOF_2008.py} +38 -50
  104. disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2010.py +105 -0
  105. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/EPFL_ROOF_2011.py +34 -51
  106. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/EPFL_ROOF_2012.py +33 -51
  107. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/GENEPI_2007.py +25 -44
  108. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/GRAND_ST_BERNARD_2007.py +25 -44
  109. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/GRAND_ST_BERNARD_2007_2.py +25 -44
  110. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/HPICONET_2010.py +34 -51
  111. disdrodb/l0/readers/{EPFL/EPFL_ROOF_2010.py → PARSIVEL/EPFL/HYMEX_LTE_SOP2.py} +37 -50
  112. disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP3.py +111 -0
  113. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/HYMEX_LTE_SOP4.py +36 -54
  114. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/LOCARNO_2018.py +34 -52
  115. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/LOCARNO_2019.py +38 -56
  116. disdrodb/l0/readers/PARSIVEL/EPFL/PARADISO_2014.py +105 -0
  117. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/PARSIVEL_2007.py +27 -45
  118. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/PLATO_2019.py +24 -44
  119. disdrodb/l0/readers/PARSIVEL/EPFL/RACLETS_2019.py +140 -0
  120. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/RACLETS_2019_WJF.py +41 -59
  121. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/RIETHOLZBACH_2011.py +34 -51
  122. disdrodb/l0/readers/PARSIVEL/EPFL/SAMOYLOV_2017.py +117 -0
  123. disdrodb/l0/readers/PARSIVEL/EPFL/SAMOYLOV_2019.py +137 -0
  124. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/UNIL_2022.py +42 -55
  125. disdrodb/l0/readers/PARSIVEL/GPM/IFLOODS.py +104 -0
  126. disdrodb/l0/readers/{GPM → PARSIVEL/GPM}/LPVEX.py +29 -48
  127. disdrodb/l0/readers/PARSIVEL/GPM/MC3E.py +184 -0
  128. disdrodb/l0/readers/PARSIVEL/KIT/BURKINA_FASO.py +133 -0
  129. disdrodb/l0/readers/PARSIVEL/NCAR/CCOPE_2015.py +113 -0
  130. disdrodb/l0/readers/{NCAR/VORTEX_SE_2016_P1.py → PARSIVEL/NCAR/OWLES_MIPS.py} +46 -72
  131. disdrodb/l0/readers/PARSIVEL/NCAR/PECAN_MOBILE.py +125 -0
  132. disdrodb/l0/readers/{NCAR/OWLES_MIPS.py → PARSIVEL/NCAR/PLOWS_MIPS.py} +45 -64
  133. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2009.py +114 -0
  134. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2010.py +176 -0
  135. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2010_UF.py +183 -0
  136. disdrodb/l0/readers/PARSIVEL/SLOVENIA/UL_FGG.py +121 -0
  137. disdrodb/l0/readers/{ARM/ARM_LD.py → PARSIVEL2/ARM/ARM_PARSIVEL2.py} +27 -50
  138. disdrodb/l0/readers/PARSIVEL2/BRAZIL/CHUVA_PARSIVEL2.py +163 -0
  139. disdrodb/l0/readers/PARSIVEL2/BRAZIL/GOAMAZON_PARSIVEL2.py +163 -0
  140. disdrodb/l0/readers/{DENMARK → PARSIVEL2/DENMARK}/EROSION_nc.py +14 -35
  141. disdrodb/l0/readers/PARSIVEL2/FRANCE/ENPC_PARSIVEL2.py +189 -0
  142. disdrodb/l0/readers/PARSIVEL2/FRANCE/SIRTA_PARSIVEL2.py +119 -0
  143. disdrodb/l0/readers/PARSIVEL2/GPM/GCPEX.py +104 -0
  144. disdrodb/l0/readers/PARSIVEL2/GPM/NSSTC.py +176 -0
  145. disdrodb/l0/readers/PARSIVEL2/ITALY/GID_PARSIVEL2.py +32 -0
  146. disdrodb/l0/readers/PARSIVEL2/MEXICO/OH_IIUNAM_nc.py +56 -0
  147. disdrodb/l0/readers/PARSIVEL2/NCAR/PECAN_FP3.py +120 -0
  148. disdrodb/l0/readers/{NCAR → PARSIVEL2/NCAR}/PECAN_MIPS.py +45 -64
  149. disdrodb/l0/readers/PARSIVEL2/NCAR/RELAMPAGO_PARSIVEL2.py +181 -0
  150. disdrodb/l0/readers/PARSIVEL2/NCAR/SNOWIE_PJ.py +160 -0
  151. disdrodb/l0/readers/PARSIVEL2/NCAR/SNOWIE_SB.py +160 -0
  152. disdrodb/l0/readers/{NCAR/PLOWS_MIPS.py → PARSIVEL2/NCAR/VORTEX_SE_2016_P1.py} +49 -66
  153. disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_P2.py +118 -0
  154. disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_PIPS.py +152 -0
  155. disdrodb/l0/readers/PARSIVEL2/NETHERLANDS/DELFT.py +166 -0
  156. disdrodb/l0/readers/PWS100/FRANCE/ENPC_PWS100.py +150 -0
  157. disdrodb/l0/readers/{NCAR/RELAMPAGO_RD80.py → RD80/BRAZIL/CHUVA_RD80.py} +36 -60
  158. disdrodb/l0/readers/{BRAZIL → RD80/BRAZIL}/GOAMAZON_RD80.py +36 -55
  159. disdrodb/l0/readers/{NCAR → RD80/NCAR}/CINDY_2011_RD80.py +35 -54
  160. disdrodb/l0/readers/{BRAZIL/CHUVA_RD80.py → RD80/NCAR/RELAMPAGO_RD80.py} +40 -54
  161. disdrodb/l0/readers/RD80/NOAA/PSL_RD80.py +274 -0
  162. disdrodb/l0/readers/template_reader_raw_netcdf_data.py +62 -0
  163. disdrodb/l0/readers/{reader_template.py → template_reader_raw_text_data.py} +20 -44
  164. disdrodb/l0/routines.py +885 -581
  165. disdrodb/l0/standards.py +77 -238
  166. disdrodb/l0/template_tools.py +105 -110
  167. disdrodb/l1/__init__.py +17 -0
  168. disdrodb/l1/beard_model.py +716 -0
  169. disdrodb/l1/encoding_attrs.py +635 -0
  170. disdrodb/l1/fall_velocity.py +260 -0
  171. disdrodb/l1/filters.py +192 -0
  172. disdrodb/l1/processing.py +202 -0
  173. disdrodb/l1/resampling.py +236 -0
  174. disdrodb/l1/routines.py +358 -0
  175. disdrodb/l1_env/__init__.py +17 -0
  176. disdrodb/l1_env/routines.py +38 -0
  177. disdrodb/l2/__init__.py +17 -0
  178. disdrodb/l2/empirical_dsd.py +1833 -0
  179. disdrodb/l2/event.py +388 -0
  180. disdrodb/l2/processing.py +528 -0
  181. disdrodb/l2/processing_options.py +213 -0
  182. disdrodb/l2/routines.py +868 -0
  183. disdrodb/metadata/__init__.py +9 -2
  184. disdrodb/metadata/checks.py +180 -124
  185. disdrodb/metadata/download.py +81 -0
  186. disdrodb/metadata/geolocation.py +146 -0
  187. disdrodb/metadata/info.py +20 -13
  188. disdrodb/metadata/manipulation.py +3 -3
  189. disdrodb/metadata/reader.py +59 -8
  190. disdrodb/metadata/search.py +77 -144
  191. disdrodb/metadata/standards.py +83 -80
  192. disdrodb/metadata/writer.py +10 -16
  193. disdrodb/psd/__init__.py +38 -0
  194. disdrodb/psd/fitting.py +2146 -0
  195. disdrodb/psd/models.py +774 -0
  196. disdrodb/routines.py +1412 -0
  197. disdrodb/scattering/__init__.py +28 -0
  198. disdrodb/scattering/axis_ratio.py +344 -0
  199. disdrodb/scattering/routines.py +456 -0
  200. disdrodb/utils/__init__.py +17 -0
  201. disdrodb/utils/attrs.py +208 -0
  202. disdrodb/utils/cli.py +269 -0
  203. disdrodb/utils/compression.py +60 -42
  204. disdrodb/utils/dask.py +62 -0
  205. disdrodb/utils/dataframe.py +342 -0
  206. disdrodb/utils/decorators.py +110 -0
  207. disdrodb/utils/directories.py +107 -46
  208. disdrodb/utils/encoding.py +127 -0
  209. disdrodb/utils/list.py +29 -0
  210. disdrodb/utils/logger.py +168 -46
  211. disdrodb/utils/time.py +657 -0
  212. disdrodb/utils/warnings.py +30 -0
  213. disdrodb/utils/writer.py +57 -0
  214. disdrodb/utils/xarray.py +138 -47
  215. disdrodb/utils/yaml.py +0 -1
  216. disdrodb/viz/__init__.py +17 -0
  217. disdrodb/viz/plots.py +17 -0
  218. disdrodb-0.1.1.dist-info/METADATA +294 -0
  219. disdrodb-0.1.1.dist-info/RECORD +232 -0
  220. {disdrodb-0.0.21.dist-info → disdrodb-0.1.1.dist-info}/WHEEL +1 -1
  221. disdrodb-0.1.1.dist-info/entry_points.txt +30 -0
  222. disdrodb/data_transfer/scripts/disdrodb_download_archive.py +0 -53
  223. disdrodb/data_transfer/scripts/disdrodb_upload_archive.py +0 -57
  224. disdrodb/l0/configs/OTT_Parsivel/l0a_encodings.yml +0 -32
  225. disdrodb/l0/configs/OTT_Parsivel2/l0a_encodings.yml +0 -39
  226. disdrodb/l0/configs/RD_80/l0a_encodings.yml +0 -16
  227. disdrodb/l0/configs/RD_80/l0b_encodings.yml +0 -135
  228. disdrodb/l0/configs/Thies_LPM/l0a_encodings.yml +0 -80
  229. disdrodb/l0/io.py +0 -257
  230. disdrodb/l0/l0_processing.py +0 -1091
  231. disdrodb/l0/readers/AUSTRALIA/MELBOURNE_2007_OTT.py +0 -178
  232. disdrodb/l0/readers/AUSTRALIA/MELBOURNE_2007_THIES.py +0 -247
  233. disdrodb/l0/readers/BRAZIL/CHUVA_LPM.py +0 -204
  234. disdrodb/l0/readers/BRAZIL/CHUVA_OTT.py +0 -183
  235. disdrodb/l0/readers/BRAZIL/GOAMAZON_OTT.py +0 -183
  236. disdrodb/l0/readers/CHINA/CHONGQING.py +0 -131
  237. disdrodb/l0/readers/EPFL/EPFL_ROOF_2008.py +0 -128
  238. disdrodb/l0/readers/EPFL/HYMEX_LTE_SOP2.py +0 -127
  239. disdrodb/l0/readers/EPFL/HYMEX_LTE_SOP3.py +0 -129
  240. disdrodb/l0/readers/EPFL/RACLETS_2019.py +0 -158
  241. disdrodb/l0/readers/EPFL/SAMOYLOV_2017.py +0 -136
  242. disdrodb/l0/readers/EPFL/SAMOYLOV_2019.py +0 -158
  243. disdrodb/l0/readers/FRANCE/SIRTA_OTT2.py +0 -138
  244. disdrodb/l0/readers/GPM/GCPEX.py +0 -123
  245. disdrodb/l0/readers/GPM/IFLOODS.py +0 -123
  246. disdrodb/l0/readers/GPM/MC3E.py +0 -123
  247. disdrodb/l0/readers/GPM/NSSTC.py +0 -164
  248. disdrodb/l0/readers/ITALY/GID.py +0 -199
  249. disdrodb/l0/readers/MEXICO/OH_IIUNAM_nc.py +0 -92
  250. disdrodb/l0/readers/NCAR/CCOPE_2015.py +0 -133
  251. disdrodb/l0/readers/NCAR/PECAN_FP3.py +0 -137
  252. disdrodb/l0/readers/NCAR/PECAN_MOBILE.py +0 -144
  253. disdrodb/l0/readers/NCAR/RELAMPAGO_OTT.py +0 -195
  254. disdrodb/l0/readers/NCAR/SNOWIE_PJ.py +0 -172
  255. disdrodb/l0/readers/NCAR/SNOWIE_SB.py +0 -179
  256. disdrodb/l0/readers/NCAR/VORTEX2_2009.py +0 -133
  257. disdrodb/l0/readers/NCAR/VORTEX2_2010.py +0 -188
  258. disdrodb/l0/readers/NCAR/VORTEX2_2010_UF.py +0 -191
  259. disdrodb/l0/readers/NCAR/VORTEX_SE_2016_P2.py +0 -135
  260. disdrodb/l0/readers/NCAR/VORTEX_SE_2016_PIPS.py +0 -170
  261. disdrodb/l0/readers/NETHERLANDS/DELFT.py +0 -187
  262. disdrodb/l0/readers/SPAIN/SBEGUERIA.py +0 -179
  263. disdrodb/l0/scripts/disdrodb_run_l0b_concat.py +0 -93
  264. disdrodb/l0/scripts/disdrodb_run_l0b_concat_station.py +0 -85
  265. disdrodb/utils/netcdf.py +0 -452
  266. disdrodb/utils/scripts.py +0 -102
  267. disdrodb-0.0.21.dist-info/AUTHORS.md +0 -18
  268. disdrodb-0.0.21.dist-info/METADATA +0 -186
  269. disdrodb-0.0.21.dist-info/RECORD +0 -168
  270. disdrodb-0.0.21.dist-info/entry_points.txt +0 -15
  271. /disdrodb/l0/configs/{RD_80 → RD80}/bins_velocity.yml +0 -0
  272. /disdrodb/l0/manuals/{Thies_LPM.pdf → LPM.pdf} +0 -0
  273. /disdrodb/l0/manuals/{ODM_470.pdf → ODM470.pdf} +0 -0
  274. /disdrodb/l0/manuals/{OTT_Parsivel.pdf → PARSIVEL.pdf} +0 -0
  275. /disdrodb/l0/manuals/{OTT_Parsivel2.pdf → PARSIVEL2.pdf} +0 -0
  276. /disdrodb/l0/manuals/{PWS_100.pdf → PWS100.pdf} +0 -0
  277. /disdrodb/l0/manuals/{RD_80.pdf → RD80.pdf} +0 -0
  278. {disdrodb-0.0.21.dist-info → disdrodb-0.1.1.dist-info/licenses}/LICENSE +0 -0
  279. {disdrodb-0.0.21.dist-info → disdrodb-0.1.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,528 @@
1
+ # -----------------------------------------------------------------------------.
2
+ # Copyright (c) 2021-2023 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
+ """Implement DISDRODB L2 processing."""
18
+
19
+ import numpy as np
20
+ import xarray as xr
21
+
22
+ from disdrodb.l1.encoding_attrs import get_attrs_dict, get_encoding_dict
23
+ from disdrodb.l1.fall_velocity import get_raindrop_fall_velocity
24
+ from disdrodb.l1_env.routines import load_env_dataset
25
+ from disdrodb.l2.empirical_dsd import (
26
+ compute_integral_parameters,
27
+ compute_qc_bins_metrics,
28
+ compute_spectrum_parameters,
29
+ get_drop_average_velocity,
30
+ get_drop_number_concentration,
31
+ get_effective_sampling_area,
32
+ get_kinetic_energy_variables_from_drop_number,
33
+ get_rain_accumulation,
34
+ get_rain_rate_from_drop_number,
35
+ )
36
+ from disdrodb.psd import create_psd, estimate_model_parameters
37
+ from disdrodb.psd.fitting import compute_gof_stats
38
+ from disdrodb.utils.attrs import set_attrs
39
+ from disdrodb.utils.decorators import check_pytmatrix_availability
40
+ from disdrodb.utils.encoding import set_encodings
41
+ from disdrodb.utils.time import ensure_sample_interval_in_seconds
42
+
43
+
44
+ def define_diameter_array(diameter_min=0, diameter_max=10, diameter_spacing=0.05):
45
+ """
46
+ Define an array of diameters and their corresponding bin properties.
47
+
48
+ Parameters
49
+ ----------
50
+ diameter_min : float, optional
51
+ The minimum diameter value. The default value is 0 mm.
52
+ diameter_max : float, optional
53
+ The maximum diameter value. The default value is 10 mm.
54
+ diameter_spacing : float, optional
55
+ The spacing between diameter values. The default value is 0.05 mm.
56
+
57
+ Returns
58
+ -------
59
+ xr.DataArray
60
+ A DataArray containing the center of each diameter bin, with coordinates for
61
+ the bin width, lower bound, upper bound, and center.
62
+
63
+ """
64
+ diameters_bounds = np.arange(diameter_min, diameter_max + diameter_spacing / 2, step=diameter_spacing)
65
+ diameters_bin_lower = diameters_bounds[:-1]
66
+ diameters_bin_upper = diameters_bounds[1:]
67
+ diameters_bin_width = diameters_bin_upper - diameters_bin_lower
68
+ diameters_bin_center = diameters_bin_lower + diameters_bin_width / 2
69
+ da = xr.DataArray(
70
+ diameters_bin_center,
71
+ dims="diameter_bin_center",
72
+ coords={
73
+ "diameter_bin_width": ("diameter_bin_center", diameters_bin_width),
74
+ "diameter_bin_lower": ("diameter_bin_center", diameters_bin_lower),
75
+ "diameter_bin_upper": ("diameter_bin_center", diameters_bin_upper),
76
+ "diameter_bin_center": ("diameter_bin_center", diameters_bin_center),
77
+ },
78
+ )
79
+ return da
80
+
81
+
82
+ def define_velocity_array(ds):
83
+ """
84
+ Create the fall velocity DataArray using various methods.
85
+
86
+ If 'velocity_bin_center' is a dimension in the dataset, returns a Dataset
87
+ with 'measured_velocity', 'average_velocity', and 'fall_velocity' as variables.
88
+ Otherwise, returns the 'fall_velocity' DataArray from the input dataset.
89
+
90
+ Parameters
91
+ ----------
92
+ ds : xarray.Dataset
93
+ The input dataset containing velocity variables.
94
+
95
+ Returns
96
+ -------
97
+ velocity: xarray.DataArray
98
+ """
99
+ drop_number = ds["drop_number"]
100
+ if "velocity_bin_center" in ds.dims:
101
+ velocity = xr.Dataset(
102
+ {
103
+ "fall_velocity": xr.ones_like(drop_number) * ds["fall_velocity"],
104
+ "measured_velocity": xr.ones_like(drop_number) * ds["velocity_bin_center"],
105
+ },
106
+ ).to_array(dim="velocity_method")
107
+ else:
108
+ velocity = ds["fall_velocity"]
109
+ return velocity
110
+
111
+
112
+ ####--------------------------------------------------------------------------
113
+ #### L2 Empirical Parameters
114
+
115
+
116
+ def generate_l2_empirical(ds, ds_env=None, compute_spectra=False):
117
+ """Generate the DISDRODB L2E dataset from the DISDRODB L1 dataset.
118
+
119
+ Parameters
120
+ ----------
121
+ ds : xarray.Dataset
122
+ DISDRODB L1 dataset.
123
+ ds_env : xarray.Dataset, optional
124
+ Environmental dataset used for fall velocity and water density estimates.
125
+ If None, a default environment dataset will be loaded.
126
+
127
+ Returns
128
+ -------
129
+ xarray.Dataset
130
+ DISRODB L2E dataset.
131
+ """
132
+ # Initialize L2E dataset
133
+ ds_l2 = xr.Dataset()
134
+
135
+ # Retrieve attributes
136
+ attrs = ds.attrs.copy()
137
+
138
+ # -------------------------------------------------------
139
+ #### Preprocessing
140
+ # Discard all timesteps without measured drops
141
+ # - This allow to speed up processing
142
+ # - Regularization can be done at the end
143
+ ds = ds.isel(time=ds["N"] > 0)
144
+
145
+ # Count number of diameter bins with data
146
+ if "Nbins" not in ds:
147
+ # Add bins statistics
148
+ ds.update(compute_qc_bins_metrics(ds))
149
+
150
+ # Retrieve ENV dataset or take defaults
151
+ # --> Used for fall velocity and water density estimates
152
+ if ds_env is None:
153
+ ds_env = load_env_dataset(ds)
154
+
155
+ # TODO: Derive water density as function of ENV (temperature, ...)
156
+ # --> (T == 10){density_water <- 999.7}else if(T == 20){density_water <- 998.2}else{density_water <- 995.7}
157
+ water_density = 1000 # kg / m3
158
+
159
+ # Determine if the velocity dimension is available
160
+ has_velocity_dimension = "velocity_bin_center" in ds.dims
161
+
162
+ # -------------------------------------------------------
163
+ # Extract variables from L1
164
+ sensor_name = ds.attrs["sensor_name"]
165
+ diameter = ds["diameter_bin_center"] / 1000 # m
166
+ diameter_bin_width = ds["diameter_bin_width"] # mm
167
+ drop_number = ds["drop_number"]
168
+ sample_interval = ensure_sample_interval_in_seconds(ds["sample_interval"]) # s
169
+
170
+ # Compute sampling area [m2]
171
+ sampling_area = get_effective_sampling_area(sensor_name=sensor_name, diameter=diameter) # m2
172
+
173
+ # Copy relevant L1 variables to L2 product
174
+ variables = [
175
+ "drop_number", # 2D V x D
176
+ "drop_counts", # 1D D
177
+ "sample_interval",
178
+ "N",
179
+ "Nremoved",
180
+ "Dmin",
181
+ "Dmax",
182
+ "fall_velocity",
183
+ ]
184
+
185
+ variables = [var for var in variables if var in ds]
186
+ ds_l2.update(ds[variables])
187
+
188
+ # -------------------------------------------------------------------------------------------
189
+ # Compute and add drop average velocity if an optical disdrometer (i.e OTT Parsivel or ThiesLPM)
190
+ # - We recompute it because if the input dataset is aggregated, it must be updated !
191
+ if has_velocity_dimension:
192
+ ds["drop_average_velocity"] = get_drop_average_velocity(ds["drop_number"])
193
+
194
+ # -------------------------------------------------------------------------------------------
195
+ # Define velocity array with dimension 'velocity_method'
196
+ velocity = define_velocity_array(ds)
197
+
198
+ # Compute drop number concentration (Nt) [#/m3/mm]
199
+ drop_number_concentration = get_drop_number_concentration(
200
+ drop_number=drop_number,
201
+ velocity=velocity,
202
+ diameter_bin_width=diameter_bin_width,
203
+ sample_interval=sample_interval,
204
+ sampling_area=sampling_area,
205
+ )
206
+ ds_l2["drop_number_concentration"] = drop_number_concentration
207
+
208
+ # -------------------------------------------------------
209
+ #### Compute L2 spectra
210
+ if compute_spectra:
211
+ ds_spectrum = compute_spectrum_parameters(
212
+ drop_number_concentration,
213
+ velocity=ds["fall_velocity"],
214
+ diameter=diameter,
215
+ sample_interval=sample_interval,
216
+ water_density=water_density,
217
+ )
218
+ ds_l2.update(ds_spectrum)
219
+
220
+ # ----------------------------------------------------------------------------
221
+ #### Compute L2 integral parameters from drop_number_concentration
222
+ ds_parameters = compute_integral_parameters(
223
+ drop_number_concentration=drop_number_concentration,
224
+ velocity=ds["fall_velocity"],
225
+ diameter=diameter,
226
+ diameter_bin_width=diameter_bin_width,
227
+ sample_interval=sample_interval,
228
+ water_density=water_density,
229
+ )
230
+
231
+ # -------------------------------------------------------
232
+ #### Compute R and P from drop number (without velocity assumptions)
233
+ # - Rain rate and accumulation computed with this method are not influenced by the fall velocity of drops !
234
+ ds_l2["Rm"] = get_rain_rate_from_drop_number(
235
+ drop_number=drop_number,
236
+ sampling_area=sampling_area,
237
+ diameter=diameter,
238
+ sample_interval=sample_interval,
239
+ )
240
+ # Compute rain accumulation (P) [mm]
241
+ ds_l2["Pm"] = get_rain_accumulation(rain_rate=ds_l2["Rm"], sample_interval=sample_interval)
242
+
243
+ # -------------------------------------------------------
244
+ #### Compute KE integral parameters directly from drop_number
245
+ # - The kinetic energy variables can be computed using the actual measured fall velocity by the sensor.
246
+ if has_velocity_dimension:
247
+ ds_ke = get_kinetic_energy_variables_from_drop_number(
248
+ drop_number=drop_number,
249
+ diameter=diameter,
250
+ velocity=velocity,
251
+ sampling_area=sampling_area,
252
+ sample_interval=sample_interval,
253
+ water_density=water_density,
254
+ )
255
+ # Combine integral parameters
256
+ ke_vars = list(ds_ke.data_vars)
257
+ ds_ke = ds_ke.expand_dims(dim={"source": ["drop_number"]}, axis=-1)
258
+ ds_ke_dsd = ds_parameters[ke_vars].expand_dims(dim={"source": ["drop_number_concentration"]}, axis=-1)
259
+ ds_ke = xr.concat((ds_ke_dsd, ds_ke), dim="source")
260
+ ds_parameters = ds_parameters.drop_vars(ke_vars)
261
+ for var in ke_vars:
262
+ ds_parameters[var] = ds_ke[var]
263
+
264
+ # ----------------------------------------------------------------------------
265
+ #### Finalize L2 Dataset
266
+ # Add DSD integral parameters
267
+ ds_l2.update(ds_parameters)
268
+
269
+ # ----------------------------------------------------------------------------.
270
+ #### Add encodings and attributes
271
+ # Add variables attributes
272
+ attrs_dict = get_attrs_dict()
273
+ ds_l2 = set_attrs(ds_l2, attrs_dict=attrs_dict)
274
+
275
+ # Add variables encoding
276
+ encoding_dict = get_encoding_dict()
277
+ ds_l2 = set_encodings(ds_l2, encoding_dict=encoding_dict)
278
+
279
+ # Add global attributes
280
+ ds_l2.attrs = attrs
281
+
282
+ return ds_l2
283
+
284
+
285
+ ####--------------------------------------------------------------------------
286
+ #### L2 Model Parameters
287
+
288
+
289
+ def generate_l2_model(
290
+ ds,
291
+ ds_env=None,
292
+ fall_velocity_method="Beard1976",
293
+ # PSD discretization
294
+ diameter_min=0,
295
+ diameter_max=10,
296
+ diameter_spacing=0.05,
297
+ # Fitting options
298
+ psd_model=None,
299
+ optimization=None,
300
+ optimization_kwargs=None,
301
+ # Filtering options
302
+ min_nbins=4,
303
+ remove_timesteps_with_few_bins=False,
304
+ mask_timesteps_with_few_bins=False,
305
+ # GOF metrics options
306
+ gof_metrics=True,
307
+ ):
308
+ """
309
+ Generate the DISDRODB L2M dataset from a DISDRODB L2E dataset.
310
+
311
+ This function estimates PSD model parameters and successively computes DSD integral parameters.
312
+ Optionally, radar variables at various bands are simulated using T-matrix simulations.
313
+ Goodness-of-fit metrics of the PSD can also be optionally included into the output dataset.
314
+
315
+ Parameters
316
+ ----------
317
+ ds : xarray.Dataset
318
+ DISDRODB L2E dataset.
319
+ ds_env : xarray.Dataset, optional
320
+ Environmental dataset used for fall velocity and water density estimates.
321
+ If None, a default environment dataset will be loaded.
322
+ diameter_min : float, optional
323
+ Minimum PSD diameter. The default value is 0 mm.
324
+ diameter_max : float, optional
325
+ Maximum PSD diameter. The default value is 8 mm.
326
+ diameter_spacing : float, optional
327
+ PSD diameter spacing. The default value is 0.05 mm.
328
+ psd_model : str
329
+ The PSD model to fit. See ``available_psd_models()``.
330
+ optimization : str, optional
331
+ The fitting optimization procedure. Either "GS" (Grid Search), "ML (Maximum Likelihood)
332
+ or "MOM" (Method of Moments).
333
+ optimization_kwargs : dict, optional
334
+ Dictionary with arguments to customize the fitting procedure.
335
+ gof_metrics : bool, optional
336
+ Whether to add goodness-of-fit metrics to the output dataset. The default is True.
337
+
338
+ Returns
339
+ -------
340
+ xarray.Dataset
341
+ DISDRODB L2M dataset.
342
+ """
343
+ # ----------------------------------------------------------------------------.
344
+ #### NOTES
345
+ # - Final processing: Optionally filter dataset only when PSD has fitted ?
346
+ # --> but good to have everything to compare across models
347
+
348
+ # ----------------------------------------------------------------------------.
349
+ # Retrieve attributes
350
+ attrs = ds.attrs.copy()
351
+
352
+ # -------------------------------------------------------
353
+ # Derive water density as function of ENV (temperature, ...)
354
+ # TODO --> Add into ds_env !
355
+ # --> (T == 10){density_water <- 999.7}else if(T == 20){density_water <- 998.2}else{density_water <- 995.7}
356
+ water_density = 1000 # kg / m3
357
+
358
+ ####------------------------------------------------------.
359
+ #### Preprocessing
360
+ # Count number of diameter bins with data
361
+ if "Nbins" not in ds:
362
+ # Add bins statistics
363
+ ds.update(compute_qc_bins_metrics(ds))
364
+
365
+ # Identify timesteps with enough diameter bins with counted trops
366
+ valid_timesteps = ds["Nbins"] >= min_nbins
367
+
368
+ # Drop such timesteps if asked
369
+ if remove_timesteps_with_few_bins:
370
+ mask_timesteps_with_few_bins = False
371
+ ds = ds.isel(time=valid_timesteps, drop=False)
372
+
373
+ # Retrieve ENV dataset or take defaults
374
+ # --> Used for fall velocity and water density estimates
375
+ if ds_env is None:
376
+ ds_env = load_env_dataset(ds)
377
+
378
+ ####------------------------------------------------------.
379
+ #### Define default PSD optimization arguments
380
+ if psd_model is None and optimization is None:
381
+ psd_model = "NormalizedGammaPSD"
382
+ optimization = "GS"
383
+ optimization_kwargs = {
384
+ "target": "ND",
385
+ "transformation": "identity",
386
+ "error_order": 1, # MAE
387
+ }
388
+
389
+ ####------------------------------------------------------.
390
+ #### Retrieve PSD parameters
391
+ ds_psd_params = estimate_model_parameters(
392
+ ds=ds,
393
+ psd_model=psd_model,
394
+ optimization=optimization,
395
+ optimization_kwargs=optimization_kwargs,
396
+ )
397
+
398
+ ####------------------------------------------------------.
399
+ #### Mask timesteps with few bins if asked
400
+ if mask_timesteps_with_few_bins:
401
+ ds_psd_params = ds_psd_params.where(valid_timesteps)
402
+
403
+ ####-------------------------------------------------------
404
+ #### Create PSD
405
+ psd_name = ds_psd_params.attrs["disdrodb_psd_model"]
406
+ psd = create_psd(psd_name, parameters=ds_psd_params)
407
+
408
+ ####-------------------------------------------------------
409
+ #### Compute integral parameters
410
+ # Define diameter array
411
+ diameter = define_diameter_array(
412
+ diameter_min=diameter_min,
413
+ diameter_max=diameter_max,
414
+ diameter_spacing=diameter_spacing,
415
+ )
416
+ diameter_bin_width = diameter["diameter_bin_width"]
417
+
418
+ # Retrieve time of integration
419
+ # - If dataset is opened with decode_timedelta=False, sample_interval is already in seconds !
420
+ sample_interval = ensure_sample_interval_in_seconds(ds["sample_interval"])
421
+
422
+ # Retrieve drop number concentration
423
+ drop_number_concentration = psd(diameter)
424
+
425
+ # Retrieve fall velocity for each new diameter bin
426
+ velocity = get_raindrop_fall_velocity(diameter=diameter, method=fall_velocity_method, ds_env=ds_env) # mm
427
+
428
+ # Compute integral parameters
429
+ ds_params = compute_integral_parameters(
430
+ drop_number_concentration=drop_number_concentration,
431
+ velocity=velocity,
432
+ diameter=diameter / 1000, # in meters !
433
+ diameter_bin_width=diameter_bin_width,
434
+ sample_interval=sample_interval,
435
+ water_density=water_density,
436
+ )
437
+
438
+ #### ----------------------------------------------------------------------------
439
+ #### Create L2 Dataset
440
+ # Update with PSD parameters
441
+ ds_params.update(ds_psd_params)
442
+
443
+ # Add GOF statistics if asked
444
+ if gof_metrics:
445
+ ds_gof = compute_gof_stats(drop_number_concentration=ds["drop_number_concentration"], psd=psd)
446
+ ds_params.update(ds_gof)
447
+
448
+ #### ----------------------------------------------------------------------------.
449
+ #### Add encodings and attributes
450
+ # Add variables attributes
451
+ attrs_dict = get_attrs_dict()
452
+ ds_params = set_attrs(ds_params, attrs_dict=attrs_dict)
453
+
454
+ # Add variables encoding
455
+ encoding_dict = get_encoding_dict()
456
+ ds_params = set_encodings(ds_params, encoding_dict=encoding_dict)
457
+
458
+ # Add global attributes
459
+ ds_params.attrs = attrs
460
+ ds_params.attrs["disdrodb_psd_model"] = psd_name
461
+
462
+ # Return dataset
463
+ return ds_params
464
+
465
+
466
+ ####-------------------------------------------------------------------------------------------------------------------.
467
+ #### L2 Radar Parameters
468
+
469
+
470
+ @check_pytmatrix_availability
471
+ def generate_l2_radar(
472
+ ds,
473
+ radar_band=None,
474
+ canting_angle_std=7,
475
+ diameter_max=10,
476
+ axis_ratio="Thurai2007",
477
+ parallel=True,
478
+ ):
479
+ """Simulate polarimetric radar variables from empirical drop number concentration or the estimated PSD.
480
+
481
+ Parameters
482
+ ----------
483
+ ds : xarray.Dataset
484
+ Dataset containing the drop number concentration variable or the PSD parameters.
485
+ radar_band : str or list of str, optional
486
+ Radar band(s) to be used.
487
+ If ``None`` (the default), all available radar bands are used.
488
+ canting_angle_std : float or list of float, optional
489
+ Standard deviation of the canting angle. The default value is 7.
490
+ diameter_max : float or list of float, optional
491
+ Maximum diameter. The default value is 8 mm.
492
+ axis_ratio : str or list of str, optional
493
+ Method to compute the axis ratio. The default method is ``Thurai2007``.
494
+ parallel : bool, optional
495
+ Whether to compute radar variables in parallel.
496
+ The default value is ``True``.
497
+
498
+ Returns
499
+ -------
500
+ xarray.Dataset
501
+ Dataset containing the computed radar parameters.
502
+ """
503
+ # Import here to avoid pytmatrix has mandatory dependency
504
+ # - It is only needed for radar simulation
505
+ from disdrodb.scattering import get_radar_parameters
506
+
507
+ # Retrieve radar variables from L2E drop number concentration or from estimated L2M PSD model
508
+ ds_radar = get_radar_parameters(
509
+ ds=ds,
510
+ radar_band=radar_band,
511
+ canting_angle_std=canting_angle_std,
512
+ diameter_max=diameter_max,
513
+ axis_ratio=axis_ratio,
514
+ parallel=parallel,
515
+ )
516
+
517
+ #### ----------------------------------------------------------------------------.
518
+ #### Add encodings and attributes
519
+ # Add variables attributes
520
+ attrs_dict = get_attrs_dict()
521
+ ds_radar = set_attrs(ds_radar, attrs_dict=attrs_dict)
522
+
523
+ # Add variables encoding
524
+ encoding_dict = get_encoding_dict()
525
+ ds_radar = set_encodings(ds_radar, encoding_dict=encoding_dict)
526
+
527
+ # Return dataset
528
+ return ds_radar