Source code for stilt.observations.observation

"""Normalized observation model."""

from __future__ import annotations

import datetime as dt
from dataclasses import dataclass, field
from typing import cast

import pandas as pd

from stilt.config import VerticalReference, validate_vertical_reference

from .geometry import HorizontalGeometry, LineOfSight, ViewingGeometry
from .operators import VerticalOperator
from .uncertainty import UncertaintyBudget


[docs] @dataclass(slots=True) class Observation: """ One normalized measurement record independent of raw file format. Observations can be constructed directly by external parsers or via ``Sensor.make_observation()`` helpers in ``stilt.observations``. """ sensor: str species: str time: pd.Timestamp | dt.datetime | str latitude: float longitude: float value: float | None = None units: str | None = None uncertainty: float | None = None uncertainty_budget: UncertaintyBudget | None = None observation_id: str | None = None platform: str | None = None altitude: float | None = None altitude_ref: VerticalReference = "agl" geometry: HorizontalGeometry | None = None line_of_sight: LineOfSight | None = None viewing: ViewingGeometry | None = None operator: VerticalOperator | None = None quality: dict[str, float | int | bool] = field(default_factory=dict) metadata: dict[str, object] = field(default_factory=dict) def __post_init__(self) -> None: parsed = pd.Timestamp(self.time) if parsed is pd.NaT: raise ValueError("Observation.time must be a valid timestamp.") self.time = cast(pd.Timestamp, parsed) self.altitude_ref = validate_vertical_reference(self.altitude_ref) if self.uncertainty is None and self.uncertainty_budget is not None: self.uncertainty = self.uncertainty_budget.total