tephpy.sounding =============== .. py:module:: tephpy.sounding .. autoapi-nested-parse:: The ``Sounding`` data model (spec §3.4). A :class:`Sounding` is a frozen dataclass holding one ascent's pressure/temperature/dewpoint/wind arrays as pint quantities on MetPy's registry, plus optional station/time metadata and a derived legend label. Inputs are coerced and validated at construction — bad data fails at ingest, not mid-plot (spec §6) — and pressure is normalized to decreasing (surface-first) storage with all arrays reversed together, so downstream ``metpy.calc`` sees one orientation. The pandas/xarray constructors consume the objects handed to them — neither library is imported at runtime — so ``import tephpy`` stays light (spec §10 item 10). .. !! processed by numpydoc !! Classes ------- .. autoapisummary:: tephpy.sounding.Sounding Module Contents --------------- .. py:class:: Sounding One sounding: quantified profile arrays plus metadata (spec §3.4). Pressure and temperature are required; dewpoint and wind are optional, and the two wind fields must arrive together. Bare arrays need the ``units=`` mapping; a constructed Sounding always holds pint quantities on MetPy's registry, with pressure stored decreasing (surface-first). NaN gaps are data everywhere except pressure. :Attributes: **pressure** : :obj:`pint.Quantity` Level pressures; required, finite, and strictly monotonic (either direction accepted, normalized to decreasing). **temperature** : :obj:`pint.Quantity` Level temperatures; required. **dewpoint** : :obj:`pint.Quantity` or :data:`python:None` Level dewpoints; where dewpoint and temperature are both non-NaN, dewpoint above temperature is rejected (equality — saturation — is physical). **wind_speed** : :obj:`pint.Quantity` or :data:`python:None` Level wind speeds; requires `wind_direction`. **wind_direction** : :obj:`pint.Quantity` or :data:`python:None` Level wind directions (degrees from north); requires `wind_speed`. **station** : :class:`python:str` or :data:`python:None` Station identifier, e.g. ``"72357"``. **time** : :obj:`datetime.datetime` or :data:`python:None` Launch time; ``numpy.datetime64`` input is accepted, naive datetimes are read as UTC, and aware ones are converted to UTC. **label** : :class:`python:str` or :data:`python:None` Legend text. When not given it derives as e.g. ``"72357 2013-05-20 12Z"`` if both `station` and `time` are present, else ``None`` — and ``None`` means no legend entry. **units** : mapping of :class:`python:str` to :class:`python:str`, optional Construction-only (not stored): unit strings for bare-array fields, keyed by field name, e.g. ``units={"pressure": "hPa", "temperature": "degC"}`` (spec §5). .. !! processed by numpydoc !! .. py:attribute:: pressure :type: pint.Quantity .. py:attribute:: temperature :type: pint.Quantity .. py:attribute:: dewpoint :type: pint.Quantity | None :value: None .. py:attribute:: wind_speed :type: pint.Quantity | None :value: None .. py:attribute:: wind_direction :type: pint.Quantity | None :value: None .. py:attribute:: station :type: str | None :value: None .. py:attribute:: time :type: datetime.datetime | None :value: None .. py:attribute:: label :type: str | None :value: None .. py:attribute:: units :type: dataclasses.InitVar[collections.abc.Mapping[str, str] | None] :value: None .. py:method:: from_dataframe(df: pandas.DataFrame, *, units: collections.abc.Mapping[str, str] | None = None, station: str | None = None, time: datetime.datetime | None = None, label: str | None = None, **column_map: str) -> Sounding :classmethod: Build a sounding from a pandas DataFrame (spec §3.4). Column names default to the field names; `column_map` overrides per field (e.g. ``dewpoint="dwpt"``). Columns are bare arrays, so the present fields need the ``units=`` mapping. :Parameters: **df** : :obj:`pandas.DataFrame` The profile table; must contain pressure and temperature columns. **units** : mapping of :class:`python:str` to :class:`python:str`, optional Unit strings keyed by field name (spec §5). **station** : :class:`python:str`, optional Station identifier. **time** : :obj:`datetime.datetime`, optional Launch time; ``pandas.Timestamp`` and ``numpy.datetime64`` are accepted. **label** : :class:`python:str`, optional Legend text override. **\*\*column_map** : :class:`python:str` Field names mapped to their column names in `df`. :Returns: :obj:`Sounding ` The validated sounding. :Raises: :obj:`KeyError` If a required or explicitly mapped column is missing. :obj:`TypeError` If `column_map` names an unknown field. .. !! processed by numpydoc !! .. py:method:: from_dataset(ds: xarray.Dataset, *, units: collections.abc.Mapping[str, str] | None = None, station: str | None = None, time: datetime.datetime | None = None, label: str | None = None, **var_map: str) -> Sounding :classmethod: Build a sounding from an xarray Dataset (spec §3.4). Variable names default to the field names; `var_map` overrides per field. Units are read from each variable's ``attrs["units"]`` (the xarray/CF convention); the ``units=`` mapping is the explicit override. :Parameters: **ds** : :obj:`xarray.Dataset` The profile dataset; must contain pressure and temperature variables. **units** : mapping of :class:`python:str` to :class:`python:str`, optional Unit strings keyed by field name, overriding ``attrs["units"]``. **station** : :class:`python:str`, optional Station identifier. **time** : :obj:`datetime.datetime`, optional Launch time; ``pandas.Timestamp`` and ``numpy.datetime64`` are accepted. **label** : :class:`python:str`, optional Legend text override. **\*\*var_map** : :class:`python:str` Field names mapped to their variable names in `ds`. :Returns: :obj:`Sounding ` The validated sounding. :Raises: :obj:`KeyError` If a required or explicitly mapped variable is missing. :obj:`TephpyUnitsError ` If a field has neither ``attrs["units"]`` nor a ``units=`` entry. :obj:`TypeError` If `var_map` names an unknown field. .. !! processed by numpydoc !!