cloudnetpy 1.64.5__py3-none-any.whl → 1.65.1__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/atmos.py +8 -1
- cloudnetpy/categorize/categorize.py +35 -29
- cloudnetpy/categorize/containers.py +5 -1
- cloudnetpy/exceptions.py +7 -0
- cloudnetpy/instruments/hatpro.py +4 -0
- cloudnetpy/products/der.py +4 -0
- cloudnetpy/products/lwc.py +4 -0
- cloudnetpy/version.py +2 -2
- {cloudnetpy-1.64.5.dist-info → cloudnetpy-1.65.1.dist-info}/METADATA +1 -1
- {cloudnetpy-1.64.5.dist-info → cloudnetpy-1.65.1.dist-info}/RECORD +13 -13
- {cloudnetpy-1.64.5.dist-info → cloudnetpy-1.65.1.dist-info}/WHEEL +1 -1
- {cloudnetpy-1.64.5.dist-info → cloudnetpy-1.65.1.dist-info}/LICENSE +0 -0
- {cloudnetpy-1.64.5.dist-info → cloudnetpy-1.65.1.dist-info}/top_level.txt +0 -0
cloudnetpy/categorize/atmos.py
CHANGED
@@ -181,7 +181,14 @@ class LiquidAttenuation(Attenuation):
|
|
181
181
|
|
182
182
|
def __init__(self, data: dict, classification: ClassificationResult):
|
183
183
|
super().__init__(data["model"], classification)
|
184
|
-
|
184
|
+
if data["mwr"] is not None:
|
185
|
+
self._mwr = data["mwr"].data
|
186
|
+
else:
|
187
|
+
n_time = data["radar"].data["Z"][:].shape[0]
|
188
|
+
self._mwr = {
|
189
|
+
"lwp": ma.masked_all(n_time),
|
190
|
+
"lwp_error": ma.masked_all(n_time),
|
191
|
+
}
|
185
192
|
self._lwc_dz_err = self._get_lwc_change_rate_error()
|
186
193
|
self.atten = self._get_liquid_atten()
|
187
194
|
self.atten_err = self._get_liquid_atten_err()
|
@@ -20,54 +20,58 @@ def generate_categorize(
|
|
20
20
|
uuid: str | None = None,
|
21
21
|
options: dict | None = None,
|
22
22
|
) -> str:
|
23
|
-
"""Generates Cloudnet Level 1c categorize file.
|
23
|
+
"""Generates a Cloudnet Level 1c categorize file.
|
24
24
|
|
25
|
-
|
26
|
-
and
|
27
|
-
insects, etc.
|
28
|
-
attenuation, and error estimates are computed.
|
29
|
-
|
25
|
+
This function rebins measurements into a common height/time grid
|
26
|
+
and classifies them into different scatterer types, such as ice,
|
27
|
+
liquid, insects, etc. The radar signal is corrected for atmospheric
|
28
|
+
attenuation, and error estimates are computed. The results are saved in
|
29
|
+
*output_file*, a compressed netCDF4 file.
|
30
30
|
|
31
31
|
Args:
|
32
|
-
input_files
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
32
|
+
input_files (dict): Contains filenames for calibrated `radar`, `lidar`,
|
33
|
+
and `model` files. Optionally, it can also include `disdrometer`,
|
34
|
+
`mwr` (containing the LWP variable), and `lv0_files` (a list of RPG
|
35
|
+
Level 0 files).
|
36
|
+
output_file (str): The full path of the output file.
|
37
|
+
uuid (str): Specific UUID to assign to the generated file.
|
38
|
+
options (dict): Dictionary containing optional parameters.
|
38
39
|
|
39
40
|
Returns:
|
40
|
-
UUID of the generated file.
|
41
|
+
str: UUID of the generated file.
|
41
42
|
|
42
43
|
Raises:
|
43
|
-
RuntimeError:
|
44
|
+
RuntimeError: Raised if the categorize file creation fails.
|
44
45
|
|
45
46
|
Notes:
|
46
|
-
|
47
|
-
measures liquid water path.
|
48
|
-
|
47
|
+
A separate MWR file is not required when using an RPG cloud radar that
|
48
|
+
measures liquid water path (LWP). In this case, the radar file can also
|
49
|
+
serve as the MWR file (e.g., {'mwr': 'radar.nc'}). If no MWR file
|
50
|
+
is provided, liquid attenuation correction cannot be performed.
|
49
51
|
|
50
|
-
If RPG L0 files are
|
51
|
-
to detect liquid droplets.
|
52
|
+
If RPG L0 files are included as additional input, the Voodoo method
|
53
|
+
is used to detect liquid droplets.
|
52
54
|
|
53
55
|
Examples:
|
54
56
|
>>> from cloudnetpy.categorize import generate_categorize
|
55
|
-
>>> input_files = {
|
56
|
-
|
57
|
-
|
58
|
-
|
57
|
+
>>> input_files = {
|
58
|
+
... 'radar': 'radar.nc',
|
59
|
+
... 'lidar': 'lidar.nc',
|
60
|
+
... 'model': 'model.nc',
|
61
|
+
... 'mwr': 'mwr.nc'
|
62
|
+
... }
|
59
63
|
>>> generate_categorize(input_files, 'output.nc')
|
60
64
|
|
61
|
-
>>> input_files[
|
62
|
-
>>> generate_categorize(input_files, 'output.nc') # Use Voodoo method
|
63
|
-
|
65
|
+
>>> input_files['lv0_files'] = ['file1.LV0', 'file2.LV0'] # Add RPG LV0 files
|
66
|
+
>>> generate_categorize(input_files, 'output.nc') # Use the Voodoo method
|
64
67
|
"""
|
65
68
|
|
66
69
|
def _interpolate_to_cloudnet_grid() -> list:
|
67
70
|
wl_band = utils.get_wl_band(data["radar"].radar_frequency)
|
68
|
-
data["mwr"].rebin_to_grid(time)
|
69
71
|
if data["disdrometer"] is not None:
|
70
72
|
data["disdrometer"].interpolate_to_grid(time)
|
73
|
+
if data["mwr"] is not None:
|
74
|
+
data["mwr"].rebin_to_grid(time)
|
71
75
|
data["model"].interpolate_to_common_height(wl_band)
|
72
76
|
model_gap_ind = data["model"].interpolate_to_grid(time, height)
|
73
77
|
radar_gap_ind = data["radar"].rebin_to_grid(time)
|
@@ -115,7 +119,7 @@ def generate_categorize(
|
|
115
119
|
**data["lidar"].data,
|
116
120
|
**data["model"].data,
|
117
121
|
**data["model"].data_sparse,
|
118
|
-
**data["mwr"].data,
|
122
|
+
**(data["mwr"].data if data["mwr"] is not None else {}),
|
119
123
|
**(data["disdrometer"].data if data["disdrometer"] is not None else {}),
|
120
124
|
}
|
121
125
|
|
@@ -131,10 +135,12 @@ def generate_categorize(
|
|
131
135
|
data: dict = {
|
132
136
|
"radar": Radar(input_files["radar"]),
|
133
137
|
"lidar": Lidar(input_files["lidar"]),
|
134
|
-
"mwr": Mwr(input_files["mwr"]),
|
135
138
|
"lv0_files": input_files.get("lv0_files"),
|
139
|
+
"mwr": None,
|
136
140
|
"disdrometer": None,
|
137
141
|
}
|
142
|
+
if "mwr" in input_files:
|
143
|
+
data["mwr"] = Mwr(input_files["mwr"])
|
138
144
|
if "disdrometer" in input_files:
|
139
145
|
try:
|
140
146
|
data["disdrometer"] = Disdrometer(input_files["disdrometer"])
|
@@ -58,7 +58,11 @@ class ClassData:
|
|
58
58
|
self.tw = data["model"].data["Tw"][:]
|
59
59
|
self.model_type = data["model"].source_type
|
60
60
|
self.beta = data["lidar"].data["beta"][:]
|
61
|
-
self.lwp =
|
61
|
+
self.lwp = (
|
62
|
+
data["mwr"].data["lwp"][:]
|
63
|
+
if data["mwr"] is not None
|
64
|
+
else ma.masked_all(self.time.shape)
|
65
|
+
)
|
62
66
|
self.is_rain = self._find_profiles_with_rain()
|
63
67
|
self.is_clutter = _find_clutter(self.v, self.is_rain)
|
64
68
|
self.altitude = data["radar"].altitude
|
cloudnetpy/exceptions.py
CHANGED
@@ -63,3 +63,10 @@ class HatproDataError(CloudnetException):
|
|
63
63
|
|
64
64
|
def __init__(self, msg: str = "Invalid HATPRO file"):
|
65
65
|
super().__init__(msg)
|
66
|
+
|
67
|
+
|
68
|
+
class InvalidSourceFileError(CloudnetException):
|
69
|
+
"""Internal exception class."""
|
70
|
+
|
71
|
+
def __init__(self, msg: str = "Invalid source file"):
|
72
|
+
super().__init__(msg)
|
cloudnetpy/instruments/hatpro.py
CHANGED
@@ -60,6 +60,10 @@ def hatpro2l1c(
|
|
60
60
|
|
61
61
|
hatpro = HatproL1c(hatpro_raw, site_meta)
|
62
62
|
|
63
|
+
if not np.any(hatpro.data["tb"][:]):
|
64
|
+
msg = "No valid brightness temperatures found"
|
65
|
+
raise HatproDataError(msg)
|
66
|
+
|
63
67
|
timestamps = hatpro.data["time"][:]
|
64
68
|
if date is not None:
|
65
69
|
# Screen timestamps if these assertions start to fail
|
cloudnetpy/products/der.py
CHANGED
@@ -10,6 +10,7 @@ from numpy import ma
|
|
10
10
|
from cloudnetpy import output, utils
|
11
11
|
from cloudnetpy.categorize import atmos
|
12
12
|
from cloudnetpy.datasource import DataSource
|
13
|
+
from cloudnetpy.exceptions import InvalidSourceFileError
|
13
14
|
from cloudnetpy.metadata import MetaData
|
14
15
|
from cloudnetpy.products.product_tools import (
|
15
16
|
CategorizeBits,
|
@@ -113,6 +114,9 @@ class DerSource(DataSource):
|
|
113
114
|
|
114
115
|
def __init__(self, categorize_file: str, parameters: Parameters | None = None):
|
115
116
|
super().__init__(categorize_file)
|
117
|
+
if "lwp" not in self.dataset.variables:
|
118
|
+
msg = "Liquid water path missing from the categorize file."
|
119
|
+
raise InvalidSourceFileError(msg)
|
116
120
|
self.is_rain = get_is_rain(categorize_file)
|
117
121
|
self.categorize_bits = CategorizeBits(categorize_file)
|
118
122
|
if parameters is None:
|
cloudnetpy/products/lwc.py
CHANGED
@@ -8,6 +8,7 @@ from numpy import ma
|
|
8
8
|
from cloudnetpy import output, utils
|
9
9
|
from cloudnetpy.categorize import atmos
|
10
10
|
from cloudnetpy.datasource import DataSource
|
11
|
+
from cloudnetpy.exceptions import InvalidSourceFileError
|
11
12
|
from cloudnetpy.metadata import MetaData
|
12
13
|
from cloudnetpy.products import product_tools as p_tools
|
13
14
|
from cloudnetpy.products.product_tools import CategorizeBits, get_is_rain
|
@@ -88,6 +89,9 @@ class LwcSource(DataSource):
|
|
88
89
|
|
89
90
|
def __init__(self, categorize_file: str):
|
90
91
|
super().__init__(categorize_file)
|
92
|
+
if "lwp" not in self.dataset.variables:
|
93
|
+
msg = "Liquid water path missing from the categorize file."
|
94
|
+
raise InvalidSourceFileError(msg)
|
91
95
|
self.lwp = self.getvar("lwp")
|
92
96
|
self.lwp[self.lwp < 0] = 0
|
93
97
|
self.lwp_error = self.getvar("lwp_error")
|
cloudnetpy/version.py
CHANGED
@@ -3,18 +3,18 @@ cloudnetpy/cloudnetarray.py,sha256=Ol1ha4RPAmFZANL__U5CaMKX4oYMXYR6OnjoCZ9w3eo,7
|
|
3
3
|
cloudnetpy/concat_lib.py,sha256=8Ek059RMLAfbbXCkX90cgnhw_8ZpcDrxw1yPvwtuitU,9846
|
4
4
|
cloudnetpy/constants.py,sha256=YVbi2porUnKIzO_PdGeH9pEO9gKa95vDcj6TBMSreoY,734
|
5
5
|
cloudnetpy/datasource.py,sha256=j7N4g59HPvOBWle-W9bOUF0BfRLgvR4zwOi_B50cI7Q,7921
|
6
|
-
cloudnetpy/exceptions.py,sha256=
|
6
|
+
cloudnetpy/exceptions.py,sha256=ns48useL9RN3mPh7CqIiLA19VI9OmVbyRsKTkwbThF8,1760
|
7
7
|
cloudnetpy/metadata.py,sha256=v_VDo2vbdTxB0zIsfP69IcrwSKiRlLpsGdq6JPI4CoA,5306
|
8
8
|
cloudnetpy/output.py,sha256=YkCaxVkG_Mt2hng_IVnhygHteV4UMKzKALkeFZwFJL8,14822
|
9
9
|
cloudnetpy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
10
|
cloudnetpy/utils.py,sha256=JV0Fawnme1HoZgoiidV3eIzsn6vx0AEjBNmI1CcrBsA,28517
|
11
|
-
cloudnetpy/version.py,sha256=
|
11
|
+
cloudnetpy/version.py,sha256=jw9H3ZZS4YhETjavFqda9t2WtO2jSz4WsOUzbwSTTvk,72
|
12
12
|
cloudnetpy/categorize/__init__.py,sha256=gP5q3Vis1y9u9OWgA_idlbjfWXYN_S0IBSWdwBhL_uU,69
|
13
|
-
cloudnetpy/categorize/atmos.py,sha256=
|
13
|
+
cloudnetpy/categorize/atmos.py,sha256=vavMC_WQQyGH14eL4vAzKLKDDZt8tBrMYimztYHOjH8,12639
|
14
14
|
cloudnetpy/categorize/atmos_utils.py,sha256=64uenj2uxj3P3Blaq_pBN1pBjcF-X4LYNt-uTOjvevg,3778
|
15
|
-
cloudnetpy/categorize/categorize.py,sha256=
|
15
|
+
cloudnetpy/categorize/categorize.py,sha256=VcxSs22icYDG3R5x9jTX7uuSjPU8tyc5bIz0Zj5F9z0,18303
|
16
16
|
cloudnetpy/categorize/classify.py,sha256=a-0bVCtynGfORnDGTsPuzqkuDeOOR_OMz5ai9NsMuic,9870
|
17
|
-
cloudnetpy/categorize/containers.py,sha256=
|
17
|
+
cloudnetpy/categorize/containers.py,sha256=g3SQHoqlY1uJ8b-MG-BbW3oWz5IyacA8kJBeIPy_4EA,4859
|
18
18
|
cloudnetpy/categorize/disdrometer.py,sha256=keU3pFvKtk840A0oLwAyNDuqOCswBPJEKf2bV0YWyA8,2004
|
19
19
|
cloudnetpy/categorize/droplet.py,sha256=894VHdL9ScaB8f1oxXwM2la4ShXd-uWywQDINoaoiD8,8687
|
20
20
|
cloudnetpy/categorize/falling.py,sha256=Wz49mbw0pubnbhoekYTqGT0S9UNaE88jWOjSPEsCIaI,4386
|
@@ -34,7 +34,7 @@ cloudnetpy/instruments/cl61d.py,sha256=g6DNBFju3wYhLFl32DKmC8pUup7y-EupXoUU0fuoG
|
|
34
34
|
cloudnetpy/instruments/cloudnet_instrument.py,sha256=RG5HJxGM6p0F-IGyr85fvOizcMmgx48OeD_XeIsrgSU,3367
|
35
35
|
cloudnetpy/instruments/copernicus.py,sha256=nmgqGOjVQFngj7BNbpcuCwA-W3yksvBbqn__iq7MyDk,6469
|
36
36
|
cloudnetpy/instruments/galileo.py,sha256=yQBedd7dmDnwuWi1MtXOsg4-RyRx0uRAXumCY4YuH9k,4686
|
37
|
-
cloudnetpy/instruments/hatpro.py,sha256=
|
37
|
+
cloudnetpy/instruments/hatpro.py,sha256=9A7H-SEDGp-1zuLFskd8WRp4nU3ZI70Bkq5_GBpIx9I,8646
|
38
38
|
cloudnetpy/instruments/instruments.py,sha256=jG5TYnZ8bdCZXnI303ZsaJBEdSKaIjKMbkGtnq6kQX0,3261
|
39
39
|
cloudnetpy/instruments/lufft.py,sha256=ugXF6pssHAAz1Y_hqPdpKuluAjxxHSR88xBmQuS6RlI,3705
|
40
40
|
cloudnetpy/instruments/mira.py,sha256=EyzEBTpWfDlgaspZVuIfaP4l73GYSVnSzEzBZc0lZNg,9333
|
@@ -97,19 +97,19 @@ cloudnetpy/plotting/plot_meta.py,sha256=JHrr-4A9fhqdi_tQFe6mR4Fdry3hkI-lmmVu5Ny2
|
|
97
97
|
cloudnetpy/plotting/plotting.py,sha256=rVaCsXTrhb0ahdXerSPLZWRASs_QktyLUbjyHoVuam8,33584
|
98
98
|
cloudnetpy/products/__init__.py,sha256=2hRb5HG9hNrxH1if5laJkLeFeaZCd5W1q3hh4ewsX0E,273
|
99
99
|
cloudnetpy/products/classification.py,sha256=bNG8W1CMgGoUBpXopQjYAW3F-uEJGyojXb4A5jmErHo,7921
|
100
|
-
cloudnetpy/products/der.py,sha256=
|
100
|
+
cloudnetpy/products/der.py,sha256=1LDBbnbUg8feMUTGWJq3bObBhEcZ_Ee17MB1x0GwRdo,12669
|
101
101
|
cloudnetpy/products/drizzle.py,sha256=58C9Mo6oRXR8KpbVPghbJvHvFX9GfS3xUp058pbf0qw,10804
|
102
102
|
cloudnetpy/products/drizzle_error.py,sha256=4GwlHRtNbk9ks7bGtXCco-wXbcDOKeAQwKmbhzut6Qk,6132
|
103
103
|
cloudnetpy/products/drizzle_tools.py,sha256=LR2AtbFQRGFrJ2LGyiLxOfbnlznVLydXvb8RFDR0_4E,10848
|
104
104
|
cloudnetpy/products/ier.py,sha256=ge1f_aYick20Nlznq8zbBl5umWlTP-UwMivy4Y05Sck,7839
|
105
105
|
cloudnetpy/products/iwc.py,sha256=Q8dXV3JF3JUQgwkmQFOKakm21Tnf8oCWsH0CSqIEKl4,10209
|
106
|
-
cloudnetpy/products/lwc.py,sha256=
|
106
|
+
cloudnetpy/products/lwc.py,sha256=wSd3GDqELz4yyWBMiKDR-QhRK8scPheqsBcS1qzxYOI,18997
|
107
107
|
cloudnetpy/products/mie_lu_tables.nc,sha256=It4fYpqJXlqOgL8jeZ-PxGzP08PMrELIDVe55y9ob58,16637951
|
108
108
|
cloudnetpy/products/mwr_tools.py,sha256=3esU5cG5GI2WVmOENqrJ0FbMuxLegADv7q8TB0RorGg,4674
|
109
109
|
cloudnetpy/products/product_tools.py,sha256=VNw2diJj30POz68-3qNVkJP7r9AUspT_d1Fp0BbeIx8,10414
|
110
110
|
docs/source/conf.py,sha256=IKiFWw6xhUd8NrCg0q7l596Ck1d61XWeVjIFHVSG9Og,1490
|
111
|
-
cloudnetpy-1.
|
112
|
-
cloudnetpy-1.
|
113
|
-
cloudnetpy-1.
|
114
|
-
cloudnetpy-1.
|
115
|
-
cloudnetpy-1.
|
111
|
+
cloudnetpy-1.65.1.dist-info/LICENSE,sha256=wcZF72bdaoG9XugpyE95Juo7lBQOwLuTKBOhhtANZMM,1094
|
112
|
+
cloudnetpy-1.65.1.dist-info/METADATA,sha256=qxDqKsWNjOAd93st6zGCAqnoJB49_j1gYKLeq7yemjc,5784
|
113
|
+
cloudnetpy-1.65.1.dist-info/WHEEL,sha256=Mdi9PDNwEZptOjTlUcAth7XJDFtKrHYaQMPulZeBCiQ,91
|
114
|
+
cloudnetpy-1.65.1.dist-info/top_level.txt,sha256=ibSPWRr6ojS1i11rtBFz2_gkIe68mggj7aeswYfaOo0,16
|
115
|
+
cloudnetpy-1.65.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|