pycontrails 0.54.3__tar.gz → 0.54.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pycontrails might be problematic. Click here for more details.
- {pycontrails-0.54.3 → pycontrails-0.54.5}/.github/workflows/doctest.yaml +2 -2
- {pycontrails-0.54.3 → pycontrails-0.54.5}/.github/workflows/release.yaml +1 -1
- {pycontrails-0.54.3 → pycontrails-0.54.5}/.zenodo.json +5 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/CHANGELOG.md +66 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/Makefile +1 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/NOTICE +1 -1
- {pycontrails-0.54.3/pycontrails.egg-info → pycontrails-0.54.5}/PKG-INFO +2 -2
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/conf.py +2 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/ECMWF.ipynb +1 -2
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/__init__.py +2 -2
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/_version.py +2 -2
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/core/aircraft_performance.py +58 -58
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/core/cache.py +7 -7
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/core/fleet.py +54 -29
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/core/flight.py +218 -301
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/core/interpolation.py +63 -60
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/core/met.py +193 -125
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/core/models.py +27 -13
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/core/polygon.py +15 -15
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/core/rgi_cython.c +187 -187
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/core/vector.py +119 -96
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/_met_utils/metsource.py +8 -5
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/ecmwf/common.py +1 -1
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/ecmwf/era5.py +7 -7
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/ecmwf/hres.py +3 -3
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/ecmwf/ifs.py +1 -1
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/gfs/gfs.py +2 -2
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/goes.py +5 -5
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/ext/empirical_grid.py +1 -1
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/apcemm/apcemm.py +5 -5
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/apcemm/utils.py +1 -1
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/cocip/cocip.py +23 -24
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/cocip/cocip_params.py +2 -11
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/cocip/cocip_uncertainty.py +24 -18
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/cocip/contrail_properties.py +331 -316
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/cocip/output_formats.py +53 -53
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/cocip/radiative_forcing.py +135 -131
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/cocip/radiative_heating.py +135 -135
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/cocip/unterstrasser_wake_vortex.py +90 -87
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/cocip/wake_vortex.py +92 -92
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/cocip/wind_shear.py +8 -8
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/cocipgrid/cocip_grid.py +37 -96
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/dry_advection.py +60 -19
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/emissions/black_carbon.py +108 -108
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/emissions/emissions.py +87 -87
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/emissions/ffm2.py +35 -35
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/humidity_scaling/humidity_scaling.py +23 -23
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/issr.py +2 -2
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/ps_model/ps_aircraft_params.py +8 -4
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/ps_model/ps_grid.py +76 -66
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/ps_model/ps_model.py +16 -16
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/ps_model/ps_operational_limits.py +20 -18
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/tau_cirrus.py +8 -1
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/physics/geo.py +67 -67
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/physics/jet.py +79 -79
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/physics/units.py +14 -14
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/utils/json.py +1 -2
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/utils/types.py +12 -7
- {pycontrails-0.54.3 → pycontrails-0.54.5/pycontrails.egg-info}/PKG-INFO +2 -2
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails.egg-info/requires.txt +1 -1
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pyproject.toml +7 -2
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/conftest.py +2 -2
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_cocip.py +38 -31
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_cocip_grid.py +67 -30
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_dry_advection.py +1 -1
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_dtypes.py +8 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_fleet.py +1 -1
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_flight.py +107 -66
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_ps_model.py +16 -1
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_sac_issr.py +4 -10
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_vector.py +1 -5
- {pycontrails-0.54.3 → pycontrails-0.54.5}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/.github/dependabot.yaml +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/.github/pull_request_template.md +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/.github/workflows/docs.yaml +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/.github/workflows/scorecard.yaml +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/.github/workflows/test.yaml +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/.gitignore +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/.pre-commit-config.yaml +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/CONTRIBUTING.md +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/LICENSE +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/README.md +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/RELEASE.md +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/_static/css/style.css +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/_static/img/colab.png +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/_static/img/favicon.png +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/_static/img/logo-dark.png +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/_static/img/logo.png +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/_static/pycontrails.bib +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/api.rst +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/changelog.rst +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/contributing.rst +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/develop.rst +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/flight.rst +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/index.rst +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/install.rst +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/integrations/ACCF.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/integrations/APCEMM.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/literature.rst +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/meteorology.rst +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/models.rst +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/ARCO-ERA5.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/AircraftPerformance.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/Cache.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/CoCiP.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/CoCiPGrid.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/Flight.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/GFS.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/GOES.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/ISSR.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/Landsat.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/Meteorology.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/SAC.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/Sentinel.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/advection.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/airports.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/data/.gitignore +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/data/flight-ap.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/data/flight-cocip.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/data/flight-fdr.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/data/flight-noisy.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/data/flight.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/data/iagos-flight-landsat.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/data/iagos-flight-sentinel.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/flightplan.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/model-levels.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/run-cocip-on-flight.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/run-cocip-with-fdr.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks/specific-humidity-interpolation.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/notebooks.rst +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/observations.rst +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/tutorials.rst +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/docs/utilities.rst +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/core/__init__.py +1 -1
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/core/airports.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/core/coordinates.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/core/flightplan.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/core/fuel.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/core/met_var.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/core/rgi_cython.pyx +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/__init__.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/_leo_utils/search.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/_leo_utils/static/bq_roi_query.sql +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/_leo_utils/vis.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/ecmwf/__init__.py +14 -14
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/ecmwf/arco_era5.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/ecmwf/era5_model_level.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/ecmwf/hres_model_level.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/ecmwf/model_levels.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/ecmwf/static/model_level_dataframe_v20240418.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/ecmwf/variables.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/gfs/__init__.py +6 -6
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/gfs/variables.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/landsat.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/sentinel.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/datalib/spire.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/ext/bada.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/ext/cirium.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/ext/synthetic_flight.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/__init__.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/accf.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/apcemm/__init__.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/apcemm/inputs.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/apcemm/static/apcemm_yaml_template.yaml +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/cocip/__init__.py +2 -2
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/cocipgrid/__init__.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/cocipgrid/cocip_grid_params.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/emissions/__init__.py +2 -2
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/emissions/static/default-engine-uids.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/emissions/static/edb-gaseous-v29b-engines.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/emissions/static/edb-nvpm-v29b-engines.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/humidity_scaling/__init__.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/humidity_scaling/quantiles/era5-model-level-quantiles.pq +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/humidity_scaling/quantiles/era5-pressure-level-quantiles.pq +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/pcc.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/pcr.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/ps_model/__init__.py +1 -1
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/ps_model/static/ps-aircraft-params-20240524.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/ps_model/static/ps-synonym-list-20240524.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/models/sac.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/physics/__init__.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/physics/constants.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/physics/static/iata-cargo-load-factors-20241115.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/physics/static/iata-passenger-load-factors-20241115.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/physics/thermo.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/py.typed +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/utils/__init__.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/utils/dependencies.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/utils/iteration.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails/utils/temp.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails.egg-info/SOURCES.txt +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails.egg-info/dependency_links.txt +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/pycontrails.egg-info/top_level.txt +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/setup.cfg +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/setup.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/__init__.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/_deprecated.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/benchmark/cocip/Makefile +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/benchmark/cocip/README.md +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/benchmark/cocip/benchmark.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/benchmark/cocip/compare.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/benchmark/cocip/data.md +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/benchmark/cocip/output.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/benchmark/cocip/review.ipynb +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/benchmark/cocip-fortran/README.md +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/benchmark/north-atlantic-study/.gcloudignore +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/benchmark/north-atlantic-study/README.md +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/benchmark/north-atlantic-study/support.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/benchmark/north-atlantic-study/validate.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/fixtures/cocip-met.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/fixtures/cocip-met2.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/fixtures/ecmwf-met.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/fixtures/gfs-met.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/__init__.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/NOAA_Solar_Calculations_day.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/cocip-contrail-output.json +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/cocip-contrail-output2.json +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/cocip-flight-output.json +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/cocip-flight-output2.json +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/cocip-output-contrail-edges.json +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/cocip-output-flts-20190101-eu.pq +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/flight-cocip2.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/flight-meridian.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/flight-metadata.json +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/flight-spire-data-cleaning.pq +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/flight.csv +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/flt-wypts-20190101-eu.pq +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/met-20190101-eu.nc +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/met-accf-pl.nc +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/met-accf-sl.nc +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/met-ecmwf-lnsp.nc +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/met-ecmwf-ml.nc +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/met-ecmwf-pl.nc +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/met-ecmwf-sl.nc +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/met-era5-cocip1.nc +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/met-era5-cocip2.nc +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/met-gfs.nc +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/polygon-bug.nc +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/rad-20190101-eu.nc +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/rad-era5-cocip1.nc +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/rad-era5-cocip2.nc +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/static/rad-gfs.nc +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_accf.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_airports.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_apcemm.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_cache.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_cocip_grid_parity.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_cocip_radiative_forcing.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_cocip_uncertainty.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_coordinates.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_datalib_metsource.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_ecmwf.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_emissions.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_flightplan.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_fuel.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_geo.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_gfs.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_goes.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_grid_to_netcdf.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_humidity_scaling.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_init.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_interpolation.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_leo.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_met.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_met_cache.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_models.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_pcc.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_polygons.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_spire.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_tau_cirrus.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_thermo_sac.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_units.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_unterstrasser_wake_vortex.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_utils.py +0 -0
- {pycontrails-0.54.3 → pycontrails-0.54.5}/tests/unit/test_zarr.py +0 -0
|
@@ -78,8 +78,8 @@ jobs:
|
|
|
78
78
|
- name: Test notebooks
|
|
79
79
|
run: make nb-test
|
|
80
80
|
|
|
81
|
-
# The doctests require numpy 2.
|
|
81
|
+
# The doctests require numpy 2.2 or higher
|
|
82
82
|
- name: Test docstrings
|
|
83
83
|
run: |
|
|
84
|
-
pip install "numpy>=2.
|
|
84
|
+
pip install "numpy>=2.2"
|
|
85
85
|
make doctest
|
|
@@ -40,7 +40,7 @@ jobs:
|
|
|
40
40
|
|
|
41
41
|
# https://cibuildwheel.readthedocs.io/en/stable/options/#testing
|
|
42
42
|
- name: Build wheels
|
|
43
|
-
uses: pypa/cibuildwheel@v2.
|
|
43
|
+
uses: pypa/cibuildwheel@v2.22
|
|
44
44
|
env:
|
|
45
45
|
CIBW_BUILD: cp310-* cp311-* cp312-* cp313-*
|
|
46
46
|
CIBW_SKIP: '*-win32 *-manylinux_i686 *-musllinux*'
|
|
@@ -1,5 +1,71 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.54.5
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- This release brings a number of very minor performance improvements to the low-level pycontrails data structures (`VectorDataset` and `MetDataset`). Cumulatively, these changes should bring in a small but nontrivial speedup (~5%) when running a model such as `Cocip` or `DryAdvection` on a single `Flight` source.
|
|
8
|
+
- Core `Flight` methods such as `copy`, `filter`, and `downselect_met` are now ~10x faster for typical use cases.
|
|
9
|
+
- Converting between `Fleet` and `Flight` instances via `Fleet.from_seq` and `Fleet.to_flight_list` are also ~5x faster.
|
|
10
|
+
- Implement low-memory met-downselection logic in `DryAdvection`. This is the same logic used in `CocipGrid` to reduce memory consumption by only loading the necessary time slices of the `met` data into memory. If `met` is already loaded into memory, this change will have no effect.
|
|
11
|
+
|
|
12
|
+
### Breaking Changes
|
|
13
|
+
|
|
14
|
+
- Remove the `copy` parameter from `GeovectorDataset.downselect_met`. This method always returns a view of the original dataset.
|
|
15
|
+
- Remove the `validate` parameter in the `MetDataArray` constructor. Input data is now always validated.
|
|
16
|
+
|
|
17
|
+
### Fixes
|
|
18
|
+
|
|
19
|
+
- Make slightly more explicit when data is copied in the `VectorDataset` constructor: data is now always shallow-copied, and the `copy` parameter governs whether to copy the underlying arrays.
|
|
20
|
+
- Call `downselect_met` in `DryAdvection.eval`. (This was previously forgotten.)
|
|
21
|
+
- Fix minor bug in `CocipGrid` downselect met logic introduced in v0.54.4. This bug may have caused some met slices to be reloaded when running `CocipGrid.eval` with lazily-loaded `met` and `rad` data.
|
|
22
|
+
|
|
23
|
+
### Internals
|
|
24
|
+
|
|
25
|
+
- Add internal `VectorDataset._from_fastpath` and `MetDataset._from_fastpath` class methods to skip data validation.
|
|
26
|
+
- Define `__slots__` on `MetBase`, `MetDataset`, `MetDataArray`, and `AttrDict`.
|
|
27
|
+
- When `MetDataset` and `MetDataArray` shared a common implementation, move the implementation to `MetBase`. This was the case for the `copy`, `downselect`, and `wrap_longitude` methods.
|
|
28
|
+
|
|
29
|
+
## v0.54.4
|
|
30
|
+
|
|
31
|
+
### Features
|
|
32
|
+
|
|
33
|
+
- Improve the `_altitude_interpolation` function used within `Flight.resample_and_fill` and ensure that it is consistent with the [existing GAIA publication](https://acp.copernicus.org/articles/24/725/2024/) The function `_altitude_interpolation` now accounts for various scenarios. For example:
|
|
34
|
+
|
|
35
|
+
1. Flight will automatically climb to an assumed cruise altitude if the first and next known waypoints are at very low altitudes with a large time gap.
|
|
36
|
+
1. If there are large time gaps between known waypoints with a small altitude difference, then the flight will climb at the mid-point of the segment.
|
|
37
|
+
1. If there are large time gaps and positive altitude difference, then the flight will climb at the start of its interpolation until the known cruising altitude and start its cruise phase.
|
|
38
|
+
1. If there are large time gaps and negative altitude difference, then the flight will continue cruising and only starts to descend towards the end of the interpolation.
|
|
39
|
+
1. If there is a shallow climb (ROCD < 500 ft/min), then always assume that the flight will climb at the next time step.
|
|
40
|
+
1. If there is a shallow descent (-250 < ROCD < 0 ft/min), then always assume that the flight will descend at the final time step.
|
|
41
|
+
|
|
42
|
+
Conditions (3) to (6) are based on the logic that the aircraft will generally prefer to climb to a higher altitude as early as possible, and descend to a lower altitude as late as possible, because a higher altitude can reduce drag and fuel consumption.
|
|
43
|
+
|
|
44
|
+
### Breaking changes
|
|
45
|
+
|
|
46
|
+
- Remove the optional input parameter `climb_descend_at_end` in `Flight.resample_and_fill`. See the description of the new `_altitude_interpolation` function for the rationale behind this change.
|
|
47
|
+
- Remove the `copy` argument from `Fleet.from_seq`. This argument was redundant and not used effectively in the implementation. The `Fleet.from_seq` method always returns a copy of the input sequence.
|
|
48
|
+
|
|
49
|
+
### Fixes
|
|
50
|
+
|
|
51
|
+
- Fix the `ERA5` interface when making a pressure-level request with a single pressure level. This change accommodates CDS-Beta server behavior. Previously, a ValueError was raised in this case.
|
|
52
|
+
- Bypass the ValueError raised by `dask.array.gradient` when the input array is not correctly chunk along the level dimension. Previously, `Cocip` would raise an error when computing tau cirrus in the case that the `met` data had single chunks along the level dimension.
|
|
53
|
+
- Fix the `CocipGrid` met downselection process to accommodate cases where `dt_integration` is as large as the time step of the met data. Previously, due to out-of-bounds interpolation, the output of `CocipGrid(met=met, rad=rad, dt_integration="1 hour")` was zero everywhere when the `met` and `rad` data had a time step of 1 hour.
|
|
54
|
+
- By default, don't interpolate air temperature when running the `DryAdvection` model in a point-wise manner (no wind-shear simulation).
|
|
55
|
+
- Use native python types (as opposed to `numpy` scalars) in the `PSAircraftEngineParams` dataclass.
|
|
56
|
+
- Ensure the `PSGrid` model maintains the precision of the `source`. Previously, float32 precision was lost per [NEP 50](https://numpy.org/neps/nep-0050-scalar-promotion.html).
|
|
57
|
+
- Fix `Fleet.resample_and_fill` when the the "flight_id" field is included on `Fleet.data` (as opposed to `Fleet.fl_attrs`). Previously, this would raise a ValueError.
|
|
58
|
+
- Use the supplied `nominal_rocd` parameter in `Flight.resample_and_fill` rather than `constants.nominal_rocd` (the default value of this parameter).
|
|
59
|
+
|
|
60
|
+
### Internals
|
|
61
|
+
|
|
62
|
+
- Add new `AdvectionBuffers` dataclass to override the zero-like values used in `ModelParams` with the buffer previously used in `CocipParams`. This is now a base class for `CocipParams` and `DryAdvectionParams`. In particular, the `DryAdvection` now uses nonzero values for the met downselect buffers.
|
|
63
|
+
- Change the order of advected points returned by `DryAdvection` to be consistent with the input order at each time step.
|
|
64
|
+
- Add the `RUF` ruleset for linting and formatting the codebase.
|
|
65
|
+
- Update type hints for `numpy` 2.2 compatibility. Additional changes may be required after the next iteration of the `numpy` 2.2 series.
|
|
66
|
+
- Relax the tolerance passed into `scipy.optimize.newton` in `ps_nominal_grid` to avoid some convergence warnings. (These warnings were more distracting than informative.)
|
|
67
|
+
- Remove the `_verify_altitude` check in `Flight.resample_and_fill`. This was often triggered by a flight with corrupt waypoints (ie, independent from the logic in `Flight.resample_and_fill`).
|
|
68
|
+
|
|
3
69
|
## v0.54.3
|
|
4
70
|
|
|
5
71
|
### Breaking changes
|
|
@@ -218,6 +218,7 @@ nb-check-links:
|
|
|
218
218
|
python -m pytest --check-links \
|
|
219
219
|
--check-links-ignore "https://doi.org/10.1021/acs.est.9b05608" \
|
|
220
220
|
--check-links-ignore "https://doi.org/10.1021/acs.est.2c05781" \
|
|
221
|
+
--check-links-ignore "https://doi.org/10.1175/JAMC-D-11-0242.1" \
|
|
221
222
|
--check-links-ignore "https://github.com/contrailcirrus/pycontrails-bada" \
|
|
222
223
|
--check-links-ignore "https://ourairports.com" \
|
|
223
224
|
--check-links-ignore "https://www.ncei.noaa.gov/products/weather-climate-models/global-forecast" \
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pycontrails
|
|
3
|
-
Version: 0.54.
|
|
3
|
+
Version: 0.54.5
|
|
4
4
|
Summary: Python library for modeling aviation climate impacts
|
|
5
5
|
Author-email: Breakthrough Energy <py@contrails.org>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -49,7 +49,7 @@ Requires-Dist: pyarrow>=5.0; extra == "dev"
|
|
|
49
49
|
Requires-Dist: pytest>=8.2; extra == "dev"
|
|
50
50
|
Requires-Dist: pytest-cov>=2.11; extra == "dev"
|
|
51
51
|
Requires-Dist: requests>=2.25; extra == "dev"
|
|
52
|
-
Requires-Dist: ruff==0.
|
|
52
|
+
Requires-Dist: ruff==0.8.0; extra == "dev"
|
|
53
53
|
Requires-Dist: setuptools; extra == "dev"
|
|
54
54
|
Provides-Extra: docs
|
|
55
55
|
Requires-Dist: doc8>=1.1; extra == "docs"
|
|
@@ -172,10 +172,12 @@ autodoc_typehints = "none"
|
|
|
172
172
|
# autodoc options
|
|
173
173
|
autoclass_content = "class" # only include docstring from Class (not __init__ method)
|
|
174
174
|
autodoc_inherit_docstrings = True
|
|
175
|
+
# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#confval-autodoc_default_options
|
|
175
176
|
autodoc_default_options = {
|
|
176
177
|
"members": None, # means yes/true/on
|
|
177
178
|
"undoc-members": None,
|
|
178
179
|
"show-inheritance": None,
|
|
180
|
+
"inherited-members": None,
|
|
179
181
|
}
|
|
180
182
|
|
|
181
183
|
# Add references in bibtex format here
|
|
@@ -3242,8 +3242,7 @@
|
|
|
3242
3242
|
"\n",
|
|
3243
3243
|
"### Access\n",
|
|
3244
3244
|
"\n",
|
|
3245
|
-
"Users within ECMWF Member and Co-operating States may contact their Computing Representative to obtain access to MARS.
|
|
3246
|
-
"All other users may [request a username and password](https://accounts.ecmwf.int/auth/realms/ecmwf/protocol/openid-connect/registrations?client_id=apps&response_type=code&scope=openid%20email&redirect_uri=https://www.ecmwf.int) and then [get an api key](https://api.ecmwf.int/v1/key/).\n",
|
|
3245
|
+
"Users within ECMWF Member and Co-operating States may contact their Computing Representative to obtain access to MARS. All other users may [request a username and password](https://confluence.ecmwf.int/display/WEBAPI/Access+MARS) and then [get an api key](https://api.ecmwf.int/v1/key/).\n",
|
|
3247
3246
|
"\n",
|
|
3248
3247
|
"Provide `url`, `key`, and `email` credentials on input, or see [ECMWF API Client documentation](https://github.com/ecmwf/ecmwf-api-client#configure) to configure local `~/.ecmwfapirc` file:\n",
|
|
3249
3248
|
"\n",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
``pycontrails`` public API.
|
|
3
3
|
|
|
4
|
-
Copyright 2021-
|
|
4
|
+
Copyright 2021-present Breakthrough Energy
|
|
5
5
|
|
|
6
6
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
7
|
you may not use this file except in compliance with the License.
|
|
@@ -60,8 +60,8 @@ __all__ = [
|
|
|
60
60
|
"HydrogenFuel",
|
|
61
61
|
"JetA",
|
|
62
62
|
"MetDataArray",
|
|
63
|
-
"MetDataset",
|
|
64
63
|
"MetDataSource",
|
|
64
|
+
"MetDataset",
|
|
65
65
|
"MetVariable",
|
|
66
66
|
"Model",
|
|
67
67
|
"ModelParams",
|
|
@@ -163,14 +163,14 @@ class AircraftPerformance(Model):
|
|
|
163
163
|
self,
|
|
164
164
|
*,
|
|
165
165
|
aircraft_type: str,
|
|
166
|
-
altitude_ft: npt.NDArray[np.
|
|
166
|
+
altitude_ft: npt.NDArray[np.floating],
|
|
167
167
|
time: npt.NDArray[np.datetime64],
|
|
168
|
-
true_airspeed: npt.NDArray[np.
|
|
169
|
-
air_temperature: npt.NDArray[np.
|
|
170
|
-
aircraft_mass: npt.NDArray[np.
|
|
171
|
-
thrust: npt.NDArray[np.
|
|
172
|
-
engine_efficiency: npt.NDArray[np.
|
|
173
|
-
fuel_flow: npt.NDArray[np.
|
|
168
|
+
true_airspeed: npt.NDArray[np.floating],
|
|
169
|
+
air_temperature: npt.NDArray[np.floating],
|
|
170
|
+
aircraft_mass: npt.NDArray[np.floating] | float | None,
|
|
171
|
+
thrust: npt.NDArray[np.floating] | float | None,
|
|
172
|
+
engine_efficiency: npt.NDArray[np.floating] | float | None,
|
|
173
|
+
fuel_flow: npt.NDArray[np.floating] | float | None,
|
|
174
174
|
q_fuel: float,
|
|
175
175
|
n_iter: int,
|
|
176
176
|
amass_oew: float,
|
|
@@ -192,21 +192,21 @@ class AircraftPerformance(Model):
|
|
|
192
192
|
----------
|
|
193
193
|
aircraft_type: str
|
|
194
194
|
Aircraft type designator used to query the underlying model database.
|
|
195
|
-
altitude_ft: npt.NDArray[np.
|
|
195
|
+
altitude_ft: npt.NDArray[np.floating]
|
|
196
196
|
Altitude at each waypoint, [:math:`ft`]
|
|
197
197
|
time: npt.NDArray[np.datetime64]
|
|
198
198
|
Waypoint time in ``np.datetime64`` format.
|
|
199
|
-
true_airspeed: npt.NDArray[np.
|
|
199
|
+
true_airspeed: npt.NDArray[np.floating]
|
|
200
200
|
True airspeed for each waypoint, [:math:`m s^{-1}`]
|
|
201
|
-
air_temperature : npt.NDArray[np.
|
|
201
|
+
air_temperature : npt.NDArray[np.floating]
|
|
202
202
|
Ambient temperature for each waypoint, [:math:`K`]
|
|
203
|
-
aircraft_mass : npt.NDArray[np.
|
|
203
|
+
aircraft_mass : npt.NDArray[np.floating] | float | None
|
|
204
204
|
Override the aircraft_mass at each waypoint, [:math:`kg`].
|
|
205
|
-
thrust : npt.NDArray[np.
|
|
205
|
+
thrust : npt.NDArray[np.floating] | float | None
|
|
206
206
|
Override the thrust setting at each waypoint, [:math: `N`].
|
|
207
|
-
engine_efficiency : npt.NDArray[np.
|
|
207
|
+
engine_efficiency : npt.NDArray[np.floating] | float | None
|
|
208
208
|
Override the engine efficiency at each waypoint.
|
|
209
|
-
fuel_flow : npt.NDArray[np.
|
|
209
|
+
fuel_flow : npt.NDArray[np.floating] | float | None
|
|
210
210
|
Override the fuel flow at each waypoint, [:math:`kg s^{-1}`].
|
|
211
211
|
q_fuel : float
|
|
212
212
|
Lower calorific value (LCV) of fuel, [:math:`J \ kg_{fuel}^{-1}`].
|
|
@@ -280,14 +280,14 @@ class AircraftPerformance(Model):
|
|
|
280
280
|
self,
|
|
281
281
|
*,
|
|
282
282
|
aircraft_type: str,
|
|
283
|
-
altitude_ft: npt.NDArray[np.
|
|
283
|
+
altitude_ft: npt.NDArray[np.floating],
|
|
284
284
|
time: npt.NDArray[np.datetime64],
|
|
285
|
-
true_airspeed: npt.NDArray[np.
|
|
286
|
-
air_temperature: npt.NDArray[np.
|
|
287
|
-
aircraft_mass: npt.NDArray[np.
|
|
288
|
-
thrust: npt.NDArray[np.
|
|
289
|
-
engine_efficiency: npt.NDArray[np.
|
|
290
|
-
fuel_flow: npt.NDArray[np.
|
|
285
|
+
true_airspeed: npt.NDArray[np.floating],
|
|
286
|
+
air_temperature: npt.NDArray[np.floating],
|
|
287
|
+
aircraft_mass: npt.NDArray[np.floating] | float,
|
|
288
|
+
thrust: npt.NDArray[np.floating] | float | None,
|
|
289
|
+
engine_efficiency: npt.NDArray[np.floating] | float | None,
|
|
290
|
+
fuel_flow: npt.NDArray[np.floating] | float | None,
|
|
291
291
|
q_fuel: float,
|
|
292
292
|
**kwargs: Any,
|
|
293
293
|
) -> AircraftPerformanceData:
|
|
@@ -332,13 +332,13 @@ class AircraftPerformance(Model):
|
|
|
332
332
|
self,
|
|
333
333
|
*,
|
|
334
334
|
aircraft_type: str,
|
|
335
|
-
altitude_ft: npt.NDArray[np.
|
|
335
|
+
altitude_ft: npt.NDArray[np.floating],
|
|
336
336
|
time: npt.NDArray[np.datetime64],
|
|
337
|
-
true_airspeed: npt.NDArray[np.
|
|
338
|
-
air_temperature: npt.NDArray[np.
|
|
339
|
-
thrust: npt.NDArray[np.
|
|
340
|
-
engine_efficiency: npt.NDArray[np.
|
|
341
|
-
fuel_flow: npt.NDArray[np.
|
|
337
|
+
true_airspeed: npt.NDArray[np.floating],
|
|
338
|
+
air_temperature: npt.NDArray[np.floating],
|
|
339
|
+
thrust: npt.NDArray[np.floating] | float | None,
|
|
340
|
+
engine_efficiency: npt.NDArray[np.floating] | float | None,
|
|
341
|
+
fuel_flow: npt.NDArray[np.floating] | float | None,
|
|
342
342
|
q_fuel: float,
|
|
343
343
|
n_iter: int,
|
|
344
344
|
amass_oew: float,
|
|
@@ -351,7 +351,7 @@ class AircraftPerformance(Model):
|
|
|
351
351
|
# Variable aircraft_mass will change dynamically after each iteration
|
|
352
352
|
# Set the initial aircraft mass depending on a possible load factor
|
|
353
353
|
|
|
354
|
-
aircraft_mass: npt.NDArray[np.
|
|
354
|
+
aircraft_mass: npt.NDArray[np.floating] | float
|
|
355
355
|
if takeoff_mass is not None:
|
|
356
356
|
aircraft_mass = takeoff_mass
|
|
357
357
|
else:
|
|
@@ -411,14 +411,14 @@ class AircraftPerformance(Model):
|
|
|
411
411
|
self,
|
|
412
412
|
*,
|
|
413
413
|
aircraft_type: str,
|
|
414
|
-
altitude_ft: npt.NDArray[np.
|
|
415
|
-
air_temperature: npt.NDArray[np.
|
|
414
|
+
altitude_ft: npt.NDArray[np.floating],
|
|
415
|
+
air_temperature: npt.NDArray[np.floating],
|
|
416
416
|
time: npt.NDArray[np.datetime64] | None,
|
|
417
|
-
true_airspeed: npt.NDArray[np.
|
|
418
|
-
aircraft_mass: npt.NDArray[np.
|
|
419
|
-
engine_efficiency: npt.NDArray[np.
|
|
420
|
-
fuel_flow: npt.NDArray[np.
|
|
421
|
-
thrust: npt.NDArray[np.
|
|
417
|
+
true_airspeed: npt.NDArray[np.floating] | float | None,
|
|
418
|
+
aircraft_mass: npt.NDArray[np.floating] | float,
|
|
419
|
+
engine_efficiency: npt.NDArray[np.floating] | float | None,
|
|
420
|
+
fuel_flow: npt.NDArray[np.floating] | float | None,
|
|
421
|
+
thrust: npt.NDArray[np.floating] | float | None,
|
|
422
422
|
q_fuel: float,
|
|
423
423
|
**kwargs: Any,
|
|
424
424
|
) -> AircraftPerformanceData:
|
|
@@ -441,24 +441,24 @@ class AircraftPerformance(Model):
|
|
|
441
441
|
----------
|
|
442
442
|
aircraft_type : str
|
|
443
443
|
Used to query the underlying model database for aircraft engine parameters.
|
|
444
|
-
altitude_ft : npt.NDArray[np.
|
|
444
|
+
altitude_ft : npt.NDArray[np.floating]
|
|
445
445
|
Altitude at each waypoint, [:math:`ft`]
|
|
446
|
-
air_temperature : npt.NDArray[np.
|
|
446
|
+
air_temperature : npt.NDArray[np.floating]
|
|
447
447
|
Ambient temperature for each waypoint, [:math:`K`]
|
|
448
448
|
time: npt.NDArray[np.datetime64] | None
|
|
449
449
|
Waypoint time in ``np.datetime64`` format. If None, only drag force
|
|
450
450
|
will is used in thrust calculations (ie, no vertical change and constant
|
|
451
451
|
horizontal change). In addition, aircraft is assumed to be in cruise.
|
|
452
|
-
true_airspeed : npt.NDArray[np.
|
|
452
|
+
true_airspeed : npt.NDArray[np.floating] | float | None
|
|
453
453
|
True airspeed for each waypoint, [:math:`m s^{-1}`].
|
|
454
454
|
If None, a nominal value is used.
|
|
455
|
-
aircraft_mass : npt.NDArray[np.
|
|
455
|
+
aircraft_mass : npt.NDArray[np.floating] | float
|
|
456
456
|
Aircraft mass for each waypoint, [:math:`kg`].
|
|
457
|
-
engine_efficiency : npt.NDArray[np.
|
|
457
|
+
engine_efficiency : npt.NDArray[np.floating] | float | None
|
|
458
458
|
Override the engine efficiency at each waypoint.
|
|
459
|
-
fuel_flow : npt.NDArray[np.
|
|
459
|
+
fuel_flow : npt.NDArray[np.floating] | float | None
|
|
460
460
|
Override the fuel flow at each waypoint, [:math:`kg s^{-1}`].
|
|
461
|
-
thrust : npt.NDArray[np.
|
|
461
|
+
thrust : npt.NDArray[np.floating] | float | None
|
|
462
462
|
Override the thrust setting at each waypoint, [:math: `N`].
|
|
463
463
|
q_fuel : float
|
|
464
464
|
Lower calorific value (LCV) of fuel, [:math:`J \ kg_{fuel}^{-1}`].
|
|
@@ -471,12 +471,12 @@ class AircraftPerformance(Model):
|
|
|
471
471
|
Derived performance metrics at each waypoint.
|
|
472
472
|
"""
|
|
473
473
|
|
|
474
|
-
def ensure_true_airspeed_on_source(self) -> npt.NDArray[np.
|
|
474
|
+
def ensure_true_airspeed_on_source(self) -> npt.NDArray[np.floating]:
|
|
475
475
|
"""Add ``true_airspeed`` field to :attr:`source` data if not already present.
|
|
476
476
|
|
|
477
477
|
Returns
|
|
478
478
|
-------
|
|
479
|
-
npt.NDArray[np.
|
|
479
|
+
npt.NDArray[np.floating]
|
|
480
480
|
True airspeed, [:math:`m s^{-1}`]. If ``true_airspeed`` is already present
|
|
481
481
|
on :attr:`source`, this is returned directly. Otherwise, it is calculated
|
|
482
482
|
using :meth:`Flight.segment_true_airspeed`.
|
|
@@ -529,30 +529,30 @@ class AircraftPerformanceData:
|
|
|
529
529
|
|
|
530
530
|
Parameters
|
|
531
531
|
----------
|
|
532
|
-
fuel_flow : npt.NDArray[np.
|
|
532
|
+
fuel_flow : npt.NDArray[np.floating]
|
|
533
533
|
Fuel mass flow rate for each waypoint, [:math:`kg s^{-1}`]
|
|
534
|
-
aircraft_mass : npt.NDArray[np.
|
|
534
|
+
aircraft_mass : npt.NDArray[np.floating]
|
|
535
535
|
Aircraft mass for each waypoint, [:math:`kg`]
|
|
536
|
-
true_airspeed : npt.NDArray[np.
|
|
536
|
+
true_airspeed : npt.NDArray[np.floating]
|
|
537
537
|
True airspeed at each waypoint, [:math: `m s^{-1}`]
|
|
538
|
-
fuel_burn: npt.NDArray[np.
|
|
538
|
+
fuel_burn: npt.NDArray[np.floating]
|
|
539
539
|
Fuel consumption for each waypoint, [:math:`kg`]. Set to an array of
|
|
540
540
|
all nan values if it cannot be computed (ie, working with gridpoints).
|
|
541
|
-
thrust: npt.NDArray[np.
|
|
541
|
+
thrust: npt.NDArray[np.floating]
|
|
542
542
|
Thrust force, [:math:`N`]
|
|
543
|
-
engine_efficiency: npt.NDArray[np.
|
|
543
|
+
engine_efficiency: npt.NDArray[np.floating]
|
|
544
544
|
Overall propulsion efficiency for each waypoint
|
|
545
|
-
rocd : npt.NDArray[np.
|
|
545
|
+
rocd : npt.NDArray[np.floating]
|
|
546
546
|
Rate of climb and descent, [:math:`ft min^{-1}`]
|
|
547
547
|
"""
|
|
548
548
|
|
|
549
|
-
fuel_flow: npt.NDArray[np.
|
|
550
|
-
aircraft_mass: npt.NDArray[np.
|
|
551
|
-
true_airspeed: npt.NDArray[np.
|
|
552
|
-
fuel_burn: npt.NDArray[np.
|
|
553
|
-
thrust: npt.NDArray[np.
|
|
554
|
-
engine_efficiency: npt.NDArray[np.
|
|
555
|
-
rocd: npt.NDArray[np.
|
|
549
|
+
fuel_flow: npt.NDArray[np.floating]
|
|
550
|
+
aircraft_mass: npt.NDArray[np.floating]
|
|
551
|
+
true_airspeed: npt.NDArray[np.floating]
|
|
552
|
+
fuel_burn: npt.NDArray[np.floating]
|
|
553
|
+
thrust: npt.NDArray[np.floating]
|
|
554
|
+
engine_efficiency: npt.NDArray[np.floating]
|
|
555
|
+
rocd: npt.NDArray[np.floating]
|
|
556
556
|
|
|
557
557
|
|
|
558
558
|
# --------------------------------
|
|
@@ -43,7 +43,7 @@ def _get_user_cache_dir() -> str:
|
|
|
43
43
|
class CacheStore(ABC):
|
|
44
44
|
"""Abstract cache storage class for storing staged and intermediate data."""
|
|
45
45
|
|
|
46
|
-
__slots__ = ("
|
|
46
|
+
__slots__ = ("allow_clear", "cache_dir")
|
|
47
47
|
cache_dir: str
|
|
48
48
|
allow_clear: bool
|
|
49
49
|
|
|
@@ -426,15 +426,15 @@ class GCPCacheStore(CacheStore):
|
|
|
426
426
|
"""
|
|
427
427
|
|
|
428
428
|
__slots__ = (
|
|
429
|
-
"
|
|
429
|
+
"_bucket",
|
|
430
|
+
"_client",
|
|
431
|
+
"_disk_cache",
|
|
430
432
|
"bucket",
|
|
433
|
+
"chunk_size",
|
|
434
|
+
"project",
|
|
431
435
|
"read_only",
|
|
432
|
-
"timeout",
|
|
433
436
|
"show_progress",
|
|
434
|
-
"
|
|
435
|
-
"_disk_cache",
|
|
436
|
-
"_client",
|
|
437
|
-
"_bucket",
|
|
437
|
+
"timeout",
|
|
438
438
|
)
|
|
439
439
|
project: str | None
|
|
440
440
|
bucket: str
|
|
@@ -32,7 +32,7 @@ class Fleet(Flight):
|
|
|
32
32
|
Flight waypoints are merged into a single :class:`Flight`-like object.
|
|
33
33
|
"""
|
|
34
34
|
|
|
35
|
-
__slots__ = ("
|
|
35
|
+
__slots__ = ("final_waypoints", "fl_attrs")
|
|
36
36
|
|
|
37
37
|
def __init__(
|
|
38
38
|
self,
|
|
@@ -132,19 +132,20 @@ class Fleet(Flight):
|
|
|
132
132
|
return final_waypoints, fl_attrs
|
|
133
133
|
|
|
134
134
|
@override
|
|
135
|
-
def copy(self, **kwargs: Any) ->
|
|
136
|
-
kwargs.setdefault("fuel", self.fuel)
|
|
135
|
+
def copy(self, **kwargs: Any) -> Self:
|
|
137
136
|
kwargs.setdefault("fl_attrs", self.fl_attrs)
|
|
137
|
+
kwargs.setdefault("final_waypoints", self.final_waypoints)
|
|
138
138
|
return super().copy(**kwargs)
|
|
139
139
|
|
|
140
140
|
@override
|
|
141
|
-
def filter(self, mask: npt.NDArray[np.bool_], copy: bool = True, **kwargs: Any) ->
|
|
142
|
-
kwargs.setdefault("fuel", self.fuel)
|
|
143
|
-
|
|
141
|
+
def filter(self, mask: npt.NDArray[np.bool_], copy: bool = True, **kwargs: Any) -> Self:
|
|
144
142
|
flight_ids = set(np.unique(self["flight_id"][mask]))
|
|
145
143
|
fl_attrs = {k: v for k, v in self.fl_attrs.items() if k in flight_ids}
|
|
146
144
|
kwargs.setdefault("fl_attrs", fl_attrs)
|
|
147
145
|
|
|
146
|
+
final_waypoints = np.array(self.final_waypoints[mask], copy=copy)
|
|
147
|
+
kwargs.setdefault("final_waypoints", final_waypoints)
|
|
148
|
+
|
|
148
149
|
return super().filter(mask, copy=copy, **kwargs)
|
|
149
150
|
|
|
150
151
|
@override
|
|
@@ -162,7 +163,6 @@ class Fleet(Flight):
|
|
|
162
163
|
cls,
|
|
163
164
|
seq: Iterable[Flight],
|
|
164
165
|
broadcast_numeric: bool = True,
|
|
165
|
-
copy: bool = True,
|
|
166
166
|
attrs: dict[str, Any] | None = None,
|
|
167
167
|
) -> Self:
|
|
168
168
|
"""Instantiate a :class:`Fleet` instance from an iterable of :class:`Flight`.
|
|
@@ -177,8 +177,6 @@ class Fleet(Flight):
|
|
|
177
177
|
An iterable of :class:`Flight` instances.
|
|
178
178
|
broadcast_numeric : bool, optional
|
|
179
179
|
If True, broadcast numeric attributes to data variables.
|
|
180
|
-
copy : bool, optional
|
|
181
|
-
If True, make copy of each flight instance in ``seq``.
|
|
182
180
|
attrs : dict[str, Any] | None, optional
|
|
183
181
|
Global attribute to attach to instance.
|
|
184
182
|
|
|
@@ -190,15 +188,16 @@ class Fleet(Flight):
|
|
|
190
188
|
in ``seq``.
|
|
191
189
|
"""
|
|
192
190
|
|
|
193
|
-
|
|
194
|
-
|
|
191
|
+
# Create a shallow copy because we add additional keys in _validate_fl
|
|
192
|
+
def _shallow_copy(fl: Flight) -> Flight:
|
|
193
|
+
return Flight._from_fastpath(fl.data, fl.attrs, fuel=fl.fuel)
|
|
195
194
|
|
|
196
195
|
def _maybe_warn(fl: Flight) -> Flight:
|
|
197
196
|
if not fl:
|
|
198
197
|
warnings.warn("Empty flight found in sequence. It will be filtered out.")
|
|
199
198
|
return fl
|
|
200
199
|
|
|
201
|
-
seq = tuple(
|
|
200
|
+
seq = tuple(_shallow_copy(fl) for fl in seq if _maybe_warn(fl))
|
|
202
201
|
|
|
203
202
|
if not seq:
|
|
204
203
|
msg = "Cannot create Fleet from empty sequence."
|
|
@@ -220,7 +219,18 @@ class Fleet(Flight):
|
|
|
220
219
|
)
|
|
221
220
|
|
|
222
221
|
data = {var: np.concatenate([fl[var] for fl in seq]) for var in seq[0]}
|
|
223
|
-
|
|
222
|
+
|
|
223
|
+
final_waypoints = np.zeros(data["time"].size, dtype=bool)
|
|
224
|
+
final_waypoint_indices = np.cumsum([fl.size for fl in seq]) - 1
|
|
225
|
+
final_waypoints[final_waypoint_indices] = True
|
|
226
|
+
|
|
227
|
+
return cls._from_fastpath(
|
|
228
|
+
data,
|
|
229
|
+
attrs,
|
|
230
|
+
fuel=fuel,
|
|
231
|
+
fl_attrs=fl_attrs,
|
|
232
|
+
final_waypoints=final_waypoints,
|
|
233
|
+
)
|
|
224
234
|
|
|
225
235
|
@property
|
|
226
236
|
def n_flights(self) -> int:
|
|
@@ -249,11 +259,19 @@ class Fleet(Flight):
|
|
|
249
259
|
List of Flights in the same order as was passed into the ``Fleet`` instance.
|
|
250
260
|
"""
|
|
251
261
|
indices = self.dataframe.groupby("flight_id", sort=False).indices
|
|
262
|
+
if copy:
|
|
263
|
+
return [
|
|
264
|
+
Flight._from_fastpath(
|
|
265
|
+
{k: v[idx] for k, v in self.data.items()},
|
|
266
|
+
self.fl_attrs[flight_id],
|
|
267
|
+
fuel=self.fuel,
|
|
268
|
+
).copy()
|
|
269
|
+
for flight_id, idx in indices.items()
|
|
270
|
+
]
|
|
252
271
|
return [
|
|
253
|
-
Flight(
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
copy=copy,
|
|
272
|
+
Flight._from_fastpath(
|
|
273
|
+
{k: v[idx] for k, v in self.data.items()},
|
|
274
|
+
self.fl_attrs[flight_id],
|
|
257
275
|
fuel=self.fuel,
|
|
258
276
|
)
|
|
259
277
|
for flight_id, idx in indices.items()
|
|
@@ -265,12 +283,12 @@ class Fleet(Flight):
|
|
|
265
283
|
|
|
266
284
|
def segment_true_airspeed(
|
|
267
285
|
self,
|
|
268
|
-
u_wind: npt.NDArray[np.
|
|
269
|
-
v_wind: npt.NDArray[np.
|
|
286
|
+
u_wind: npt.NDArray[np.floating] | float = 0.0,
|
|
287
|
+
v_wind: npt.NDArray[np.floating] | float = 0.0,
|
|
270
288
|
smooth: bool = True,
|
|
271
289
|
window_length: int = 7,
|
|
272
290
|
polyorder: int = 1,
|
|
273
|
-
) -> npt.NDArray[np.
|
|
291
|
+
) -> npt.NDArray[np.floating]:
|
|
274
292
|
"""Calculate the true airspeed [:math:`m / s`] from the ground speed and horizontal winds.
|
|
275
293
|
|
|
276
294
|
Because Flight.segment_true_airspeed uses a smoothing pattern, waypoints in :attr:`data`
|
|
@@ -302,7 +320,7 @@ class Fleet(Flight):
|
|
|
302
320
|
self[key] = v_wind
|
|
303
321
|
|
|
304
322
|
# Calculate TAS on each flight individually
|
|
305
|
-
def calc_tas(fl: Flight) -> npt.NDArray[np.
|
|
323
|
+
def calc_tas(fl: Flight) -> npt.NDArray[np.floating]:
|
|
306
324
|
u = fl.get("__u_wind", u_wind)
|
|
307
325
|
v = fl.get("__v_wind", v_wind)
|
|
308
326
|
|
|
@@ -325,19 +343,27 @@ class Fleet(Flight):
|
|
|
325
343
|
return np.concatenate(tas)
|
|
326
344
|
|
|
327
345
|
@override
|
|
328
|
-
def segment_groundspeed(self, *args: Any, **kwargs: Any) -> npt.NDArray[np.
|
|
346
|
+
def segment_groundspeed(self, *args: Any, **kwargs: Any) -> npt.NDArray[np.floating]:
|
|
329
347
|
fls = self.to_flight_list(copy=False)
|
|
330
348
|
gs = [fl.segment_groundspeed(*args, **kwargs) for fl in fls]
|
|
331
349
|
return np.concatenate(gs)
|
|
332
350
|
|
|
333
351
|
@override
|
|
334
|
-
def resample_and_fill(self, *args: Any, **kwargs: Any) ->
|
|
352
|
+
def resample_and_fill(self, *args: Any, **kwargs: Any) -> Self:
|
|
335
353
|
flights = self.to_flight_list(copy=False)
|
|
354
|
+
|
|
355
|
+
# We need to ensure that each flight has an flight_id attrs field
|
|
356
|
+
# When we call fl.resample_and_fill, any flight_id data field
|
|
357
|
+
# will be lost, so the call to Fleet.from_seq will fail.
|
|
358
|
+
for fl in flights:
|
|
359
|
+
if "flight_id" not in fl.attrs:
|
|
360
|
+
fl.attrs["flight_id"] = _extract_flight_id(fl)
|
|
361
|
+
|
|
336
362
|
flights = [fl.resample_and_fill(*args, **kwargs) for fl in flights]
|
|
337
|
-
return type(self).from_seq(flights,
|
|
363
|
+
return type(self).from_seq(flights, broadcast_numeric=False, attrs=self.attrs)
|
|
338
364
|
|
|
339
365
|
@override
|
|
340
|
-
def segment_length(self) -> npt.NDArray[np.
|
|
366
|
+
def segment_length(self) -> npt.NDArray[np.floating]:
|
|
341
367
|
return np.where(self.final_waypoints, np.nan, super().segment_length())
|
|
342
368
|
|
|
343
369
|
@property
|
|
@@ -346,11 +372,11 @@ class Fleet(Flight):
|
|
|
346
372
|
return np.nanmax(self.segment_length()).item()
|
|
347
373
|
|
|
348
374
|
@override
|
|
349
|
-
def segment_azimuth(self) -> npt.NDArray[np.
|
|
375
|
+
def segment_azimuth(self) -> npt.NDArray[np.floating]:
|
|
350
376
|
return np.where(self.final_waypoints, np.nan, super().segment_azimuth())
|
|
351
377
|
|
|
352
378
|
@override
|
|
353
|
-
def segment_angle(self) -> tuple[npt.NDArray[np.
|
|
379
|
+
def segment_angle(self) -> tuple[npt.NDArray[np.floating], npt.NDArray[np.floating]]:
|
|
354
380
|
sin_a, cos_a = super().segment_angle()
|
|
355
381
|
sin_a[self.final_waypoints] = np.nan
|
|
356
382
|
cos_a[self.final_waypoints] = np.nan
|
|
@@ -368,8 +394,7 @@ class Fleet(Flight):
|
|
|
368
394
|
force_filter: bool = False,
|
|
369
395
|
drop: bool = True,
|
|
370
396
|
keep_original_index: bool = False,
|
|
371
|
-
|
|
372
|
-
) -> Flight:
|
|
397
|
+
) -> NoReturn:
|
|
373
398
|
msg = "Only implemented for Flight instances"
|
|
374
399
|
raise NotImplementedError(msg)
|
|
375
400
|
|