cloudnetpy 1.86.0__py3-none-any.whl → 1.86.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.
- cloudnetpy/categorize/radar.py +0 -1
- cloudnetpy/instruments/bowtie.py +5 -0
- cloudnetpy/instruments/mira.py +11 -2
- cloudnetpy/instruments/rpg.py +125 -88
- cloudnetpy/output.py +5 -2
- cloudnetpy/utils.py +38 -3
- cloudnetpy/version.py +1 -1
- {cloudnetpy-1.86.0.dist-info → cloudnetpy-1.86.2.dist-info}/METADATA +1 -1
- {cloudnetpy-1.86.0.dist-info → cloudnetpy-1.86.2.dist-info}/RECORD +13 -13
- {cloudnetpy-1.86.0.dist-info → cloudnetpy-1.86.2.dist-info}/WHEEL +0 -0
- {cloudnetpy-1.86.0.dist-info → cloudnetpy-1.86.2.dist-info}/entry_points.txt +0 -0
- {cloudnetpy-1.86.0.dist-info → cloudnetpy-1.86.2.dist-info}/licenses/LICENSE +0 -0
- {cloudnetpy-1.86.0.dist-info → cloudnetpy-1.86.2.dist-info}/top_level.txt +0 -0
cloudnetpy/categorize/radar.py
CHANGED
cloudnetpy/instruments/bowtie.py
CHANGED
cloudnetpy/instruments/mira.py
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
import datetime
|
4
4
|
import logging
|
5
5
|
import os
|
6
|
+
import re
|
6
7
|
from collections import OrderedDict
|
7
8
|
from collections.abc import Sequence
|
8
9
|
from os import PathLike
|
@@ -224,7 +225,7 @@ def _parse_input_files(
|
|
224
225
|
)
|
225
226
|
raise FileNotFoundError(msg)
|
226
227
|
|
227
|
-
filetypes = list({f
|
228
|
+
filetypes = list({_get_suffix(f) for f in valid_files})
|
228
229
|
|
229
230
|
if len(filetypes) > 1:
|
230
231
|
err_msg = "Mixed mmclx and znc files. Please use only one filetype."
|
@@ -241,7 +242,7 @@ def _parse_input_files(
|
|
241
242
|
)
|
242
243
|
else:
|
243
244
|
input_filename = input_files
|
244
|
-
keymap = _get_keymap(
|
245
|
+
keymap = _get_keymap(_get_suffix(input_filename))
|
245
246
|
|
246
247
|
return input_filename, keymap
|
247
248
|
|
@@ -258,6 +259,13 @@ def _get_ignored_variables(filetype: str) -> list | None:
|
|
258
259
|
return keymaps.get(filetype.lower(), keymaps.get("mmclx"))
|
259
260
|
|
260
261
|
|
262
|
+
def _get_suffix(filename: str | PathLike) -> str:
|
263
|
+
m = re.search(r"\.(\w+)(\.\d+)?$", str(filename))
|
264
|
+
if m is None:
|
265
|
+
return ""
|
266
|
+
return m[1].lower()
|
267
|
+
|
268
|
+
|
261
269
|
def _get_keymap(filetype: str) -> dict[str, str]:
|
262
270
|
"""Returns a dictionary mapping the variables in the raw data to the processed
|
263
271
|
Cloudnet file.
|
@@ -284,6 +292,7 @@ def _get_keymap(filetype: str) -> dict[str, str]:
|
|
284
292
|
("nave", "nave"),
|
285
293
|
("prf", "prf"),
|
286
294
|
("rg0", "rg0"),
|
295
|
+
("tpow", "tpow"),
|
287
296
|
],
|
288
297
|
),
|
289
298
|
"mmclx": OrderedDict(
|
cloudnetpy/instruments/rpg.py
CHANGED
@@ -1,9 +1,7 @@
|
|
1
|
-
"""This module contains RPG Cloud Radar related functions."""
|
2
|
-
|
3
1
|
import datetime
|
4
2
|
import logging
|
5
3
|
import math
|
6
|
-
from collections.abc import
|
4
|
+
from collections.abc import Sequence
|
7
5
|
from os import PathLike
|
8
6
|
from uuid import UUID
|
9
7
|
|
@@ -15,7 +13,7 @@ from rpgpy import RPGFileError
|
|
15
13
|
from cloudnetpy import output, utils
|
16
14
|
from cloudnetpy.cloudnetarray import CloudnetArray
|
17
15
|
from cloudnetpy.constants import G_TO_KG, HPA_TO_PA, KM_H_TO_M_S, MM_H_TO_M_S
|
18
|
-
from cloudnetpy.exceptions import
|
16
|
+
from cloudnetpy.exceptions import ValidTimeStampError
|
19
17
|
from cloudnetpy.instruments import instruments
|
20
18
|
from cloudnetpy.instruments.cloudnet_instrument import CloudnetInstrument
|
21
19
|
from cloudnetpy.instruments.instruments import Instrument
|
@@ -68,9 +66,8 @@ def rpg2nc(
|
|
68
66
|
l1_files = utils.get_sorted_filenames(path_to_l1_files, ".LV1")
|
69
67
|
fmcw94_objects, valid_files = _get_fmcw94_objects(l1_files, date)
|
70
68
|
one_day_of_data = create_one_day_data_record(fmcw94_objects)
|
71
|
-
|
72
|
-
|
73
|
-
print_info(one_day_of_data)
|
69
|
+
one_day_of_data["nyquist_velocity"] = _expand_nyquist(one_day_of_data)
|
70
|
+
_print_info(one_day_of_data)
|
74
71
|
fmcw = Fmcw(one_day_of_data, site_meta)
|
75
72
|
fmcw.convert_time_to_fraction_hour()
|
76
73
|
fmcw.mask_invalid_ldr()
|
@@ -93,7 +90,7 @@ def rpg2nc(
|
|
93
90
|
return uuid, valid_files
|
94
91
|
|
95
92
|
|
96
|
-
def
|
93
|
+
def _print_info(data: dict) -> None:
|
97
94
|
dual_pol = data["dual_polarization"]
|
98
95
|
if dual_pol == 0:
|
99
96
|
mode = "single polarisation"
|
@@ -108,57 +105,66 @@ RpgObjects = Sequence[Fmcw94Bin] | Sequence[HatproBinCombined]
|
|
108
105
|
|
109
106
|
|
110
107
|
def create_one_day_data_record(rpg_objects: RpgObjects) -> dict:
|
111
|
-
"""Concatenates all RPG data from one day."""
|
108
|
+
"""Concatenates all RPG FMCW / HATPRO data from one day."""
|
112
109
|
rpg_raw_data, rpg_header = _stack_rpg_data(rpg_objects)
|
113
|
-
if
|
114
|
-
rpg_header =
|
110
|
+
if "range" in rpg_header:
|
111
|
+
rpg_header["range"] = rpg_objects[0].header["range"]
|
112
|
+
should_be_constant = [
|
113
|
+
"model_number",
|
114
|
+
"dual_polarization",
|
115
|
+
"antenna_separation",
|
116
|
+
"antenna_diameter",
|
117
|
+
"antenna_gain",
|
118
|
+
"half_power_beam_width",
|
119
|
+
"radar_frequency",
|
120
|
+
]
|
121
|
+
for key in should_be_constant:
|
122
|
+
if key not in rpg_header:
|
123
|
+
continue
|
124
|
+
unique_values = np.unique(rpg_header[key])
|
125
|
+
if len(unique_values) > 1:
|
126
|
+
msg = f"More than one value for {key} found: {unique_values}"
|
127
|
+
raise ValueError(msg)
|
128
|
+
rpg_header[key] = unique_values[0]
|
129
|
+
|
115
130
|
rpg_raw_data = _mask_invalid_data(rpg_raw_data)
|
116
131
|
return {**rpg_header, **rpg_raw_data}
|
117
132
|
|
118
133
|
|
119
|
-
def
|
120
|
-
"""
|
121
|
-
|
122
|
-
|
123
|
-
|
134
|
+
def _expand_nyquist(data: dict) -> npt.NDArray:
|
135
|
+
"""Expands Nyquist velocity from time X chirp => time X range."""
|
136
|
+
nyquist_velocity = ma.array(data["nyquist_velocity"])
|
137
|
+
chirp_start_indices = ma.array(data["chirp_start_indices"])
|
138
|
+
n_time = chirp_start_indices.shape[0]
|
139
|
+
n_range = len(data["range"])
|
140
|
+
expanded_nyquist = np.empty((n_time, n_range))
|
141
|
+
for t in range(n_time):
|
142
|
+
starts = chirp_start_indices[t].compressed()
|
143
|
+
v_nyq = nyquist_velocity[t].compressed()
|
144
|
+
ends = np.r_[starts[1:], n_range]
|
145
|
+
seg_lengths = ends - starts
|
146
|
+
expanded_nyquist[t, :] = np.repeat(v_nyq, seg_lengths)
|
147
|
+
return expanded_nyquist
|
124
148
|
|
125
|
-
"""
|
126
|
-
|
127
|
-
def _stack(source: dict, target: dict, fun: Callable) -> None:
|
128
|
-
for name, value in source.items():
|
129
|
-
if not name.startswith("_"):
|
130
|
-
target[name] = fun((target[name], value)) if name in target else value
|
131
149
|
|
150
|
+
def _stack_rpg_data(rpg_objects: RpgObjects) -> tuple[dict, dict]:
|
132
151
|
data: dict = {}
|
133
152
|
header: dict = {}
|
134
153
|
for rpg in rpg_objects:
|
135
|
-
|
136
|
-
|
154
|
+
for src, dst in ((rpg.data, data), (rpg.header, header)):
|
155
|
+
for name, value in src.items():
|
156
|
+
if name.startswith("_"):
|
157
|
+
continue
|
158
|
+
arr = dst.get(name)
|
159
|
+
fun = (
|
160
|
+
ma.concatenate
|
161
|
+
if any(isinstance(x, ma.MaskedArray) for x in (value, arr))
|
162
|
+
else np.concatenate
|
163
|
+
)
|
164
|
+
dst[name] = fun((arr, value)) if arr is not None else value
|
137
165
|
return data, header
|
138
166
|
|
139
167
|
|
140
|
-
def _reduce_header(header: dict) -> dict:
|
141
|
-
"""Removes duplicate header data. Otherwise, we would need n_files dimension."""
|
142
|
-
reduced_header = {}
|
143
|
-
for key, data in header.items():
|
144
|
-
# Handle outliers in latitude and longitude (e.g. Galati 2024-02-11):
|
145
|
-
if key in ("latitude", "longitude"):
|
146
|
-
reduced_header[key] = ma.median(data)
|
147
|
-
continue
|
148
|
-
first_profile_value = data[0]
|
149
|
-
is_identical_value = bool(
|
150
|
-
np.isclose(data, first_profile_value, rtol=1e-2).all(),
|
151
|
-
)
|
152
|
-
if is_identical_value is False:
|
153
|
-
msg = f"Inconsistent header: {key}: {data}"
|
154
|
-
if key in ("sample_duration", "calibration_interval", "noise_threshold"):
|
155
|
-
logging.warning(msg)
|
156
|
-
else:
|
157
|
-
raise InconsistentDataError(msg)
|
158
|
-
reduced_header[key] = first_profile_value
|
159
|
-
return reduced_header
|
160
|
-
|
161
|
-
|
162
168
|
def _mask_invalid_data(data_in: dict) -> dict:
|
163
169
|
"""Masks zeros and other fill values from data."""
|
164
170
|
data = data_in.copy()
|
@@ -193,33 +199,68 @@ def _get_fmcw94_objects(
|
|
193
199
|
continue
|
194
200
|
objects.append(obj)
|
195
201
|
valid_files.append(file)
|
196
|
-
if objects:
|
197
|
-
|
198
|
-
|
199
|
-
|
202
|
+
if not objects:
|
203
|
+
msg = "No valid files found"
|
204
|
+
raise ValidTimeStampError(msg)
|
205
|
+
objects = _interpolate_to_common_height(objects)
|
206
|
+
objects = _pad_chirp_related_fields(objects)
|
207
|
+
objects = _expand_time_related_fields(objects)
|
200
208
|
return objects, valid_files
|
201
209
|
|
202
210
|
|
203
|
-
def
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
for
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
211
|
+
def _interpolate_to_common_height(objects: list[Fmcw94Bin]) -> list[Fmcw94Bin]:
|
212
|
+
range_arrays = [obj.header["range"] for obj in objects]
|
213
|
+
if all(np.array_equal(range_arrays[0], r) for r in range_arrays[1:]):
|
214
|
+
return objects
|
215
|
+
# Use range with the highest range gate for interpolation
|
216
|
+
target_height = max(range_arrays, key=lambda r: r[-1])
|
217
|
+
for obj in objects:
|
218
|
+
src_range = obj.header["range"]
|
219
|
+
if np.array_equal(src_range, target_height):
|
220
|
+
continue
|
221
|
+
for key, arr in obj.data.items():
|
222
|
+
if arr.ndim == 2 and arr.shape[1] == src_range.size:
|
223
|
+
obj.data[key] = utils.interpolate_2D_along_y(
|
224
|
+
src_range, arr, target_height
|
225
|
+
)
|
226
|
+
obj.header["range"] = target_height
|
227
|
+
return objects
|
228
|
+
|
229
|
+
|
230
|
+
def _pad_chirp_related_fields(objects: list[Fmcw94Bin]) -> list[Fmcw94Bin]:
|
231
|
+
"""Pads chirp-related header fields with masked values to have the same length."""
|
232
|
+
chirp_lens = [len(obj.header["chirp_start_indices"]) for obj in objects]
|
233
|
+
if all(chirp_lens[0] == length for length in chirp_lens[1:]):
|
234
|
+
return objects
|
235
|
+
max_chirp_len = max(chirp_lens)
|
236
|
+
for obj in objects:
|
237
|
+
n_chirps = len(obj.header["chirp_start_indices"])
|
238
|
+
if n_chirps == max_chirp_len:
|
239
|
+
continue
|
240
|
+
for key, arr in obj.header.items():
|
241
|
+
if not isinstance(arr, str) and arr.ndim == 1 and arr.size == n_chirps:
|
242
|
+
pad_len = max_chirp_len - n_chirps
|
243
|
+
masked_arr = ma.array(arr, dtype=arr.dtype)
|
244
|
+
pad = ma.masked_all(pad_len, dtype=arr.dtype)
|
245
|
+
obj.header[key] = ma.concatenate([masked_arr, pad])
|
246
|
+
return objects
|
247
|
+
|
248
|
+
|
249
|
+
def _expand_time_related_fields(objects: list[Fmcw94Bin]) -> list[Fmcw94Bin]:
|
250
|
+
for obj in objects:
|
251
|
+
n_time = obj.data["time"].size
|
252
|
+
for key in obj.header:
|
253
|
+
if key in ("range", "time") or key.startswith("_"):
|
254
|
+
continue
|
255
|
+
arr = obj.header[key]
|
256
|
+
# Handle outliers in latitude and longitude (e.g. Galati 2024-02-11):
|
257
|
+
if key in ("latitude", "longitude"):
|
258
|
+
arr = ma.median(arr)
|
259
|
+
if utils.isscalar(arr):
|
260
|
+
obj.header[key] = np.repeat(arr, n_time)
|
261
|
+
else:
|
262
|
+
obj.header[key] = np.tile(arr, (n_time, 1))
|
263
|
+
return objects
|
223
264
|
|
224
265
|
|
225
266
|
def _validate_date(obj: Fmcw94Bin, expected_date: datetime.date) -> None:
|
@@ -443,9 +484,11 @@ RPG_ATTRIBUTES = {
|
|
443
484
|
long_name="File code",
|
444
485
|
units="1",
|
445
486
|
comment="Indicates the RPG software version.",
|
446
|
-
dimensions=
|
487
|
+
dimensions=("time",),
|
488
|
+
),
|
489
|
+
"program_number": MetaData(
|
490
|
+
long_name="Program number", units="1", dimensions=("time",)
|
447
491
|
),
|
448
|
-
"program_number": MetaData(long_name="Program number", units="1", dimensions=None),
|
449
492
|
"model_number": MetaData(
|
450
493
|
long_name="Model number",
|
451
494
|
units="1",
|
@@ -469,54 +512,51 @@ RPG_ATTRIBUTES = {
|
|
469
512
|
dimensions=None,
|
470
513
|
),
|
471
514
|
"sample_duration": MetaData(
|
472
|
-
long_name="Sample duration", units="s", dimensions=
|
515
|
+
long_name="Sample duration", units="s", dimensions=("time",)
|
473
516
|
),
|
474
517
|
"calibration_interval": MetaData(
|
475
|
-
long_name="Calibration interval in samples", units="1", dimensions=
|
518
|
+
long_name="Calibration interval in samples", units="1", dimensions=("time",)
|
476
519
|
),
|
477
520
|
"number_of_spectral_samples": MetaData(
|
478
521
|
long_name="Number of spectral samples in each chirp sequence",
|
479
522
|
units="1",
|
480
|
-
dimensions=("chirp_sequence"
|
481
|
-
),
|
482
|
-
"nyquist_velocity": MetaData(
|
483
|
-
long_name="Nyquist velocity", units="m s-1", dimensions=("chirp_sequence",)
|
523
|
+
dimensions=("time", "chirp_sequence"),
|
484
524
|
),
|
485
525
|
"number_of_averaged_chirps": MetaData(
|
486
526
|
long_name="Number of averaged chirps in sequence",
|
487
527
|
units="1",
|
488
|
-
dimensions=("chirp_sequence"
|
528
|
+
dimensions=("time", "chirp_sequence"),
|
489
529
|
),
|
490
530
|
"chirp_start_indices": MetaData(
|
491
531
|
long_name="Chirp sequences start indices",
|
492
532
|
units="1",
|
493
|
-
dimensions=("chirp_sequence"
|
533
|
+
dimensions=("time", "chirp_sequence"),
|
494
534
|
),
|
495
535
|
"integration_time": MetaData(
|
496
536
|
long_name="Integration time",
|
497
537
|
units="s",
|
498
538
|
comment="Effective integration time of chirp sequence",
|
499
|
-
dimensions=("chirp_sequence"
|
539
|
+
dimensions=("time", "chirp_sequence"),
|
500
540
|
),
|
501
541
|
"range_resolution": MetaData(
|
502
542
|
long_name="Vertical resolution of range",
|
503
543
|
units="m",
|
504
|
-
dimensions=("chirp_sequence"
|
544
|
+
dimensions=("time", "chirp_sequence"),
|
505
545
|
),
|
506
546
|
"FFT_window": MetaData(
|
507
547
|
long_name="FFT window type",
|
508
548
|
units="1",
|
509
549
|
definition=DEFINITIONS["FFT_window"],
|
510
|
-
dimensions=
|
550
|
+
dimensions=("time",),
|
511
551
|
),
|
512
552
|
"input_voltage_range": MetaData(
|
513
|
-
long_name="ADC input voltage range (+/-)", units="mV", dimensions=
|
553
|
+
long_name="ADC input voltage range (+/-)", units="mV", dimensions=("time",)
|
514
554
|
),
|
515
555
|
"noise_threshold": MetaData(
|
516
556
|
long_name="Noise filter threshold factor",
|
517
557
|
units="1",
|
518
558
|
comment="Multiple of the standard deviation of Doppler spectra.",
|
519
|
-
dimensions=
|
559
|
+
dimensions=("time",),
|
520
560
|
),
|
521
561
|
"time_ms": MetaData(long_name="Time ms", units="ms", dimensions=("time",)),
|
522
562
|
"quality_flag": MetaData(
|
@@ -545,7 +585,4 @@ RPG_ATTRIBUTES = {
|
|
545
585
|
"pc_temperature": MetaData(
|
546
586
|
long_name="PC temperature", units="K", dimensions=("time",)
|
547
587
|
),
|
548
|
-
"correlation_coefficient": MetaData(
|
549
|
-
long_name="Correlation coefficient", units="1", dimensions=None
|
550
|
-
),
|
551
588
|
}
|
cloudnetpy/output.py
CHANGED
@@ -391,7 +391,6 @@ def _write_vars2nc(nc: netCDF4.Dataset, cloudnet_variables: dict) -> None:
|
|
391
391
|
else:
|
392
392
|
fill_value = False
|
393
393
|
size = obj.dimensions if obj.dimensions is not None else ()
|
394
|
-
|
395
394
|
nc_variable = nc.createVariable(
|
396
395
|
obj.name,
|
397
396
|
obj.data_type,
|
@@ -399,7 +398,11 @@ def _write_vars2nc(nc: netCDF4.Dataset, cloudnet_variables: dict) -> None:
|
|
399
398
|
zlib=True,
|
400
399
|
fill_value=fill_value,
|
401
400
|
)
|
402
|
-
|
401
|
+
try:
|
402
|
+
nc_variable[:] = obj.data
|
403
|
+
except IndexError as err:
|
404
|
+
msg = f"Unable to write variable {obj.name} to file: {err}"
|
405
|
+
raise IndexError(msg) from err
|
403
406
|
for attr in obj.fetch_attributes():
|
404
407
|
setattr(nc_variable, attr, getattr(obj, attr))
|
405
408
|
|
cloudnetpy/utils.py
CHANGED
@@ -387,7 +387,7 @@ def interpolate_2d_mask(
|
|
387
387
|
def interpolate_2d_nearest(
|
388
388
|
x: npt.NDArray,
|
389
389
|
y: npt.NDArray,
|
390
|
-
z:
|
390
|
+
z: ma.MaskedArray,
|
391
391
|
x_new: npt.NDArray,
|
392
392
|
y_new: npt.NDArray,
|
393
393
|
) -> ma.MaskedArray:
|
@@ -419,18 +419,53 @@ def interpolate_2d_nearest(
|
|
419
419
|
return fun((xx, yy)).T
|
420
420
|
|
421
421
|
|
422
|
+
def interpolate_2D_along_y(
|
423
|
+
y: npt.NDArray,
|
424
|
+
z: npt.NDArray | ma.MaskedArray,
|
425
|
+
y_new: npt.NDArray,
|
426
|
+
) -> ma.MaskedArray:
|
427
|
+
"""Fast 1D nearest-neighbor interpolation along y for each x.
|
428
|
+
|
429
|
+
Args:
|
430
|
+
y: 1D numpy array of y-coordinates (length M).
|
431
|
+
z: 2D array of shape (N, M).
|
432
|
+
y_new: 1D numpy array of new y-coordinates.
|
433
|
+
|
434
|
+
Returns:
|
435
|
+
Masked 2D masked array interpolated along y.
|
436
|
+
|
437
|
+
Notes:
|
438
|
+
Only interpolates along y. Points outside range are masked.
|
439
|
+
"""
|
440
|
+
idx = np.searchsorted(y, y_new, side="left")
|
441
|
+
idx = np.clip(idx, 0, len(y) - 1)
|
442
|
+
left = np.maximum(idx - 1, 0)
|
443
|
+
choose_right = (idx == 0) | (
|
444
|
+
(idx < len(y)) & (np.abs(y[idx] - y_new) < np.abs(y_new - y[left]))
|
445
|
+
)
|
446
|
+
idx[~choose_right] = left[~choose_right]
|
447
|
+
z_interp = ma.array(z[:, idx])
|
448
|
+
mask = (y_new < y.min()) | (y_new > y.max())
|
449
|
+
if z_interp.mask is ma.nomask:
|
450
|
+
z_mask = np.zeros(z_interp.shape, dtype=bool)
|
451
|
+
else:
|
452
|
+
z_mask = z_interp.mask.copy()
|
453
|
+
z_mask[:, mask] = True
|
454
|
+
return ma.MaskedArray(z_interp, mask=z_mask)
|
455
|
+
|
456
|
+
|
422
457
|
def interpolate_1d(
|
423
458
|
time: npt.NDArray,
|
424
459
|
y: ma.MaskedArray,
|
425
460
|
time_new: npt.NDArray,
|
426
461
|
max_time: float,
|
427
462
|
method: str = "linear",
|
428
|
-
) ->
|
463
|
+
) -> ma.MaskedArray:
|
429
464
|
"""1D linear interpolation preserving the mask.
|
430
465
|
|
431
466
|
Args:
|
432
467
|
time: 1D array in fraction hour.
|
433
|
-
y: 1D
|
468
|
+
y: 1D array, data values.
|
434
469
|
time_new: 1D array, new time coordinates.
|
435
470
|
max_time: Maximum allowed gap in minutes. Values outside this gap will
|
436
471
|
be masked.
|
cloudnetpy/version.py
CHANGED
@@ -6,10 +6,10 @@ cloudnetpy/constants.py,sha256=YnoSzZm35NDooJfhlulSJBc7g0eSchT3yGytRaTaJEI,845
|
|
6
6
|
cloudnetpy/datasource.py,sha256=EMJ4UHD8Z-JJ9Q82S7RgU1I2q4Z0RcBzBMKUAIwnZBI,6356
|
7
7
|
cloudnetpy/exceptions.py,sha256=ZB3aUwjVRznR0CcZ5sZHrB0yz13URDf52Ksv7G7C7EA,1817
|
8
8
|
cloudnetpy/metadata.py,sha256=qqLXSUVhIi6H_Z1zlfXeEkc9qBqA1XO-UwsCVxjIcfk,7317
|
9
|
-
cloudnetpy/output.py,sha256=
|
9
|
+
cloudnetpy/output.py,sha256=NpuxmtLk2JLTdubCupdL4rFbx30YqgeU6vwAe_v8thc,15133
|
10
10
|
cloudnetpy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
|
-
cloudnetpy/utils.py,sha256=
|
12
|
-
cloudnetpy/version.py,sha256=
|
11
|
+
cloudnetpy/utils.py,sha256=9MMYok1A7oJS2XBkIFhaiDWt_MYLo8tLzF3_880masM,34321
|
12
|
+
cloudnetpy/version.py,sha256=xTNi15DzFrRbaqtjeQYlOEPWmIqgzeFhBlZ_cPtzD-4,72
|
13
13
|
cloudnetpy/categorize/__init__.py,sha256=gtvzWr0IDRn2oA6yHBvinEhTGTuub-JkrOv93lBsgrE,61
|
14
14
|
cloudnetpy/categorize/atmos_utils.py,sha256=uWc9TABVYPI0sn4H5Az9Jf6NVRaWyEKIi17f0pAJQxE,10679
|
15
15
|
cloudnetpy/categorize/attenuation.py,sha256=Y_-fzmQTltWTqIZTulJhovC7a6ifpMcaAazDJcnMIOc,990
|
@@ -26,7 +26,7 @@ cloudnetpy/categorize/lidar.py,sha256=CkIbsMFHROYnhIc1e1ci61-POqeL8AOf6RCZicpNBV
|
|
26
26
|
cloudnetpy/categorize/melting.py,sha256=vhc6zq3L4gp7oEPHMnQlT2m6YBE5-CS5gdTNA7gVHRg,6329
|
27
27
|
cloudnetpy/categorize/model.py,sha256=iFakrXy3npbg4qUrpUGEBEdwBnmlWsMgogPCtfWl7sw,6805
|
28
28
|
cloudnetpy/categorize/mwr.py,sha256=QKc6f_h0mCVjzSa4BrwTtVAPx0Tn1VJ4jqGmIBke5II,1710
|
29
|
-
cloudnetpy/categorize/radar.py,sha256=
|
29
|
+
cloudnetpy/categorize/radar.py,sha256=CHcCWm2Nl-ycBqmbNz8LPSTmuNzgmmNxaJO2uQ-o09c,16005
|
30
30
|
cloudnetpy/categorize/attenuations/__init__.py,sha256=kIyQEZ6VVO6jJOAndrt7jNU15pm0Cavh5GnDjFmIG1M,1040
|
31
31
|
cloudnetpy/categorize/attenuations/gas_attenuation.py,sha256=emr-RCxQT0i2N8k6eBNhRsmsCBPHJzQsWJfjC4fVSTo,975
|
32
32
|
cloudnetpy/categorize/attenuations/liquid_attenuation.py,sha256=bmqmPk_93J4njE16-VQ1bPI7oNSS8m9ACuUH7IErBs8,3069
|
@@ -34,7 +34,7 @@ cloudnetpy/categorize/attenuations/melting_attenuation.py,sha256=zmpF7Gek4W9cF-5
|
|
34
34
|
cloudnetpy/categorize/attenuations/rain_attenuation.py,sha256=wJPyCiKWzsQDzMhqbA7mYwj9YRVcJIpXWhBnEYFy3uU,2843
|
35
35
|
cloudnetpy/instruments/__init__.py,sha256=PEgrrQNoiOuN_ctYilmt4LV2QCLg1likPjJdWtuGlLs,528
|
36
36
|
cloudnetpy/instruments/basta.py,sha256=N-kRgl5Vm52pXzr9umo4YsA0hn4zZCOa-0_zZTzhheY,4284
|
37
|
-
cloudnetpy/instruments/bowtie.py,sha256=
|
37
|
+
cloudnetpy/instruments/bowtie.py,sha256=1wavsYkVMC81CflUD-nTjeyjmATGKYfEJ6aNcwOOapM,4450
|
38
38
|
cloudnetpy/instruments/ceilo.py,sha256=scb3n0gLOZ1gPs_WdWw9KS5Ut_mtCvSdWFMKKCvXhBI,8979
|
39
39
|
cloudnetpy/instruments/ceilometer.py,sha256=c37uteeuGnlE-o-Smu49H2qQJw6qZ0tc3Bzhyr1FoSo,13063
|
40
40
|
cloudnetpy/instruments/cl61d.py,sha256=JsCHqVzFGhZi-5xcnsB507FDpyuw83uSWK3IFO3DhdI,2238
|
@@ -46,14 +46,14 @@ cloudnetpy/instruments/galileo.py,sha256=f_-GkRxhNaQPbI8HpOwSmoKfGqyjmD16A0ZFgwL
|
|
46
46
|
cloudnetpy/instruments/hatpro.py,sha256=TGOqwW0TfoPEYk13MFvFzwgJGzm6MVE5AsPavcIoj3I,10248
|
47
47
|
cloudnetpy/instruments/instruments.py,sha256=WZgH7HjzM9Ane1CSnYCSLidbST8hunUeSt2lPntq9As,4999
|
48
48
|
cloudnetpy/instruments/lufft.py,sha256=G6KeJOeltLUlGCHHEk8ns2K7WJ9ImAr25rSB2JltawE,4286
|
49
|
-
cloudnetpy/instruments/mira.py,sha256=
|
49
|
+
cloudnetpy/instruments/mira.py,sha256=fLDpEdsoq-TArT49s6-YmrntnqsF5bxi01WWdc1tLP4,12831
|
50
50
|
cloudnetpy/instruments/mrr.py,sha256=KvhfNIY2ozHE1MRLNYPqtBFThxLGN_YuCpBUGDIR76s,6319
|
51
51
|
cloudnetpy/instruments/nc_lidar.py,sha256=PtZauDdI3bX3bv4gIVvV6N53e2Co-ehBL_tByHM9hj8,1713
|
52
52
|
cloudnetpy/instruments/nc_radar.py,sha256=XFKxPLKivnhHTgjE5HFrxjWZ0oCifhDUAog051vkMiY,7533
|
53
53
|
cloudnetpy/instruments/pollyxt.py,sha256=IFq_RJrhgJ79OVyuo48PwYQK_zZ6VZFB_S5bEirRyzs,10566
|
54
54
|
cloudnetpy/instruments/radiometrics.py,sha256=QKfnrZlQ0sFcFjmv1ShnCMTJQv64w4akjK-JAIY4gCg,16116
|
55
55
|
cloudnetpy/instruments/rain_e_h3.py,sha256=fjv3SgeUNx9GisYqLrBnX9AjnO17VtouyoPh12VE9uo,5465
|
56
|
-
cloudnetpy/instruments/rpg.py,sha256=
|
56
|
+
cloudnetpy/instruments/rpg.py,sha256=LmvViLSevzjR2HmkP6MCHHDzafpTWoCvw7GaaEC37s0,21029
|
57
57
|
cloudnetpy/instruments/rpg_reader.py,sha256=EcsUUyKNiZ-kEEz48zibs-uXH7CMNpedqlrfWOY4Dks,11899
|
58
58
|
cloudnetpy/instruments/toa5.py,sha256=CfmmBMv5iMGaWHIGBK01Rw24cuXC1R1RMNTXkmsm340,1760
|
59
59
|
cloudnetpy/instruments/vaisala.py,sha256=tu7aljkMKep0uCWz-Sd-GuBXF_Yy421a4nHy0ffpMoc,4725
|
@@ -118,10 +118,10 @@ cloudnetpy/products/lwc.py,sha256=xsNiiG6dGKIkWaFk0xWTabc1bZ4ULf6SqcqHs7itAUk,19
|
|
118
118
|
cloudnetpy/products/mie_lu_tables.nc,sha256=It4fYpqJXlqOgL8jeZ-PxGzP08PMrELIDVe55y9ob58,16637951
|
119
119
|
cloudnetpy/products/mwr_tools.py,sha256=MMWnp68U7bv157-CPB2VeTQvaR6zl7sexbBT_kJ_pn8,6734
|
120
120
|
cloudnetpy/products/product_tools.py,sha256=eyqIw_0KhlpmmYQE69RpGdRIAOW7JVPlEgkTBp2kdps,11302
|
121
|
-
cloudnetpy-1.86.
|
121
|
+
cloudnetpy-1.86.2.dist-info/licenses/LICENSE,sha256=wcZF72bdaoG9XugpyE95Juo7lBQOwLuTKBOhhtANZMM,1094
|
122
122
|
docs/source/conf.py,sha256=IKiFWw6xhUd8NrCg0q7l596Ck1d61XWeVjIFHVSG9Og,1490
|
123
|
-
cloudnetpy-1.86.
|
124
|
-
cloudnetpy-1.86.
|
125
|
-
cloudnetpy-1.86.
|
126
|
-
cloudnetpy-1.86.
|
127
|
-
cloudnetpy-1.86.
|
123
|
+
cloudnetpy-1.86.2.dist-info/METADATA,sha256=kf1RXoG3IYdfagnVpUBSggxThGxNc8SutPD3XeuzFv8,5836
|
124
|
+
cloudnetpy-1.86.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
125
|
+
cloudnetpy-1.86.2.dist-info/entry_points.txt,sha256=HhY7LwCFk4qFgDlXx_Fy983ZTd831WlhtdPIzV-Y3dY,51
|
126
|
+
cloudnetpy-1.86.2.dist-info/top_level.txt,sha256=ibSPWRr6ojS1i11rtBFz2_gkIe68mggj7aeswYfaOo0,16
|
127
|
+
cloudnetpy-1.86.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|