traffic.core.flight

class traffic.core.Flight(data, *args, **kwargs)

Bases: HBoxMixin, GeographyMixin, ShapelyMixin, NavigationFeatures, OpenAP

Flight is the most basic class associated to a trajectory. Flights are the building block of all processing methods, built on top of pandas DataFrame. The minimum set of required features are:

  • icao24: the ICAO transponder ID of an aircraft;

  • callsign: an identifier which may be associated with the registration of an aircraft, with its mission (VOR calibration, firefighting) or with a route (for a commercial aircraft);

  • timestamp: timezone aware timestamps are preferable. Some methods may work with timezone naive timestamps but the behaviour is not guaranteed;

  • latitude, longitude: in degrees, WGS84 (EPSG:4326);

  • altitude: in feet.

Note

The flight_id (identifier for a trajectory) may be used in place of a pair of (icao24, callsign). More features may also be provided for further processing, e.g. groundspeed, vertical_rate, track, heading, IAS (indicated airspeed) or squawk.

Tip

Read more about:

Abridged contents:

Scattergeo(**kwargs)

Create a Scattergeo with Plotly.

Requires the plotly package (optional dependency).

Return type:

Scattergeo

Scattermap(**kwargs)

Create a Scattermap with Plotly.

Requires the plotly package (optional dependency).

Return type:

Scattermap

abs(features=None, **kwargs)

Assign absolute versions of features to new columns.

Return type:

Flight

>>> flight.abs("track")

The two following commands are equivalent:

>>> flight.abs(["track", "heading"])
>>> flight.abs(track="track_abs", heading="heading_abs")
after(time, strict=True)

Returns the part of the trajectory flown after a given timestamp. :rtype: Optional[Flight]

  • time can be passed as a string, an epoch, a Python datetime, or a Pandas timestamp.

agg_time(freq='1 min', merge=True, **kwargs)

Aggregate features on time windows.

The following is performed: :rtype: Flight

  • a new column rounded rounds the timestamp at the given rate;

  • the groupby/agg is operated with parameters passed in kwargs;

  • if merge is True, the new column in merged into the Flight, otherwise a pd.DataFrame is returned.

For example:

>>> f.agg_time('3T', groundspeed='mean')

returns a Flight with a new column groundspeed_mean with groundspeed averaged per intervals of 3 minutes.

agg_xy(resolution, projection=None, **kwargs)

Aggregates values of a traffic over a grid of x/y, with x and y computed by compute_xy().

Parameters:
  • resolution (None | dict[str, float]) – The resolution of the grid is passed as a dictionary parameter. By default, the grid is made by rounding x and y to the lower ten kilometer values. dict(x=5000, y=3000) will take 1 value per 5000 meters for x (10000, 15000, 20000, …) and 1 value per 3000 meters for y (9000, 12000, 15000, 18000, 20000, …).

  • projection (None | pyproj.Proj | ‘crs.Projection) – is used to compute the x and y values.

The kwargs specifies how to aggregate values:

  • altitude="mean" would average all values in the given cell;

  • timestamp="count" would return the number of samples per cell;

  • icao24="nunique" would return the number of different aircraft int the given cell.

Return type:

pd.DataFrame

Returns:

a DataFrame indexed over x and y values. It is conveniently chainable with the .to_xarray() method in order to plot density heatmaps.

Example usage:

belevingsvlucht.agg_xy(
    resolution=dict(x=3e3, y=3e3),
    vertical_rate="mean",
    timestamp="count"
)
airborne()

Returns the airborne part of the Flight.

The airborne part is determined by an onground flag or null values in the altitude column.

Return type:

Optional[Flight]

aligned_on_ils(airport, angle_tolerance=0.1, min_duration='1 min')

Iterates on all segments of trajectory aligned with the ILS of the given airport. The runway number is appended as a new ILS column.

Parameters:
  • airport (Union[None, str, Airport]) – Airport where the ILS is located

  • angle_tolerance (float) – maximum tolerance on bearing difference between ILS and flight trajectory.

  • min_duration (Union[None, str, Real, timedelta, Timedelta]) – minimum duration a flight has to spend on the ILS to be considered as aligned.

Return type:

FlightIterator

Example usage:

>>> aligned = belevingsvlucht.aligned_on_ils('EHAM').next()
>>> f"ILS {aligned.max('ILS')} until {aligned.stop:%H:%M}"
'ILS 06 until 20:17'
>>> for aligned in belevingsvlucht.aligned_on_ils('EHLE'):
...     print(aligned.start)
2018-05-30 16:50:44+00:00
2018-05-30 18:13:02+00:00
2018-05-30 16:00:55+00:00
2018-05-30 17:21:17+00:00
2018-05-30 19:05:22+00:00
2018-05-30 19:42:36+00:00

>>> from operator import attrgetter
>>> last_aligned = max(
...     belevingsvlucht.aligned_on_ils("EHLE"),
...     key=attrgetter('start')
... )
aligned_on_navpoint(points, angle_precision=1, time_precision='2 min', min_time='30s', min_distance=80)

Iterates on segments of trajectories aligned with one of the given navigational beacons passed in parameter.

The name of the navigational beacon is assigned in a new column navaid.

Return type:

FlightIterator

aligned_on_runway(airport)

Iterates on all segments of trajectory matching a runway of the given airport.

Example usage:

Return type:

FlightIterator

>>> sum(1 for _ in belevingsvlucht.aligned_on_runway("EHAM"))
2
all(method, flight_id=None)

Returns the concatenation of segments returned by flight.method().

Example usage:

Return type:

Optional[Flight]

>>> flight.all("go_around")
>>> flight.all("runway_change")
>>> flight.all('aligned_on_ils("LFBO")')
>>> flight.all(lambda f: f.aligned_on_ils("LFBO"))
apply_time(freq='1 min', merge=True, **kwargs)

Apply features on time windows.

