Skip to content

Commit

Permalink
Support Jülich weather station
Browse files Browse the repository at this point in the history
  • Loading branch information
siiptuo committed Jan 29, 2025
1 parent 6689d1b commit 24ffdc6
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 1 deletion.
50 changes: 49 additions & 1 deletion cloudnetpy/instruments/weather_station.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ def ws2nc(
ws = HyytialaWS(weather_station_file, site_meta)
elif site_meta["name"] == "Galați":
ws = GalatiWS(weather_station_file, site_meta)
elif site_meta["name"] == "Jülich":
ws = JuelichWS(weather_station_file, site_meta)
else:
msg = "Unsupported site"
raise ValueError(msg) # noqa: TRY301
Expand Down Expand Up @@ -87,7 +89,7 @@ def __init__(self, site_meta: dict):
date: list[str]

def calculate_rainfall_amount(self) -> None:
if "rainfall_amount" in self.data:
if "rainfall_amount" in self.data or "rainfall_rate" not in self.data:
return
resolution = np.median(np.diff(self.data["time"].data)) * SEC_IN_HOUR
rainfall_amount = ma.cumsum(self.data["rainfall_rate"].data * resolution)
Expand Down Expand Up @@ -116,6 +118,8 @@ def convert_temperature_and_humidity(self) -> None:
self.data["relative_humidity"].data = self.data["relative_humidity"][:] / 100

def convert_rainfall_rate(self) -> None:
if "rainfall_rate" not in self.data:
return
rainfall_rate = self.data["rainfall_rate"][:]
self.data["rainfall_rate"].data = rainfall_rate / 60 / 1000 # mm/min -> m/s

Expand Down Expand Up @@ -438,3 +442,47 @@ def add_data(self) -> None:
def convert_pressure(self) -> None:
mmHg2Pa = 133.322
self.data["air_pressure"].data = self.data["air_pressure"][:] * mmHg2Pa


class JuelichWS(WS):
def __init__(self, filenames: list[str], site_meta: dict):
super().__init__(site_meta)
self.filename = filenames[0]
self._data = self._read_data()

def _read_data(self) -> dict:
keymap = {
"TIMESTAMP": "time",
"AirTC_Avg": "air_temperature",
"RH": "relative_humidity",
"BV_BP_Avg": "air_pressure",
"WS_ms_S_WVT": "wind_speed",
"WindDir_D1_WVT": "wind_direction",
}
expected_units = {
"AirTC_Avg": "Deg C",
"RH": "%",
"BV_BP_Avg": "hPa",
"WS_ms_S_WVT": "meters/Second",
"WindDir_D1_WVT": "Deg",
}
units, process, rows = read_toa5(self.filename)
for key in units:
if key in expected_units and expected_units[key] != units[key]:
msg = (
f"Expected {key} to have units {expected_units[key]},"
f" got {units[key]} instead"
)
raise ValueError(msg)

data: dict[str, list] = {keymap[key]: [] for key in units if key in keymap}
for row in rows:
for key, value in row.items():
if key not in keymap:
continue
parsed = value
if keymap[key] != "time":
parsed = float(value)
data[keymap[key]].append(parsed)

return self.format_data(data)
13 changes: 13 additions & 0 deletions tests/unit/data/ws/20250127_JOYCE_WST_01m.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"TOA5","JOYCE_WST","CR300","16480","CR310.Std.10.07","CPU:joyce_20240403.CR300","19693","JOYCE_WST_01m"
"TIMESTAMP","RECORD","AirTC_Avg","RH","WS_ms_S_WVT","WindDir_D1_WVT","WS_ms_Max","WSDiag","BV_BP_Avg","BV_Temp_Avg","BV_Qual_Min","BattV_Avg","PTemp_C_Avg","BV_BP_SL_Avg"
"TS","RN","Deg C","%","meters/Second","Deg","meters/Second","unitless","hPa","deg C","unitless","Volts","Deg C","hPa"
"","","Avg","Smp","WVc","WVc","Max","Smp","Avg","Avg","Min","Avg","Avg","Avg"
"2025-01-27 00:01:00",429741,9.77,72.09,3.182,133.7,3.89,0,982.1,8.12,6.88,13.78,16.03,995.3639
"2025-01-27 00:02:00",429742,9.78,72.16,2.84,141.7,3.39,0,982.1,8.14,6.87,13.78,16.05,995.3639
"2025-01-27 00:03:00",429743,9.77,72.17,2.978,150.8,4.02,0,982.1,8.15,6.87,13.76,16.06,995.3639
"2025-01-27 00:04:00",429744,9.75,72.18,2.032,131,3.34,0,982.0583,8.16,6.87,13.78,16.07,995.3223
"2025-01-27 00:05:00",429745,9.75,72.22,2.335,140.6,2.79,0,982,8.17,6.88,13.78,16.08,995.2639
"2025-01-27 00:06:00",429746,9.74,72.22,2.575,147.2,3.4,0,982,8.19,6.89,13.79,16.1,995.2639
"2025-01-27 00:07:00",429747,9.74,72.23,2.626,137.4,3.57,0,981.925,8.2,6.88,13.78,16.11,995.189
"2025-01-27 00:08:00",429748,9.74,72.25,3.228,138.3,4.23,0,981.9,8.21,6.88,13.81,16.12,995.1639
"2025-01-27 00:09:00",429749,9.74,72.24,2.337,124.8,3.76,0,981.8667,8.22,6.88,13.82,16.13,995.1306
16 changes: 16 additions & 0 deletions tests/unit/test_weather_station.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,17 @@ def test_wind_direction_values(self):
assert max_wind_dir <= 360

def test_rainfall_rate_values(self):
if "rainfall_rate" not in self.nc.variables:
return
assert self.nc.variables["rainfall_rate"].units == "m s-1"
min_rainfall = ma.min(self.nc.variables["rainfall_rate"][:])
max_rainfall = ma.max(self.nc.variables["rainfall_rate"][:])
assert min_rainfall >= 0
assert max_rainfall <= 1.4e-6

def test_rainfall_amount(self):
if "rainfall_amount" not in self.nc.variables:
return
assert self.nc.variables["rainfall_amount"][0] == 0.0
assert (np.diff(self.nc.variables["rainfall_amount"][:]) >= 0).all()

Expand Down Expand Up @@ -203,6 +207,18 @@ def test_dimensions(self):
assert self.nc.dimensions["time"].size == 48


class TestWeatherStationJuelich(WS):
date = "2025-01-27"
temp_dir = TemporaryDirectory()
temp_path = temp_dir.name + "/test.nc"
site_meta = {**SITE_META, "name": "Jülich"}
filename = f"{SCRIPT_PATH}/data/ws/20250127_JOYCE_WST_01m.dat"
uuid = weather_station.ws2nc(filename, temp_path, site_meta, date=date)

def test_dimensions(self):
assert self.nc.dimensions["time"].size == 9


@pytest.mark.parametrize(
"original, expected",
[
Expand Down

0 comments on commit 24ffdc6

Please sign in to comment.