pycontrails 0.54.5__tar.gz → 0.54.7__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.5 → pycontrails-0.54.7}/CHANGELOG.md +46 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/NOTICE +1 -1
- {pycontrails-0.54.5/pycontrails.egg-info → pycontrails-0.54.7}/PKG-INFO +5 -6
- {pycontrails-0.54.5 → pycontrails-0.54.7}/RELEASE.md +1 -1
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/conf.py +4 -2
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/ECMWF.ipynb +7 -7
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/__init__.py +1 -1
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/_version.py +2 -2
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/core/aircraft_performance.py +46 -46
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/core/airports.py +7 -5
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/core/flight.py +6 -8
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/core/flightplan.py +11 -11
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/core/met.py +41 -33
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/core/met_var.py +80 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/core/models.py +80 -3
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/core/rgi_cython.c +217 -217
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/core/vector.py +66 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/_met_utils/metsource.py +1 -1
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/ecmwf/era5.py +5 -6
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/ecmwf/era5_model_level.py +4 -5
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/ecmwf/ifs.py +1 -3
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/gfs/gfs.py +1 -3
- pycontrails-0.54.7/pycontrails/datalib/spire/__init__.py +5 -0
- pycontrails-0.54.7/pycontrails/datalib/spire/exceptions.py +62 -0
- pycontrails-0.54.7/pycontrails/datalib/spire/spire.py +606 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/accf.py +4 -4
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/cocip/cocip.py +116 -19
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/cocip/cocip_params.py +10 -1
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/cocip/output_formats.py +1 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/cocip/unterstrasser_wake_vortex.py +132 -30
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/cocipgrid/cocip_grid.py +3 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/dry_advection.py +51 -19
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/emissions/black_carbon.py +19 -14
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/emissions/emissions.py +8 -8
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/humidity_scaling/humidity_scaling.py +1 -1
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/pcc.py +1 -2
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/ps_model/ps_model.py +3 -31
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/ps_model/ps_operational_limits.py +2 -6
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/tau_cirrus.py +13 -6
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/physics/constants.py +2 -1
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/physics/geo.py +3 -3
- {pycontrails-0.54.5 → pycontrails-0.54.7/pycontrails.egg-info}/PKG-INFO +5 -6
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails.egg-info/SOURCES.txt +3 -1
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails.egg-info/requires.txt +2 -3
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pyproject.toml +5 -6
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/benchmark/cocip/benchmark.py +2 -6
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/benchmark/north-atlantic-study/validate.py +3 -3
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/conftest.py +61 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_apcemm.py +1 -2
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_cache.py +1 -1
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_cocip.py +170 -2
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_cocip_grid.py +71 -1
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_cocip_grid_parity.py +1 -1
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_dry_advection.py +38 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_geo.py +1 -2
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_met.py +1 -1
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_models.py +22 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_ps_model.py +1 -2
- pycontrails-0.54.7/tests/unit/test_spire.py +200 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_unterstrasser_wake_vortex.py +42 -26
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_vector.py +1 -2
- pycontrails-0.54.5/pycontrails/datalib/spire.py +0 -739
- pycontrails-0.54.5/tests/unit/test_spire.py +0 -93
- {pycontrails-0.54.5 → pycontrails-0.54.7}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/.github/dependabot.yaml +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/.github/pull_request_template.md +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/.github/workflows/docs.yaml +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/.github/workflows/doctest.yaml +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/.github/workflows/release.yaml +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/.github/workflows/scorecard.yaml +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/.github/workflows/test.yaml +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/.gitignore +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/.pre-commit-config.yaml +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/.zenodo.json +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/CONTRIBUTING.md +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/LICENSE +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/Makefile +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/README.md +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/_static/css/style.css +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/_static/img/colab.png +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/_static/img/favicon.png +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/_static/img/logo-dark.png +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/_static/img/logo.png +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/_static/pycontrails.bib +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/api.rst +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/changelog.rst +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/contributing.rst +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/develop.rst +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/flight.rst +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/index.rst +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/install.rst +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/integrations/ACCF.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/integrations/APCEMM.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/literature.rst +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/meteorology.rst +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/models.rst +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/ARCO-ERA5.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/AircraftPerformance.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/Cache.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/CoCiP.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/CoCiPGrid.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/Flight.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/GFS.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/GOES.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/ISSR.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/Landsat.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/Meteorology.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/SAC.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/Sentinel.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/advection.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/airports.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/data/.gitignore +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/data/flight-ap.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/data/flight-cocip.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/data/flight-fdr.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/data/flight-noisy.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/data/flight.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/data/iagos-flight-landsat.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/data/iagos-flight-sentinel.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/flightplan.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/model-levels.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/run-cocip-on-flight.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/run-cocip-with-fdr.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks/specific-humidity-interpolation.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/notebooks.rst +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/observations.rst +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/tutorials.rst +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/docs/utilities.rst +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/core/__init__.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/core/cache.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/core/coordinates.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/core/fleet.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/core/fuel.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/core/interpolation.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/core/polygon.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/core/rgi_cython.pyx +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/__init__.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/_leo_utils/search.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/_leo_utils/static/bq_roi_query.sql +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/_leo_utils/vis.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/ecmwf/__init__.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/ecmwf/arco_era5.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/ecmwf/common.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/ecmwf/hres.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/ecmwf/hres_model_level.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/ecmwf/model_levels.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/ecmwf/static/model_level_dataframe_v20240418.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/ecmwf/variables.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/gfs/__init__.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/gfs/variables.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/goes.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/landsat.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/datalib/sentinel.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/ext/bada.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/ext/cirium.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/ext/empirical_grid.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/ext/synthetic_flight.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/__init__.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/apcemm/__init__.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/apcemm/apcemm.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/apcemm/inputs.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/apcemm/static/apcemm_yaml_template.yaml +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/apcemm/utils.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/cocip/__init__.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/cocip/cocip_uncertainty.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/cocip/contrail_properties.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/cocip/radiative_forcing.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/cocip/radiative_heating.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/cocip/wake_vortex.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/cocip/wind_shear.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/cocipgrid/__init__.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/cocipgrid/cocip_grid_params.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/emissions/__init__.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/emissions/ffm2.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/emissions/static/default-engine-uids.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/emissions/static/edb-gaseous-v29b-engines.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/emissions/static/edb-nvpm-v29b-engines.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/humidity_scaling/__init__.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/humidity_scaling/quantiles/era5-model-level-quantiles.pq +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/humidity_scaling/quantiles/era5-pressure-level-quantiles.pq +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/issr.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/pcr.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/ps_model/__init__.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/ps_model/ps_aircraft_params.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/ps_model/ps_grid.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/ps_model/static/ps-aircraft-params-20240524.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/ps_model/static/ps-synonym-list-20240524.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/models/sac.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/physics/__init__.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/physics/jet.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/physics/static/iata-cargo-load-factors-20241115.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/physics/static/iata-passenger-load-factors-20241115.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/physics/thermo.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/physics/units.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/py.typed +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/utils/__init__.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/utils/dependencies.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/utils/iteration.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/utils/json.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/utils/temp.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails/utils/types.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails.egg-info/dependency_links.txt +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/pycontrails.egg-info/top_level.txt +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/setup.cfg +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/setup.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/__init__.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/_deprecated.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/benchmark/cocip/Makefile +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/benchmark/cocip/README.md +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/benchmark/cocip/compare.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/benchmark/cocip/data.md +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/benchmark/cocip/output.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/benchmark/cocip/review.ipynb +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/benchmark/cocip-fortran/README.md +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/benchmark/north-atlantic-study/.gcloudignore +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/benchmark/north-atlantic-study/README.md +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/benchmark/north-atlantic-study/support.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/fixtures/cocip-met.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/fixtures/cocip-met2.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/fixtures/ecmwf-met.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/fixtures/gfs-met.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/__init__.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/NOAA_Solar_Calculations_day.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/cocip-contrail-output.json +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/cocip-contrail-output2.json +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/cocip-flight-output.json +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/cocip-flight-output2.json +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/cocip-output-contrail-edges.json +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/cocip-output-flts-20190101-eu.pq +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/flight-cocip2.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/flight-meridian.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/flight-metadata.json +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/flight-spire-data-cleaning.pq +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/flight.csv +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/flt-wypts-20190101-eu.pq +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/met-20190101-eu.nc +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/met-accf-pl.nc +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/met-accf-sl.nc +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/met-ecmwf-lnsp.nc +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/met-ecmwf-ml.nc +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/met-ecmwf-pl.nc +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/met-ecmwf-sl.nc +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/met-era5-cocip1.nc +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/met-era5-cocip2.nc +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/met-gfs.nc +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/polygon-bug.nc +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/rad-20190101-eu.nc +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/rad-era5-cocip1.nc +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/rad-era5-cocip2.nc +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/static/rad-gfs.nc +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_accf.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_airports.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_cocip_radiative_forcing.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_cocip_uncertainty.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_coordinates.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_datalib_metsource.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_dtypes.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_ecmwf.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_emissions.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_fleet.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_flight.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_flightplan.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_fuel.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_gfs.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_goes.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_grid_to_netcdf.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_humidity_scaling.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_init.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_interpolation.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_leo.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_met_cache.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_pcc.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_polygons.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_sac_issr.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_tau_cirrus.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_thermo_sac.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_units.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_utils.py +0 -0
- {pycontrails-0.54.5 → pycontrails-0.54.7}/tests/unit/test_zarr.py +0 -0
|
@@ -1,5 +1,51 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.54.7
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- Add helper `classmethods` to `Model`, `Cocip`, and `CocipGrid` for generating lists of required variables from specific data sources.
|
|
8
|
+
- Add a `ValidateTrajectoryHandler` to the `spire` module to validate spire ADS-B data. This work is experimental and will be improved in future releases.
|
|
9
|
+
- Update Unterstrasser (2016)'s parameterised model of the contrail ice crystal survival fraction to the latest version (Lottermoser & Unterstrasser, 2025). This update:
|
|
10
|
+
- improves the goodness of fit between the parameterised model and LES, and
|
|
11
|
+
- expands the parameter space for application to very low and very high nvPM inputs, different fuel types (where the EI H2Os are different), and higher ambient temperatures (up to 235 K) to accommodate for contrails formed by liquid hydrogen aircraft.
|
|
12
|
+
|
|
13
|
+
### Breaking changes
|
|
14
|
+
|
|
15
|
+
- The `MetDataset.standardize_variables` method now returns a new `MetDataset` rather than modifying the existing dataset in place. To retain the previous behavior, use `MetDataset.standardize_variables(..., inplace=True)`.
|
|
16
|
+
|
|
17
|
+
### Fixes
|
|
18
|
+
|
|
19
|
+
- Change naming convention for eastward and northward wind fields in `AircraftPerformance` models for consistency with the `Cocip` and `DryAdvection` models. Fields on the `source` are now named `u_wind` and `v_wind` instead of `eastward_wind` and `northward_wind`. Under some paths of computation, this avoids a redundant interpolation.
|
|
20
|
+
- Fix the `AircraftPerformance.ensure_true_airspeed_on_source` method in the case when the `met` attr is None and the `fill_with_groundspeed` parameter is enabled.
|
|
21
|
+
|
|
22
|
+
### Internals
|
|
23
|
+
|
|
24
|
+
- Make `pycontrails` compatible with `pandas 2.0` and `pandas 2.1`.
|
|
25
|
+
- Avoid auto-promotion of float32 to float64 within the `Emissions` model run-time.
|
|
26
|
+
- Add convenience `VectorDataset.get_constant` method.
|
|
27
|
+
|
|
28
|
+
## v0.54.6
|
|
29
|
+
|
|
30
|
+
### Features
|
|
31
|
+
|
|
32
|
+
- Add support for generic (model-agnostic) meteorology data to `Cocip` and `CocipGrid`.
|
|
33
|
+
|
|
34
|
+
- Add two new parameters to the `DryAdvection` model.
|
|
35
|
+
- If the `verbose_outputs` parameter is enabled, additional wind-shear data is included in the output.
|
|
36
|
+
- If the `include_source_in_output` parameter is enabled, the source data with any of the intermediate artifacts (e.g., interpolated met data, wind-shear data, etc.) is included in the output.
|
|
37
|
+
|
|
38
|
+
Both parameters are disabled by default.
|
|
39
|
+
|
|
40
|
+
### Fixes
|
|
41
|
+
|
|
42
|
+
- Update the CDS URL referenced throughout pycontrails from ``https://cds-beta.climate.copernicus.eu`` to ``https://cds.climate.copernicus.eu``.
|
|
43
|
+
|
|
44
|
+
### Internals
|
|
45
|
+
|
|
46
|
+
- Suppress mypy `return-value` errors for functions in `geo.py` where mypy fails to correctly infer return types of numpy ufuncs applied to xarray objects.
|
|
47
|
+
- Change `AircraftPerformance` and downstream implementations for better support in running over `Fleet` sources. The runtime of `PSFlight` remains the same.
|
|
48
|
+
|
|
3
49
|
## v0.54.5
|
|
4
50
|
|
|
5
51
|
### Features
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: pycontrails
|
|
3
|
-
Version: 0.54.
|
|
3
|
+
Version: 0.54.7
|
|
4
4
|
Summary: Python library for modeling aviation climate impacts
|
|
5
|
-
Author-email:
|
|
5
|
+
Author-email: "Contrails.org" <py@contrails.org>
|
|
6
6
|
License: Apache-2.0
|
|
7
7
|
Project-URL: Changelog, https://py.contrails.org/changelog.html
|
|
8
8
|
Project-URL: Documentation, https://py.contrails.org
|
|
@@ -29,7 +29,7 @@ License-File: LICENSE
|
|
|
29
29
|
License-File: NOTICE
|
|
30
30
|
Requires-Dist: dask>=2022.3
|
|
31
31
|
Requires-Dist: numpy>=1.22
|
|
32
|
-
Requires-Dist: pandas>=2.
|
|
32
|
+
Requires-Dist: pandas>=2.0
|
|
33
33
|
Requires-Dist: scipy>=1.10
|
|
34
34
|
Requires-Dist: typing-extensions>=4.5; python_version < "3.12"
|
|
35
35
|
Requires-Dist: xarray>=2022.3
|
|
@@ -49,8 +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
|
|
53
|
-
Requires-Dist: setuptools; extra == "dev"
|
|
52
|
+
Requires-Dist: ruff>=0.9.0; extra == "dev"
|
|
54
53
|
Provides-Extra: docs
|
|
55
54
|
Requires-Dist: doc8>=1.1; extra == "docs"
|
|
56
55
|
Requires-Dist: furo>=2023.3; extra == "docs"
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
Double check that the release tag is consistent and consecutive with
|
|
12
12
|
the previous release tag following [PEP 440](https://peps.python.org/pep-0440/#version-scheme).
|
|
13
13
|
This often but not always agrees with [Semantic Versioning](https://semver.org/).
|
|
14
|
-
1. Copy the CHANGELOG content for the release into the *Description*.
|
|
14
|
+
1. Copy the [CHANGELOG](https://raw.githubusercontent.com/contrailcirrus/pycontrails/refs/heads/main/CHANGELOG.md) content for the release into the *Description*.
|
|
15
15
|
1. Publish the new release.
|
|
16
16
|
This will create a tag on `main` and trigger the [Release Action](https://github.com/contrailcirrus/pycontrails/actions/workflows/release.yaml).
|
|
17
17
|
1. Confirm that the release is successfully deployed to [PyPI](https://pypi.org/project/pycontrails/).
|
|
@@ -15,9 +15,11 @@ import pycontrails
|
|
|
15
15
|
# -- Project information -----------------------------------------------------
|
|
16
16
|
|
|
17
17
|
project = "pycontrails"
|
|
18
|
-
copyright =
|
|
18
|
+
copyright = (
|
|
19
|
+
f"2021-{datetime.datetime.now().year}, Contrails.org and the Breakthrough Energy Foundation"
|
|
20
|
+
)
|
|
19
21
|
|
|
20
|
-
author = "
|
|
22
|
+
author = "Contrails.org"
|
|
21
23
|
version = pycontrails.__version__
|
|
22
24
|
release = pycontrails.__version__
|
|
23
25
|
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"\n",
|
|
17
17
|
"Support provided for:\n",
|
|
18
18
|
"\n",
|
|
19
|
-
"- [ERA5](https://www.ecmwf.int/en/forecasts/dataset/ecmwf-reanalysis-v5) via the [Copernicus Data Store
|
|
19
|
+
"- [ERA5](https://www.ecmwf.int/en/forecasts/dataset/ecmwf-reanalysis-v5) via the [Copernicus Data Store](https://cds.climate.copernicus.eu/) using [cdsapi](https://github.com/ecmwf/cdsapi) or user provided files\n",
|
|
20
20
|
"- [HRES](https://confluence.ecmwf.int/display/FUG/Section+2.1.1.2+Rationale+for+High+Resolution) and [ENS](https://confluence.ecmwf.int/display/FUG/Section+2.1.2.1+Medium+Range+Ensemble+forecasts) via [MARS](https://confluence.ecmwf.int/display/UDOC/MARS+user+documentation) using [ecmwf-api-client](https://github.com/ecmwf/ecmwf-api-client) or user provided files.\n",
|
|
21
21
|
"\n",
|
|
22
22
|
"For both ERA5 and HRES, we provide interfaces for accessing \"pressure-level data\" (fields pre-interpolated to a fixed set of pressure levels) or \"model-level data\" (fields retrieved on the native vertical grid and [interpolated after retrieval to an arbitrary set of pressure levels](model-levels.ipynb)). We recommend using model-level data when possible, as the resolution of pressure-level data is coarse relative to the vertical scale of ice-supersaturated regions.\n",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"\n",
|
|
33
33
|
"### Access\n",
|
|
34
34
|
"\n",
|
|
35
|
-
"- Requires account with [Copernicus Data Portal](https://cds
|
|
36
|
-
"- Provide `url` and `key` credentials on input, or refer to the [CDS API Documentation](https://cds
|
|
35
|
+
"- Requires account with [Copernicus Data Portal](https://cds.climate.copernicus.eu/)\n",
|
|
36
|
+
"- Provide `url` and `key` credentials on input, or refer to the [CDS API Documentation](https://cds.climate.copernicus.eu/how-to-api) for how to create `~/.cdsapirc` file to configure access.\n",
|
|
37
37
|
"\n",
|
|
38
38
|
"### Reference\n",
|
|
39
39
|
"\n",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
" time=\"2022-03-01 00:00:00\",\n",
|
|
88
88
|
" variables=[\"t\", \"q\", \"u\", \"v\", \"w\", \"ciwc\", \"z\", \"cc\"], # supports CF name or short names\n",
|
|
89
89
|
" pressure_levels=[200, 250, 300],\n",
|
|
90
|
-
" # url=\"https://cds
|
|
90
|
+
" # url=\"https://cds.climate.copernicus.eu/api\",\n",
|
|
91
91
|
" # key=\"<key>\"\n",
|
|
92
92
|
")\n",
|
|
93
93
|
"era5"
|
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
" \"cc\",\n",
|
|
133
133
|
" ], # supports CF name or short names\n",
|
|
134
134
|
" pressure_levels=[300, 250, 200],\n",
|
|
135
|
-
" # url=\"https://cds
|
|
135
|
+
" # url=\"https://cds.climate.copernicus.eu/api\",\n",
|
|
136
136
|
" # key=\"<key>\"\n",
|
|
137
137
|
")\n",
|
|
138
138
|
"era5"
|
|
@@ -1429,7 +1429,7 @@
|
|
|
1429
1429
|
"era5 = ERA5(\n",
|
|
1430
1430
|
" time=(\"2022-03-01 00:00:00\", \"2022-03-01 03:00:00\"),\n",
|
|
1431
1431
|
" variables=[\"tsr\", \"ttr\"],\n",
|
|
1432
|
-
" # url=\"https://cds
|
|
1432
|
+
" # url=\"https://cds.climate.copernicus.eu/api\",\n",
|
|
1433
1433
|
" # key=\"<key>\"\n",
|
|
1434
1434
|
")\n",
|
|
1435
1435
|
"era5"
|
|
@@ -6071,7 +6071,7 @@
|
|
|
6071
6071
|
" variables=variables,\n",
|
|
6072
6072
|
" pressure_levels=[300, 250, 150],\n",
|
|
6073
6073
|
" cachestore=gcp,\n",
|
|
6074
|
-
" # url=\"https://cds
|
|
6074
|
+
" # url=\"https://cds.climate.copernicus.eu/api\",\n",
|
|
6075
6075
|
" # key=\"<key>\"\n",
|
|
6076
6076
|
")"
|
|
6077
6077
|
]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
``pycontrails`` public API.
|
|
3
3
|
|
|
4
|
-
Copyright 2021-present Breakthrough Energy
|
|
4
|
+
Copyright 2021-present Contrails.org and the Breakthrough Energy Foundation
|
|
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.
|
|
@@ -71,6 +71,8 @@ class AircraftPerformanceParams(ModelParams, CommonAircraftPerformanceParams):
|
|
|
71
71
|
#: level with zero wind when computing true airspeed. In other words,
|
|
72
72
|
#: approximate low-altitude true airspeed with the ground speed. Enabling
|
|
73
73
|
#: this does NOT remove any NaN values in the ``met`` data itself.
|
|
74
|
+
#: In the case that ``met`` is not provided, any missing values are
|
|
75
|
+
#: filled with zero wind.
|
|
74
76
|
fill_low_altitude_with_zero_wind: bool = False
|
|
75
77
|
|
|
76
78
|
|
|
@@ -96,22 +98,52 @@ class AircraftPerformance(Model):
|
|
|
96
98
|
|
|
97
99
|
source: Flight
|
|
98
100
|
|
|
99
|
-
@abc.abstractmethod
|
|
100
101
|
@overload
|
|
101
102
|
def eval(self, source: Fleet, **params: Any) -> Fleet: ...
|
|
102
103
|
|
|
103
|
-
@abc.abstractmethod
|
|
104
104
|
@overload
|
|
105
105
|
def eval(self, source: Flight, **params: Any) -> Flight: ...
|
|
106
106
|
|
|
107
|
-
@abc.abstractmethod
|
|
108
107
|
@overload
|
|
109
108
|
def eval(self, source: None = ..., **params: Any) -> NoReturn: ...
|
|
110
109
|
|
|
111
|
-
@abc.abstractmethod
|
|
112
110
|
def eval(self, source: Flight | None = None, **params: Any) -> Flight:
|
|
113
111
|
"""Evaluate the aircraft performance model.
|
|
114
112
|
|
|
113
|
+
Parameters
|
|
114
|
+
----------
|
|
115
|
+
source : Flight
|
|
116
|
+
Flight trajectory to evaluate. Can be a :class:`Flight` or :class:`Fleet`.
|
|
117
|
+
params : Any
|
|
118
|
+
Override :attr:`params` with keyword arguments.
|
|
119
|
+
|
|
120
|
+
Returns
|
|
121
|
+
-------
|
|
122
|
+
Flight
|
|
123
|
+
Flight trajectory with aircraft performance data.
|
|
124
|
+
"""
|
|
125
|
+
self.update_params(params)
|
|
126
|
+
self.set_source(source)
|
|
127
|
+
self.source = self.require_source_type(Flight)
|
|
128
|
+
self.downselect_met()
|
|
129
|
+
self.set_source_met()
|
|
130
|
+
self._cleanup_indices()
|
|
131
|
+
|
|
132
|
+
# Calculate true airspeed if not included on source
|
|
133
|
+
self.ensure_true_airspeed_on_source()
|
|
134
|
+
|
|
135
|
+
if isinstance(self.source, Fleet):
|
|
136
|
+
fls = [self.eval_flight(fl) for fl in self.source.to_flight_list()]
|
|
137
|
+
self.source = Fleet.from_seq(fls, attrs=self.source.attrs, broadcast_numeric=False)
|
|
138
|
+
return self.source
|
|
139
|
+
|
|
140
|
+
self.source = self.eval_flight(self.source)
|
|
141
|
+
return self.source
|
|
142
|
+
|
|
143
|
+
@abc.abstractmethod
|
|
144
|
+
def eval_flight(self, fl: Flight) -> Flight:
|
|
145
|
+
"""Evaluate the aircraft performance model on a single flight trajectory.
|
|
146
|
+
|
|
115
147
|
The implementing model adds the following fields to the source flight:
|
|
116
148
|
|
|
117
149
|
- ``aircraft_mass``: aircraft mass at each waypoint, [:math:`kg`]
|
|
@@ -128,18 +160,6 @@ class AircraftPerformance(Model):
|
|
|
128
160
|
- ``max_mach``: maximum Mach number
|
|
129
161
|
- ``max_altitude``: maximum altitude, [:math:`m`]
|
|
130
162
|
- ``total_fuel_burn``: total fuel burn, [:math:`kg`]
|
|
131
|
-
|
|
132
|
-
Parameters
|
|
133
|
-
----------
|
|
134
|
-
source : Flight
|
|
135
|
-
Flight trajectory to evaluate.
|
|
136
|
-
params : Any
|
|
137
|
-
Override :attr:`params` with keyword arguments.
|
|
138
|
-
|
|
139
|
-
Returns
|
|
140
|
-
-------
|
|
141
|
-
Flight
|
|
142
|
-
Flight trajectory with aircraft performance data.
|
|
143
163
|
"""
|
|
144
164
|
|
|
145
165
|
@override
|
|
@@ -491,7 +511,8 @@ class AircraftPerformance(Model):
|
|
|
491
511
|
tas[cond] = self.source.segment_groundspeed()[cond]
|
|
492
512
|
return tas
|
|
493
513
|
|
|
494
|
-
|
|
514
|
+
# Use current cocip convention: eastward_wind on met, u_wind on source
|
|
515
|
+
wind_available = ("u_wind" in self.source and "v_wind" in self.source) or (
|
|
495
516
|
self.met is not None and "eastward_wind" in self.met and "northward_wind" in self.met
|
|
496
517
|
)
|
|
497
518
|
|
|
@@ -508,12 +529,16 @@ class AircraftPerformance(Model):
|
|
|
508
529
|
)
|
|
509
530
|
raise ValueError(msg)
|
|
510
531
|
|
|
511
|
-
u = interpolate_met(self.met, self.source, "eastward_wind", **self.interp_kwargs)
|
|
512
|
-
v = interpolate_met(self.met, self.source, "northward_wind", **self.interp_kwargs)
|
|
532
|
+
u = interpolate_met(self.met, self.source, "eastward_wind", "u_wind", **self.interp_kwargs)
|
|
533
|
+
v = interpolate_met(self.met, self.source, "northward_wind", "v_wind", **self.interp_kwargs)
|
|
513
534
|
|
|
514
535
|
if fill_with_groundspeed:
|
|
515
|
-
|
|
516
|
-
|
|
536
|
+
if self.met is None:
|
|
537
|
+
cond = np.isnan(u) & np.isnan(v)
|
|
538
|
+
else:
|
|
539
|
+
met_level_max = self.met.data["level"][-1].item() # type: ignore[union-attr]
|
|
540
|
+
cond = self.source.level > met_level_max
|
|
541
|
+
|
|
517
542
|
# We DON'T overwrite the original u and v arrays already attached to the source
|
|
518
543
|
u = np.where(cond, 0.0, u)
|
|
519
544
|
v = np.where(cond, 0.0, v)
|
|
@@ -639,28 +664,3 @@ def _fill_low_altitude_with_isa_temperature(vector: GeoVectorDataset, met_level_
|
|
|
639
664
|
|
|
640
665
|
t_isa = vector.T_isa()
|
|
641
666
|
air_temperature[cond] = t_isa[cond]
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
def _fill_low_altitude_tas_with_true_groundspeed(fl: Flight, met_level_max: float) -> None:
|
|
645
|
-
"""Fill low-altitude NaN values in ``true_airspeed`` with ground speed.
|
|
646
|
-
|
|
647
|
-
The ``true_airspeed`` param is assumed to have been computed by
|
|
648
|
-
interpolating against a gridded wind field that did not necessarily
|
|
649
|
-
extend to the surface. This function fills points below the lowest
|
|
650
|
-
altitude in the gridded data with ground speed values.
|
|
651
|
-
|
|
652
|
-
This function operates in-place and modifies the ``true_airspeed`` field.
|
|
653
|
-
|
|
654
|
-
Parameters
|
|
655
|
-
----------
|
|
656
|
-
fl : Flight
|
|
657
|
-
Flight instance associated with the ``true_airspeed`` data.
|
|
658
|
-
met_level_max : float
|
|
659
|
-
The maximum level in the met data, [:math:`hPa`].
|
|
660
|
-
"""
|
|
661
|
-
tas = fl["true_airspeed"]
|
|
662
|
-
is_nan = np.isnan(tas)
|
|
663
|
-
low_alt = fl.level > met_level_max
|
|
664
|
-
cond = is_nan & low_alt
|
|
665
|
-
|
|
666
|
-
tas[cond] = fl.segment_groundspeed()[cond]
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import functools
|
|
6
|
+
|
|
5
7
|
import numpy as np
|
|
6
8
|
import pandas as pd
|
|
7
9
|
|
|
@@ -35,6 +37,7 @@ def _download_ourairports_csv() -> pd.DataFrame:
|
|
|
35
37
|
)
|
|
36
38
|
|
|
37
39
|
|
|
40
|
+
@functools.cache
|
|
38
41
|
def global_airport_database(
|
|
39
42
|
cachestore: cache.CacheStore | None = None, update_cache: bool = False
|
|
40
43
|
) -> pd.DataFrame:
|
|
@@ -91,7 +94,7 @@ def global_airport_database(
|
|
|
91
94
|
airports = airports.rename(
|
|
92
95
|
columns={"latitude_deg": "latitude", "longitude_deg": "longitude", "gps_code": "icao_code"},
|
|
93
96
|
)
|
|
94
|
-
airports.fillna({"elevation_ft": 0}, inplace=True)
|
|
97
|
+
airports.fillna({"elevation_ft": 0.0}, inplace=True)
|
|
95
98
|
|
|
96
99
|
# Keep specific airport types used by commercial aviation
|
|
97
100
|
subset = ("large_airport", "medium_airport", "small_airport", "heliport")
|
|
@@ -162,7 +165,7 @@ def find_nearest_airport(
|
|
|
162
165
|
) & airports["latitude"].between((latitude - bbox), (latitude + bbox))
|
|
163
166
|
|
|
164
167
|
# Find the nearest airport from largest to smallest airport type
|
|
165
|
-
search_priority =
|
|
168
|
+
search_priority = ("large_airport", "medium_airport", "small_airport")
|
|
166
169
|
|
|
167
170
|
for airport_type in search_priority:
|
|
168
171
|
is_airport_type = airports["type"] == airport_type
|
|
@@ -171,7 +174,7 @@ def find_nearest_airport(
|
|
|
171
174
|
if len(nearest_airports) == 1:
|
|
172
175
|
return nearest_airports["icao_code"].values[0]
|
|
173
176
|
|
|
174
|
-
|
|
177
|
+
if len(nearest_airports) > 1:
|
|
175
178
|
distance = distance_to_airports(
|
|
176
179
|
nearest_airports,
|
|
177
180
|
longitude,
|
|
@@ -181,8 +184,7 @@ def find_nearest_airport(
|
|
|
181
184
|
i_nearest = np.argmin(distance)
|
|
182
185
|
return nearest_airports["icao_code"].values[i_nearest]
|
|
183
186
|
|
|
184
|
-
|
|
185
|
-
continue
|
|
187
|
+
continue
|
|
186
188
|
|
|
187
189
|
return None
|
|
188
190
|
|
|
@@ -891,7 +891,7 @@ class Flight(GeoVectorDataset):
|
|
|
891
891
|
"""
|
|
892
892
|
methods = "geodesic", "linear"
|
|
893
893
|
if fill_method not in methods:
|
|
894
|
-
raise ValueError(f
|
|
894
|
+
raise ValueError(f"Unknown `fill_method`. Supported methods: {', '.join(methods)}")
|
|
895
895
|
|
|
896
896
|
# STEP 0: If self is empty, return an empty flight
|
|
897
897
|
if not self:
|
|
@@ -1388,7 +1388,7 @@ class Flight(GeoVectorDataset):
|
|
|
1388
1388
|
|
|
1389
1389
|
jump_indices = _antimeridian_index(pd.Series(self["longitude"]))
|
|
1390
1390
|
|
|
1391
|
-
def _group_to_feature(group: pd.DataFrame) -> dict[str, str | dict[str, Any]]:
|
|
1391
|
+
def _group_to_feature(name: str, group: pd.DataFrame) -> dict[str, str | dict[str, Any]]:
|
|
1392
1392
|
# assigns a different value to each group of consecutive indices
|
|
1393
1393
|
subgrouping = group.index.to_series().diff().ne(1).cumsum()
|
|
1394
1394
|
|
|
@@ -1405,7 +1405,7 @@ class Flight(GeoVectorDataset):
|
|
|
1405
1405
|
geometry = {"type": "MultiLineString", "coordinates": multi_ls}
|
|
1406
1406
|
|
|
1407
1407
|
# adding in static properties
|
|
1408
|
-
properties: dict[str, Any] = {key:
|
|
1408
|
+
properties: dict[str, Any] = {key: name} if key is not None else {}
|
|
1409
1409
|
properties.update(self.constants)
|
|
1410
1410
|
return {"type": "Feature", "geometry": geometry, "properties": properties}
|
|
1411
1411
|
|
|
@@ -1415,11 +1415,11 @@ class Flight(GeoVectorDataset):
|
|
|
1415
1415
|
# create a single group containing all rows of dataframe
|
|
1416
1416
|
groups = self.dataframe.groupby(lambda _: 0)
|
|
1417
1417
|
|
|
1418
|
-
features =
|
|
1418
|
+
features = [_group_to_feature(*name_group) for name_group in groups]
|
|
1419
1419
|
return {"type": "FeatureCollection", "features": features}
|
|
1420
1420
|
|
|
1421
1421
|
def to_traffic(self) -> traffic.core.Flight:
|
|
1422
|
-
"""Convert to :class:`traffic.core.Flight`instance.
|
|
1422
|
+
"""Convert to :class:`traffic.core.Flight` instance.
|
|
1423
1423
|
|
|
1424
1424
|
Returns
|
|
1425
1425
|
-------
|
|
@@ -1982,9 +1982,7 @@ def filter_altitude(
|
|
|
1982
1982
|
result[i0:i1] = altitude_filt[i0:i1]
|
|
1983
1983
|
|
|
1984
1984
|
# reapply Savitzky-Golay filter to smooth climb and descent
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
return result
|
|
1985
|
+
return _sg_filter(result, window_length=kernel_size)
|
|
1988
1986
|
|
|
1989
1987
|
|
|
1990
1988
|
def segment_duration(
|
|
@@ -21,24 +21,24 @@ def to_atc_plan(plan: dict[str, Any]) -> str:
|
|
|
21
21
|
--------
|
|
22
22
|
:func:`parse_atc_plan`
|
|
23
23
|
"""
|
|
24
|
-
ret = f
|
|
25
|
-
ret += f
|
|
24
|
+
ret = f"(FPL-{plan['callsign']}-{plan['flight_rules']}"
|
|
25
|
+
ret += f"{plan['type_of_flight']}\n"
|
|
26
26
|
ret += "-"
|
|
27
27
|
if "number_aircraft" in plan and plan["number_aircraft"] <= 10:
|
|
28
28
|
ret += plan["number_aircraft"]
|
|
29
|
-
ret += f
|
|
30
|
-
ret += f
|
|
31
|
-
ret += f
|
|
32
|
-
ret += f
|
|
33
|
-
ret += f
|
|
29
|
+
ret += f"{plan['type_of_aircraft']}/{plan['wake_category']}-"
|
|
30
|
+
ret += f"{plan['equipment']}/{plan['transponder']}\n"
|
|
31
|
+
ret += f"-{plan['departure_icao']}{plan['time']}\n"
|
|
32
|
+
ret += f"-{plan['speed_type']}{plan['speed']}{plan['level_type']}"
|
|
33
|
+
ret += f"{plan['level']} {plan['route']}\n"
|
|
34
34
|
if "destination_icao" in plan and "duration" in plan:
|
|
35
|
-
ret += f
|
|
35
|
+
ret += f"-{plan['destination_icao']}{plan['duration']}"
|
|
36
36
|
if "alt_icao" in plan:
|
|
37
|
-
ret += f
|
|
37
|
+
ret += f" {plan['alt_icao']}"
|
|
38
38
|
if "second_alt_icao" in plan:
|
|
39
|
-
ret += f
|
|
39
|
+
ret += f" {plan['second_alt_icao']}"
|
|
40
40
|
ret += "\n"
|
|
41
|
-
ret += f
|
|
41
|
+
ret += f"-{plan['other_info']})\n"
|
|
42
42
|
if "supplementary_info" in plan:
|
|
43
43
|
ret += " ".join([f"{i[0]}/{i[1]}" for i in plan["supplementary_info"].items()])
|
|
44
44
|
|
|
@@ -150,11 +150,8 @@ class MetBase(ABC, Generic[XArrayType]):
|
|
|
150
150
|
"""
|
|
151
151
|
longitude = self.indexes["longitude"].to_numpy()
|
|
152
152
|
if longitude.dtype != COORD_DTYPE:
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
"Instantiate with 'copy=True' to convert to float64. "
|
|
156
|
-
"Instantiate with 'validate=False' to skip validation."
|
|
157
|
-
)
|
|
153
|
+
msg = f"Longitude values must have dtype {COORD_DTYPE}. Instantiate with 'copy=True'."
|
|
154
|
+
raise ValueError(msg)
|
|
158
155
|
|
|
159
156
|
if self.is_wrapped:
|
|
160
157
|
# Relax verification if the longitude has already been processed and wrapped
|
|
@@ -194,11 +191,8 @@ class MetBase(ABC, Generic[XArrayType]):
|
|
|
194
191
|
"""
|
|
195
192
|
latitude = self.indexes["latitude"].to_numpy()
|
|
196
193
|
if latitude.dtype != COORD_DTYPE:
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
"Instantiate with 'copy=True' to convert to float64. "
|
|
200
|
-
"Instantiate with 'validate=False' to skip validation."
|
|
201
|
-
)
|
|
194
|
+
msg = f"Latitude values must have dtype {COORD_DTYPE}. Instantiate with 'copy=True'."
|
|
195
|
+
raise ValueError(msg)
|
|
202
196
|
|
|
203
197
|
if latitude[0] < -90.0:
|
|
204
198
|
raise ValueError(
|
|
@@ -233,8 +227,8 @@ class MetBase(ABC, Generic[XArrayType]):
|
|
|
233
227
|
if da.dims != self.dim_order:
|
|
234
228
|
if key is not None:
|
|
235
229
|
msg = (
|
|
236
|
-
f"Data dimension not transposed on variable '{key}'.
|
|
237
|
-
" 'copy=True'."
|
|
230
|
+
f"Data dimension not transposed on variable '{key}'. "
|
|
231
|
+
"Instantiate with 'copy=True'."
|
|
238
232
|
)
|
|
239
233
|
else:
|
|
240
234
|
msg = "Data dimension not transposed. Instantiate with 'copy=True'."
|
|
@@ -258,11 +252,8 @@ class MetBase(ABC, Generic[XArrayType]):
|
|
|
258
252
|
self._validate_latitude()
|
|
259
253
|
self._validate_transpose()
|
|
260
254
|
if self.data["level"].dtype != COORD_DTYPE:
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
"Instantiate with 'copy=True' to convert to float64. "
|
|
264
|
-
"Instantiate with 'validate=False' to skip validation."
|
|
265
|
-
)
|
|
255
|
+
msg = f"Level values must have dtype {COORD_DTYPE}. Instantiate with 'copy=True'."
|
|
256
|
+
raise ValueError(msg)
|
|
266
257
|
|
|
267
258
|
def _preprocess_dims(self, wrap_longitude: bool) -> None:
|
|
268
259
|
"""Confirm DataArray or Dataset include required dimension in a consistent format.
|
|
@@ -435,7 +426,7 @@ class MetBase(ABC, Generic[XArrayType]):
|
|
|
435
426
|
Assumes the longitude dimension is sorted (this is established by the
|
|
436
427
|
:class:`MetDataset` or :class:`MetDataArray` constructor).
|
|
437
428
|
|
|
438
|
-
.. versionchanged 0.26.0
|
|
429
|
+
.. versionchanged:: 0.26.0
|
|
439
430
|
|
|
440
431
|
The previous implementation checked for the minimum and maximum longitude
|
|
441
432
|
dimension values to be duplicated. The current implementation only checks for
|
|
@@ -492,7 +483,7 @@ class MetBase(ABC, Generic[XArrayType]):
|
|
|
492
483
|
|
|
493
484
|
Does not yet save in parallel.
|
|
494
485
|
|
|
495
|
-
.. versionchanged::0.34.1
|
|
486
|
+
.. versionchanged:: 0.34.1
|
|
496
487
|
|
|
497
488
|
If :attr:`cachestore` is None, this method assigns it
|
|
498
489
|
to new :class:`DiskCacheStore`.
|
|
@@ -1178,19 +1169,45 @@ class MetDataset(MetBase):
|
|
|
1178
1169
|
}
|
|
1179
1170
|
return self._get_pycontrails_attr_template("product", supported, examples)
|
|
1180
1171
|
|
|
1181
|
-
|
|
1182
|
-
|
|
1172
|
+
@overload
|
|
1173
|
+
def standardize_variables(
|
|
1174
|
+
self, variables: Iterable[MetVariable], inplace: Literal[False] = ...
|
|
1175
|
+
) -> Self: ...
|
|
1176
|
+
|
|
1177
|
+
@overload
|
|
1178
|
+
def standardize_variables(
|
|
1179
|
+
self, variables: Iterable[MetVariable], inplace: Literal[True]
|
|
1180
|
+
) -> None: ...
|
|
1181
|
+
|
|
1182
|
+
def standardize_variables(
|
|
1183
|
+
self, variables: Iterable[MetVariable], inplace: bool = False
|
|
1184
|
+
) -> Self | None:
|
|
1185
|
+
"""Standardize variable names.
|
|
1186
|
+
|
|
1187
|
+
.. versionchanged:: 0.54.7
|
|
1188
|
+
|
|
1189
|
+
By default, this method returns a new :class:`MetDataset` instead
|
|
1190
|
+
of renaming in place. To retain the old behavior, set ``inplace=True``.
|
|
1183
1191
|
|
|
1184
1192
|
Parameters
|
|
1185
1193
|
----------
|
|
1186
1194
|
variables : Iterable[MetVariable]
|
|
1187
1195
|
Data source variables
|
|
1196
|
+
inplace : bool, optional
|
|
1197
|
+
If True, rename variables in place. Otherwise, return a new
|
|
1198
|
+
:class:`MetDataset` with renamed variables.
|
|
1188
1199
|
|
|
1189
1200
|
See Also
|
|
1190
1201
|
--------
|
|
1191
1202
|
:func:`standardize_variables`
|
|
1192
1203
|
"""
|
|
1193
|
-
standardize_variables(self, variables)
|
|
1204
|
+
data_renamed = standardize_variables(self.data, variables)
|
|
1205
|
+
|
|
1206
|
+
if inplace:
|
|
1207
|
+
self.data = data_renamed
|
|
1208
|
+
return None
|
|
1209
|
+
|
|
1210
|
+
return type(self)._from_fastpath(data_renamed, cachestore=self.cachestore)
|
|
1194
1211
|
|
|
1195
1212
|
@classmethod
|
|
1196
1213
|
def from_coords(
|
|
@@ -2642,7 +2659,7 @@ def downselect(data: XArrayType, bbox: tuple[float, ...]) -> XArrayType:
|
|
|
2642
2659
|
return data.where(cond, drop=True)
|
|
2643
2660
|
|
|
2644
2661
|
|
|
2645
|
-
def standardize_variables(ds:
|
|
2662
|
+
def standardize_variables(ds: xr.Dataset, variables: Iterable[MetVariable]) -> xr.Dataset:
|
|
2646
2663
|
"""Rename all variables in dataset from short name to standard name.
|
|
2647
2664
|
|
|
2648
2665
|
This function does not change any variables in ``ds`` that are not found in ``variables``.
|
|
@@ -2652,8 +2669,7 @@ def standardize_variables(ds: DatasetType, variables: Iterable[MetVariable]) ->
|
|
|
2652
2669
|
Parameters
|
|
2653
2670
|
----------
|
|
2654
2671
|
ds : DatasetType
|
|
2655
|
-
An :class:`xr.Dataset
|
|
2656
|
-
passed, the underlying :class:`xr.Dataset` is modified in place.
|
|
2672
|
+
An :class:`xr.Dataset`.
|
|
2657
2673
|
variables : Iterable[MetVariable]
|
|
2658
2674
|
Data source variables
|
|
2659
2675
|
|
|
@@ -2662,14 +2678,6 @@ def standardize_variables(ds: DatasetType, variables: Iterable[MetVariable]) ->
|
|
|
2662
2678
|
DatasetType
|
|
2663
2679
|
Dataset with variables renamed to standard names
|
|
2664
2680
|
"""
|
|
2665
|
-
if isinstance(ds, xr.Dataset):
|
|
2666
|
-
return _standardize_variables(ds, variables)
|
|
2667
|
-
|
|
2668
|
-
ds.data = _standardize_variables(ds.data, variables)
|
|
2669
|
-
return ds
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
def _standardize_variables(ds: xr.Dataset, variables: Iterable[MetVariable]) -> xr.Dataset:
|
|
2673
2681
|
variables_dict: dict[Hashable, str] = {v.short_name: v.standard_name for v in variables}
|
|
2674
2682
|
name_dict = {var: variables_dict[var] for var in ds.data_vars if var in variables_dict}
|
|
2675
2683
|
return ds.rename(name_dict)
|