pycontrails 0.40.0__cp310-cp310-macosx_10_9_x86_64.whl → 0.40.1__cp310-cp310-macosx_10_9_x86_64.whl

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/_version.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # file generated by setuptools_scm
2
2
  # don't change, don't track in version control
3
- __version__ = version = '0.40.0'
4
- __version_tuple__ = version_tuple = (0, 40, 0)
3
+ __version__ = version = '0.40.1'
4
+ __version_tuple__ = version_tuple = (0, 40, 1)
pycontrails/core/met.py CHANGED
@@ -94,7 +94,14 @@ class MetBase(ABC, Generic[XArrayType]):
94
94
  """
95
95
  for dim in self.dim_order:
96
96
  if dim not in self.data.dims:
97
- raise ValueError(f"Meteorology data must contain dimension '{dim}'")
97
+ if dim == "level":
98
+ raise ValueError(
99
+ f"Meteorology data must contain dimension '{dim}'. "
100
+ "For single level data, set 'level' coordinate to constant -1 "
101
+ "using `ds = ds.expand_dims({'level': [-1]})`"
102
+ )
103
+ else:
104
+ raise ValueError(f"Meteorology data must contain dimension '{dim}'.")
98
105
 
99
106
  def _validate_longitude(self) -> None:
100
107
  """Check longitude bounds.
@@ -220,11 +227,12 @@ class MetBase(ABC, Generic[XArrayType]):
220
227
  def _preprocess_dims(self, wrap_longitude: bool) -> None:
