Skip to main content

Acropole Logo

Acropole — Predict aircraft fuel flow from trajectory data

CI axm-audit axm-init coverage PyPI Python 3.12+ License: AGPL-3.0 Docs


acropole predicts the fuel flow of aircraft (kg/s, kg/h and cumulative kg) from trajectory data — groundspeed, altitude and vertical rate — using a portable ONNX model trained on Quick Access Recorder (QAR) data. It accepts a pandas or polars DataFrame, dispatches per aircraft typecode, and returns the same frame enriched with fuel-flow columns. The runtime depends only on numpy + polars + onnxruntime — no heavy ML framework.

📖 Full documentation

Features

  • Fuel-flow prediction — per-sample fuel_flow (kg/s), fuel_flow_kgh (kg/h) and fuel_cumsum (kg) from a flight trajectory
  • ✈️ Multi-aircraft — frames mixing several typecodes are scored per typecode, each row with its own aircraft parameters
  • 🐼 pandas and polarsestimate() accepts either and returns the same type; the engine runs on polars internally
  • 🚀 Fast ONNX runtime — migrated from TensorFlow, 2–4.8× faster depending on batch size, numerical parity validated to 1e-6; no TensorFlow dependency
  • 📈 Temporal derivatives — supply a second column to compute accelerations (and fuel_cumsum), or pass pre-computed derivatives directly
  • 🎯 Column mapping — map your own column names with keyword arguments, no renaming required
  • Typecode-bound fast pathAircraftFuelEstimator offers numpy-only I/O with pre-computed parameters for hot loops
  • 🧪 Fully typed — ships py.typed, strict mypy on source and tests, 98% coverage

Installation

acropole is published on PyPI:

uv add acropole      # or: pip install acropole

The core library runs on numpy + polars + onnxruntime. To pass and receive pandas DataFrames, install the optional pandas extra:

uv add "acropole[pandas]"      # or: pip install "acropole[pandas]"

To work from source, this project uses uv:

git clone https://github.com/DGAC/Acropole.git
cd Acropole
uv sync

Quick Start

import pandas as pd
from acropole import FuelEstimator

fe = FuelEstimator()

flight = pd.DataFrame({
    "typecode": ["A320", "A320", "A320", "A320"],
    "groundspeed": [400, 410, 420, 430],     # kt
    "altitude": [10000, 11000, 12000, 13000],  # ft
    "vertical_rate": [2000, 1500, 1000, 500],   # ft/min
    # optional features:
    "second": [0.0, 4.0, 8.0, 12.0],
    "airspeed": [400, 410, 420, 430],
    "mass": [60000, 60000, 60000, 60000],
})

flight_fuel = fe.estimate(flight)
# adds fuel_flow (kg/s), fuel_flow_kgh (kg/h), fuel_cumsum (kg)

Notes:

  • Providing the second column makes the estimation more accurate (it derives accelerations of the speeds) and enables fuel_cumsum.
  • airspeed is optional; if absent it defaults to groundspeed. Accurate airspeed improves the estimate.
  • The expected sampling rate is 4 seconds. A higher or lower rate produces noisier fuel flow — resample before estimating.

For a full notebook, see examples/fuel_estimation.ipynb.

Advanced Usage

Mapping your own column names

estimate() accepts keyword arguments mapping each logical feature to the column name in your frame. The example flight (QAR columns) maps like this:

import pandas as pd
from acropole import FuelEstimator

flight = pd.read_csv("examples/example_flight.csv")
flight = flight.iloc[::4]  # resample to ~4 s

fe = FuelEstimator()
flight_fuel = fe.estimate(
    flight,
    typecode="FLPL_AIRC_TYPE",
    groundspeed="GRND_SPD_KT",
    altitude="ALTI_STD_FT",
    vertical_rate="VERT_SPD_FTMN",
    second="FLIGHT_TIME",
    airspeed="TRUE_AIR_SPD_KT",
    mass="MASS_KG",
)

Required logical columns: typecode, groundspeed (kt), altitude (ft), vertical_rate (ft/min). Optional: second, airspeed, mass, and the pre-computed derivatives d_altitude / d_groundspeed / d_airspeed.

Multi-aircraft frames

A single frame can mix typecodes; each row is scored with its own aircraft parameters. Unsupported typecodes emit a warning and leave fuel_flow as NaN:

flight = pd.DataFrame({
    "typecode": ["A320", "A320", "B738", "B738"],
    "groundspeed": [400, 410, 420, 430],
    "altitude": [10000, 11000, 12000, 13000],
    "vertical_rate": [2000, 1500, 1000, 500],
})
fe.estimate(flight)  # A320 rows and B738 rows each use their own params

Typecode-bound fast path

For hot loops on a single aircraft, AircraftFuelEstimator works directly on numpy arrays (no per-call params lookup) and returns fuel flow in kg/s:

import numpy as np
from acropole import FuelEstimator

# share the already-loaded ONNX session and parameters
afe = FuelEstimator().for_aircraft("A320")

