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,56 @@
1
+ #!/usr/bin/env python3
2
+ # -----------------------------------------------------------------------------.
3
+ # Copyright (c) 2021-2023 DISDRODB developers
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ # -----------------------------------------------------------------------------.
18
+ """Reader for MEXICO OH_IIUNAM OTT PARSIVEL2 Mexico City Network."""
19
+ from disdrodb.l0.l0_reader import is_documented_by, reader_generic_docstring
20
+ from disdrodb.l0.l0b_nc_processing import open_raw_netcdf_file, standardize_raw_dataset
21
+
22
+
23
+ @is_documented_by(reader_generic_docstring)
24
+ def reader(
25
+ filepath,
26
+ logger=None,
27
+ ):
28
+ """Reader."""
29
+ ##------------------------------------------------------------------------.
30
+ #### Open the netCDF
31
+ ds = open_raw_netcdf_file(filepath=filepath, logger=logger)
32
+
33
+ ##------------------------------------------------------------------------.
34
+ #### Adapt the dataframe to adhere to DISDRODB L0 standards
35
+ # Define dictionary mapping dataset variables to select and rename
36
+ dict_names = {
37
+ ### Dimensions
38
+ "diameter": "diameter_bin_center",
39
+ "velocity": "velocity_bin_center",
40
+ ### Variables
41
+ "intensity": "rainfall_rate_32bit",
42
+ "rain": "rainfall_accumulated_32bit",
43
+ "reflectivity": "reflectivity_32bit",
44
+ "visibility": "mor_visibility",
45
+ "particles": "number_particles",
46
+ # "energy": "rain_kinetic_energy", #KJ, OTT PARSIVEL2 log in J/mh
47
+ # "velocity_avg": only depend on time
48
+ # "diameter_avg": only depend on time
49
+ "spectrum": "raw_drop_number",
50
+ }
51
+
52
+ # Rename dataset variables and columns and infill missing variables
53
+ ds = standardize_raw_dataset(ds=ds, dict_names=dict_names, sensor_name="PARSIVEL2")
54
+
55
+ # Return the dataset adhering to DISDRODB L0B standards
56
+ return ds
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env python3
2
+ # -----------------------------------------------------------------------------.
3
+ # Copyright (c) 2021-2023 DISDRODB developers
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ # -----------------------------------------------------------------------------.
18
+ import pandas as pd
19
+
20
+ from disdrodb.l0.l0_reader import is_documented_by, reader_generic_docstring
21
+ from disdrodb.l0.l0a_processing import read_raw_text_file
22
+
23
+
24
+ @is_documented_by(reader_generic_docstring)
25
+ def reader(
26
+ filepath,
27
+ logger=None,
28
+ ):
29
+ """Reader."""
30
+ ##------------------------------------------------------------------------.
31
+ #### Define column names
32
+ column_names = ["TO_SPLIT"]
33
+
34
+ ##------------------------------------------------------------------------.
35
+ #### Define reader options
36
+ reader_kwargs = {}
37
+
38
+ # - Define delimiter
39
+ reader_kwargs["delimiter"] = "\\n"
40
+
41
+ # - Avoid first column to become df index !!!
42
+ reader_kwargs["index_col"] = False
43
+
44
+ # - Skip first row as columns names
45
+ reader_kwargs["header"] = None
46
+
47
+ # - Define encoding
48
+ reader_kwargs["encoding"] = "latin1"
49
+
50
+ # - Define behaviour when encountering bad lines
51
+ reader_kwargs["on_bad_lines"] = "skip"
52
+
53
+ # - Define reader engine
54
+ # - C engine is faster
55
+ # - Python engine is more feature-complete
56
+ reader_kwargs["engine"] = "python"
57
+
58
+ # - Strings to recognize as NA/NaN and replace with standard NA flags
59
+ # - Already included: '#N/A', '#N/A N/A', '#NA', '-1.#IND', '-1.#QNAN',
60
+ # '-NaN', '-nan', '1.#IND', '1.#QNAN', '<NA>', 'N/A',
61
+ # 'NA', 'NULL', 'NaN', 'n/a', 'nan', 'null'
62
+ reader_kwargs["na_values"] = ["na", "error", "-.-", " NA"]
63
+
64
+ ##------------------------------------------------------------------------.
65
+ #### Read the data
66
+ df = read_raw_text_file(
67
+ filepath=filepath,
68
+ column_names=column_names,
69
+ reader_kwargs=reader_kwargs,
70
+ logger=logger,
71
+ )
72
+
73
+ ##------------------------------------------------------------------------.
74
+ #### Adapt the dataframe to adhere to DISDRODB L0 standards
75
+
76
+ # Remove repeated headers (with length 333)
77
+ df = df[df["TO_SPLIT"].str.len() != 333]
78
+
79
+ # Split into columns and assign name
80
+ df = df["TO_SPLIT"].str.split(",", expand=True, n=15)
81
+ columns = [
82
+ "date",
83
+ "time",
84
+ "rainfall_rate_32bit",
85
+ "rainfall_accumulated_32bit",
86
+ "weather_code_synop_4680",
87
+ "weather_code_metar_4678",
88
+ "weather_code_nws",
89
+ "reflectivity_32bit",
90
+ "mor_visibility",
91
+ "laser_amplitude",
92
+ "number_particles",
93
+ "sensor_temperature",
94
+ "sensor_heating_current",
95
+ "sensor_battery_voltage",
96
+ "rain_kinetic_energy",
97
+ "raw_drop_number",
98
+ ]
99
+ df.columns = columns
100
+
101
+ # Add datetime time column
102
+ df["time"] = df["date"] + "-" + df["time"]
103
+ df["time"] = pd.to_datetime(df["time"], format="%Y.%m.%d-%H:%M:%S", errors="coerce")
104
+ df = df.drop(columns=["date"])
105
+
106
+ # Preprocess the raw spectrum
107
+ # - The '<SPECTRUM>ZERO</SPECTRUM>' indicates no drops detected
108
+ # --> "" generates an array of zeros in L0B processing
109
+ df["raw_drop_number"] = df["raw_drop_number"].replace("<SPECTRUM>ZERO</SPECTRUM>", "")
110
+
111
+ # Remove <SPECTRUM> and </SPECTRUM>" acronyms from the raw_drop_number field
112
+ df["raw_drop_number"] = df["raw_drop_number"].str.replace("<SPECTRUM>", "")
113
+ df["raw_drop_number"] = df["raw_drop_number"].str.replace("</SPECTRUM>", "")
114
+
115
+ # Add 0 before every , if , not preceded by a digit
116
+ # Example: ',,1,,' --> '0,0,1,0,'
117
+ df["raw_drop_number"] = df["raw_drop_number"].str.replace(r"(?<!\d),", "0,", regex=True)
118
+
119
+ # Return the dataframe adhering to DISDRODB L0 standards
120
+ return df
@@ -15,23 +15,20 @@
15
15
  # You should have received a copy of the GNU General Public License