221
228
  """Confirm DataArray or Dataset include required dimension in a consistent format.
222
229
 
223
- Expects DataArray or Dataset to contain dimensions "latitude", "longitude", "time",
224
- and "level" (in hPa/mbar). Adds additional coordinate variables ``air_pressure``
225
- and ``altitude`` coordinates mapped to "level" dimension if "level" > 0.
230
+ Expects DataArray or Dataset to contain dimensions ``latitude`, ``longitude``, ``time``,
231
+ and ``level`` (in hPa/mbar).
232
+ Adds additional coordinate variables ``air_pressure`` and ``altitude`` coordinates
233
+ mapped to "level" dimension if "level" > 0.
226
234
 
227
- Set "level" to -1 to signify surface level.
235
+ Set ``level`` to -1 to signify single level.
228
236
 
229
237
  .. versionchanged:: 0.40.0
230
238
 
@@ -280,7 +288,7 @@ class MetBase(ABC, Generic[XArrayType]):
280
288
  dim_order = self.dim_order + [d for d in self.data.dims if d not in self.dim_order]
281
289
  self.data = self.data.transpose(*dim_order)
282
290
 
283
- # surface level data
291
+ # single level data
284
292
  if self.is_single_level:
285
293
  # add level attributes to reflect surface level
286
294
  self.data["level"].attrs.update(units="", long_name="Single Level")
@@ -147,12 +147,13 @@ class Model(ABC):
147
147
  #: Require meteorology is not None on __init__()
148
148
  met_required: bool = False
149
149
 
150
- #: Required meteorology variables
151
- #: Each element in the list is a MetVariable or a list[MetVariable].
152
- #: If a list[MetVariable], only one variable in the list is required by input :attr:`met`.
150
+ #: Required meteorology pressure level variables.
151
+ #: Each element in the list is a :class:`MetVariable` or a ``tuple[MetVariable]``.
152
+ #: If element is a ``tuple[MetVariable]``, the variable depends on the data source.
153
+ #: Only one variable in the tuple is required.
153
154
  met_variables: tuple[MetVariable | tuple[MetVariable, ...], ...]
154
155
 
155
- #: Minimal set of required parameters if processing already complete on met input.
156
+ #: Set of required parameters if processing already complete on ``met`` input.
156
157
  processed_met_variables: tuple[MetVariable, ...]
157
158
 
158
159
  #: Optional meteorology variables
@@ -4,6 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import hashlib
6
6
  import logging
7
+ import os
7
8
  import pathlib
8
9
  import warnings
9
10
  from contextlib import ExitStack
@@ -40,13 +41,16 @@ class ERA5(ECMWFAPI):
40
41
  `Copernicus Data Portal <https://cds.climate.copernicus.eu/cdsapp#!/home>`_
41
42
  and local credentials.
42
43
 
43
- Local credentials can be specified in a ``~/.cdsapirc`` file
44
+ API credentials can be stored in a ``~/.cdsapirc`` file
44
45
  or as ``CDSAPI_URL`` and ``CDSAPI_KEY`` environment variables.
45
46
 
46
-
47
47
  export CDSAPI_URL=...
48
48
  export CDSAPI_KEY=...
49
49
 
50
+ Credentials can also be provided directly ``url`` and ``key`` keyword args.
51
+
52
+ See `cdsapi <https://github.com/ecmwf/cdsapi>`_ documentation
53
+ for more information.
50
54
 
51
55
  Parameters
52
56
  ----------
@@ -80,6 +84,10 @@ class ERA5(ECMWFAPI):
80
84
  Cache data store for staging ECMWF ERA5 files.
81
85
  Defaults to :class:`cache.DiskCacheStore`.
82
86
  If None, cache is turned off.
87
+ url : str
88
+ Override `cdsapi <https://github.com/ecmwf/cdsapi>`_ url
89
+ key : str
90
+ Override `cdsapi <https://github.com/ecmwf/cdsapi>`_ key
83
91
 
84
92
  Notes
85
93
  -----
@@ -93,7 +101,6 @@ class ERA5(ECMWFAPI):
93
101
  Local ``paths`` are loaded using :func:`xarray.open_mfdataset`.
94
102
  Pass ``xr_kwargs`` inputs to :meth:`open_metdataset` to customize file loading.
95
103
 
96
-
97
104
  Examples
98
105
  --------
99
106
  >>> from datetime import datetime
@@ -120,14 +127,22 @@ class ERA5(ECMWFAPI):
120
127
  __slots__ = (
121
128
  "product_type",
122
129
  "cds",
130
+ "url",
131
+ "key",
123
132
  )
124
133
 
125
134
  #: Product type, one of "reanalysis", "ensemble_mean", "ensemble_members", "ensemble_spread"
126
135
  product_type: str
127
136
 
128
- #: Handle to CDSAPI client
137
+ #: Handle to ``cdsapi.Client``
129
138
  cds: cdsapi.Client
130
139
 
140
+ #: User provided ``cdsapi.Client`` url
141
+ url: str | None
142
+
143
+ #: User provided ``cdsapi.Client`` url
144
+ key: str | None
145
+
131
146
  __marker = object()
132
147
 
133
148
  def __init__(
@@ -140,6 +155,8 @@ class ERA5(ECMWFAPI):
140
155
  product_type: str = "reanalysis",
141
156
  grid: float = 0.25,
142
157
  cachestore: cache.CacheStore | None = __marker, # type: ignore[assignment]
158
+ url: str | None = None,
159
+ key: str | None = None,
143
160
  ):
144
161
  # inputs
145
162
  self.product_type = product_type
@@ -147,6 +164,8 @@ class ERA5(ECMWFAPI):
147
164
  cachestore = cache.DiskCacheStore()
148
165
  self.cachestore = cachestore
149
166
  self.paths = paths
167
+ self.url = url or os.environ.get("CDSAPI_URL", None)
168
+ self.key = key or os.environ.get("CDSAPI_KEY", None)
150
169
 
151
170
  if time is None and paths is None:
152
171
  raise ValueError("Time input is required when paths is None")
@@ -504,7 +523,7 @@ class ERA5(ECMWFAPI):
504
523
  ) from e
505
524
 
506
525
  try:
507
- self.cds = cdsapi.Client()
526
+ self.cds = cdsapi.Client(url=self.url, key=self.key)
508
527
  # cdsapi throws base-level Exception
509
528
  except Exception as err:
510
529
  raise CDSCredentialsNotFound from err
@@ -102,7 +102,9 @@ def get_forecast_filename(
102
102
  class HRES(ECMWFAPI):
103
103
  """Class to support HRES data access, download, and organization.
104
104
 
105
- Requires account with ECMWF and API key set in local ``~/.ecmwfapirc`` file:
105
+ Requires account with ECMWF and API key.
106
+
107
+ API credentials set in local ``~/.ecmwfapirc`` file:
106
108
 
107
109
  .. code:: json
108
110
 
@@ -112,7 +114,9 @@ class HRES(ECMWFAPI):
112
114
  "key": "<key>"
