Skip to content

Commit 360b9c2

Browse files
committed
put all processing functions in one file
1 parent bfc6ce5 commit 360b9c2

File tree

3 files changed

+114
-143
lines changed

3 files changed

+114
-143
lines changed

scripts/process_level_1.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@
33
import yaml
44
import xarray as xr
55
import shutil
6-
from src.process_lev0 import (
6+
from src.process import (
77
radiometer,
88
radar,
99
iwv,
1010
add_georeference,
11-
)
12-
from src.process_lev1 import (
1311
correct_radar_height,
1412
filter_radar,
1513
add_masks_radar,
Lines changed: 113 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,119 @@
1717
config = json.load(f)
1818

1919

20+
def _bahamas_fix_time(ds):
21+
"""Fix time coordinate of BAHAMAS datasets."""
22+
return ds.rename({"tid": "time", "TIME": "time"}).set_index(time="time")
23+
24+
25+
def _radar_fix_time(ds):
26+
"""Fix time coordinate of RADAR moments datasets."""
27+
datetime = (
28+
np.datetime64("1970-01-01", "ns")
29+
+ ds.time.values * np.timedelta64(1, "s")
30+
+ ds.microsec.values * np.timedelta64(1, "us")
31+
)
32+
33+
return ds.assign(time=datetime).drop_vars("microsec")
34+
35+
36+
def _radar_add_dBZ(ds):
37+
"""Add reflectivity in dB."""
38+
ds = ds.assign(
39+
dBZg=lambda dx: 10 * np.log10(dx.Zg),
40+
dBZe=lambda dx: 10 * np.log10(dx.Ze),
41+
)
42+
ds.dBZg.attrs = {
43+
"units": "dBZg",
44+
"long_name": "Decadal logarithm of equivalent radar reflectivity of all targets (Zg)",
45+
}
46+
ds.dBZe.attrs = {
47+
"units": "dBZe",
48+
"long_name": "Decadal logarithm of equivalent radar reflectivity of hydrometeors (Ze)",
49+
}
50+
51+
return ds
52+
53+
54+
def _fix_radiometer_time(ds):
55+
"""Replace duplicates in time coordinate of radiometer datasets with correct time and ensure 4Hz frequency."""
56+
57+
# replace duplicate values
58+
time_broken = ds.time.values
59+
first_occurence = time_broken[0]
60+
n = 0
61+
time_new = []
62+
for i in range(len(time_broken)):
63+
if time_broken[i] == first_occurence:
64+
time_new.append(time_broken[i] + pd.Timedelta("0.25s") * n)
65+
n += 1
66+
else:
67+
n = 1
68+
first_occurence = time_broken[i]
69+
time_new.append(first_occurence)
70+
71+
ds = ds.assign_coords(time=time_new).sortby("time").drop_duplicates("time")
72+
73+
# ensure 4Hz frequency
74+
start_time = ds.time.min().values
75+
end_time = ds.time.max().values
76+
time_expected = pd.date_range(start=start_time, end=end_time, freq="0.25s")
77+
ds = ds.reindex(time=time_expected, fill_value=np.nan)
78+
79+
return ds
80+
81+
82+
def add_georeference(ds, lat, lon, plane_pitch, plane_roll, plane_altitude, source):
83+
"""Add georeference information to dataset."""
84+
ds = ds.assign(
85+
plane_altitude=plane_altitude.sel(time=ds.time, method="nearest").assign_coords(
86+
time=ds.time
87+
),
88+
lat=lat.sel(time=ds.time, method="nearest").assign_coords(time=ds.time),
89+
lon=lon.sel(time=ds.time, method="nearest").assign_coords(time=ds.time),
90+
plane_roll=plane_roll.sel(time=ds.time, method="nearest").assign_coords(
91+
time=ds.time
92+
),
93+
plane_pitch=plane_pitch.sel(time=ds.time, method="nearest").assign_coords(
94+
time=ds.time
95+
),
96+
)
97+
ds.attrs["georeference source"] = source
98+
return ds
99+
100+
101+
def bahamas(ds):
102+
"""Post-processing of BAHAMAS datasets."""
103+
return ds.pipe(
104+
_bahamas_fix_time,
105+
)
106+
107+
108+
def radiometer(ds):
109+
"""Post-processing of radiometer datasets."""
110+
return (
111+
ds.rename(number_frequencies="frequency")
112+
.set_index(frequency="Freq")
113+
.pipe(
114+
_fix_radiometer_time,
115+
)
116+
)
117+
118+
119+
def iwv(ds):
120+
"""Post-processing of IWV datasets."""
121+
return ds.pipe(_fix_radiometer_time)
122+
123+
124+
def radar(ds):
125+
"""Post-processing of Radar quick look datasets."""
126+
return ds.pipe(
127+
_radar_fix_time,
128+
).pipe(
129+
_radar_add_dBZ,
130+
)
131+
132+
20133
def _selective_where(ds, condition):
21134
"""
22135
Apply where to dataset but do not touch georeference data which should not be masked
@@ -419,31 +532,6 @@ def add_masks_radar(ds, sea_land_mask):
419532
)
420533

421534

422-
def filter_spikes(ds, threshold=5, window=1200):
423-
"""
424-
Filters out spikes in a time series by comparing the difference between each point
425-
and the minimum of the surrounding 5 minutes.
426-
427-
Parameters
428-
----------
429-
ds : xr.DataArray
430-
DataArray to filter.
431-
threshold : float
432-
Maximum allowed difference between the data and the minimum within the window.
433-
window : int
434-
Size of the window in seconds to compare the data, default is 5 minutes.
435-
436-
Returns
437-
-------
438-
xr.DataArray
439-
Filtered DataArray.
440-
"""
441-
diff = ds - ds.rolling(time=window, center=True, min_periods=1).min()
442-
filtered = ds.where(abs(diff) < threshold)
443-
interpolated = filtered.interpolate_na("time", method="linear")
444-
return xr.where(abs(diff) < threshold, ds, interpolated)
445-
446-
447535
def correct_radar_height(ds):
448536
"""Correct radar range gates with HALO flight altitude to height above WGS84 ellipsoid.
449537

src/process_lev0.py

Lines changed: 0 additions & 115 deletions
This file was deleted.

0 commit comments

Comments
 (0)