cloudnetpy 1.49.9__py3-none-any.whl → 1.87.3__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/__init__.py +1 -2
- cloudnetpy/categorize/atmos_utils.py +297 -67
- cloudnetpy/categorize/attenuation.py +31 -0
- cloudnetpy/categorize/attenuations/__init__.py +37 -0
- cloudnetpy/categorize/attenuations/gas_attenuation.py +30 -0
- cloudnetpy/categorize/attenuations/liquid_attenuation.py +84 -0
- cloudnetpy/categorize/attenuations/melting_attenuation.py +78 -0
- cloudnetpy/categorize/attenuations/rain_attenuation.py +84 -0
- cloudnetpy/categorize/categorize.py +332 -156
- cloudnetpy/categorize/classify.py +127 -125
- cloudnetpy/categorize/containers.py +107 -76
- cloudnetpy/categorize/disdrometer.py +40 -0
- cloudnetpy/categorize/droplet.py +23 -21
- cloudnetpy/categorize/falling.py +53 -24
- cloudnetpy/categorize/freezing.py +25 -12
- cloudnetpy/categorize/insects.py +35 -23
- cloudnetpy/categorize/itu.py +243 -0
- cloudnetpy/categorize/lidar.py +36 -41
- cloudnetpy/categorize/melting.py +34 -26
- cloudnetpy/categorize/model.py +84 -37
- cloudnetpy/categorize/mwr.py +18 -14
- cloudnetpy/categorize/radar.py +215 -102
- cloudnetpy/cli.py +578 -0
- cloudnetpy/cloudnetarray.py +43 -89
- cloudnetpy/concat_lib.py +218 -78
- cloudnetpy/constants.py +28 -10
- cloudnetpy/datasource.py +61 -86
- cloudnetpy/exceptions.py +49 -20
- cloudnetpy/instruments/__init__.py +5 -0
- cloudnetpy/instruments/basta.py +29 -12
- cloudnetpy/instruments/bowtie.py +135 -0
- cloudnetpy/instruments/ceilo.py +138 -115
- cloudnetpy/instruments/ceilometer.py +164 -80
- cloudnetpy/instruments/cl61d.py +21 -5
- cloudnetpy/instruments/cloudnet_instrument.py +74 -36
- cloudnetpy/instruments/copernicus.py +108 -30
- cloudnetpy/instruments/da10.py +54 -0
- cloudnetpy/instruments/disdrometer/common.py +126 -223
- cloudnetpy/instruments/disdrometer/parsivel.py +453 -94
- cloudnetpy/instruments/disdrometer/thies.py +254 -87
- cloudnetpy/instruments/fd12p.py +201 -0
- cloudnetpy/instruments/galileo.py +65 -23
- cloudnetpy/instruments/hatpro.py +123 -49
- cloudnetpy/instruments/instruments.py +113 -1
- cloudnetpy/instruments/lufft.py +39 -17
- cloudnetpy/instruments/mira.py +268 -61
- cloudnetpy/instruments/mrr.py +187 -0
- cloudnetpy/instruments/nc_lidar.py +19 -8
- cloudnetpy/instruments/nc_radar.py +109 -55
- cloudnetpy/instruments/pollyxt.py +135 -51
- cloudnetpy/instruments/radiometrics.py +313 -59
- cloudnetpy/instruments/rain_e_h3.py +171 -0
- cloudnetpy/instruments/rpg.py +321 -189
- cloudnetpy/instruments/rpg_reader.py +74 -40
- cloudnetpy/instruments/toa5.py +49 -0
- cloudnetpy/instruments/vaisala.py +95 -343
- cloudnetpy/instruments/weather_station.py +774 -105
- cloudnetpy/metadata.py +90 -19
- cloudnetpy/model_evaluation/file_handler.py +55 -52
- cloudnetpy/model_evaluation/metadata.py +46 -20
- cloudnetpy/model_evaluation/model_metadata.py +1 -1
- cloudnetpy/model_evaluation/plotting/plot_tools.py +32 -37
- cloudnetpy/model_evaluation/plotting/plotting.py +327 -117
- cloudnetpy/model_evaluation/products/advance_methods.py +92 -83
- cloudnetpy/model_evaluation/products/grid_methods.py +88 -63
- cloudnetpy/model_evaluation/products/model_products.py +43 -35
- cloudnetpy/model_evaluation/products/observation_products.py +41 -35
- cloudnetpy/model_evaluation/products/product_resampling.py +17 -7
- cloudnetpy/model_evaluation/products/tools.py +29 -20
- cloudnetpy/model_evaluation/statistics/statistical_methods.py +30 -20
- cloudnetpy/model_evaluation/tests/e2e/conftest.py +3 -3
- cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py +9 -5
- cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py +15 -14
- cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py +9 -5
- cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py +15 -14
- cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py +9 -5
- cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py +15 -14
- cloudnetpy/model_evaluation/tests/unit/conftest.py +42 -41
- cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py +41 -48
- cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py +216 -194
- cloudnetpy/model_evaluation/tests/unit/test_model_products.py +23 -21
- cloudnetpy/model_evaluation/tests/unit/test_observation_products.py +37 -38
- cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py +43 -40
- cloudnetpy/model_evaluation/tests/unit/test_plotting.py +30 -36
- cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py +68 -31
- cloudnetpy/model_evaluation/tests/unit/test_tools.py +33 -26
- cloudnetpy/model_evaluation/utils.py +2 -1
- cloudnetpy/output.py +170 -111
- cloudnetpy/plotting/__init__.py +2 -1
- cloudnetpy/plotting/plot_meta.py +562 -822
- cloudnetpy/plotting/plotting.py +1142 -704
- cloudnetpy/products/__init__.py +1 -0
- cloudnetpy/products/classification.py +370 -88
- cloudnetpy/products/der.py +85 -55
- cloudnetpy/products/drizzle.py +77 -34
- cloudnetpy/products/drizzle_error.py +15 -11
- cloudnetpy/products/drizzle_tools.py +79 -59
- cloudnetpy/products/epsilon.py +211 -0
- cloudnetpy/products/ier.py +27 -50
- cloudnetpy/products/iwc.py +55 -48
- cloudnetpy/products/lwc.py +96 -70
- cloudnetpy/products/mwr_tools.py +186 -0
- cloudnetpy/products/product_tools.py +170 -128
- cloudnetpy/utils.py +455 -240
- cloudnetpy/version.py +2 -2
- {cloudnetpy-1.49.9.dist-info → cloudnetpy-1.87.3.dist-info}/METADATA +44 -40
- cloudnetpy-1.87.3.dist-info/RECORD +127 -0
- {cloudnetpy-1.49.9.dist-info → cloudnetpy-1.87.3.dist-info}/WHEEL +1 -1
- cloudnetpy-1.87.3.dist-info/entry_points.txt +2 -0
- docs/source/conf.py +2 -2
- cloudnetpy/categorize/atmos.py +0 -361
- cloudnetpy/products/mwr_multi.py +0 -68
- cloudnetpy/products/mwr_single.py +0 -75
- cloudnetpy-1.49.9.dist-info/RECORD +0 -112
- {cloudnetpy-1.49.9.dist-info → cloudnetpy-1.87.3.dist-info/licenses}/LICENSE +0 -0
- {cloudnetpy-1.49.9.dist-info → cloudnetpy-1.87.3.dist-info}/top_level.txt +0 -0
cloudnetpy/metadata.py
CHANGED
|
@@ -4,7 +4,8 @@ from typing import NamedTuple
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class MetaData(NamedTuple):
|
|
7
|
-
long_name: str
|
|
7
|
+
long_name: str
|
|
8
|
+
dimensions: tuple[str, ...] | None
|
|
8
9
|
standard_name: str | None = None
|
|
9
10
|
units: str | None = None
|
|
10
11
|
comment: str | None = None
|
|
@@ -15,6 +16,7 @@ class MetaData(NamedTuple):
|
|
|
15
16
|
axis: str | None = None
|
|
16
17
|
calendar: str | None = None
|
|
17
18
|
source: str | None = None
|
|
19
|
+
source_instrument_pid: str | None = None
|
|
18
20
|
|
|
19
21
|
|
|
20
22
|
COMMON_ATTRIBUTES = {
|
|
@@ -23,30 +25,38 @@ COMMON_ATTRIBUTES = {
|
|
|
23
25
|
axis="T",
|
|
24
26
|
standard_name="time",
|
|
25
27
|
calendar="standard",
|
|
28
|
+
dimensions=("time",),
|
|
26
29
|
),
|
|
27
30
|
"height": MetaData(
|
|
28
31
|
long_name="Height above mean sea level",
|
|
29
32
|
standard_name="height_above_mean_sea_level",
|
|
30
33
|
units="m",
|
|
34
|
+
dimensions=("range",),
|
|
31
35
|
),
|
|
32
36
|
"range": MetaData(
|
|
33
37
|
long_name="Range from instrument",
|
|
34
38
|
axis="Z",
|
|
35
39
|
units="m",
|
|
36
40
|
comment="Distance from instrument to centre of each range bin.",
|
|
41
|
+
dimensions=("range",),
|
|
37
42
|
),
|
|
38
43
|
"latitude": MetaData(
|
|
39
44
|
long_name="Latitude of site",
|
|
40
45
|
units="degree_north",
|
|
41
46
|
standard_name="latitude",
|
|
47
|
+
dimensions=("time",),
|
|
42
48
|
),
|
|
43
49
|
"longitude": MetaData(
|
|
44
50
|
long_name="Longitude of site",
|
|
45
51
|
units="degree_east",
|
|
46
52
|
standard_name="longitude",
|
|
53
|
+
dimensions=("time",),
|
|
47
54
|
),
|
|
48
55
|
"altitude": MetaData(
|
|
49
|
-
long_name="Altitude of site",
|
|
56
|
+
long_name="Altitude of site",
|
|
57
|
+
standard_name="altitude",
|
|
58
|
+
units="m",
|
|
59
|
+
dimensions=("time",),
|
|
50
60
|
),
|
|
51
61
|
"Zh": MetaData(
|
|
52
62
|
long_name="Radar reflectivity factor",
|
|
@@ -54,6 +64,7 @@ COMMON_ATTRIBUTES = {
|
|
|
54
64
|
comment="Calibrated reflectivity. Calibration convention: in the absence\n"
|
|
55
65
|
"of attenuation, a cloud at 273 K containing one million 100-micron droplets\n"
|
|
56
66
|
"per cubic metre will have a reflectivity of 0 dBZ at all frequencies.",
|
|
67
|
+
dimensions=("time", "range"),
|
|
57
68
|
),
|
|
58
69
|
"width": MetaData(
|
|
59
70
|
long_name="Spectral width",
|
|
@@ -62,6 +73,7 @@ COMMON_ATTRIBUTES = {
|
|
|
62
73
|
"This parameter is the standard deviation of the reflectivity-weighted\n"
|
|
63
74
|
"velocities in the radar pulse volume."
|
|
64
75
|
),
|
|
76
|
+
dimensions=("time", "range"),
|
|
65
77
|
),
|
|
66
78
|
"v": MetaData(
|
|
67
79
|
long_name="Doppler velocity",
|
|
@@ -70,91 +82,150 @@ COMMON_ATTRIBUTES = {
|
|
|
70
82
|
"This parameter is the radial component of the velocity, with positive\n"
|
|
71
83
|
"velocities are away from the radar."
|
|
72
84
|
),
|
|
85
|
+
dimensions=("time", "range"),
|
|
73
86
|
),
|
|
74
87
|
"ldr": MetaData(
|
|
75
88
|
long_name="Linear depolarisation ratio",
|
|
76
89
|
units="dB",
|
|
77
90
|
comment="This parameter is the ratio of cross-polar to co-polar reflectivity.",
|
|
91
|
+
dimensions=("time", "range"),
|
|
92
|
+
),
|
|
93
|
+
"sldr": MetaData(
|
|
94
|
+
long_name="Slanted linear depolarisation ratio",
|
|
95
|
+
units="dB",
|
|
96
|
+
dimensions=("time", "range"),
|
|
78
97
|
),
|
|
79
|
-
"sldr": MetaData(long_name="Slanted linear depolarisation ratio", units="dB"),
|
|
80
98
|
"lwp": MetaData(
|
|
81
99
|
long_name="Liquid water path",
|
|
82
100
|
units="kg m-2",
|
|
83
101
|
standard_name="atmosphere_cloud_liquid_water_content",
|
|
102
|
+
dimensions=("time",),
|
|
84
103
|
),
|
|
85
104
|
"iwv": MetaData(
|
|
86
105
|
long_name="Integrated water vapour",
|
|
87
106
|
units="kg m-2",
|
|
88
107
|
standard_name="atmosphere_mass_content_of_water_vapor",
|
|
108
|
+
dimensions=("time",),
|
|
89
109
|
),
|
|
90
110
|
"kurtosis": MetaData(
|
|
91
111
|
long_name="Kurtosis of spectra",
|
|
92
112
|
units="1",
|
|
113
|
+
dimensions=("time", "range"),
|
|
114
|
+
),
|
|
115
|
+
"skewness": MetaData(
|
|
116
|
+
long_name="Skewness of spectra",
|
|
117
|
+
units="1",
|
|
118
|
+
dimensions=("time", "range"),
|
|
119
|
+
),
|
|
120
|
+
"nyquist_velocity": MetaData(
|
|
121
|
+
long_name="Nyquist velocity",
|
|
122
|
+
units="m s-1",
|
|
123
|
+
dimensions=("time", "range"),
|
|
124
|
+
),
|
|
125
|
+
"radar_frequency": MetaData(
|
|
126
|
+
long_name="Radar transmit frequency", units="GHz", dimensions=None
|
|
93
127
|
),
|
|
94
|
-
"nyquist_velocity": MetaData(long_name="Nyquist velocity", units="m s-1"),
|
|
95
|
-
"radar_frequency": MetaData(long_name="Radar transmit frequency", units="GHz"),
|
|
96
128
|
"beta": MetaData(
|
|
97
129
|
long_name="Attenuated backscatter coefficient",
|
|
98
130
|
units="sr-1 m-1",
|
|
99
131
|
comment="SNR-screened attenuated backscatter coefficient.",
|
|
132
|
+
dimensions=("time", "range"),
|
|
100
133
|
),
|
|
101
134
|
"beta_raw": MetaData(
|
|
102
135
|
long_name="Attenuated backscatter coefficient",
|
|
103
136
|
units="sr-1 m-1",
|
|
104
137
|
comment="Non-screened attenuated backscatter coefficient.",
|
|
138
|
+
dimensions=("time", "range"),
|
|
105
139
|
),
|
|
106
140
|
"beta_smooth": MetaData(
|
|
107
141
|
long_name="Attenuated backscatter coefficient",
|
|
108
142
|
units="sr-1 m-1",
|
|
109
143
|
comment="SNR-screened attenuated backscatter coefficient.\n"
|
|
110
144
|
"Weak background smoothed using Gaussian 2D-kernel.",
|
|
145
|
+
dimensions=("time", "range"),
|
|
111
146
|
),
|
|
112
|
-
"wavelength": MetaData(
|
|
113
|
-
long_name="Laser wavelength",
|
|
114
|
-
units="nm",
|
|
115
|
-
),
|
|
147
|
+
"wavelength": MetaData(long_name="Laser wavelength", units="nm", dimensions=None),
|
|
116
148
|
"zenith_angle": MetaData(
|
|
117
149
|
long_name="Zenith angle",
|
|
118
150
|
units="degree",
|
|
119
151
|
standard_name="zenith_angle",
|
|
120
152
|
comment="Angle to the local vertical. A value of zero is directly overhead.",
|
|
153
|
+
dimensions=("time",),
|
|
154
|
+
),
|
|
155
|
+
"ir_zenith_angle": MetaData(
|
|
156
|
+
long_name="Infrared sensor zenith angle",
|
|
157
|
+
units="degree",
|
|
158
|
+
comment="90=horizon, 0=zenith",
|
|
159
|
+
dimensions=("time",),
|
|
121
160
|
),
|
|
122
161
|
"azimuth_angle": MetaData(
|
|
123
162
|
long_name="Azimuth angle",
|
|
124
163
|
standard_name="sensor_azimuth_angle",
|
|
125
164
|
units="degree",
|
|
126
165
|
comment="Angle between North and the line of sight, measured clockwise.",
|
|
166
|
+
dimensions=("time",),
|
|
127
167
|
),
|
|
128
|
-
"temperature": MetaData(
|
|
129
|
-
|
|
130
|
-
units="K",
|
|
131
|
-
),
|
|
132
|
-
"pressure": MetaData(
|
|
133
|
-
long_name="Pressure",
|
|
134
|
-
units="Pa",
|
|
135
|
-
),
|
|
168
|
+
"temperature": MetaData(long_name="Temperature", units="K", dimensions=("time",)),
|
|
169
|
+
"pressure": MetaData(long_name="Pressure", units="Pa", dimensions=("time",)),
|
|
136
170
|
"SNR": MetaData(
|
|
137
|
-
long_name="Signal-to-noise ratio",
|
|
138
|
-
units="dB",
|
|
171
|
+
long_name="Signal-to-noise ratio", units="dB", dimensions=("time", "range")
|
|
139
172
|
),
|
|
140
173
|
"relative_humidity": MetaData(
|
|
141
174
|
long_name="Relative humidity",
|
|
142
175
|
standard_name="relative_humidity",
|
|
143
176
|
units="1",
|
|
177
|
+
dimensions=("time",),
|
|
178
|
+
),
|
|
179
|
+
"absolute_humidity": MetaData(
|
|
180
|
+
long_name="Absolute humidity",
|
|
181
|
+
standard_name="mass_concentration_of_water_vapor_in_air",
|
|
182
|
+
units="kg m-3",
|
|
183
|
+
dimensions=("time", "range"),
|
|
144
184
|
),
|
|
145
185
|
"wind_speed": MetaData(
|
|
146
186
|
long_name="Wind speed",
|
|
147
187
|
standard_name="wind_speed",
|
|
148
188
|
units="m s-1",
|
|
189
|
+
dimensions=("time",),
|
|
149
190
|
),
|
|
150
191
|
"wind_direction": MetaData(
|
|
151
192
|
long_name="Wind direction",
|
|
152
193
|
standard_name="wind_from_direction",
|
|
153
194
|
units="degree",
|
|
195
|
+
dimensions=("time",),
|
|
154
196
|
),
|
|
155
197
|
"rainfall_rate": MetaData(
|
|
156
198
|
long_name="Rainfall rate",
|
|
157
199
|
standard_name="rainfall_rate",
|
|
158
200
|
units="m s-1",
|
|
201
|
+
dimensions=("time",),
|
|
202
|
+
),
|
|
203
|
+
"rainfall_amount": MetaData(
|
|
204
|
+
long_name="Rainfall amount",
|
|
205
|
+
standard_name="thickness_of_rainfall_amount",
|
|
206
|
+
units="m",
|
|
207
|
+
comment="Cumulated precipitation since 00:00 UTC",
|
|
208
|
+
dimensions=("time",),
|
|
209
|
+
),
|
|
210
|
+
"air_temperature": MetaData(
|
|
211
|
+
long_name="Air temperature",
|
|
212
|
+
standard_name="air_temperature",
|
|
213
|
+
units="K",
|
|
214
|
+
dimensions=("time",),
|
|
215
|
+
),
|
|
216
|
+
"air_pressure": MetaData(
|
|
217
|
+
long_name="Air pressure",
|
|
218
|
+
standard_name="air_pressure",
|
|
219
|
+
units="Pa",
|
|
220
|
+
dimensions=("time",),
|
|
221
|
+
),
|
|
222
|
+
"snr_limit": MetaData(
|
|
223
|
+
long_name="SNR limit",
|
|
224
|
+
units="dB",
|
|
225
|
+
comment="SNR threshold used in data screening.",
|
|
226
|
+
dimensions=None,
|
|
227
|
+
),
|
|
228
|
+
"synop_WaWa": MetaData(
|
|
229
|
+
long_name="Synop code WaWa", units="1", dimensions=("time",)
|
|
159
230
|
),
|
|
160
231
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from datetime import datetime
|
|
3
|
+
from os import PathLike
|
|
4
|
+
from uuid import UUID
|
|
3
5
|
|
|
4
6
|
import netCDF4
|
|
7
|
+
import numpy.typing as npt
|
|
5
8
|
|
|
6
9
|
from cloudnetpy import output, utils
|
|
7
10
|
|
|
@@ -10,12 +13,11 @@ from .metadata import (
|
|
|
10
13
|
MODEL_ATTRIBUTES,
|
|
11
14
|
MODEL_L3_ATTRIBUTES,
|
|
12
15
|
REGRID_PRODUCT_ATTRIBUTES,
|
|
13
|
-
MetaData,
|
|
14
16
|
)
|
|
15
17
|
from .products.model_products import ModelManager
|
|
16
18
|
|
|
17
19
|
|
|
18
|
-
def update_attributes(model_downsample_variables: dict, attributes: dict):
|
|
20
|
+
def update_attributes(model_downsample_variables: dict, attributes: dict) -> None:
|
|
19
21
|
"""Overrides existing Cloudnet-ME Array-attributes.
|
|
20
22
|
Overrides existing attributes using hard-coded values.
|
|
21
23
|
New attributes are added.
|
|
@@ -33,11 +35,11 @@ def update_attributes(model_downsample_variables: dict, attributes: dict):
|
|
|
33
35
|
model_downsample_variables[key].set_attributes(MODEL_ATTRIBUTES[key])
|
|
34
36
|
elif "_".join(key_parts[0:-1]) in REGRID_PRODUCT_ATTRIBUTES:
|
|
35
37
|
model_downsample_variables[key].set_attributes(
|
|
36
|
-
REGRID_PRODUCT_ATTRIBUTES["_".join(key_parts[0:-1])]
|
|
38
|
+
REGRID_PRODUCT_ATTRIBUTES["_".join(key_parts[0:-1])],
|
|
37
39
|
)
|
|
38
40
|
elif "_".join(key_parts[0:-2]) in REGRID_PRODUCT_ATTRIBUTES:
|
|
39
41
|
model_downsample_variables[key].set_attributes(
|
|
40
|
-
REGRID_PRODUCT_ATTRIBUTES["_".join(key_parts[0:-2])]
|
|
42
|
+
REGRID_PRODUCT_ATTRIBUTES["_".join(key_parts[0:-2])],
|
|
41
43
|
)
|
|
42
44
|
elif (
|
|
43
45
|
"_".join(key_parts[1:]) in MODEL_L3_ATTRIBUTES
|
|
@@ -45,29 +47,29 @@ def update_attributes(model_downsample_variables: dict, attributes: dict):
|
|
|
45
47
|
):
|
|
46
48
|
try:
|
|
47
49
|
model_downsample_variables[key].set_attributes(
|
|
48
|
-
MODEL_L3_ATTRIBUTES["_".join(key_parts[1:])]
|
|
50
|
+
MODEL_L3_ATTRIBUTES["_".join(key_parts[1:])],
|
|
49
51
|
)
|
|
50
52
|
except KeyError:
|
|
51
53
|
model_downsample_variables[key].set_attributes(
|
|
52
|
-
MODEL_L3_ATTRIBUTES["_".join(key_parts[2:])]
|
|
54
|
+
MODEL_L3_ATTRIBUTES["_".join(key_parts[2:])],
|
|
53
55
|
)
|
|
54
56
|
elif "_".join(key_parts[1:]) in CYCLE_ATTRIBUTES:
|
|
55
57
|
model_downsample_variables[key].set_attributes(
|
|
56
|
-
CYCLE_ATTRIBUTES["_".join(key_parts[1:])]
|
|
58
|
+
CYCLE_ATTRIBUTES["_".join(key_parts[1:])],
|
|
57
59
|
)
|
|
58
60
|
elif "_".join(key_parts[2:]) in CYCLE_ATTRIBUTES:
|
|
59
61
|
model_downsample_variables[key].set_attributes(
|
|
60
|
-
CYCLE_ATTRIBUTES["_".join(key_parts[2:])]
|
|
62
|
+
CYCLE_ATTRIBUTES["_".join(key_parts[2:])],
|
|
61
63
|
)
|
|
62
64
|
|
|
63
65
|
|
|
64
66
|
def save_downsampled_file(
|
|
65
67
|
id_mark: str,
|
|
66
|
-
file_name: str,
|
|
68
|
+
file_name: str | PathLike,
|
|
67
69
|
objects: tuple,
|
|
68
|
-
files: tuple,
|
|
69
|
-
uuid:
|
|
70
|
-
):
|
|
70
|
+
files: tuple[list[str | PathLike], str | PathLike],
|
|
71
|
+
uuid: UUID,
|
|
72
|
+
) -> None:
|
|
71
73
|
"""Saves a standard downsampled day product file.
|
|
72
74
|
|
|
73
75
|
Args:
|
|
@@ -83,35 +85,31 @@ def save_downsampled_file(
|
|
|
83
85
|
"""
|
|
84
86
|
obj = objects[0]
|
|
85
87
|
dimensions = {"time": len(obj.time), "level": len(obj.data["level"][:])}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
obj.dataset
|
|
98
|
-
|
|
99
|
-
root_group
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
nc_file.close()
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
def _write_vars2nc(rootgrp: netCDF4.Dataset, cloudnet_variables: dict):
|
|
88
|
+
with output.init_file(file_name, dimensions, obj.data, uuid) as root_group:
|
|
89
|
+
_augment_global_attributes(root_group)
|
|
90
|
+
root_group.cloudnet_file_type = "l3-" + id_mark.split("_")[0]
|
|
91
|
+
root_group.title = (
|
|
92
|
+
f"Downsampled {id_mark.capitalize().replace('_', ' of ')} "
|
|
93
|
+
f"from {obj.dataset.location}"
|
|
94
|
+
)
|
|
95
|
+
_add_source(root_group, objects, files)
|
|
96
|
+
output.copy_global(
|
|
97
|
+
obj.dataset, root_group, ("location", "day", "month", "year")
|
|
98
|
+
)
|
|
99
|
+
if not hasattr(obj.dataset, "day"):
|
|
100
|
+
root_group.year, root_group.month, root_group.day = obj.date
|
|
101
|
+
output.merge_history(root_group, id_mark, obj)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def add_var2ncfile(obj: ModelManager, file_name: str | PathLike) -> None:
|
|
105
|
+
with netCDF4.Dataset(file_name, "r+", format="NETCDF4_CLASSIC") as nc_file:
|
|
106
|
+
_write_vars2nc(nc_file, obj.data)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _write_vars2nc(rootgrp: netCDF4.Dataset, cloudnet_variables: dict) -> None:
|
|
112
110
|
"""Iterates over Cloudnet-ME instances and write to given rootgrp."""
|
|
113
111
|
|
|
114
|
-
def _get_dimensions(array):
|
|
112
|
+
def _get_dimensions(array: npt.NDArray) -> tuple:
|
|
115
113
|
"""Finds correct dimensions for a variable."""
|
|
116
114
|
if utils.isscalar(array):
|
|
117
115
|
return ()
|
|
@@ -119,8 +117,8 @@ def _write_vars2nc(rootgrp: netCDF4.Dataset, cloudnet_variables: dict):
|
|
|
119
117
|
file_dims = rootgrp.dimensions
|
|
120
118
|
array_dims = array.shape
|
|
121
119
|
for length in array_dims:
|
|
122
|
-
dim = [key for key in file_dims
|
|
123
|
-
variable_size = variable_size
|
|
120
|
+
dim = [key for key in file_dims if file_dims[key].size == length][0] # noqa: RUF015
|
|
121
|
+
variable_size = (*variable_size, dim)
|
|
124
122
|
return variable_size
|
|
125
123
|
|
|
126
124
|
for key in cloudnet_variables:
|
|
@@ -128,7 +126,10 @@ def _write_vars2nc(rootgrp: netCDF4.Dataset, cloudnet_variables: dict):
|
|
|
128
126
|
size = _get_dimensions(obj.data)
|
|
129
127
|
try:
|
|
130
128
|
nc_variable = rootgrp.createVariable(
|
|
131
|
-
obj.name,
|
|
129
|
+
obj.name,
|
|
130
|
+
obj.data_type,
|
|
131
|
+
size,
|
|
132
|
+
zlib=True,
|
|
132
133
|
)
|
|
133
134
|
nc_variable[:] = obj.data
|
|
134
135
|
for attr in obj.fetch_attributes():
|
|
@@ -137,13 +138,12 @@ def _write_vars2nc(rootgrp: netCDF4.Dataset, cloudnet_variables: dict):
|
|
|
137
138
|
continue
|
|
138
139
|
|
|
139
140
|
|
|
140
|
-
def _augment_global_attributes(root_group: netCDF4.Dataset):
|
|
141
|
+
def _augment_global_attributes(root_group: netCDF4.Dataset) -> None:
|
|
141
142
|
root_group.Conventions = "CF-1.8"
|
|
142
|
-
# root_group.cloudnetme_version = version.__version__
|
|
143
143
|
|
|
144
144
|
|
|
145
|
-
def _add_source(root_ground: netCDF4.Dataset, objects: tuple, files: tuple):
|
|
146
|
-
"""Generates source info for multiple files"""
|
|
145
|
+
def _add_source(root_ground: netCDF4.Dataset, objects: tuple, files: tuple) -> None:
|
|
146
|
+
"""Generates source info for multiple files."""
|
|
147
147
|
model, obs = objects
|
|
148
148
|
model_files, obs_file = files
|
|
149
149
|
source = f"Observation file: {os.path.basename(obs_file)}"
|
|
@@ -154,18 +154,21 @@ def _add_source(root_ground: netCDF4.Dataset, objects: tuple, files: tuple):
|
|
|
154
154
|
if i < len(model_files) - 1:
|
|
155
155
|
source += "\n"
|
|
156
156
|
root_ground.source = source
|
|
157
|
-
root_ground.source_file_uuids = output.get_source_uuids(model, obs)
|
|
157
|
+
root_ground.source_file_uuids = output.get_source_uuids([model, obs])
|
|
158
158
|
|
|
159
159
|
|
|
160
160
|
def add_time_attribute(date: datetime) -> dict:
|
|
161
|
-
"""
|
|
161
|
+
"""Adds time attribute with correct units.
|
|
162
|
+
|
|
162
163
|
Args:
|
|
163
164
|
attributes: Attributes of variables.
|
|
164
165
|
date: Date as Y M D 0 0 0.
|
|
166
|
+
|
|
165
167
|
Returns:
|
|
166
168
|
dict: Same attributes with 'time' attribute added.
|
|
167
169
|
"""
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
return {
|
|
171
|
+
"time": MODEL_ATTRIBUTES["time"]._replace(
|
|
172
|
+
units=f"hours since {date:%Y-%m-%d} 00:00:00 +00:00",
|
|
173
|
+
),
|
|
174
|
+
}
|
|
@@ -1,27 +1,24 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class MetaData(NamedTuple):
|
|
5
|
-
long_name: str
|
|
6
|
-
units: str
|
|
7
|
-
comment: str | None = None
|
|
8
|
-
standard_name: str | None = None
|
|
9
|
-
axis: str | None = None
|
|
10
|
-
positive: str | None = None
|
|
11
|
-
|
|
1
|
+
from cloudnetpy.metadata import MetaData
|
|
12
2
|
|
|
13
3
|
MODEL_ATTRIBUTES = {
|
|
14
4
|
"time": MetaData(
|
|
15
|
-
units="
|
|
5
|
+
units="",
|
|
16
6
|
long_name="Time UTC",
|
|
17
7
|
axis="T",
|
|
8
|
+
calendar="standard",
|
|
9
|
+
dimensions=("time",),
|
|
10
|
+
),
|
|
11
|
+
"latitude": MetaData(
|
|
12
|
+
long_name="Latitude of grid point", units="degree_north", dimensions=None
|
|
13
|
+
),
|
|
14
|
+
"longitude": MetaData(
|
|
15
|
+
long_name="Longitude of grid point", units="degree_east", dimensions=None
|
|
18
16
|
),
|
|
19
|
-
"latitude": MetaData(long_name="Latitude of grid point", units="dergees_north"),
|
|
20
|
-
"longitude": MetaData(long_name="Longitude of grid point", units="degrees_east"),
|
|
21
17
|
"horizontal_resolution": MetaData(
|
|
22
18
|
long_name="Horizontal resolution of model",
|
|
23
19
|
units="km",
|
|
24
20
|
comment="Distance between two grid point",
|
|
21
|
+
dimensions=None,
|
|
25
22
|
),
|
|
26
23
|
"level": MetaData(
|
|
27
24
|
long_name="Model level",
|
|
@@ -29,6 +26,7 @@ MODEL_ATTRIBUTES = {
|
|
|
29
26
|
comment="Level 1 describes the highest height from ground.",
|
|
30
27
|
axis="Z",
|
|
31
28
|
positive="down",
|
|
29
|
+
dimensions=("level",),
|
|
32
30
|
),
|
|
33
31
|
}
|
|
34
32
|
|
|
@@ -41,6 +39,7 @@ CYCLE_ATTRIBUTES = {
|
|
|
41
39
|
"which it was taken. Note that the profiles in this file may be taken\n"
|
|
42
40
|
"from more than one forecast."
|
|
43
41
|
),
|
|
42
|
+
dimensions=("time",),
|
|
44
43
|
),
|
|
45
44
|
"height": MetaData(
|
|
46
45
|
long_name="Height above ground",
|
|
@@ -50,16 +49,21 @@ CYCLE_ATTRIBUTES = {
|
|
|
50
49
|
"specific humidity."
|
|
51
50
|
),
|
|
52
51
|
positive="up",
|
|
52
|
+
dimensions=("time", "level"),
|
|
53
53
|
),
|
|
54
|
-
"pressure": MetaData(long_name="Pressure", units="Pa"),
|
|
55
|
-
"temperature": MetaData(long_name="Temperature", units="K"),
|
|
54
|
+
"pressure": MetaData(long_name="Pressure", units="Pa", dimensions=None),
|
|
55
|
+
"temperature": MetaData(long_name="Temperature", units="K", dimensions=None),
|
|
56
56
|
"uwind": MetaData(
|
|
57
|
-
long_name="Zonal wind",
|
|
57
|
+
long_name="Zonal wind",
|
|
58
|
+
units="m s-1",
|
|
59
|
+
standard_name="eastward_wind",
|
|
60
|
+
dimensions=None,
|
|
58
61
|
),
|
|
59
62
|
"vwind": MetaData(
|
|
60
63
|
long_name="Meridional wind",
|
|
61
64
|
units="m s-1",
|
|
62
65
|
standard_name="northward_wind",
|
|
66
|
+
dimensions=None,
|
|
63
67
|
),
|
|
64
68
|
"wwind": MetaData(
|
|
65
69
|
long_name="Vertical wind",
|
|
@@ -69,13 +73,15 @@ CYCLE_ATTRIBUTES = {
|
|
|
69
73
|
"The vertical wind has been calculated from omega (Pa s-1),\n"
|
|
70
74
|
"height and pressure using: w=omega*dz/dp"
|
|
71
75
|
),
|
|
76
|
+
dimensions=None,
|
|
72
77
|
),
|
|
73
78
|
"omega": MetaData(
|
|
74
79
|
long_name="Vertical wind in pressure coordinates",
|
|
75
80
|
units="PA s-1",
|
|
76
81
|
standard_name="omega",
|
|
82
|
+
dimensions=None,
|
|
77
83
|
),
|
|
78
|
-
"q": MetaData(long_name="Specific humidity", units="1"),
|
|
84
|
+
"q": MetaData(long_name="Specific humidity", units="1", dimensions=None),
|
|
79
85
|
"rh": MetaData(
|
|
80
86
|
long_name="Relative humidity",
|
|
81
87
|
units="1",
|
|
@@ -83,28 +89,36 @@ CYCLE_ATTRIBUTES = {
|
|
|
83
89
|
"With respect to liquid above 0 degrees C and with respect to ice\n"
|
|
84
90
|
"below 0 degrees C"
|
|
85
91
|
),
|
|
92
|
+
dimensions=None,
|
|
86
93
|
),
|
|
87
94
|
}
|
|
88
95
|
|
|
89
96
|
MODEL_L3_ATTRIBUTES = {
|
|
90
|
-
"cf": MetaData(
|
|
97
|
+
"cf": MetaData(
|
|
98
|
+
long_name="Cloud fraction of model grid point",
|
|
99
|
+
units="1",
|
|
100
|
+
dimensions=("time", "level"),
|
|
101
|
+
),
|
|
91
102
|
"cf_cirrus": MetaData(
|
|
92
103
|
long_name="Cloud fraction of model grid point with filtered cirrus fraction",
|
|
93
104
|
units="1",
|
|
94
105
|
comment="High level cirrus fraction is reduce do to lack if a radar\n"
|
|
95
106
|
"capability to observe correctly particles small and high.",
|
|
107
|
+
dimensions=("time", "level"),
|
|
96
108
|
),
|
|
97
109
|
"iwc": MetaData(
|
|
98
110
|
long_name="Ice water content of model grid point",
|
|
99
111
|
units="kg m-3",
|
|
100
112
|
comment="Calculated using model ice water mixing ration, pressure\n"
|
|
101
113
|
"and temperature: qi*P/287*T",
|
|
114
|
+
dimensions=("time", "level"),
|
|
102
115
|
),
|
|
103
116
|
"lwc": MetaData(
|
|
104
117
|
long_name="Liquid water content of model grid point",
|
|
105
118
|
units="kg m-3",
|
|
106
119
|
comment="Calculated using model liquid water mixing ration, pressure\n"
|
|
107
120
|
"and temperature: ql*P/287*T",
|
|
121
|
+
dimensions=("time", "level"),
|
|
108
122
|
),
|
|
109
123
|
}
|
|
110
124
|
|
|
@@ -115,8 +129,9 @@ REGRID_PRODUCT_ATTRIBUTES = {
|
|
|
115
129
|
comment=(
|
|
116
130
|
"Cloud fraction generated from observations and by volume,\n"
|
|
117
131
|
"averaged onto the models grid with height and time. Volume is\n"
|
|
118
|
-
"space
|
|
132
|
+
"space within four grid points."
|
|
119
133
|
),
|
|
134
|
+
dimensions=("time", "level"),
|
|
120
135
|
),
|
|
121
136
|
"cf_A": MetaData(
|
|
122
137
|
long_name="Observed cloud fraction by area",
|
|
@@ -126,6 +141,7 @@ REGRID_PRODUCT_ATTRIBUTES = {
|
|
|
126
141
|
"averaged onto the models grid with height and time. Area is\n"
|
|
127
142
|
"sum of time columns with any cloud fraction."
|
|
128
143
|
),
|
|
144
|
+
dimensions=("time", "level"),
|
|
129
145
|
),
|
|
130
146
|
"cf_V_adv": MetaData(
|
|
131
147
|
long_name="Observed cloud fraction by advection volume",
|
|
@@ -135,6 +151,7 @@ REGRID_PRODUCT_ATTRIBUTES = {
|
|
|
135
151
|
"except that model winds were used to estimate the time taken to advect\n"
|
|
136
152
|
"airflow a distance equivalent to the models horizontal resolution."
|
|
137
153
|
),
|
|
154
|
+
dimensions=("time", "level"),
|
|
138
155
|
),
|
|
139
156
|
"cf_A_adv": MetaData(
|
|
140
157
|
long_name="Observed cloud fraction by advection area",
|
|
@@ -144,6 +161,7 @@ REGRID_PRODUCT_ATTRIBUTES = {
|
|
|
144
161
|
"except that model winds were used to estimate the time taken to advect\n"
|
|
145
162
|
"airflow a distance equivalent to the models horizontal resolution."
|
|
146
163
|
),
|
|
164
|
+
dimensions=("time", "level"),
|
|
147
165
|
),
|
|
148
166
|
"iwc": MetaData(
|
|
149
167
|
long_name="Observed ice water content reshaped to model dimensions by"
|
|
@@ -155,6 +173,7 @@ REGRID_PRODUCT_ATTRIBUTES = {
|
|
|
155
173
|
"The formula has been applied where the categorization data has\n"
|
|
156
174
|
"diagnosed that the radar echo is due to ice."
|
|
157
175
|
),
|
|
176
|
+
dimensions=("time", "level"),
|
|
158
177
|
),
|
|
159
178
|
"iwc_att": MetaData(
|
|
160
179
|
long_name="Observed ice water content with attenuation reshaped to model grid"
|
|
@@ -165,6 +184,7 @@ REGRID_PRODUCT_ATTRIBUTES = {
|
|
|
165
184
|
"except that profiles with uncorrected attenuation of the radar\n"
|
|
166
185
|
"reflectivity were included."
|
|
167
186
|
),
|
|
187
|
+
dimensions=("time", "level"),
|
|
168
188
|
),
|
|
169
189
|
"iwc_rain": MetaData(
|
|
170
190
|
long_name="Observed ice water content with raining reshaped to model grid"
|
|
@@ -175,6 +195,7 @@ REGRID_PRODUCT_ATTRIBUTES = {
|
|
|
175
195
|
"including attenuation, iwc_att, except that profiles with rain\n"
|
|
176
196
|
"at the surface were also included."
|
|
177
197
|
),
|
|
198
|
+
dimensions=("time", "level"),
|
|
178
199
|
),
|
|
179
200
|
"iwc_adv": MetaData(
|
|
180
201
|
long_name="Observed ice water content reshaped to model advection grid"
|
|
@@ -185,6 +206,7 @@ REGRID_PRODUCT_ATTRIBUTES = {
|
|
|
185
206
|
"except that model winds were used to estimate the time taken to advect\n"
|
|
186
207
|
"the flow a distance equivalent to the models horizontal resolution."
|
|
187
208
|
),
|
|
209
|
+
dimensions=("time", "level"),
|
|
188
210
|
),
|
|
189
211
|
"iwc_att_adv": MetaData(
|
|
190
212
|
long_name="Observed ice water content with attenuation reshaped to model"
|
|
@@ -195,6 +217,7 @@ REGRID_PRODUCT_ATTRIBUTES = {
|
|
|
195
217
|
"iwc_adv, except that profiles with uncorrected attenuation of the radar\n"
|
|
196
218
|
"reflectivity were included."
|
|
197
219
|
),
|
|
220
|
+
dimensions=("time", "level"),
|
|
198
221
|
),
|
|
199
222
|
"iwc_rain_adv": MetaData(
|
|
200
223
|
long_name="Observed ice water content with raining reshaped to model"
|
|
@@ -205,6 +228,7 @@ REGRID_PRODUCT_ATTRIBUTES = {
|
|
|
205
228
|
"including attenuation, iwc_att_adv, except that profiles with rain\n"
|
|
206
229
|
"at the surface were also included."
|
|
207
230
|
),
|
|
231
|
+
dimensions=("time", "level"),
|
|
208
232
|
),
|
|
209
233
|
"lwc": MetaData(
|
|
210
234
|
long_name="Observed liquid water content reshaped to model grid by averaging",
|
|
@@ -214,6 +238,7 @@ REGRID_PRODUCT_ATTRIBUTES = {
|
|
|
214
238
|
"pixels where the categorization data has diagnosed that liquid water \n"
|
|
215
239
|
"is present, averaged onto the model grid with height and time."
|
|
216
240
|
),
|
|
241
|
+
dimensions=("time", "level"),
|
|
217
242
|
),
|
|
218
243
|
"lwc_adv": MetaData(
|
|
219
244
|
long_name="Observed liquid water content reshaped to model advection grid by "
|
|
@@ -224,5 +249,6 @@ REGRID_PRODUCT_ATTRIBUTES = {
|
|
|
224
249
|
"lwc, except that model winds were used to estimate the time taken to\n"
|
|
225
250
|
"advect flow over the models grid points."
|
|
226
251
|
),
|
|
252
|
+
dimensions=("time", "level"),
|
|
227
253
|
),
|
|
228
254
|
}
|