The following is performed: :rtype: Flight

  • a new column rounded rounds the timestamp at the given rate;

  • the groupby/apply is operated with parameters passed in apply;

  • if merge is True, the new column in merged into the Flight, otherwise a pd.DataFrame is returned.

For example:

>>> f.agg_time("10 min", straight=lambda df: Flight(df).distance())

returns a Flight with a new column straight with the great circle distance between points sampled every 10 minutes.

property area: float

Returns the area of the shape, in square meters. The shape is projected to an equivalent local projection before computing a value.

assign(*args, **kwargs)

Applies the Pandas assign() method to the underlying pandas DataFrame and get the result back in the same structure.

Return type:

Self

assign_id(name='{self.callsign}_{idx:>03}', idx=0)

Assigns a flight_id to a Flight.

This method is more generally used by the corresponding Traffic and LazyTraffic methods but works fine on Flight as well.

Return type:

Flight

at(time=None)

Returns the position in the trajectory at a given timestamp. :rtype: Optional[Position]

  • time can be passed as a string, an epoch, a Python datetime, or a Pandas timestamp.

  • If no time is passed (default), the last know position is returned.

  • If no position is available at the given timestamp, None is returned. If you expect a position at any price, consider Flight.resample

at_ratio(ratio=0.5)

Returns a position on the trajectory.

This method is convenient to place a marker on the trajectory in visualisation output. :rtype: Optional[Position]

  • Flight.at_ratio(0) is the first point in the trajectory.

  • Flight.at_ratio(1) is the last point of the trajectory (equivalent to Flight.at())

before(time, strict=True)

Returns the part of the trajectory flown before a given timestamp. :rtype: Optional[Flight]

  • time can be passed as a string, an epoch, a Python datetime, or a Pandas timestamp.

between(start, stop, strict=True)

Returns the part of the trajectory flown between start and stop. :rtype: Optional[Flight]

  • start and stop can be passed as a string, an epoch, a Python datetime, or a Pandas timestamp.

  • stop can also be passed as a timedelta.

property bounds: tuple[float, float, float, float]

Returns the bounds of the (bounding box of the) shape. Bounds are given in the following order in the origin crs: (west, south, east, north)

property callsign: str | Set[str] | None

Returns the unique callsign value(s) associated to the Flight.

A callsign is an identifier sent by an aircraft during its flight. It may be associated with the registration of an aircraft, its mission or with a route for a commercial aircraft.

property centroid: Point

Returns the centroid of the shape as a shapely Point.

chart(*features)

Initializes an altair Chart based on Flight data.

The features passed in parameters are dispatched to allow plotting multiple features on the same graph.

Example usage:

# Most simple usage
flight.chart().encode(alt.Y("altitude"))

# With some configuration
flight.chart().encode(
    alt.X(
        "utcyearmonthdatehoursminutes(timestamp)",
        axis=alt.Axis(title=None, format="%H:%M"),
    ),
    alt.Y("altitude", title="altitude (in ft)"),
    alt.Color("callsign")
)

For a more complex graph plotting similar physical quantities on the same graph, and other quantities on a different graph, the following snippet may be of use.

# More advanced with several plots on the same graph
base = (
    flight.chart("altitude", "groundspeed", "IAS")
    .encode(
        alt.X(
            "utcyearmonthdatehoursminutesseconds(timestamp)",
            axis=alt.Axis(title=None, format="%H:%M"),
        )
    )
    .properties(height=200)
)

alt.vconcat(
    base.transform_filter('datum.variable != "altitude"').encode(
        alt.Y(
            "value:Q",
            axis=alt.Axis(title="speed (in kts)"),
            scale=alt.Scale(zero=False),
        )
    ),
    base.transform_filter('datum.variable == "altitude"').encode(
        alt.Y("value:Q", title="altitude (in ft)")
    ),
)
Return type:

Chart

Note

See also plot_time() for the Matplotlib equivalent.

clip(shape, strict=True)

Clips the trajectory to a given shape.

For a shapely Geometry, the first time of entry and the last time of exit are first computed before returning the part of the trajectory between the two timestamps.

Most of the time, aircraft do not repeatedly come out and in an airspace, but computation errors may sometimes give this impression. As a consequence, the clipped trajectory may have points outside the shape. :rtype: Optional[Flight]

Warning

Altitudes are not taken into account.

closest_point(points)

Selects the closest point of the trajectory with respect to a point or list of points.

The pd.Series returned by the function is enriched with two fields: distance (in meters) and point (containing the name of the closest point to the trajectory)

Example usage:

>>> item = belevingsvlucht.between(
...     "2018-05-30 16:00", "2018-05-30 17:00"
... ).closest_point(  # type: ignore
...     [
...         airports["EHLE"],  # type: ignore
...         airports["EHAM"],  # type: ignore
...         navaids["NARAK"],  # type: ignore
...     ]
... )
>>> f"{item.point}, {item.distance:.2f}m"
"Lelystad Airport, 49.11m"
Return type:

Series

compute_DME_NSE(dme, column_name='NSE')

Adds the DME/DME Navigation System Error.

Computes the max Navigation System Error using DME-DME navigation. The obtained NSE value corresponds to the 2 \(\sigma\) (95%) requirement in nautical miles.

Source: EUROCONTROL Guidelines for RNAV 1 Infrastructure Assessment

Parameters:
  • dme (Union[Navaids, Tuple[Navaid, Navaid]]) –

    • when the parameter is of type Navaids, only the pair of Navaid giving the smallest NSE are used;

    • when the parameter is of type tuple, the NSE is computed using only the pair of specified Navaid.

  • column_name (str) – (default: "NSE"), the name of the new column containing the computed NSE

Return type:

Flight

compute_TAS()

Computes the wind triangle for each timestamp.

This method requires groundspeed, track, wind_u and wind_v (in knots) to compute true airspeed (TAS), and heading features. The groundspeed and the track angle are usually available in ADS-B messages; wind information may be included from a GRIB file using the include_grib() method.

