doppy 0.1.4__cp310-abi3-macosx_11_0_arm64.whl → 0.2.1__cp310-abi3-macosx_11_0_arm64.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.

Potentially problematic release.


This version of doppy might be problematic. Click here for more details.

doppy/data/api.py CHANGED
@@ -37,7 +37,13 @@ class Api:
37
37
  return self.get(
38
38
  "raw-files",
39
39
  params={
40
- "instrument": ["halo-doppler-lidar", "wls100s", "wls200s", "wls400s"],
40
+ "instrument": [
41
+ "halo-doppler-lidar",
42
+ "wls100s",
43
+ "wls200s",
44
+ "wls400s",
45
+ "wls70",
46
+ ],
41
47
  "site": site,
42
48
  "date": date,
43
49
  },
doppy/product/stare.py CHANGED
@@ -27,6 +27,7 @@ class Stare:
27
27
  radial_velocity: npt.NDArray[np.float64]
28
28
  mask: npt.NDArray[np.bool_]
29
29
  wavelength: float
30
+ system_id: str
30
31
 
31
32
  @classmethod
32
33
  def from_halo_data(
@@ -66,6 +67,8 @@ class Stare:
66
67
  .non_strictly_increasing_timesteps_removed()
67
68
  )
68
69
  raw, intensity_bg_corrected = _correct_background(raw, bg, bg_correction_method)
70
+ if len(raw.time) == 0:
71
+ raise doppy.exceptions.NoDataError("No matching data and bg files")
69
72
  intensity_noise_bias_corrected = _correct_intensity_noise_bias(
70
73
  raw, intensity_bg_corrected
71
74
  )
@@ -87,6 +90,7 @@ class Stare:
87
90
  radial_velocity=raw.radial_velocity,
88
91
  mask=mask,
89
92
  wavelength=wavelength,
93
+ system_id=raw.header.system_id,
90
94
  )
91
95
 
92
96
 
doppy/product/wind.py CHANGED
@@ -26,6 +26,7 @@ class Wind:
26
26
  meridional_wind: npt.NDArray[np.float64]
27
27
  vertical_wind: npt.NDArray[np.float64]
28
28
  mask: npt.NDArray[np.bool_]
29
+ system_id: str
29
30
 
30
31
  @functools.cached_property
31
32
  def horizontal_wind_speed(self) -> npt.NDArray[np.float64]:
@@ -93,6 +94,7 @@ class Wind:
93
94
  meridional_wind=wind[:, :, 1],
94
95
  vertical_wind=wind[:, :, 2],
95
96
  mask=mask,
97
+ system_id=raw.header.system_id,
96
98
  )
97
99
 
98
100
  @classmethod
@@ -147,6 +149,40 @@ class Wind:
147
149
  meridional_wind=wind[:, :, 1],
148
150
  vertical_wind=wind[:, :, 2],
149
151
  mask=mask,
152
+ system_id=raw.system_id,
153
+ )
154
+
155
+ @classmethod
156
+ def from_wls70_data(
157
+ cls,
158
+ data: Sequence[str]
159
+ | Sequence[Path]
160
+ | Sequence[bytes]
161
+ | Sequence[BufferedIOBase],
162
+ ) -> Wind:
163
+ raws = doppy.raw.Wls70.from_srcs(data)
164
+
165
+ if len(raws) == 0:
166
+ raise doppy.exceptions.NoDataError("Wls70 data missing")
167
+
168
+ raw = (
169
+ doppy.raw.Wls70.merge(raws)
170
+ .sorted_by_time()
171
+ .non_strictly_increasing_timesteps_removed()
172
+ )
173
+ mask = (
174
+ np.isnan(raw.meridional_wind)
175
+ | np.isnan(raw.zonal_wind)
176
+ | np.isnan(raw.vertical_wind)
177
+ )
178
+ return Wind(
179
+ time=raw.time,
180
+ height=raw.altitude,
181
+ zonal_wind=raw.zonal_wind,
182
+ meridional_wind=raw.meridional_wind,
183
+ vertical_wind=raw.vertical_wind,
184
+ mask=mask,
185
+ system_id=raw.system_id,
150
186
  )
