Skip to main content

fluxfootprints

fluxfootprints is a Python package for micrometeorological flux-footprint analysis. It bundles several footprint models — the Kljun et al. (2015) parameterisation, the Kormann & Meixner (2001) and Wang et al. (2006) analytical models, and a backward Lagrangian stochastic particle model — behind one consistent interface, together with tooling to build footprint climatologies from eddy-covariance tower data, summarise them by day and month, and export the results as GeoPackages, GeoTIFFs, and CSV statistics.


Table of Contents

  1. Installation
  2. Documentation
  3. Quick-start Example
  4. Available Models
  5. Input Requirements
  6. Beyond the Climatology
  7. Citing & Referencing
  8. Contributing
  9. Development Road-map
  10. License

Installation

# Stable release (PyPI)
pip install fluxfootprints

# Development version (GitHub)
pip install git+https://github.com/inkenbrandt/footprints.git

Requires Python 3.10+. Because the export tooling is geospatial, the required dependencies include a full GIS stack: numpy, pandas, xarray, scipy, matplotlib, shapely, fiona, geopandas, rasterio, pyproj, affine, requests, and netcdf4.

Optional extras:

Extra Installs For
contours scikit-image, scikit-learn the marching-squares contour export path
examples jupyter, ipykernel, seaborn, plotly running the notebooks in docs/notebooks/
docs sphinx, nbsphinx, numpydoc, … building the documentation
test pytest, pytest-cov, tox, black, ruff running the test suite and linters
pip install "fluxfootprints[contours,examples]"

Documentation

Full API docs, background material, and example notebooks are hosted at Read the Docs: https://fluxfootprints.readthedocs.io/en/latest/

To build locally:

pip install -r docs/requirements.txt
sphinx-build -M html docs/ docs/_build

Quick-start Example

build_climatology is the main entry point. It maps your column names onto the package's internal names, constructs the requested model, runs it, and returns the model object.

import numpy as np
import pandas as pd
from fluxfootprints import build_climatology

# Half-hourly tower data indexed by timestamp
idx = pd.date_range("2024-06-01", periods=48, freq="30min")
rng = np.random.default_rng(0)
df = pd.DataFrame(
    {
        "USTAR":     rng.uniform(0.2, 0.6, 48),   # friction velocity  [m s-1]
        "MO_LENGTH": rng.uniform(-200, -50, 48),  # Obukhov length     [m]
        "WS":        rng.uniform(2.0, 5.0, 48),   # wind speed at zm   [m s-1]
        "V_SIGMA":   rng.uniform(0.3, 0.9, 48),   # lateral sigma_v    [m s-1]
        "WD":        rng.uniform(0, 360, 48),     # wind direction     [deg]
    },
    index=idx,
)

model = build_climatology(
    df,
    model_type="ffp",
    # Each of these takes a column name, a scalar, or a pandas Series
    ustar="USTAR", ol="MO_LENGTH", umean="WS", sigmav="V_SIGMA", wind_dir="WD",
    zm=3.0,        # measurement height       [m]
    z0=0.05,       # roughness length         [m]
    h=1500.0,      # boundary-layer height    [m]
    dx=10.0, dy=10.0,
    domain=(-500, 500, -500, 500),
)

fclim = model.get_footprint_climatology()   # xarray.DataArray, dims (x, y)
print(fclim.sizes)                          # {'x': 101, 'y': 101}

Every model exposes the same interface, so switching models is a one-word change (model_type="km", "wang", "ls", "ffp_xr"):

model.get_footprint_climatology()   # 2-D climatology,      dims (x, y)
model.get_footprint_timeseries()    # per-timestamp 3-D,    dims (time, x, y)
model.get_coordinates()             # (x, y) arrays in metres
model.get_results()                 # full xarray.Dataset
model.to_netcdf("footprint.nc")

Available Models

All models subclass BaseFootprintModel and share the API shown above.

model_type Class Type Reference
"ffp" FFPModel Parameterisation Kljun et al. (2015)
"ffp_xr" ffp_climatology_new Parameterisation Kljun et al. (2015), xarray implementation
"km", "kormann-meixner" KormannMeixnerModel Analytical Kormann & Meixner (2001)
"wang", "wang2006" WangFootprintModel Analytical (convective BL) Wang et al. (2006)
"ls", "lagrangian" LSFootprintModelAdapter Backward Lagrangian stochastic

wang is not a general-purpose model: it is a semi-empirical parameterisation for the daytime convective boundary layer and requires an Obukhov length below zero. Its published validity range is −L/h ≈ 0.01–0.1 and 0.1 h ≤ zₘ ≤ 0.6 h; results outside that range should be treated with caution.

The models can also be instantiated directly, and the underlying analytical functions (footprint_2d, wang2006_fy, crosswind_integrated_footprint, …) are exported for use on their own. fluxfootprints.ep_footprint additionally provides one-dimensional, EddyPro-style estimates (Kljun 2004, Kormann & Meixner 2001, Hsieh et al. 2000), and fluxfootprints.compare runs several models side by side and reports RMSE, peak-location bias, and 80 % source-area overlap.


Input Requirements

Internally the models all work with these standardised, lower-case column names:

Column Units Description
ustar m s⁻¹ Friction velocity, u*
sigmav m s⁻¹ Lateral velocity std. dev., σᵥ
ol m Obukhov length, L
wind_dir ° Wind direction (0–360)
umean m s⁻¹ Mean wind speed at zₘ
zm m Measurement height
z0 m Roughness length
h m Boundary-layer height

