pycontrails 0.57.0__tar.gz → 0.58.0__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.57.0 → pycontrails-0.58.0}/.github/workflows/release.yaml +2 -2
- {pycontrails-0.57.0 → pycontrails-0.58.0}/.github/workflows/test.yaml +1 -1
- {pycontrails-0.57.0 → pycontrails-0.58.0}/CHANGELOG.md +16 -0
- {pycontrails-0.57.0/pycontrails.egg-info → pycontrails-0.58.0}/PKG-INFO +5 -5
- {pycontrails-0.57.0 → pycontrails-0.58.0}/README.md +1 -1
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/api.rst +4 -2
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/install.rst +3 -2
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/GOES.ipynb +4 -4
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/_version.py +3 -3
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/core/aircraft_performance.py +1 -1
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/core/cache.py +2 -2
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/core/fleet.py +2 -7
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/core/flight.py +2 -7
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/core/interpolation.py +42 -64
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/core/met.py +36 -16
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/core/polygon.py +3 -3
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/core/rgi_cython.c +419 -1985
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/core/rgi_cython.pyx +0 -144
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/core/vector.py +3 -8
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/_met_utils/metsource.py +4 -7
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/ecmwf/common.py +2 -2
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/ecmwf/hres.py +2 -2
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/ecmwf/ifs.py +1 -1
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/gfs/gfs.py +1 -1
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/himawari/header_struct.py +1 -1
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/himawari/himawari.py +20 -7
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/leo_utils/sentinel_metadata.py +9 -9
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/ext/synthetic_flight.py +2 -2
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/cocip/cocip_uncertainty.py +1 -1
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/cocip/contrail_properties.py +1 -1
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/cocip/output_formats.py +1 -1
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/cocipgrid/cocip_grid.py +3 -3
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/dry_advection.py +1 -1
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/extended_k15.py +4 -4
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/humidity_scaling/humidity_scaling.py +2 -2
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/ps_model/ps_grid.py +2 -2
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/sac.py +1 -1
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/tau_cirrus.py +1 -1
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/physics/thermo.py +1 -1
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/utils/iteration.py +1 -1
- {pycontrails-0.57.0 → pycontrails-0.58.0/pycontrails.egg-info}/PKG-INFO +5 -5
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails.egg-info/requires.txt +1 -1
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pyproject.toml +23 -8
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_dtypes.py +2 -2
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_grid_to_netcdf.py +1 -1
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_interpolation.py +7 -9
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_met.py +20 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/.github/dependabot.yaml +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/.github/pull_request_template.md +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/.github/workflows/docs.yaml +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/.github/workflows/doctest.yaml +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/.github/workflows/scorecard.yaml +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/.gitignore +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/.pre-commit-config.yaml +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/.zenodo.json +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/CONTRIBUTING.md +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/LICENSE +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/Makefile +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/NOTICE +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/RELEASE.md +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/_static/css/style.css +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/_static/img/colab.png +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/_static/img/favicon.png +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/_static/img/logo-dark.png +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/_static/img/logo.png +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/_static/pycontrails.bib +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/changelog.rst +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/conf.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/contributing.rst +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/develop.rst +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/flight.rst +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/index.rst +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/integrations/ACCF.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/integrations/APCEMM.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/literature.rst +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/meteorology.rst +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/models.rst +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/ARCO-ERA5.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/AircraftPerformance.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/Cache.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/CoCiP.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/CoCiPGrid.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/ECMWF.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/Flight.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/GFS.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/Himawari.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/ISSR.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/Landsat.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/Meteorology.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/SAC.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/Sentinel.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/advection.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/airports.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/data/.gitignore +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/data/flight-ap.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/data/flight-cocip.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/data/flight-fdr.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/data/flight-noisy.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/data/flight.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/data/iagos-flight-landsat.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/data/iagos-flight-sentinel.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/flightplan.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/model-levels.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/run-cocip-on-flight.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/run-cocip-with-fdr.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks/specific-humidity-interpolation.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/notebooks.rst +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/observations.rst +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/tutorials.rst +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/docs/utilities.rst +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/core/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/core/airports.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/core/coordinates.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/core/flightplan.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/core/fuel.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/core/met_var.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/core/models.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/ecmwf/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/ecmwf/arco_era5.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/ecmwf/era5.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/ecmwf/era5_model_level.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/ecmwf/hres_model_level.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/ecmwf/model_levels.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/ecmwf/static/model_level_dataframe_v20240418.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/ecmwf/variables.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/geo_utils.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/gfs/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/gfs/variables.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/goes.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/himawari/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/landsat.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/leo_utils/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/leo_utils/correction.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/leo_utils/landsat_metadata.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/leo_utils/search.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/leo_utils/static/bq_roi_query.sql +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/leo_utils/vis.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/sentinel.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/spire/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/spire/exceptions.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/datalib/spire/spire.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/ext/bada.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/ext/cirium.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/ext/empirical_grid.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/accf.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/apcemm/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/apcemm/apcemm.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/apcemm/inputs.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/apcemm/static/apcemm_yaml_template.yaml +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/apcemm/utils.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/cocip/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/cocip/cocip.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/cocip/cocip_params.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/cocip/radiative_forcing.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/cocip/radiative_heating.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/cocip/unterstrasser_wake_vortex.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/cocip/wake_vortex.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/cocip/wind_shear.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/cocipgrid/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/cocipgrid/cocip_grid_params.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/emissions/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/emissions/black_carbon.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/emissions/emissions.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/emissions/ffm2.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/emissions/static/default-engine-uids.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/emissions/static/edb-gaseous-v29b-engines.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/emissions/static/edb-nvpm-v29b-engines.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/humidity_scaling/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/humidity_scaling/quantiles/era5-model-level-quantiles.pq +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/humidity_scaling/quantiles/era5-pressure-level-quantiles.pq +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/issr.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/pcc.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/pcr.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/ps_model/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/ps_model/ps_aircraft_params.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/ps_model/ps_model.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/ps_model/ps_operational_limits.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/ps_model/static/ps-aircraft-params-20250328.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/models/ps_model/static/ps-synonym-list-20250328.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/physics/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/physics/constants.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/physics/geo.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/physics/jet.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/physics/static/iata-cargo-load-factors-20250221.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/physics/static/iata-passenger-load-factors-20250221.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/physics/units.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/py.typed +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/utils/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/utils/dependencies.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/utils/json.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/utils/temp.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails/utils/types.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails.egg-info/SOURCES.txt +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails.egg-info/dependency_links.txt +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/pycontrails.egg-info/top_level.txt +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/setup.cfg +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/setup.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/_deprecated.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/benchmark/cocip/Makefile +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/benchmark/cocip/README.md +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/benchmark/cocip/benchmark.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/benchmark/cocip/compare.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/benchmark/cocip/data.md +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/benchmark/cocip/output.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/benchmark/cocip/review.ipynb +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/benchmark/cocip-fortran/README.md +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/benchmark/north-atlantic-study/.gcloudignore +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/benchmark/north-atlantic-study/README.md +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/benchmark/north-atlantic-study/support.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/benchmark/north-atlantic-study/validate.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/fixtures/cocip-met.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/fixtures/cocip-met2.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/fixtures/ecmwf-met.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/fixtures/gfs-met.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/__init__.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/conftest.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/NOAA_Solar_Calculations_day.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/cocip-contrail-output.json +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/cocip-contrail-output2.json +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/cocip-flight-output.json +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/cocip-flight-output2.json +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/cocip-output-contrail-edges.json +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/cocip-output-flts-20190101-eu.pq +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/flight-cocip2.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/flight-meridian.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/flight-metadata.json +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/flight-spire-data-cleaning.pq +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/flight.csv +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/flt-wypts-20190101-eu.pq +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/met-20190101-eu.nc +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/met-accf-pl.nc +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/met-accf-sl.nc +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/met-ecmwf-lnsp.nc +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/met-ecmwf-ml.nc +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/met-ecmwf-pl.nc +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/met-ecmwf-sl.nc +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/met-era5-cocip1.nc +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/met-era5-cocip2.nc +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/met-gfs.nc +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/polygon-bug.nc +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/rad-20190101-eu.nc +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/rad-era5-cocip1.nc +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/rad-era5-cocip2.nc +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/static/rad-gfs.nc +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_accf.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_airports.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_apcemm.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_cache.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_cocip.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_cocip_grid.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_cocip_grid_parity.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_cocip_radiative_forcing.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_cocip_uncertainty.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_coordinates.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_datalib_metsource.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_dry_advection.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_ecmwf.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_emissions.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_fleet.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_flight.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_flightplan.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_fuel.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_geo.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_gfs.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_goes.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_himawari.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_humidity_scaling.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_init.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_leo.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_met_cache.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_models.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_pcc.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_polygons.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_ps_model.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_sac_issr.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_spire.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_tau_cirrus.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_thermo_sac.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_units.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_unterstrasser_wake_vortex.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_utils.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_vector.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_vpm.py +0 -0
- {pycontrails-0.57.0 → pycontrails-0.58.0}/tests/unit/test_zarr.py +0 -0
|
@@ -42,11 +42,11 @@ jobs:
|
|
|
42
42
|
- name: Build wheels
|
|
43
43
|
uses: pypa/cibuildwheel@v3.2
|
|
44
44
|
env:
|
|
45
|
-
CIBW_BUILD:
|
|
45
|
+
CIBW_BUILD: cp311-* cp312-* cp313-* cp314-*
|
|
46
46
|
CIBW_SKIP: '*-win32 *-manylinux_i686 *-musllinux*'
|
|
47
47
|
CIBW_BUILD_VERBOSITY: 3
|
|
48
48
|
CIBW_ARCHS_MACOS: x86_64 arm64
|
|
49
|
-
CIBW_TEST_SKIP: '*-macosx_arm64'
|
|
49
|
+
CIBW_TEST_SKIP: '*-macosx_arm64 cp314-*'
|
|
50
50
|
# Completely isolate tests to prevent cibuildwheel from importing the
|
|
51
51
|
# source instead of the wheel. This happens when tests/__init__.py is read.
|
|
52
52
|
CIBW_TEST_EXTRAS: "complete,dev"
|
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.58.0
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- Build wheels for python 3.14. These are not yet tested in the CI (not all dependencies support python 3.14 yet).
|
|
8
|
+
|
|
9
|
+
### Breaking changes
|
|
10
|
+
|
|
11
|
+
- Drop support for python 3.10 per [NEP 29](https://numpy.org/neps/nep-0029-deprecation_policy.html).
|
|
12
|
+
- Require scipy >= 1.12 to better support the `PycontrailsRegularGridInterpolator` interface.
|
|
13
|
+
|
|
14
|
+
### Fixes
|
|
15
|
+
|
|
16
|
+
- When instantiated with `copy=True`, `MetDataset` and `MetDataArray` now remove duplicate dimension values, preserving only the first occurrence of each. Previously, duplicates were silently retained (such duplicates are not expected with typical gridded weather data). With `copy=False`, a `ValueError` is raised if duplicate dimension values are present.
|
|
17
|
+
- Update `PycontrailsRegularGridInterpolator` for improved compatibility with `scipy.interpolate.RegularGridInterpolator`. All methods now delegate to SciPy’s implementation, except for `method="linear"`, which retains a fast-path optimized in `PycontrailsRegularGridInterpolator`.
|
|
18
|
+
|
|
3
19
|
## 0.57.0
|
|
4
20
|
|
|
5
21
|
### Features
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pycontrails
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.58.0
|
|
4
4
|
Summary: Python library for modeling aviation climate impacts
|
|
5
5
|
Author-email: "Contrails.org" <py@contrails.org>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -13,23 +13,23 @@ Classifier: Development Status :: 4 - Beta
|
|
|
13
13
|
Classifier: Intended Audience :: Science/Research
|
|
14
14
|
Classifier: Operating System :: OS Independent
|
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
20
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
21
21
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
22
|
Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
|
|
23
23
|
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
24
24
|
Classifier: Typing :: Typed
|
|
25
|
-
Requires-Python: >=3.
|
|
25
|
+
Requires-Python: >=3.11
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
27
27
|
License-File: LICENSE
|
|
28
28
|
License-File: NOTICE
|
|
29
29
|
Requires-Dist: dask>=2022.3
|
|
30
30
|
Requires-Dist: numpy>=1.22
|
|
31
31
|
Requires-Dist: pandas>=2.0
|
|
32
|
-
Requires-Dist: scipy>=1.
|
|
32
|
+
Requires-Dist: scipy>=1.12
|
|
33
33
|
Requires-Dist: typing-extensions>=4.5; python_version < "3.12"
|
|
34
34
|
Requires-Dist: xarray>=2022.3
|
|
35
35
|
Provides-Extra: complete
|
|
@@ -140,7 +140,7 @@ Documentation and examples available at [py.contrails.org](https://py.contrails.
|
|
|
140
140
|
|
|
141
141
|
### Install with pip
|
|
142
142
|
|
|
143
|
-
You can install pycontrails from PyPI with `pip` (Python 3.
|
|
143
|
+
You can install pycontrails from PyPI with `pip` (Python 3.11 or later required):
|
|
144
144
|
|
|
145
145
|
```bash
|
|
146
146
|
$ pip install pycontrails
|
|
@@ -25,7 +25,7 @@ Documentation and examples available at [py.contrails.org](https://py.contrails.
|
|
|
25
25
|
|
|
26
26
|
### Install with pip
|
|
27
27
|
|
|
28
|
-
You can install pycontrails from PyPI with `pip` (Python 3.
|
|
28
|
+
You can install pycontrails from PyPI with `pip` (Python 3.11 or later required):
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
31
|
$ pip install pycontrails
|
|
@@ -83,13 +83,15 @@ ARCO ERA5
|
|
|
83
83
|
datalib.ecmwf.arco_era5
|
|
84
84
|
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
""""
|
|
86
|
+
Geostationary Satellites
|
|
87
|
+
""""""""""""""""""""""""
|
|
88
88
|
|
|
89
89
|
.. autosummary::
|
|
90
90
|
:toctree: api/
|
|
91
91
|
|
|
92
92
|
datalib.goes
|
|
93
|
+
datalib.himawari
|
|
94
|
+
datalib.geo_utils
|
|
93
95
|
|
|
94
96
|
|
|
95
97
|
Low Earth Orbit Satellites
|
|
@@ -17,7 +17,7 @@ The conda-forge package includes all optional runtime dependencies.
|
|
|
17
17
|
pip install
|
|
18
18
|
-----------
|
|
19
19
|
|
|
20
|
-
With Python 3.
|
|
20
|
+
With Python 3.11 or later, install the latest release from PyPI using ``pip``:
|
|
21
21
|
|
|
22
22
|
.. code-block:: bash
|
|
23
23
|
|
|
@@ -27,7 +27,8 @@ With Python 3.10 or later, install the latest release from PyPI using ``pip``:
|
|
|
27
27
|
# install with all optional dependencies
|
|
28
28
|
$ pip install "pycontrails[complete]"
|
|
29
29
|
|
|
30
|
-
Wheels are currently built
|
|
30
|
+
Wheels are currently built for python 3.11 - 3.14 and tested for
|
|
31
|
+
python 3.11 - 3.13 on Linux, macOS, and Windows.
|
|
31
32
|
|
|
32
33
|
Install the latest development version directly from GitHub:
|
|
33
34
|
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"\n",
|
|
31
31
|
"By default, any GOES data will be cached on disk. Set `cachestore=None` to disable caching when defining the `GOES` object.\n",
|
|
32
32
|
"\n",
|
|
33
|
-
"We download data for
|
|
33
|
+
"We download data for bands 1, 2, and 3. These are needed for creating a true color image."
|
|
34
34
|
]
|
|
35
35
|
},
|
|
36
36
|
{
|
|
@@ -692,7 +692,7 @@
|
|
|
692
692
|
}
|
|
693
693
|
],
|
|
694
694
|
"source": [
|
|
695
|
-
"handler = goes.GOES(region=\"conus\",
|
|
695
|
+
"handler = goes.GOES(region=\"conus\", bands=(\"C01\", \"C02\", \"C03\"))\n",
|
|
696
696
|
"\n",
|
|
697
697
|
"# Download the data\n",
|
|
698
698
|
"da = handler.get(\"2023-02-05T18:00:00\")\n",
|
|
@@ -3849,7 +3849,7 @@
|
|
|
3849
3849
|
"\n",
|
|
3850
3850
|
"The ash color scheme was originally developed to visualize volcanic ash. It is also useful for visualizing contrails.\n",
|
|
3851
3851
|
"\n",
|
|
3852
|
-
"We download data for
|
|
3852
|
+
"We download data for bands 11, 14, and 15 to create an ash color image."
|
|
3853
3853
|
]
|
|
3854
3854
|
},
|
|
3855
3855
|
{
|
|
@@ -3858,7 +3858,7 @@
|
|
|
3858
3858
|
"metadata": {},
|
|
3859
3859
|
"outputs": [],
|
|
3860
3860
|
"source": [
|
|
3861
|
-
"handler = goes.GOES(region=\"conus\",
|
|
3861
|
+
"handler = goes.GOES(region=\"conus\", bands=(\"C11\", \"C14\", \"C15\"))\n",
|
|
3862
3862
|
"da = handler.get(\"2023-02-09T18:00:00\")\n",
|
|
3863
3863
|
"\n",
|
|
3864
3864
|
"rgb, src_crs, src_extent = goes.extract_visualization(da, color_scheme=\"ash\")"
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.
|
|
32
|
-
__version_tuple__ = version_tuple = (0,
|
|
31
|
+
__version__ = version = '0.58.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 58, 0)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g142ff7355'
|
|
@@ -550,7 +550,7 @@ class AircraftPerformance(Model):
|
|
|
550
550
|
if self.met is None:
|
|
551
551
|
cond = np.isnan(u) & np.isnan(v)
|
|
552
552
|
else:
|
|
553
|
-
met_level_max = self.met.data["level"][-1].item()
|
|
553
|
+
met_level_max = self.met.data["level"][-1].item()
|
|
554
554
|
cond = self.source.level > met_level_max
|
|
555
555
|
|
|
556
556
|
# We DON'T overwrite the original u and v arrays already attached to the source
|
|
@@ -189,7 +189,7 @@ class DiskCacheStore(CacheStore):
|
|
|
189
189
|
self,
|
|
190
190
|
cache_dir: str | pathlib.Path | None = None,
|
|
191
191
|
allow_clear: bool = False,
|
|
192
|
-
):
|
|
192
|
+
) -> None:
|
|
193
193
|
if cache_dir is None:
|
|
194
194
|
# Avoid unnecessary import of platformdirs (called in _get_user_cache_dir)
|
|
195
195
|
cache_dir = os.getenv("PYCONTRAILS_CACHE_DIR") or _get_user_cache_dir()
|
|
@@ -461,7 +461,7 @@ class GCPCacheStore(CacheStore):
|
|
|
461
461
|
timeout: int = 300,
|
|
462
462
|
show_progress: bool = False,
|
|
463
463
|
chunk_size: int = 64 * 262144,
|
|
464
|
-
):
|
|
464
|
+
) -> None:
|
|
465
465
|
try:
|
|
466
466
|
from google.cloud import storage
|
|
467
467
|
except ModuleNotFoundError as e:
|
|
@@ -5,12 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import sys
|
|
6
6
|
import warnings
|
|
7
7
|
from collections.abc import Iterable
|
|
8
|
-
from typing import Any, NoReturn
|
|
9
|
-
|
|
10
|
-
if sys.version_info >= (3, 11):
|
|
11
|
-
from typing import Self
|
|
12
|
-
else:
|
|
13
|
-
from typing_extensions import Self
|
|
8
|
+
from typing import Any, NoReturn, Self
|
|
14
9
|
|
|
15
10
|
if sys.version_info >= (3, 12):
|
|
16
11
|
from typing import override
|
|
@@ -122,7 +117,7 @@ class Fleet(Flight):
|
|
|
122
117
|
# Set default fl_attrs if not provided
|
|
123
118
|
fl_attrs = fl_attrs or {}
|
|
124
119
|
for flight_id in groups.index:
|
|
125
|
-
fl_attrs.setdefault(flight_id, {})
|
|
120
|
+
fl_attrs.setdefault(flight_id, {})
|
|
126
121
|
|
|
127
122
|
extra = fl_attrs.keys() - groups.index
|
|
128
123
|
if extra:
|
|
@@ -6,18 +6,13 @@ import enum
|
|
|
6
6
|
import logging
|
|
7
7
|
import sys
|
|
8
8
|
import warnings
|
|
9
|
-
from typing import TYPE_CHECKING, Any, NoReturn
|
|
9
|
+
from typing import TYPE_CHECKING, Any, NoReturn, Self
|
|
10
10
|
|
|
11
11
|
if sys.version_info >= (3, 12):
|
|
12
12
|
from typing import override
|
|
13
13
|
else:
|
|
14
14
|
from typing_extensions import override
|
|
15
15
|
|
|
16
|
-
if sys.version_info >= (3, 11):
|
|
17
|
-
from typing import Self
|
|
18
|
-
else:
|
|
19
|
-
from typing_extensions import Self
|
|
20
|
-
|
|
21
16
|
|
|
22
17
|
import numpy as np
|
|
23
18
|
import numpy.typing as npt
|
|
@@ -2138,7 +2133,7 @@ def segment_rocd(
|
|
|
2138
2133
|
T_correction[:-1] = (air_temperature[:-1] + air_temperature[1:]) / (T_isa[:-1] + T_isa[1:])
|
|
2139
2134
|
T_correction[-1] = np.nan
|
|
2140
2135
|
|
|
2141
|
-
return T_correction * out
|
|
2136
|
+
return T_correction * out
|
|
2142
2137
|
|
|
2143
2138
|
|
|
2144
2139
|
def _resample_to_freq_or_time(
|
|
@@ -26,57 +26,74 @@ class PycontrailsRegularGridInterpolator(scipy.interpolate.RegularGridInterpolat
|
|
|
26
26
|
|
|
27
27
|
This class is a thin wrapper around the
|
|
28
28
|
:class:`scipy.interpolate.RegularGridInterpolator` in order to make typical
|
|
29
|
-
``pycontrails`` use-cases more
|
|
29
|
+
``pycontrails`` linear interpolation use-cases more performant:
|
|
30
30
|
|
|
31
|
-
#. Avoid ``RegularGridInterpolator`` constructor validation
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
#. Avoid ``RegularGridInterpolator`` constructor validation when `method="linear"`.
|
|
32
|
+
In :func:`interp`, parameters are carefully crafted to fit into the intended form,
|
|
33
|
+
thereby making validation unnecessary.
|
|
34
34
|
#. Override the :meth:`_evaluate_linear` method with a faster implementation. See
|
|
35
|
-
|
|
35
|
+
the :meth:`_evaluate_linear` docstring for more information.
|
|
36
36
|
|
|
37
|
-
This class should not be used directly. Instead, use the
|
|
37
|
+
**This class should not be used directly. Instead, use the ``interp`` function.**
|
|
38
38
|
|
|
39
39
|
.. versionchanged:: 0.40.0
|
|
40
40
|
|
|
41
41
|
The :meth:`_evaluate_linear` method now uses a Cython implementation. The dtype
|
|
42
42
|
of the output is now consistent with the dtype of the underlying :attr:`values`
|
|
43
43
|
|
|
44
|
+
.. versionchanged:: 0.58.0
|
|
45
|
+
|
|
46
|
+
Any ``method`` other than ``"linear"`` now uses the
|
|
47
|
+
:class:`scipy.interpolate.RegularGridInterpolator` implementation. This
|
|
48
|
+
allows for greater flexibility in the ``method`` parameter.
|
|
49
|
+
|
|
44
50
|
Parameters
|
|
45
51
|
----------
|
|
46
52
|
points : tuple[npt.NDArray[np.floating], ...]
|
|
47
53
|
Coordinates of the grid points.
|
|
48
54
|
values : npt.NDArray[np.floating]
|
|
49
55
|
Grid values. The shape of this array must be compatible with the
|
|
50
|
-
coordinates.
|
|
51
|
-
or ``np.float64``.
|
|
56
|
+
coordinates.
|
|
52
57
|
method : str
|
|
53
58
|
Passed into :class:`scipy.interpolate.RegularGridInterpolator`
|
|
54
59
|
bounds_error : bool
|
|
55
60
|
Passed into :class:`scipy.interpolate.RegularGridInterpolator`
|
|
56
61
|
fill_value : float | np.float64 | None
|
|
57
62
|
Passed into :class:`scipy.interpolate.RegularGridInterpolator`
|
|
63
|
+
|
|
64
|
+
See Also
|
|
65
|
+
--------
|
|
66
|
+
scipy.interpolate.RegularGridInterpolator
|
|
67
|
+
interp
|
|
58
68
|
"""
|
|
59
69
|
|
|
60
70
|
def __init__(
|
|
61
71
|
self,
|
|
62
72
|
points: tuple[npt.NDArray[np.floating], ...],
|
|
63
73
|
values: npt.NDArray[np.floating],
|
|
74
|
+
*,
|
|
64
75
|
method: str,
|
|
65
76
|
bounds_error: bool,
|
|
66
77
|
fill_value: float | np.float64 | None,
|
|
67
|
-
):
|
|
68
|
-
if values.dtype not in (np.float32, np.float64):
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
78
|
+
) -> None:
|
|
79
|
+
if method != "linear" or values.dtype not in (np.float32, np.float64):
|
|
80
|
+
# Slow path: use parent class
|
|
81
|
+
super().__init__(
|
|
82
|
+
points,
|
|
83
|
+
values,
|
|
84
|
+
method=method,
|
|
85
|
+
bounds_error=bounds_error,
|
|
86
|
+
fill_value=fill_value,
|
|
87
|
+
)
|
|
88
|
+
return
|
|
89
|
+
|
|
90
|
+
# Fast path: no validation
|
|
72
91
|
self.grid = points
|
|
73
92
|
self.values = values
|
|
74
|
-
|
|
75
|
-
# see https://github.com/scipy/scipy/releases/tag/v1.13.0
|
|
76
|
-
self.method = _pick_method(scipy.__version__, method)
|
|
93
|
+
self.method = method
|
|
77
94
|
self.bounds_error = bounds_error
|
|
78
95
|
self.fill_value = fill_value
|
|
79
|
-
self._spline = None
|
|
96
|
+
self._spline = None # XXX: setting private attribute on RGI
|
|
80
97
|
|
|
81
98
|
def _prepare_xi_simple(self, xi: npt.NDArray[np.floating]) -> npt.NDArray[np.bool_]:
|
|
82
99
|
"""Run looser version of :meth:`_prepare_xi`.
|
|
@@ -103,7 +120,7 @@ class PycontrailsRegularGridInterpolator(scipy.interpolate.RegularGridInterpolat
|
|
|
103
120
|
|
|
104
121
|
return np.zeros(xi.shape[0], dtype=bool)
|
|
105
122
|
|
|
106
|
-
return self._find_out_of_bounds(xi.T)
|
|
123
|
+
return self._find_out_of_bounds(xi.T) # XXX: calling private method on RGI
|
|
107
124
|
|
|
108
125
|
def __call__(
|
|
109
126
|
self, xi: npt.NDArray[np.floating], method: str | None = None
|
|
@@ -130,7 +147,7 @@ class PycontrailsRegularGridInterpolator(scipy.interpolate.RegularGridInterpolat
|
|
|
130
147
|
return super().__call__(xi, method)
|
|
131
148
|
|
|
132
149
|
out_of_bounds = self._prepare_xi_simple(xi)
|
|
133
|
-
xi_indices, norm_distances =
|
|
150
|
+
xi_indices, norm_distances = self._find_indices(xi.T) # XXX: calling private method on RGI
|
|
134
151
|
|
|
135
152
|
out = self._evaluate_linear(xi_indices, norm_distances)
|
|
136
153
|
return self._set_out_of_bounds(out, out_of_bounds)
|
|
@@ -223,45 +240,6 @@ class PycontrailsRegularGridInterpolator(scipy.interpolate.RegularGridInterpolat
|
|
|
223
240
|
raise ValueError(msg)
|
|
224
241
|
|
|
225
242
|
|
|
226
|
-
def _pick_method(scipy_version: str, method: str) -> str:
|
|
227
|
-
"""Select an interpolation method.
|
|
228
|
-
|
|
229
|
-
For scipy versions 1.13.0 and later, fall back on legacy implementations
|
|
230
|
-
of tensor-product spline methods. The default implementations in 1.13.0
|
|
231
|
-
and later are incompatible with this class.
|
|
232
|
-
|
|
233
|
-
Parameters
|
|
234
|
-
----------
|
|
235
|
-
scipy_version : str
|
|
236
|
-
scipy version (major.minor.patch)
|
|
237
|
-
|
|
238
|
-
method : str
|
|
239
|
-
Interpolation method. Passed into :class:`scipy.interpolate.RegularGridInterpolator`
|
|
240
|
-
as-is unless ``scipy_version`` is 1.13.0 or later and ``method`` is ``"slinear"``,
|
|
241
|
-
``"cubic"``, or ``"quintic"``. In this case, ``"_legacy"`` is appended to ``method``.
|
|
242
|
-
|
|
243
|
-
Returns
|
|
244
|
-
-------
|
|
245
|
-
str
|
|
246
|
-
Interpolation method adjusted for compatibility with this class.
|
|
247
|
-
"""
|
|
248
|
-
if method == "linear":
|
|
249
|
-
return method
|
|
250
|
-
|
|
251
|
-
try:
|
|
252
|
-
version = scipy_version.split(".")
|
|
253
|
-
major = int(version[0])
|
|
254
|
-
minor = int(version[1])
|
|
255
|
-
except (IndexError, ValueError) as exc:
|
|
256
|
-
msg = f"Failed to parse major and minor version from {scipy_version}"
|
|
257
|
-
raise ValueError(msg) from exc
|
|
258
|
-
|
|
259
|
-
reimplemented_methods = ["slinear", "cubic", "quintic"]
|
|
260
|
-
if major > 1 or ((major == 1 and minor >= 13) and method in reimplemented_methods):
|
|
261
|
-
return method + "_legacy"
|
|
262
|
-
return method
|
|
263
|
-
|
|
264
|
-
|
|
265
243
|
def _floatize_time(
|
|
266
244
|
time: npt.NDArray[np.datetime64], offset: np.datetime64
|
|
267
245
|
) -> npt.NDArray[np.floating]:
|
|
@@ -431,7 +409,7 @@ def interp(
|
|
|
431
409
|
Include ``indices`` and ``return_indices`` experimental parameters.
|
|
432
410
|
Currently, nan values in ``longitude``, ``latitude``, ``level``, or ``time``
|
|
433
411
|
are always propagated through to the output, regardless of ``bounds_error``.
|
|
434
|
-
In other words, a ValueError for an out of bounds coordinate is only raised
|
|
412
|
+
In other words, a ``ValueError`` for an out of bounds coordinate is only raised
|
|
435
413
|
if a non-nan value is out of bounds.
|
|
436
414
|
|
|
437
415
|
.. versionchanged:: 0.40.0
|
|
@@ -480,9 +458,9 @@ def interp(
|
|
|
480
458
|
|
|
481
459
|
See Also
|
|
482
460
|
--------
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
461
|
+
pycontrails.MetDataArray.interpolate
|
|
462
|
+
scipy.interpolate.interpn
|
|
463
|
+
scipy.interpolate.RegularGridInterpolator
|
|
486
464
|
"""
|
|
487
465
|
if localize:
|
|
488
466
|
coords = {"longitude": longitude, "latitude": latitude, "level": level, "time": time}
|
|
@@ -579,7 +557,7 @@ def _linear_interp_with_indices(
|
|
|
579
557
|
if indices is None:
|
|
580
558
|
assert xi is not None, "xi must be provided if indices is None"
|
|
581
559
|
out_of_bounds = interp._prepare_xi_simple(xi)
|
|
582
|
-
xi_indices, norm_distances =
|
|
560
|
+
xi_indices, norm_distances = interp._find_indices(xi.T)
|
|
583
561
|
indices = RGIArtifacts(xi_indices, norm_distances, out_of_bounds)
|
|
584
562
|
|
|
585
563
|
out = interp._evaluate_linear(indices.xi_indices, indices.norm_distances)
|
|
@@ -606,7 +584,7 @@ class EmissionsProfileInterpolator:
|
|
|
606
584
|
|
|
607
585
|
This class simply wraps :func:`numpy.interp` with fixed values for the
|
|
608
586
|
``xp`` and ``fp`` arguments. Unlike :class:`xarray.DataArray` interpolation,
|
|
609
|
-
the
|
|
587
|
+
the :func:`numpy.interp` automatically clips values outside the range of the
|
|
610
588
|
``xp`` array.
|
|
611
589
|
|
|
612
590
|
Parameters
|
|
@@ -26,15 +26,11 @@ from typing import (
|
|
|
26
26
|
Any,
|
|
27
27
|
Generic,
|
|
28
28
|
Literal,
|
|
29
|
+
Self,
|
|
29
30
|
TypeVar,
|
|
30
31
|
overload,
|
|
31
32
|
)
|
|
32
33
|
|
|
33
|
-
if sys.version_info >= (3, 11):
|
|
34
|
-
from typing import Self
|
|
35
|
-
else:
|
|
36
|
-
from typing_extensions import Self
|
|
37
|
-
|
|
38
34
|
if sys.version_info >= (3, 12):
|
|
39
35
|
from typing import override
|
|
40
36
|
else:
|
|
@@ -211,14 +207,22 @@ class MetBase(ABC, Generic[XArrayType]):
|
|
|
211
207
|
Raises
|
|
212
208
|
------
|
|
213
209
|
ValueError
|
|
214
|
-
If one of the coordinates is not sorted.
|
|
210
|
+
If one of the coordinates is not sorted or contains duplicate values.
|
|
215
211
|
"""
|
|
216
212
|
indexes = self.indexes
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
213
|
+
for coord in self.dim_order:
|
|
214
|
+
arr = indexes[coord]
|
|
215
|
+
d = np.diff(arr)
|
|
216
|
+
zero = np.zeros((), dtype=d.dtype) # ensure same dtype
|
|
217
|
+
|
|
218
|
+
if np.any(d <= zero):
|
|
219
|
+
if np.any(d == zero):
|
|
220
|
+
msg = f"Coordinate '{coord}' contains duplicate values."
|
|
221
|
+
else:
|
|
222
|
+
msg = f"Coordinate '{coord}' not sorted."
|
|
223
|
+
|
|
224
|
+
msg += " Instantiate with 'copy=True'."
|
|
225
|
+
raise ValueError(msg)
|
|
222
226
|
|
|
223
227
|
def _validate_transpose(self) -> None:
|
|
224
228
|
"""Check that data is transposed according to :attr:`dim_order`."""
|
|
@@ -271,6 +275,10 @@ class MetBase(ABC, Generic[XArrayType]):
|
|
|
271
275
|
Auxiliary coordinates (altitude and air_pressure) are now cast to the same
|
|
272
276
|
dtype as the underlying grid data.
|
|
273
277
|
|
|
278
|
+
.. versionchanged:: 0.58.0
|
|
279
|
+
|
|
280
|
+
Duplicate dimension values are dropped, keeping the first occurrence.
|
|
281
|
+
|
|
274
282
|
|
|
275
283
|
Parameters
|
|
276
284
|
----------
|
|
@@ -297,6 +305,18 @@ class MetBase(ABC, Generic[XArrayType]):
|
|
|
297
305
|
# sortby to ensure each coordinate has ascending order
|
|
298
306
|
self.data = self.data.sortby(list(self.dim_order), ascending=True)
|
|
299
307
|
|
|
308
|
+
# Drop any duplicated dimension values
|
|
309
|
+
indexes = self.indexes
|
|
310
|
+
for coord in self.dim_order:
|
|
311
|
+
arr = indexes[coord]
|
|
312
|
+
d = np.diff(arr)
|
|
313
|
+
zero = np.zeros((), dtype=d.dtype) # ensure same dtype
|
|
314
|
+
|
|
315
|
+
if np.any(d == zero):
|
|
316
|
+
# Remove duplicates
|
|
317
|
+
filt = np.r_[True, d > zero] # prepend True keeps the first occurrence
|
|
318
|
+
self.data = self.data.isel({coord: filt})
|
|
319
|
+
|
|
300
320
|
if not self.is_wrapped:
|
|
301
321
|
# Ensure longitude is contained in interval [-180, 180)
|
|
302
322
|
# If longitude has value at 180, we might not want to shift it?
|
|
@@ -1087,7 +1107,7 @@ class MetDataset(MetBase):
|
|
|
1087
1107
|
out[key] = da.values.ravel() # type: ignore[index]
|
|
1088
1108
|
|
|
1089
1109
|
if transfer_attrs:
|
|
1090
|
-
out.attrs.update(self.attrs)
|
|
1110
|
+
out.attrs.update(self.attrs)
|
|
1091
1111
|
|
|
1092
1112
|
return out
|
|
1093
1113
|
|
|
@@ -1300,7 +1320,7 @@ class MetDataset(MetBase):
|
|
|
1300
1320
|
coords: dict[str, np.ndarray] = {}
|
|
1301
1321
|
for key, val in input_data.items():
|
|
1302
1322
|
dtype = "datetime64[ns]" if key == "time" else COORD_DTYPE
|
|
1303
|
-
arr: np.ndarray = np.asarray(val, dtype=dtype)
|
|
1323
|
+
arr: np.ndarray = np.asarray(val, dtype=dtype)
|
|
1304
1324
|
|
|
1305
1325
|
if arr.ndim == 0:
|
|
1306
1326
|
arr = arr.reshape(1)
|
|
@@ -1889,7 +1909,7 @@ class MetDataArray(MetBase):
|
|
|
1889
1909
|
if not self.binary:
|
|
1890
1910
|
raise NotImplementedError("proportion method is only implemented for binary fields")
|
|
1891
1911
|
|
|
1892
|
-
return self.data.sum().values.item() / self.data.count().values.item()
|
|
1912
|
+
return self.data.sum().values.item() / self.data.count().values.item()
|
|
1893
1913
|
|
|
1894
1914
|
def find_edges(self) -> Self:
|
|
1895
1915
|
"""Find edges of regions.
|
|
@@ -2598,9 +2618,9 @@ def _extract_2d_arr_and_altitude(
|
|
|
2598
2618
|
except KeyError:
|
|
2599
2619
|
altitude = None
|
|
2600
2620
|
else:
|
|
2601
|
-
altitude = round(altitude)
|
|
2621
|
+
altitude = round(altitude)
|
|
2602
2622
|
|
|
2603
|
-
return arr, altitude
|
|
2623
|
+
return arr, altitude
|
|
2604
2624
|
|
|
2605
2625
|
|
|
2606
2626
|
def downselect(data: XArrayType, bbox: tuple[float, ...]) -> XArrayType:
|
|
@@ -238,7 +238,7 @@ def _contours_to_polygons(
|
|
|
238
238
|
latitude=latitude,
|
|
239
239
|
precision=precision,
|
|
240
240
|
buffer=buffer,
|
|
241
|
-
i=child_i,
|
|
241
|
+
i=child_i,
|
|
242
242
|
)
|
|
243
243
|
|
|
244
244
|
candidate = shapely.Polygon(polygon.exterior, [h.exterior for h in holes])
|
|
@@ -354,11 +354,11 @@ def find_multipolygon(
|
|
|
354
354
|
return shapely.MultiPolygon()
|
|
355
355
|
|
|
356
356
|
assert len(hierarchy) == 1
|
|
357
|
-
hierarchy = hierarchy[0]
|
|
357
|
+
hierarchy = hierarchy[0]
|
|
358
358
|
|
|
359
359
|
polygons = _contours_to_polygons(
|
|
360
360
|
contours, # type: ignore[arg-type]
|
|
361
|
-
hierarchy,
|
|
361
|
+
hierarchy,
|
|
362
362
|
min_area,
|
|
363
363
|
convex_hull,
|
|
364
364
|
epsilon,
|