Metadata-Version: 2.4
Name: forkairos
Version: 0.1.3
Summary: Operational pipeline for meteorological forcing data in CF-compliant NetCDF
Author-email: Cristóbal Reyes <cristobal.sarda@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/Jano01/forkairos
Project-URL: Documentation, https://forkairos.readthedocs.io
Project-URL: Repository, https://github.com/Jano01/forkairos
Project-URL: Issues, https://github.com/Jano01/forkairos/issues
Keywords: hydrology,meteorology,NWP,forcing,NetCDF,ERA5,GFS,ECMWF
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
Classifier: Topic :: Scientific/Engineering :: Hydrology
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: xarray>=2024.1.0
Requires-Dist: geopandas>=0.14.0
Requires-Dist: netcdf4>=1.6.0
Requires-Dist: requests>=2.31.0
Requires-Dist: tqdm>=4.66.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: openmeteo-requests>=1.1.0
Requires-Dist: requests-cache>=1.1.0
Requires-Dist: retry-requests>=2.0.0
Requires-Dist: cdsapi>=0.6.0
Requires-Dist: cfgrib>=0.9.10
Requires-Dist: scipy>=1.12.0
Requires-Dist: numpy>=1.26.0
Requires-Dist: pandas>=2.2.0
Requires-Dist: ecmwf-opendata>=0.3.0
Dynamic: license-file

# forkairos

**Operational pipeline for meteorological forcing data in CF-compliant NetCDF**

forkairos downloads NWP forecast and reanalysis data from free providers for any
user-defined watershed, and delivers CF-compliant NetCDF files ready for
hydrological or land surface models. Variable names, units, and metadata are
standardized across all providers — the output format is always the same,
regardless of the data source.

## Installation
```bash
pip install forkairos
```

## Quick start
```python
from forkairos import run, get_provider

# See what a provider offers
provider = get_provider("open_meteo")
print(provider.available_variables())
print(provider.available_date_range())
print(provider.available_frequencies())

# Download data for a watershed
ds = run(
    shapefile="my_basin.shp",
    provider_name="open_meteo",
    variables=["temperature_2m", "precipitation", "snowfall",
               "wind_speed_10m", "shortwave_radiation", "longwave_radiation"],
    start="2024-06-01",
    end="2024-06-30",
    freq="1h",
    buffer_km=10.0,
    output_path="output.nc",
)
print(ds)
```

## Providers

| Provider | Mode | Resolution | Credentials |
|---|---|---|---|
| `open_meteo` | forecast + reanalysis | 0.25° / hourly | none |
| `era5` | reanalysis | 0.25° / hourly | CDS (free) |
| `gfs` | forecast | 0.25° / hourly | none |
| `ecmwf_open` | forecast | 0.25° / hourly | none |

## Canonical variable vocabulary

All providers use the same variable names in the output NetCDF:

| Variable | Description | Units |
|---|---|---|
| `temperature_2m` | Air temperature at 2m | °C |
| `dewpoint_2m` | Dewpoint temperature at 2m | °C |
| `precipitation` | Total precipitation | mm |
| `snowfall` | Snowfall amount | mm w.e. |
| `snow_depth` | Snow depth | m |
| `relative_humidity_2m` | Relative humidity at 2m | % |
| `wind_speed_10m` | Wind speed at 10m | m/s |
| `wind_u_10m` | U-component of wind at 10m | m/s |
| `wind_v_10m` | V-component of wind at 10m | m/s |
| `wind_direction_10m` | Wind direction at 10m | ° |
| `surface_pressure` | Surface pressure | hPa |
| `shortwave_radiation` | Downwelling shortwave radiation | W/m² |
| `longwave_radiation` | Downwelling longwave radiation | W/m² |
| `cloud_cover` | Total cloud cover | % |
| `geopotential_height_500hPa` | Geopotential height at 500 hPa | m |
| `geopotential_height_700hPa` | Geopotential height at 700 hPa | m |
| `geopotential_height_850hPa` | Geopotential height at 850 hPa | m |

Not all variables are available from every provider. Use `provider.available_variables()`
to check what is available before downloading.

## Optional post-processing

forkairos includes two optional post-processing steps that can be applied
independently after downloading. Both are modular — new methods can be added
as plugins in future versions.

### Spatial regridding

NWP data is typically available at coarse resolutions (0.25°, ~25 km). For
hydrological applications over complex terrain such as the Andes, finer
spatial resolution is often required.

forkairos implements **bilinear interpolation** to regrid data to a
user-specified target resolution. The target resolution should be chosen
based on the digital elevation model (DEM) used in the downstream model.
```python
from forkairos.processing import regrid, resolution_guide

# Print recommended resolutions based on common DEMs
resolution_guide()

# Regrid to 0.05° (~5 km)
ds_fine = regrid(ds, resolution=0.05)
```

> **Note:** Bilinear interpolation does not account for topographic effects
> on temperature lapse rates or orographic precipitation enhancement. For
> applications requiring physically consistent downscaling, the regridded
> output should be combined with a topographic correction scheme applied
> externally (e.g. Liston & Elder, 2006; Fiddes & Gruber, 2014).

### Bias correction

NWP models exhibit systematic biases that can affect the performance of
downstream hydrological models. forkairos implements **Quantile Delta
Mapping (QDM)** (Cannon et al., 2015), a method that corrects the
cumulative distribution function of model output while preserving the
model's projected changes (deltas). QDM is preferred over standard
Quantile Mapping (QM) because it does not distort model trends.

The correction requires a reference observational dataset (e.g. CR2MET
for the Andes, ERA5-Land for global applications) provided as a
CF-compliant NetCDF file.
```python
from forkairos.processing import bias_correct

# Load your reference dataset
import xarray as xr
ds_ref = xr.open_dataset("cr2met_reference.nc")

# Apply QDM bias correction
ds_corrected = bias_correct(ds, reference=ds_ref, method="qdm")
```

**References**

- Cannon, A. J., Sobie, S. R., & Murdock, T. Q. (2015). Bias correction of
  GCM precipitation by quantile mapping: How well do methods preserve
  changes in quantiles and extremes? *Journal of Climate*, 28(17), 6938–6959.
  https://doi.org/10.1175/JCLI-D-14-00754.1

- Fiddes, J., & Gruber, S. (2014). TopoSCALE v.1.0: downscaling gridded
  climate data in complex terrain. *Geoscientific Model Development*, 7,
  387–405. https://doi.org/10.5194/gmd-7-387-2014

- Liston, G. E., & Elder, K. (2006). A meteorological distribution system
  for high-resolution terrestrial modeling (MicroMet). *Journal of
  Hydrometeorology*, 7(2), 217–234.
  https://doi.org/10.1175/JHM486.1```

## ERA5 credentials

ERA5 requires a free account at the
[Copernicus Climate Data Store](https://cds.climate.copernicus.eu).
After registering, create a file `~/.cdsapirc` with your credentials:
```
url: https://cds.climate.copernicus.eu/api
key: YOUR-API-KEY
```

## License

MIT — see [LICENSE](LICENSE)

## Citation

If you use forkairos in your research, please cite it using the metadata
available in the GitHub repository.
