011 — Weather station vs chamber

011 — Weather station vs chamber#

Cross-check the climate variables measured inside each chamber against the open-air weather station, to detect chamber-induced microclimate artifacts (e.g. solar heating, RH suppression). A well-vented chamber tracks ambient closely; large divergences suggest sensor drift, blocked ventilation, or condensation.

Runs on the bundled synthetic sample.

from pathlib import Path
import pandas as pd
import matplotlib.pyplot as plt

from palmwtc.config import DataPaths
from palmwtc.viz import set_style

set_style()
paths = DataPaths.resolve()
print(paths.describe())
DataPaths (source=sample (bundled synthetic), site=libz):
  raw_dir       = /home/runner/work/palmwtc/palmwtc/src/palmwtc/data/sample/synthetic
  processed_dir = /home/runner/work/palmwtc/palmwtc/src/palmwtc/data/sample/Data/Integrated_QC_Data
  exports_dir   = /home/runner/work/palmwtc/palmwtc/src/palmwtc/data/sample/exports
  config_dir    = /home/runner/work/palmwtc/palmwtc/src/palmwtc/data/sample/config
  extras        = <none>
# Load chamber QC parquet and weather CSV.
qc_path = paths.raw_dir / "QC_Flagged_Data_synthetic.parquet"
weather_path = paths.raw_dir / "weather_30min.csv"

if not qc_path.exists():
    from palmwtc.io import find_latest_qc_file
    qc_path = Path(find_latest_qc_file(processed_dir=paths.processed_dir))

chamber = pd.read_parquet(qc_path, columns=["TIMESTAMP", "Temp_1_C1", "Temp_1_C2", "RH_1_C1", "RH_1_C2"])
weather = pd.read_csv(weather_path, parse_dates=["TIMESTAMP"])
print(f"Chamber: {len(chamber)} rows | Weather: {len(weather)} rows")
Chamber: 20160 rows | Weather: 336 rows

Compare temperature#

fig, ax = plt.subplots(figsize=(10, 4))
ax.plot(weather["TIMESTAMP"], weather["AirTC_Avg"], label="Weather (open air)", lw=1.2)
ax.plot(chamber["TIMESTAMP"][::60], chamber["Temp_1_C1"][::60], label="Chamber 1 (every 30 min)", alpha=0.6)
ax.plot(chamber["TIMESTAMP"][::60], chamber["Temp_1_C2"][::60], label="Chamber 2 (every 30 min)", alpha=0.6)
ax.set_xlabel("Time")
ax.set_ylabel("Temperature (°C)")
ax.set_title("Temperature: chamber vs open-air weather")
ax.legend()
plt.tight_layout()
plt.show()
../_images/a2b8300675380c44ee122c7d2f6a535933bf435f5e3db4da3cbe35aef55b1864.png

A 1-2 °C offset between chamber and ambient is normal during the day (chamber walls heat slightly under direct sun). Persistent > 5 °C divergence is a red flag for ventilation or shading issues.