cloudnetpy 1.95.4__tar.gz → 1.95.6__tar.gz
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-1.95.4/cloudnetpy.egg-info → cloudnetpy-1.95.6}/PKG-INFO +1 -1
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/arm.py +10 -3
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/categorize.py +11 -1
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/classify.py +3 -1
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/containers.py +2 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/radar.py +10 -1
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/cli.py +18 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/arm_ceilo.py +2 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/kazr.py +57 -12
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/output.py +1 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/plotting/plotting.py +9 -1
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/version.py +1 -1
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6/cloudnetpy.egg-info}/PKG-INFO +1 -1
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/LICENSE +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/MANIFEST.in +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/README.md +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/__init__.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/__init__.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/atmos_utils.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/attenuation.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/attenuations/__init__.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/attenuations/gas_attenuation.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/attenuations/liquid_attenuation.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/attenuations/melting_attenuation.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/attenuations/rain_attenuation.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/disdrometer.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/droplet.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/falling.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/freezing.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/insects.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/lidar.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/melting.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/model.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/mwr.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/cloudnetarray.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/concat_lib.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/constants.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/datasource.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/disdronator/__init__.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/disdronator/lpm.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/disdronator/parsivel.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/disdronator/process.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/disdronator/rd80.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/disdronator/utils.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/exceptions.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/__init__.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/arm_ld.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/arm_utils.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/basta.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/bowtie.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/ceilo.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/ceilometer.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/cl61d.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/cloudnet_instrument.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/copernicus.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/da10.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/dealias.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/disdrometer.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/fd12p.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/galileo.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/hatpro.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/instruments.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/lufft.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/mira.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/mmcr.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/mrr.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/mwr3c.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/mwrlos.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/nc_lidar.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/nc_radar.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/pollyxt.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/radiometrics.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/rain_e_h3.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/rpg.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/rpg_reader.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/toa5.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/vaisala.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/weather_radar.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/instruments/weather_station.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/metadata.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/__init__.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/file_handler.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/metadata.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/model_metadata.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/plotting/__init__.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/plotting/plot_meta.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/plotting/plot_tools.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/plotting/plotting.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/products/__init__.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/products/advance_methods.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/products/grid_methods.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/products/model_products.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/products/observation_products.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/products/product_resampling.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/products/tools.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/statistics/__init__.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/statistics/statistical_methods.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/__init__.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/e2e/__init__.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/e2e/conftest.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/e2e/process_cf/__init__.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/__init__.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/__init__.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/unit/__init__.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/unit/conftest.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/unit/test_model_products.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/unit/test_observation_products.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/unit/test_plotting.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/unit/test_tools.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/utils.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/plotting/__init__.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/plotting/plot_meta.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/products/__init__.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/products/classification.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/products/der.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/products/drizzle.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/products/drizzle_error.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/products/drizzle_tools.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/products/epsilon_lidar.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/products/epsilon_radar.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/products/ier.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/products/iwc.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/products/iwc_weather_radar.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/products/lwc.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/products/mie_lu_tables.nc +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/products/mwr_tools.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/products/product_tools.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/py.typed +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/utils.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy.egg-info/SOURCES.txt +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy.egg-info/dependency_links.txt +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy.egg-info/entry_points.txt +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy.egg-info/requires.txt +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy.egg-info/top_level.txt +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/docs/source/conf.py +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/pyproject.toml +0 -0
- {cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/setup.cfg +0 -0
|
@@ -61,15 +61,22 @@ class ArmInstrument(NamedTuple):
|
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
# In order of preference within each product; the first with files is used.
|
|
64
|
+
# Raw moments are preferred over ARM corrected products for consistency. The
|
|
65
|
+
# b1-level KAZR moments are identical to the a1-level ones except for the
|
|
66
|
+
# reflectivity calibration applied by ARM.
|
|
64
67
|
ARM_INSTRUMENTS: Final = (
|
|
68
|
+
# KAZR2 calibrated moments (2020 onwards, hourly files, months of delay)
|
|
69
|
+
ArmInstrument("radar", "kazr", "kazrcfrgeqc.b1", kazr2nc, multi_file=True),
|
|
70
|
+
# KAZR2 calibrated moments at ENA
|
|
71
|
+
ArmInstrument("radar", "kazr", "kazr2cfrgeqc.b1", kazr2nc, multi_file=True),
|
|
65
72
|
# KAZR2 (approx. 2019 onwards, hourly files)
|
|
66
73
|
ArmInstrument("radar", "kazr", "kazrcfrge.a1", kazr2nc, multi_file=True),
|
|
67
74
|
# KAZR2 at ENA (Dec 2019 onwards, hourly files)
|
|
68
75
|
ArmInstrument("radar", "kazr", "kazr2cfrge.a1", kazr2nc, multi_file=True),
|
|
69
|
-
# KAZR
|
|
70
|
-
ArmInstrument("radar", "kazr", "kazrcorge.c1", kazr2nc, multi_file=True),
|
|
71
|
-
# KAZR moments (approx. 2011-2019, e.g. mobile facilities)
|
|
76
|
+
# KAZR moments (approx. 2011-2019, daily files)
|
|
72
77
|
ArmInstrument("radar", "kazr", "kazrge.a1", kazr2nc, multi_file=True),
|
|
78
|
+
# KAZR corrected moments (approx. 2011-2012), fallback if raw missing
|
|
79
|
+
ArmInstrument("radar", "kazr", "kazrcorge.c1", kazr2nc, multi_file=True),
|
|
73
80
|
# MMCR (before 2011)
|
|
74
81
|
ArmInstrument("radar", "mmcr", "mmcrmom.b1", mmcr2nc, multi_file=False),
|
|
75
82
|
ArmInstrument("lidar", "cl31", "ceil.b1", armceilo2nc, multi_file=False),
|
|
@@ -212,6 +212,10 @@ def generate_categorize(
|
|
|
212
212
|
attributes = output.add_time_attribute(CATEGORIZE_ATTRIBUTES, date)
|
|
213
213
|
attributes = output.add_time_attribute(attributes, date, "model_time")
|
|
214
214
|
attributes = output.add_source_attribute(attributes, data)
|
|
215
|
+
if "Z_offset" in cloudnet_arrays:
|
|
216
|
+
attributes["Z"] = attributes["Z"]._replace(
|
|
217
|
+
ancillary_variables=f"{attributes['Z'].ancillary_variables} Z_offset"
|
|
218
|
+
)
|
|
215
219
|
output.update_attributes(cloudnet_arrays, attributes)
|
|
216
220
|
_save_cat(output_file, data, cloudnet_arrays, uuid)
|
|
217
221
|
return uuid
|
|
@@ -336,7 +340,7 @@ COMMENTS = {
|
|
|
336
340
|
"and possibly liquid water, rain and melting layer (see quality_bits\n"
|
|
337
341
|
"variable). Calibration convention: in the absence of attenuation, a cloud\n"
|
|
338
342
|
"at 273 K containing one million 100-micron droplets per cubic metre will\n"
|
|
339
|
-
"have
|
|
343
|
+
"have a reflectivity of 0 dBZ at all frequencies."
|
|
340
344
|
),
|
|
341
345
|
"bias": (
|
|
342
346
|
"This variable is an estimate of the one-standard-deviation\ncalibration error."
|
|
@@ -439,6 +443,12 @@ CATEGORIZE_ATTRIBUTES = {
|
|
|
439
443
|
"nyquist_velocity": COMMON_ATTRIBUTES["nyquist_velocity"]._replace(
|
|
440
444
|
dimensions=("time", "height")
|
|
441
445
|
),
|
|
446
|
+
"Z_offset": MetaData(
|
|
447
|
+
long_name="Radar reflectivity calibration offset",
|
|
448
|
+
units="dBZ",
|
|
449
|
+
comment="Calibration offset applied to the reflectivity in the radar file.",
|
|
450
|
+
dimensions=None,
|
|
451
|
+
),
|
|
442
452
|
# Lidar variables
|
|
443
453
|
"beta": MetaData(
|
|
444
454
|
long_name="Attenuated backscatter coefficient",
|
|
@@ -62,7 +62,9 @@ def classify_measurements(data: Observations) -> ClassificationResult:
|
|
|
62
62
|
|
|
63
63
|
bits.melting = melting.find_melting_layer(obs)
|
|
64
64
|
bits.freezing = freezing.find_freezing_region(obs, bits.melting)
|
|
65
|
-
|
|
65
|
+
# Vaisala CL51/CL61 have reliable near-range data, so allow lower liquid peaks
|
|
66
|
+
is_cl = any(model in obs.lidar_type.lower() for model in ("cl51", "cl61"))
|
|
67
|
+
liquid_from_lidar = droplet.find_liquid(obs, min_alt=70 if is_cl else 100)
|
|
66
68
|
if obs.lv0_files is not None and len(obs.lv0_files) > 0:
|
|
67
69
|
if "rpg-fmcw-94" not in obs.radar_type.lower():
|
|
68
70
|
msg = "VoodooNet is only implemented for RPG-FMCW-94 radar."
|
|
@@ -56,6 +56,7 @@ class ClassData:
|
|
|
56
56
|
height (ndarray): 1D height vector (m).
|
|
57
57
|
model_type (str): Model identifier.
|
|
58
58
|
radar_type (str): Radar identifier.
|
|
59
|
+
lidar_type (str): Lidar identifier.
|
|
59
60
|
is_rain (ndarray): 2D boolean array denoting rain.
|
|
60
61
|
is_clutter (ndarray): 2D boolean array denoting clutter.
|
|
61
62
|
altitude: site altitude.
|
|
@@ -76,6 +77,7 @@ class ClassData:
|
|
|
76
77
|
self.tw = data.model.data["Tw"][:]
|
|
77
78
|
self.model_type = data.model.source_type
|
|
78
79
|
self.beta = data.lidar.data["beta"][:]
|
|
80
|
+
self.lidar_type = data.lidar.source
|
|
79
81
|
self.lwp = (
|
|
80
82
|
data.mwr.data["lwp"][:]
|
|
81
83
|
if data.mwr is not None
|
|
@@ -341,10 +341,19 @@ class Radar(DataSource):
|
|
|
341
341
|
def _init_data(self) -> None:
|
|
342
342
|
self.append_data(self.getvar("Zh"), "Z", units="dBZ")
|
|
343
343
|
self.append_data(self.getvar("v"), "v_sigma")
|
|
344
|
-
for key in (
|
|
344
|
+
for key in (
|
|
345
|
+
"v",
|
|
346
|
+
"ldr",
|
|
347
|
+
"width",
|
|
348
|
+
"sldr",
|
|
349
|
+
"rainfall_rate",
|
|
350
|
+
"nyquist_velocity",
|
|
351
|
+
):
|
|
345
352
|
if key in self.dataset.variables:
|
|
346
353
|
data = self.dataset.variables[key]
|
|
347
354
|
self.append_data(data, key)
|
|
355
|
+
if "Zh_offset" in self.dataset.variables:
|
|
356
|
+
self.append_data(self.dataset.variables["Zh_offset"], "Z_offset")
|
|
348
357
|
|
|
349
358
|
def _rebin_velocity(
|
|
350
359
|
self,
|
|
@@ -437,6 +437,8 @@ def _process_instrument_product(
|
|
|
437
437
|
input_files = input_folder
|
|
438
438
|
case ("mrr", _id):
|
|
439
439
|
fun = instruments.mrr2nc
|
|
440
|
+
case ("weather-radar", _id):
|
|
441
|
+
fun = instruments.wr2nc
|
|
440
442
|
case ("weather-station", _id):
|
|
441
443
|
fun = instruments.ws2nc
|
|
442
444
|
case (invalid_product_id, invalid_instrument_id):
|
|
@@ -770,6 +772,10 @@ def _plot(
|
|
|
770
772
|
options = PlotParameters()
|
|
771
773
|
if args.max_y is not None:
|
|
772
774
|
options.max_y = args.max_y
|
|
775
|
+
if args.start_time is not None:
|
|
776
|
+
options.start_time = args.start_time
|
|
777
|
+
if args.stop_time is not None:
|
|
778
|
+
options.stop_time = args.stop_time
|
|
773
779
|
try:
|
|
774
780
|
generate_figure(
|
|
775
781
|
filepath,
|
|
@@ -949,6 +955,18 @@ def main() -> None:
|
|
|
949
955
|
help="Maximum y-axis value (km) in 2D time/height plots (default: 12)",
|
|
950
956
|
default=None,
|
|
951
957
|
)
|
|
958
|
+
parser.add_argument(
|
|
959
|
+
"--start-time",
|
|
960
|
+
type=float,
|
|
961
|
+
help="Start time in fractional hours since midnight UTC (default: 0)",
|
|
962
|
+
default=None,
|
|
963
|
+
)
|
|
964
|
+
parser.add_argument(
|
|
965
|
+
"--stop-time",
|
|
966
|
+
type=float,
|
|
967
|
+
help="Stop time in fractional hours since midnight UTC (default: 24)",
|
|
968
|
+
default=None,
|
|
969
|
+
)
|
|
952
970
|
parser.add_argument(
|
|
953
971
|
"-o",
|
|
954
972
|
"--options",
|
|
@@ -112,6 +112,8 @@ class ArmCeilo(Ceilometer):
|
|
|
112
112
|
self.data["time"] = np.array(nc["time"][:])
|
|
113
113
|
calibration_factor = float(self.site_meta.get("calibration_factor", 1))
|
|
114
114
|
backscatter = ma.masked_invalid(nc["backscatter"][:])
|
|
115
|
+
# Missing profiles are filled with int32 min without _FillValue
|
|
116
|
+
backscatter = ma.masked_less(backscatter, -1e6)
|
|
115
117
|
self.data["beta_raw"] = backscatter * BACKSCATTER_SCALE * calibration_factor
|
|
116
118
|
self.data["calibration_factor"] = calibration_factor
|
|
117
119
|
self.data["zenith_angle"] = float(ma.median(nc["tilt_angle"][:]))
|
|
@@ -12,6 +12,7 @@ from uuid import UUID
|
|
|
12
12
|
|
|
13
13
|
import netCDF4
|
|
14
14
|
import numpy as np
|
|
15
|
+
import numpy.typing as npt
|
|
15
16
|
from numpy import ma
|
|
16
17
|
|
|
17
18
|
from cloudnetpy import output, utils
|
|
@@ -27,7 +28,7 @@ from cloudnetpy.instruments.dealias import (
|
|
|
27
28
|
)
|
|
28
29
|
from cloudnetpy.instruments.instruments import KAZR
|
|
29
30
|
from cloudnetpy.instruments.nc_radar import estimate_snr_limit
|
|
30
|
-
from cloudnetpy.metadata import COMMON_ATTRIBUTES
|
|
31
|
+
from cloudnetpy.metadata import COMMON_ATTRIBUTES, MetaData
|
|
31
32
|
|
|
32
33
|
# KAZR2 CF/Radial format (e.g. sgpkazrcfrgeC1.a1, hourly files)
|
|
33
34
|
KEYMAP_CFR = {
|
|
@@ -67,15 +68,18 @@ def kazr2nc(
|
|
|
67
68
|
) -> UUID:
|
|
68
69
|
"""Converts ARM KAZR cloud radar data into Cloudnet Level 1b netCDF file.
|
|
69
70
|
|
|
70
|
-
Supports the KAZR2 CF/Radial moments (`kazrcfrge.a1
|
|
71
|
-
ARM corrected moments (`kazrcorge.c1`,
|
|
72
|
-
moments (`kazrge.a1`, daily files).
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
71
|
+
Supports the KAZR2 CF/Radial moments (`kazrcfrge.a1` and the calibrated
|
|
72
|
+
`kazrcfrgeqc.b1`, hourly files), the ARM corrected moments (`kazrcorge.c1`,
|
|
73
|
+
daily files) and the original KAZR moments (`kazrge.a1`, daily files). The
|
|
74
|
+
reflectivity calibration offset applied by ARM in the calibrated files is
|
|
75
|
+
kept and recorded in `Zh_offset`. Uncalibrated files are calibrated with
|
|
76
|
+
`Zh_offset` from `site_meta` if given. With the corrected moments, noise is
|
|
77
|
+
screened using the ARM significant detection mask and
|
|
78
|
+
LDR is calculated from the cross- and co-polar reflectivities. LDR is
|
|
79
|
+
screened using the cross-polar SNR and removed completely if the
|
|
80
|
+
cross-polar channel is found unreliable. Stationary clutter layers (zero
|
|
81
|
+
velocity and spectral width) are removed. Velocities of the non-corrected
|
|
82
|
+
formats are dealiased using velocity continuity.
|
|
79
83
|
|
|
80
84
|
Args:
|
|
81
85
|
raw_files: Input file, a sequence of files, or a folder containing the
|
|
@@ -83,9 +87,11 @@ def kazr2nc(
|
|
|
83
87
|
output_file: Output filename.
|
|
84
88
|
site_meta: Dictionary containing information about the site. Required key
|
|
85
89
|
value pair is `name`. Optional are `latitude`, `longitude` and
|
|
86
|
-
`altitude` (taken from the raw file if missing)
|
|
90
|
+
`altitude` (taken from the raw file if missing), `snr_limit`
|
|
87
91
|
(fixed SNR threshold in dB; by default the threshold is estimated
|
|
88
|
-
from the noise in the top range gates)
|
|
92
|
+
from the noise in the top range gates) and `Zh_offset` (reflectivity
|
|
93
|
+
calibration offset in dB, used only if the file is not calibrated
|
|
94
|
+
by ARM).
|
|
89
95
|
uuid: Set specific UUID for the file.
|
|
90
96
|
date: Expected date as YYYY-MM-DD of all profiles in the file.
|
|
91
97
|
|
|
@@ -107,6 +113,7 @@ def kazr2nc(
|
|
|
107
113
|
snr_limit = site_meta.get("snr_limit")
|
|
108
114
|
kazr = Kazr(_get_files(raw_files), site_meta, date)
|
|
109
115
|
kazr.read_files()
|
|
116
|
+
kazr.calibrate_reflectivity()
|
|
110
117
|
kazr.sort_timestamps()
|
|
111
118
|
kazr.remove_duplicate_timestamps()
|
|
112
119
|
kazr.calc_ldr()
|
|
@@ -152,6 +159,7 @@ class Kazr(CloudnetInstrument):
|
|
|
152
159
|
self.dealiased = False
|
|
153
160
|
self.ldr_floor: float | None = None
|
|
154
161
|
self.corrected = False # ARM corrected (dealiased) moments
|
|
162
|
+
self.offset_applied: float | None = None # Calibration offset by ARM
|
|
155
163
|
self._raw: dict[str, list] = {}
|
|
156
164
|
|
|
157
165
|
def read_files(self) -> None:
|
|
@@ -171,6 +179,20 @@ class Kazr(CloudnetInstrument):
|
|
|
171
179
|
self.data[key] = CloudnetArray(ma.concatenate(arrays), key)
|
|
172
180
|
self._screen_date()
|
|
173
181
|
|
|
182
|
+
def calibrate_reflectivity(self) -> None:
|
|
183
|
+
"""Applies `Zh_offset` from site_meta unless already calibrated by ARM."""
|
|
184
|
+
zh_offset = self.site_meta.get("Zh_offset")
|
|
185
|
+
if self.offset_applied is not None:
|
|
186
|
+
if zh_offset is not None:
|
|
187
|
+
logging.info("File calibrated by ARM, ignoring Zh_offset")
|
|
188
|
+
zh_offset = self.offset_applied
|
|
189
|
+
elif zh_offset is None:
|
|
190
|
+
zh_offset = 0.0
|
|
191
|
+
else:
|
|
192
|
+
zh_offset = float(zh_offset)
|
|
193
|
+
self.data["Zh"].data[:] += zh_offset
|
|
194
|
+
self.append_data(np.array(zh_offset, dtype=np.float32), "Zh_offset")
|
|
195
|
+
|
|
174
196
|
def screen_noise(self, snr_limit: float | None = None) -> None:
|
|
175
197
|
"""Masks noise using ARM detection mask if available, otherwise SNR.
|
|
176
198
|
|
|
@@ -339,6 +361,10 @@ class Kazr(CloudnetInstrument):
|
|
|
339
361
|
else:
|
|
340
362
|
msg = "Unknown KAZR file format"
|
|
341
363
|
raise RadarDataError(msg)
|
|
364
|
+
zh_key = next(k for k, v in self.keymap.items() if v == "Zh")
|
|
365
|
+
bias = getattr(nc[zh_key], "applied_bias_correction", None)
|
|
366
|
+
if bias is not None:
|
|
367
|
+
self.offset_applied = _parse_bias(bias)
|
|
342
368
|
self.serial_number = getattr(nc, "serial_number", None) or None
|
|
343
369
|
self.append_data(np.array(nc["range"][:], dtype=float), "range")
|
|
344
370
|
self.append_data(0.0, "zenith_angle")
|
|
@@ -508,6 +534,25 @@ def _get_files(raw_files: str | PathLike | Sequence[str | PathLike]) -> list[Pat
|
|
|
508
534
|
|
|
509
535
|
ATTRIBUTES = {
|
|
510
536
|
"correction_bits": CORRECTION_BITS_ATTRIBUTES,
|
|
537
|
+
"Zh_offset": MetaData(
|
|
538
|
+
long_name="Radar reflectivity calibration offset",
|
|
539
|
+
units="dBZ",
|
|
540
|
+
comment=(
|
|
541
|
+
"Calibration offset applied to the reflectivity, either by ARM "
|
|
542
|
+
"in the calibrated (b1) files or by Cloudnet in the other files."
|
|
543
|
+
),
|
|
544
|
+
dimensions=None,
|
|
545
|
+
),
|
|
511
546
|
"zenith_angle": COMMON_ATTRIBUTES["zenith_angle"]._replace(dimensions=None),
|
|
512
547
|
"nyquist_velocity": COMMON_ATTRIBUTES["nyquist_velocity"]._replace(dimensions=None),
|
|
513
548
|
}
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
def _parse_bias(bias: npt.ArrayLike) -> float | None:
|
|
552
|
+
"""Parses ARM reflectivity bias attribute, which may be an empty array."""
|
|
553
|
+
values = np.atleast_1d(np.asarray(bias, dtype=float))
|
|
554
|
+
if len(values) == 0:
|
|
555
|
+
return None
|
|
556
|
+
if len(np.unique(values)) > 1:
|
|
557
|
+
logging.warning("Multiple bias corrections %s, using the first one", values)
|
|
558
|
+
return round(float(values[0]), 2)
|
|
@@ -54,6 +54,8 @@ class PlotParameters:
|
|
|
54
54
|
plotted variable.
|
|
55
55
|
minor_ticks: Whether to display minor ticks on the x-axis.
|
|
56
56
|
plot_above_ground: Whether to plot above ground instead of above mean sea level.
|
|
57
|
+
start_time: Start time in fractional hours for time-axis limits.
|
|
58
|
+
stop_time: Stop time in fractional hours for time-axis limits.
|
|
57
59
|
|
|
58
60
|
"""
|
|
59
61
|
|
|
@@ -70,6 +72,8 @@ class PlotParameters:
|
|
|
70
72
|
raise_on_empty: bool = False
|
|
71
73
|
minor_ticks: bool = True
|
|
72
74
|
plot_above_ground: bool = True
|
|
75
|
+
start_time: float | None = None
|
|
76
|
+
stop_time: float | None = None
|
|
73
77
|
|
|
74
78
|
|
|
75
79
|
class Dimensions:
|
|
@@ -337,7 +341,11 @@ class SubPlot:
|
|
|
337
341
|
if self.options.minor_ticks:
|
|
338
342
|
self.ax.xaxis.set_minor_locator(AutoMinorLocator(4))
|
|
339
343
|
self.ax.tick_params(which="minor", length=2.5)
|
|
340
|
-
|
|
344
|
+
start_time = (
|
|
345
|
+
self.options.start_time if self.options.start_time is not None else 0
|
|
346
|
+
)
|
|
347
|
+
stop_time = self.options.stop_time if self.options.stop_time is not None else 24
|
|
348
|
+
self.ax.set_xlim(start_time, stop_time)
|
|
341
349
|
|
|
342
350
|
def set_yax(
|
|
343
351
|
self,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/attenuations/gas_attenuation.py
RENAMED
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/attenuations/liquid_attenuation.py
RENAMED
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/attenuations/melting_attenuation.py
RENAMED
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/categorize/attenuations/rain_attenuation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/products/advance_methods.py
RENAMED
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/products/grid_methods.py
RENAMED
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/products/model_products.py
RENAMED
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/products/observation_products.py
RENAMED
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/products/product_resampling.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/e2e/process_cf/__init__.py
RENAMED
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py
RENAMED
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py
RENAMED
|
File without changes
|
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py
RENAMED
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py
RENAMED
|
File without changes
|
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py
RENAMED
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py
RENAMED
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/unit/test_plotting.py
RENAMED
|
File without changes
|
|
File without changes
|
{cloudnetpy-1.95.4 → cloudnetpy-1.95.6}/cloudnetpy/model_evaluation/tests/unit/test_tools.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|