151
187
 
152
188
 
doppy/raw/__init__.py CHANGED
@@ -2,5 +2,6 @@ from .halo_bg import HaloBg
2
2
  from .halo_hpl import HaloHpl
3
3
  from .halo_sys_params import HaloSysParams
4
4
  from .windcube import WindCube
5
+ from .wls70 import Wls70
5
6
 
6
- __all__ = ["HaloHpl", "HaloBg", "HaloSysParams", "WindCube"]
7
+ __all__ = ["HaloHpl", "HaloBg", "HaloSysParams", "WindCube", "Wls70"]
doppy/raw/halo_hpl.py CHANGED
@@ -8,7 +8,7 @@ from datetime import datetime, timedelta
8
8
  from io import BufferedIOBase
9
9
  from os.path import commonprefix
10
10
  from pathlib import Path
11
- from typing import Any, Sequence, TypeVar, cast
11
+ from typing import Any, Sequence, cast
12
12
 
13
13
  import numpy as np
14
14
  import numpy.typing as npt
@@ -16,8 +16,7 @@ from numpy import datetime64, timedelta64
16
16
 
17
17
  import doppy
18
18
  from doppy import exceptions
19
-
20
- T = TypeVar("T")
19
+ from doppy.utils import merge_all_equal
21
20
 
22
21
 
23
22
  @dataclass
@@ -258,18 +257,12 @@ class HaloHplHeader:
258
257
  )
259
258
 
260
259
 
261
- def _merger(key: str, lst: list[T]) -> T:
262
- if len(set(lst)) != 1:
263
- raise ValueError(f"Cannot merge header key {key} values {lst}")
264
- return lst[0]
265
-
266
-
267
260
  def _merge_headers(headers: list[HaloHplHeader]) -> HaloHplHeader:
268
261
  return HaloHplHeader(
269
262
  filename=commonprefix([h.filename for h in headers]),
270
263
  start_time=np.min([h.start_time for h in headers]),
271
264
  **{
272
- key: _merger(key, [getattr(h, key) for h in headers])
265
+ key: merge_all_equal(key, [getattr(h, key) for h in headers])
273
266
  for key in (
274
267
  "gate_points",
275
268
  "nrays",
doppy/raw/windcube.py CHANGED
@@ -10,6 +10,8 @@ import numpy.typing as npt
10
10
  from netCDF4 import Dataset, num2date
11
11
  from numpy import datetime64
12
12
 
13
+ from doppy.utils import merge_all_equal
14
+
13
15
 
14
16
  @dataclass
15
17
  class WindCube:
@@ -22,6 +24,7 @@ class WindCube:
22
24
  radial_velocity: npt.NDArray[np.float64] # dim: (time, radial_distance)
23
25
  radial_velocity_confidence: npt.NDArray[np.float64] # dim: (time, radial_distance)
24
26
  scan_index: npt.NDArray[np.int64]
27
+ system_id: str
25
28
 
26
29
  @classmethod
27
30
  def from_vad_srcs(
@@ -53,6 +56,7 @@ class WindCube:
53
56
  [r.radial_velocity_confidence for r in raws]
54
57
  ),
55
58
  cnr=np.concatenate([r.cnr for r in raws]),
59
+ system_id=merge_all_equal("system_id", [r.system_id for r in raws]),
56
60
  )
57
61
 
58
62
  def __getitem__(
@@ -75,6 +79,7 @@ class WindCube:
75
79
  radial_velocity_confidence=self.radial_velocity_confidence[index],
76
80
  cnr=self.cnr[index],
77
81
  scan_index=self.scan_index[index],
82
+ system_id=self.system_id,
78
83
  )
79
84
  raise TypeError
80
85
 
@@ -189,6 +194,7 @@ def _from_vad_src(nc: Dataset) -> WindCube:
189
194
  radial_velocity=np.concatenate(radial_wind_speed_list),
190
195
  radial_velocity_confidence=np.concatenate(radial_wind_speed_confidence_list),
191
196
  cnr=np.concatenate(cnr_list),
197
+ system_id=nc.instrument_name,
192
198
  )
193
199
 
194
200
 
doppy/raw/wls70.py ADDED
@@ -0,0 +1,192 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from datetime import datetime
5
+ from io import BufferedIOBase
6
+ from pathlib import Path
7
+ from typing import Any, Sequence
8
+
9
+ import numpy as np
10
+ import numpy.typing as npt
11
+ from numpy import datetime64
12
+
13
+ import doppy
14
+ from doppy import exceptions
15
+ from doppy.utils import merge_all_equal
16
+
17
+
18
+ @dataclass
19
+ class Wls70:
20
+ time: npt.NDArray[datetime64] # dim: (time, )
21
+ altitude: npt.NDArray[np.float64] # dim: (altitude, )
22
+ position: npt.NDArray[np.float64] # dim: (time, )
23
+ temperature: npt.NDArray[np.float64] # dim: (time, )
24
+ wiper: npt.NDArray[np.bool_] # dim: (time, )
25
+ cnr: npt.NDArray[np.float64] # dim: (time, altitude)
26
+ radial_velocity: npt.NDArray[np.float64] # dim: (time, altitude)
27
+ radial_velocity_deviation: npt.NDArray[np.float64] # dim: (time, altitude)
28
+ vh: npt.NDArray[np.float64] # dim: (time, altitude)
29
+ wind_direction: npt.NDArray[np.float64] # dim: (time, altitude)
30
+ zonal_wind: npt.NDArray[np.float64] # u := zonal wind?, dim: (time, altitude)
31
+ meridional_wind: npt.NDArray[
32
+ np.float64
33
+ ] # v := meridional wind?, dim: (time, altitude)
34
+ vertical_wind: npt.NDArray[np.float64] # w := vertical wind?, dim: (time, altitude)
35
+ system_id: str
36
+
37
+ @classmethod
38
+ def from_srcs(
39
+ cls,
40
+ data: Sequence[str]
41
+ | Sequence[Path]
42
+ | Sequence[bytes]
43
+ | Sequence[BufferedIOBase],
44
+ ) -> list[Wls70]:
45
+ if not isinstance(data, (list, tuple)):
46
+ raise TypeError("data should be list or tuple")
47
+ if all(isinstance(src, bytes) for src in data):
48
+ data_bytes = data
49
+ elif all(isinstance(src, str) for src in data):
50
+ data_bytes = []
51
+ for src in data:
52
+ with Path(src).open("rb") as f:
53
+ data_bytes.append(f.read())
54
+ elif all(isinstance(src, Path) for src in data):
55
+ data_bytes = []
56
+ for src in data:
57
+ with src.open("rb") as f:
58
+ data_bytes.append(f.read())
59
+ elif all(isinstance(src, BufferedIOBase) for src in data):
60
+ data_bytes = [src.read() for src in data]
61
+ else:
62
+ raise TypeError("Unexpected types in data")
63
+ raws = doppy.rs.raw.wls70.from_bytes_srcs(data_bytes)
64
+ try:
65
+ return [_raw_rs_to_wls70(r) for r in raws]
66
+ except RuntimeError as err:
67
+ raise exceptions.RawParsingError(err) from err
68
+
69
+ @classmethod
70
+ def from_src(cls, data: str | Path | bytes | BufferedIOBase) -> Wls70:
71
+ if isinstance(data, str):
72
+ path = Path(data)
73
+ with path.open("rb") as f:
74
+ data_bytes = f.read()
75
+ elif isinstance(data, Path):
76
+ with data.open("rb") as f:
77
+ data_bytes = f.read()
78
+ elif isinstance(data, bytes):
79
+ data_bytes = data
80
+ elif isinstance(data, BufferedIOBase):
81
+ data_bytes = data.read()
82
+ else:
83
+ raise TypeError("Unsupported data type")
84
+ try:
85
+ return _raw_rs_to_wls70(doppy.rs.raw.wls70.from_bytes_src(data_bytes))
86
+ except RuntimeError as err:
87
+ raise exceptions.RawParsingError(err) from err
88
+
89
+ def __getitem__(
90
+ self,
91
+ index: int
92
+ | slice
93
+ | list[int]
94
+ | npt.NDArray[np.int64]
95
+ | npt.NDArray[np.bool_]
96
+ | tuple[slice, slice],
97
+ ) -> Wls70:
98
+ if isinstance(index, (int, slice, list, np.ndarray)):
99
+ return Wls70(
100
+ time=self.time[index],
101
+ altitude=self.altitude,
102
+ position=self.position[index],
103
+ temperature=self.temperature[index],
104
+ wiper=self.wiper[index],
105
+ cnr=self.cnr[index],
106
+ radial_velocity=self.radial_velocity[index],
107
+ radial_velocity_deviation=self.radial_velocity_deviation[index],
108
+ vh=self.vh[index],
109
+ wind_direction=self.wind_direction[index],
110
+ zonal_wind=self.zonal_wind[index],
111
+ meridional_wind=self.meridional_wind[index],
112
+ vertical_wind=self.vertical_wind[index],
113
+ system_id=self.system_id,
114
+ )
115
+ raise TypeError
116
+
117
+ def sorted_by_time(self) -> Wls70:
118
+ sort_indices = np.argsort(self.time)
119
+ return self[sort_indices]
120
+
121
+ @classmethod
122
+ def merge(cls, raws: Sequence[Wls70]) -> Wls70:
123
+ return cls(
124
+ time=np.concatenate(tuple(r.time for r in raws)),
125
+ altitude=raws[0].altitude,
126
+ position=np.concatenate(tuple(r.position for r in raws)),
127
+ temperature=np.concatenate(tuple(r.temperature for r in raws)),
128
+ wiper=np.concatenate(tuple(r.wiper for r in raws)),
129
+ cnr=np.concatenate(tuple(r.cnr for r in raws)),
130
+ radial_velocity=np.concatenate(tuple(r.radial_velocity for r in raws)),
131
+ radial_velocity_deviation=np.concatenate(
132
+ tuple(r.radial_velocity_deviation for r in raws)
133
+ ),
134
+ vh=np.concatenate(tuple(r.vh for r in raws)),
135
+ wind_direction=np.concatenate(tuple(r.wind_direction for r in raws)),
136
+ zonal_wind=np.concatenate(tuple(r.zonal_wind for r in raws)),
137
+ meridional_wind=np.concatenate(tuple(r.meridional_wind for r in raws)),
138
+ vertical_wind=np.concatenate(tuple(r.vertical_wind for r in raws)),
139
+ system_id=merge_all_equal("system_id", [r.system_id for r in raws]),
140
+ )
141
+
142
+ def non_strictly_increasing_timesteps_removed(self) -> Wls70:
143
+ if len(self.time) == 0:
144
+ return self
145
+ mask = np.ones_like(self.time, dtype=np.bool_)
146
+ latest_time = self.time[0]
147
+ for i, t in enumerate(self.time[1:], start=1):
148
+ if t <= latest_time:
149
+ mask[i] = False
150
+ else:
151
+ latest_time = t
152
+ return self[mask]
153
+
154
+
155
+ def _raw_rs_to_wls70(
156
+ raw_rs: tuple[dict[str, Any], list[str], npt.NDArray[np.float64]],
157
+ ) -> Wls70:
158
+ info, cols, data = raw_rs
159
+ altitude = info["altitude"]
160
+ system_id = info["system_id"]
161
+ data = data.reshape(-1, len(cols))
162
+ time_ts = data[:, 0]
163
+ time = np.array([datetime64(datetime.utcfromtimestamp(ts)) for ts in time_ts])
164
+
165
+ position = data[:, 1]
166
+ temperature = data[:, 2]
167
+ wiper = np.array(np.isclose(data[:, 3], 1), dtype=np.bool_)
168
+ cnr = data[:, 4::8]
169
+ rws = data[:, 5::8]
170
+ rwsd = data[:, 6::8]
171
+ vh = data[:, 7::8]
172
+ direction = data[:, 8::8]
173
+ u = data[:, 9::8]
174
+ v = data[:, 10::8]
175
+ w = data[:, 11::8]
176
+
177
+ return Wls70(
178
+ time=time,
179
+ altitude=altitude,
180
+ position=position,
181
+ temperature=temperature,
182
+ wiper=wiper,
183
+ cnr=cnr,
184
+ radial_velocity=rws,
185
+ radial_velocity_deviation=rwsd,
186
+ vh=vh,
187
+ wind_direction=direction,
188
+ zonal_wind=u,
189
+ meridional_wind=v,
190
+ vertical_wind=w,
191
+ system_id=system_id,
192
+ )
doppy/rs.abi3.so CHANGED
Binary file
doppy/utils.py ADDED
@@ -0,0 +1,9 @@
1
+ from typing import TypeVar
2
+
3
+ T = TypeVar("T")
4
+
5
+
6
+ def merge_all_equal(key: str, lst: list[T]) -> T:
7
+ if len(set(lst)) != 1:
8
+ raise ValueError(f"Cannot merge header key {key} values {lst}")
9
+ return lst[0]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: doppy
3
- Version: 0.1.4
3
+ Version: 0.2.1
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Programming Language :: Python :: 3
6
6
  Classifier: Programming Language :: Python :: 3.10
@@ -13,7 +13,7 @@ Requires-Dist: requests
13
13
  Requires-Dist: urllib3
14
14
  Requires-Dist: numpy
15
15
  Requires-Dist: netcdf4
16
- Requires-Dist: typer[all]
16
+ Requires-Dist: typer
17
17
  Requires-Dist: matplotlib
18
18
  Requires-Dist: scikit-learn
19
19
  Requires-Dist: scipy
@@ -1,27 +1,29 @@
1
- doppy-0.1.4.dist-info/METADATA,sha256=oKScpypbKzChDTyTJPUPYD4_zGhyRbsdpw7eGgCaDi4,1794
2
- doppy-0.1.4.dist-info/WHEEL,sha256=Eyff-rEDSOF0Q7IZpSwsYe3r6zR3sNi9c9VlO0C9EVo,103
3
- doppy-0.1.4.dist-info/entry_points.txt,sha256=9b_Ca7vJoh6AwL3W8qAPh_UmJ_1Pa6hi-TDfCTDjvSk,43
4
- doppy-0.1.4.dist-info/license_files/LICENSE,sha256=V-0iroMNMI8ctnLgUau1kdFvwhkYhr9vi-5kWKxw2wc,1089
5
- doppy-0.1.4.dist-info/license_files/LICENSE,sha256=V-0iroMNMI8ctnLgUau1kdFvwhkYhr9vi-5kWKxw2wc,1089
1
+ doppy-0.2.1.dist-info/METADATA,sha256=0T7yh-b9uQUGEeBymLzElKfO6tw2QAlDqffDPUNda7k,1789
2
+ doppy-0.2.1.dist-info/WHEEL,sha256=Eyff-rEDSOF0Q7IZpSwsYe3r6zR3sNi9c9VlO0C9EVo,103
3
+ doppy-0.2.1.dist-info/entry_points.txt,sha256=9b_Ca7vJoh6AwL3W8qAPh_UmJ_1Pa6hi-TDfCTDjvSk,43
4
+ doppy-0.2.1.dist-info/license_files/LICENSE,sha256=V-0iroMNMI8ctnLgUau1kdFvwhkYhr9vi-5kWKxw2wc,1089
5
+ doppy-0.2.1.dist-info/license_files/LICENSE,sha256=V-0iroMNMI8ctnLgUau1kdFvwhkYhr9vi-5kWKxw2wc,1089
6
6
  doppy/options.py,sha256=73BDODO4OYHn2qOshhwz6u6G3J1kNd3uj6P0a3V4HBE,205
7
7
  doppy/__init__.py,sha256=Z9aEUlbPRWRUAoB8_-djkgrJuS4-6pjem4-mVSB6Z9I,191
8
- doppy/product/wind.py,sha256=k9VACH3HoAhoDr6TrC65wmWer7_un_YDxoKph_XQnsE,11133
8
+ doppy/product/wind.py,sha256=MAK-ZTx37gL7y-x3RbqN_QrZR9kjAiLxdIMn_c6M5UA,12151
9
9
  doppy/product/__init__.py,sha256=lyp88zs7GBk8uUzkj8lxaXPuYwPa52xXeTwf5qwFddU,103
10
- doppy/product/stare.py,sha256=LknHQLbilqjRohnrVmvZDEu4gV_gk2x3dBdCkHHTC8U,19733
10
+ doppy/product/stare.py,sha256=aMhOA5yXjcnwgzAp4GvLF1HT1cD-Zuqg9sEQIPlxWa0,19907
11
11
  doppy/bench.py,sha256=iVNYveMVGGRES2oe3Orsn31jQFCKTXOmxRFuFiJ8_OA,248
12
12
  doppy/netcdf.py,sha256=uEiJfqxXxHwe5ghT6OpIu8xeY1HgWDW1ENTBlFLOGtE,3416
13
+ doppy/utils.py,sha256=qPtIYBJPaKKTmRWwJI93TFUuhJg7CAoecpyHCm5ZyxI,214
13
14
  doppy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
15
  doppy/exceptions.py,sha256=1tljrtzp0McQhB6INFXj4yfLjxj6mXor5jLF9HZjp1A,138
15
16
  doppy/defaults.py,sha256=-il4DWU1HPttlGFoVQTPC7R4pDZERoPvt3kw6xwMKrw,38
16
17
  doppy/data/cache.py,sha256=2rxmkWFn-FPy2LNGuCW2Vu4KKLBwIV9sb2gPBA-Jfck,996
17
18
  doppy/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- doppy/data/api.py,sha256=QKKP-TYHjve-O3GNFKfjyAMYTcVLOTRPCSEg4D7Ax3k,1735
19
+ doppy/data/api.py,sha256=QaVKj304OPcu8OF5xgtduQzDis8Srn-I6UgR9qb2u9E,1863
19
20
  doppy/data/exceptions.py,sha256=6CS6OHIWq8CqlxiceEvC1j0EfWUYoIfM7dW88apQVn4,89
20
21
  doppy/raw/halo_sys_params.py,sha256=IXH40xBHyXCGX0ZE79KnSeXRj1wbqoqL0RYUQyBJqdE,3937
21
- doppy/raw/__init__.py,sha256=bIUObQPtOGStVoZRrDYyCVrWbGto0IGjm0s7JRY-E7Y,194
22
+ doppy/raw/__init__.py,sha256=AMHyONuH0aUJUQz20EhlANaq9UjWJtSZf7kWUVx3ZjA,228
23
+ doppy/raw/wls70.py,sha256=paFT8PddRemtiDAXxkZVcMljCq_CFw1DHmxLHXY0ZhE,7008
22
24
  doppy/raw/halo_bg.py,sha256=kO03yGlKS-DpMMGHYuy_BuidyeUL38TxT5vMn8H_8lE,4809
23
- doppy/raw/halo_hpl.py,sha256=_hq0JCNPuZrt3yt4U2KphKvJVNx_Uh4bnGfKbVPRGoA,18625
24
- doppy/raw/windcube.py,sha256=TVqR3SwfUJYHtPJXnA_b6uUGo_ylVkGGEPob63Zcee0,9685
25
+ doppy/raw/halo_hpl.py,sha256=VkWemJfGFu-tF-fkhjYwF6dCZPrNQanqL0NBFJVS-TQ,18485
26
+ doppy/raw/windcube.py,sha256=ZaOswQJbVDPBYj5oU1pTYmsX8F-mKIbjJRZmLYEMXP0,9906
25
27
  doppy/__main__.py,sha256=zrKQJVj0k0ypBQCGK65Czt9G9FZ_qx3ussw6Q9VJ14g,346
26
- doppy/rs.abi3.so,sha256=xReLvr5yy-AY_AyKt80-Gix6iSF8CAz2TkINuTSYqNg,2587709
27
- doppy-0.1.4.dist-info/RECORD,,
28
+ doppy/rs.abi3.so,sha256=ZL1C3AFu5SRDGfsmCXrJzL8yNxzDT4noGXkg7c1tlD0,2752832
29
+ doppy-0.2.1.dist-info/RECORD,,
File without changes