Return type:

Flight

compute_latlon_from_xy(projection)

Enrich a DataFrame with new longitude and latitude columns computed from x and y columns. :rtype: Self

Warning

Make sure to use as source projection the one used to compute 'x' and 'y' columns in the first place.

compute_navpoints(navaids=None, buffer=0.1)

This functions recomputes the most probable alignments on navigational points on the trajectory.

By default, all navaids of the default database are considered, but limited to a buffered bounding box around the trajectory.

Once computed, the following Altair snippet may be useful to display the trajectory as a succession of segments:

import altair as alt

df = flight.compute_navpoints()

segments = (
    alt.Chart(df.drop(columns="duration")).encode(
        alt.X("start", title=None),
        alt.X2("stop"),
        alt.Y("navaid", sort="x", title=None),
        alt.Color("type", title="Navigational point"),
        alt.Tooltip(["navaid", "distance", "shift_mean"]),
    )
    .mark_bar(size=10)
    .configure_legend(
        orient="bottom",
        labelFontSize=14, titleFontSize=14, labelFont="Ubuntu"
    )
    .configure_axis(labelFontSize=14, labelFont="Ubuntu")
)
Return type:

Optional[DataFrame]

compute_wind()

Computes the wind triangle for each timestamp.

This method requires groundspeed, track, true airspeed (TAS), and heading features. The groundspeed and the track angle are usually available in ADS-B messages; the heading and the true airspeed may be decoded in EHS messages. :rtype: Flight

Note

Check the query_ehs() method to find a way to enrich your flight with such features. Note that this data is not necessarily available depending on the location.

compute_xy(projection=None)

Enrich the structure with new x and y columns computed through a projection of the latitude and longitude columns.

The source projection is WGS84 (EPSG 4326). The default destination projection is a Lambert Conformal Conical projection centred on the data inside the dataframe.

Other valid projections are available: :rtype: Self

  • as pyproj.Proj objects;

  • as cartopy.crs.Projection objects.

convert_dtypes(*args, **kwargs)

Applies the Pandas convert_dtypes() method to the underlying pandas DataFrame and get the result back in the same structure.

Return type:

Self

cumulative_distance(compute_gs=True, compute_track=True, *, reverse=False, **kwargs)

Enrich the structure with new cumdist column computed from latitude and longitude columns.

The first cumdist value is 0, then distances are computed (in nautical miles) and summed between consecutive positions. The last value is the total length of the trajectory.

When the compute_gs flag is set to True (default), an additional compute_gs is also added. This value can be compared with the decoded groundspeed value in ADSB messages.

When the compute_track flag is set to True (default), an additional compute_track is also added. This value can be compared with the decoded track value in ADSB messages.

Return type:

Flight

property destination: str | Set[str] | None

Returns the unique destination value(s), None if not available in the DataFrame.

The destination airport is usually represented as a ICAO or a IATA code.

The ICAO code of an airport is represented by 4 letters (e.g. EHAM for Amsterdam Schiphol International Airport) and the IATA code is represented by 3 letters and more familiar to the public (e.g. AMS for Amsterdam)

diff(features=None, **kwargs)

Assign differential versions of features to new columns.

Return type:

Flight

>>> flight.diff("track")

The two following commands are equivalent:

>>> flight.diff(["track", "heading"])
>>> flight.diff(track="track_diff", heading="heading_diff")
distance(other=None, column_name='distance')

Computes the distance from a Flight to another entity.

The behaviour is different according to the type of the second element: :rtype: Union[None, float, Flight, DataFrame]

  • if the other element is None (i.e. flight.distance()), the method returns a distance in nautical miles between the first and last recorded positions in the DataFrame.

  • if the other element is a Flight, the method returns a pandas DataFrame with corresponding data from both flights, aligned with their timestamps, and two new columns with lateral and vertical distances (resp. in nm and ft) separating them.

  • otherwise, the same Flight is returned enriched with a new column (by default, named “distance”) with the distance of each point of the trajectory to the geometrical element.

Warning

  • An Airspace is (currently) considered as its flattened representation

  • Computing a distance to a polygon is quite slow at the moment. Consider a strict resampling (e.g. one point per minute, “1 min”) before calling the method.

diversion()

Returns the segment of trajectory after a possible decision of diversion.

The method relies on the destination parameter to identify the intended destination.

Return type:

Optional[Flight]

property diverted: str | Set[str] | None

Returns the unique diverted value(s), None if not available in the DataFrame.

The diverted airport is usually represented as a ICAO or a IATA code.

The ICAO code of an airport is represented by 4 letters (e.g. EHAM for Amsterdam Schiphol International Airport) and the IATA code is represented by 3 letters and more familiar to the public (e.g. AMS for Amsterdam)

drop(*args, **kwargs)

Applies the Pandas drop() method to the underlying pandas DataFrame and get the result back in the same structure.

Return type:

Self

drop_duplicates(*args, **kwargs)

Applies the Pandas drop_duplicates() method to the underlying pandas DataFrame and get the result back in the same structure.

Return type:

Self

property duration: Timedelta

Returns the duration of the flight.

emergency()

Iterates on emergency segments of trajectory.

An emergency is defined with a 7700 squawk code.

Return type:

FlightIterator

property extent: tuple[float, float, float, float]

Returns the extent of the (bounding box of the) shape.

Note

When plotting with Matplotlib and Cartopy, the extent property is convenient in the following use case:

>>> ax.set_extent(obj.extent)
Returns:

Extent is given in the following order in the origin crs: (west, east, south, north)

feature_gt(feature, value, strict=True)

Returns True if feature(flight) is greater than value.

This is fully equivalent to f.longer_than(“1 minute”):

Return type:

bool

>>> f.feature_gt("duration", pd.Timedelta('1 minute'))
True

This is equivalent to f.max(‘altitude’) > 35000:

>>> f.feature_gt(lambda f: f.max("altitude"), 35000)
True

The second one can be useful for stacking operations during lazy evaluation.

feature_lt(feature, value, strict=True)

Returns True if feature(flight) is less than value.

This is fully equivalent to f.shorter_than(“1 minute”):

Return type:

bool

>>> f.feature_lt("duration", pd.Timedelta('1 minute'))
True

This is equivalent to f.max(‘altitude’) < 35000:

>>> f.feature_lt(lambda f: f.max("altitude"), 35000)
True

The second one can be useful for stacking operations during lazy evaluation.

fillna(*args, **kwargs)

Applies the Pandas fillna() method to the underlying pandas DataFrame and get the result back in the same structure.

Return type:

Self

filter(filter='default', strategy=<function Flight.<lambda>>, **kwargs)

Filters a trajectory with predefined methods.

Parameters:
  • filter (str | FilterBase) – (default: FilterAboveSigmaMedian) is one of the filters predefined in traffic.algorithms.filters or any filter implementing the Filter protocol. Use “aggressive” for an experimental filter by @krumjan

  • strategy (Optional[Callable[[DataFrame], DataFrame]]) –

    (default: backward fill followed by forward fill) is applied after the filter to deal with resulting NaN values.

    • Explicitely specify to None if NaN values should be left as is.

    • lambda x: x.interpolate() may be a smart strategy

Return type:

Flight

final(method)

Returns the final (last) segment of trajectory yielded by flight.method()

Return type:

Optional[Flight]

>>> flight.final("go_around")
>>> flight.final("runway_change")
>>> flight.final(lambda f: f.aligned_on_ils("LFBO"))
first(value=None, **kwargs)

Returns the first n days, hours, minutes or seconds of the Flight.

The elements passed as kwargs as passed as is to the datetime.timedelta constructor.

Example usage:

Return type:

Flight

>>> flight.first(minutes=10)
>>> flight.first("1h")
>>> flight.first(10)  # seconds by default
property flight_id: str | Set[str] | None

Returns the unique flight_id value(s) of the DataFrame.

Neither the icao24 (the aircraft) nor the callsign (the route) is a reliable way to identify trajectories. You can either use an external source of data to assign flight ids (for example DDR files by Eurocontrol, identifiers by FlightRadar24, etc.) or assign a flight_id by yourself (see Flight.assign_id(name: str) method).

The Traffic.assign_id() method uses a heuristic based on the timestamps associated to callsign/icao24 pairs to automatically assign a flight_id and separate flights.

forward(delta=None, **kwargs)

Projects the trajectory in a straight line.

The method uses the last position of a trajectory (method at()) and uses the track (in degrees), groundspeed (in knots) and vertical_rate (in ft/min) values to interpolate the trajectory in a straight line.

The elements passed as kwargs as passed as is to the datetime.timedelta constructor.

Example usage:

flight.forward(minutes=10)
flight.before("2018-12-24 23:55").forward(minutes=10)  # Merry XMas!
Return type:

Flight

classmethod from_file(filename, **kwargs)

Read data from various formats.

This class method dispatches the loading of data in various format to the proper pandas.read_* method based on the extension of the filename. :rtype: Self

  • .pkl and .pkl.gz dispatch to pandas.read_pickle;

  • .parquet and .parquet.gz dispatch to pandas.read_parquet;

  • .json and .json.gz dispatch to pandas.read_json;

  • .csv and .csv.gz dispatch to pandas.read_csv;

  • .h5 dispatch to pandas.read_hdf.

Other extensions return None. Specific arguments may be passed to the underlying pandas.read_* method with the kwargs argument.

Example usage:

>>> from traffic.core import Flight
>>> t = Flight.from_file("example_flight.csv")
fuelflow(initial_mass=None, typecode=None, engine=None)

Estimates the fuel flow with OpenAP.

The OpenAP model is based on the aircraft type (actually, the most probable engine type) and on three features commonly available in ADS-B data:

  • altitude (in ft),

  • vertical rate (in ft/min), and

  • speed (in kts), in order of priority, TAS (true air speed), CAS (computed air speed, used to compute TAS) and groundspeed, if no air speed is available.

Parameters:
  • initial_mass (Union[None, str, float]) – by default (None), 90% of the maximum take-off weight. You can also pass a value to initialise the mass. When initial_mass > 1, the mass is in kg. When initial_mass <= 1, it represents the fraction of the maximum take-off weight.

  • typecode (Optional[str]) – by default (None), use the typecode column if available, the provided aircraft database to infer the typecode based on the icao24. Ignored if the engine parameter is not None.

  • engine (Optional[str]) – by default (None), use the default engine associated with the aircraft type.

Return type:

Flight

Returns:

the same instance enriched with three extra features: the mass, the fuel flow (in kg/s) and the total burnt fuel (in kg).

geoencode(**kwargs)

Returns an altair encoding of the shape to be composed in an interactive visualization. Specific plot features, such as line widths, can be passed with the kwargs argument. See documentation.

Return type:

Chart

geojson()

Returns the GeoJSON representation of the shape as a Dict. The transformation is delegated to shapely mapping method.

Return type:

dict[str, Any] | list[dict[str, Any]]

go_around(airport=None, dataset=None, **kwargs)

Detects go-arounds.

The method yields pieces of trajectories with exactly two landing attempts (aligned on one runway) on the same airport separated by exactly one climbing phase.

Parameters:
  • airport (None | str | ‘Airport) – If None, the method tries to guess the landing airport based on the dataset parameter. (see landing_airport())

  • dataset (None | ‘Airports) – database of candidate airports, only used if airport is None

Return type:

FlightIterator

See also: How to select go-arounds from a set of trajectories?

ground_trajectory(airport)

Returns the ground part of the trajectory limited to the apron of the airport passed in parameter.

The same trajectory could use the apron several times, hence the safest option to return a FlightIterator.

Return type:

FlightIterator

