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
@@ -32,23 +32,25 @@ from disdrodb.l0.check_standards import (
32
32
  from disdrodb.l0.standards import (
33
33
  # get_valid_coordinates_names,
34
34
  get_bin_coords_dict,
35
- get_coords_attrs_dict,
36
35
  get_data_range_dict,
37
36
  get_dims_size_dict,
38
37
  get_l0b_cf_attrs_dict,
39
38
  get_l0b_encodings_dict,
40
39
  get_raw_array_dims_order,
41
40
  get_raw_array_nvalues,
42
- get_time_encoding,
41
+ )
42
+ from disdrodb.utils.attrs import (
43
+ set_coordinate_attributes,
43
44
  set_disdrodb_attrs,
44
45
  )
45
46
  from disdrodb.utils.directories import create_directory, remove_if_exists
47
+ from disdrodb.utils.encoding import set_encodings
46
48
  from disdrodb.utils.logger import (
47
49
  # log_warning,
48
50
  # log_debug,
49
- log_error,
50
51
  log_info,
51
52
  )
53
+ from disdrodb.utils.time import ensure_sorted_by_time
52
54
 
53
55
  logger = logging.getLogger(__name__)
54
56
 
@@ -78,10 +80,7 @@ def infer_split_str(string: str) -> str:
78
80
  idx_delimiter = np.argmax(counts)
79
81
  # If don't find the delimiter, set to None
80
82
  # --> The array will not be split, and then raise an error later on
81
- if counts[idx_delimiter] == 0:
82
- split_str = None
83
- else:
84
- split_str = valid_delims[idx_delimiter]
83
+ split_str = None if counts[idx_delimiter] == 0 else valid_delims[idx_delimiter]
85
84
  else:
86
85
  split_str = None # ''.split(None) output []
87
86
  return split_str
@@ -114,7 +113,6 @@ def _format_string_array(string: str, n_values: int) -> np.array:
114
113
  np.array
115
114
  array of float
116
115
  """
117
-
118
116
  split_str = infer_split_str(string)
119
117
  values = np.array(string.strip(split_str).split(split_str))
120
118
 
@@ -160,17 +158,20 @@ def _reshape_raw_spectrum(
160
158
  dims_order : list
161
159
  The order of dimension in the raw spectrum.
162
160
 
163
- Examples:
164
- - OTT Parsivel spectrum [v1d1 ... v1d32, v2d1, ..., v2d32]
161
+ Examples
162
+ --------
163
+ - OTT PARSIVEL spectrum [v1d1 ... v1d32, v2d1, ..., v2d32]
165
164
  --> dims_order = ["diameter_bin_center", "velocity_bin_center"]
166
165
  - Thies LPM spectrum [v1d1 ... v20d1, v1d2, ..., v20d2]
167
166
  --> dims_order = ["velocity_bin_center", "diameter_bin_center"]
168
167
  dims_size_dict : dict
169
168
  Dictionary with the number of bins for each dimension.
170
- For OTT_Parsivel:
169
+ For PARSIVEL and PARSIVEL2:
171
170
  {"diameter_bin_center": 32, "velocity_bin_center": 32}
172
- For This_LPM
171
+ For LPM
173
172
  {"diameter_bin_center": 22, "velocity_bin_center": 20}
173
+ For PWS100
174
+ {"diameter_bin_center": 34, "velocity_bin_center": 34}
174
175
  n_timesteps : int
175
176
  Number of timesteps.
176
177
 
@@ -185,14 +186,13 @@ def _reshape_raw_spectrum(
185
186
  Impossible to reshape the raw_spectrum matrix
186
187
  """
187
188
  # Define output dimensions
188
- dims = ["time"] + dims_order
189
+ dims = ["time", *dims_order]
189
190
  # Retrieve reshaping dimensions as function of dimension order
190
191
  reshape_dims = [n_timesteps] + [dims_size_dict[dim] for dim in dims_order]
191
192
  try:
192
193
  arr = arr.reshape(reshape_dims)
193
194
  except Exception as e:
194
195
  msg = f"Impossible to reshape the raw_spectrum matrix. The error is: \n {e}"
195
- log_error(logger=logger, msg=msg, verbose=False)
196
196
  raise ValueError(msg)
197
197
  return arr, dims
198
198
 
@@ -200,13 +200,14 @@ def _reshape_raw_spectrum(
200
200
  def retrieve_l0b_arrays(
201
201
  df: pd.DataFrame,
202
202
  sensor_name: str,
203
+ logger=None,
203
204
  verbose: bool = False,
204
205
  ) -> dict:
205
206
  """Retrieves the L0B data matrix.
206
207
 
207
208
  Parameters
208
209
  ----------
209
- df : pd.DataFrame
210
+ df : pandas.DataFrame
210
211
  Input dataframe
211
212
  sensor_name : str
212
213
  Name of the sensor
@@ -217,12 +218,11 @@ def retrieve_l0b_arrays(
217
218
  Dictionary with data arrays.
218
219
 
219
220
  """
220
-
221
- msg = " - Retrieval of L0B data arrays started."
221
+ msg = "Retrieval of L0B data arrays started."
222
222
  log_info(logger=logger, msg=msg, verbose=verbose)
223
223
  # ----------------------------------------------------------.
224
224
  # Check L0 raw field availability
225
- _check_raw_fields_available(df=df, sensor_name=sensor_name)
225
+ _check_raw_fields_available(df=df, sensor_name=sensor_name, logger=logger, verbose=verbose)
226
226
 
227
227
  # Retrieve the number of values expected for each array
228
228
  n_values_dict = get_raw_array_nvalues(sensor_name=sensor_name)
@@ -258,8 +258,8 @@ def retrieve_l0b_arrays(
258
258
 
259
259
  # For key='raw_drop_number', if 2D spectrum, reshape to 2D matrix
260
260
  # Example:
261
- # - This applies i.e for OTT_Parsivel* and Thies_LPM
262
- # - This does not apply to RD_80
261
+ # - This applies i.e for PARSIVEL*, LPM, PWS100
262
+ # - This does not apply to RD80
263
263
  if key == "raw_drop_number" and len(dims_order) == 2:
264
264
  arr, dims = _reshape_raw_spectrum(
265
265
  arr=arr,
@@ -269,14 +269,14 @@ def retrieve_l0b_arrays(
269
269
  )
270
270
  else:
271
271
  # Otherwise just define the dimensions of the array
272
- dims = ["time"] + dims_order
272
+ dims = ["time", *dims_order]
273
273
 
274
274
  # Define dictionary to pass to xr.Dataset
275
275
  dict_data[key] = (dims, arr)
276
276
 
277
277
  # -------------------------------------------------------------------------.
278
278
  # Log
279
- msg = " - Retrieval of L0B data arrays ended."
279
+ msg = "Retrieval of L0B data arrays ended."
280
280
  log_info(logger=logger, msg=msg, verbose=verbose)
281
281
  # Return
282
282
  return dict_data
@@ -287,16 +287,16 @@ def retrieve_l0b_arrays(
287
287
 
288
288
 
289
289
  def _convert_object_variables_to_string(ds: xr.Dataset) -> xr.Dataset:
290
- """Convert variables with object dtype to string.
290
+ """Convert variables with ``object`` dtype to ``string``.
291
291
 
292
292
  Parameters
293
293
  ----------
294
- ds : xr.Dataset
294
+ ds : xarray.Dataset
295
295
  Input dataset.
296
296
 
297
297
  Returns
298
298
  -------
299
- xr.Dataset
299
+ xarray.Dataset
300
300
  Output dataset.
301
301
  """
302
302
  for var in ds.data_vars:
@@ -306,11 +306,11 @@ def _convert_object_variables_to_string(ds: xr.Dataset) -> xr.Dataset:
306
306
 
307
307
 
308
308
  def _set_variable_attributes(ds: xr.Dataset, sensor_name: str) -> xr.Dataset:
309
- """Set attributes to each xr.Dataset variable.
309
+ """Set attributes to each ``xr.Dataset`` variable.
310
310
 
311
311
  Parameters
312
312
  ----------
313
- ds : xr.Dataset
313
+ ds : xarray.Dataset
314
314
  Input dataset.
315
315
  sensor_name : str
316
316
  Name of the sensor.
@@ -333,35 +333,20 @@ def _set_variable_attributes(ds: xr.Dataset, sensor_name: str) -> xr.Dataset:
333
333
  return ds
334
334
 
335
335
 
336
- def _set_attrs_dict(ds, attrs_dict):
337
- for var in attrs_dict.keys():
338
- if var in ds:
339
- ds[var].attrs.update(attrs_dict[var])
340
- return ds
341
-
342
-
343
- def _set_coordinate_attributes(ds):
344
- # Get attributes dictionary
345
- attrs_dict = get_coords_attrs_dict(ds)
346
- # Set attributes
347
- ds = _set_attrs_dict(ds, attrs_dict)
348
- return ds
349
-
350
-
351
336
  def _set_dataset_attrs(ds, sensor_name):
352
337
  """Set variable and coordinates attributes."""
353
338
  # - Add netCDF variable attributes
354
339
  # --> Attributes: long_name, units, descriptions, valid_min, valid_max
355
340
  ds = _set_variable_attributes(ds=ds, sensor_name=sensor_name)
356
341
  # - Add netCDF coordinate attributes
357
- ds = _set_coordinate_attributes(ds=ds)
342
+ ds = set_coordinate_attributes(ds=ds)
358
343
  # - Set DISDRODB global attributes
359
344
  ds = set_disdrodb_attrs(ds=ds, product="L0B")
360
345
  return ds
361
346
 
362
347
 
363
348
  def add_dataset_crs_coords(ds):
364
- "Add the CRS coordinate to the xr.Dataset"
349
+ """Add the CRS coordinate to the xr.Dataset."""
365
350
  # TODO: define CF-compliant CRS !
366
351
  # - CF compliant
367
352
  # - wkt
@@ -377,75 +362,54 @@ def add_dataset_crs_coords(ds):
377
362
  #### L0B Raw DataFrame Preprocessing
378
363
 
379
364
 
380
- def _define_dataset_variables(df, sensor_name, verbose):
365
+ def _define_dataset_variables(df, sensor_name, logger=None, verbose=False):
381
366
  """Define DISDRODB L0B netCDF variables."""
382
367
  # Preprocess raw_spectrum, diameter and velocity arrays if available
383
368
  raw_fields = ["raw_drop_concentration", "raw_drop_average_velocity", "raw_drop_number"]
384
369
  if np.any(np.isin(raw_fields, df.columns)):
385
370
  # Retrieve dictionary of raw data matrices for xarray Dataset
386
- data_vars = retrieve_l0b_arrays(df, sensor_name, verbose=verbose)
371
+ data_vars = retrieve_l0b_arrays(df, sensor_name=sensor_name, logger=logger, verbose=verbose)
387
372
  else:
388
373
  raise ValueError("No raw fields available.")
389
374
 
390
375
  # Define other disdrometer 'auxiliary' variables varying over time dimension
376
+ # - Includes time
377
+ # - Includes longitude and latitude for moving sensors
391
378
  valid_core_fields = [
392
379
  "raw_drop_concentration",
393
380
  "raw_drop_average_velocity",
394
381
  "raw_drop_number",
395
- "time",
396
- # longitude and latitude too for moving sensors
397
382
  ]
398
383
  aux_columns = df.columns[np.isin(df.columns, valid_core_fields, invert=True)]
399
- aux_data_vars = {column: (["time"], df[column].values) for column in aux_columns}
384
+ aux_data_vars = {column: (["time"], df[column].to_numpy()) for column in aux_columns}
400
385
  data_vars.update(aux_data_vars)
401
-
402
- # Add key "time"
403
- # - Is dropped in _define_coordinates !
404
- data_vars["time"] = df["time"].values
405
-
406
386
  return data_vars
407
387
 
408
388
 
409
- def _define_coordinates(data_vars, attrs, sensor_name):
410
- """Define DISDRODB L0B netCDF coordinates."""
411
- # Note: attrs and data_vars are modified in place !
412
-
413
- # - Diameter and velocity
414
- coords = get_bin_coords_dict(sensor_name=sensor_name)
415
-
416
- # - Geolocation + Time
417
- geolocation_vars = ["time", "latitude", "longitude", "altitude"]
418
- for var in geolocation_vars:
419
- if var in data_vars:
420
- coords[var] = data_vars[var]
421
- _ = data_vars.pop(var)
422
- _ = attrs.pop(var, None)
423
- else:
424
- coords[var] = attrs[var]
425
- _ = attrs.pop(var)
426
- return coords
427
-
428
-
429
389
  def create_l0b_from_l0a(
430
390
  df: pd.DataFrame,
431
- attrs: dict,
391
+ metadata: dict,
392
+ logger=None,
432
393
  verbose: bool = False,
433
394
  ) -> xr.Dataset:
434
395
  """Transform the L0A dataframe to the L0B xr.Dataset.
435
396
 
436
397
  Parameters
437
398
  ----------
438
- df : pd.DataFrame
399
+ df : pandas.DataFrame
439
400
  DISDRODB L0A dataframe.
440
- attrs : dict
441
- Station metadata.
401
+ The raw drop number spectrum is reshaped to a 2D(+time) array.
402
+ The raw drop concentration and velocity are reshaped to 1D(+time) arrays.
403
+ metadata : dict
404
+ DISDRODB station metadata.
405
+ To use this function outside the DISDRODB routines, the dictionary must
406
+ contain the fields: ``sensor_name``, ``latitude``, ``longitude``, ``altitude``, ``platform_type``.
442
407
  verbose : bool, optional
443
- Whether to verbose the processing.
444
- The default is False.
408
+ Whether to verbose the processing. The default value is ``False``.
445
409
 
446
410
  Returns
447
411
  -------
448
- xr.Dataset
412
+ xarray.Dataset
449
413
  DISDRODB L0B dataset.
450
414
 
451
415
  Raises
@@ -454,27 +418,15 @@ def create_l0b_from_l0a(
454
418
  Error if the DISDRODB L0B xarray dataset can not be created.
455
419
  """
456
420
  # Retrieve sensor name
457
- attrs = attrs.copy()
458
- sensor_name = attrs["sensor_name"]
459
- # -----------------------------------------------------------.
460
- # Define Dataset variables and coordinates
461
- data_vars = _define_dataset_variables(df, sensor_name=sensor_name, verbose=verbose)
421
+ metadata = metadata.copy()
422
+ sensor_name = metadata["sensor_name"]
462
423
 
463
- # -----------------------------------------------------------.
464
- # Define coordinates for xarray Dataset
465
- # - attrs and data_vars are modified in place !
466
- coords = _define_coordinates(data_vars, attrs=attrs, sensor_name=sensor_name)
424
+ # Define Dataset variables and coordinates
425
+ data_vars = _define_dataset_variables(df, sensor_name=sensor_name, logger=logger, verbose=verbose)
467
426
 
468
- # -----------------------------------------------------------
469
427
  # Create xarray Dataset
470
- ds = xr.Dataset(
471
- data_vars=data_vars,
472
- coords=coords,
473
- attrs=attrs,
474
- )
475
- ds = finalize_dataset(ds, sensor_name=sensor_name)
476
-
477
- # -----------------------------------------------------------
428
+ ds = xr.Dataset(data_vars=data_vars)
429
+ ds = finalize_dataset(ds, sensor_name=sensor_name, metadata=metadata)
478
430
  return ds
479
431
 
480
432
 
@@ -482,8 +434,43 @@ def create_l0b_from_l0a(
482
434
  #### L0B netCDF4 Writer
483
435
 
484
436
 
485
- def finalize_dataset(ds, sensor_name):
437
+ def set_geolocation_coordinates(ds, metadata):
438
+ """Add geolocation coordinates to dataset."""
439
+ # Assumption
440
+ # - If coordinate is present in L0A, overrides the one specified in the attributes
441
+ # - If a station is fixed, discard the coordinates in the DISDRODB reader !
442
+
443
+ # Assign geolocation coordinates to dataset
444
+ coords = ["latitude", "longitude", "altitude"]
445
+ for coord in coords:
446
+ # If coordinate not present, add it from dictionary
447
+ if coord not in ds:
448
+ ds = ds.assign_coords({coord: metadata.pop(coord, np.nan)})
449
+ # Else if set coordinates the variable in the dataset (present in the raw data)
450
+ else:
451
+ ds = ds.set_coords(coord)
452
+ _ = metadata.pop(coord, None)
453
+
454
+ # Set -9999 flag value to np.nan
455
+ for coord in coords:
456
+ ds[coord] = xr.where(ds[coord] == -9999, np.nan, ds[coord])
457
+
458
+ # Set attributes without geolocation coordinates
459
+ ds.attrs = metadata
460
+ return ds
461
+
462
+
463
+ def finalize_dataset(ds, sensor_name, metadata):
486
464
  """Finalize DISDRODB L0B Dataset."""
465
+ # Ensure sorted by time
466
+ ds = ensure_sorted_by_time(ds)
467
+
468
+ # Set diameter and velocity bin coordinates
469
+ ds = ds.assign_coords(get_bin_coords_dict(sensor_name=sensor_name))
470
+
471
+ # Set geolocation coordinates and attributes
472
+ ds = set_geolocation_coordinates(ds, metadata=metadata)
473
+
487
474
  # Add dataset CRS coordinate
488
475
  ds = add_dataset_crs_coords(ds)
489
476
 
@@ -501,88 +488,23 @@ def finalize_dataset(ds, sensor_name):
501
488
  return ds
502
489
 
503
490
 
504
- def sanitize_encodings_dict(encoding_dict: dict, ds: xr.Dataset) -> dict:
505
- """Ensure chunk size to be smaller than the array shape.
491
+ def set_l0b_encodings(ds: xr.Dataset, sensor_name: str):
492
+ """Apply the L0B encodings to the xarray Dataset.
506
493
 
507
494
  Parameters
508
495
  ----------
509
- encoding_dict : dict
510
- Dictionary containing the encoding to write DISDRODB L0B netCDFs.
511
- ds : xr.Dataset
512
- Input dataset.
513
-
514
- Returns
515
- -------
516
- dict
517
- Encoding dictionary.
518
- """
519
- for var in ds.data_vars:
520
- shape = ds[var].shape
521
- chunks = encoding_dict[var]["chunksizes"]
522
- if chunks is not None:
523
- chunks = [shape[i] if chunks[i] > shape[i] else chunks[i] for i in range(len(chunks))]
524
- encoding_dict[var]["chunksizes"] = chunks
525
- return encoding_dict
526
-
527
-
528
- def rechunk_dataset(ds: xr.Dataset, encoding_dict: dict) -> xr.Dataset:
529
- """Coerce the dataset arrays to have the chunk size specified in the encoding dictionary.
530
-
531
- Parameters
532
- ----------
533
- ds : xr.Dataset
534
- Input xarray dataset
535
- encoding_dict : dict
536
- Dictionary containing the encoding to write the xarray dataset as a netCDF.
537
-
538
- Returns
539
- -------
540
- xr.Dataset
541
- Output xarray dataset
542
- """
543
-
544
- for var in ds.data_vars:
545
- chunks = encoding_dict[var].pop("chunksizes")
546
- dims = list(ds[var].dims)
547
- chunks_dict = dict(zip(dims, chunks))
548
- if chunks is not None:
549
- ds[var] = ds[var].chunk(chunks_dict)
550
- return ds
551
-
552
-
553
- def set_encodings(ds: xr.Dataset, sensor_name: str) -> xr.Dataset:
554
- """Apply the encodings to the xarray Dataset.
555
-
556
- Parameters
557
- ----------
558
- ds : xr.Dataset
496
+ ds : xarray.Dataset
559
497
  Input xarray dataset.
560
498
  sensor_name : str
561
499
  Name of the sensor.
562
500
 
563
501
  Returns
564
502
  -------
565
- xr.Dataset
503
+ xarray.Dataset
566
504
  Output xarray dataset.
567
505
  """
568
- # Get encoding dictionary
569
506
  encoding_dict = get_l0b_encodings_dict(sensor_name)
570
- encoding_dict = {k: encoding_dict[k] for k in ds.data_vars}
571
-
572
- # Ensure chunksize smaller than the array shape
573
- encoding_dict = sanitize_encodings_dict(encoding_dict, ds)
574
-
575
- # Rechunk variables for fast writing !
576
- # - This pop the chunksize argument from the encoding dict !
577
- ds = rechunk_dataset(ds, encoding_dict)
578
-
579
- # Set time encoding
580
- ds["time"].encoding.update(get_time_encoding())
581
-
582
- # Set the variable encodings
583
- for var in ds.data_vars:
584
- ds[var].encoding.update(encoding_dict[var])
585
-
507
+ ds = set_encodings(ds=ds, encoding_dict=encoding_dict)
586
508
  return ds
587
509
 
588
510
 
@@ -591,7 +513,7 @@ def write_l0b(ds: xr.Dataset, filepath: str, force=False) -> None:
591
513
 
592
514
  Parameters
593
515
  ----------
594
- ds : xr.Dataset
516
+ ds : xarray.Dataset
595
517
  Input xarray dataset.
596
518
  filepath : str
597
519
  Output file path.
@@ -599,8 +521,8 @@ def write_l0b(ds: xr.Dataset, filepath: str, force=False) -> None:
599
521
  Name of the sensor.
600
522
  force : bool, optional
601
523
  Whether to overwrite existing data.
602
- If True, overwrite existing data into destination directories.
603
- If False, raise an error if there are already data into destination directories. This is the default.
524
+ If ``True``, overwrite existing data into destination directories.
525
+ If ``False``, raise an error if there are already data into destination directories. This is the default.
604
526
  """
605
527
  # Create station directory if does not exist
606
528
  create_directory(os.path.dirname(filepath))
@@ -614,7 +536,7 @@ def write_l0b(ds: xr.Dataset, filepath: str, force=False) -> None:
614
536
  sensor_name = ds.attrs.get("sensor_name")
615
537
 
616
538
  # Set encodings
617
- ds = set_encodings(ds=ds, sensor_name=sensor_name)
539
+ ds = set_l0b_encodings(ds=ds, sensor_name=sensor_name)
618
540
 
619
541
  # Write netcdf
620
542
  ds.to_netcdf(filepath, engine="netcdf4")