cloudnetpy 1.90.0__tar.gz → 1.90.2__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.90.0/cloudnetpy.egg-info → cloudnetpy-1.90.2}/PKG-INFO +1 -1
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/categorize.py +1 -2
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/constants.py +2 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/__init__.py +1 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/instruments.py +11 -4
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/rain_e_h3.py +1 -1
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/rpg.py +0 -6
- cloudnetpy-1.90.2/cloudnetpy/instruments/weather_radar.py +199 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/weather_station.py +1 -1
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/metadata.py +6 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/plotting/plotting.py +18 -18
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/version.py +1 -1
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2/cloudnetpy.egg-info}/PKG-INFO +1 -1
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy.egg-info/SOURCES.txt +1 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/LICENSE +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/MANIFEST.in +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/README.md +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/__init__.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/__init__.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/atmos_utils.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/attenuation.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/attenuations/__init__.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/attenuations/gas_attenuation.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/attenuations/liquid_attenuation.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/attenuations/melting_attenuation.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/attenuations/rain_attenuation.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/classify.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/containers.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/disdrometer.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/droplet.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/falling.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/freezing.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/insects.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/itu.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/lidar.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/melting.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/model.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/mwr.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/radar.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/cli.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/cloudnetarray.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/concat_lib.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/datasource.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/disdronator/__init__.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/disdronator/lpm.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/disdronator/parsivel.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/disdronator/rd80.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/disdronator/utils.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/exceptions.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/basta.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/bowtie.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/ceilo.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/ceilometer.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/cl61d.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/cloudnet_instrument.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/copernicus.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/da10.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/disdrometer/__init__.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/disdrometer/common.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/disdrometer/parsivel.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/disdrometer/rd80.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/disdrometer/thies.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/fd12p.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/galileo.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/hatpro.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/lufft.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/mira.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/mrr.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/nc_lidar.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/nc_radar.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/pollyxt.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/radiometrics.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/rpg_reader.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/toa5.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/instruments/vaisala.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/__init__.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/file_handler.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/metadata.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/model_metadata.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/plotting/__init__.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/plotting/plot_meta.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/plotting/plot_tools.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/plotting/plotting.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/products/__init__.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/products/advance_methods.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/products/grid_methods.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/products/model_products.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/products/observation_products.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/products/product_resampling.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/products/tools.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/statistics/__init__.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/statistics/statistical_methods.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/__init__.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/e2e/__init__.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/e2e/conftest.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/e2e/process_cf/__init__.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/__init__.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/__init__.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/unit/__init__.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/unit/conftest.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/unit/test_model_products.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/unit/test_observation_products.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/unit/test_plotting.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/unit/test_tools.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/utils.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/output.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/plotting/__init__.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/plotting/plot_meta.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/products/__init__.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/products/classification.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/products/der.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/products/drizzle.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/products/drizzle_error.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/products/drizzle_tools.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/products/epsilon.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/products/ier.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/products/iwc.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/products/lwc.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/products/mie_lu_tables.nc +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/products/mwr_tools.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/products/product_tools.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/py.typed +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/utils.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy.egg-info/dependency_links.txt +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy.egg-info/entry_points.txt +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy.egg-info/requires.txt +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy.egg-info/top_level.txt +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/docs/source/conf.py +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/pyproject.toml +0 -0
- {cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/setup.cfg +0 -0
|
@@ -22,7 +22,6 @@ from cloudnetpy.categorize.mwr import Mwr
|
|
|
22
22
|
from cloudnetpy.categorize.radar import Radar
|
|
23
23
|
from cloudnetpy.datasource import DataSource
|
|
24
24
|
from cloudnetpy.exceptions import DisdrometerDataError, ValidTimeStampError
|
|
25
|
-
from cloudnetpy.instruments.rpg import RPG_ATTRIBUTES
|
|
26
25
|
from cloudnetpy.metadata import COMMON_ATTRIBUTES, MetaData
|
|
27
26
|
from cloudnetpy.products.product_tools import CategoryBits, QualityBits
|
|
28
27
|
|
|
@@ -436,7 +435,7 @@ CATEGORIZE_ATTRIBUTES = {
|
|
|
436
435
|
units="m s-1",
|
|
437
436
|
dimensions=("time", "height"),
|
|
438
437
|
),
|
|
439
|
-
"zdr":
|
|
438
|
+
"zdr": COMMON_ATTRIBUTES["zdr"]._replace(dimensions=("time", "height")),
|
|
440
439
|
"nyquist_velocity": COMMON_ATTRIBUTES["nyquist_velocity"]._replace(
|
|
441
440
|
dimensions=("time", "height")
|
|
442
441
|
),
|
|
@@ -27,9 +27,11 @@ G_TO_KG: Final = 1e-3
|
|
|
27
27
|
M_TO_KM: Final = 1e-3
|
|
28
28
|
KG_TO_G: Final = 1e3
|
|
29
29
|
M_TO_MM: Final = 1e3
|
|
30
|
+
CM_TO_M: Final = 1e-2
|
|
30
31
|
M_S_TO_MM_H: Final = SEC_IN_HOUR / MM_TO_M
|
|
31
32
|
MM_H_TO_M_S: Final = 1 / M_S_TO_MM_H
|
|
32
33
|
GHZ_TO_HZ: Final = 1e9
|
|
34
|
+
HZ_TO_GHZ: Final = 1e-9
|
|
33
35
|
HPA_TO_PA: Final = 100
|
|
34
36
|
PA_TO_HPA: Final = 1 / HPA_TO_PA
|
|
35
37
|
KM_H_TO_M_S: Final = 1000 / SEC_IN_HOUR
|
|
@@ -216,31 +216,38 @@ RD80 = Instrument(
|
|
|
216
216
|
PLUVIO2 = Instrument(
|
|
217
217
|
manufacturer="OTT HydroMet",
|
|
218
218
|
domain="rain-gauge",
|
|
219
|
-
category="rain
|
|
219
|
+
category="rain gauge",
|
|
220
220
|
model="Pluvio2",
|
|
221
221
|
)
|
|
222
222
|
|
|
223
223
|
PLUVIO2S = Instrument(
|
|
224
224
|
manufacturer="OTT HydroMet",
|
|
225
225
|
domain="rain-gauge",
|
|
226
|
-
category="rain
|
|
226
|
+
category="rain gauge",
|
|
227
227
|
model="Pluvio2S",
|
|
228
228
|
)
|
|
229
229
|
|
|
230
230
|
THIES_PT = Instrument(
|
|
231
231
|
manufacturer="Thies Clima",
|
|
232
232
|
domain="rain-gauge",
|
|
233
|
-
category="rain
|
|
233
|
+
category="rain gauge",
|
|
234
234
|
model="Precipitation Transmitter",
|
|
235
235
|
)
|
|
236
236
|
|
|
237
237
|
RAIN_E_H3 = Instrument(
|
|
238
238
|
manufacturer="LAMBRECHT meteo GmbH",
|
|
239
239
|
domain="rain-gauge",
|
|
240
|
-
category="rain
|
|
240
|
+
category="rain gauge",
|
|
241
241
|
model="rain[e]H3",
|
|
242
242
|
)
|
|
243
243
|
|
|
244
|
+
WRM200 = Instrument(
|
|
245
|
+
manufacturer="Vaisala",
|
|
246
|
+
domain="weather-radar",
|
|
247
|
+
category="weather radar",
|
|
248
|
+
model="WRM200",
|
|
249
|
+
)
|
|
250
|
+
|
|
244
251
|
GENERIC_WEATHER_STATION = Instrument(
|
|
245
252
|
domain="weather-station",
|
|
246
253
|
category="weather station",
|
|
@@ -19,7 +19,7 @@ def rain_e_h32nc(
|
|
|
19
19
|
uuid: str | UUID | None = None,
|
|
20
20
|
date: str | datetime.date | None = None,
|
|
21
21
|
) -> UUID:
|
|
22
|
-
"""Converts rain_e_h3 rain
|
|
22
|
+
"""Converts rain_e_h3 rain gauge into Cloudnet Level 1b netCDF file.
|
|
23
23
|
|
|
24
24
|
Args:
|
|
25
25
|
input_file: Filename of rain_e_h3 CSV file.
|
|
@@ -471,12 +471,6 @@ RPG_ATTRIBUTES = {
|
|
|
471
471
|
dimensions=("time", "range"),
|
|
472
472
|
),
|
|
473
473
|
# STSR-mode radars
|
|
474
|
-
"zdr": MetaData(
|
|
475
|
-
long_name="Differential reflectivity", units="dB", dimensions=("time", "range")
|
|
476
|
-
),
|
|
477
|
-
"rho_hv": MetaData(
|
|
478
|
-
long_name="Correlation coefficient", units="1", dimensions=("time", "range")
|
|
479
|
-
),
|
|
480
474
|
"phi_dp": MetaData(
|
|
481
475
|
long_name="Differential phase", units="rad", dimensions=("time", "range")
|
|
482
476
|
),
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
from collections import defaultdict
|
|
3
|
+
from collections.abc import Iterable, Sequence
|
|
4
|
+
from os import PathLike
|
|
5
|
+
from uuid import UUID
|
|
6
|
+
|
|
7
|
+
import netCDF4
|
|
8
|
+
import numpy as np
|
|
9
|
+
import numpy.typing as npt
|
|
10
|
+
from numpy import ma
|
|
11
|
+
|
|
12
|
+
from cloudnetpy import output, utils
|
|
13
|
+
from cloudnetpy.cloudnetarray import CloudnetArray
|
|
14
|
+
from cloudnetpy.constants import CM_TO_M, HZ_TO_GHZ, M_TO_KM, SPEED_OF_LIGHT
|
|
15
|
+
from cloudnetpy.instruments import instruments
|
|
16
|
+
from cloudnetpy.instruments.cloudnet_instrument import CloudnetInstrument
|
|
17
|
+
from cloudnetpy.metadata import MetaData
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def wr2nc(
|
|
21
|
+
input_files: str | PathLike | Sequence[str | PathLike],
|
|
22
|
+
output_file: str | PathLike,
|
|
23
|
+
site_meta: dict,
|
|
24
|
+
uuid: str | UUID | None = None,
|
|
25
|
+
date: str | datetime.date | None = None,
|
|
26
|
+
) -> UUID:
|
|
27
|
+
"""Converts OPERA HDF5 weather radar data into Cloudnet Level 1b netCDF file.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
input_files: List of OPERA HDF5 files.
|
|
31
|
+
output_file: Output filename.
|
|
32
|
+
site_meta: Dictionary containing information about the site. Required
|
|
33
|
+
keys are `name`, `latitude`, `longitude` and `altitude`.
|
|
34
|
+
uuid: Set specific UUID for the file.
|
|
35
|
+
date: Expected date as YYYY-MM-DD.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
UUID of the generated file.
|
|
39
|
+
"""
|
|
40
|
+
if isinstance(date, str):
|
|
41
|
+
date = datetime.date.fromisoformat(date)
|
|
42
|
+
uuid = utils.get_uuid(uuid)
|
|
43
|
+
if isinstance(input_files, str | PathLike):
|
|
44
|
+
input_files = [input_files]
|
|
45
|
+
wr = WeatherRadar(input_files, site_meta, date)
|
|
46
|
+
wr.sort_and_dedup_timestamps()
|
|
47
|
+
wr.convert_to_cloudnet_arrays()
|
|
48
|
+
wr.screen_noise()
|
|
49
|
+
wr.add_meta()
|
|
50
|
+
attributes = output.add_time_attribute(ATTRIBUTES, wr.date)
|
|
51
|
+
output.update_attributes(wr.data, attributes)
|
|
52
|
+
output.save_level1b(wr, output_file, uuid)
|
|
53
|
+
return uuid
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class WeatherRadar(CloudnetInstrument):
|
|
57
|
+
def __init__(
|
|
58
|
+
self,
|
|
59
|
+
filenames: Iterable[str | PathLike],
|
|
60
|
+
site_meta: dict,
|
|
61
|
+
expected_date: datetime.date | None = None,
|
|
62
|
+
) -> None:
|
|
63
|
+
super().__init__()
|
|
64
|
+
self.site_meta = site_meta
|
|
65
|
+
self._read_data(filenames)
|
|
66
|
+
self._screen_time(expected_date)
|
|
67
|
+
self.instrument = instruments.WRM200
|
|
68
|
+
|
|
69
|
+
def _read_data(self, filenames: Iterable[str | PathLike]) -> None:
|
|
70
|
+
times = []
|
|
71
|
+
ranges = []
|
|
72
|
+
data = []
|
|
73
|
+
for filename in filenames:
|
|
74
|
+
file_time, file_range, file_data, file_scalars = _read_opera_h5(filename)
|
|
75
|
+
times.append(file_time)
|
|
76
|
+
ranges.append(file_range)
|
|
77
|
+
data.append(file_data)
|
|
78
|
+
target_range = max(ranges, key=lambda rng: rng[-1])
|
|
79
|
+
all_data = defaultdict(list)
|
|
80
|
+
for src_range, values in zip(ranges, data, strict=True):
|
|
81
|
+
for key, value in values.items():
|
|
82
|
+
block = ma.array([value])
|
|
83
|
+
if not np.array_equal(src_range, target_range):
|
|
84
|
+
block = utils.interpolate_2D_along_y(src_range, block, target_range)
|
|
85
|
+
all_data[key].append(block)
|
|
86
|
+
self.raw_time = np.array(times)
|
|
87
|
+
self.raw_range = target_range
|
|
88
|
+
self.raw_data = {key: ma.concatenate(value) for key, value in all_data.items()}
|
|
89
|
+
self.scalars = file_scalars
|
|
90
|
+
|
|
91
|
+
def _screen_time(self, expected_date: datetime.date | None = None) -> None:
|
|
92
|
+
if expected_date is None:
|
|
93
|
+
self.date = self.raw_time[0].date()
|
|
94
|
+
else:
|
|
95
|
+
is_valid = [dt.date() == expected_date for dt in self.raw_time]
|
|
96
|
+
self.raw_time = self.raw_time[is_valid]
|
|
97
|
+
for key in self.raw_data:
|
|
98
|
+
self.raw_data[key] = self.raw_data[key][is_valid]
|
|
99
|
+
self.date = expected_date
|
|
100
|
+
|
|
101
|
+
def sort_and_dedup_timestamps(self) -> None:
|
|
102
|
+
self.raw_time, time_ind = np.unique(self.raw_time, return_index=True)
|
|
103
|
+
for key in self.raw_data:
|
|
104
|
+
self.raw_data[key] = self.raw_data[key][time_ind]
|
|
105
|
+
|
|
106
|
+
def add_meta(self) -> None:
|
|
107
|
+
valid_keys = ("latitude", "longitude", "altitude")
|
|
108
|
+
for key, value in self.site_meta.items():
|
|
109
|
+
name = key.lower()
|
|
110
|
+
if name in valid_keys:
|
|
111
|
+
self.data[name] = CloudnetArray(float(value), name)
|
|
112
|
+
|
|
113
|
+
def convert_to_cloudnet_arrays(self) -> None:
|
|
114
|
+
epoch = datetime.datetime.combine(self.date, datetime.time())
|
|
115
|
+
hour = (self.raw_time - epoch) / datetime.timedelta(hours=1)
|
|
116
|
+
height = self.site_meta["altitude"] + self.raw_range
|
|
117
|
+
self.data["time"] = CloudnetArray(hour.astype(np.float32), "time")
|
|
118
|
+
self.data["range"] = CloudnetArray(self.raw_range, "range")
|
|
119
|
+
self.data["height"] = CloudnetArray(height, "height")
|
|
120
|
+
self.data["SNR"] = CloudnetArray(self.raw_data["SNR"], "SNR")
|
|
121
|
+
self.data["Zh"] = CloudnetArray(self.raw_data["ZH"], "Zh")
|
|
122
|
+
self.data["v"] = CloudnetArray(self.raw_data["VRADH"], "v")
|
|
123
|
+
self.data["width"] = CloudnetArray(self.raw_data["WRADH"], "width")
|
|
124
|
+
self.data["zdr"] = CloudnetArray(self.raw_data["ZDR"], "zdr")
|
|
125
|
+
self.data["rho_hv"] = CloudnetArray(self.raw_data["RHOHV"], "rho_hv")
|
|
126
|
+
self.data["radar_frequency"] = CloudnetArray(
|
|
127
|
+
self.scalars["FREQ"], "radar_frequency"
|
|
128
|
+
)
|
|
129
|
+
self.data["nyquist_velocity"] = CloudnetArray(
|
|
130
|
+
self.scalars["NI"], "nyquist_velocity"
|
|
131
|
+
)
|
|
132
|
+
self.data["calibration_reflectivity_factor"] = CloudnetArray(
|
|
133
|
+
self.scalars["NEZ"], "calibration_reflectivity_factor"
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
def screen_noise(self) -> None:
|
|
137
|
+
is_noise = self.data["SNR"].data < 0
|
|
138
|
+
for cloudnet_array in self.data.values():
|
|
139
|
+
if cloudnet_array.data.ndim == 2:
|
|
140
|
+
cloudnet_array.mask_indices(is_noise)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _read_opera_h5(
|
|
144
|
+
file: str | PathLike,
|
|
145
|
+
) -> tuple[datetime.datetime, npt.NDArray, dict[str, npt.NDArray], dict[str, float]]:
|
|
146
|
+
all_data = {}
|
|
147
|
+
with netCDF4.Dataset(file) as rootgrp:
|
|
148
|
+
date = rootgrp["what"].date
|
|
149
|
+
time = rootgrp["what"].time
|
|
150
|
+
dt = datetime.datetime.strptime(date + time, "%Y%m%d%H%M%S")
|
|
151
|
+
|
|
152
|
+
dataset = rootgrp["dataset1"]
|
|
153
|
+
nbins = dataset["where"].nbins
|
|
154
|
+
# NOTE: rstart is documented to be in km, but it's actually in m at
|
|
155
|
+
# least for FMI radars.
|
|
156
|
+
rstart = dataset["where"].nbins
|
|
157
|
+
rscale = dataset["where"].rscale # m
|
|
158
|
+
halfbin = rscale / 2
|
|
159
|
+
rng = rstart + halfbin + rscale * np.arange(nbins)
|
|
160
|
+
|
|
161
|
+
nez = dataset["how"].NEZH
|
|
162
|
+
ni = dataset["how"].NI
|
|
163
|
+
wavelength = rootgrp["how"].wavelength * CM_TO_M
|
|
164
|
+
frequency = HZ_TO_GHZ * SPEED_OF_LIGHT / wavelength
|
|
165
|
+
scalars = {"NEZ": nez, "NI": ni, "FREQ": frequency}
|
|
166
|
+
|
|
167
|
+
grpnames = [group for group in dataset.groups if group.startswith("data")]
|
|
168
|
+
for grpname in grpnames:
|
|
169
|
+
grp = dataset[grpname]
|
|
170
|
+
quantity = grp["what"].quantity
|
|
171
|
+
is_db = quantity in ("ZDR", "SNR")
|
|
172
|
+
offset = grp["what"].offset
|
|
173
|
+
gain = grp["what"].gain
|
|
174
|
+
nodata = grp["what"].nodata
|
|
175
|
+
undetect = grp["what"].undetect
|
|
176
|
+
grpdata = grp["data"][:]
|
|
177
|
+
is_masked = (grpdata == nodata) | (grpdata == undetect)
|
|
178
|
+
grpdata = offset + gain * ma.masked_where(is_masked, grpdata)
|
|
179
|
+
if is_db:
|
|
180
|
+
grpdata = utils.db2lin(grpdata)
|
|
181
|
+
grpdata = ma.mean(grpdata, axis=0)
|
|
182
|
+
if is_db:
|
|
183
|
+
grpdata = utils.lin2db(grpdata)
|
|
184
|
+
all_data[quantity] = grpdata
|
|
185
|
+
|
|
186
|
+
all_data["ZH"] = all_data["SNR"] + nez + 20 * np.log10(rng * M_TO_KM)
|
|
187
|
+
|
|
188
|
+
return dt, rng, all_data, scalars
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
ATTRIBUTES = {
|
|
192
|
+
"calibration_reflectivity_factor": MetaData(
|
|
193
|
+
long_name="Calibration reflectivity factor",
|
|
194
|
+
comment="This parameter is the equivalent radar reflectivity factor at 1 km\n"
|
|
195
|
+
"when the return signal power is equal to the noise power (SNR=0 dB).",
|
|
196
|
+
units="dBZ",
|
|
197
|
+
dimensions=(),
|
|
198
|
+
)
|
|
199
|
+
}
|
|
@@ -399,7 +399,7 @@ class KenttarovaWS(WS):
|
|
|
399
399
|
|
|
400
400
|
|
|
401
401
|
class HyytialaWS(WS):
|
|
402
|
-
"""Hyytiälä rain
|
|
402
|
+
"""Hyytiälä rain gauge variables: a = Pluvio400 and b = Pluvio200.
|
|
403
403
|
E.g.
|
|
404
404
|
- AaRNRT/mm = amount of non-real-time rain total (Pluvio400) [mm]
|
|
405
405
|
- BbRT/mm = Bucket content in real-time (Pluvio200) [mm].
|
|
@@ -170,6 +170,12 @@ COMMON_ATTRIBUTES = {
|
|
|
170
170
|
"SNR": MetaData(
|
|
171
171
|
long_name="Signal-to-noise ratio", units="dB", dimensions=("time", "range")
|
|
172
172
|
),
|
|
173
|
+
"zdr": MetaData(
|
|
174
|
+
long_name="Differential reflectivity", units="dB", dimensions=("time", "range")
|
|
175
|
+
),
|
|
176
|
+
"rho_hv": MetaData(
|
|
177
|
+
long_name="Correlation coefficient", units="1", dimensions=("time", "range")
|
|
178
|
+
),
|
|
173
179
|
"relative_humidity": MetaData(
|
|
174
180
|
long_name="Relative humidity",
|
|
175
181
|
standard_name="relative_humidity",
|
|
@@ -710,9 +710,9 @@ class Plot2D(Plot):
|
|
|
710
710
|
cbar, clabel = _hide_segments()
|
|
711
711
|
alt = self._screen_data_by_max_y(figure_data)
|
|
712
712
|
image = self._ax.pcolorfast(
|
|
713
|
-
figure_data.time_including_gaps,
|
|
714
|
-
alt,
|
|
715
|
-
self._data.T
|
|
713
|
+
_make_edges(figure_data.time_including_gaps),
|
|
714
|
+
_make_edges(alt),
|
|
715
|
+
self._data.T,
|
|
716
716
|
cmap=ListedColormap(cbar),
|
|
717
717
|
vmin=-0.5,
|
|
718
718
|
vmax=len(cbar) - 0.5,
|
|
@@ -752,21 +752,12 @@ class Plot2D(Plot):
|
|
|
752
752
|
"zorder": _get_zorder("data"),
|
|
753
753
|
}
|
|
754
754
|
image: Any
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
shading="nearest",
|
|
762
|
-
)
|
|
763
|
-
else:
|
|
764
|
-
image = self._ax.pcolorfast(
|
|
765
|
-
figure_data.time_including_gaps,
|
|
766
|
-
alt,
|
|
767
|
-
self._data.T[:-1, :-1],
|
|
768
|
-
**pcolor_kwargs,
|
|
769
|
-
)
|
|
755
|
+
image = self._ax.pcolorfast(
|
|
756
|
+
_make_edges(figure_data.time_including_gaps),
|
|
757
|
+
_make_edges(alt),
|
|
758
|
+
self._data.T,
|
|
759
|
+
**pcolor_kwargs,
|
|
760
|
+
)
|
|
770
761
|
cbar = self._init_colorbar(image)
|
|
771
762
|
cbar.set_label(str(self._plot_meta.clabel), fontsize=13)
|
|
772
763
|
|
|
@@ -1212,6 +1203,7 @@ def _get_max_gap_in_minutes(figure_data: FigureData) -> float:
|
|
|
1212
1203
|
"epsilon-lidar": 75,
|
|
1213
1204
|
"radar": 5,
|
|
1214
1205
|
"cpr-simulation": 60,
|
|
1206
|
+
"weather-radar": 20,
|
|
1215
1207
|
}
|
|
1216
1208
|
return max_allowed_gap.get(file_type, 10)
|
|
1217
1209
|
|
|
@@ -1225,6 +1217,14 @@ def _get_zorder(name: str) -> int:
|
|
|
1225
1217
|
return zorder.get(name, -1)
|
|
1226
1218
|
|
|
1227
1219
|
|
|
1220
|
+
def _make_edges(centers: npt.NDArray) -> npt.NDArray:
|
|
1221
|
+
edges = np.empty(len(centers) + 1)
|
|
1222
|
+
edges[0] = centers[0] - (centers[1] - centers[0]) / 2
|
|
1223
|
+
edges[1:-1] = (centers[:-1] + centers[1:]) / 2
|
|
1224
|
+
edges[-1] = centers[-1] + (centers[-1] - centers[-2]) / 2
|
|
1225
|
+
return edges
|
|
1226
|
+
|
|
1227
|
+
|
|
1228
1228
|
def find_batches_of_ones(array: ndarray) -> list[tuple[int, int]]:
|
|
1229
1229
|
"""Find batches of ones in a binary array."""
|
|
1230
1230
|
starts = np.where(np.diff(np.hstack(([0], array))) == 1)[0]
|
|
@@ -72,6 +72,7 @@ cloudnetpy/instruments/rpg.py
|
|
|
72
72
|
cloudnetpy/instruments/rpg_reader.py
|
|
73
73
|
cloudnetpy/instruments/toa5.py
|
|
74
74
|
cloudnetpy/instruments/vaisala.py
|
|
75
|
+
cloudnetpy/instruments/weather_radar.py
|
|
75
76
|
cloudnetpy/instruments/weather_station.py
|
|
76
77
|
cloudnetpy/instruments/disdrometer/__init__.py
|
|
77
78
|
cloudnetpy/instruments/disdrometer/common.py
|
|
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.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/attenuations/gas_attenuation.py
RENAMED
|
File without changes
|
{cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/attenuations/liquid_attenuation.py
RENAMED
|
File without changes
|
{cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/categorize/attenuations/melting_attenuation.py
RENAMED
|
File without changes
|
{cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/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
|
{cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/products/advance_methods.py
RENAMED
|
File without changes
|
{cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/products/grid_methods.py
RENAMED
|
File without changes
|
{cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/products/model_products.py
RENAMED
|
File without changes
|
{cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/products/observation_products.py
RENAMED
|
File without changes
|
{cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/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.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/e2e/process_cf/__init__.py
RENAMED
|
File without changes
|
{cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py
RENAMED
|
File without changes
|
{cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py
RENAMED
|
File without changes
|
|
File without changes
|
{cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py
RENAMED
|
File without changes
|
{cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py
RENAMED
|
File without changes
|
|
File without changes
|
{cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py
RENAMED
|
File without changes
|
{cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py
RENAMED
|
File without changes
|
{cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/cloudnetpy/model_evaluation/tests/unit/test_plotting.py
RENAMED
|
File without changes
|
|
File without changes
|
{cloudnetpy-1.90.0 → cloudnetpy-1.90.2}/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
|