113
115
  }
114
116
 
115
- See `ECMWF Web API <https://www.ecmwf.int/en/computing/software/ecmwf-web-api>`_ documentation
117
+ Credentials can also be provided directly ``url`` ``key``, and ``email`` keyword args.
118
+
119
+ See `ecmwf-api-client <https://github.com/ecmwf/ecmwf-api-client>`_ documentation
116
120
  for more information.
117
121
 
118
122
  Parameters
@@ -154,7 +158,12 @@ class HRES(ECMWFAPI):
154
158
  Cache data store for staging data files.
155
159
  Defaults to :class:`cache.DiskCacheStore`.
156
160
  If None, cache is turned off.
157
-
161
+ url : str
162
+ Override `ecmwf-api-client <https://github.com/ecmwf/ecmwf-api-client>`_ url
163
+ key : str
164
+ Override `ecmwf-api-client <https://github.com/ecmwf/ecmwf-api-client>`_ key
165
+ email : str
166
+ Override `ecmwf-api-client <https://github.com/ecmwf/ecmwf-api-client>`_ email
158
167
 
159
168
  Notes
160
169
  -----
@@ -211,7 +220,7 @@ class HRES(ECMWFAPI):
211
220
  ... )
212
221
  """
213
222
 
214
- __slots__ = ("server", "stream", "field_type", "forecast_time")
223
+ __slots__ = ("server", "stream", "field_type", "forecast_time", "url", "key", "email")
215
224
 
216
225
  #: stream type, "oper" = atmospheric model/HRES, "enfo" = ensemble forecast.
217
226
  stream: str
@@ -226,6 +235,15 @@ class HRES(ECMWFAPI):
226
235
  #: Forecast run time, either specified or assigned by the closest previous forecast run
227
236
  forecast_time: datetime
228
237
 
238
+ #: User provided ``ECMWFService`` url
239
+ url: str | None
240
+
241
+ #: User provided ``ECMWFService`` key
242
+ key: str | None
243
+
244
+ #: User provided ``ECMWFService`` email
245
+ email: str | None
246
+
229
247
  __marker = object()
230
248
 
231
249
  def __init__(
@@ -240,6 +258,9 @@ class HRES(ECMWFAPI):
240
258
  field_type: str = "fc",
241
259
  forecast_time: DatetimeLike | None = None,
242
260
  cachestore: cache.CacheStore | None = __marker, # type: ignore[assignment]
261
+ url: str | None = None,
262
+ key: str | None = None,
263
+ email: str | None = None,
243
264
  ) -> None:
244
265
  try:
245
266
  from ecmwfapi import ECMWFService
@@ -252,7 +273,10 @@ class HRES(ECMWFAPI):
252
273
  # constants
253
274
  # ERA5 now delays creating the server attribute until it is needed to download
254
275
  # from CDS. We could do the same here.
255
- self.server = ECMWFService("mars")
276
+ self.url = url
277
+ self.key = key
278
+ self.email = email
279
+ self.server = ECMWFService("mars", url=self.url, key=self.key, email=self.email)
256
280
  self.paths = paths
257
281
  if cachestore is self.__marker:
258
282
  cachestore = cache.DiskCacheStore()
@@ -45,9 +45,11 @@ class Cocip(Model):
45
45
  Parameters
46
46
  ----------
47
47
  met : MetDataset
48
- Dataset containing :attr:`met_variables` variables.
48
+ Pressure level dataset containing :attr:`met_variables` variables.
49
+ See *Notes* for variable names by data source.
49
50
  rad : MetDataset
50
- Radiation dataset
51
+ Single level dataset containing top of atmosphere radiation fluxes.
52
+ See *Notes* for variable names by data source.
51
53
  params : dict[str, Any], optional
52
54
  Override Cocip model parameters with dictionary.
53
55
  See :class:`CocipFlightParams` for model parameters.
@@ -57,6 +59,59 @@ class Cocip(Model):
57
59
 
58
60
  Notes
59
61
  -----
62
+ **Inputs**
63
+
64
+ The required meteorology variables depend on the data source (e.g. ECMWF, GFS).
65
+
66
+ See :attr:`met_variables` and :attr:`rad_variables` for the list of required variables
67
+ to the ``met`` and ``rad`` inputs, respectively.
68
+ When an item in one of these arrays is a tuple, variable keys depend on data source.
69
+
70
+ The current list of required variables (labelled by ``"standard_name"``):
71
+
72
+ .. list-table:: Variable keys for pressure level data
73
+ :header-rows: 1
74
+
75
+ * - Parameter
76
+ - ECMWF
77
+ - GFS
78
+ * - Air Temperature
79
+ - ``air_temperature``
80
+ - ``air_temperature``
81
+ * - Specific Humidity
82
+ - ``specific_humidity``
83
+ - ``specific_humidity``
84
+ * - Eastward wind
85
+ - ``eastward_wind``
86
+ - ``eastward_wind``
87
+ * - Northward wind
88
+ - ``northward_wind``
89
+ - ``northward_wind``
90
+ * - Vertical velocity
91
+ - ``lagrangian_tendency_of_air_pressure``
92
+ - ``lagrangian_tendency_of_air_pressure``
93
+ * - Ice water content
94
+ - ``specific_cloud_ice_water_content``
95
+ - ``ice_water_mixing_ratio``
96
+ * - Geopotential
97
+ - ``geopotential``
98
+ - ``geopotential_height``
99
+
100
+ .. list-table:: Variable keys for single-level radiation data
101
+ :header-rows: 1
102
+
103
+ * - Parameter
104
+ - ECMWF
105
+ - GFS
106
+ * - Top solar radiation
107
+ - ``top_net_solar_radiation``
108
+ - ``toa_upward_shortwave_flux``
109
+ * - Top thermal radiation
110
+ - ``top_net_thermal_radiation``
111
+ - ``toa_upward_longwave_flux``
112
+
113
+ **Modifications**
114
+
60
115
  This implementation differs from original CoCiP (Fortran) implementation in a few places:
61
116
 
62
117
  - This model uses aircraft performance and emissions models to calculate nvPM, fuel flow,
@@ -96,6 +151,8 @@ class Cocip(Model):
96
151
  results from :cite:`teohAviationContrailClimate2022`.
97
152
  See `tests/benchmark/north-atlantic-study/validate.py`.
98
153
 
154
+ **Outputs**
155
+
99
156
  NaN values may appear in model output. Specifically, `np.nan` values are used to indicate:
100
157
 
101
158
  - Flight waypoint or contrail waypoint is not contained with the :attr:`met` domain.
@@ -108,6 +165,10 @@ class Cocip(Model):
108
165
 
109
166
  References
110
167
  ----------
168
+ - :cite:`schumannDeterminationContrailsSatellite1990`
169
+ - :cite:`schumannContrailCirrusPrediction2010`
170
+ - :cite:`voigtInsituObservationsYoung2010`
171
+ - :cite:`schumannPotentialReduceClimate2011a`
111
172
  - :cite:`schumannContrailCirrusPrediction2012`
112
173
  - :cite:`schumannParametricRadiativeForcing2012`
113
174
  - :cite:`schumannContrailsVisibleAviation2012`
@@ -154,15 +215,16 @@ class Cocip(Model):
154
215
  (met_var.Geopotential, met_var.GeopotentialHeight),
155
216
  )
156
217
 
157
- #: Required radiation (single level) variables for model
218
+ #: Required single-level top of atmosphere radiation variables.
219
+ #: Variable keys depend on data source (e.g. ECMWF, GFS).
158
220
  rad_variables = (
159
221
  (ecmwf.TopNetSolarRadiation, gfs.TOAUpwardShortwaveRadiation),
160
222
  (ecmwf.TopNetThermalRadiation, gfs.TOAUpwardLongwaveRadiation),
161
223
  )
162
224
 
163
- #: Minimal set of met variables needed to run the model after preprocessing
164
- #: The intention here is that geopotential and sciwc are unnecessary after
165
- #: tau cirrus has already been calculated.
225
+ #: Minimal set of met variables needed to run the model after pre-processing.
226
+ #: The intention here is that ``geopotential`` and ``ciwc`` are unnecessary after
227
+ #: ``tau_cirrus`` has already been calculated.
166
228
  processed_met_variables = (
167
229
  met_var.AirTemperature,
168
230
  met_var.SpecificHumidity,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pycontrails
3
- Version: 0.40.0
3
+ Version: 0.40.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
@@ -1,29 +1,29 @@
1
- pycontrails-0.40.0.dist-info/RECORD,,
2
- pycontrails-0.40.0.dist-info/LICENSE,sha256=gJ-h7SFFD1mCfR6a7HILvEtodDT6Iig8bLXdgqR6ucA,10175
3
- pycontrails-0.40.0.dist-info/WHEEL,sha256=doY7Ynwndq62v9G9yH4QQiKEI6qNEsMeVrkmo76vHLE,111
4
- pycontrails-0.40.0.dist-info/NOTICE,sha256=gKI8DcN1WhiXB2SFRKDogcjONldGubTvBxiOYdC4CXU,1926
5
- pycontrails-0.40.0.dist-info/top_level.txt,sha256=Z8J1R_AiBAyCVjNw6jYLdrA68PrQqTg0t3_Yek_IZ0Q,29
6
- pycontrails-0.40.0.dist-info/METADATA,sha256=hkJ7OO2NnXLn2E-ZPYSR7JIDTzILwyU67IxMj3RkqYA,8291
7
- pycontrails/_version.py,sha256=gWVz7kYkjvWUgegETRrPqz0hpRYbz2Brc0ekOeULhdI,162
1
+ pycontrails-0.40.1.dist-info/RECORD,,
2
+ pycontrails-0.40.1.dist-info/LICENSE,sha256=gJ-h7SFFD1mCfR6a7HILvEtodDT6Iig8bLXdgqR6ucA,10175
3
+ pycontrails-0.40.1.dist-info/WHEEL,sha256=doY7Ynwndq62v9G9yH4QQiKEI6qNEsMeVrkmo76vHLE,111
4
+ pycontrails-0.40.1.dist-info/NOTICE,sha256=gKI8DcN1WhiXB2SFRKDogcjONldGubTvBxiOYdC4CXU,1926
5
+ pycontrails-0.40.1.dist-info/top_level.txt,sha256=Z8J1R_AiBAyCVjNw6jYLdrA68PrQqTg0t3_Yek_IZ0Q,29
6
+ pycontrails-0.40.1.dist-info/METADATA,sha256=Oe51rO4DRHIm5lSgR78bisV9Wx5XCA0E7Xo021uhVm8,8291
7
+ pycontrails/_version.py,sha256=Uv7Kv0aTKGB_HcctAoescgkUZZANf1_pdzcWwwttsDc,162
8
8
  pycontrails/__init__.py,sha256=sf7Xhr91V2jAvcQkla9oPqNCaXSKQp2M_dcxkiVkl6w,1943
9
9
  pycontrails/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  pycontrails/core/vector.py,sha256=nd1shWNp3A7ebihYgiUF-SHEtk_gpuuj65KBpCMpK7Q,57940
11
- pycontrails/core/models.py,sha256=6vyP8E0RsX17Dyo73TcaCqGnHi2N2gzv_C0BmvmHK0A,26722
11
+ pycontrails/core/models.py,sha256=eapTP-JlMgfXVvvLn3WcbushGpCRgbUp3u25sgwi9IU,26792
12
12
  pycontrails/core/interpolation.py,sha256=3SK7xE0ChmCc7Ev4uM1saUF3LhS7h0mqNMk4qR3XxwY,24032
13
13
  pycontrails/core/fleet.py,sha256=7BqRWNWAHhtpYsGSslYiMo1Zk4cM9vJe_L7UrZHi2dM,12341
14
- pycontrails/core/rgi_cython.cpython-310-darwin.so,sha256=LZMCM8Q-T07DDUam-IaPIwmvZ16nthZgxTuOUS1lDgo,286896
14
+ pycontrails/core/rgi_cython.cpython-310-darwin.so,sha256=CowO5ca3MsYZzNK02wtNWho-g8aJamVUWlXGl4PpM4w,286896
15
15
  pycontrails/core/flight.py,sha256=o6LfqDhd2WRbVEiPxKU263dZvfrjH0JieRY1-LmqjGw,49611
16
16
  pycontrails/core/fuel.py,sha256=lEMUgLeFBoazDsiKN07s9udQ12xghOos5v3H9bjveBs,4044
17
17
  pycontrails/core/polygon.py,sha256=mkpvZ7y5M-3lJAYyM_-LJQuUwVuVUVz6P1ZbEGMU0NU,18361
18
18
  pycontrails/core/datalib.py,sha256=JVI1rGndJ6GgcfbVI8f3jpk1nROILvc2jCYumfCmEFI,21346
19
19
  pycontrails/core/cache.py,sha256=uMzN45MUgIni1uhlypLVjc0NhFDvn6m-uK78p9sDdE8,28536
20
20
  pycontrails/core/__init__.py,sha256=C6bOLNBKeQaLCHCRza1oPrQTUazutPST7hX4C6O2MG0,866
21
- pycontrails/core/met.py,sha256=sS6mx_Qsj26kWM1ufH57pNU0PMUFnA0vZa2FNrELNhQ,86908
21
+ pycontrails/core/met.py,sha256=bEFiBItpxNzF0-HsTHcy4KqdJ4RvgkoPHxC1cjSXDfA,87281
22
22
  pycontrails/core/met_var.py,sha256=-gaodcmxx507ryMVKvFclqKkf1c8OHVVtXeG9s2eOOs,9191
23
23
  pycontrails/core/coordinates.py,sha256=b7D2lknnnwh8rBSla9M3ojqRYiASAOrVv0OAFD8xpDw,5078
24
24
  pycontrails/datalib/__init__.py,sha256=xcEVKnOmDvtswY6SQgiSVAWmx4YMTaqZECSnDzsTbEQ,200
25
- pycontrails/datalib/ecmwf/era5.py,sha256=_Kx4MY1NsRFsZ4jBSuObcLbE-M9g6hvE_yk6Ufg3Z14,18882
26
- pycontrails/datalib/ecmwf/hres.py,sha256=1pyVbUa83Od49Rv9eO6HFoNamM1rK1V9G2NTQXw7DIo,29499
25
+ pycontrails/datalib/ecmwf/era5.py,sha256=ulII_wQDSLmaqpMdZpAlOCmCCxhpzfSdBBgb8NW4ioA,19590
26
+ pycontrails/datalib/ecmwf/hres.py,sha256=wnGSZ67fnJ7NOw4hZXk3UCNcfFvShK1pWMm4nx0fz6c,30333
27
27
  pycontrails/datalib/ecmwf/variables.py,sha256=akqjUS3WKnSzV1Y0KkHLylH7QByvitc3wo8NBFeSNew,8714
28
28
  pycontrails/datalib/ecmwf/__init__.py,sha256=9rrlhfePtMrkofmFMg7t9fJ3teVufRJ0uM3Y-2PdzQ4,1045
29
29
  pycontrails/datalib/ecmwf/common.py,sha256=MCIFgGPnjb9tzjia4QzyPxIOAZBBqmpb4ucmua-B62Q,4890
@@ -56,7 +56,7 @@ pycontrails/models/emissions/static/edb-gaseous-v28c-engines.csv,sha256=9mok7P9N
56
56
  pycontrails/models/emissions/static/edb-nvpm-v28c-engines.csv,sha256=otZ3PWXcbu7ZuEgZ3v3bLB0CGjGRAacd69CGFUXAdSU,63472
57
57
  pycontrails/models/cocip/radiative_forcing.py,sha256=ReLufq2BWw_Vot18MIBkTkaOqNXrbGyGcoZnAwO0NOg,28853
58
58
  pycontrails/models/cocip/wind_shear.py,sha256=g6T_ZL77Vs7kxagrp6o_nFpycbnc5SyA4PBL1DOD0nA,3735
59
- pycontrails/models/cocip/cocip.py,sha256=hW0-ub6cSQyUm_qeh6OqEAAYrBAqO83Oz3_7cu_LnNA,84410
59
+ pycontrails/models/cocip/cocip.py,sha256=PDnMfZZ7FXqd5r-WWtQCZurD_FyLIvcY2qBELw0YXZE,86552
60
60
  pycontrails/models/cocip/__init__.py,sha256=vBicDVNyw-M3bglx1iVplxm6CQRPRk5SS-3_VgL7WQM,370
61
61
  pycontrails/models/cocip/cocip_params.py,sha256=0624P6cVc2vBeD8-2S3lMnfZtKkdOaycGhscgyp_nYo,9098
62
62
  pycontrails/models/cocip/wake_vortex.py,sha256=mH8qbuWvZlFzmjBokHp6TAIgii6wVXvaV_xmHzb34MI,11654