groupby(*args, **kwargs)

Applies the Pandas groupby() method to the underlying pandas DataFrame.

Return type:

DataFrameGroupBy

has(method)

Returns True if flight.method() returns a non-empty iterator.

Example usage:

Return type:

bool

>>> flight.has("go_around")
>>> flight.has("runway_change")
>>> flight.has(lambda f: f.aligned_on_ils("LFBO"))
holding_pattern(duration='6 min', step='2 min', threshold='5 min', samples=30, model_path=None, vertical_rate=False)

Iterates on all holding pattern segments in the trajectory.

This approach is based on a neuronal network model. Details will be published in a coming academic publication.

Parameters should be left as default as they are strongly coupled with the proposed model.

The model has been trained on manually labelled holding patterns for trajectories landing at different European airports including London Heathrow.

(new in version 2.8)

Return type:

FlightIterator

property holes: int

Returns the number of ‘holes’ in a trajectory.

property icao24: str | Set[str] | None

Returns the unique icao24 value(s) of the DataFrame.

icao24 (ICAO 24-bit address) is a unique identifier associated to a transponder. These identifiers correlate to the aircraft registration.

For example icao24 code ‘ac82ec’ is associated to ‘N905NA’.

inside_bbox(bounds)

Returns the part of the DataFrame with coordinates located within the bounding box of the shape passed in parameter. :rtype: Optional[TypeVar(T, bound= GeographyMixin)]

The bounds parameter can be:

  • an Airspace,

  • a shapely Geometry,

  • a tuple of floats (west, south, east, north)

Note

This method will use the :class:Flight implementation when stacked for lazy evaluation.

intersects(shape)

Returns True if the trajectory is inside the given shape. :rtype: bool

  • If an Airspace is passed, the 3D trajectory is compared to each layers constituting the airspace, with corresponding altitude limits.

  • If a shapely Geometry is passed, the 2D trajectory alone is considered.

is_from_inertial(freq_threshold=0.05)

Returns True if ground trajectory data looks noisy. :rtype: bool

Warning

This method is still experimental and tries to catch trajectories based on the inertial system rather than the GPS. It catches zig-zag patterns but fails to get trajectories driving between taxiways.

label(method, **kwargs)

Returns the same flight with extra information from iterators.

Every keyword argument will be used to create a new column in the Flight dataframe, filled by default with None values: :rtype: Flight

  • if the passed value is True, the default one is False

  • if the passed value is a string:
    • “{i}” will be replaced by the index of the segment;

    • “{segment}” will be replaced by the current piece of trajectory;

    • “{self}” will be replaced by the current flight instance

If a function is passed it will be evaluated with:

  • the current piece of trajectory (segment) if the function or the lambda has one argument;

  • the index and the segment if the function or the lambda has two arguments;

  • the index, the segment and the flight if the function or the lamdba has three arguments;

Before returning, the dataframe applies convert_dtypes() and so None values maybe replaced by NaT or NaN values.

Example usage:

  • Add a column holding which is True when the trajectory follows a holding pattern

    flight.label(holding_pattern, holding=True)
    
  • Add a column index to enumerate holding patterns:

    flight.label(holding_pattern, index="{i}")
    
  • More complicated enriching:

    flight.label(
        "aligned_on_ils('LSZH')",
        aligned=True,
        label="{self.flight_id}_{i}",
        index=lambda i, segment: i,
        start=lambda segment: segment.start,
        altitude_max=lambda segment: segment.altitude_max
    )
    
landing_airport(**kwargs)

Returns the most probable landing airport based on the last location in the trajectory.

>>> belevingsvlucht.landing_airport()
EHAM/AMS: Amsterdam  Schiphol

When data is missing near the ground, it may be relevant to specify a subset of airports as a keyword parameter.

>>> missing_data = belevingsvlucht.before("2018-05-30 20:00")
>>> missing_data.landing_airport()
NL-0024/nan: Middenmeer Aerodrome

>>> large_airports = airports.query("type == 'large_airport'")
>>> missing_data.landing_airport(dataset=large_airports)
EHAM/AMS: Amsterdam  Schiphol
Return type:

Airport

landing_at(airport)

Returns True if the flight lands at the given airport.

Return type:

bool

landing_attempts(dataset=None, **kwargs)

Iterates on all landing attempts for current flight.

First, candidates airports are identified in the neighbourhood of the segments of trajectory below 10,000 ft. By default, the full airport database is considered but it is possible to restrict it and pass a smaller database with the dataset parameter.

If no runway information is available for the given airport, no trajectory segment will be provided. :rtype: FlightIterator

Warning

This API is not stable yet. The interface may change in a near future.

last(value=None, **kwargs)

Returns the last n days, hours, minutes or seconds of the Flight.

The elements passed as kwargs as passed as is to the datetime.timedelta constructor.

Example usage:

Return type:

Flight

>>> flight.last(minutes=10)
>>> flight.last("1h")
>>> flight.last(10)  # seconds by default
leaflet(**kwargs)

Returns a Leaflet layer to be directly added to a Map.

The elements passed as kwargs as passed as is to the PolyLine constructor.

Example usage:

Return type:

Optional[Polyline]

>>> from ipyleaflet import Map
>>> # Center the map near the landing airport
>>> m = Map(center=flight.at().latlon, zoom=7)
>>> m.add(flight)
>>> m.add(flight.leaflet(color='red'))
>>> m
line_geo(**kwargs)

Create a line plot with Plotly.

Requires the plotly package (optional dependency).

Return type:

Figure

line_map(map_style='carto-positron', **kwargs)

Create a line plot with Plotly.

Requires the plotly package (optional dependency).

Return type:

Figure

longer_than(value, strict=True)

Returns True if flight duration is longer than value.

Return type:

bool

max(feature)

Returns the maximum value of given feature.

Return type:

Any

>>> flight.max('altitude')  # dummy example
35000
max_split(value='10 min', unit=None, key='duration')