16
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  # -----------------------------------------------------------------------------.
18
- from disdrodb.l0 import run_l0a
18
+ import pandas as pd
19
+
19
20
  from disdrodb.l0.l0_reader import is_documented_by, reader_generic_docstring
21
+ from disdrodb.l0.l0a_processing import read_raw_text_file
20
22
 
21
23
 
22
24
  @is_documented_by(reader_generic_docstring)
23
25
  def reader(
24
- raw_dir,
25
- processed_dir,
26
- station_name,
27
- # Processing options
28
- force=False,
29
- verbose=False,
30
- parallel=False,
31
- debugging_mode=False,
26
+ filepath,
27
+ logger=None,
32
28
  ):
33
- ####----------------------------------------------------------------------.
34
- #### - Define column names
29
+ """Reader."""
30
+ ##------------------------------------------------------------------------.
31
+ #### Define column names
35
32
  column_names = [
36
33
  "day",
37
34
  "month",
@@ -50,7 +47,7 @@ def reader(
50
47
  ]
51
48
 
52
49
  ##------------------------------------------------------------------------.
53
- #### - Define reader options
50
+ #### Define reader options
54
51
  reader_kwargs = {}
55
52
  # - Define delimiter
56
53
  reader_kwargs["delimiter"] = ","
@@ -77,61 +74,45 @@ def reader(
77
74
  reader_kwargs["compression"] = "infer"
78
75
 
79
76
  # - Strings to recognize as NA/NaN and replace with standard NA flags
80
- # - Already included: ‘#N/A’, ‘#N/A N/A’, ‘#NA’, ‘-1.#IND’, ‘-1.#QNAN’,
81
- # ‘-NaN’, ‘-nan’, 1.#IND’, 1.#QNAN’, ‘<NA>’, N/A’,
82
- # NA’, NULL’, NaN’, n/a’, nan’, null
77
+ # - Already included: '#N/A', '#N/A N/A', '#NA', '-1.#IND', '-1.#QNAN',
78
+ # '-NaN', '-nan', '1.#IND', '1.#QNAN', '<NA>', 'N/A',
79
+ # 'NA', 'NULL', 'NaN', 'n/a', 'nan', 'null'
83
80
  reader_kwargs["na_values"] = ["na", "", "error"]
84
81
 
85
82
  ##------------------------------------------------------------------------.
86
- #### - Define facultative dataframe sanitizer function for L0 processing
87
- def df_sanitizer_fun(df):
88
- # Import pandas
89
- import pandas as pd
90
-
91
- # Define datetime time column
92
- df["time"] = (
93
- df["day"].astype(str)
94
- + "-"
95
- + df["month"].astype(str)
96
- + "-"
97
- + df["year"].astype(str)
98
- + " "
99
- + df["hour_minute"].astype(str)
100
- + ":"
101
- + df["second"].astype(str)
102
- )
103
- df["time"] = pd.to_datetime(df["time"], format="%d-%m-%Y %H%M:%S", errors="coerce")
104
-
105
- # Drop columns not agreeing with DISDRODB L0 standards
106
- columns_to_drop = [
107
- "day",
108
- "month",
109
- "year",
110
- "hour_minute",
111
- "second",
112
- ]
113
- df = df.drop(columns=columns_to_drop)
114
-
115
- return df
116
-
117
- ##------------------------------------------------------------------------.
118
- #### - Define glob pattern to search data files in raw_dir/data/<station_name>
119
- glob_patterns = "*.dat"
120
-
121
- ####----------------------------------------------------------------------.
122
- #### - Create L0A products
123
- run_l0a(
124
- raw_dir=raw_dir,
125
- processed_dir=processed_dir,
126
- station_name=station_name,
127
- # Custom arguments of the reader for L0A processing
128
- glob_patterns=glob_patterns,
83
+ #### Read the data
84
+ df = read_raw_text_file(
85
+ filepath=filepath,
129
86
  column_names=column_names,
130
87
  reader_kwargs=reader_kwargs,
131
- df_sanitizer_fun=df_sanitizer_fun,
132
- # Processing options
133
- force=force,
134
- verbose=verbose,
135
- parallel=parallel,
136
- debugging_mode=debugging_mode,
88
+ logger=logger,
137
89
  )
90
+
91
+ ##------------------------------------------------------------------------.
92
+ #### Adapt the dataframe to adhere to DISDRODB L0 standards
93
+ # Define datetime time column
94
+ df["time"] = (
95
+ df["day"].astype(str)
96
+ + "-"
97
+ + df["month"].astype(str)
98
+ + "-"
99
+ + df["year"].astype(str)
100
+ + " "
101
+ + df["hour_minute"].astype(str)
102
+ + ":"
103
+ + df["second"].astype(str)
104
+ )
105
+ df["time"] = pd.to_datetime(df["time"], format="%d-%m-%Y %H%M:%S", errors="coerce")
106
+
107
+ # Drop columns not agreeing with DISDRODB L0 standards
108
+ columns_to_drop = [
109
+ "day",
110
+ "month",
111
+ "year",
112
+ "hour_minute",
113
+ "second",
114
+ ]
115
+ df = df.drop(columns=columns_to_drop)
116
+
117
+ # Return the dataframe adhering to DISDRODB L0 standards
118
+ return df
@@ -0,0 +1,181 @@
1
+ #!/usr/bin/env python3
2
+ # -----------------------------------------------------------------------------.
3
+ # Copyright (c) 2021-2023 DISDRODB developers
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ # -----------------------------------------------------------------------------.
18
+ import numpy as np
19
+ import pandas as pd
20
+
21
+ from disdrodb.l0.l0_reader import is_documented_by, reader_generic_docstring
22
+ from disdrodb.l0.l0a_processing import read_raw_text_file
23
+
24
+
25
+ @is_documented_by(reader_generic_docstring)
26
+ def reader(
27
+ filepath,
28
+ logger=None,
29
+ ):
30
+ """Reader."""
31
+ ##------------------------------------------------------------------------.
32
+ #### Define column names
33
+ column_names = ["TO_PARSE"]
34
+
35
+ ##------------------------------------------------------------------------.
36
+ #### Define reader options
37
+ reader_kwargs = {}
38
+
39
+ # - Define delimiter
40
+ reader_kwargs["delimiter"] = "\\n"
41
+
42
+ # - Define encoding
43
+ reader_kwargs["encoding"] = "ISO-8859-1"
44
+
45
+ # Skip first row as columns names
46
+ reader_kwargs["header"] = None
47
+
48
+ # - Avoid first column to become df index !!!
49
+ reader_kwargs["index_col"] = False
50
+
51
+ # - Define behaviour when encountering bad lines
52
+ reader_kwargs["on_bad_lines"] = "skip"
53
+
54
+ # - Define reader engine
55
+ # - C engine is faster
56
+ # - Python engine is more feature-complete
57
+ reader_kwargs["engine"] = "python"
58
+
59
+ # - Define on-the-fly decompression of on-disk data
60
+ # - Available: gzip, bz2, zip
61
+ reader_kwargs["compression"] = "infer"
62
+
63
+ # - Strings to recognize as NA/NaN and replace with standard NA flags
64
+ # - Already included: '#N/A', '#N/A N/A', '#NA', '-1.#IND', '-1.#QNAN',
65
+ # '-NaN', '-nan', '1.#IND', '1.#QNAN', '<NA>', 'N/A',
66
+ # 'NA', 'NULL', 'NaN', 'n/a', 'nan', 'null'
67
+ reader_kwargs["na_values"] = ["na", "", "error"]
68
+
69
+ ##------------------------------------------------------------------------.
70
+ #### Read the data
71
+ df = read_raw_text_file(
72
+ filepath=filepath,
73
+ column_names=column_names,
74
+ reader_kwargs=reader_kwargs,
75
+ logger=logger,
76
+ )
77
+
78
+ ##------------------------------------------------------------------------.
79
+ #### Adapt the dataframe to adhere to DISDRODB L0 standards
80
+ # Create ID and Value columns
81
+ df = df["TO_PARSE"].str.split(":", expand=True, n=1)
82
+ df.columns = ["ID", "Value"]
83
+
84
+ # Select only rows with values
85
+ df = df[df["Value"].astype(bool)]
86
+ df = df[df["Value"].apply(lambda x: x is not None)]
87
+
88
+ # Drop rows with invalid IDs
89
+ # - Corrupted rows
90
+ valid_id_str = np.char.rjust(np.arange(0, 94).astype(str), width=2, fillchar="0")
91
+ df = df[df["ID"].astype(str).isin(valid_id_str)]
92
+
93
+ # Create the dataframe with each row corresponding to a timestep
94
+ # - Group rows based on when ID values restart
95
+ groups = df.groupby((df["ID"].astype(int).diff() <= 0).cumsum())
96
+
97
+ # Reshape the dataframe
98
+ group_dfs = []
99
+ for _, group in groups:
100
+ group_df = group.set_index("ID").T
101
+ group_dfs.append(group_df)
102
+
103
+ # Merge each timestep dataframe
104
+ # --> Missing columns are infilled by NaN
105
+ df = pd.concat(group_dfs, axis=0)
106
+ df.columns = df.columns.astype(str).str.pad(width=2, side="left", fillchar="0")
107
+
108
+ # Assign column names
109
+ column_dict = {
110
+ "01": "rainfall_rate_32bit",
111
+ "02": "rainfall_accumulated_32bit",
112
+ "03": "weather_code_synop_4680",
113
+ "04": "weather_code_synop_4677",
114
+ "05": "weather_code_metar_4678",
115
+ "06": "weather_code_nws",
116
+ "07": "reflectivity_32bit",
117
+ "08": "mor_visibility",
118
+ "09": "sample_interval",
119
+ "10": "laser_amplitude",
120
+ "11": "number_particles",
121
+ "12": "sensor_temperature",
122
+ # "13": "sensor_serial_number",
123
+ # "14": "firmware_iop",
124
+ # "15": "firmware_dsp",
125
+ "16": "sensor_heating_current",
126
+ "17": "sensor_battery_voltage",
127
+ "18": "sensor_status",
128
+ # "19": "start_time",
129
+ "20": "sensor_time",
130
+ "21": "sensor_date",
131
+ # "22": "station_name",
132
+ # "23": "station_number",
133
+ "24": "rainfall_amount_absolute_32bit",
134
+ "25": "error_code",
135
+ "26": "sensor_temperature_pcb",
136
+ "27": "sensor_temperature_receiver",
137
+ "28": "sensor_temperature_trasmitter",
138
+ "30": "rainfall_rate_16_bit_30",
139
+ "31": "rainfall_rate_16_bit_1200",
140
+ "32": "rainfall_accumulated_16bit",
141
+ "33": "reflectivity_16bit",
142
+ "34": "rain_kinetic_energy",
143
+ "35": "snowfall_rate",
144
+ # 60: "number_particles_all",
145
+ # 61: "list_particles",
146
+ "90": "raw_drop_concentration",
147
+ "91": "raw_drop_average_velocity",
148
+ "93": "raw_drop_number",
149
+ }
150
+
151
+ # Identify missing columns and add NaN
152
+ expected_columns = np.array(list(column_dict.keys()))
153
+ missing_columns = expected_columns[np.isin(expected_columns, df.columns, invert=True)].tolist()
154
+ if len(missing_columns) > 0:
155
+ for column in missing_columns:
156
+ df[column] = "NaN"
157
+
158
+ # Rename columns
159
+ df = df.rename(column_dict, axis=1)
160
+
161
+ # Keep only columns defined in the dictionary
162
+ df = df[list(column_dict.values())]
163
+
164
+ # Define datetime "time" column
165
+ df["time"] = df["sensor_date"] + "-" + df["sensor_time"]
166
+ df["time"] = pd.to_datetime(df["time"], format="%d.%m.%Y-%H:%M:%S", errors="coerce")
167
+
168
+ # Drop columns not agreeing with DISDRODB L0 standards
169
+ columns_to_drop = [
170
+ "sensor_date",
171
+ "sensor_time",
172
+ # "firmware_iop",
173
+ # "firmware_dsp",
174
+ # "sensor_serial_number",
175
+ # "station_name",
176
+ # "station_number",
177
+ ]
178
+ df = df.drop(columns=columns_to_drop)
179
+
180
+ # Return the dataframe adhering to DISDRODB L0 standards
181
+ return df
@@ -0,0 +1,160 @@
1
+ #!/usr/bin/env python3
2
+ # -----------------------------------------------------------------------------.
3
+ # Copyright (c) 2021-2023 DISDRODB developers
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ # -----------------------------------------------------------------------------.
18
+ import numpy as np
19
+ import pandas as pd
20
+
21
+ from disdrodb.l0.l0_reader import is_documented_by, reader_generic_docstring
22
+ from disdrodb.l0.l0a_processing import read_raw_text_file
23
+
24
+
25
+ @is_documented_by(reader_generic_docstring)
26
+ def reader(
27
+ filepath,
28
+ logger=None,
29
+ ):
30
+ """Reader."""
31
+ ##------------------------------------------------------------------------.
32
+ #### Define column names
33
+ column_names = ["TO_PARSE"]
34
+
35
+ ##------------------------------------------------------------------------.
36
+ #### Define reader options
37
+ reader_kwargs = {}
38
+ # - Define delimiter
39
+ reader_kwargs["delimiter"] = "\\n"
40
+ # - Skip first row as columns names
41
+ # - Define encoding
42
+ reader_kwargs["encoding"] = "latin" # "ISO-8859-1"
43
+ # - Avoid first column to become df index !!!
44
+ reader_kwargs["index_col"] = False
45
+ # - Define behaviour when encountering bad lines
46
+ reader_kwargs["on_bad_lines"] = "skip"
47
+ # - Define reader engine
48
+ # - C engine is faster
49
+ # - Python engine is more feature-complete
50
+ reader_kwargs["engine"] = "python"
51
+ # - Define on-the-fly decompression of on-disk data
52
+ # - Available: gzip, bz2, zip
53
+ reader_kwargs["compression"] = "infer"
54
+ # - Strings to recognize as NA/NaN and replace with standard NA flags
55
+ # - Already included: '#N/A', '#N/A N/A', '#NA', '-1.#IND', '-1.#QNAN',
56
+ # '-NaN', '-nan', '1.#IND', '1.#QNAN', '<NA>', 'N/A',
57
+ # 'NA', 'NULL', 'NaN', 'n/a', 'nan', 'null'
58
+ reader_kwargs["na_values"] = ["na", "", "error"]
59
+
60
+ ##------------------------------------------------------------------------.
61
+ #### Read the data
62
+ df = read_raw_text_file(
63
+ filepath=filepath,
64
+ column_names=column_names,
65
+ reader_kwargs=reader_kwargs,
66
+ logger=logger,
67
+ )
68
+
69
+ ##------------------------------------------------------------------------.
70
+ #### Adapt the dataframe to adhere to DISDRODB L0 standards
71
+ # Create ID and Value columns
72
+ df = df["TO_PARSE"].str.split(":", expand=True, n=1)
73
+ df.columns = ["ID", "Value"]
74
+
75
+ # Select only rows with values
76
+ df = df[df["Value"].astype(bool)]
77
+ df = df[df["Value"].apply(lambda x: x is not None)]
78
+
79
+ # Drop rows with invalid IDs
80
+ # - Corrupted rows
81
+ valid_id_str = np.char.rjust(np.arange(0, 94).astype(str), width=2, fillchar="0")
82
+ df = df[df["ID"].astype(str).isin(valid_id_str)]
83
+
84
+ # Create the dataframe with each row corresponding to a timestep
85
+ # - Group rows based on when ID values restart
86
+ groups = df.groupby((df["ID"].astype(int).diff() <= 0).cumsum())
87
+
88
+ # Reshape the dataframe
89
+ group_dfs = []
90
+ for _, group in groups:
91
+ group_df = group.set_index("ID").T
92
+ group_dfs.append(group_df)
93
+
94
+ # Merge each timestep dataframe
95
+ # --> Missing columns are infilled by NaN
96
+ df = pd.concat(group_dfs, axis=0)
97
+
98
+ # Assign column names
99
+ column_dict = {
100
+ "01": "rainfall_rate_32bit",
101
+ "02": "rainfall_accumulated_32bit",
102
+ "03": "weather_code_synop_4680",
103
+ "04": "weather_code_synop_4677",
104
+ "05": "weather_code_metar_4678",
105
+ "06": "weather_code_nws",
106
+ "07": "reflectivity_32bit",
107
+ "08": "mor_visibility",
108
+ "09": "sample_interval",
109
+ "10": "laser_amplitude",
110
+ "11": "number_particles",
111
+ "12": "sensor_temperature",
112
+ # "13": "sensor_serial_number",
113
+ # "14": "firmware_iop",
114
+ # "15": "firmware_dsp",
115
+ "16": "sensor_heating_current",
116
+ "17": "sensor_battery_voltage",
117
+ "18": "sensor_status",
118
+ # "19": "start_time",
119
+ "20": "sensor_time",
120
+ "21": "sensor_date",
121
+ # "22": "station_name",
122
+ # "23": "station_number",
123
+ "24": "rainfall_amount_absolute_32bit",
124
+ "25": "error_code",
125
+ "30": "rainfall_rate_16_bit_30",
126
+ "31": "rainfall_rate_16_bit_1200",
127
+ "32": "rainfall_accumulated_16bit",
128
+ "90": "raw_drop_concentration",
129
+ "91": "raw_drop_average_velocity",
130
+ "93": "raw_drop_number",
131
+ }
132
+ df = df.rename(column_dict, axis=1)
133
+
134
+ # Keep only columns defined in the dictionary
135
+ df = df[list(column_dict.values())]
136
+
137
+ # Define datetime "time" column
138
+ df["time"] = df["sensor_date"] + "-" + df["sensor_time"]
139
+ df["time"] = pd.to_datetime(df["time"], format="%d.%m.%Y-%H:%M:%S", errors="coerce")
140
+
141
+ # Drop columns not agreeing with DISDRODB L0 standards
142
+ columns_to_drop = [
143
+ "sensor_date",
144
+ "sensor_time",
145
+ # "firmware_iop",
146
+ # "firmware_dsp",
147
+ # "sensor_serial_number",
148
+ # "station_name",
149
+ # "station_number",
150
+ ]
151
+ df = df.drop(columns=columns_to_drop)
152
+
153
+ # Preprocess the raw spectrum and raw_drop_average_velocity
154
+ # - Add 0 before every ; if ; not preceded by a digit
155
+ # - Example: ';;1;;' --> '0;0;1;0;'
156
+ df["raw_drop_average_velocity"] = df["raw_drop_average_velocity"].str.replace(r"(?<!\d);", "0;", regex=True)
157
+ df["raw_drop_number"] = df["raw_drop_number"].str.replace(r"(?<!\d);", "0;", regex=True)
158
+
159
+ # Return the dataframe adhering to DISDRODB L0 standards
160
+ return df