pycontrails.Fleet¶
- class pycontrails.Fleet(data=None, *, longitude=None, latitude=None, altitude=None, altitude_ft=None, level=None, time=None, attrs=None, copy=True, fuel=None, fl_attrs=None, **attrs_kwargs)¶
Bases:
Flight
Data structure for holding a sequence of
Flight
instances.Flight waypoints are merged into a single
Flight
-like object.- __init__(data=None, *, longitude=None, latitude=None, altitude=None, altitude_ft=None, level=None, time=None, attrs=None, copy=True, fuel=None, fl_attrs=None, **attrs_kwargs)¶
Methods
T_isa
()Calculate the ICAO standard atmosphere temperature at each point.
__init__
([data, longitude, latitude, ...])broadcast_attrs
(keys[, overwrite, raise_error])Attach values from
keys
inattrs
ontodata
.broadcast_numeric_attrs
([ignore_keys, overwrite])Attach numeric values in
attrs
ontodata
.clean_and_resample
([freq, fill_method, ...])Resample and (possibly) filter a flight trajectory.
coords_intersect_met
(met)Return boolean mask of data inside the bounding box defined by
met
.copy
(**kwargs)Return a copy of this instance.
create_empty
([keys, attrs])Create instance with variables defined by
keys
and size 0.distance_to_coords
(distance)Convert distance along flight path to geodesic coordinates.
downselect_met
(met, *[, longitude_buffer, ...])Downselect
met
to encompass a spatiotemporal region of the data.ensure_vars
(vars[, raise_error])Ensure variables exist in column of
data
orattrs
.filter
(mask[, copy])Filter
data
according to a boolean arraymask
.filter_altitude
([kernel_size, cruise_threshold])Filter noisy altitude on a single flight.
filter_by_first
()Keep first row of group of waypoints with identical coordinates.
from_dict
(obj[, copy])Create instance from dict representation containing data and attrs.
from_seq
(seq[, broadcast_numeric, copy, attrs])generate_splits
(n_splits[, copy])Split instance into
n_split
sub-vectors.get
(key[, default_value])Get values from
data
withdefault_value
ifkey
not indata
.get_data_or_attr
(key[, default])Get value from
data
orattrs
.intersect_met
(mda, *[, longitude, latitude, ...])Intersect waypoints with MetDataArray.
length_met
(key[, threshold])Calculate total horizontal distance where column
key
exceedsthreshold
.plot
(**kwargs)Plot flight trajectory longitude-latitude values.
plot_profile
(**kwargs)Plot flight trajectory time-altitude values.
proportion_met
(key[, threshold])Calculate proportion of flight with certain meteorological constraint.
resample_and_fill
(*args, **kwargs)Resample and fill flight trajectory with geodesics and linear interpolation.
Calculate sine and cosine for the angle between each segment and the longitudinal axis.
Calculate (forward) azimuth at each waypoint.
segment_duration
([dtype])Compute time elapsed between waypoints in seconds.
segment_groundspeed
(*args, **kwargs)Return groundspeed across segments.
segment_haversine
()Compute Haversine (great circle) distance between flight waypoints.
Compute spherical distance between flight waypoints.
segment_mach_number
(true_airspeed, ...)Calculate the mach number of each segment.
segment_phase
([threshold_rocd, ...])Identify the phase of flight (climb, cruise, descent) for each segment.
segment_rocd
([air_temperature])Calculate the rate of climb and descent (ROCD).
segment_true_airspeed
([u_wind, v_wind, ...])Calculate the true airspeed [\(m / s\)] from the ground speed and horizontal winds.
select
(keys[, copy])Return new class instance only containing specified keys.
setdefault
(key[, default])Shortcut to
VectorDataDict.setdefault()
.sort
(by)Sort data by key(s).
sum
(vectors[, infer_attrs, fill_value])Sum a list of
VectorDataset
instances.to_dataframe
([copy])Create
pd.DataFrame
in which each key-value pair indata
is a column.to_dict
()Create dictionary with
data
andattrs
.to_flight_list
([copy])De-concatenate merged waypoints into a list of
Flight
instances.to_geojson_linestring
()Return trajectory as geojson FeatureCollection containing single LineString.
to_geojson_multilinestring
([key, ...])Return trajectory as GeoJSON FeatureCollection of MultiLineStrings.
to_geojson_points
()Return dataset as GeoJSON FeatureCollection of Points.
to_lon_lat_grid
(agg, *[, spatial_bbox, ...])Convert vectors to a longitude-latitude grid.
to_traffic
()Convert to :class:`traffic.core.Flight`instance.
transform_crs
(crs)Transform trajectory data from one coordinate reference system (CRS) to another.
update
([other])Update values in
data
dict without warning if overwriting.Attributes
air_pressure
Get
air_pressure
values for points.altitude
Get altitude.
altitude_ft
Get altitude in feet.
attrs
Generic dataset attributes
constants
Return a dictionary of constant attributes and data values.
coords
Get geospatial coordinates for compatibility with MetDataArray.
data
Vector data with labels as keys and
numpy.ndarray
as valuesdataframe
Shorthand property to access
to_dataframe()
withcopy=False
.duration
Determine flight duration.
fuel
Fuel used in flight trajectory
hash
Generate a unique hash for this class instance.
length
Return flight length based on WGS84 geodesic.
level
Get pressure
level
values for points.Return maximum distance gap between waypoints along flight trajectory.
max_time_gap
Return maximum time gap between waypoints along flight trajectory.
Return number of distinct flights.
required_keys
Required keys for creating GeoVectorDataset
shape
Shape of each array in
data
.size
Length of each array in
data
.time_end
Last waypoint time.
time_start
First waypoint time.
vertical_keys
At least one of these vertical-coordinate keys must also be included
- clean_and_resample(freq='1min', fill_method='geodesic', geodesic_threshold=100000.0, nominal_rocd=0.0, kernel_size=17, cruise_threshold=120, force_filter=False, drop=True, keep_original_index=False, climb_descend_at_end=False)¶
Resample and (possibly) filter a flight trajectory.
Waypoints are resampled according to the frequency
freq
. If the original flight data has a short sampling period, filter_altitude will also be called to clean the data. Large gaps in trajectories may be interpolated as step climbs through _altitude_interpolation.- Parameters:
freq (
str
, optional) – Resampling frequency, by default “1min”fill_method (
{"geodesic", "linear"}
, optional) – Choose between"geodesic"
and"linear"
, by default"geodesic"
. In geodesic mode, large gaps between waypoints are filled with geodesic interpolation and small gaps are filled with linear interpolation. In linear mode, all gaps are filled with linear interpolation.geodesic_threshold (
float
, optional) – Threshold for geodesic interpolation, [\(m\)]. If the distance between consecutive waypoints is under this threshold, values are interpolated linearly.nominal_rocd (
float
, optional) – Nominal rate of climb / descent for aircraft type. Defaults toconstants.nominal_rocd
.kernel_size (
int
, optional) – Passed directly toscipy.signal.medfilt()
, by default 11. Passed also toscipy.signal.medfilt()
cruise_theshold (
float
, optional) – Minimal length of time, in seconds, for a flight to be in cruise to apply median filterforce_filter (
bool
, optional) – If set to true, meth:filter_altitude will always be called. otherwise, it will only be called if the flight has a median sample period under 10 secondsdrop (
bool
, optional) – Drop any columns that are not resampled and filled. Defaults toTrue
, dropping all keys outside of “time”, “latitude”, “longitude” and “altitude”. If set to False, the extra keys will be kept but filled withnan
orNone
values, depending on the data type.keep_original_index (
bool
, optional) – Keep the original index of theFlight
in addition to the new resampled index. Defaults toFalse
. .. versionadded:: 0.45.2climb_or_descend_at_end (
bool
) – If true, the climb or descent will be placed at the end of each segment rather than the start. Default is false (climb or descent immediately).
- Returns:
Flight
– Filled Flight
- copy(**kwargs)¶
Return a copy of this instance.
- Parameters:
**kwargs (
Any
) – Additional keyword arguments passed into the constructor of the returned class.- Returns:
Self
– Copy of class
- filter(mask, copy=True, **kwargs)¶
Filter
data
according to a boolean arraymask
.Entries corresponding to
mask == True
are kept.- Parameters:
mask (
npt.NDArray[np.bool_]
) – Boolean array with compatible shape.copy (
bool
, optional) – Copy data on filter. Defaults to True. See numpy best practices for insight into whether copy is appropriate.**kwargs (
Any
) – Additional keyword arguments passed into the constructor of the returned class.
- Returns:
Self
– Containing filtered data- Raises:
TypeError – If
mask
is not a boolean array.
- final_waypoints¶
- fl_attrs¶
- classmethod from_seq(seq, broadcast_numeric=True, copy=True, attrs=None)¶
Instantiate a
Fleet
instance from an iterable ofFlight
.Changed in version 0.49.3: Empty flights are now filtered out before concatenation.
- Parameters:
seq (
Iterable[Flight]
) – An iterable ofFlight
instances.broadcast_numeric (
bool
, optional) – If True, broadcast numeric attributes to data variables.copy (
bool
, optional) – If True, make copy of each flight instance inseq
.attrs (
dict[str
,Any] | None
, optional) – Global attribute to attach to instance.
- Returns:
Fleet
– A Fleet instance made from concatenating theFlight
instances inseq
. The fuel type is taken from the firstFlight
inseq
.
- property max_distance_gap¶
Return maximum distance gap between waypoints along flight trajectory.
Distance is calculated based on WGS84 geodesic.
- Returns:
float
– Maximum distance between waypoints, [\(m\)]
Examples
>>> import numpy as np >>> fl = Flight( ... longitude=np.linspace(20, 30, 200), ... latitude=np.linspace(40, 30, 200), ... altitude=11000 * np.ones(200), ... time=pd.date_range('2021-01-01T12', '2021-01-01T14', periods=200), ... ) >>> fl.max_distance_gap np.float64(7391.27...)
- resample_and_fill(*args, **kwargs)¶
Resample and fill flight trajectory with geodesics and linear interpolation.
Waypoints are resampled according to the frequency
freq
. Values fordata
columnslongitude
,latitude
, andaltitude
are interpolated.Resampled waypoints will include all multiples of
freq
between the flight start and end time. For example, when resampling to a frequency of 1 minute, a flight that starts at 2020/1/1 00:00:59 and ends at 2020/1/1 00:01:01 will return a single waypoint at 2020/1/1 00:01:00, whereas a flight that starts at 2020/1/1 00:01:01 and ends at 2020/1/1 00:01:59 will return an empty flight.- Parameters:
freq (
str
, optional) – Resampling frequency, by default “1min”fill_method (
{"geodesic", "linear"}
, optional) – Choose between"geodesic"
and"linear"
, by default"geodesic"
. In geodesic mode, large gaps between waypoints are filled with geodesic interpolation and small gaps are filled with linear interpolation. In linear mode, all gaps are filled with linear interpolation.geodesic_threshold (
float
, optional) – Threshold for geodesic interpolation, [\(m\)]. If the distance between consecutive waypoints is under this threshold, values are interpolated linearly.nominal_rocd (
float | None
, optional) – Nominal rate of climb / descent for aircraft type. Defaults toconstants.nominal_rocd
.drop (
bool
, optional) – Drop any columns that are not resampled and filled. Defaults toTrue
, dropping all keys outside of “time”, “latitude”, “longitude” and “altitude”. If set to False, the extra keys will be kept but filled withnan
orNone
values, depending on the data type.keep_original_index (
bool
, optional) – Keep the original index of theFlight
in addition to the new resampled index. Defaults toFalse
. .. versionadded:: 0.45.2climb_or_descend_at_end (
bool
) – If true, the climb or descent will be placed at the end of each segment rather than the start. Default is false (climb or descent immediately).
- Returns:
Flight
– Filled Flight- Raises:
ValueError – Unknown
fill_method
Examples
>>> from datetime import datetime >>> import pandas as pd
>>> df = pd.DataFrame() >>> df['longitude'] = [0, 0, 50] >>> df['latitude'] = 0 >>> df['altitude'] = 0 >>> df['time'] = [datetime(2020, 1, 1, h) for h in range(3)]
>>> fl = Flight(df) >>> fl.dataframe longitude latitude altitude time 0 0.0 0.0 0.0 2020-01-01 00:00:00 1 0.0 0.0 0.0 2020-01-01 01:00:00 2 50.0 0.0 0.0 2020-01-01 02:00:00
>>> fl.resample_and_fill('10min').dataframe # resample with 10 minute frequency longitude latitude altitude time 0 0.000000 0.0 0.0 2020-01-01 00:00:00 1 0.000000 0.0 0.0 2020-01-01 00:10:00 2 0.000000 0.0 0.0 2020-01-01 00:20:00 3 0.000000 0.0 0.0 2020-01-01 00:30:00 4 0.000000 0.0 0.0 2020-01-01 00:40:00 5 0.000000 0.0 0.0 2020-01-01 00:50:00 6 0.000000 0.0 0.0 2020-01-01 01:00:00 7 8.333333 0.0 0.0 2020-01-01 01:10:00 8 16.666667 0.0 0.0 2020-01-01 01:20:00 9 25.000000 0.0 0.0 2020-01-01 01:30:00 10 33.333333 0.0 0.0 2020-01-01 01:40:00 11 41.666667 0.0 0.0 2020-01-01 01:50:00 12 50.000000 0.0 0.0 2020-01-01 02:00:00
- segment_angle()¶
Calculate sine and cosine for the angle between each segment and the longitudinal axis.
This is different from the usual navigational angle between two points known as bearing.
Bearing in 3D spherical coordinates is referred to as azimuth.
(lon_2, lat_2) X /| / | / | / | / | / | / | (lon_1, lat_1) X -------> longitude (x-axis)
- Returns:
npt.NDArray[np.float64]
,npt.NDArray[np.float64]
– Returnssin(a), cos(a)
, wherea
is the angle between the segment and the longitudinal axis. The final values are of both arrays arenp.nan
.
See also
geo.segment_angle()
,units.heading_to_longitudinal_angle()
,segment_azimuth()
,geo.forward_azimuth()
Examples
>>> from pycontrails import Flight >>> fl = Flight( ... longitude=np.array([1, 2, 3, 5, 8]), ... latitude=np.arange(5), ... altitude=np.full(shape=(5,), fill_value=11000), ... time=pd.date_range('2021-01-01T12', '2021-01-01T14', periods=5), ... ) >>> sin, cos = fl.segment_angle() >>> sin array([0.70716063, 0.70737598, 0.44819424, 0.31820671, nan])
>>> cos array([0.70705293, 0.70683748, 0.8939362 , 0.94802136, nan])
- segment_azimuth()¶
Calculate (forward) azimuth at each waypoint.
Method calls pyproj.Geod.inv, which is slow. See geo.forward_azimuth for an outline of a faster implementation.
Changed in version 0.33.7: The dtype of the output now matches the dtype of
self["longitude"]
.- Returns:
npt.NDArray[np.float64]
– Array of azimuths.
See also
segment_angle()
,geo.forward_azimuth()
- segment_groundspeed(*args, **kwargs)¶
Return groundspeed across segments.
Calculate by dividing the horizontal segment length by the difference in waypoint times.
- Parameters:
smooth (
bool
, optional) – Smooth airspeed with Savitzky-Golay filter. Defaults to False.window_length (
int
, optional) – Passed directly toscipy.signal.savgol_filter()
, by default 7.polyorder (
int
, optional) – Passed directly toscipy.signal.savgol_filter()
, by default 1.
- Returns:
npt.NDArray[np.float64]
– Groundspeed of the segment, [\(m s^{-1}\)]
- segment_length()¶
Compute spherical distance between flight waypoints.
Helper function used in
length()
andlength_met()
. np.nan appended so the length of the output is the same as number of waypoints.- Returns:
npt.NDArray[np.float64]
– Array of distances in [\(m\)] between waypoints
Examples
>>> from pycontrails import Flight >>> fl = Flight( ... longitude=np.array([1, 2, 3, 5, 8]), ... latitude=np.arange(5), ... altitude=np.full(shape=(5,), fill_value=11000), ... time=pd.date_range('2021-01-01T12', '2021-01-01T14', periods=5), ... ) >>> fl.segment_length() array([157255.03346286, 157231.08336815, 248456.48781503, 351047.44358851, nan])
See also
- segment_true_airspeed(u_wind=0.0, v_wind=0.0, smooth=True, window_length=7, polyorder=1)¶
Calculate the true airspeed [\(m / s\)] from the ground speed and horizontal winds.
Because Flight.segment_true_airspeed uses a smoothing pattern, waypoints in
data
are not independent. Moreover, we expect the final waypoint of each flight to have a nan value associated to any segment property. Consequently, we need to define a custom method here to deal with these issues when applying this method on a fleet of flights.See docstring for
Flight.segment_true_airspeed()
.- Raises:
RuntimeError – Unexpected key __u_wind or __v_wind found in
data
.
- sort(by)¶
Sort data by key(s).
This method always creates a copy of the data by calling
pandas.DataFrame.sort_values()
.- Parameters:
by (
str | list[str]
) – Key or list of keys to sort by.- Returns:
Self
– Instance with sorted data.