Returns the biggest (by default, longest) part of trajectory.

Example usage:

Return type:

Optional[Flight]

>>> from traffic.data.samples import elal747
>>> elal747.query("altitude < 15000").max_split()
Flight ELY1747
aircraft: 738043 · 🇮🇱 4X-ELC (B744)
origin: LIRF (2019-11-03 12:14:40+00:00)
destination: LLBG (2019-11-03 14:13:00+00:00)

In this example, the fancy part of the trajectory occurs below 15,000 ft. The command extracts the plane pattern.

mean(feature)

Returns the average value of given feature.

Return type:

Any

>>> flight.mean('vertical_rate')  # dummy example
-1000
merge(*args, **kwargs)

Applies the Pandas merge() method to the underlying pandas DataFrame and get the result back in the same structure.

Return type:

Self

min(feature)

Returns the minimum value of given feature.

Return type:

Any

>>> flight.min('altitude')  # dummy example
24000
moving(speed_threshold=2, time_threshold='30s', filter_dict={'compute_gs': 3}, resample_rule='5s')

Returns the part of the trajectory after the aircraft starts moving. :rtype: Optional[Flight]

Warning

This method has been extensively tested on aircraft taxiing before take-off. It should be adapted/taken with extra care for trajectories after landing.

next(method)

Returns the first segment of trajectory yielded by flight.method()

Return type:

Optional[Flight]

>>> flight.next("go_around")
>>> flight.next("runway_change")
>>> flight.next(lambda f: f.aligned_on_ils("LFBO"))
property number: str | Set[str] | None

Returns the unique number value(s) associated to the Flight.

This field is reserved for the commercial number of the flight, prefixed by the two letter code of the airline. For instance, AFR292 is the callsign and AF292 is the flight number.

Callsigns are often more complicated as they are designed to limit confusion on the radio: hence DLH02X can be the callsign associated to flight number LH1100.

on_parking_position(airport, buffer_size=1e-05, parking_positions=None)

Generates possible parking positions at a given airport.

Example usage:

Return type:

FlightIterator

>>> parking = flight.on_parking_position('LSZH').max()
# returns the most probable parking position in terms of duration

Warning

This method has been well tested for aircraft taking off, but should be double checked for landing trajectories.

on_runway(airport)

Returns the longest segment of trajectory which perfectly matches a runway at given airport.

>>> landing = belevingsvlucht.last(minutes=30).on_runway("EHAM")
>>> landing.mean("altitude")
-26.0

>>> takeoff = belevingsvlucht.first(minutes=30).on_runway("EHAM")
>>> takeoff.mean("altitude")
437.27272727272725
Return type:

Optional[Flight]

on_taxiway(airport_or_taxiways, *, tolerance=15, max_dist=85)

Iterates on segments of trajectory matching a single runway label.

Return type:

FlightIterator

property origin: str | Set[str] | None

Returns the unique origin value(s), None if not available in the DataFrame.

The origin airport is usually represented as a ICAO or a IATA code.

The ICAO code of an airport is represented by 4 letters (e.g. EHAM for Amsterdam Schiphol International Airport) and the IATA code is represented by 3 letters and more familiar to the public (e.g. AMS for Amsterdam)

phases(twindow=60)

Assign a flight phase to each timestamp of a flight using OpenAP phase detection fuzzy logic method.

Return type:

Flight

pipe(func, *args, **kwargs)

Applies func to the object. :rtype: None | Flight | bool

Warning

The logic is similar to that of pipe() method, but the function applies on T, not on the DataFrame.

plot(ax, **kwargs)

Plots the trajectory on a Matplotlib axis.

The Flight supports Cartopy axis as well with automatic projection. If no projection is provided, a default PlateCarree is applied.

Example usage:

from cartes.crs import Mercator
fig, ax = plt.subplots(1, subplot_kw=dict(projection=Mercator())
flight.plot(ax, alpha=.5)
Return type:

List[Artist]

Note

See also geoencode() for the altair equivalent.

plot_time(ax, y, secondary_y=None, **kwargs)

Plots the given features according to time.

The method ensures: :rtype: None

  • only non-NaN data are displayed (no gap in the plot);

  • the timestamp is naively converted to UTC if not localized.

Example usage:

ax = plt.axes()
# most simple version
flight.plot_time(ax, 'altitude')
# or with several comparable features and twin axes
flight.plot_time(
    ax, ['altitude', 'groundspeed', 'IAS', 'TAS'],
    secondary_y=['altitude']
)

Note

See also chart() for the altair equivalent.

plot_wind(ax, resolution='5 min', filtered=False, **kwargs)

Plots the wind field seen by the aircraft on a Matplotlib axis.

The Flight supports Cartopy axis as well with automatic projection. If no projection is provided, a default PlateCarree is applied.

The resolution argument may be: :rtype: List[Artist]

  • None for a raw plot;

  • an integer or a string to pass to a Flight.resample() method as a preprocessing before plotting;

  • or a dictionary, e.g dict(latitude=4, longitude=4), if you want a grid with a resolution of 4 points per latitude and longitude degree.

Example usage:

from cartes.crs import Mercator
fig, ax = plt.subplots(1, subplot_kw=dict(projection=Mercator()))
(
    flight
    .resample("1s")
    .query('altitude > 10000')
    .compute_wind()
    .plot_wind(ax, alpha=.5)
)
point_merge(point_merge, secondary_point=None, distance_interval=None, delta_threshold=0.05, airport=None, runway=None, **kwargs)

Iterates on all point merge segments in a trajectory before landing at a given airport.

Only the point_merge argument is mandatory but other arguments may reduce the number of false positives.

Parameters:
  • point_merge (str | PointMixin | list[PointMergeParams]) – The procedure point on which trajectories all align.

  • secondary_point (None | str | PointMixin) –

    In some cases (e.g. Dublin 10R), aircraft align to the point_merge after a segment of almost constant distance to a secondary point.

    Most often, the secondary_point is the point_merge and can be left as None.

  • distance_interval (None | tuple[float, float]) –

    A tuple of distances in nautical miles, corresponding to lower and upper bound distances in the AIP between the constant distance segments and the point merge.

    This parameter is ignored if left as None.

  • delta_threshold (float) – keep as default

  • airport (None | str | Airport) – Remove false positives by specifying the landing airport. The algorithm will ensure all trajectories are aligned with one of the airport’s ILS.

  • runway (None | str) – Remove false positives by specifying the landing runway. The algorithm will ensure all trajectories are aligned with the runway’s ILS. (ignored if airport is None)

Return type:

FlightIterator

(new in version 2.8)

project_shape(projection=None)

Returns a projected representation of the shape.

Parameters:

projection (None | pyproj.Proj | ‘crs.Projection) – By default (None), an equivalent projection is applied. Equivalent projections locally respect areas, which is convenient for the area attribute.

Return type:

base.BaseGeometry

pushback(airport, filter_dict={'compute_gs': 21, 'compute_track': 21, 'compute_track_unwrapped': 21}, track_threshold=90, parking_positions=None)

Returns the pushback part of the trajectory on ground.

The method identifies the start of the movement, the parking_position and the moment the aircraft suddenly changes direction the computed track angle. :rtype: Optional[‘Flight’]

Warning

The method has poor performance when trajectory point on ground are lacking. This is often the case for data recorded from locations far from the airport.

query(query_str, *args, **kwargs)

Applies the Pandas query() method to the underlying pandas DataFrame and get the result back in the same structure.

Return type:

Optional[Self]

query_ehs(data=None, failure_mode='info', **kwargs)

Extends data with extra columns from EHS messages.

By default, raw messages are requested from the OpenSky Network database. :rtype: Flight

Warning

Making a lot of small requests can be very inefficient and may look like a denial of service. If you get the raw messages using a different channel, you can provide the resulting dataframe as a parameter. See the page about OpenSky Impala access

The data parameter expect three columns: icao24, rawmsg and mintime, in conformance with the OpenSky API.

Note

Read more about access to the OpenSky Network database here

query_opensky(**kwargs)

Returns data from the same Flight as stored in OpenSky database.

This may be useful if you write your own parser for data from a different channel. The method will use the callsign and icao24 attributes to build a request for current Flight in the OpenSky Network database.

The kwargs argument helps overriding arguments from the query, namely start, stop, callsign and icao24.

Returns None if no data is found. :rtype: Optional[Flight]

Note

Read more about access to the OpenSky Network database here

rename(*args, **kwargs)

Applies the Pandas rename() method to the underlying pandas DataFrame and get the result back in the same structure.

Return type:

Self

replace(*args, **kwargs)

Applies the Pandas replace() method to the underlying pandas DataFrame and get the result back in the same structure.

Return type:

Self

resample(rule='1s', how='interpolate', interpolate_kw={}, projection=None)

Resample the trajectory at a given frequency or for a target number of samples.

Parameters:
  • rule (str | int) –

    • If the rule is a string representing Offset aliases for time frequencies is passed, then the data is resampled along the timestamp axis, then interpolated (according to the how parameter).

    • If the rule is an integer, the trajectory is resampled to the given number of evenly distributed points per trajectory.

  • how (None | str | dict[str, Iterable[str]]) –

    (default: "interpolate")

    • When the parameter is a string, the method applies to all columns

    • When the parameter is a dictionary with keys as methods (e.g. "interpolate", "ffill") and names of columns as values. Columns not included in any value are left as is.

  • interpolate_kw (dict[str, Any]) –

    (default: {})

    • A dictionary with keyword arguments that will be passed to the pandas :py:method:`pandas.Series.interpolate` method.

      Example usage: To specify a fifth-degree polynomial interpolation, you can pass the following dictionary:

      
      

      interpolate_kw = {“method”: “polynomial”, “order”: 5}

  • projection (None | str | pyproj.Proj | ‘crs.Projection) –

    (default: None)

    • By default, lat/lon are resampled with a linear interpolation;

    • If a projection is passed, the linear interpolation is applied on the x and y dimensions, then lat/lon are reprojected back;

    • If the projection is a string parameter, e.g. "lcc", a projection is created on the fly, centred on the trajectory. This approach is helpful to fill gaps along a great circle.

Return type:

Flight

reset_index(*args, **kwargs)

Applies the Pandas reset_index() method to the underlying pandas DataFrame and get the result back in the same structure.

Return type:

Self

runway_change(airport=None, dataset=None, **kwargs)

Detects runway changes.

The method yields pieces of trajectories with exactly two runway alignments on the same airport not separated by a climbing phase.

In each piece of yielded trajectory, the ILS column contains the name of the runway targetted by the aircraft at each instant.

Return type:

FlightIterator

scatter_geo(**kwargs)

Create a scatter plot with Plotly.

Requires the plotly package (optional dependency).

Return type:

Figure

scatter_map(map_style='carto-positron', **kwargs)

Create a scatter plot with Plotly.

Requires the plotly package (optional dependency).

Return type:

Figure

shorten(value=None, **kwargs)

Removes the last n days, hours, minutes or seconds of the Flight.

The elements passed as kwargs as passed as is to the datetime.timedelta constructor.

Example usage:

Return type:

Optional[Flight]

>>> flight.shorten(minutes=10)
>>> flight.shorten("1h")
>>> flight.shorten(10)  # seconds by default
shorter_than(value, strict=True)

Returns True if flight duration is shorter than value.

Return type:

bool

simplify(tolerance, altitude=None, z_factor=3.048)

Simplifies a trajectory with Douglas-Peucker algorithm.

The method uses latitude and longitude, projects the trajectory to a conformal projection and applies the algorithm. If x and y features are already present in the DataFrame (after a call to compute_xy for instance) then this projection is taken into account.

The tolerance parameter must be defined in meters. :rtype: Flight

  • By default, a 2D version of the algorithm is called, unless you pass a column name for altitude.

  • You may scale the z-axis for more relevance (z_factor). The default value works well in most situations.

The method returns a Flight or a 1D mask if you specify return_mask=True.

See also: How to simplify or resample a trajectory?

skip(value=None, **kwargs)

Removes the first n days, hours, minutes or seconds of the Flight.

The elements passed as kwargs as passed as is to the datetime.timedelta constructor.

Example usage:

Return type:

Optional[Flight]

>>> flight.skip(minutes=10)
>>> flight.skip("1h")
>>> flight.skip(10)  # seconds by default
slow_taxi(min_duration='60s', max_diameter=150)

Holding segments are part of a trajectory where the aircraft stays more than min_duration (in s) within a circle of diameter max_diameter (in m)

Return type:

FlightIterator

sort_values(by, **kwargs)

Applies the Pandas sort_values() method to the underlying pandas DataFrame and get the result back in the same structure.

Return type:

Self

split(value=10, unit=None, condition=None)

Iterates on legs of a Flight based on the distribution of timestamps.

By default, the method stops a flight and yields a new one after a gap of 10 minutes without data.

The length of the gap (here 10 minutes) can be expressed: :rtype: FlightIterator

  • in the NumPy style: Flight.split(10, 'm') (see np.timedelta64);

  • in the pandas style: Flight.split('10 min') (see pd.Timedelta)

If the condition parameter is set, the flight is split between two segments only if condition(f1, f2) is verified.

Example:

def no_split_below_5000ft(f1, f2):
    first = f1.data.iloc[-1].altitude >= 5000
    second = f2.data.iloc[0].altitude >= 5000
    return first or second

# would yield many segments
belevingsvlucht.query('altitude > 2000').split('1 min')

# yields only one segment
belevingsvlucht.query('altitude > 2000').split(
    '1 min', condition = no_split_below_5000ft
)
property squawk: Set[str]

Returns all the unique squawk values in the trajectory.

A squawk code is a four-digit number assigned by ATC and set on the transponder. Some squawk codes are reserved for specific situations and emergencies, e.g. 7700 for general emergency, 7600 for radio failure or 7500 for hijacking.

property start: Timestamp

Returns the minimum value of timestamp.

property stop: Timestamp

Returns the maximum value of timestamp.

sum(method)

Returns the number of segments returned by flight.method().

Example usage:

Return type:

int

>>> flight.sum("go_around")
>>> flight.sum("runway_change")
>>> flight.sum(lambda f: f.aligned_on_ils("LFBO"))
summary(attributes)

Returns a summary of the current Flight structure containing featured attributes.

Example usage:

Return type:

dict[str, Any]

>>> t.summary(['icao24', 'start', 'stop', 'duration'])

Consider monkey-patching properties to the Flight class if you need more information in your summary dictionary.

takeoff_airport(**kwargs)

Returns the most probable takeoff airport based on the first location in the trajectory.

>>> belevingsvlucht.takeoff_airport()
EHAM/AMS: Amsterdam  Schiphol

When data is missing near the ground, it may be relevant to specify a subset of airports as a keyword parameter.

>>> missing_data = belevingsvlucht.after("2018-05-30 15:30")
>>> missing_data.takeoff_airport()
NL-0015/nan: Universitair Medisch Centrum Utrecht Heliport

>>> large_airports = airports.query("type == 'large_airport'")
>>> missing_data.takeoff_airport(dataset=large_airports)
EHAM/AMS: Amsterdam  Schiphol
Return type:

Airport

takeoff_from(airport)

Returns True if the flight takes off from the given airport.

Return type:

bool

takeoff_from_runway(airport, threshold_alt=2000, zone_length=6000, little_base=50, opening=5)

Identifies the take-off runway for trajectories.

Iterates on all segments of trajectory matching a zone around a runway of the given airport. The takeoff runway number is appended as a new runway column.

Return type:

FlightIterator

thermals()

Detects thermals for gliders.

Return type:

FlightIterator

to_csv(filename, *args, **kwargs)

Exports to CSV format.

Options can be passed to pandas.DataFrame.to_csv() as args and kwargs arguments.

Read more: How to export and store trajectory and airspace data?

Return type:

None

to_excel(filename, *args, **kwargs)

Exports to Excel format.

Options can be passed to pandas.DataFrame.to_excel() as args and kwargs arguments.

Read more: How to export and store trajectory and airspace data?

Return type:

None

to_feather(filename, *args, **kwargs)

Exports to feather format.

Options can be passed to pandas.DataFrame.to_feather() as args and kwargs arguments.

Read more: How to export and store trajectory and airspace data?

Return type:

None

to_hdf(filename, *args, **kwargs)

Exports to HDF format.

Options can be passed to pandas.DataFrame.to_hdf() as args and kwargs arguments.

Read more: How to export and store trajectory and airspace data?

Return type:

None

to_json(filename, *args, **kwargs)

Exports to JSON format.

Options can be passed to pandas.DataFrame.to_json() as args and kwargs arguments.

Read more: How to export and store trajectory and airspace data?

Return type:

None

to_parquet(filename, *args, **kwargs)

Exports to parquet format.

Options can be passed to pandas.DataFrame.to_parquet() as args and kwargs arguments.

Read more: How to export and store trajectory and airspace data?

Return type:

None

to_pickle(filename, *args, **kwargs)

Exports to pickle format.

Options can be passed to pandas.DataFrame.to_pickle() as args and kwargs arguments.

Read more: How to export and store trajectory and airspace data?

Return type:

None

unwrap(features=None)

Unwraps angles in the DataFrame.

All features representing angles may be unwrapped (through Numpy) to avoid gaps between 359° and 1°.

The method applies by default to features track and heading. More or different features may be passed in parameter.

Return type:

Flight