You do not normally have to rename anything yourself: build_climatology accepts a column name, a scalar, or a pandas.Series for each of these and assembles the standardised frame for you, so AmeriFlux-style names (USTAR, MO_LENGTH, V_SIGMA, WD, WS) work by passing them as arguments. Note that the defaults are the lower-case AmeriFlux-style variants (ustar_1_1_1, mo_length_1_1_1, ws_1_1_1, v_sigma_1_1_1, wd_1_1_1).

In practice, supply all eight. build_climatology fills every one of them (h defaults to 2000.0), and the individual models differ in which they consume: km and ls ignore h, while ffp, ffp_xr, and wang use it. One special case is worth knowing: in ffp_xr, z0 and umean are interchangeable — supply either one per timestep, and a missing z0 is derived from the log-wind profile.

Rows failing basic physical checks (u* ≤ 0.1 m s⁻¹, non-finite σᵥ, zm above the boundary layer, out-of-range wind direction) are dropped automatically.

If you have canopy height rather than roughness length, compute_aerodynamic_params derives z0 and displacement height from instrument and crop height.


Beyond the Climatology

from fluxfootprints import (
    summarize_periods, export_contours_gpkg,
    export_rasters_geotiff, export_contour_stats_csv,
)

# Daily and monthly means, optionally weighted by ET derived from latent heat
summaries = summarize_periods(model, df, et_source="LE", is_le=True)

# Georeferenced output, projected to an auto-selected UTM zone
export_rasters_geotiff(model, summaries, station_lat, station_lon, "out/")
export_contours_gpkg(model, summaries, df, station_lat, station_lon,
                     "footprints.gpkg", levels=(0.8,))

The package also includes helpers to pull forcing data (fetch_nldas_forcing_dataset, call_nldas_time_series) and to turn per-row fetch geometry into daily centroids and density rasters (polar_to_cartesian_dataframe, aggregate_to_daily_centroid, generate_density_raster, concat_fetch_gdf).


Citing & Referencing

If you use fluxfootprints in a publication, please cite the parameterisation you actually used. For the default ffp model:

Kljun, N., Calanca, P., Rotach, M.W., & Schmid, H.P. (2015). A simple two-dimensional parameterisation for flux footprint prediction (FFP). Geoscientific Model Development, 8(11), 3695–3713. https://doi.org/10.5194/gmd-8-3695-2015

For the other models, cite the corresponding paper — Kormann & Meixner (2001) for km (entry Kormann2001Analytical in docs/refs.bib), and for wang:

Wang, W., Davis, K.J., Ricciuto, D.M., & Butler, M.P. (2006). An Approximate Footprint Model for Flux Measurements in the Convective Boundary Layer. Journal of Atmospheric and Oceanic Technology, 23(10), 1384–1394. https://doi.org/10.1175/JTECH1911.1

Note that wang implements this 2006 paper (Wang2006Approximate in docs/refs.bib), not the separate Wang & Davis (2008) convective boundary-layer model listed there as Wang2008Analytical.

You may also cite the software directly (see CITATION.cff).


Contributing

  1. Forkcreate a branchcommit your changes
  2. Run the tests (pytest) and linters (ruff check ., black .)
  3. Open a pull request

All contributions — bug reports, suggestions, or code — are welcome!


Development Road-map

  • Footprint uncertainty quantification via Monte-Carlo resampling
  • Broader OpenET API integration and comparison
  • Consolidate tools.py into by_row_fetch_tools.py
  • QGIS plug-in for in-map footprint visualisation

License

This project is licensed under the GNU General Public License v3.0 – see the LICENSE file for details.


Happy footprinting!

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fluxfootprints-0.4.0.tar.gz (18.1 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fluxfootprints-0.4.0-py3-none-any.whl (91.1 kB view details)

Uploaded Python 3

File details

Details for the file fluxfootprints-0.4.0.tar.gz.

File metadata

  • Download URL: fluxfootprints-0.4.0.tar.gz
  • Upload date:
  • Size: 18.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.14

File hashes

Hashes for fluxfootprints-0.4.0.tar.gz
Algorithm Hash digest
SHA256 738b983050824e39c564c6e005fced774e3cb884dcef289a519317863079c2cf
MD5 e96af98fe5106cc814d474f1b9db4d3d
BLAKE2b-256 cbc66ac27170d45124c3181ff5042474a8a6ce77941de8ca12019ddedf4a155d

See more details on using hashes here.

File details

Details for the file fluxfootprints-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: fluxfootprints-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 91.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.14

File hashes

Hashes for fluxfootprints-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9bba6211fc36022129736b9a8dbe27fe0320c63c291413619755ac656b3aaac1
MD5 89a2605d9b05d22fee5faed8a07a1d67
BLAKE2b-256 1e85b69c55980acfd245c0e3684811e3ef74ddf251f305ada6aa7a7fbc95e174

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 files

0.3.1

2 files

0.3.0

2 files

0.2.4

2 files

0.2.3

2 files

0.2.1

2 files

0.2.0

2 files

0.1.12

2 files

0.1.11

2 files

0.1.10

2 files

0.1.9

2 files

0.1.8

2 files

0.1.7

2 files

0.1.6

2 files

0.1.5

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page