fuel_flow = afe.estimate(
    groundspeed=np.array([400.0, 410.0, 420.0]),
    altitude=np.array([10000.0, 11000.0, 12000.0]),
    vertical_rate=np.array([2000.0, 1500.0, 1000.0]),
)  # kg/s  (multiply by 3600 for kg/h)

Custom aircraft parameters and model

fe = FuelEstimator(
    aircraft_params_path="path/to/your/aircraft_params.csv",
    model_path="path/to/your/model.onnx",
)

Aircraft parameters from open data are bundled in src/acropole/data/aircraft_params.csv and the ONNX model in src/acropole/models/; both are loaded by default.

Command-Line

Installing acropole also installs the acropole command (entry point acropole.cli:main). It reads a flight from a CSV or parquet file, estimates fuel flow, and writes the enriched table back to disk — adding fuel_flow (kg/s), fuel_flow_kgh (kg/h) and, with --second, fuel_cumsum (kg):

acropole estimate examples/example_flight.csv \
  --typecode FLPL_AIRC_TYPE --groundspeed GRND_SPD_KT --altitude ALTI_STD_FT \
  --vertical-rate VERT_SPD_FTMN --airspeed TRUE_AIR_SPD_KT --mass MASS_KG \
  --second FLIGHT_TIME --out result.csv
# wrote 7796 rows with fuel columns to result.csv

If your file already uses the standard column names, no mapping is needed and the output defaults to <flight>_fuel.<ext> next to the input:

acropole estimate flight.csv        # writes flight_fuel.csv

Each --typecode, --groundspeed, --altitude, --vertical-rate, --airspeed, --mass and --second flag maps a logical feature to the matching column in your file (defaults are the standard names). See the CLI reference for all options.

Comparison of Different Model Performances

Comparison of different model performances per phase for 1000 test flights of A320-214 aircraft using real mass and true airspeed.

Phase Samples # Metric ACROPOLE OpenAP OpenAP V2 BADA Poll-Schumann
MAPE (%) 2.13 30.35 8.84 6.53 6.85
CLIMB 1,403,850 MAE (kg/min) 1.66 25.81 6.92 5.53 5.65
ME (kg/min) 0.85 -25.66 -2.48 -5.27 -4.62
MAPE (%) 4.41 18.59 10.69 7.01 4.84
LEVEL 4,017,801 MAE (kg/min) 1.82 7.82 3.48 2.65 2.03
ME (kg/min) 1.22 -7.47 2.64 -1.43 -0.73
MAPE (%) 12.63 51.69 32.4 21.50 21.55
DESCENT 1,684,117 MAE (kg/min) 2.71 8.62 5.58 3.71 4.71
ME (kg/min) 1.88 -1.75 -1.16 -0.64 -3.67
MAPE (%) 5.91 27.60 14.71 9.84 8.61
ALL 7,105,768 MAE (kg/min) 1.99 11.55 4.58 3.44 3.29
ME (kg/min) 1.30 -9.92 0.84 -2.03 -2.09
Processing time (s) 3 284 255 474 28

The Acropole model is a neural network trained on Quick Access Recorder (QAR) data from several aircraft types. Evaluation and the list of supported aircraft are available at evaluation/Dense_Acropole_FuelFlow_Scaling.

Development

Set up a full development environment (runtime, dev, and docs groups):

uv sync --all-groups

Common tasks:

uv run pytest                    # run the test suite (98% coverage)
make lint                        # ruff + mypy strict on src AND tests
pre-commit install               # enable the pre-commit hooks

License

Acropole is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). See the LICENSE file for the full text.

Credits

@inproceedings{jarry2024towards,
  title={Towards aircraft generic Quick Access Recorder fuel flow regression models for ADS-B data},
  author={Jarry, Gabriel and Delahaye, Daniel and Hurter, Christophe},
  booktitle={International Conference on Research in Air Transportation},
  year={2024}
}

Release files for acropole 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for acropole 0.1.3
File Size Uploaded
acropole-0.1.3.tar.gz 542.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for acropole 0.1.3
File Interpreter ABI Platform
acropole-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 604.0 kB

Release files / acropole-0.1.3.tar.gz

Download URL acropole-0.1.3.tar.gz
Size 542.9 kB
Tags Source
SHA-256 checksum
How to use checksums
aa06f0407384a4b241962f1b029712b0aadb62d4206911c179b16301d7b6179c
BLAKE2b-256 checksum
How to use checksums
371df0cbf8e85ff71b632cc6c66b2b10899740cf0c87b934b1572436c169697b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 15, 2026.

Transparency log

Release files / acropole-0.1.3-py3-none-any.whl

Download URL acropole-0.1.3-py3-none-any.whl
Size 61.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1db38ba8cfe1df4af4315ce5f27d32ca76b2ce51f299d74ca6a910136b28a785
BLAKE2b-256 checksum
How to use checksums
a1a5dfe235276801907b589d2b3f813050a365b42d628fd5b8998120014436ce
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.3 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page