disdrodb 0.0.21__py3-none-any.whl → 0.1.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 (264) 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 +295 -269
  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 +32 -42
  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 +62 -59
  57. disdrodb/l0/configs/{Thies_LPM → LPM}/l0b_encodings.yml +9 -9
  58. disdrodb/l0/configs/{Thies_LPM → LPM}/raw_data_format.yml +245 -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 +22 -20
  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 +24 -22
  69. disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/l0b_encodings.yml +20 -20
  70. disdrodb/l0/configs/{OTT_Parsivel2 → PARSIVEL2}/raw_data_format.yml +98 -98
  71. disdrodb/l0/configs/{RD_80 → RD80}/bins_diameter.yml +40 -40
  72. disdrodb/l0/configs/RD80/l0a_encodings.yml +16 -0
  73. disdrodb/l0/configs/{RD_80 → RD80}/l0b_cf_attrs.yml +3 -3
  74. disdrodb/l0/configs/RD80/l0b_encodings.yml +135 -0
  75. disdrodb/l0/configs/{RD_80 → RD80}/raw_data_format.yml +48 -48
  76. disdrodb/l0/l0_reader.py +216 -340
  77. disdrodb/l0/l0a_processing.py +237 -208
  78. disdrodb/l0/l0b_nc_processing.py +227 -80
  79. disdrodb/l0/l0b_processing.py +93 -173
  80. disdrodb/l0/l0c_processing.py +627 -0
  81. disdrodb/l0/readers/{ARM → LPM/ARM}/ARM_LPM.py +36 -58
  82. disdrodb/l0/readers/LPM/AUSTRALIA/MELBOURNE_2007_LPM.py +226 -0
  83. disdrodb/l0/readers/LPM/BRAZIL/CHUVA_LPM.py +185 -0
  84. disdrodb/l0/readers/LPM/BRAZIL/GOAMAZON_LPM.py +183 -0
  85. disdrodb/l0/readers/LPM/ITALY/GID_LPM.py +179 -0
  86. disdrodb/l0/readers/{UK → LPM/UK}/DIVEN.py +14 -35
  87. disdrodb/l0/readers/PARSIVEL/AUSTRALIA/MELBOURNE_2007_PARSIVEL.py +157 -0
  88. disdrodb/l0/readers/PARSIVEL/CHINA/CHONGQING.py +113 -0
  89. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/ARCTIC_2021.py +40 -57
  90. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/COMMON_2011.py +37 -54
  91. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/DAVOS_2009_2011.py +34 -51
  92. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/EPFL_2009.py +34 -51
  93. disdrodb/l0/readers/{EPFL/PARADISO_2014.py → PARSIVEL/EPFL/EPFL_ROOF_2008.py} +38 -50
  94. disdrodb/l0/readers/PARSIVEL/EPFL/EPFL_ROOF_2010.py +105 -0
  95. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/EPFL_ROOF_2011.py +34 -51
  96. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/EPFL_ROOF_2012.py +33 -51
  97. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/GENEPI_2007.py +25 -44
  98. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/GRAND_ST_BERNARD_2007.py +25 -44
  99. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/GRAND_ST_BERNARD_2007_2.py +25 -44
  100. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/HPICONET_2010.py +34 -51
  101. disdrodb/l0/readers/{EPFL/EPFL_ROOF_2010.py → PARSIVEL/EPFL/HYMEX_LTE_SOP2.py} +37 -50
  102. disdrodb/l0/readers/PARSIVEL/EPFL/HYMEX_LTE_SOP3.py +111 -0
  103. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/HYMEX_LTE_SOP4.py +36 -54
  104. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/LOCARNO_2018.py +34 -52
  105. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/LOCARNO_2019.py +38 -56
  106. disdrodb/l0/readers/PARSIVEL/EPFL/PARADISO_2014.py +105 -0
  107. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/PARSIVEL_2007.py +27 -45
  108. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/PLATO_2019.py +24 -44
  109. disdrodb/l0/readers/PARSIVEL/EPFL/RACLETS_2019.py +140 -0
  110. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/RACLETS_2019_WJF.py +41 -59
  111. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/RIETHOLZBACH_2011.py +34 -51
  112. disdrodb/l0/readers/PARSIVEL/EPFL/SAMOYLOV_2017.py +117 -0
  113. disdrodb/l0/readers/PARSIVEL/EPFL/SAMOYLOV_2019.py +137 -0
  114. disdrodb/l0/readers/{EPFL → PARSIVEL/EPFL}/UNIL_2022.py +42 -55
  115. disdrodb/l0/readers/PARSIVEL/GPM/IFLOODS.py +104 -0
  116. disdrodb/l0/readers/{GPM → PARSIVEL/GPM}/LPVEX.py +29 -48
  117. disdrodb/l0/readers/PARSIVEL/GPM/MC3E.py +184 -0
  118. disdrodb/l0/readers/PARSIVEL/NCAR/CCOPE_2015.py +113 -0
  119. disdrodb/l0/readers/{NCAR/VORTEX_SE_2016_P1.py → PARSIVEL/NCAR/OWLES_MIPS.py} +46 -72
  120. disdrodb/l0/readers/PARSIVEL/NCAR/PECAN_MOBILE.py +125 -0
  121. disdrodb/l0/readers/{NCAR/OWLES_MIPS.py → PARSIVEL/NCAR/PLOWS_MIPS.py} +45 -64
  122. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2009.py +114 -0
  123. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2010.py +176 -0
  124. disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2010_UF.py +183 -0
  125. disdrodb/l0/readers/{ARM/ARM_LD.py → PARSIVEL2/ARM/ARM_PARSIVEL2.py} +27 -50
  126. disdrodb/l0/readers/PARSIVEL2/BRAZIL/CHUVA_PARSIVEL2.py +163 -0
  127. disdrodb/l0/readers/PARSIVEL2/BRAZIL/GOAMAZON_PARSIVEL2.py +163 -0
  128. disdrodb/l0/readers/{DENMARK → PARSIVEL2/DENMARK}/EROSION_nc.py +14 -35
  129. disdrodb/l0/readers/PARSIVEL2/FRANCE/SIRTA_PARSIVEL2.py +119 -0
  130. disdrodb/l0/readers/PARSIVEL2/GPM/GCPEX.py +104 -0
  131. disdrodb/l0/readers/PARSIVEL2/GPM/NSSTC.py +176 -0
  132. disdrodb/l0/readers/PARSIVEL2/ITALY/GID_PARSIVEL2.py +32 -0
  133. disdrodb/l0/readers/PARSIVEL2/MEXICO/OH_IIUNAM_nc.py +56 -0
  134. disdrodb/l0/readers/PARSIVEL2/NCAR/PECAN_FP3.py +120 -0
  135. disdrodb/l0/readers/{NCAR → PARSIVEL2/NCAR}/PECAN_MIPS.py +45 -64
  136. disdrodb/l0/readers/PARSIVEL2/NCAR/RELAMPAGO_PARSIVEL2.py +181 -0
  137. disdrodb/l0/readers/PARSIVEL2/NCAR/SNOWIE_PJ.py +160 -0
  138. disdrodb/l0/readers/PARSIVEL2/NCAR/SNOWIE_SB.py +160 -0
  139. disdrodb/l0/readers/{NCAR/PLOWS_MIPS.py → PARSIVEL2/NCAR/VORTEX_SE_2016_P1.py} +49 -66
  140. disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_P2.py +118 -0
  141. disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_PIPS.py +152 -0
  142. disdrodb/l0/readers/PARSIVEL2/NETHERLANDS/DELFT.py +166 -0
  143. disdrodb/l0/readers/{NCAR/RELAMPAGO_RD80.py → RD80/BRAZIL/CHUVA_RD80.py} +36 -60
  144. disdrodb/l0/readers/{BRAZIL → RD80/BRAZIL}/GOAMAZON_RD80.py +36 -55
  145. disdrodb/l0/readers/{NCAR → RD80/NCAR}/CINDY_2011_RD80.py +35 -54
  146. disdrodb/l0/readers/{BRAZIL/CHUVA_RD80.py → RD80/NCAR/RELAMPAGO_RD80.py} +40 -54
  147. disdrodb/l0/readers/template_reader_raw_netcdf_data.py +62 -0
  148. disdrodb/l0/readers/{reader_template.py → template_reader_raw_text_data.py} +20 -44
  149. disdrodb/l0/routines.py +885 -581
  150. disdrodb/l0/standards.py +72 -236
  151. disdrodb/l0/template_tools.py +104 -109
  152. disdrodb/l1/__init__.py +17 -0
  153. disdrodb/l1/beard_model.py +716 -0
  154. disdrodb/l1/encoding_attrs.py +620 -0
  155. disdrodb/l1/fall_velocity.py +260 -0
  156. disdrodb/l1/filters.py +192 -0
  157. disdrodb/l1/processing.py +200 -0
  158. disdrodb/l1/resampling.py +236 -0
  159. disdrodb/l1/routines.py +357 -0
  160. disdrodb/l1_env/__init__.py +17 -0
  161. disdrodb/l1_env/routines.py +38 -0
  162. disdrodb/l2/__init__.py +17 -0
  163. disdrodb/l2/empirical_dsd.py +1735 -0
  164. disdrodb/l2/event.py +388 -0
  165. disdrodb/l2/processing.py +519 -0
  166. disdrodb/l2/processing_options.py +213 -0
  167. disdrodb/l2/routines.py +868 -0
  168. disdrodb/metadata/__init__.py +9 -2
  169. disdrodb/metadata/checks.py +165 -118
  170. disdrodb/metadata/download.py +81 -0
  171. disdrodb/metadata/geolocation.py +146 -0
  172. disdrodb/metadata/info.py +20 -13
  173. disdrodb/metadata/manipulation.py +1 -1
  174. disdrodb/metadata/reader.py +59 -8
  175. disdrodb/metadata/search.py +77 -144
  176. disdrodb/metadata/standards.py +7 -8
  177. disdrodb/metadata/writer.py +8 -14
  178. disdrodb/psd/__init__.py +38 -0
  179. disdrodb/psd/fitting.py +2146 -0
  180. disdrodb/psd/models.py +774 -0
  181. disdrodb/routines.py +1176 -0
  182. disdrodb/scattering/__init__.py +28 -0
  183. disdrodb/scattering/axis_ratio.py +344 -0
  184. disdrodb/scattering/routines.py +456 -0
  185. disdrodb/utils/__init__.py +17 -0
  186. disdrodb/utils/attrs.py +208 -0
  187. disdrodb/utils/cli.py +269 -0
  188. disdrodb/utils/compression.py +60 -42
  189. disdrodb/utils/dask.py +62 -0
  190. disdrodb/utils/decorators.py +110 -0
  191. disdrodb/utils/directories.py +107 -46
  192. disdrodb/utils/encoding.py +127 -0
  193. disdrodb/utils/list.py +29 -0
  194. disdrodb/utils/logger.py +168 -46
  195. disdrodb/utils/time.py +657 -0
  196. disdrodb/utils/warnings.py +30 -0
  197. disdrodb/utils/writer.py +57 -0
  198. disdrodb/utils/xarray.py +138 -47
  199. disdrodb/utils/yaml.py +0 -1
  200. disdrodb/viz/__init__.py +17 -0
  201. disdrodb/viz/plots.py +17 -0
  202. disdrodb-0.1.0.dist-info/METADATA +321 -0
  203. disdrodb-0.1.0.dist-info/RECORD +216 -0
  204. {disdrodb-0.0.21.dist-info → disdrodb-0.1.0.dist-info}/WHEEL +1 -1
  205. disdrodb-0.1.0.dist-info/entry_points.txt +30 -0
  206. disdrodb/data_transfer/scripts/disdrodb_download_archive.py +0 -53
  207. disdrodb/data_transfer/scripts/disdrodb_upload_archive.py +0 -57
  208. disdrodb/l0/configs/OTT_Parsivel/l0a_encodings.yml +0 -32
  209. disdrodb/l0/configs/OTT_Parsivel2/l0a_encodings.yml +0 -39
  210. disdrodb/l0/configs/RD_80/l0a_encodings.yml +0 -16
  211. disdrodb/l0/configs/RD_80/l0b_encodings.yml +0 -135
  212. disdrodb/l0/configs/Thies_LPM/l0a_encodings.yml +0 -80
  213. disdrodb/l0/io.py +0 -257
  214. disdrodb/l0/l0_processing.py +0 -1091
  215. disdrodb/l0/readers/AUSTRALIA/MELBOURNE_2007_OTT.py +0 -178
  216. disdrodb/l0/readers/AUSTRALIA/MELBOURNE_2007_THIES.py +0 -247
  217. disdrodb/l0/readers/BRAZIL/CHUVA_LPM.py +0 -204
  218. disdrodb/l0/readers/BRAZIL/CHUVA_OTT.py +0 -183
  219. disdrodb/l0/readers/BRAZIL/GOAMAZON_LPM.py +0 -204
  220. disdrodb/l0/readers/BRAZIL/GOAMAZON_OTT.py +0 -183
  221. disdrodb/l0/readers/CHINA/CHONGQING.py +0 -131
  222. disdrodb/l0/readers/EPFL/EPFL_ROOF_2008.py +0 -128
  223. disdrodb/l0/readers/EPFL/HYMEX_LTE_SOP2.py +0 -127
  224. disdrodb/l0/readers/EPFL/HYMEX_LTE_SOP3.py +0 -129
  225. disdrodb/l0/readers/EPFL/RACLETS_2019.py +0 -158
  226. disdrodb/l0/readers/EPFL/SAMOYLOV_2017.py +0 -136
  227. disdrodb/l0/readers/EPFL/SAMOYLOV_2019.py +0 -158
  228. disdrodb/l0/readers/FRANCE/SIRTA_OTT2.py +0 -138
  229. disdrodb/l0/readers/GPM/GCPEX.py +0 -123
  230. disdrodb/l0/readers/GPM/IFLOODS.py +0 -123
  231. disdrodb/l0/readers/GPM/MC3E.py +0 -123
  232. disdrodb/l0/readers/GPM/NSSTC.py +0 -164
  233. disdrodb/l0/readers/ITALY/GID.py +0 -199
  234. disdrodb/l0/readers/MEXICO/OH_IIUNAM_nc.py +0 -92
  235. disdrodb/l0/readers/NCAR/CCOPE_2015.py +0 -133
  236. disdrodb/l0/readers/NCAR/PECAN_FP3.py +0 -137
  237. disdrodb/l0/readers/NCAR/PECAN_MOBILE.py +0 -144
  238. disdrodb/l0/readers/NCAR/RELAMPAGO_OTT.py +0 -195
  239. disdrodb/l0/readers/NCAR/SNOWIE_PJ.py +0 -172
  240. disdrodb/l0/readers/NCAR/SNOWIE_SB.py +0 -179
  241. disdrodb/l0/readers/NCAR/VORTEX2_2009.py +0 -133
  242. disdrodb/l0/readers/NCAR/VORTEX2_2010.py +0 -188
  243. disdrodb/l0/readers/NCAR/VORTEX2_2010_UF.py +0 -191
  244. disdrodb/l0/readers/NCAR/VORTEX_SE_2016_P2.py +0 -135
  245. disdrodb/l0/readers/NCAR/VORTEX_SE_2016_PIPS.py +0 -170
  246. disdrodb/l0/readers/NETHERLANDS/DELFT.py +0 -187
  247. disdrodb/l0/readers/SPAIN/SBEGUERIA.py +0 -179
  248. disdrodb/l0/scripts/disdrodb_run_l0b_concat.py +0 -93
  249. disdrodb/l0/scripts/disdrodb_run_l0b_concat_station.py +0 -85
  250. disdrodb/utils/netcdf.py +0 -452
  251. disdrodb/utils/scripts.py +0 -102
  252. disdrodb-0.0.21.dist-info/AUTHORS.md +0 -18
  253. disdrodb-0.0.21.dist-info/METADATA +0 -186
  254. disdrodb-0.0.21.dist-info/RECORD +0 -168
  255. disdrodb-0.0.21.dist-info/entry_points.txt +0 -15
  256. /disdrodb/l0/configs/{RD_80 → RD80}/bins_velocity.yml +0 -0
  257. /disdrodb/l0/manuals/{Thies_LPM.pdf → LPM.pdf} +0 -0
  258. /disdrodb/l0/manuals/{ODM_470.pdf → ODM470.pdf} +0 -0
  259. /disdrodb/l0/manuals/{OTT_Parsivel.pdf → PARSIVEL.pdf} +0 -0
  260. /disdrodb/l0/manuals/{OTT_Parsivel2.pdf → PARSIVEL2.pdf} +0 -0
  261. /disdrodb/l0/manuals/{PWS_100.pdf → PWS100.pdf} +0 -0
  262. /disdrodb/l0/manuals/{RD_80.pdf → RD80.pdf} +0 -0
  263. {disdrodb-0.0.21.dist-info → disdrodb-0.1.0.dist-info/licenses}/LICENSE +0 -0
  264. {disdrodb-0.0.21.dist-info → disdrodb-0.1.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,260 @@
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
+ """Theoretical models to estimate the drop fall velocity."""
18
+
19
+
20
+ import numpy as np
21
+
22
+
23
+ def get_fall_velocity_atlas_1973(diameter):
24
+ """
25
+ Compute the fall velocity of raindrops using the Atlas et al. (1973) relationship.
26
+
27
+ Parameters
28
+ ----------
29
+ diameter : array-like
30
+ Diameter of the raindrops in millimeters.
31
+
32
+ Returns
33
+ -------
34
+ fall_velocity : array-like
35
+ Fall velocities corresponding to the input diameters, in meters per second.
36
+
37
+ References
38
+ ----------
39
+ Atlas, D., Srivastava, R. C., & Sekhon, R. S. (1973).
40
+ Doppler radar characteristics of precipitation at vertical incidence.
41
+ Reviews of Geophysics, 11(1), 1-35.
42
+ https://doi.org/10.1029/RG011i001p00001
43
+
44
+ Atlas, D., & Ulbrich, C. W. (1977).
45
+ Path- and area-integrated rainfall measurement by microwave attenuation in the 1-3 cm band.
46
+ Journal of Applied Meteorology, 16(12), 1322-1331.
47
+ https://doi.org/10.1175/1520-0450(1977)016<1322:PAAIRM>2.0.CO;2
48
+
49
+ Gunn, R., & Kinzer, G. D. (1949).
50
+ The terminal velocity of fall for water droplets in stagnant air.
51
+ Journal of Meteorology, 6(4), 243-248.
52
+ https://doi.org/10.1175/1520-0469(1949)006<0243:TTVOFF>2.0.CO;2
53
+
54
+ """
55
+ fall_velocity = 9.65 - 10.3 * np.exp(-0.6 * diameter) # clip to 0 !
56
+ fall_velocity = np.clip(fall_velocity, 0, None)
57
+ return fall_velocity
58
+
59
+
60
+ def get_fall_velocity_brandes_2002(diameter):
61
+ """
62
+ Compute the fall velocity of raindrops using the Brandes et al. (2002) relationship.
63
+
64
+ Parameters
65
+ ----------
66
+ diameter : array-like
67
+ Diameter of the raindrops in millimeters.
68
+
69
+ Returns
70
+ -------
71
+ fall_velocity : array-like
72
+ Fall velocities in meters per second.
73
+
74
+ References
75
+ ----------
76
+ Brandes, E. A., Zhang, G., & Vivekanandan, J. (2002).
77
+ Experiments in rainfall estimation with a polarimetric radar in a subtropical environment.
78
+ Journal of Applied Meteorology, 41(6), 674-685.
79
+ https://doi.org/10.1175/1520-0450(2002)041<0674:EIREWA>2.0.CO;2
80
+
81
+ """
82
+ fall_velocity = -0.1021 + 4.932 * diameter - 0.9551 * diameter**2 + 0.07934 * diameter**3 - 0.002362 * diameter**4
83
+ return fall_velocity
84
+
85
+
86
+ def get_fall_velocity_uplinger_1981(diameter):
87
+ """
88
+ Compute the fall velocity of raindrops using Uplinger (1981) relationship.
89
+
90
+ Parameters
91
+ ----------
92
+ diameter : array-like
93
+ Diameter of the raindrops in millimeters.
94
+ Valid for diameters between 0.1 mm and 7 mm.
95
+
96
+ Returns
97
+ -------
98
+ fall_velocity : array-like
99
+ Fall velocities in meters per second.
100
+
101
+ References
102
+ ----------
103
+ Uplinger, C. W. (1981). A new formula for raindrop terminal velocity.
104
+ In Proceedings of the 20th Conference on Radar Meteorology (pp. 389-391).
105
+ AMS.
106
+
107
+ """
108
+ # Valid between 0.1 and 7 mm
109
+ fall_velocity = 4.874 * diameter * np.exp(-0.195 * diameter)
110
+ return fall_velocity
111
+
112
+
113
+ def get_fall_velocity_van_dijk_2002(diameter):
114
+ """
115
+ Compute the fall velocity of raindrops using van Dijk et al. (2002) relationship.
116
+
117
+ Parameters
118
+ ----------
119
+ diameter : array-like
120
+ Diameter of the raindrops in millimeters.
121
+
122
+ Returns
123
+ -------
124
+ fall_velocity : array-like
125
+ Fall velocities in meters per second.
126
+
127
+ References
128
+ ----------
129
+ van Dijk, A. I. J. M., Bruijnzeel, L. A., & Rosewell, C. J. (2002).
130
+ Rainfall intensity-kinetic energy relationships: a critical literature appraisal.
131
+ Journal of Hydrology, 261(1-4), 1-23.
132
+ https://doi.org/10.1016/S0022-1694(02)00020-3
133
+
134
+ """
135
+ fall_velocity = -0.254 + 5.03 * diameter - 0.912 * diameter**2 + 0.0561 * diameter**3
136
+ return fall_velocity
137
+
138
+
139
+ def get_fall_velocity_beard_1976(diameter, ds_env):
140
+ """Calculate the fall velocity of a particle using the Beard (1976) model.
141
+
142
+ Parameters
143
+ ----------
144
+ diameter : array-like
145
+ Diameter of the raindrops in millimeters.
146
+ ds_env : xr.Dataset
147
+ A dataset containing the following environmental variables:
148
+ - 'altitude' : Altitude in meters (m).
149
+ - 'latitude' : Latitude in degrees.
150
+ - 'temperature' : Temperature in degrees Celsius (°C).
151
+ - 'relative_humidity' : Relative humidity in percentage (%).
152
+ - 'sea_level_air_pressure' : Sea level air pressure in Pascals (Pa).
153
+ - 'lapse_rate' : Lapse rate in degrees Celsius per meter (°C/m).
154
+
155
+ Returns
156
+ -------
157
+ fall_velocity : array-like
158
+ The calculated fall velocities of the raindrops.
159
+ """
160
+ from disdrodb.l1.beard_model import retrieve_fall_velocity
161
+
162
+ # Input diameter in mmm
163
+ fall_velocity = retrieve_fall_velocity(
164
+ diameter=diameter / 1000, # diameter expected in m !!!
165
+ altitude=ds_env["altitude"],
166
+ latitude=ds_env["latitude"],
167
+ temperature=ds_env["temperature"],
168
+ relative_humidity=ds_env["relative_humidity"],
169
+ # TODO: add air_pressure # TODO
170
+ sea_level_air_pressure=ds_env["sea_level_air_pressure"],
171
+ lapse_rate=ds_env["lapse_rate"],
172
+ )
173
+ return fall_velocity
174
+
175
+
176
+ def ensure_valid_coordinates(ds, default_altitude=0, default_latitude=0, default_longitude=0):
177
+ """Ensure dataset valid coordinates for altitude, latitude, and longitude.
178
+
179
+ Invalid values are np.nan and -9999.
180
+
181
+ Parameters
182
+ ----------
183
+ ds : xarray.Dataset
184
+ The dataset for which to ensure valid geolocation coordinates.
185
+ default_altitude : float, optional
186
+ The default value to use for invalid altitude values. Defaults to 0.
187
+ default_latitude : float, optional
188
+ The default value to use for invalid latitude values. Defaults to 0.
189
+ default_longitude : float, optional
190
+ The default value to use for invalid longitude values. Defaults to 0.
191
+
192
+ Returns
193
+ -------
194
+ xarray.Dataset
195
+ The dataset with invalid coordinates replaced by default values.
196
+
197
+ """
198
+ invalid_altitude = np.logical_or(np.isnan(ds["altitude"]), ds["altitude"] == -9999)
199
+ ds["altitude"] = ds["altitude"].where(~invalid_altitude, default_altitude)
200
+
201
+ invalid_lat = np.logical_or(np.isnan(ds["latitude"]), ds["latitude"] == -9999)
202
+ ds["latitude"] = ds["latitude"].where(~invalid_lat, default_latitude)
203
+
204
+ invalid_lon = np.logical_or(np.isnan(ds["longitude"]), ds["longitude"] == -9999)
205
+ ds["longitude"] = ds["longitude"].where(~invalid_lon, default_longitude)
206
+ return ds
207
+
208
+
209
+ def get_raindrop_fall_velocity(diameter, method, ds_env=None):
210
+ """Calculate the fall velocity of raindrops based on their diameter.
211
+
212
+ Parameters
213
+ ----------
214
+ diameter : array-like
215
+ The diameter of the raindrops in millimeters.
216
+ method : str
217
+ The method to use for calculating the fall velocity. Must be one of the following:
218
+ 'Atlas1973', 'Beard1976', 'Brandes2002', 'Uplinger1981', 'VanDijk2002'.
219
+ ds_env : xr.Dataset, optional
220
+ A dataset containing the following environmental variables:
221
+ - 'altitude' : Altitude in meters (m).
222
+ - 'latitude' : Latitude in degrees.
223
+ - 'temperature' : Temperature in degrees Celsius (°C).
224
+ - 'relative_humidity' : Relative humidity. A value between 0 and 1.
225
+ - 'sea_level_air_pressure' : Sea level air pressure in Pascals (Pa).
226
+ - 'lapse_rate' : Lapse rate in degrees Celsius per meter (°C/m).
227
+ It is required for for the 'Beard1976' method.
228
+
229
+ Returns
230
+ -------
231
+ fall_velocity : array-like
232
+ The calculated fall velocities of the raindrops.
233
+
234
+ Notes
235
+ -----
236
+ The 'Beard1976' method requires additional environmental parameters such as altitude and latitude.
237
+ These parameters can be provided through the `ds_env` argument. If not provided, default values will be used.
238
+ """
239
+ # Input diameter in mm
240
+ dict_methods = {
241
+ "Atlas1973": get_fall_velocity_atlas_1973,
242
+ "Beard1976": get_fall_velocity_beard_1976,
243
+ "Brandes2002": get_fall_velocity_brandes_2002,
244
+ "Uplinger1981": get_fall_velocity_uplinger_1981,
245
+ "VanDijk2002": get_fall_velocity_van_dijk_2002,
246
+ }
247
+ # Check valid method
248
+ available_methods = list(dict_methods)
249
+ if method not in dict_methods:
250
+ raise ValueError(f"{method} is an invalid fall velocity method. Valid methods: {available_methods}.")
251
+ # Copy diameter
252
+ diameter = diameter.copy()
253
+ # Ensure valid altitude and geolocation (if missing set defaults)
254
+ # - altitude required by Beard
255
+ # - latitude required for gravity
256
+ ds_env = ensure_valid_coordinates(ds_env)
257
+ # Retrieve fall velocity
258
+ func = dict_methods[method]
259
+ fall_velocity = func(diameter, ds_env=ds_env) if method == "Beard1976" else func(diameter)
260
+ return fall_velocity
disdrodb/l1/filters.py ADDED
@@ -0,0 +1,192 @@
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
+ """Utilities for filtering the disdrometer raw drop spectra."""
18
+
19
+ import numpy as np
20
+ import xarray as xr
21
+
22
+
23
+ def filter_diameter_bins(ds, minimum_diameter=None, maximum_diameter=None):
24
+ """
25
+ Filter the dataset to include only diameter bins within specified bounds.
26
+
27
+ Parameters
28
+ ----------
29
+ ds : xarray.Dataset
30
+ The dataset containing diameter bin data.
31
+ minimum_diameter : float, optional
32
+ The minimum diameter to include in the filter, in millimeters.
33
+ Defaults to the minimum value in `ds["diameter_bin_lower"]`.
34
+ maximum_diameter : float, optional
35
+ The maximum diameter to include in the filter, in millimeters.
36
+ Defaults to the maximum value in `ds["diameter_bin_upper"]`.
37
+
38
+ Returns
39
+ -------
40
+ xarray.Dataset
41
+ The filtered dataset containing only the specified diameter bins.
42
+ """
43
+ # Initialize default arguments
44
+ if minimum_diameter is None:
45
+ minimum_diameter = ds["diameter_bin_lower"].min().item()
46
+ if maximum_diameter is None:
47
+ maximum_diameter = ds["diameter_bin_upper"].max().item()
48
+ # Select valid bins
49
+ valid_indices = np.logical_and(
50
+ ds["diameter_bin_lower"] >= minimum_diameter,
51
+ ds["diameter_bin_upper"] <= maximum_diameter,
52
+ )
53
+ ds = ds.isel({"diameter_bin_center": valid_indices})
54
+ # Update history
55
+ history = ds.attrs.get("history", "")
56
+ ds.attrs["history"] = (
57
+ history + f" Selected drops with diameters between {minimum_diameter} and {maximum_diameter} mm \n"
58
+ )
59
+ return ds
60
+
61
+
62
+ def filter_velocity_bins(ds, minimum_velocity=0, maximum_velocity=12):
63
+ """
64
+ Filter the dataset to include only velocity bins within specified bounds.
65
+
66
+ Parameters
67
+ ----------
68
+ ds : xarray.Dataset
69
+ The dataset containing velocity bin data.
70
+ minimum_velocity : float, optional
71
+ The minimum velocity to include in the filter, in meters per second.
72
+ Defaults to 0 m/s.
73
+ maximum_velocity : float, optional
74
+ The maximum velocity to include in the filter, in meters per second.
75
+ Defaults to 12 m/s.
76
+
77
+ Returns
78
+ -------
79
+ xarray.Dataset
80
+ The filtered dataset containing only the specified velocity bins.
81
+ """
82
+ # Initialize default arguments
83
+ if minimum_velocity is None:
84
+ minimum_velocity = ds["velocity_bin_lower"].min().item()
85
+ if maximum_velocity is None:
86
+ maximum_velocity = ds["velocity_bin_upper"].max().item()
87
+ # Select valid bins
88
+ valid_indices = np.logical_and(
89
+ ds["velocity_bin_lower"] >= minimum_velocity,
90
+ ds["velocity_bin_upper"] <= maximum_velocity,
91
+ )
92
+ ds = ds.isel({"velocity_bin_center": valid_indices})
93
+ # Update history
94
+ history = ds.attrs.get("history", "")
95
+ ds.attrs["history"] = (
96
+ history + f" Selected drops with fall velocity between {minimum_velocity} and {maximum_velocity} m/s \n"
97
+ )
98
+ return ds
99
+
100
+
101
+ def define_spectrum_mask(
102
+ drop_number,
103
+ fall_velocity,
104
+ above_velocity_fraction=None,
105
+ above_velocity_tolerance=None,
106
+ below_velocity_fraction=None,
107
+ below_velocity_tolerance=None,
108
+ small_diameter_threshold=1, # 1, # 2
109
+ small_velocity_threshold=2.5, # 2.5, # 3
110
+ maintain_smallest_drops=False,
111
+ ):
112
+ """Define a mask for the drop spectrum based on fall velocity thresholds.
113
+
114
+ Parameters
115
+ ----------
116
+ drop_number : xarray.DataArray
117
+ Array of drop counts per diameter and velocity bins.
118
+ fall_velocity : array-like
119
+ The expected terminal fall velocities for drops of given sizes.
120
+ above_velocity_fraction : float, optional
121
+ Fraction of terminal fall velocity above which drops are considered too fast.
122
+ Either specify ``above_velocity_fraction`` or ``above_velocity_tolerance``.
123
+ above_velocity_tolerance : float, optional
124
+ Absolute tolerance above which drops terminal fall velocities are considered too fast.
125
+ Either specify ``above_velocity_fraction`` or ``above_velocity_tolerance``.
126
+ below_velocity_fraction : float, optional
127
+ Fraction of terminal fall velocity below which drops are considered too slow.
128
+ Either specify ``below_velocity_fraction`` or ``below_velocity_tolerance``.
129
+ below_velocity_tolerance : float, optional
130
+ Absolute tolerance below which drops terminal fall velocities are considered too slow.
131
+ Either specify ``below_velocity_fraction`` or ``below_velocity_tolerance``.
132
+ maintain_smallest : bool, optional
133
+ If True, ensures that the small drops in the spectrum are retained in the mask.
134
+ The smallest drops are characterized by ``small_diameter_threshold``
135
+ and ``small_velocity_threshold`` arguments.
136
+ Defaults to False.
137
+ small_diameter_threshold : float, optional
138
+ The diameter threshold to use for keeping the smallest drop.
139
+ Defaults to 1 mm.
140
+ small_velocity_threshold : float, optional
141
+ The fall velocity threshold to use for keeping the smallest drops.
142
+ Defaults to 2.5 m/s.
143
+
144
+ Returns
145
+ -------
146
+ xarray.DataArray
147
+ A boolean mask array indicating valid bins according to the specified criteria.
148
+
149
+ """
150
+ # Ensure it creates a 2D mask if the fall_velocity does not vary over time
151
+ if "time" in drop_number.dims and "time" not in fall_velocity.dims:
152
+ drop_number = drop_number.isel(time=0)
153
+
154
+ # Check arguments
155
+ if above_velocity_fraction is not None and above_velocity_tolerance is not None:
156
+ raise ValueError("Either specify 'above_velocity_fraction' or 'above_velocity_tolerance'.")
157
+ if below_velocity_fraction is not None and below_velocity_tolerance is not None:
158
+ raise ValueError("Either specify 'below_velocity_fraction' or 'below_velocity_tolerance'.")
159
+
160
+ # Define above/below velocity thresholds
161
+ if above_velocity_fraction is not None:
162
+ above_fall_velocity = fall_velocity * (1 + above_velocity_fraction)
163
+ elif above_velocity_tolerance is not None:
164
+ above_fall_velocity = fall_velocity + above_velocity_tolerance
165
+ else:
166
+ above_fall_velocity = np.inf
167
+ if below_velocity_fraction is not None:
168
+ below_fall_velocity = fall_velocity * (1 - below_velocity_fraction)
169
+ elif below_velocity_tolerance is not None:
170
+ below_fall_velocity = fall_velocity - below_velocity_tolerance
171
+ else:
172
+ below_fall_velocity = 0
173
+
174
+ # Define velocity 2D array
175
+ velocity_lower = xr.ones_like(drop_number) * drop_number["velocity_bin_lower"]
176
+ velocity_upper = xr.ones_like(drop_number) * drop_number["velocity_bin_upper"]
177
+
178
+ # Define mask
179
+ mask = np.logical_and(
180
+ np.logical_or(velocity_lower >= below_fall_velocity, velocity_upper >= below_fall_velocity),
181
+ np.logical_or(velocity_lower <= above_fall_velocity, velocity_upper <= above_fall_velocity),
182
+ )
183
+
184
+ # Maintant smallest drops
185
+ if maintain_smallest_drops:
186
+ mask_smallest = np.logical_and(
187
+ drop_number["diameter_bin_upper"] < small_diameter_threshold,
188
+ drop_number["velocity_bin_upper"] < small_velocity_threshold,
189
+ )
190
+ mask = np.logical_or(mask, mask_smallest)
191
+
192
+ return mask
@@ -0,0 +1,200 @@
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
+ """Core functions for DISDRODB L1 production."""
18
+
19
+
20
+ import xarray as xr
21
+
22
+ from disdrodb import DIAMETER_DIMENSION, VELOCITY_DIMENSION
23
+ from disdrodb.l1.encoding_attrs import get_attrs_dict, get_encoding_dict
24
+ from disdrodb.l1.fall_velocity import get_raindrop_fall_velocity
25
+ from disdrodb.l1.filters import define_spectrum_mask, filter_diameter_bins, filter_velocity_bins
26
+ from disdrodb.l1.resampling import add_sample_interval
27
+ from disdrodb.l1_env.routines import load_env_dataset
28
+ from disdrodb.l2.empirical_dsd import ( # TODO: maybe move out of L2
29
+ count_bins_with_drops,
30
+ get_min_max_diameter,
31
+ )
32
+ from disdrodb.utils.attrs import set_attrs
33
+ from disdrodb.utils.encoding import set_encodings
34
+ from disdrodb.utils.time import ensure_sample_interval_in_seconds, infer_sample_interval
35
+
36
+
37
+ def generate_l1(
38
+ ds,
39
+ # Fall velocity option
40
+ fall_velocity_method="Beard1976",
41
+ # Diameter-Velocity Filtering Options
42
+ minimum_diameter=0,
43
+ maximum_diameter=10,
44
+ minimum_velocity=0,
45
+ maximum_velocity=12,
46
+ above_velocity_fraction=0.5,
47
+ above_velocity_tolerance=None,
48
+ below_velocity_fraction=0.5,
49
+ below_velocity_tolerance=None,
50
+ small_diameter_threshold=1, # 2
51
+ small_velocity_threshold=2.5, # 3
52
+ maintain_smallest_drops=True,
53
+ ):
54
+ """Generate the DISDRODB L1 dataset from the DISDRODB L0C dataset.
55
+
56
+ Parameters
57
+ ----------
58
+ ds : xarray.Dataset
59
+ DISDRODB L0C dataset.
60
+ fall_velocity_method : str, optional
61
+ Method to compute fall velocity.
62
+ The default method is ``"Beard1976"``.
63
+ minimum_diameter : float, optional
64
+ Minimum diameter for filtering. The default value is 0 mm.
65
+ maximum_diameter : float, optional
66
+ Maximum diameter for filtering. The default value is 10 mm.
67
+ minimum_velocity : float, optional
68
+ Minimum velocity for filtering. The default value is 0 m/s.
69
+ maximum_velocity : float, optional
70
+ Maximum velocity for filtering. The default value is 12 m/s.
71
+ above_velocity_fraction : float, optional
72
+ Fraction of drops above velocity threshold. The default value is 0.5.
73
+ above_velocity_tolerance : float or None, optional
74
+ Tolerance for above velocity filtering. The default value is ``None``.
75
+ below_velocity_fraction : float, optional
76
+ Fraction of drops below velocity threshold. The default value is 0.5.
77
+ below_velocity_tolerance : float or None, optional
78
+ Tolerance for below velocity filtering. The default value is ``None``.
79
+ small_diameter_threshold : float, optional
80
+ Threshold for small diameter drops. The default value is 1.
81
+ small_velocity_threshold : float, optional
82
+ Threshold for small velocity drops. The default value is 2.5.
83
+ maintain_smallest_drops : bool, optional
84
+ Whether to maintain the smallest drops. The default value is ``True``.
85
+
86
+ Returns
87
+ -------
88
+ xarray.Dataset
89
+ DISRODB L1 dataset.
90
+ """
91
+ # Take as input an L0 !
92
+
93
+ # Retrieve source attributes
94
+ attrs = ds.attrs.copy()
95
+
96
+ # Determine if the velocity dimension is available
97
+ has_velocity_dimension = VELOCITY_DIMENSION in ds.dims
98
+
99
+ # Initialize L2 dataset
100
+ ds_l1 = xr.Dataset()
101
+
102
+ # Retrieve sample interval
103
+ # --> sample_interval is a coordinate of L0C products
104
+ if "sample_interval" in ds:
105
+ sample_interval = ensure_sample_interval_in_seconds(ds["sample_interval"].data)
106
+ else:
107
+ # This line is not called in the DISDRODB processing chain !
108
+ sample_interval = infer_sample_interval(ds, verbose=False)
109
+
110
+ # Re-add sample interval as coordinate (in seconds)
111
+ ds = add_sample_interval(ds, sample_interval=sample_interval)
112
+
113
+ # ---------------------------------------------------------------------------
114
+ # Retrieve ENV dataset or take defaults
115
+ # --> Used only for Beard fall velocity currently !
116
+ ds_env = load_env_dataset(ds)
117
+
118
+ # -------------------------------------------------------------------------------------------
119
+ # Filter dataset by diameter and velocity bins
120
+ # - Filter diameter bins
121
+ ds = filter_diameter_bins(ds=ds, minimum_diameter=minimum_diameter, maximum_diameter=maximum_diameter)
122
+ # - Filter velocity bins
123
+ if has_velocity_dimension:
124
+ ds = filter_velocity_bins(ds=ds, minimum_velocity=minimum_velocity, maximum_velocity=maximum_velocity)
125
+
126
+ # -------------------------------------------------------------------------------------------
127
+ # Compute fall velocity
128
+ fall_velocity = get_raindrop_fall_velocity(
129
+ diameter=ds["diameter_bin_center"],
130
+ method=fall_velocity_method,
131
+ ds_env=ds_env, # mm
132
+ )
133
+
134
+ # Add fall velocity
135
+ ds_l1["fall_velocity"] = fall_velocity
136
+
137
+ # -------------------------------------------------------------------------------------------
138
+ # Define filtering mask according to fall velocity
139
+ if has_velocity_dimension:
140
+ mask = define_spectrum_mask(
141
+ drop_number=ds["raw_drop_number"],
142
+ fall_velocity=fall_velocity,
143
+ above_velocity_fraction=above_velocity_fraction,
144
+ above_velocity_tolerance=above_velocity_tolerance,
145
+ below_velocity_fraction=below_velocity_fraction,
146
+ below_velocity_tolerance=below_velocity_tolerance,
147
+ small_diameter_threshold=small_diameter_threshold,
148
+ small_velocity_threshold=small_velocity_threshold,
149
+ maintain_smallest_drops=maintain_smallest_drops,
150
+ )
151
+
152
+ # -------------------------------------------------------------------------------------------
153
+ # Retrieve drop number and drop_counts arrays
154
+ if has_velocity_dimension:
155
+ drop_number = ds["raw_drop_number"].where(mask) # 2D (diameter, velocity)
156
+ drop_counts = drop_number.sum(dim=VELOCITY_DIMENSION) # 1D (diameter)
157
+ drop_counts_raw = ds["raw_drop_number"].sum(dim=VELOCITY_DIMENSION) # 1D (diameter)
158
+
159
+ else:
160
+ drop_number = ds["raw_drop_number"] # 1D (diameter)
161
+ drop_counts = ds["raw_drop_number"] # 1D (diameter)
162
+ drop_counts_raw = ds["raw_drop_number"]
163
+
164
+ # Add drop number and drop_counts
165
+ ds_l1["drop_number"] = drop_number
166
+ ds_l1["drop_counts"] = drop_counts
167
+
168
+ # -------------------------------------------------------------------------------------------
169
+ # Compute minimum and max drop diameter observed
170
+ min_drop_diameter, max_drop_diameter = get_min_max_diameter(drop_counts)
171
+
172
+ # Add drop statistics
173
+ ds_l1["Dmin"] = min_drop_diameter
174
+ ds_l1["Dmax"] = max_drop_diameter
175
+ ds_l1["n_drops_selected"] = drop_counts.sum(dim=DIAMETER_DIMENSION)
176
+ ds_l1["n_drops_discarded"] = drop_counts_raw.sum(dim=DIAMETER_DIMENSION) - ds_l1["n_drops_selected"]
177
+ ds_l1["n_bins_with_drops"] = count_bins_with_drops(ds_l1)
178
+
179
+ # -------------------------------------------------------------------------------------------
180
+ # Add quality flags
181
+ # TODO: snow_flags, insects_flag, ...
182
+
183
+ # -------------------------------------------------------------------------------------------
184
+ #### Add L0C coordinates that might got lost
185
+ if "time_qc" in ds:
186
+ ds_l1 = ds_l1.assign_coords({"time_qc": ds["time_qc"]})
187
+
188
+ #### ----------------------------------------------------------------------------.
189
+ #### Add encodings and attributes
190
+ # Add variables attributes
191
+ attrs_dict = get_attrs_dict()
192
+ ds_l1 = set_attrs(ds_l1, attrs_dict=attrs_dict)
193
+
194
+ # Add variables encoding
195
+ encoding_dict = get_encoding_dict()
196
+ ds_l1 = set_encodings(ds_l1, encoding_dict=encoding_dict)
197
+
198
+ # Add global attributes
199
+ ds_l1.attrs = attrs
200
+ return ds_l1