Fix memory bottleneck in
CocipGridsimulation by avoiding expensive call to
oldest-supported-numpyfor python 3.12. Remove logic for
numpy1.26.0rc1 in the
This release updates the Poll-Schumann (PS) aircraft performance model to version 2.0. It also includes a number of bug fixes and internal improvements.
Update the PS model aircraft-engine parameters.
Improve PS model accuracy in fuel consumption estimates.
Improve PS model accuracy in overall propulsive efficiency estimates.
Include additional guardrails in the PS model to constrain the operational limits of different aircraft-engine types, i.e., the maximum permitted Mach number by altitude, maximum available thrust coefficient, maximum lift coefficient, and maximum allowable aircraft mass.
Update polygon algorithm to use
shapely.LinearRingfor contours with at least 4 vertices.
Fleet.to_flight_listto avoid duplicating global attributes on the child
Fleet. The base
VectorDatasetclass already uses
sourceparameter is mutated in
CocipGrid.evalwhen the model parameter
met.shift_longitude()to translate longitude coordinates onto any domain bounds.
VectorDataset.to_dict()methods to output Vector data as dictionary. This method enables
Flight.to_dict()objects to be serialized for input to the Contrails API.
VectorDataset.from_dict()class method to create
VectorDatasetclass from dictionary.
Support more time formats, including timezone aware times, in
VectorDatasetcreation. All timezone aware `”time”`` coordinates are converted to UTC and stripped of timezone identifier.
Fix issue in the
wake_vortex.max_downward_displacementfunction in which float32 dtypes were promoted to float64 dtypes in certain cases.
Ignore empty vectors in
Test against python 3.12 in the GitHub Actions CI. Use python 3.12 the docs and doctest workflows.
This release includes a number of breaking changes and new features. If upgrading from a previous version of
pycontrails, please read the changelog carefully. Open an issue if you experience problems.
radparameter must now contain predefined metadata attributes
productdescribing the met source. An error will now be raised in
Cocipif these attributes are not present.
Deprecate passing arbitrary
No longer convert accumulated radiation data to average instantaneous data in
HRESinterfaces. This logic is now handled downstream by the model (e.g.,
Cocip). This change allows for more flexibility in the
raddata passed into the model and avoids unnecessary computation in the
MetDataSource.set_met_source_metadataabstract method. This should be called within the implementing class
No longer take a finite difference in the time dimension for HRES radiation data. This is now also handled natively in
No longer convert relative humidity from a percentage to a fraction in
streamparameter to be one of
["oper", "enfo"]. Require the
field_typeparameter to be one of
["fc", "pf", "cf", "an"].
step_offsetproperties in the
GFSForecastinterface. Now the
timestepsattribute is the only source of truth for determining AWS S3 keys. Change the
filenamemethod to take in a
datatimetimestep instead of an
intstep. No longer assign the first step radiation data to the zeroth step.
Change the return type of
MetDataset. This is more consistent with the return type of other
pycontrailsmodels and more closely mirrors the behavior of vector models. Set output
attrsmetadata on the global
MetDatasetinstead of the individual
MetDataArrayin each case.
Rewrite parts of the
pycontrails.core.datalibmodule for higher performance and readability.
MetDatasetconstructor. This allows the user to customize the attributes on the underlying
xarray.Datasetobject. This update makes
MetDatasetmore consistent with
Add three new properties
MetDataset. These properties give metadata describing the underlying meterological data source.
Model.transfer_met_source_attrsmethod for more consistent handling of met source metadata on the
sourceparameter passed into
No longer require
geopotentialdata when computing
tau_cirrus. If neither
geopotential_heightare available, geopotential is approximated from the geometric height. No longer require geopotential on the
shift_radiation_timeparameter. This is now inferred directly from the
radmetadata. An error is raised if the necessary metadata is not present.
Cocipto run with both instantaneous (
W m-2) and accumulated (
J m-2) radiation data.
Cocipto run with accumulated ECMWF HRES radiation data.
Correct radiation unit in the
ACCFwrapper model [#64]. Both instantaneous (
W m-2) and accumulated (
J m-2) radiation data are now supported, and the
ACCFwrapper will handle each appropriately.
Avoid unnecessary writing and reading of temporary files in
Fix timestep resolution bug in
GFSForecast. When the
gridparameter is 0.5 or 1.0, forecasts are only available every 3 hours. Previously, the
timestepsproperty would define an hourly timestep.
coordinates.slice_domainfunction slightly more performant by explicitly dropping nan values from the
Round unwieldy floating point numbers in
ecmwflibspackage from the
Add NPY to
p_settingsattribute on the
ACCFinterface. This is now constructed internally within
ACCF.eval. Replace the
ACCF._update_accf_configmethod with a
PSmodelto account for descent conditions.
Clip the denominator computed in
Ensure the token used within GitHub workflows has the fewest privileges required. Set top-level permissions to
nonein each workflow file. Remove unnecessary permissions previously used in the
Fix bug in
radiative_forcing.effective_tau_contrailidentified in #99.
Fix the unit for
Fix bug appearing in
Flight._geodesic_interpolationin which a single initial large gap was not interpolated with a geodesic path.
GOESinterface for downloading and visualizing GOES-16 satellite imagery.
Add new GOES example notebook highlighting the interface.
Build python 3.12 wheels for Linux, macOS, and Windows on release. This is in addition to the existing python 3.9, 3.10, and 3.11 wheels.
Use the experimental version number parameter
pycontrails.ecmwf.hres.get_forecast_filename. Update the logic involved in setting the dissemination data stream indicator
Change the behavior of
_altitude_interpolationmethod that is called within
resample_and_fill. Step climbs are now placed in the middle of long flight segments. Descents continue to occur at the end of segments.
ModuleNotFoundErrormessages when optional dependencies are not installed.
synthetic_flightmodule into the
Fix bug in
PSGridin which the
metdata was assumed to be already loaded into memory. This caused errors when running
Fix bug (#86) in which
sourcefuel type. Instead of instantiating a new
Fleetinstance with the default fuel type, the
Cocip._bundle_resultsmethod now overwrites the
self.source.dataattribute with the bundled predictions.
Avoid a memory explosion when running
Cocipon a large non-dask-backed
metparameter. Previously the
tau_cirruscomputation would be performed in memory over the entire
datetime.utcfromtimestamp(deprecated in python 3.12) with
Explicitly support python 3.12 in the
CocipParams. This controls whether to compute the cirrus optical depth in
Cocip.eval. When set to
"auto"(the default), the
tau_cirrusis computed in
Cocip.__init__if and only if the
metparameter is dask-backed.
Change data requirements for the
EmpiricalGridaircraft performance model.
ECMWFAPI.cache_datasetmethod. Previously the child implementations were identical.
No longer require the
pyprojpackage as a dependency. This is now an optional dependency, and can be installed with
pip install pycontrails[pyproj].
Implement a Poll-Schumann (
PSGrid) theoretical aircraft performance over a grid.
Use the instance
fuelattribute in the
Fleet.to_flight_listmethod. Previously, the default
JetAfuel was always used.
Fleet.fuelattribute is inferred from the underlying sequence of flights in the
PSGridmodel. For a given aircraft type and position, this model computes optimal aircraft performance at cruise conditions. In particular, this model can be used to estimate fuel flow, engine efficiency, and aircraft mass at cruise. In particular, the
PSGridmodel can now be used in conjunction with
CocipGridto simulate contrail formation over a grid.
Emissionsmodel so that
source: GeoVectorDataset. Previously, the
evalmethod required a
Flightinstance for the
sourceparameter. This change allows the
Emissionsmodel to run more seamlessly as a sub-model of a gridded model (ie,
No longer require
pycontrails-badato import or run the
CocipGridmodel. Instead, the
CocipGridParams.aircraft_performanceparameter can be set to any
AircraftPerformanceGridinstance. This allows the
CocipGridmodel to run with any aircraft performance model that implements the
GeoVectorDataset.T_isamethod to compute the ISA temperature at each point.
climb_descend_at_endparameter to the
Flight.resample_and_fillmethod. If True, the climb or descent will be placed at the end of each segment rather than the start.
AircraftPerformanceGridDataabstract interfaces for gridded aircraft performance models.
Include additional classes and functions in the
Hardcode the paths to the static data files used in the
PSFlightmodels. Previously these were configurable by model parameters.
altitude_ftparameter to the
GeoVectorDatasetconstructor. Warn if at least two of
Allow instantiation of
params: ModelParams. Previously, the
paramsparameter was required to be a
dict. The current implementation checks that the
paramsparameter is either a
dictor has type
Support “dry advection” simulation.
DryAdvectionmodel to simulate sediment-free advection of an aircraft’s exhaust plume. This model is experimental and may change in future releases. By default, the current implementation simulates plume geometry as a cylinder with an elliptical cross section (the same geometry assumed in CoCiP). Wind shear perturbs the ellipse azimuth, width, and depth over the plume evolution. The
DryAdvectionmodel may also be used to simulate advection without wind-shear effects by setting the model parameters
Add new Dry Advection example notebook highlighting the new
DryAdvectionmodel and comparing it to the
(#80) Fix unit error in
wake_vortex.turbulent_kinetic_energy_dissipation_rate. This fix affects the estimate of wake vortex max downward displacement and slightly changes
Change the implementation of
Flight.resample_and_fillso that lat-lon interpolation is linear in time. Previously, the timestamp associated to a waypoint was floored according to the resampling frequency without updating the position accordingly. This caused errors in segment calculations (e.g., true airspeed).
keep_original_indexparameter to the
True, the time original index is preserved in the output in addition to the new time index obtained by resampling.
Improve docstrings in
wake_vortexfunctions to remove
get_prefix at the start of each function name.
Add pytest command line parameter
--regenerate-resultsto regenerate static test fixture results. Automate in make recipe
Update handling of
GeoVectorDatasetconstructor. Add class variable
GeoVectorDataset.vertical_keysfor handing the vertical dimension.
units.dt_to_secondsfunction to convert
Add experimental support for simulating radiative effects due to contrail-contrail overlap.
Support simulating contrail contrail overlap when running the
Cocipmodel with a
dz_overlap_mparameters govern the overlap calculation. This mode of calculation is still experimental and may change in future releases.
pycontrails.models.cocip.outputmodules into a single
pycontrails.cocip.output_formatsmodule. The new module supports flight waypoint summary statistics, contrail waypoints summary statistics, gridded outputs, and time-slice outputs.
GeoVectorDataset.to_lon_lat_gridmethod. This method can be thought of as a partial inverse to the
MetDataset.to_vectormethod. The current implementation is brittle and may be revised in a future release.
interpolation_q_method="cubic-spline"when working with
MetDatasetsource (ie, so-called gridded models). Previously a
Flight.copyimplementation works with
Fleetinstances as well.
Avoid looping over
VectorDataset.broadcast_attrs. This is a slight performance enhancement.
Fleetsignature for compatibility with
Fix a few hard-coded assumptions in broadcasting aircraft performance and emissions when running
Fleetsource. The previous implementation did not consider the possibility of aircraft performance variables on
raise_errorparameter to the
Narrow type hints on the ABC
AircraftPerformance.evalmethod requires a
Flightobject for the
PSFlight.eval, explicitly set any aircraft performance data at waypoints with zero true airspeed to
np.nan. This avoids numpy
RuntimeWarnings without affecting the results.
Fix corner-case in the
polygon.buffer_and_cleanfunction in which the polygon created by buffering the
opencvcontour is not valid. Now a second attempt to buffer the polygon is made with a smaller buffer distance.
Ignore RuntimeError raised in
scipy.optimize.newtonif the maximum number of iterations is reached before convergence. This is a workaround for occasional false positive convergence warnings. The pycontrails use-case may be related to this GitHub issue.
humidity_scalingis not provided. The previous warning provided an outdated code example.
interpolation_q_methodused in a parent model is passed into the
humidity_scalingchild model in the
Models.__init__method. If the two
interpolation_q_methodvalues are different, a warning is issued. This could be extended to other model parameters in the future.
ExponentialBoostLatitudeCorrectionHumidityScalinghumidity scaling for the model parameter
Add GFS notebook example.
ExponentialBoostLatitudeCorrectionHumidityScalingParams. These parameters are now hard-coded in the
By default, call
MetDataSource.open_datasetmethod. This helps alleviate a
daskthreading issue similar to this GitHub issue.
MetDatasetsource in the
HistogramMatchinghumidity scaling model. Previously only
GeoVectorDatasetsources were explicitly supported.
tau_cirrusmodule. This ensures that the computation is done lazily for dask-backed arrays.
Round to 6 digits in the
polygon.determine_bufferfunction. This avoid unnecessary warnings for rounding errors.
Fix type hint for
Take more care with
inttypes in the
np.maximumfor clipping values.
CocipGridverbose formation outputs.
Support for the Poll-Schumann aircraft performance model.
Implement a basic working version of the Poll-Schumann (PS) aircraft performance model. This is experimental and may undergo revision in future releases. The PS Model currently supports the following 53 aircraft types:
The “gridded” version of this model is not yet implemented. This will be added in a future release.
Improve the runtime of instantiating the
Emissionsmodel by a factor of 10-15x. This translates to a time savings of several hundred milliseconds on modern hardware. This improvement is achieved by more efficient parsing of the underlying static data and by deferring the construction of the interpolation artifacts until they are needed.
Automatically use a default engine type from the aircraft type in the
Emissionsmodel if an
engine_uidparameter is not included on the
source. This itself is configurable via the
use_default_engine_uidparameter on the
Emissionsmodel. The default mappings from aircraft types to engines is included in
Flightinstantiation. Any code previously using this should instead directly pass additional
load_factoris now required in
AircraftPerformancemodels. The global
pycontrails.models.aircraft_performanceprovides a reasonable default. This is currently set to 0.7.
AircraftPerformancemodels if provided in the
No longer use a reference mass
AircraftPerformancemodels. This is replaced by the
takeoff_massparameter if provided, or calculated from operating empty operating mass, max payload mass, total fuel consumption mass, reserve fuel mass, and the load factor.
fuelparameter from the
Emissionsmodel. This is inferred directly from the
Fix edge cases in the
jet.reserve_fuel_requirementsimplementation. The previous version would return
nanfor some combinations of
Fix a spelling mistake:
ruffin place of
pydocstylefor linting docstrings.
ruffin place of
isortfor sorting imports.
AircraftPerformancetemplate based on the patterns used in the new
PSFlightclass. This may change again in the future.
Support experimental interpolation against gridded specific humidity. Add new data-driven humidity scaling models.
Add new experimental
interpolation_q_methodfield to the
ModelParamsdata class. This parameter controls the interpolation methodology when interpolation against gridded specific humidity. The possible values are:
None: Interpolate linearly against specific humidity. This is the default behavior and is the same as the previous behavior.
"cubic-spline": Apply cubic-spline scaling to the interpolation table vertical coordinate before interpolating linearly against specific humidity.
"log-q-log-p": Interpolate in the log-log domain against specific humidity and pressure.
This interpolation parameter is used when calling
pycontrails.core.models.interpolate_met. It can also be used directly with the new lower-level
Add new experimental
HistogramMatchinghumidity scaling model to match RHi values against IAGOS observations. The previous
HistogramMatchingWithEckelscaling is still available when working with ERA5 ensemble members.
Add new tutorial discussing the new specific humidity interpolation methodology.
Add an optional
q_methodparameter to the
pycontrails.core.models.interpolate_metfunction. The default value
Noneagrees with the previous behavior.
Change function signatures in the
cocip.pymodule for consistency. The
interp_kwargsparameter is now unpacked in the
MetDataset.from_zarr. Previously this parameter allowed the user to wrap the Zarr store in a
LRUCacheStoreto improve performance. Changes to Zarr internals have broken this approach. Custom Zarr patterns should now be handled outside of
Recompute and extend quantiles for histogram matching humidity scaling. Quantiles are now available for each combination of
q_methodand the following ERA5 data products: reanalysis and ensemble members 0-9. This data is available as a parquet file and is packaged with
Fix the precomputed Eckel coefficients. Previous values where computed for different interpolation assumptions and were not correct for the default interpolation method.
Clip the scaled humidity values computed by the
humidity_scaling.eckel_scalingfunction to ensure that they are non-negative. Previously, both relative and specific humidity values arising from Eckel scaling could be negative.
Handle edge case of all NaN values in the
T_critical_sacfunction in the
Avoid extraneous copy when calling
pytest-timeoutlimit for tests in
tests/unit/test_ecmwf.pyto avoid hanging tests.
forecast_stepparameter to the
Refactor auxillary functions used by
HistogramMatchingWithEckelto better isolated histogram matching from Eckel scaling.
pycontrails.core.modelsto handle experimental
Include precomputed humidity lapse rate values in the new
humidity_scaling.pymodule into its own subdirectory within
Re-release of v0.42.1.
HistogramMatchingWithEckelexperimental humidity scaling model. This is still a work in progress.
Flight.fit_altitudemethod which uses piecewise linear fitting to smooth a flight profile.
pycontrails.core.flightplanmodule for parsing ATC flight plans between string and dictionary representations.
No longer attach empty fields “sdr”, “rsr”, “olr”, “rf_sw”, “rf_lw”, “rf_net” onto the
Cocip.evalwhen the flight doesn’t generate any persistent contrails.
Change the default value for
parallelfrom True to False in
xr.open_mfdataset. This can be overridden by setting the
Fix a unit test (
test_dtypes.py::test_issr_sac_grid_output) that occasionally hangs. There may be another test in
test_ecmwf.pythat suffers from the same issue.
Fix issue encountered in
Cocip.evalwhen concatenating contrails with inconsistent values for
_out_of_bounds. This is only relevant when running the model with the experimental parameter
Fleet.max_distance_gapproperty. The previous property on the
Flightclass was not applicable to
Fix warning in
Flightclass to correctly suggest adding kwarg
Fix an issue in the
VectorDatasetconstructor with a
dataparameter of type
pd.DataFrame. Previously, time data was rewritten to the underlying DataFrame. This could cause copy-on-write issues if the DataFrame was a view of another DataFrame. This is now avoided.
When possible, replace type hints
Slight performance enhancements in the
Change the default value of
v_windfrom None to 0 in
Flight.segment_true_airspeed. This makes more sense semantically.
Phase 1 of the Spire datalib, which contains functions to identify unique flight trajectories from the raw Spire ADS-B data.
pycontrails.core.airportmodule to read and process the global airport database, which can be used to identify the nearest airport to a given coordinate.
pycontrails.datalib.spire.cleanfunction to remove and address erroneous waypoints in the raw Spire ADS-B data.
pycontrails.datalib.spire.filter_altitudefunction to remove noise in cruise altitude.
pycontrails.datalib.spire.identify_flightsfunction to identify unique flight trajectories from ADS-B messages.
pycontrails.datalib.spire.validate_trajectoryfunction to check the validity of the identified trajectories from ADS-B messages.
flightmodule. This includes a new
Add unit tests providing examples to identify unique flights.
FlightPhaseto be a dictionary enumeration of flight phases.
Add references to
Improve polygon algorithms.
Completely rewrite the
polygonmodule. Replace the “main” public function
polygon.find_multipolygon. Replace the
shapelyobjects when convenient to do so.
Convert continuous data to binary for polygon computation.
depthparameter has been replaced by the boolean
interiorsparameter. Add a
propertiesparameter for adding properties to the
epsilonparameters are now expressed in terms of latitude-longitude degrees.
opencv-python-headless>=4.5as an optional “vis” dependency. Some flavor of
opencvis required for the updated polygon algorithms.
Support scipy 1.10, improve interpolation performance, and fix many windows issues.
Improve interpolation performance by cythonizing linear interpolation. This extends the approach taken in scipy 1.10. The pycontrails cython routines allow for both float64 and float32 grids via cython fused types (the current scipy implementation assumes float64). In addition, interpolation up to dimension 4 is supported (the scipy implementation supports dimension 1 and 2).
Officially support scipy 1.10.
Officially test on windows in the GitHub Actions CI.
Build custom wheels for python 3.9, 3.10, and 3.11 for the following platforms:
macOS (arm64 and x86_64)
MetDataArrayconventions: underlying dimension coordinates are automatically promoted to float64.
Change how datetime arrays are converted to floating values for interpolation. The new approach introduces small differences compared with the previous implementation. These differences are significant enough to see relative differences in CoCiP predictions on the order of 1e-4.
Unit tests no longer raise errors when the
pycontrails-badapackage is not installed. Instead, some tests are skipped.
Fix many numpy casting issues encountered on windows.
Fix temp file issues encountered on windows.
Officially support changes in
interpolationmodule more aligned with scipy 1.10 enhancements to the
RegularGridInterpolator. In particular, grid coordinates now must be float64.
Use cibuildwheel to build wheels for Linux, macOS (arm64 and x86_64), and Windows on release in Github Actions. Allow this workflow to be triggered manually to test the release process without actually publishing to PyPI.
Simplify interpolation with pre-computed indices (invoked with the model parameter
interpolation_use_indices) via a
Overhaul much of the interpolation module to improve performance.
Slight performance enhancements to the
geo.segment_azimuthfunctions to calculate the azimuth between coordinates. Azimuth is the angle between coordinates relative to true north on the interval
Fix edge case in polygon algorithm by utilizing the
measure.find_contours. This update leads to slight changes in interior contours in some cases.
Fix hard-coded POSIX path in
conftest.pyfor windows compatibility.
shutil.copywhen the destination file is open in another thread. The copy is skipped and a warning is logged.
Fix some unit tests in
test_ecmwf.pyfor windows compatibility. There are still a few tests that fail on windows (unrelated to changes in this release) that will be fixed in v0.40.0.
cachestore=Noneto skip caching in
GFSinterfaces. Previously a default
DiskCacheStorewas created even when
cachestore=None. By default, caching is still enabled.
Add Wikipedia reference for Azimuth.
MetBase._loadto from a class method to a function.
docs/examples/CoCiP.ipynbexample demonstrating aircraft performance integration
Fix unit test caused by breaking change in pyproj 3.5.0
Add additional Zenodo metadata
Execute notebook examples in Docs Action
Fix links in documentation website.
Deploy build to PyPI (in addition to Test PyPI) on release.
Use setuptools_scm to manage the
Fix erroneous docstrings in
Add Github action to push to
pypion tag (#3)
nb-cleanto pre-commit hooks for example notebooks
doc8rst linter and pre-commit hook
Change default value of
epsilonparameter in method
MetDataArray.to_polygon_featurefrom 0.15 to 0.0.
Change the polygon simplification algorithm. The new implementation uses
shapely.bufferand doesn’t try to preserve the topology of the simplified polygon. This change may result in slightly different polygon geometries.
MetDataArray.to_polygon_featureto control the depth of the contour searching.
MetDataArray.to_polygon_featureto control whether to take the convex hull of each contour.
iso_valueis not specified in
Consolidate three redundant implementations of standardizing variables into a single
Ensure simplified polygons returned by
MetDataArray.to_polygon_featureare disjoint. While non-disjoint polygons don’t violate the GeoJSON spec, they can cause problems in some applications.
Add citations for ISA calculations
Abstract functionality to convert a Dataset or DataArray to longitude coordinates
core.met.shift_longitude. Add tests for method.
Add auto-formatting checks to CI testing
ACCF integration updates
Fixes ability to evaluate ACCF model over a
MetDatasetgrid by passing in tuple of (dims, data) when assigning data
Fixes minor issues with ACCF configuration and allows more configuration options
Updates example ACCF notebook with example of how to set configuration options when evaluating ACCFs over a grid
Include “rhi” and “iwc” variables in
Update CoCiP unit test static results for breaking changes in tau cirrus calculation. The relative difference in pinned energy forcing values is less than 0.001%.
Fix geopotential height gradient calculation in the
tau_cirrusmodule. When calculating finite differences along the vertical axis, the tau cirrus model previously divided the top and bottom differences by 2. To numerically approximate the derivative at the top and bottom levels, these differences should have actually been divided by 1. The calculation now uses
np.gradientto calculate the derivative along the vertical axis, which handles this correctly.
Make tau cirrus calculation slightly more performant.
Include a warning in the suspect
_deprecated.tau_cirrus_alt. This function is now the default
tau_cirruscalculation. The original
tau_cirruscalculation is still available in the
flake8over test modules.