Source code for stilt.config.transforms

from typing import Annotated, Any, Literal

from pydantic import BaseModel, Field, model_validator
from typing_extensions import Self


[docs] class VerticalOperatorTransformSpec(BaseModel): """Declarative built-in transform for applying a vertical operator.""" kind: Literal["vertical_operator"] = Field( description="Discriminator identifying this transform as a vertical operator.", ) mode: Literal["none", "uniform", "ak", "pwf", "ak_pwf", "integration", "tccon"] = ( Field( description="Built-in vertical-operator mode used to interpret the levels and values arrays." ) ) levels: list[float] = Field( default_factory=list, description="Vertical coordinates paired with the operator values.", ) values: list[float] = Field( default_factory=list, description="Operator values applied at the specified vertical levels.", ) pressure_levels: list[float] = Field( default_factory=list, description="Optional pressure grid used by pressure-based operator modes.", ) coordinate: str = Field( default="xhgt", description="Trajectory column used as the vertical coordinate when applying the operator.", ) metadata: dict[str, Any] = Field( default_factory=dict, description="Optional metadata stored alongside the transform specification.", ) @model_validator(mode="after") def _validate_operator_shape(self) -> Self: """Validate that operator level and value arrays have matching lengths.""" if self.mode not in {"none", "uniform"}: if not self.levels or not self.values: raise ValueError( "Vertical operator transforms require non-empty levels and " "values unless mode is 'none' or 'uniform'." ) if len(self.levels) != len(self.values): raise ValueError( "Vertical operator transform levels and values must have the " "same length." ) return self
[docs] class FirstOrderLifetimeTransformSpec(BaseModel): """Declarative built-in transform for first-order lifetime decay.""" kind: Literal["first_order_lifetime"] = Field( description="Discriminator identifying this transform as first-order lifetime decay.", ) lifetime_hours: float = Field( gt=0, description="E-folding lifetime, in hours, used for exponential decay.", ) time_column: str = Field( default="time", description="Trajectory column containing the elapsed transport time.", ) time_unit: str = Field( default="min", description="Unit for the trajectory time column, typically minutes or hours.", ) metadata: dict[str, Any] = Field( default_factory=dict, description="Optional metadata stored alongside the transform specification.", )
ParticleTransformSpec = Annotated[ VerticalOperatorTransformSpec | FirstOrderLifetimeTransformSpec, Field(discriminator="kind"), ]