disdrodb 0.1.0__py3-none-any.whl → 0.1.2__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.
- disdrodb/__init__.py +1 -1
- disdrodb/_version.py +2 -2
- disdrodb/api/io.py +12 -2
- disdrodb/data_transfer/download_data.py +145 -14
- disdrodb/l0/check_standards.py +15 -10
- disdrodb/l0/configs/LPM/bins_diameter.yml +3 -3
- disdrodb/l0/configs/LPM/l0a_encodings.yml +4 -4
- disdrodb/l0/configs/LPM/l0b_cf_attrs.yml +22 -6
- disdrodb/l0/configs/LPM/l0b_encodings.yml +41 -0
- disdrodb/l0/configs/LPM/raw_data_format.yml +40 -0
- disdrodb/l0/configs/PARSIVEL/l0b_cf_attrs.yml +1 -1
- disdrodb/l0/configs/PARSIVEL/raw_data_format.yml +1 -1
- disdrodb/l0/configs/PARSIVEL2/l0a_encodings.yml +4 -0
- disdrodb/l0/configs/PARSIVEL2/l0b_cf_attrs.yml +20 -4
- disdrodb/l0/configs/PARSIVEL2/l0b_encodings.yml +41 -0
- disdrodb/l0/configs/PARSIVEL2/raw_data_format.yml +50 -10
- disdrodb/l0/configs/PWS100/bins_diameter.yml +173 -0
- disdrodb/l0/configs/PWS100/bins_velocity.yml +173 -0
- disdrodb/l0/configs/PWS100/l0a_encodings.yml +19 -0
- disdrodb/l0/configs/PWS100/l0b_cf_attrs.yml +76 -0
- disdrodb/l0/configs/PWS100/l0b_encodings.yml +176 -0
- disdrodb/l0/configs/PWS100/raw_data_format.yml +182 -0
- disdrodb/l0/configs/RD80/raw_data_format.yml +2 -6
- disdrodb/l0/l0b_nc_processing.py +1 -1
- disdrodb/l0/l0b_processing.py +12 -10
- disdrodb/l0/manuals/SWS250.pdf +0 -0
- disdrodb/l0/manuals/VPF730.pdf +0 -0
- disdrodb/l0/manuals/VPF750.pdf +0 -0
- disdrodb/l0/readers/LPM/AUSTRALIA/MELBOURNE_2007_LPM.py +23 -13
- disdrodb/l0/readers/LPM/BRAZIL/CHUVA_LPM.py +3 -3
- disdrodb/l0/readers/LPM/BRAZIL/GOAMAZON_LPM.py +5 -3
- disdrodb/l0/readers/LPM/ITALY/GID_LPM.py +36 -20
- disdrodb/l0/readers/LPM/ITALY/GID_LPM_W.py +210 -0
- disdrodb/l0/readers/LPM/KIT/CHWALA.py +225 -0
- disdrodb/l0/readers/LPM/SLOVENIA/ARSO.py +197 -0
- disdrodb/l0/readers/LPM/SLOVENIA/CRNI_VRH.py +197 -0
- disdrodb/l0/readers/PARSIVEL/GPM/PIERS.py +107 -0
- disdrodb/l0/readers/PARSIVEL/JAPAN/JMA.py +125 -0
- disdrodb/l0/readers/PARSIVEL/NCAR/PECAN_MOBILE.py +1 -1
- disdrodb/l0/readers/PARSIVEL/NCAR/VORTEX2_2009.py +1 -1
- disdrodb/l0/readers/PARSIVEL/SLOVENIA/UL_FGG.py +121 -0
- disdrodb/l0/readers/PARSIVEL2/FRANCE/ENPC_PARSIVEL2.py +189 -0
- disdrodb/l0/readers/PARSIVEL2/KIT/BURKINA_FASO.py +133 -0
- disdrodb/l0/readers/PARSIVEL2/NCAR/FARM_PARSIVEL2.py +138 -0
- disdrodb/l0/readers/PARSIVEL2/NCAR/PECAN_FP3.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_P2.py +1 -1
- disdrodb/l0/readers/PARSIVEL2/NCAR/VORTEX_SE_2016_PIPS.py +9 -0
- disdrodb/l0/readers/PARSIVEL2/NETHERLANDS/DELFT_NC.py +67 -0
- disdrodb/l0/readers/PWS100/FRANCE/ENPC_PWS100.py +150 -0
- disdrodb/l0/readers/RD80/NOAA/PSL_RD80.py +291 -0
- disdrodb/l0/readers/template_reader_raw_netcdf_data.py +1 -1
- disdrodb/l0/standards.py +7 -4
- disdrodb/l0/template_tools.py +2 -2
- disdrodb/l1/encoding_attrs.py +30 -8
- disdrodb/l1/processing.py +6 -4
- disdrodb/l1/resampling.py +1 -1
- disdrodb/l1/routines.py +9 -7
- disdrodb/l2/empirical_dsd.py +100 -2
- disdrodb/l2/event.py +3 -3
- disdrodb/l2/processing.py +21 -12
- disdrodb/l2/processing_options.py +7 -7
- disdrodb/l2/routines.py +3 -3
- disdrodb/metadata/checks.py +15 -6
- disdrodb/metadata/manipulation.py +2 -2
- disdrodb/metadata/standards.py +83 -79
- disdrodb/metadata/writer.py +2 -2
- disdrodb/routines.py +246 -10
- disdrodb/scattering/routines.py +1 -1
- disdrodb/utils/dataframe.py +342 -0
- disdrodb/utils/directories.py +14 -2
- disdrodb/utils/xarray.py +83 -0
- {disdrodb-0.1.0.dist-info → disdrodb-0.1.2.dist-info}/METADATA +34 -61
- {disdrodb-0.1.0.dist-info → disdrodb-0.1.2.dist-info}/RECORD +77 -54
- {disdrodb-0.1.0.dist-info → disdrodb-0.1.2.dist-info}/WHEEL +1 -1
- {disdrodb-0.1.0.dist-info → disdrodb-0.1.2.dist-info}/entry_points.txt +3 -3
- {disdrodb-0.1.0.dist-info → disdrodb-0.1.2.dist-info}/licenses/LICENSE +0 -0
- {disdrodb-0.1.0.dist-info → disdrodb-0.1.2.dist-info}/top_level.txt +0 -0
disdrodb/__init__.py
CHANGED
|
@@ -73,7 +73,7 @@ DIAMETER_COORDS = ["diameter_bin_center", "diameter_bin_width", "diameter_bin_lo
|
|
|
73
73
|
VELOCITY_COORDS = ["velocity_bin_center", "velocity_bin_width", "velocity_bin_lower", "velocity_bin_upper"]
|
|
74
74
|
VELOCITY_DIMENSION = "velocity_bin_center"
|
|
75
75
|
DIAMETER_DIMENSION = "diameter_bin_center"
|
|
76
|
-
OPTICAL_SENSORS = ["PARSIVEL", "PARSIVEL2", "LPM"]
|
|
76
|
+
OPTICAL_SENSORS = ["PARSIVEL", "PARSIVEL2", "LPM", "PWS100"]
|
|
77
77
|
IMPACT_SENSORS = ["RD80"]
|
|
78
78
|
|
|
79
79
|
|
disdrodb/_version.py
CHANGED
disdrodb/api/io.py
CHANGED
|
@@ -141,6 +141,7 @@ def open_dataset(
|
|
|
141
141
|
product_kwargs=None,
|
|
142
142
|
debugging_mode: bool = False,
|
|
143
143
|
data_archive_dir: Optional[str] = None,
|
|
144
|
+
parallel=False,
|
|
144
145
|
**open_kwargs,
|
|
145
146
|
):
|
|
146
147
|
"""Retrieve DISDRODB product files for a give station.
|
|
@@ -205,8 +206,17 @@ def open_dataset(
|
|
|
205
206
|
# Open DISDRODB netCDF files using xarray
|
|
206
207
|
# - TODO: parallel option and add closers !
|
|
207
208
|
# - decode_timedelta -- > sample_interval not decoded to timedelta !
|
|
208
|
-
list_ds = [xr.open_dataset(fpath, decode_timedelta=False, **open_kwargs) for fpath in filepaths]
|
|
209
|
-
ds = xr.concat(list_ds, dim="time")
|
|
209
|
+
# list_ds = [xr.open_dataset(fpath, decode_timedelta=False, **open_kwargs) for fpath in filepaths]
|
|
210
|
+
# ds = xr.concat(list_ds, dim="time")
|
|
211
|
+
ds = xr.open_mfdataset(
|
|
212
|
+
filepaths,
|
|
213
|
+
engine="netcdf4",
|
|
214
|
+
combine="nested", # 'by_coords',
|
|
215
|
+
concat_dim="time",
|
|
216
|
+
decode_timedelta=False,
|
|
217
|
+
parallel=parallel,
|
|
218
|
+
**open_kwargs,
|
|
219
|
+
)
|
|
210
220
|
return ds
|
|
211
221
|
|
|
212
222
|
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
import logging
|
|
22
22
|
import os
|
|
23
23
|
import shutil
|
|
24
|
+
import subprocess
|
|
25
|
+
import urllib.parse
|
|
24
26
|
from typing import Optional, Union
|
|
25
27
|
|
|
26
28
|
import click
|
|
@@ -213,7 +215,7 @@ def download_station(
|
|
|
213
215
|
check_exists=True,
|
|
214
216
|
)
|
|
215
217
|
# Download data
|
|
216
|
-
|
|
218
|
+
download_station_data(metadata_filepath, data_archive_dir=data_archive_dir, force=force)
|
|
217
219
|
|
|
218
220
|
|
|
219
221
|
def _is_valid_disdrodb_data_url(disdrodb_data_url):
|
|
@@ -228,13 +230,25 @@ def _extract_station_files(zip_filepath, station_dir):
|
|
|
228
230
|
os.remove(zip_filepath)
|
|
229
231
|
|
|
230
232
|
|
|
231
|
-
def
|
|
233
|
+
def check_consistent_station_name(metadata_filepath, station_name):
|
|
234
|
+
"""Check consistent station_name between YAML file name and metadata key."""
|
|
235
|
+
# Check consistent station name
|
|
236
|
+
expected_station_name = os.path.basename(metadata_filepath).replace(".yml", "")
|
|
237
|
+
if station_name and str(station_name) != str(expected_station_name):
|
|
238
|
+
raise ValueError(f"Inconsistent station_name values in the {metadata_filepath} file. Download aborted.")
|
|
239
|
+
return station_name
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def download_station_data(metadata_filepath: str, data_archive_dir: str, force: bool = False) -> None:
|
|
232
243
|
"""Download and unzip the station data .
|
|
233
244
|
|
|
234
245
|
Parameters
|
|
235
246
|
----------
|
|
236
247
|
metadata_filepaths : str
|
|
237
248
|
Metadata file path.
|
|
249
|
+
data_archive_dir : str (optional)
|
|
250
|
+
DISDRODB Data Archive directory. Format: ``<...>/DISDRODB``.
|
|
251
|
+
If ``None`` (the default), the disdrodb config variable ``data_archive_dir`` is used.
|
|
238
252
|
force : bool, optional
|
|
239
253
|
If ``True``, delete existing files and redownload it. The default value is ``False``.
|
|
240
254
|
|
|
@@ -247,7 +261,7 @@ def _download_station_data(metadata_filepath: str, data_archive_dir: str, force:
|
|
|
247
261
|
campaign_name = metadata_dict["campaign_name"]
|
|
248
262
|
station_name = metadata_dict["station_name"]
|
|
249
263
|
station_name = check_consistent_station_name(metadata_filepath, station_name)
|
|
250
|
-
# Define the
|
|
264
|
+
# Define the path to the station RAW data directory
|
|
251
265
|
station_dir = define_station_dir(
|
|
252
266
|
data_archive_dir=data_archive_dir,
|
|
253
267
|
data_source=data_source,
|
|
@@ -259,19 +273,136 @@ def _download_station_data(metadata_filepath: str, data_archive_dir: str, force:
|
|
|
259
273
|
disdrodb_data_url = metadata_dict.get("disdrodb_data_url", None)
|
|
260
274
|
if not _is_valid_disdrodb_data_url(disdrodb_data_url):
|
|
261
275
|
raise ValueError(f"Invalid disdrodb_data_url '{disdrodb_data_url}' for station {station_name}")
|
|
262
|
-
# Download file
|
|
263
|
-
zip_filepath = _download_file_from_url(disdrodb_data_url, dst_dir=station_dir, force=force)
|
|
264
|
-
# Extract the stations files from the downloaded station.zip file
|
|
265
|
-
_extract_station_files(zip_filepath, station_dir=station_dir)
|
|
266
276
|
|
|
277
|
+
# Download files
|
|
278
|
+
# - Option 1: Zip file from Zenodo containing all station raw data
|
|
279
|
+
if disdrodb_data_url.startswith("https://zenodo.org/"):
|
|
280
|
+
download_zenodo_zip_file(url=disdrodb_data_url, dst_dir=station_dir, force=force)
|
|
281
|
+
# - Option 2: Recursive download from a web server via HTTP or HTTPS.
|
|
282
|
+
elif disdrodb_data_url.startswith("http"):
|
|
283
|
+
download_web_server_data(url=disdrodb_data_url, dst_dir=station_dir, force=force, verbose=True)
|
|
284
|
+
else:
|
|
285
|
+
raise NotImplementedError(f"Open a GitHub Issue to enable the download of data from {disdrodb_data_url}.")
|
|
267
286
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
287
|
+
|
|
288
|
+
####-----------------------------------------------------------------------------------------.
|
|
289
|
+
#### Download from Web Server via HTTP or HTTPS
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def download_web_server_data(url: str, dst_dir: str, force=True, verbose=True) -> None:
|
|
293
|
+
"""Download data from a web server via HTTP or HTTPS.
|
|
294
|
+
|
|
295
|
+
Use the system's wget command to recursively download all files and subdirectories
|
|
296
|
+
under the given HTTPS “directory” URL. Works on both Windows and Linux, provided
|
|
297
|
+
that wget is installed and on the PATH.
|
|
298
|
+
|
|
299
|
+
1. Ensure wget is available.
|
|
300
|
+
2. Normalize URL to end with '/'.
|
|
301
|
+
3. Compute cut-dirs so that only the last segment of the path remains locally.
|
|
302
|
+
4. Build and run the wget command.
|
|
303
|
+
|
|
304
|
+
Example:
|
|
305
|
+
download_with_wget("https://ruisdael.citg.tudelft.nl/parsivel/PAR001_Cabauw/2021/202101/")
|
|
306
|
+
# → Creates a local folder "202101/" with all files and subfolders.
|
|
307
|
+
"""
|
|
308
|
+
# 1. Ensure wget exists
|
|
309
|
+
ensure_wget_available()
|
|
310
|
+
|
|
311
|
+
# 2. Normalize URL
|
|
312
|
+
url = ensure_trailing_slash(url)
|
|
313
|
+
|
|
314
|
+
# 3. Compute cut-dirs so that only the last URL segment remains locally
|
|
315
|
+
cut_dirs = compute_cut_dirs(url)
|
|
316
|
+
|
|
317
|
+
# 4. Create destination directory if needed
|
|
318
|
+
os.makedirs(dst_dir, exist_ok=True)
|
|
319
|
+
|
|
320
|
+
# 5. Build wget command
|
|
321
|
+
cmd = build_webserver_wget_command(url, cut_dirs=cut_dirs, dst_dir=dst_dir, force=force, verbose=verbose)
|
|
322
|
+
|
|
323
|
+
# 6. Run wget command
|
|
324
|
+
try:
|
|
325
|
+
subprocess.run(cmd, check=True)
|
|
326
|
+
except subprocess.CalledProcessError as e:
|
|
327
|
+
raise subprocess.CalledProcessError(
|
|
328
|
+
returncode=e.returncode,
|
|
329
|
+
cmd=e.cmd,
|
|
330
|
+
output=e.output,
|
|
331
|
+
stderr=e.stderr,
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def ensure_wget_available() -> None:
|
|
336
|
+
"""Raise FileNotFoundError if 'wget' is not on the system PATH."""
|
|
337
|
+
if shutil.which("wget") is None:
|
|
338
|
+
raise FileNotFoundError("The WGET software was not found. Please install WGET or add it to PATH.")
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
def ensure_trailing_slash(url: str) -> str:
|
|
342
|
+
"""Return `url` guaranteed to end with a slash."""
|
|
343
|
+
return url if url.endswith("/") else url.rstrip("/") + "/"
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
def compute_cut_dirs(url: str) -> int:
|
|
347
|
+
"""Compute the wget cut_dirs value to download directly in `dst_dir`.
|
|
348
|
+
|
|
349
|
+
Given a URL ending with '/', compute the total number of path segments.
|
|
350
|
+
By returning len(segments), we strip away all of them—so that files
|
|
351
|
+
within that final directory land directly in `dst_dir` without creating
|
|
352
|
+
an extra subfolder.
|
|
353
|
+
"""
|
|
354
|
+
parsed = urllib.parse.urlparse(url)
|
|
355
|
+
path = parsed.path.strip("/") # remove leading/trailing '/'
|
|
356
|
+
segments = path.split("/") if path else []
|
|
357
|
+
return len(segments)
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
def build_webserver_wget_command(url: str, cut_dirs: int, dst_dir: str, force: bool, verbose: bool) -> list[str]:
|
|
361
|
+
"""Construct the wget command list for subprocess.run.
|
|
362
|
+
|
|
363
|
+
Notes
|
|
364
|
+
-----
|
|
365
|
+
The following wget arguments are used
|
|
366
|
+
- -q : quiet mode (no detailed progress)
|
|
367
|
+
- -r : recursive
|
|
368
|
+
- -np : no parent
|
|
369
|
+
- -nH : no host directories
|
|
370
|
+
- --timestamping: download missing files or when remote version is newer
|
|
371
|
+
- --cut-dirs : strip all but the last path segment from the remote path
|
|
372
|
+
- -P dst_dir : download into `dst_dir`
|
|
373
|
+
- url
|
|
374
|
+
"""
|
|
375
|
+
cmd = ["wget"]
|
|
376
|
+
if verbose:
|
|
377
|
+
cmd.append("-q")
|
|
378
|
+
cmd += [
|
|
379
|
+
"-r",
|
|
380
|
+
"-np",
|
|
381
|
+
"-nH",
|
|
382
|
+
f"--cut-dirs={cut_dirs}",
|
|
383
|
+
]
|
|
384
|
+
if force:
|
|
385
|
+
cmd.append("--timestamping") # -N
|
|
386
|
+
|
|
387
|
+
# Define source and destination directory
|
|
388
|
+
cmd += [
|
|
389
|
+
"-P",
|
|
390
|
+
dst_dir,
|
|
391
|
+
url,
|
|
392
|
+
]
|
|
393
|
+
return cmd
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
####--------------------------------------------------------------------.
|
|
397
|
+
#### Download from Zenodo
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
def download_zenodo_zip_file(url, dst_dir, force):
|
|
401
|
+
"""Download zip file from zenodo and extract station raw data."""
|
|
402
|
+
# Download zip file
|
|
403
|
+
zip_filepath = _download_file_from_url(url, dst_dir=dst_dir, force=force)
|
|
404
|
+
# Extract the stations files from the downloaded station.zip file
|
|
405
|
+
_extract_station_files(zip_filepath, station_dir=dst_dir)
|
|
275
406
|
|
|
276
407
|
|
|
277
408
|
def _download_file_from_url(url: str, dst_dir: str, force: bool = False) -> str:
|
disdrodb/l0/check_standards.py
CHANGED
|
@@ -80,7 +80,12 @@ def _check_valid_values(df, dict_valid_values):
|
|
|
80
80
|
raise ValueError(f"Columns {list_wrong_columns} have invalid values.")
|
|
81
81
|
|
|
82
82
|
|
|
83
|
-
def _check_raw_fields_available(
|
|
83
|
+
def _check_raw_fields_available(
|
|
84
|
+
df: pd.DataFrame,
|
|
85
|
+
sensor_name: str, # noqa: ARG001
|
|
86
|
+
logger=None, # noqa: ARG001
|
|
87
|
+
verbose: bool = False, # noqa: ARG001
|
|
88
|
+
) -> None:
|
|
84
89
|
"""Check the presence of the raw spectrum data according to the type of sensor.
|
|
85
90
|
|
|
86
91
|
Parameters
|
|
@@ -95,22 +100,22 @@ def _check_raw_fields_available(df: pd.DataFrame, sensor_name: str, logger=None,
|
|
|
95
100
|
ValueError
|
|
96
101
|
Error if the ``raw_drop_number`` field is missing.
|
|
97
102
|
"""
|
|
98
|
-
from disdrodb.l0.standards import get_raw_array_nvalues
|
|
99
|
-
|
|
100
|
-
# Retrieve raw arrays that could be available (based on sensor_name)
|
|
101
|
-
n_bins_dict = get_raw_array_nvalues(sensor_name=sensor_name)
|
|
102
|
-
raw_vars = np.array(list(n_bins_dict.keys()))
|
|
103
|
+
# from disdrodb.l0.standards import get_raw_array_nvalues
|
|
103
104
|
|
|
104
105
|
# Check that raw_drop_number is present
|
|
105
106
|
if "raw_drop_number" not in df.columns:
|
|
106
107
|
msg = "The 'raw_drop_number' column is not present in the dataframe."
|
|
107
108
|
raise ValueError(msg)
|
|
108
109
|
|
|
110
|
+
# Retrieve raw arrays that could be available (based on sensor_name)
|
|
111
|
+
# n_bins_dict = get_raw_array_nvalues(sensor_name=sensor_name)
|
|
112
|
+
|
|
109
113
|
# Report additional raw arrays that are missing
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
+
# raw_vars = np.array(list(n_bins_dict.keys()))
|
|
115
|
+
# missing_vars = raw_vars[np.isin(raw_vars, list(df.columns), invert=True)]
|
|
116
|
+
# if len(missing_vars) > 0:
|
|
117
|
+
# msg = f"The following raw array variable are missing: {missing_vars}"
|
|
118
|
+
# log_info(logger=logger, msg=msg, verbose=verbose)
|
|
114
119
|
|
|
115
120
|
|
|
116
121
|
def check_l0a_column_names(df: pd.DataFrame, sensor_name: str) -> None:
|
|
@@ -20,7 +20,7 @@ center:
|
|
|
20
20
|
18: 6.75
|
|
21
21
|
19: 7.25
|
|
22
22
|
20: 7.75
|
|
23
|
-
21:
|
|
23
|
+
21: 9
|
|
24
24
|
bounds:
|
|
25
25
|
0:
|
|
26
26
|
- 0.125
|
|
@@ -87,7 +87,7 @@ bounds:
|
|
|
87
87
|
- 8.0
|
|
88
88
|
21:
|
|
89
89
|
- 8.0
|
|
90
|
-
-
|
|
90
|
+
- 10.0
|
|
91
91
|
width:
|
|
92
92
|
0: 0.125
|
|
93
93
|
1: 0.125
|
|
@@ -110,4 +110,4 @@ width:
|
|
|
110
110
|
18: 0.5
|
|
111
111
|
19: 0.5
|
|
112
112
|
20: 0.5
|
|
113
|
-
21:
|
|
113
|
+
21: 2
|
|
@@ -74,7 +74,7 @@ number_particles_class_8_internal_data: "float32"
|
|
|
74
74
|
number_particles_class_9: "float32" # 'uint16'
|
|
75
75
|
number_particles_class_9_internal_data: "float32"
|
|
76
76
|
raw_drop_number: "str"
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
air_temperature: "float32"
|
|
78
|
+
relative_humidity: "float32"
|
|
79
|
+
wind_speed: "float32"
|
|
80
|
+
wind_direction: "float32"
|
|
@@ -127,13 +127,13 @@ reserve_status:
|
|
|
127
127
|
long_name: Reserve status
|
|
128
128
|
units: ""
|
|
129
129
|
temperature_interior:
|
|
130
|
-
description: "Interior temperature [
|
|
130
|
+
description: "Interior temperature [C] (NNN)"
|
|
131
131
|
long_name: Interior temperature
|
|
132
|
-
units: "
|
|
132
|
+
units: "C"
|
|
133
133
|
laser_temperature:
|
|
134
|
-
description: "Temperature of laser driver 0-
|
|
134
|
+
description: "Temperature of laser driver 0-80C (NN)"
|
|
135
135
|
long_name: Temperature of laser driver
|
|
136
|
-
units: "
|
|
136
|
+
units: "C"
|
|
137
137
|
laser_current_average:
|
|
138
138
|
description: Mean value laser current [1/100 mA] (NNNN)
|
|
139
139
|
long_name: Mean value laser current
|
|
@@ -159,9 +159,9 @@ current_heating_pane_receiver_head:
|
|
|
159
159
|
long_name: Current pane heating receiver head
|
|
160
160
|
units: mA
|
|
161
161
|
temperature_ambient:
|
|
162
|
-
description: "Ambient temperature [
|
|
162
|
+
description: "Ambient temperature [C] (NNN.N)"
|
|
163
163
|
long_name: Ambient temperature
|
|
164
|
-
units: "
|
|
164
|
+
units: "C"
|
|
165
165
|
current_heating_voltage_supply:
|
|
166
166
|
description:
|
|
167
167
|
Voltage Heating supply [1/10 V] (only 5.4110.x1.xxx, otherwise "999")
|
|
@@ -308,3 +308,19 @@ raw_drop_number:
|
|
|
308
308
|
description: Precipitation spectrum
|
|
309
309
|
long_name: Precipitation spectrum
|
|
310
310
|
units: ""
|
|
311
|
+
air_temperature:
|
|
312
|
+
description: "Air temperature in degrees Celsius (C)"
|
|
313
|
+
long_name: Air temperature
|
|
314
|
+
units: "C"
|
|
315
|
+
relative_humidity:
|
|
316
|
+
description: "Relative humidity in percent (%)"
|
|
317
|
+
long_name: Relative humidity
|
|
318
|
+
units: "%"
|
|
319
|
+
wind_speed:
|
|
320
|
+
description: "Wind speed in m/s"
|
|
321
|
+
long_name: Wind speed
|
|
322
|
+
units: "m/s"
|
|
323
|
+
wind_direction:
|
|
324
|
+
description: "Wind direction in degrees (0-360)"
|
|
325
|
+
long_name: Wind direction
|
|
326
|
+
units: "degrees"
|
|
@@ -693,3 +693,44 @@ raw_drop_number:
|
|
|
693
693
|
- 5000
|
|
694
694
|
- 22 # diameter
|
|
695
695
|
- 20 # velocity
|
|
696
|
+
air_temperature:
|
|
697
|
+
dtype: uint16
|
|
698
|
+
scale_factor: 0.1
|
|
699
|
+
add_offset: -99.9
|
|
700
|
+
zlib: true
|
|
701
|
+
complevel: 3
|
|
702
|
+
shuffle: true
|
|
703
|
+
fletcher32: false
|
|
704
|
+
contiguous: false
|
|
705
|
+
_FillValue: 65535
|
|
706
|
+
chunksizes: 5000
|
|
707
|
+
relative_humidity:
|
|
708
|
+
dtype: uint16
|
|
709
|
+
scale_factor: 0.01
|
|
710
|
+
zlib: true
|
|
711
|
+
complevel: 3
|
|
712
|
+
shuffle: true
|
|
713
|
+
fletcher32: false
|
|
714
|
+
contiguous: false
|
|
715
|
+
_FillValue: 65535
|
|
716
|
+
chunksizes: 5000
|
|
717
|
+
wind_speed:
|
|
718
|
+
dtype: uint16
|
|
719
|
+
scale_factor: 0.1
|
|
720
|
+
add_offset: -99.9
|
|
721
|
+
zlib: true
|
|
722
|
+
complevel: 3
|
|
723
|
+
shuffle: true
|
|
724
|
+
fletcher32: false
|
|
725
|
+
contiguous: false
|
|
726
|
+
_FillValue: 65535
|
|
727
|
+
chunksizes: 5000
|
|
728
|
+
wind_direction:
|
|
729
|
+
dtype: uint16
|
|
730
|
+
zlib: true
|
|
731
|
+
complevel: 3
|
|
732
|
+
shuffle: true
|
|
733
|
+
fletcher32: false
|
|
734
|
+
contiguous: false
|
|
735
|
+
_FillValue: 65535
|
|
736
|
+
chunksizes: 5000
|
|
@@ -828,3 +828,43 @@ raw_drop_number:
|
|
|
828
828
|
- velocity_bin_center
|
|
829
829
|
n_values: 440
|
|
830
830
|
field_number: "81"
|
|
831
|
+
air_temperature:
|
|
832
|
+
n_digits: 4
|
|
833
|
+
n_characters: 5
|
|
834
|
+
n_decimals: 1
|
|
835
|
+
n_naturals: 2
|
|
836
|
+
data_range:
|
|
837
|
+
- -40
|
|
838
|
+
- 70
|
|
839
|
+
nan_flags: 99999
|
|
840
|
+
field_number: "521"
|
|
841
|
+
relative_humidity:
|
|
842
|
+
n_digits: 5
|
|
843
|
+
n_characters: 5
|
|
844
|
+
n_decimals: 0
|
|
845
|
+
n_naturals: 5
|
|
846
|
+
data_range:
|
|
847
|
+
- 0
|
|
848
|
+
- 99999
|
|
849
|
+
nan_flags: 99999
|
|
850
|
+
field_number: "522"
|
|
851
|
+
wind_speed:
|
|
852
|
+
n_digits: 3
|
|
853
|
+
n_characters: 4
|
|
854
|
+
n_decimals: 1
|
|
855
|
+
n_naturals: 2
|
|
856
|
+
data_range:
|
|
857
|
+
- 0
|
|
858
|
+
- 60
|
|
859
|
+
nan_flags: null
|
|
860
|
+
field_number: "523"
|
|
861
|
+
wind_direction:
|
|
862
|
+
n_digits: 3
|
|
863
|
+
n_characters: 3
|
|
864
|
+
n_decimals: 0
|
|
865
|
+
n_naturals: 3
|
|
866
|
+
data_range:
|
|
867
|
+
- 0
|
|
868
|
+
- 360
|
|
869
|
+
nan_flags: 999
|
|
870
|
+
field_number: "524"
|
|
@@ -47,7 +47,7 @@ number_particles:
|
|
|
47
47
|
sensor_temperature:
|
|
48
48
|
description: Temperature in sensor housing
|
|
49
49
|
long_name: Temperature of the sensor
|
|
50
|
-
units: "
|
|
50
|
+
units: "C"
|
|
51
51
|
sensor_serial_number:
|
|
52
52
|
description: Sensor serial number
|
|
53
53
|
long_name: Serial number of the sensor
|
|
@@ -47,7 +47,7 @@ number_particles:
|
|
|
47
47
|
sensor_temperature:
|
|
48
48
|
description: Temperature in sensor housing
|
|
49
49
|
long_name: Temperature of the sensor
|
|
50
|
-
units: "
|
|
50
|
+
units: "C"
|
|
51
51
|
sensor_serial_number:
|
|
52
52
|
description: Sensor serial number
|
|
53
53
|
long_name: Serial number of the sensor
|
|
@@ -105,15 +105,15 @@ error_code:
|
|
|
105
105
|
sensor_temperature_pcb:
|
|
106
106
|
description: Temperature in printed circuit board
|
|
107
107
|
long_name: Sensor PCB temperature
|
|
108
|
-
units: "
|
|
108
|
+
units: "C"
|
|
109
109
|
sensor_temperature_receiver:
|
|
110
110
|
description: Temperature in right sensor head
|
|
111
111
|
long_name: Sensor receiver temperature
|
|
112
|
-
units: "
|
|
112
|
+
units: "C"
|
|
113
113
|
sensor_temperature_trasmitter:
|
|
114
114
|
description: Temperature in left sensor head
|
|
115
115
|
long_name: Sensor trasmitter temperature
|
|
116
|
-
units: "
|
|
116
|
+
units: "C"
|
|
117
117
|
rainfall_rate_16_bit_30:
|
|
118
118
|
description: Rainfall rate
|
|
119
119
|
long_name: Rainfall rate max 30 mm/h 16 bit
|
|
@@ -158,3 +158,19 @@ raw_drop_number:
|
|
|
158
158
|
description: Drop counts per diameter and velocity class
|
|
159
159
|
long_name: Raw drop number
|
|
160
160
|
units: ""
|
|
161
|
+
air_temperature:
|
|
162
|
+
description: "Air temperature in degrees Celsius (C)"
|
|
163
|
+
long_name: Air temperature
|
|
164
|
+
units: "C"
|
|
165
|
+
relative_humidity:
|
|
166
|
+
description: "Relative humidity in percent (%)"
|
|
167
|
+
long_name: Relative humidity
|
|
168
|
+
units: "%"
|
|
169
|
+
wind_speed:
|
|
170
|
+
description: "Wind speed in m/s"
|
|
171
|
+
long_name: Wind speed
|
|
172
|
+
units: "m/s"
|
|
173
|
+
wind_direction:
|
|
174
|
+
description: "Wind direction in degrees (0-360)"
|
|
175
|
+
long_name: Wind direction
|
|
176
|
+
units: "degrees"
|
|
@@ -331,3 +331,44 @@ raw_drop_number:
|
|
|
331
331
|
- 5000
|
|
332
332
|
- 32
|
|
333
333
|
- 32
|
|
334
|
+
air_temperature:
|
|
335
|
+
dtype: uint16
|
|
336
|
+
scale_factor: 0.1
|
|
337
|
+
add_offset: -99.9
|
|
338
|
+
zlib: true
|
|
339
|
+
complevel: 3
|
|
340
|
+
shuffle: true
|
|
341
|
+
fletcher32: false
|
|
342
|
+
contiguous: false
|
|
343
|
+
_FillValue: 65535
|
|
344
|
+
chunksizes: 5000
|
|
345
|
+
relative_humidity:
|
|
346
|
+
dtype: uint16
|
|
347
|
+
scale_factor: 0.01
|
|
348
|
+
zlib: true
|
|
349
|
+
complevel: 3
|
|
350
|
+
shuffle: true
|
|
351
|
+
fletcher32: false
|
|
352
|
+
contiguous: false
|
|
353
|
+
_FillValue: 65535
|
|
354
|
+
chunksizes: 5000
|
|
355
|
+
wind_speed:
|
|
356
|
+
dtype: uint16
|
|
357
|
+
scale_factor: 0.1
|
|
358
|
+
add_offset: -99.9
|
|
359
|
+
zlib: true
|
|
360
|
+
complevel: 3
|
|
361
|
+
shuffle: true
|
|
362
|
+
fletcher32: false
|
|
363
|
+
contiguous: false
|
|
364
|
+
_FillValue: 65535
|
|
365
|
+
chunksizes: 5000
|
|
366
|
+
wind_direction:
|
|
367
|
+
dtype: uint16
|
|
368
|
+
zlib: true
|
|
369
|
+
complevel: 3
|
|
370
|
+
shuffle: true
|
|
371
|
+
fletcher32: false
|
|
372
|
+
contiguous: false
|
|
373
|
+
_FillValue: 65535
|
|
374
|
+
chunksizes: 5000
|
|
@@ -65,10 +65,10 @@ reflectivity_32bit:
|
|
|
65
65
|
nan_flags: null
|
|
66
66
|
field_number: "07"
|
|
67
67
|
mor_visibility:
|
|
68
|
-
n_digits:
|
|
69
|
-
n_characters:
|
|
68
|
+
n_digits: 5
|
|
69
|
+
n_characters: 5
|
|
70
70
|
n_decimals: 0
|
|
71
|
-
n_naturals:
|
|
71
|
+
n_naturals: 5
|
|
72
72
|
data_range:
|
|
73
73
|
- 0
|
|
74
74
|
- 20000
|
|
@@ -270,8 +270,8 @@ sensor_temperature_trasmitter:
|
|
|
270
270
|
rainfall_rate_16_bit_30:
|
|
271
271
|
n_digits: 5
|
|
272
272
|
n_characters: 6
|
|
273
|
-
n_decimals:
|
|
274
|
-
n_naturals:
|
|
273
|
+
n_decimals: 3
|
|
274
|
+
n_naturals: 2
|
|
275
275
|
data_range:
|
|
276
276
|
- 0
|
|
277
277
|
- 30
|
|
@@ -280,8 +280,8 @@ rainfall_rate_16_bit_30:
|
|
|
280
280
|
rainfall_rate_16_bit_1200:
|
|
281
281
|
n_digits: 5
|
|
282
282
|
n_characters: 6
|
|
283
|
-
n_decimals:
|
|
284
|
-
n_naturals:
|
|
283
|
+
n_decimals: 1
|
|
284
|
+
n_naturals: 4
|
|
285
285
|
data_range:
|
|
286
286
|
- 0
|
|
287
287
|
- 1200
|
|
@@ -310,11 +310,11 @@ reflectivity_16bit:
|
|
|
310
310
|
rain_kinetic_energy:
|
|
311
311
|
n_digits: 6
|
|
312
312
|
n_characters: 7
|
|
313
|
-
n_decimals:
|
|
314
|
-
n_naturals:
|
|
313
|
+
n_decimals: 2
|
|
314
|
+
n_naturals: 4
|
|
315
315
|
data_range:
|
|
316
316
|
- 0
|
|
317
|
-
-
|
|
317
|
+
- 9999.99
|
|
318
318
|
nan_flags: null
|
|
319
319
|
field_number: "34"
|
|
320
320
|
snowfall_rate:
|
|
@@ -379,3 +379,43 @@ raw_drop_number:
|
|
|
379
379
|
- diameter_bin_center
|
|
380
380
|
n_values: 1024
|
|
381
381
|
field_number: "93"
|
|
382
|
+
air_temperature:
|
|
383
|
+
n_digits: 4
|
|
384
|
+
n_characters: 5
|
|
385
|
+
n_decimals: 1
|
|
386
|
+
n_naturals: 2
|
|
387
|
+
data_range:
|
|
388
|
+
- -40
|
|
389
|
+
- 70
|
|
390
|
+
nan_flags: 99999
|
|
391
|
+
field_number: "521"
|
|
392
|
+
relative_humidity:
|
|
393
|
+
n_digits: 5
|
|
394
|
+
n_characters: 5
|
|
395
|
+
n_decimals: 0
|
|
396
|
+
n_naturals: 5
|
|
397
|
+
data_range:
|
|
398
|
+
- 0
|
|
399
|
+
- 99999
|
|
400
|
+
nan_flags: 99999
|
|
401
|
+
field_number: "522"
|
|
402
|
+
wind_speed:
|
|
403
|
+
n_digits: 3
|
|
404
|
+
n_characters: 4
|
|
405
|
+
n_decimals: 1
|
|
406
|
+
n_naturals: 2
|
|
407
|
+
data_range:
|
|
408
|
+
- 0
|
|
409
|
+
- 60
|
|
410
|
+
nan_flags: null
|
|
411
|
+
field_number: "523"
|
|
412
|
+
wind_direction:
|
|
413
|
+
n_digits: 3
|
|
414
|
+
n_characters: 3
|
|
415
|
+
n_decimals: 0
|
|
416
|
+
n_naturals: 3
|
|
417
|
+
data_range:
|
|
418
|
+
- 0
|
|
419
|
+
- 360
|
|
420
|
+
nan_flags: 999
|
|
421
|
+
field_number: "524"
|