Metadata-Version: 2.4
Name: sdatmospheric
Version: 0.1.0
Summary: Easy lat/lon/altitude queries against NOAA HRRR/GFS weather data for rocketry.
Author: Michael Karpov
License: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: herbie-data>=2024.8
Requires-Dist: xarray>=2023.1
Requires-Dist: cfgrib>=0.9.14
Requires-Dist: numpy>=1.24
Requires-Dist: pandas>=2.0
Requires-Dist: pyproj>=3.5

# SDAtmospheric

This package allows for arbitrary data decoding for variables related to high powered rocketry by querying HRRR and GFS data above the continental united states

## Install

`cfgrib` needs the `eccodes` C library. Easiest on conda-forge:

```bash
conda install -c conda-forge eccodes cfgrib herbie-data
pip install -e .
```

Pip-only (Linux/macOS or recent Windows with eccodes wheels):

```bash
pip install eccodes
pip install -e .
```

## Basic usage

The SDAtmospheric API is built around the `Atmosphere` class, which represents a snapshot of the atmospheric model above the continental US at any given time. The `Atmosphere` class provides only two methods:

```python
from sdatmospheric import Atmosphere
atmos = Atmosphere()

atmos.q(LATITUDE, LONGITUDE)        # Returns a `State` function closure (described below)
atmost.preload(LATITUDE, LONGITUDE) # Preloads a certain GRIB grid square around a given point
```

In reality, the `Atmosphere` class is lazy, and only loads wind data for the times and the regions directly queried by the host application. Because GRIB downloads and decoding is an involved process, we implement the use of 2 caching levels:
- *Hot Caching*, where the data for a given location is stored within program memory, so queries within a region that is hot cached requires only a program memory lookup (~50ms)
- *Warm Caching*, which will store GRIB regions on disk and allow for a relatively quick disk lookup rather than a redownload from the NOAA servers (~3s)

Full cache misses will trigger a download from the NOAA servers, which (depending on server traffic) can take a few minutes.

## State Return

The return type of `Atmosphere.q` is a `State`-returning function closure. This means that `Atmosphere.q` returns a function `f` that, given an altitude, returns a `State` object.

```python
class State(NamedTuple):
    u: float        # east wind, m/s
    v: float        # north wind, m/s
    T: float        # K
    rho: float      # kg/m^3
    P: float        # Pa
    mach_v: float   # m/s, speed of sound
```

## Models

```python
Atmosphere(model="hrrr") # 3km spatial resolution, 1h temporal up to 48h, 20km ceiling
Atmosphere(model="gfs") # 0.25 degree spatial resolution, 6h temporal up to 384h, 50km ceiling 
Atmosphere(model="blend") # Blends between the hrrr and gfs models
Atmosphere(model="blend", blend_range=(15_000, 19_000)) # Adjusable blending range (default 17km)
```

## Forecasting

The analysis time defaults to the latest available analysis for the given model. This can be overridden to provide future (and past) analyses of weather data at a location.

```python
Atmosphere(time="2025-08-03T12:00Z") # Specific time
Atmosphere(forecast_hours=3) # Forecast 3h in the future
```

## Conventions

- **Altitude:** MSL by default. `alt_ref="agl"` subtracts surface elevation at the query point.
- **Longitude:** accept within CONUS
- **Ceiling:** altitudes above the top pressure level emit a `UserWarning` and extrapolate based on a linear fit
- **Cache:** herbie stores subset GRIBs under `~/data/` by default, and can be overridden with `cache_dir=...`.
