Skip to content

Commit b24293a

Browse files
sync embedded/arc_tz_weather from arc_tz_weather
1 parent 434ef1a commit b24293a

3 files changed

Lines changed: 52 additions & 11 deletions

File tree

embedded/arc_tz_weather/index.html

Lines changed: 14 additions & 8 deletions
Large diffs are not rendered by default.

embedded/arc_tz_weather/modules/common.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,38 @@ def spike_filter(series, max_val):
295295
return series.where(series <= max_val)
296296

297297

298+
def peak_wind_qc(df):
299+
"""Apply quality control to peak_wind_kph in-place and return the DataFrame.
300+
301+
Two filters are applied:
302+
1. Reed switch bounce: peak_wind_kph / avg_wind_kph > 8 AND peak_wind_kph > 25.
303+
A ratio this extreme is physically implausible and indicates sensor artefact.
304+
Rows where avg == 0 and peak > 25 are treated as infinite ratio and flagged.
305+
2. Ceiling filter: peak_wind_kph > 100, regardless of average speed.
306+
307+
Flagged rows have peak_wind_kph replaced with NaN. avg_wind_kph is unaffected.
308+
A boolean column 'peak_wind_flagged' is added (True = flagged).
309+
310+
Args:
311+
df: DataFrame with columns avg_wind_kph and peak_wind_kph.
312+
Returns:
313+
The same DataFrame with peak_wind_kph cleaned and peak_wind_flagged added.
314+
"""
315+
import numpy as np
316+
317+
# Ratio-based bounce filter: peak > 8x average AND peak > 25 km/h.
318+
# Rows with avg == 0 and peak > 25 are treated as ratio-infinite, so flagged directly.
319+
zero_avg = df["avg_wind_kph"] == 0
320+
ratio = np.where(zero_avg, np.inf, df["peak_wind_kph"] / df["avg_wind_kph"].replace(0, np.nan))
321+
bounce_mask = (np.array(ratio) > 8) & (df["peak_wind_kph"] > 25)
322+
ceiling_mask = df["peak_wind_kph"] > 100
323+
flagged = bounce_mask | ceiling_mask
324+
325+
df["peak_wind_flagged"] = flagged
326+
df.loc[flagged, "peak_wind_kph"] = np.nan
327+
return df
328+
329+
298330
def compass_bin(degrees, n_points=16):
299331
"""Assign a compass direction label to a bearing in degrees."""
300332
dirs = COMPASS_DIRS_16 if n_points == 16 else COMPASS_DIRS_8

embedded/arc_tz_weather/modules/wind.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
COMPASS_DIRS_16, COMPASS_DIRS_8, WIND_SPEED_BINS, WIND_SPEED_LABELS,
1414
WIND_SPEED_COLORS, BEAUFORT_SCALE, VENTILATION_COLORS, WIND_CLASSIFICATIONS,
1515
KN_TO_KPH, TIMEZONE, CALM_THRESHOLD_KPH,
16-
spike_filter, compass_bin, beaufort_number, weibull_fit, to_eat_ms,
16+
peak_wind_qc, compass_bin, beaufort_number, weibull_fit, to_eat_ms,
1717
get_season_boundaries,
1818
)
1919

@@ -28,8 +28,11 @@ def process(df):
2828
"""
2929
wdf = df.copy()
3030

31-
# Apply spike filter to peak wind
32-
wdf["peak_wind_kph"] = spike_filter(wdf["peak_wind_kph"], 150)
31+
# Quality-control peak wind before any analysis:
32+
# - flag reed switch bounce (avg < 1.0 km/h and peak > 25 km/h)
33+
# - flag implausible ceiling (peak > 100 km/h)
34+
# Flagged values are set to NaN; avg_wind_kph is unchanged.
35+
wdf = peak_wind_qc(wdf)
3336

3437
# Compass direction labels
3538
wdf["compass_16"] = wdf["wind_dir"].apply(lambda d: compass_bin(d, 16))

0 commit comments

Comments
 (0)