Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 66 additions & 27 deletions docs/explanation/input-prioritization.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,41 +11,78 @@ This page describes the decision logic for determining which performance and fue
| Data | Primary (AO-provided) | Secondary (modelled) |
| --- | --- | --- |
| Trajectory | OFP, QAR | FTFM/RTFM, CTFM |
| Fuel flow | Recorded fuel flow | BADA estimate |
| Engine efficiency | Recorded η | BADA thrust / fuel flow |
| Aircraft mass | Mass evolution | BADA iterative estimate |
| Take-off weight | AO-declared TOW | OEW + load_factor × (MTOW − OEW) |
| Fuel flow | Recorded fuel flow, or derived from the recorded mass evolution | BADA estimate |
| Engine efficiency | Recorded η | From BADA thrust and BADA fuel flow |
| Aircraft mass | Mass evolution | Take-off weight decreased along the trajectory with the BADA fuel flow |
| Take-off weight | AO-declared TOW | Iterative estimate: min(MTOW, OEW + load_factor × MPL + 1.15 × trip fuel), see [Mass Estimation](#mass-estimation) |
| Fuel properties | AO-declared (H/C, q_fuel) | JET-A defaults |
| Engine UID | AO-declared | MRR conservative value |

---

## Performance Input Decision Tree

Each performance quantity has its own source, so the cases are not exclusive: for example, an AO fuel flow can be combined with a BADA aircraft mass. The source of one quantity can still depend on what else is provided, as the tree shows.

```mermaid
graph TD
A{"Fuel flow +<br/>engine η<br/>provided?"} -->|Yes| B["Use directly<br/><b>Skip performance step</b>"]
A -->|No| C{"Fuel flow<br/>only<br/>provided?"}
C -->|Yes| D["Use AO fuel flow<br/>Compute η via BADA<br/>thrust + fuel flow"]
C -->|No| E{"Aircraft mass<br/>evolution<br/>provided?"}
E -->|Yes| F["Use mass in BADA<br/>→ fuel flow, thrust, η"]
E -->|No| G{"TOW<br/>provided?"}
G -->|Yes| H["Use TOW in BADA<br/>→ mass evolution<br/>→ fuel flow, thrust, η"]
G -->|No| I["Infer mass from<br/>load factor<br/><b>Iterative estimation</b>"]

style B fill:#4caf50,color:#fff
style D fill:#ff9800,color:#fff
style F fill:#ff9800,color:#fff
style H fill:#2196f3,color:#fff
style I fill:#f44336,color:#fff
A{"Aircraft type in<br/>the BADA mapping?"} -->|No| X["Flight fails"]
A -->|Yes| B{"Fuel flow + engine η<br/>+ aircraft mass<br/>all provided?"}
B -->|Yes| S["Use them directly<br/><b>No BADA thrust or<br/>fuel-flow calculation</b>"]
B -->|No| M{"Aircraft mass<br/>provided?"}
M -->|Yes| M1["Mass: AO values"]
M -->|No| T{"TOW<br/>provided?"}
T -->|Yes| M2["Mass: AO TOW, decreased<br/>with the BADA fuel flow"]
T -->|No| M3["Mass: iterative estimate<br/>from the load factor"]
M1 --> R["BADA thrust and<br/>BADA fuel flow at each point"]
M2 --> R
M3 --> R
R --> FF{"Fuel flow<br/>provided?"}
FF -->|Yes| F1["Fuel flow: AO"]
FF -->|No, mass provided| F2["Fuel flow: from the<br/>AO mass decrease"]
FF -->|No, no mass| F3["Fuel flow: BADA"]
R --> E{"Engine η<br/>provided?"}
E -->|Yes| E1["η: AO"]
E -->|No| E2["η: from BADA thrust<br/>and BADA fuel flow"]

style X fill:#9e9e9e,color:#fff
style S fill:#4caf50,color:#fff
style M1 fill:#ff9800,color:#fff
style M2 fill:#2196f3,color:#fff
style M3 fill:#f44336,color:#fff
```

!!! note "Case 2 — Fuel flow without engine efficiency"
Even when the AO provides fuel flow, BADA fuel flow and thrust must still be computed at each trajectory point to derive engine efficiency correctly. The AO fuel flow is used for downstream emission calculations.
| AO provides | BADA calculation | Aircraft mass | Fuel flow | Engine efficiency |
| --- | --- | --- | --- | --- |
| Fuel flow, engine η and aircraft mass | none (see low-speed points below) | AO | AO | AO |
| Aircraft mass, with at most one of fuel flow and engine η | thrust and fuel flow | AO | AO if provided, else from the AO mass decrease | AO if provided, else BADA |
| TOW, no aircraft mass | thrust and fuel flow | AO TOW, decreased with the BADA fuel flow | AO if provided, else BADA | AO if provided, else BADA |
| Neither aircraft mass nor TOW | thrust and fuel flow | iterative estimate (below), decreased with the BADA fuel flow | AO if provided, else BADA | AO if provided, else BADA |

!!! note "BADA mapping"
Every flight needs its aircraft type in the BADA mapping, even when the AO provides fuel flow, engine efficiency and aircraft mass. The BADA file gives the wingspan (needed for contrails). The mapping gives the number of engines (needed for emissions; read from the BADA file when no BADA calculation is made) and, when no engine is declared, the engine UID: the MRR conservative engine where the type has one, otherwise the engine of the mapping row. A type that is not in the mapping makes the flight fail.

!!! note "Engine efficiency with AO fuel flow"
When the AO provides fuel flow but not engine efficiency, the efficiency is computed from BADA thrust and BADA fuel flow, so that thrust and fuel flow come from the same model. The AO fuel flow is used for the downstream emission calculations.

!!! note "Aircraft mass with AO fuel flow"
When the AO provides fuel flow but no aircraft mass, the aircraft mass decreases along the trajectory with the BADA fuel flow, not with the AO fuel flow. This holds whether the mass starts from the AO TOW or from the estimated TOW, whose trip fuel also uses the BADA fuel flow. The mass decrease along the trajectory then differs from the reported fuel burn.

!!! note "Mass decrease"
With AO aircraft mass and no AO fuel flow, the fuel flow at each point is the mass decrease since the previous point divided by the time step to the next point, set to 0 where the mass increases. It is 0 at the first point and empty at the last point, so the mass decrease over the last segment is not counted in the fuel burn.

!!! note "Provided values"
A quantity counts as provided when at least one point has a value. Points left empty are not filled from BADA: they stay empty and are left out of the fuel totals. After the resampling to 60 s, an empty point also empties the resampled points between its two neighbours.

!!! note "Fuel-burn plausibility check"
A flight is rejected when its total fuel burn, with the fuel flow actually used (AO, derived from the mass, or BADA), exceeds 1.2 × (MTOW − OEW). The check is not applied when fuel flow, engine efficiency and aircraft mass are all provided. A BADA fuel flow above 100 kg/s at a point counts as a BADA failure at that point; AO fuel flow is not checked point by point.

!!! note "Low-speed points"
Before any of the cases above, points whose true airspeed is below the BADA stall speed (at MTOW, take-off configuration), or that have no true airspeed, are removed, also when the AO provides fuel flow, engine efficiency and aircraft mass. If more than 80 % of the points would be removed, none are. Currently this applies only to aircraft computed with BADA 3; this filter is under review.

---

## Mass Estimation (Case 5)
## Mass Estimation

When neither aircraft mass nor TOW is available, PyNeats applies an **iterative** procedure using the load factor (AO-provided or conservative default of 1):

Expand Down Expand Up @@ -78,11 +115,13 @@ Reduce aircraft mass along the trajectory according to fuel burnt at each point.

The correspondence between ICAO aircraft types, aircraft versions, engine identifiers and BADA types follows a multi-level fallback strategy:

1. **BADA 4** match (preferred — higher fidelity)
2. **BADA 3** fallback if no BADA 4 type exists
3. **Fleet statistics** used as frequency-based proxies when no direct mapping is possible
1. **BADA 4** type from the mapping tables (preferred — higher fidelity), looked up by ICAO type, aircraft version and engine, then with fewer of these keys
2. **BADA 3** type when the mapping gives no BADA 4 type, or when the BADA 4 calculation fails
3. If that also fails and the error allows a retry, points below FL20 are removed and the calculation is tried again (BADA 4, then BADA 3)

The mapping tables were built with fleet statistics, used as frequency-based proxies where no direct correspondence exists. A type absent from the tables makes the flight fail.

The engine UID for emission computations defaults to the **MRR conservative value** if not provided as primary data.
The engine UID for emission computations, if not provided as primary data, is the **MRR conservative value** where the type has one, otherwise the engine of the mapping row.

---

Expand All @@ -93,7 +132,7 @@ The granularity of AO-provided data significantly affects output accuracy:
| Input level | Performance accuracy | Notes |
| --- | --- | --- |
| Full primary (mass + fuel + η) | ★★★★★ | Best — no modelling needed |
| Fuel flow only | ★★★★☆ | η derived from BADA |
| Mass evolution | ★★★☆☆ | Full BADA performance chain |
| Fuel flow only | ★★★★☆ | η from BADA thrust and BADA fuel flow; aircraft mass and TOW estimated from the load factor |
| Mass evolution | ★★★☆☆ | Fuel flow from the AO mass decrease; thrust (and η) from BADA |
| TOW only | ★★☆☆☆ | Mass evolution estimated |
| Load factor only | ★☆☆☆☆ | Fully modelled — conservative |
24 changes: 16 additions & 8 deletions docs/explanation/mrv-specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ The interpolation module converts the input trajectory (primary or secondary) to

*PyNeats currently uses straightforward linear interpolation via PyContrails' `resample_and_fill` method. For secondary data, the coarse native sampling can yield segments that are not fully realistic and may stray outside the flight envelope after interpolation. To obtain more realistic trajectories, smoothing is applied to ground speed using the **Savitzky–Golay filter** from PyContrails, reducing the number of segments that fall outside the flight envelope.*

For optional primary variables along the trajectory (e.g. true airspeed, aircraft mass, fuel flow, or engine efficiency), **linear interpolation** is applied to align their values with the trajectory timestamps. Missing data points are filled using the same interpolation method.
For optional primary variables along the trajectory (e.g. true airspeed, aircraft mass, fuel flow, or engine efficiency), **linear interpolation** is applied to align their values with the trajectory timestamps. Missing data points are not filled: a point the AO leaves empty also empties the resampled points between its two neighbours, and these stay empty in the performance step.

### 3.3 Weather

Expand Down Expand Up @@ -169,7 +169,7 @@ The emissions and climate modules require the following aircraft-performance val
- **Fuel flow**
- **Engine efficiency**

The performance model is used to estimate these values when they are not available at a point along the trajectory.
The performance model is used to estimate these values when the AO does not provide them. A quantity is taken from the AO when at least one point has a value; points the AO leaves empty are not estimated (see Input Decision Logic).

**BADA** is the current chosen model for performance computation in PyNeats, in its open-source version from EUROCONTROL (**pyBADA**). BADA requires, at a given point of the trajectory:

Expand All @@ -178,18 +178,26 @@ The performance model is used to estimate these values when they are not availab

#### Basic Parameterisation

- If TAS is not provided by the AO, wind fields **above 840 hPa (FL050)** are used to compute it; below that pressure level TAS is set to 0.
- If TAS is not provided by the AO, it is computed from the (smoothed) ground speed and the wind fields, available **above 840 hPa (FL050)**; where no wind is available (below that level) the wind is set to 0, so TAS equals the smoothed ground speed.
- The International Standard Atmosphere is corrected with actual air above 550 hPa, backfilling and forward-filling the correction for lower altitudes.
- BADA flight phases are determined from **vertical speed** using simple decision thresholds.

#### Input Decision Logic

The following rules are applied **sequentially** to determine how the primary data provided by the AO is used:
Each performance quantity has its own source, so the cases below are not exclusive (an AO fuel flow can be combined with a BADA aircraft mass); the source of one quantity can still depend on what else is provided, as rules 2 and 4 show:

1. **BADA mapping:** every flight needs its aircraft type in the BADA mapping, even when the AO provides all performance data. The BADA file gives the wingspan (contrails); the mapping gives the number of engines (emissions; read from the BADA file when no BADA calculation is made) and, when no engine is declared, the engine UID (the MRR conservative engine where the type has one, otherwise the engine of the mapping row). A type not in the mapping makes the flight fail.
2. **Fuel flow, engine efficiency and aircraft mass all provided:** no BADA thrust or fuel-flow calculation; the provided values are used directly downstream. The fuel-burn plausibility check (total fuel burn at most 1.2 × (MTOW − OEW), applied on every other path with the fuel flow actually used) is not applied on this path.
3. **Otherwise BADA computes thrust and fuel flow at each point**, with the aircraft mass taken from, in order: the AO aircraft mass, if provided; else the AO take-off weight (TOW), decreased along the trajectory with the BADA fuel flow; else the iterative estimate of rule 5.
4. **Outputs:**
- **Fuel flow:** AO fuel flow (kg/s) if provided; else, if the AO provides aircraft mass, the mass decrease since the previous point divided by the time step to the next point (set to 0 where the mass increases; 0 at the first point and empty at the last, so the last segment's mass decrease is not counted); else the BADA fuel flow.
- **Engine efficiency:** AO value if provided; else computed from BADA thrust and BADA fuel flow. This also holds when the AO provides fuel flow: **engine efficiency requires thrust AND fuel flow** from a consistent source, so engine efficiency = f(BADA thrust, BADA fuel flow), while the AO fuel flow is used downstream.
- **Aircraft mass:** as in rule 3. When the AO provides fuel flow but no aircraft mass, the mass decreases with the BADA fuel flow (from the AO TOW or from the estimated TOW, whose trip fuel also uses the BADA fuel flow), so the mass decrease differs from the reported fuel burn.

A quantity counts as provided when at least one point has a value; points left empty are not filled from BADA and are left out of the fuel totals.

Before any of these rules, points whose true airspeed is below the BADA stall speed (at MTOW, take-off configuration), or that have no true airspeed, are removed, also on the path of rule 2; if more than 80 % of the points would be removed, none are. Currently this applies only to aircraft computed with BADA 3; this filter is under review.

1. **Fuel flow and engine efficiency provided at each point:** no additional computation; the performance step is **skipped** and provided values are used directly downstream.
2. **Fuel flow only provided at each point:** AO fuel flow (kg/s) is used downstream. However, **engine efficiency requires thrust AND fuel flow** from a consistent source. To avoid mixing AO fuel flow with BADA-estimated thrust (which would be inconsistent), BADA fuel flow must **still be computed** at each trajectory point so that **engine efficiency = f(BADA thrust, BADA fuel flow)**.
3. **Aircraft mass evolution provided:** used directly in BADA to compute fuel flow, thrust, and engine efficiency.
4. **Only take-off weight (TOW) provided:** TOW is used in the performance model to estimate mass evolution along the trajectory, and then fuel flow, thrust, and engine efficiency are computed with BADA.
5. **Neither mass nor TOW provided:** the load factor is used (AO-provided or conservative default of 1). The following approach (similar to PyContrails) is applied:

1. **Initial estimate** (constant along the trajectory):
Expand Down
Loading
Loading