pycontrails 0.48.0__tar.gz → 0.48.1__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.

Files changed (235) hide show
  1. {pycontrails-0.48.0 → pycontrails-0.48.1}/.github/workflows/docs.yaml +1 -1
  2. {pycontrails-0.48.0 → pycontrails-0.48.1}/.github/workflows/doctest.yaml +1 -1
  3. {pycontrails-0.48.0 → pycontrails-0.48.1}/.github/workflows/release.yaml +1 -1
  4. {pycontrails-0.48.0 → pycontrails-0.48.1}/.github/workflows/scorecard.yaml +1 -1
  5. {pycontrails-0.48.0 → pycontrails-0.48.1}/.github/workflows/test.yaml +1 -3
  6. {pycontrails-0.48.0 → pycontrails-0.48.1}/CHANGELOG.md +19 -0
  7. {pycontrails-0.48.0/pycontrails.egg-info → pycontrails-0.48.1}/PKG-INFO +2 -1
  8. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/_version.py +2 -2
  9. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/core/met.py +34 -22
  10. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/core/met_var.py +2 -2
  11. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/core/models.py +5 -0
  12. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/core/rgi_cython.c +283 -203
  13. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/core/vector.py +243 -24
  14. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/cocip/cocip.py +21 -11
  15. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/cocip/wake_vortex.py +9 -7
  16. {pycontrails-0.48.0 → pycontrails-0.48.1/pycontrails.egg-info}/PKG-INFO +2 -1
  17. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails.egg-info/requires.txt +3 -0
  18. {pycontrails-0.48.0 → pycontrails-0.48.1}/pyproject.toml +6 -1
  19. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_flight.py +118 -0
  20. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_met.py +55 -2
  21. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_vector.py +45 -8
  22. {pycontrails-0.48.0 → pycontrails-0.48.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  23. {pycontrails-0.48.0 → pycontrails-0.48.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  24. {pycontrails-0.48.0 → pycontrails-0.48.1}/.github/dependabot.yaml +0 -0
  25. {pycontrails-0.48.0 → pycontrails-0.48.1}/.github/pull_request_template.md +0 -0
  26. {pycontrails-0.48.0 → pycontrails-0.48.1}/.github/workflows/benchmark.yaml +0 -0
  27. {pycontrails-0.48.0 → pycontrails-0.48.1}/.gitignore +0 -0
  28. {pycontrails-0.48.0 → pycontrails-0.48.1}/.pre-commit-config.yaml +0 -0
  29. {pycontrails-0.48.0 → pycontrails-0.48.1}/.zenodo.json +0 -0
  30. {pycontrails-0.48.0 → pycontrails-0.48.1}/CONTRIBUTING.md +0 -0
  31. {pycontrails-0.48.0 → pycontrails-0.48.1}/LICENSE +0 -0
  32. {pycontrails-0.48.0 → pycontrails-0.48.1}/Makefile +0 -0
  33. {pycontrails-0.48.0 → pycontrails-0.48.1}/NOTICE +0 -0
  34. {pycontrails-0.48.0 → pycontrails-0.48.1}/README.md +0 -0
  35. {pycontrails-0.48.0 → pycontrails-0.48.1}/RELEASE.md +0 -0
  36. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/_static/css/style.css +0 -0
  37. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/_static/img/favicon.png +0 -0
  38. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/_static/img/logo-dark.png +0 -0
  39. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/_static/img/logo.png +0 -0
  40. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/_static/pycontrails.bib +0 -0
  41. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/api.rst +0 -0
  42. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/changelog.rst +0 -0
  43. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/conf.py +0 -0
  44. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/contributing.rst +0 -0
  45. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/develop.rst +0 -0
  46. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/examples/ACCF.ipynb +0 -0
  47. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/examples/AircraftPerformance.ipynb +0 -0
  48. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/examples/Cache.ipynb +0 -0
  49. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/examples/CoCiP.ipynb +0 -0
  50. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/examples/ECMWF.ipynb +0 -0
  51. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/examples/Flight.ipynb +0 -0
  52. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/examples/GFS.ipynb +0 -0
  53. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/examples/GOES.ipynb +0 -0
  54. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/examples/ISSR.ipynb +0 -0
  55. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/examples/Meteorology.ipynb +0 -0
  56. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/examples/SAC.ipynb +0 -0
  57. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/examples/advection.ipynb +0 -0
  58. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/examples/airports.ipynb +0 -0
  59. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/examples/flight.csv +0 -0
  60. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/examples/flight2.csv +0 -0
  61. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/examples/flightplan.ipynb +0 -0
  62. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/examples.rst +0 -0
  63. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/index.rst +0 -0
  64. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/install.rst +0 -0
  65. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/literature.rst +0 -0
  66. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/tutorials/CoCiP.ipynb +0 -0
  67. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/tutorials/flight.csv +0 -0
  68. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/tutorials/interpolating-specific-humidity.ipynb +0 -0
  69. {pycontrails-0.48.0 → pycontrails-0.48.1}/docs/tutorials.rst +0 -0
  70. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/__init__.py +0 -0
  71. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/core/__init__.py +0 -0
  72. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/core/aircraft_performance.py +0 -0
  73. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/core/airports.py +0 -0
  74. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/core/cache.py +0 -0
  75. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/core/coordinates.py +0 -0
  76. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/core/datalib.py +0 -0
  77. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/core/fleet.py +0 -0
  78. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/core/flight.py +0 -0
  79. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/core/flightplan.py +0 -0
  80. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/core/fuel.py +0 -0
  81. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/core/interpolation.py +0 -0
  82. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/core/polygon.py +0 -0
  83. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/core/rgi_cython.pyx +0 -0
  84. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/datalib/__init__.py +0 -0
  85. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/datalib/ecmwf/__init__.py +0 -0
  86. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/datalib/ecmwf/common.py +0 -0
  87. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/datalib/ecmwf/era5.py +0 -0
  88. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/datalib/ecmwf/hres.py +0 -0
  89. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/datalib/ecmwf/ifs.py +0 -0
  90. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/datalib/ecmwf/variables.py +0 -0
  91. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/datalib/gfs/__init__.py +0 -0
  92. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/datalib/gfs/gfs.py +0 -0
  93. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/datalib/gfs/variables.py +0 -0
  94. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/datalib/goes.py +0 -0
  95. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/datalib/spire/__init__.py +0 -0
  96. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/datalib/spire/spire.py +0 -0
  97. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/ext/bada.py +0 -0
  98. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/ext/cirium.py +0 -0
  99. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/ext/empirical_grid.py +0 -0
  100. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/ext/synthetic_flight.py +0 -0
  101. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/__init__.py +0 -0
  102. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/accf.py +0 -0
  103. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/cocip/__init__.py +0 -0
  104. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/cocip/cocip_params.py +0 -0
  105. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/cocip/cocip_uncertainty.py +0 -0
  106. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/cocip/contrail_properties.py +0 -0
  107. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/cocip/output_formats.py +0 -0
  108. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/cocip/radiative_forcing.py +0 -0
  109. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/cocip/radiative_heating.py +0 -0
  110. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/cocip/wind_shear.py +0 -0
  111. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/cocipgrid/__init__.py +0 -0
  112. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/cocipgrid/cocip_grid.py +0 -0
  113. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/cocipgrid/cocip_grid_params.py +0 -0
  114. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/cocipgrid/cocip_time_handling.py +0 -0
  115. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/dry_advection.py +0 -0
  116. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/emissions/__init__.py +0 -0
  117. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/emissions/black_carbon.py +0 -0
  118. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/emissions/emissions.py +0 -0
  119. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/emissions/ffm2.py +0 -0
  120. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/emissions/static/default-engine-uids.csv +0 -0
  121. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/emissions/static/edb-gaseous-v28c-engines.csv +0 -0
  122. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/emissions/static/edb-nvpm-v28c-engines.csv +0 -0
  123. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/humidity_scaling/__init__.py +0 -0
  124. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/humidity_scaling/humidity_scaling.py +0 -0
  125. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/humidity_scaling/quantiles/era5-quantiles.pq +0 -0
  126. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/issr.py +0 -0
  127. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/pcc.py +0 -0
  128. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/pcr.py +0 -0
  129. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/ps_model/__init__.py +0 -0
  130. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/ps_model/ps_aircraft_params.py +0 -0
  131. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/ps_model/ps_grid.py +0 -0
  132. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/ps_model/ps_model.py +0 -0
  133. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/ps_model/static/ps-aircraft-params-20230517.csv +0 -0
  134. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/sac.py +0 -0
  135. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/models/tau_cirrus.py +0 -0
  136. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/physics/__init__.py +0 -0
  137. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/physics/constants.py +0 -0
  138. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/physics/geo.py +0 -0
  139. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/physics/jet.py +0 -0
  140. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/physics/thermo.py +0 -0
  141. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/physics/units.py +0 -0
  142. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/py.typed +0 -0
  143. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/utils/__init__.py +0 -0
  144. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/utils/dependencies.py +0 -0
  145. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/utils/iteration.py +0 -0
  146. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/utils/json.py +0 -0
  147. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/utils/temp.py +0 -0
  148. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails/utils/types.py +0 -0
  149. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails.egg-info/SOURCES.txt +0 -0
  150. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails.egg-info/dependency_links.txt +0 -0
  151. {pycontrails-0.48.0 → pycontrails-0.48.1}/pycontrails.egg-info/top_level.txt +0 -0
  152. {pycontrails-0.48.0 → pycontrails-0.48.1}/setup.cfg +0 -0
  153. {pycontrails-0.48.0 → pycontrails-0.48.1}/setup.py +0 -0
  154. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/__init__.py +0 -0
  155. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/_deprecated.py +0 -0
  156. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/benchmark/cocip/Makefile +0 -0
  157. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/benchmark/cocip/README.md +0 -0
  158. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/benchmark/cocip/benchmark.py +0 -0
  159. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/benchmark/cocip/compare.py +0 -0
  160. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/benchmark/cocip/data.md +0 -0
  161. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/benchmark/cocip/output.py +0 -0
  162. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/benchmark/cocip/review.ipynb +0 -0
  163. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/benchmark/cocip-fortran/README.md +0 -0
  164. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/benchmark/north-atlantic-study/.gcloudignore +0 -0
  165. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/benchmark/north-atlantic-study/README.md +0 -0
  166. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/benchmark/north-atlantic-study/support.py +0 -0
  167. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/benchmark/north-atlantic-study/validate.py +0 -0
  168. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/fixtures/cocip-met.py +0 -0
  169. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/fixtures/cocip-met2.py +0 -0
  170. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/fixtures/ecmwf-met.py +0 -0
  171. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/fixtures/gfs-met.py +0 -0
  172. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/__init__.py +0 -0
  173. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/conftest.py +0 -0
  174. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/NOAA_Solar_Calculations_day.csv +0 -0
  175. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/cocip-contrail-output.json +0 -0
  176. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/cocip-contrail-output2.json +0 -0
  177. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/cocip-flight-output.json +0 -0
  178. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/cocip-flight-output2.json +0 -0
  179. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/cocip-output-contrail-edges.json +0 -0
  180. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/cocip-output-flts-20190101-eu.pq +0 -0
  181. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/flight-cocip2.csv +0 -0
  182. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/flight-meridian.csv +0 -0
  183. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/flight-metadata.json +0 -0
  184. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/flight-spire-data-cleaning.pq +0 -0
  185. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/flight.csv +0 -0
  186. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/flt-wypts-20190101-eu.pq +0 -0
  187. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/met-20190101-eu.nc +0 -0
  188. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/met-accf-pl.nc +0 -0
  189. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/met-accf-sl.nc +0 -0
  190. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/met-ecmwf-pl.nc +0 -0
  191. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/met-ecmwf-sl.nc +0 -0
  192. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/met-era5-cocip1.nc +0 -0
  193. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/met-era5-cocip2.nc +0 -0
  194. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/met-gfs.nc +0 -0
  195. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/polygon-bug.nc +0 -0
  196. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/rad-20190101-eu.nc +0 -0
  197. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/rad-era5-cocip1.nc +0 -0
  198. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/rad-era5-cocip2.nc +0 -0
  199. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/static/rad-gfs.nc +0 -0
  200. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_accf.py +0 -0
  201. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_airports.py +0 -0
  202. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_cache.py +0 -0
  203. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_cocip.py +0 -0
  204. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_cocip_grid.py +0 -0
  205. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_cocip_grid_parity.py +0 -0
  206. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_cocip_radiative_forcing.py +0 -0
  207. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_cocip_uncertainty.py +0 -0
  208. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_coordinates.py +0 -0
  209. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_datalib.py +0 -0
  210. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_dry_advection.py +0 -0
  211. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_dtypes.py +0 -0
  212. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_ecmwf.py +0 -0
  213. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_emissions.py +0 -0
  214. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_fleet.py +0 -0
  215. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_flightplan.py +0 -0
  216. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_fuel.py +0 -0
  217. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_geo.py +0 -0
  218. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_gfs.py +0 -0
  219. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_goes.py +0 -0
  220. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_grid_to_netcdf.py +0 -0
  221. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_humidity_scaling.py +0 -0
  222. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_init.py +0 -0
  223. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_interpolation.py +0 -0
  224. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_met_cache.py +0 -0
  225. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_models.py +0 -0
  226. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_pcc.py +0 -0
  227. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_polygons.py +0 -0
  228. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_ps_model.py +0 -0
  229. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_sac_issr.py +0 -0
  230. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_spire.py +0 -0
  231. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_tau_cirrus.py +0 -0
  232. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_thermo_sac.py +0 -0
  233. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_units.py +0 -0
  234. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_utils.py +0 -0
  235. {pycontrails-0.48.0 → pycontrails-0.48.1}/tests/unit/test_zarr.py +0 -0
@@ -41,7 +41,7 @@ jobs:
41
41
 
42
42
  - uses: actions/setup-python@v4
43
43
  with:
44
- python-version: '3.11'
44
+ python-version: '3.12'
45
45
  cache: 'pip'
46
46
  cache-dependency-path: pyproject.toml
47
47
 
@@ -41,7 +41,7 @@ jobs:
41
41
 
42
42
  - uses: actions/setup-python@v4
43
43
  with:
44
- python-version: '3.11'
44
+ python-version: '3.12'
45
45
  cache: 'pip'
46
46
  cache-dependency-path: pyproject.toml
47
47
 
@@ -46,7 +46,7 @@ jobs:
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 cp312-*'
49
+ CIBW_TEST_SKIP: '*-macosx_arm64'
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"
@@ -30,7 +30,7 @@ jobs:
30
30
  - uses: actions/checkout@v4
31
31
 
32
32
  - name: Run OpenSSF Security Scorecard
33
- uses: ossf/scorecard-action@v2.3.0
33
+ uses: ossf/scorecard-action@v2.3.1
34
34
  with:
35
35
  results_file: results.sarif
36
36
  results_format: sarif
@@ -1,8 +1,6 @@
1
1
  # Run unit tests from the ground up
2
2
  # installing "pycontrails" into the Github OS environments
3
3
 
4
- # TODO: Include windows platforms testing here
5
-
6
4
  name: Unit tests
7
5
 
8
6
  on:
@@ -40,7 +38,7 @@ jobs:
40
38
  fail-fast: false
41
39
  matrix:
42
40
  os: [ubuntu-latest, windows-latest]
43
- pyversion: ['3.9', '3.10', '3.11']
41
+ pyversion: ['3.9', '3.10', '3.11', '3.12']
44
42
  runs-on: ${{ matrix.os }}
45
43
 
46
44
  steps:
@@ -1,6 +1,25 @@
1
1
 
2
2
  # Changelog
3
3
 
4
+ ## v0.48.1
5
+
6
+ ### Features
7
+
8
+ - Generalize `met.shift_longitude()` to translate longitude coordinates onto any domain bounds.
9
+ - Add `VectorDataset.to_dict()` methods to output Vector data as dictionary. This method enables `Flight.to_dict()` objects to be serialized for input to the [Contrails API](https://api.contrails.org).
10
+ - Add `VectorDataset.from_dict()` class method to create `VectorDataset` class from dictionary.
11
+ - Support more time formats, including timezone aware times, in `VectorDataset` creation. All timezone aware `"time"`` coordinates are converted to UTC and stripped of timezone identifier.
12
+
13
+ ### Fixes
14
+
15
+ - Fix issue in the `wake_vortex.max_downward_displacement` function in which float32 dtypes were promoted to float64 dtypes in certain cases.
16
+ - Ignore empty vectors in `VectorDataset.sum`.
17
+
18
+ ### Internals
19
+
20
+ - Set `frozen=True` on the `MetVariable` dataclass.
21
+ - Test against python 3.12 in the GitHub Actions CI. Use python 3.12 the docs and doctest workflows.
22
+
4
23
  ## v0.48.0
5
24
 
6
25
  This release includes a number of breaking changes and new features. If upgrading from a previous version of `pycontrails`, please read the changelog carefully. Open an [issue](https://github.com/contrailcirrus/pycontrails/issues) if you experience problems.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pycontrails
3
- Version: 0.48.0
3
+ Version: 0.48.1
4
4
  Summary: Python library for modeling aviation climate impacts
5
5
  Author-email: Breakthrough Energy <py@contrails.org>
6
6
  License: Apache-2.0
@@ -83,6 +83,7 @@ Requires-Dist: eccodes>=1.4; extra == "gfs"
83
83
  Requires-Dist: platformdirs>=3.0; extra == "gfs"
84
84
  Requires-Dist: tqdm>=4.61; extra == "gfs"
85
85
  Provides-Extra: goes
86
+ Requires-Dist: aiohttp>=3.9.0b0; python_version >= "3.12" and extra == "goes"
86
87
  Requires-Dist: cartopy>=0.22; extra == "goes"
87
88
  Requires-Dist: gcsfs>=2022.3; extra == "goes"
88
89
  Requires-Dist: h5netcdf>=1.2; extra == "goes"
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.48.0'
16
- __version_tuple__ = version_tuple = (0, 48, 0)
15
+ __version__ = version = '0.48.1'
16
+ __version_tuple__ = version_tuple = (0, 48, 1)
@@ -96,13 +96,14 @@ class MetBase(ABC, Generic[XArrayType]):
96
96
  for dim in self.dim_order:
97
97
  if dim not in self.data.dims:
98
98
  if dim == "level":
99
- raise ValueError(
99
+ msg = (
100
100
  f"Meteorology data must contain dimension '{dim}'. "
101
101
  "For single level data, set 'level' coordinate to constant -1 "
102
102
  "using `ds = ds.expand_dims({'level': [-1]})`"
103
103
  )
104
104
  else:
105
- raise ValueError(f"Meteorology data must contain dimension '{dim}'.")
105
+ msg = f"Meteorology data must contain dimension '{dim}'."
106
+ raise ValueError(msg)
106
107
 
107
108
  def _validate_longitude(self) -> None:
108
109
  """Check longitude bounds.
@@ -196,15 +197,15 @@ class MetBase(ABC, Generic[XArrayType]):
196
197
 
197
198
  dims_tuple = tuple(self.dim_order)
198
199
 
199
- def _check_da(da: xr.DataArray, key: str | None = None) -> None:
200
+ def _check_da(da: xr.DataArray, key: Hashable | None = None) -> None:
200
201
  if da.dims != dims_tuple:
201
202
  if key is not None:
202
203
  msg = (
203
- "Data dimension not transposed on variable '{key}'. Initiate with"
204
- " `copy=True`."
204
+ f"Data dimension not transposed on variable '{key}'. Initiate with"
205
+ " 'copy=True'."
205
206
  )
206
207
  else:
207
- msg = "Data dimension not transposed. Initiate with `copy=True`."
208
+ msg = "Data dimension not transposed. Initiate with 'copy=True'."
208
209
  raise ValueError(msg)
209
210
 
210
211
  data = self.data
@@ -212,7 +213,7 @@ class MetBase(ABC, Generic[XArrayType]):
212
213
  _check_da(data)
213
214
  return
214
215
 
215
- for key, da in self.data.data_vars.items():
216
+ for key, da in self.data.items():
216
217
  _check_da(da, key)
217
218
 
218
219
  def _validate_dims(self) -> None:
@@ -654,11 +655,9 @@ class MetDataset(MetBase):
654
655
  attrs: dict[str, Any] | None = None,
655
656
  **attrs_kwargs: Any,
656
657
  ) -> None:
657
- # init cache
658
658
  self.cachestore = cachestore
659
659
 
660
- data.attrs.update(attrs or {})
661
- data.attrs.update(attrs_kwargs)
660
+ data.attrs.update(attrs or {}, **attrs_kwargs)
662
661
 
663
662
  # if input is already a Dataset, copy into data
664
663
  if not isinstance(data, xr.Dataset):
@@ -872,7 +871,7 @@ class MetDataset(MetBase):
872
871
  Raises when dataset does not contain variable in ``vars``
873
872
  """
874
873
  if isinstance(vars, (MetVariable, str)):
875
- vars = [vars]
874
+ vars = (vars,)
876
875
 
877
876
  met_keys: list[str] = []
878
877
  for variable in vars:
@@ -1372,7 +1371,7 @@ class MetDataArray(MetBase):
1372
1371
  """
1373
1372
  if not self.in_memory:
1374
1373
  self._check_memory("Extracting numpy array from")
1375
- self.data = self.data.load()
1374
+ self.data.load()
1376
1375
 
1377
1376
  return self.data.values
1378
1377
 
@@ -1618,8 +1617,20 @@ class MetDataArray(MetBase):
1618
1617
  )
1619
1618
 
1620
1619
  def _check_memory(self, msg_start: str) -> None:
1620
+ """Check the memory usage of the underlying data.
1621
+
1622
+ If the data is larger than 4 GB, a warning is issued. If the data is
1623
+ larger than 32 GB, a RuntimeError is raised.
1624
+ """
1621
1625
  n_bytes = self.data.nbytes
1626
+ mb = round(n_bytes / int(1e6), 2)
1627
+ logger.debug("Loading %s into memory consumes %s MB.", self.name, mb)
1628
+
1622
1629
  n_gb = n_bytes // int(1e9)
1630
+ if n_gb <= 4:
1631
+ return
1632
+
1633
+ # Prevent something stupid
1623
1634
  msg = (
1624
1635
  f"{msg_start} MetDataArray {self.name} requires loading "
1625
1636
  f"at least {n_gb} GB of data into memory. Downselect data if possible. "
@@ -1627,13 +1638,9 @@ class MetDataArray(MetBase):
1627
1638
  "with the method 'downselect_met'."
1628
1639
  )
1629
1640
 
1630
- if n_gb > 32: # Prevent something stupid
1641
+ if n_gb > 32:
1631
1642
  raise RuntimeError(msg)
1632
- if n_gb > 4:
1633
- warnings.warn(msg)
1634
-
1635
- mb = round(n_bytes / int(1e6), 2)
1636
- logger.debug("Loading %s into memory consumes %s MB.", self.name, mb)
1643
+ warnings.warn(msg)
1637
1644
 
1638
1645
  def save(self, **kwargs: Any) -> list[str]:
1639
1646
  """Save intermediate to :attr:`cachestore` as netcdf.
@@ -2228,24 +2235,29 @@ def _is_zarr(ds: xr.Dataset | xr.DataArray) -> bool:
2228
2235
  return dask0.array.array.array.__class__.__name__ == "ZarrArrayWrapper"
2229
2236
 
2230
2237
 
2231
- def shift_longitude(data: XArrayType) -> XArrayType:
2232
- """Shift longitude values from [0, 360) to [-180, 180) domain.
2238
+ def shift_longitude(data: XArrayType, bound: float = -180.0) -> XArrayType:
2239
+ """Shift longitude values from any input domain to [bound, 360 + bound) domain.
2233
2240
 
2234
2241
  Sorts data by ascending longitude values.
2235
2242
 
2243
+
2236
2244
  Parameters
2237
2245
  ----------
2238
2246
  data : XArrayType
2239
2247
  :class:`xr.Dataset` or :class:`xr.DataArray` with longitude dimension
2248
+ bound : float, optional
2249
+ Lower bound of the domain.
2250
+ Output domain will be [bound, 360 + bound).
2251
+ Defaults to -180, which results in longitude domain [-180, 180).
2240
2252
 
2241
2253
 
2242
2254
  Returns
2243
2255
  -------
2244
2256
  XArrayType
2245
- :class:`xr.Dataset` or :class:`xr.DataArray` with longitude values on [-180, 180).
2257
+ :class:`xr.Dataset` or :class:`xr.DataArray` with longitude values on [a, 360 + a).
2246
2258
  """
2247
2259
  return data.assign_coords(
2248
- longitude=((data["longitude"].values + 180.0) % 360.0) - 180.0
2260
+ longitude=((data["longitude"].values - bound) % 360.0) + bound
2249
2261
  ).sortby("longitude", ascending=True)
2250
2262
 
2251
2263
 
@@ -2,10 +2,10 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from dataclasses import dataclass
5
+ import dataclasses
6
6
 
7
7
 
8
- @dataclass
8
+ @dataclasses.dataclass(frozen=True)
9
9
  class MetVariable:
10
10
  """Met variable defined using CF, ECMWF, and WMO conventions.
11
11
 
@@ -714,6 +714,11 @@ class Model(ABC):
714
714
  except KeyError:
715
715
  pass
716
716
 
717
+ try:
718
+ source.attrs["met_source_forecast_time"] = self.met.attrs["forecast_time"]
719
+ except KeyError:
720
+ pass
721
+
717
722
 
718
723
  def _interp_grid_to_grid(
719
724
  met_key: str,