pycontrails 0.54.2__cp310-cp310-win_amd64.whl → 0.54.4__cp310-cp310-win_amd64.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.

Files changed (68) hide show
  1. pycontrails/__init__.py +2 -2
  2. pycontrails/_version.py +2 -2
  3. pycontrails/core/__init__.py +1 -1
  4. pycontrails/core/aircraft_performance.py +75 -61
  5. pycontrails/core/cache.py +7 -7
  6. pycontrails/core/fleet.py +25 -21
  7. pycontrails/core/flight.py +215 -301
  8. pycontrails/core/interpolation.py +56 -56
  9. pycontrails/core/met.py +48 -39
  10. pycontrails/core/models.py +25 -11
  11. pycontrails/core/polygon.py +15 -15
  12. pycontrails/core/rgi_cython.cp310-win_amd64.pyd +0 -0
  13. pycontrails/core/vector.py +22 -22
  14. pycontrails/datalib/_met_utils/metsource.py +8 -5
  15. pycontrails/datalib/ecmwf/__init__.py +14 -14
  16. pycontrails/datalib/ecmwf/common.py +1 -1
  17. pycontrails/datalib/ecmwf/era5.py +7 -7
  18. pycontrails/datalib/ecmwf/hres.py +3 -3
  19. pycontrails/datalib/ecmwf/ifs.py +1 -1
  20. pycontrails/datalib/ecmwf/variables.py +1 -0
  21. pycontrails/datalib/gfs/__init__.py +6 -6
  22. pycontrails/datalib/gfs/gfs.py +2 -2
  23. pycontrails/datalib/goes.py +5 -5
  24. pycontrails/datalib/landsat.py +5 -8
  25. pycontrails/datalib/sentinel.py +7 -11
  26. pycontrails/ext/bada.py +3 -2
  27. pycontrails/ext/empirical_grid.py +1 -1
  28. pycontrails/ext/synthetic_flight.py +3 -2
  29. pycontrails/models/accf.py +40 -19
  30. pycontrails/models/apcemm/apcemm.py +5 -4
  31. pycontrails/models/cocip/__init__.py +2 -2
  32. pycontrails/models/cocip/cocip.py +16 -17
  33. pycontrails/models/cocip/cocip_params.py +2 -11
  34. pycontrails/models/cocip/cocip_uncertainty.py +24 -18
  35. pycontrails/models/cocip/contrail_properties.py +331 -316
  36. pycontrails/models/cocip/output_formats.py +53 -53
  37. pycontrails/models/cocip/radiative_forcing.py +135 -131
  38. pycontrails/models/cocip/radiative_heating.py +135 -135
  39. pycontrails/models/cocip/unterstrasser_wake_vortex.py +90 -87
  40. pycontrails/models/cocip/wake_vortex.py +92 -92
  41. pycontrails/models/cocip/wind_shear.py +8 -8
  42. pycontrails/models/cocipgrid/cocip_grid.py +118 -107
  43. pycontrails/models/dry_advection.py +59 -58
  44. pycontrails/models/emissions/__init__.py +2 -2
  45. pycontrails/models/emissions/black_carbon.py +108 -108
  46. pycontrails/models/emissions/emissions.py +85 -85
  47. pycontrails/models/emissions/ffm2.py +35 -35
  48. pycontrails/models/humidity_scaling/humidity_scaling.py +23 -23
  49. pycontrails/models/ps_model/__init__.py +3 -2
  50. pycontrails/models/ps_model/ps_aircraft_params.py +11 -6
  51. pycontrails/models/ps_model/ps_grid.py +256 -60
  52. pycontrails/models/ps_model/ps_model.py +18 -21
  53. pycontrails/models/ps_model/ps_operational_limits.py +58 -69
  54. pycontrails/models/tau_cirrus.py +8 -1
  55. pycontrails/physics/geo.py +216 -67
  56. pycontrails/physics/jet.py +220 -90
  57. pycontrails/physics/static/iata-cargo-load-factors-20241115.csv +71 -0
  58. pycontrails/physics/static/iata-passenger-load-factors-20241115.csv +71 -0
  59. pycontrails/physics/units.py +14 -14
  60. pycontrails/utils/json.py +1 -2
  61. pycontrails/utils/types.py +12 -7
  62. {pycontrails-0.54.2.dist-info → pycontrails-0.54.4.dist-info}/METADATA +10 -10
  63. {pycontrails-0.54.2.dist-info → pycontrails-0.54.4.dist-info}/NOTICE +1 -1
  64. pycontrails-0.54.4.dist-info/RECORD +111 -0
  65. {pycontrails-0.54.2.dist-info → pycontrails-0.54.4.dist-info}/WHEEL +1 -1
  66. pycontrails-0.54.2.dist-info/RECORD +0 -109
  67. {pycontrails-0.54.2.dist-info → pycontrails-0.54.4.dist-info}/LICENSE +0 -0
  68. {pycontrails-0.54.2.dist-info → pycontrails-0.54.4.dist-info}/top_level.txt +0 -0
@@ -43,9 +43,9 @@ class PycontrailsRegularGridInterpolator(scipy.interpolate.RegularGridInterpolat
43
43
 
44
44
  Parameters
45
45
  ----------
46
- points : tuple[npt.NDArray[np.float64], ...]
46
+ points : tuple[npt.NDArray[np.floating], ...]
47
47
  Coordinates of the grid points.
48
- values : npt.NDArray[np.float64]
48
+ values : npt.NDArray[np.floating]
49
49
  Grid values. The shape of this array must be compatible with the
50
50
  coordinates. An error is raised if the dtype is not ``np.float32``
51
51
  or ``np.float64``.
@@ -59,8 +59,8 @@ class PycontrailsRegularGridInterpolator(scipy.interpolate.RegularGridInterpolat
59
59
 
60
60
  def __init__(
61
61
  self,
62
- points: tuple[npt.NDArray[np.float64], ...],
63
- values: npt.NDArray[np.float64],
62
+ points: tuple[npt.NDArray[np.floating], ...],
63
+ values: npt.NDArray[np.floating],
64
64
  method: str,
65
65
  bounds_error: bool,
66
66
  fill_value: float | np.float64 | None,
@@ -78,12 +78,12 @@ class PycontrailsRegularGridInterpolator(scipy.interpolate.RegularGridInterpolat
78
78
  self.fill_value = fill_value
79
79
  self._spline = None
80
80
 
81
- def _prepare_xi_simple(self, xi: npt.NDArray[np.float64]) -> npt.NDArray[np.bool_]:
81
+ def _prepare_xi_simple(self, xi: npt.NDArray[np.floating]) -> npt.NDArray[np.bool_]:
82
82
  """Run looser version of :meth:`_prepare_xi`.
83
83
 
84
84
  Parameters
85
85
  ----------
86
- xi : npt.NDArray[np.float64]
86
+ xi : npt.NDArray[np.floating]
87
87
  Points at which to interpolate.
88
88
 
89
89
  Returns
@@ -106,13 +106,13 @@ class PycontrailsRegularGridInterpolator(scipy.interpolate.RegularGridInterpolat
106
106
  return self._find_out_of_bounds(xi.T)
107
107
 
108
108
  def __call__(
109
- self, xi: npt.NDArray[np.float64], method: str | None = None
110
- ) -> npt.NDArray[np.float64]:
109
+ self, xi: npt.NDArray[np.floating], method: str | None = None
110
+ ) -> npt.NDArray[np.floating]:
111
111
  """Evaluate the interpolator at the given points.
112
112
 
113
113
  Parameters
114
114
  ----------
115
- xi : npt.NDArray[np.float64]
115
+ xi : npt.NDArray[np.floating]
116
116
  Points at which to interpolate. Must have shape ``(n, ndim)``, where
117
117
  ``ndim`` is the number of dimensions of the interpolator.
118
118
  method : str | None
@@ -120,7 +120,7 @@ class PycontrailsRegularGridInterpolator(scipy.interpolate.RegularGridInterpolat
120
120
 
121
121
  Returns
122
122
  -------
123
- npt.NDArray[np.float64]
123
+ npt.NDArray[np.floating]
124
124
  Interpolated values. Has shape ``(n,)``. When computing linear interpolation,
125
125
  the dtype is the same as the :attr:`values` array.
126
126
  """
@@ -137,21 +137,21 @@ class PycontrailsRegularGridInterpolator(scipy.interpolate.RegularGridInterpolat
137
137
 
138
138
  def _set_out_of_bounds(
139
139
  self,
140
- out: npt.NDArray[np.float64],
140
+ out: npt.NDArray[np.floating],
141
141
  out_of_bounds: npt.NDArray[np.bool_],
142
- ) -> npt.NDArray[np.float64]:
142
+ ) -> npt.NDArray[np.floating]:
143
143
  """Set out-of-bounds values to the fill value.
144
144
 
145
145
  Parameters
146
146
  ----------
147
- out : npt.NDArray[np.float64]
147
+ out : npt.NDArray[np.floating]
148
148
  Values from interpolation. This is modified in-place.
149
149
  out_of_bounds : npt.NDArray[np.bool_]
150
150
  A 1-dimensional Boolean array indicating which points are out of bounds.
151
151
 
152
152
  Returns
153
153
  -------
154
- out : npt.NDArray[np.float64]
154
+ out : npt.NDArray[np.floating]
155
155
  A reference to the ``out`` array.
156
156
  """
157
157
  if self.fill_value is not None and np.any(out_of_bounds):
@@ -162,8 +162,8 @@ class PycontrailsRegularGridInterpolator(scipy.interpolate.RegularGridInterpolat
162
162
  def _evaluate_linear(
163
163
  self,
164
164
  indices: npt.NDArray[np.int64],
165
- norm_distances: npt.NDArray[np.float64],
166
- ) -> npt.NDArray[np.float64]:
165
+ norm_distances: npt.NDArray[np.floating],
166
+ ) -> npt.NDArray[np.floating]:
167
167
  """Evaluate the interpolator using linear interpolation.
168
168
 
169
169
  This is a faster alternative to
@@ -181,13 +181,13 @@ class PycontrailsRegularGridInterpolator(scipy.interpolate.RegularGridInterpolat
181
181
  indices : npt.NDArray[np.int64]
182
182
  Indices of the grid points to the left of the interpolation points.
183
183
  Has shape ``(ndim, n_points)``.
184
- norm_distances : npt.NDArray[np.float64]
184
+ norm_distances : npt.NDArray[np.floating]
185
185
  Normalized distances between the interpolation points and the grid
186
186
  points to the left. Has shape ``(ndim, n_points)``.
187
187
 
188
188
  Returns
189
189
  -------
190
- npt.NDArray[np.float64]
190
+ npt.NDArray[np.floating]
191
191
  Interpolated values with shape ``(n_points,)`` and the same dtype as
192
192
  the :attr:`values` array.
193
193
  """
@@ -254,14 +254,14 @@ def _pick_method(scipy_version: str, method: str) -> str:
254
254
  raise ValueError(msg) from exc
255
255
 
256
256
  reimplemented_methods = ["slinear", "cubic", "quintic"]
257
- if major > 1 or (major == 1 and minor >= 13) and method in reimplemented_methods:
257
+ if major > 1 or ((major == 1 and minor >= 13) and method in reimplemented_methods):
258
258
  return method + "_legacy"
259
259
  return method
260
260
 
261
261
 
262
262
  def _floatize_time(
263
263
  time: npt.NDArray[np.datetime64], offset: np.datetime64
264
- ) -> npt.NDArray[np.float64]:
264
+ ) -> npt.NDArray[np.floating]:
265
265
  """Convert an array of ``np.datetime64`` to an array of ``np.float64``.
266
266
 
267
267
  In calls to :class:`scipy.interpolate.RegularGridInterpolator`, it's critical
@@ -296,7 +296,7 @@ def _floatize_time(
296
296
 
297
297
  Returns
298
298
  -------
299
- npt.NDArray[np.float64]
299
+ npt.NDArray[np.floating]
300
300
  The number of milliseconds since ``offset``.
301
301
  """
302
302
  delta = time - offset
@@ -354,9 +354,9 @@ def _localize(da: xr.DataArray, coords: dict[str, np.ndarray]) -> xr.DataArray:
354
354
 
355
355
  @overload
356
356
  def interp(
357
- longitude: npt.NDArray[np.float64],
358
- latitude: npt.NDArray[np.float64],
359
- level: npt.NDArray[np.float64],
357
+ longitude: npt.NDArray[np.floating],
358
+ latitude: npt.NDArray[np.floating],
359
+ level: npt.NDArray[np.floating],
360
360
  time: npt.NDArray[np.datetime64],
361
361
  da: xr.DataArray,
362
362
  method: str,
@@ -366,14 +366,14 @@ def interp(
366
366
  *,
367
367
  indices: RGIArtifacts | None = ...,
368
368
  return_indices: Literal[False] = ...,
369
- ) -> npt.NDArray[np.float64]: ...
369
+ ) -> npt.NDArray[np.floating]: ...
370
370
 
371
371
 
372
372
  @overload
373
373
  def interp(
374
- longitude: npt.NDArray[np.float64],
375
- latitude: npt.NDArray[np.float64],
376
- level: npt.NDArray[np.float64],
374
+ longitude: npt.NDArray[np.floating],
375
+ latitude: npt.NDArray[np.floating],
376
+ level: npt.NDArray[np.floating],
377
377
  time: npt.NDArray[np.datetime64],
378
378
  da: xr.DataArray,
379
379
  method: str,
@@ -383,14 +383,14 @@ def interp(
383
383
  *,
384
384
  indices: RGIArtifacts | None = ...,
385
385
  return_indices: Literal[True],
386
- ) -> tuple[npt.NDArray[np.float64], RGIArtifacts]: ...
386
+ ) -> tuple[npt.NDArray[np.floating], RGIArtifacts]: ...
387
387
 
388
388
 
389
389
  @overload
390
390
  def interp(
391
- longitude: npt.NDArray[np.float64],
392
- latitude: npt.NDArray[np.float64],
393
- level: npt.NDArray[np.float64],
391
+ longitude: npt.NDArray[np.floating],
392
+ latitude: npt.NDArray[np.floating],
393
+ level: npt.NDArray[np.floating],
394
394
  time: npt.NDArray[np.datetime64],
395
395
  da: xr.DataArray,
396
396
  method: str,
@@ -400,13 +400,13 @@ def interp(
400
400
  *,
401
401
  indices: RGIArtifacts | None = ...,
402
402
  return_indices: bool = ...,
403
- ) -> npt.NDArray[np.float64] | tuple[npt.NDArray[np.float64], RGIArtifacts]: ...
403
+ ) -> npt.NDArray[np.floating] | tuple[npt.NDArray[np.floating], RGIArtifacts]: ...
404
404
 
405
405
 
406
406
  def interp(
407
- longitude: npt.NDArray[np.float64],
408
- latitude: npt.NDArray[np.float64],
409
- level: npt.NDArray[np.float64],
407
+ longitude: npt.NDArray[np.floating],
408
+ latitude: npt.NDArray[np.floating],
409
+ level: npt.NDArray[np.floating],
410
410
  time: npt.NDArray[np.datetime64],
411
411
  da: xr.DataArray,
412
412
  method: str,
@@ -416,7 +416,7 @@ def interp(
416
416
  *,
417
417
  indices: RGIArtifacts | None = None,
418
418
  return_indices: bool = False,
419
- ) -> npt.NDArray[np.float64] | tuple[npt.NDArray[np.float64], RGIArtifacts]:
419
+ ) -> npt.NDArray[np.floating] | tuple[npt.NDArray[np.floating], RGIArtifacts]:
420
420
  """Interpolate over a grid with ``localize`` option.
421
421
 
422
422
  .. versionchanged:: 0.25.6
@@ -471,7 +471,7 @@ def interp(
471
471
 
472
472
  Returns
473
473
  -------
474
- npt.NDArray[np.float64] | tuple[npt.NDArray[np.float64], RGIArtifacts]
474
+ npt.NDArray[np.floating] | tuple[npt.NDArray[np.floating], RGIArtifacts]
475
475
  Interpolated values with same size as ``longitude``. If ``return_indices``
476
476
  is True, return intermediate indices artifacts as well.
477
477
 
@@ -499,7 +499,7 @@ def interp(
499
499
  t = _floatize_time(t, offset)
500
500
 
501
501
  single_level = z.size == 1 and z.item() == -1.0
502
- points: tuple[npt.NDArray[np.float64], ...]
502
+ points: tuple[npt.NDArray[np.floating], ...]
503
503
  if single_level:
504
504
  values = da.values.squeeze(axis=2)
505
505
  points = x, y, t
@@ -529,13 +529,13 @@ def interp(
529
529
 
530
530
 
531
531
  def _buildxi(
532
- longitude: npt.NDArray[np.float64],
533
- latitude: npt.NDArray[np.float64],
534
- level: npt.NDArray[np.float64],
532
+ longitude: npt.NDArray[np.floating],
533
+ latitude: npt.NDArray[np.floating],
534
+ level: npt.NDArray[np.floating],
535
535
  time: npt.NDArray[np.datetime64],
536
536
  offset: np.datetime64,
537
537
  single_level: bool,
538
- ) -> npt.NDArray[np.float64]:
538
+ ) -> npt.NDArray[np.floating]:
539
539
  """Build the input array for interpolation.
540
540
 
541
541
  The implementation below achieves the same result as the following::
@@ -562,10 +562,10 @@ def _buildxi(
562
562
 
563
563
  def _linear_interp_with_indices(
564
564
  interp: PycontrailsRegularGridInterpolator,
565
- xi: npt.NDArray[np.float64] | None,
565
+ xi: npt.NDArray[np.floating] | None,
566
566
  localize: bool,
567
567
  indices: RGIArtifacts | None,
568
- ) -> tuple[npt.NDArray[np.float64], RGIArtifacts]:
568
+ ) -> tuple[npt.NDArray[np.floating], RGIArtifacts]:
569
569
  if interp.method != "linear":
570
570
  msg = "Parameter 'indices' is only supported for 'method=linear'"
571
571
  raise ValueError(msg)
@@ -589,7 +589,7 @@ class RGIArtifacts:
589
589
  """An interface to intermediate RGI interpolation artifacts."""
590
590
 
591
591
  xi_indices: npt.NDArray[np.int64]
592
- norm_distances: npt.NDArray[np.float64]
592
+ norm_distances: npt.NDArray[np.floating]
593
593
  out_of_bounds: npt.NDArray[np.bool_]
594
594
 
595
595
 
@@ -608,10 +608,10 @@ class EmissionsProfileInterpolator:
608
608
 
609
609
  Parameters
610
610
  ----------
611
- xp : npt.NDarray[np.float64]
611
+ xp : npt.NDArray[np.floating]
612
612
  Array of x-values. These must be strictly increasing and free from
613
613
  any nan values. Passed to :func:`numpy.interp`.
614
- fp : npt.NDarray[np.float64]
614
+ fp : npt.NDArray[np.floating]
615
615
  Array of y-values. Passed to :func:`numpy.interp`.
616
616
  drop_duplicates : bool, optional
617
617
  Whether to drop duplicate values in ``xp``. Defaults to ``True``.
@@ -648,8 +648,8 @@ class EmissionsProfileInterpolator:
648
648
 
649
649
  def __init__(
650
650
  self,
651
- xp: npt.NDArray[np.float64],
652
- fp: npt.NDArray[np.float64],
651
+ xp: npt.NDArray[np.floating],
652
+ fp: npt.NDArray[np.floating],
653
653
  drop_duplicates: bool = True,
654
654
  ) -> None:
655
655
  if drop_duplicates:
@@ -680,17 +680,17 @@ class EmissionsProfileInterpolator:
680
680
  msg = "xp must not contain nan values"
681
681
  raise ValueError(msg)
682
682
 
683
- def interp(self, x: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]:
683
+ def interp(self, x: npt.NDArray[np.floating]) -> npt.NDArray[np.floating]:
684
684
  """Interpolate x against xp and fp.
685
685
 
686
686
  Parameters
687
687
  ----------
688
- x : npt.NDArray[np.float64]
688
+ x : npt.NDArray[np.floating]
689
689
  Array of x-values to interpolate.
690
690
 
691
691
  Returns
692
692
  -------
693
- npt.NDArray[np.float64]
693
+ npt.NDArray[np.floating]
694
694
  Array of interpolated y-values arising from the x-values. The ``dtype`` of
695
695
  the output array is the same as the ``dtype`` of ``x``.
696
696
  """
@@ -700,7 +700,7 @@ class EmissionsProfileInterpolator:
700
700
  dtype = np.result_type(x, np.float32)
701
701
  return np.interp(x, self.xp, self.fp).astype(dtype)
702
702
 
703
- def log_interp(self, x: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]:
703
+ def log_interp(self, x: npt.NDArray[np.floating]) -> npt.NDArray[np.floating]:
704
704
  """Interpolate x against xp and fp on a logarithmic scale.
705
705
 
706
706
  This method composes the following three functions.
@@ -710,12 +710,12 @@ class EmissionsProfileInterpolator:
710
710
 
711
711
  Parameters
712
712
  ----------
713
- x : npt.NDArray[np.float64]
713
+ x : npt.NDArray[np.floating]
714
714
  Array of x-values to interpolate.
715
715
 
716
716
  Returns
717
717
  -------
718
- npt.NDArray[np.float64]
718
+ npt.NDArray[np.floating]
719
719
  Array of interpolated y-values arising from the x-values.
720
720
  """
721
721
  return np.exp(self.interp(np.log(x)))
pycontrails/core/met.py CHANGED
@@ -1495,9 +1495,9 @@ class MetDataArray(MetBase):
1495
1495
  @overload
1496
1496
  def interpolate(
1497
1497
  self,
1498
- longitude: float | npt.NDArray[np.float64],
1499
- latitude: float | npt.NDArray[np.float64],
1500
- level: float | npt.NDArray[np.float64],
1498
+ longitude: float | npt.NDArray[np.floating],
1499
+ latitude: float | npt.NDArray[np.floating],
1500
+ level: float | npt.NDArray[np.floating],
1501
1501
  time: np.datetime64 | npt.NDArray[np.datetime64],
1502
1502
  *,
1503
1503
  method: str = ...,
@@ -1507,14 +1507,14 @@ class MetDataArray(MetBase):
1507
1507
  lowmem: bool = ...,
1508
1508
  indices: interpolation.RGIArtifacts | None = ...,
1509
1509
  return_indices: Literal[False] = ...,
1510
- ) -> npt.NDArray[np.float64]: ...
1510
+ ) -> npt.NDArray[np.floating]: ...
1511
1511
 
1512
1512
  @overload
1513
1513
  def interpolate(
1514
1514
  self,
1515
- longitude: float | npt.NDArray[np.float64],
1516
- latitude: float | npt.NDArray[np.float64],
1517
- level: float | npt.NDArray[np.float64],
1515
+ longitude: float | npt.NDArray[np.floating],
1516
+ latitude: float | npt.NDArray[np.floating],
1517
+ level: float | npt.NDArray[np.floating],
1518
1518
  time: np.datetime64 | npt.NDArray[np.datetime64],
1519
1519
  *,
1520
1520
  method: str = ...,
@@ -1524,13 +1524,13 @@ class MetDataArray(MetBase):
1524
1524
  lowmem: bool = ...,
1525
1525
  indices: interpolation.RGIArtifacts | None = ...,
1526
1526
  return_indices: Literal[True],
1527
- ) -> tuple[npt.NDArray[np.float64], interpolation.RGIArtifacts]: ...
1527
+ ) -> tuple[npt.NDArray[np.floating], interpolation.RGIArtifacts]: ...
1528
1528
 
1529
1529
  def interpolate(
1530
1530
  self,
1531
- longitude: float | npt.NDArray[np.float64],
1532
- latitude: float | npt.NDArray[np.float64],
1533
- level: float | npt.NDArray[np.float64],
1531
+ longitude: float | npt.NDArray[np.floating],
1532
+ latitude: float | npt.NDArray[np.floating],
1533
+ level: float | npt.NDArray[np.floating],
1534
1534
  time: np.datetime64 | npt.NDArray[np.datetime64],
1535
1535
  *,
1536
1536
  method: str = "linear",
@@ -1540,7 +1540,7 @@ class MetDataArray(MetBase):
1540
1540
  lowmem: bool = False,
1541
1541
  indices: interpolation.RGIArtifacts | None = None,
1542
1542
  return_indices: bool = False,
1543
- ) -> npt.NDArray[np.float64] | tuple[npt.NDArray[np.float64], interpolation.RGIArtifacts]:
1543
+ ) -> npt.NDArray[np.floating] | tuple[npt.NDArray[np.floating], interpolation.RGIArtifacts]:
1544
1544
  """Interpolate values over underlying DataArray.
1545
1545
 
1546
1546
  Zero dimensional coordinates are reshaped to 1D arrays.
@@ -1569,11 +1569,11 @@ class MetDataArray(MetBase):
1569
1569
 
1570
1570
  Parameters
1571
1571
  ----------
1572
- longitude : float | npt.NDArray[np.float64]
1572
+ longitude : float | npt.NDArray[np.floating]
1573
1573
  Longitude values to interpolate. Assumed to be 0 or 1 dimensional.
1574
- latitude : float | npt.NDArray[np.float64]
1574
+ latitude : float | npt.NDArray[np.floating]
1575
1575
  Latitude values to interpolate. Assumed to be 0 or 1 dimensional.
1576
- level : float | npt.NDArray[np.float64]
1576
+ level : float | npt.NDArray[np.floating]
1577
1577
  Level values to interpolate. Assumed to be 0 or 1 dimensional.
1578
1578
  time : np.datetime64 | npt.NDArray[np.datetime64]
1579
1579
  Time values to interpolate. Assumed to be 0 or 1 dimensional.
@@ -1696,18 +1696,17 @@ class MetDataArray(MetBase):
1696
1696
 
1697
1697
  def _interp_lowmem(
1698
1698
  self,
1699
- longitude: float | npt.NDArray[np.float64],
1700
- latitude: float | npt.NDArray[np.float64],
1701
- level: float | npt.NDArray[np.float64],
1699
+ longitude: float | npt.NDArray[np.floating],
1700
+ latitude: float | npt.NDArray[np.floating],
1701
+ level: float | npt.NDArray[np.floating],
1702
1702
  time: np.datetime64 | npt.NDArray[np.datetime64],
1703
1703
  *,
1704
1704
  method: str = "linear",
1705
1705
  bounds_error: bool = False,
1706
1706
  fill_value: float | np.float64 | None = np.nan,
1707
- minimize_memory: bool = False,
1708
1707
  indices: interpolation.RGIArtifacts | None = None,
1709
1708
  return_indices: bool = False,
1710
- ) -> npt.NDArray[np.float64] | tuple[npt.NDArray[np.float64], interpolation.RGIArtifacts]:
1709
+ ) -> npt.NDArray[np.floating] | tuple[npt.NDArray[np.floating], interpolation.RGIArtifacts]:
1711
1710
  """Interpolate values against underlying DataArray.
1712
1711
 
1713
1712
  This method is used by :meth:`interpolate` when ``lowmem=True``.
@@ -1762,27 +1761,37 @@ class MetDataArray(MetBase):
1762
1761
  )
1763
1762
  da.load()
1764
1763
 
1765
- tmp = interpolation.interp(
1766
- longitude=lon_sl,
1767
- latitude=lat_sl,
1768
- level=lev_sl,
1769
- time=t_sl,
1770
- da=da,
1771
- method=method,
1772
- bounds_error=bounds_error,
1773
- fill_value=fill_value,
1774
- localize=False, # would be no-op; da is localized already
1775
- indices=indices_sl,
1776
- return_indices=return_indices,
1777
- )
1778
-
1779
1764
  if return_indices:
1780
- out[mask], rgi_sl = tmp
1765
+ out[mask], rgi_sl = interpolation.interp(
1766
+ longitude=lon_sl,
1767
+ latitude=lat_sl,
1768
+ level=lev_sl,
1769
+ time=t_sl,
1770
+ da=da,
1771
+ method=method,
1772
+ bounds_error=bounds_error,
1773
+ fill_value=fill_value,
1774
+ localize=False, # would be no-op; da is localized already
1775
+ indices=indices_sl,
1776
+ return_indices=return_indices,
1777
+ )
1781
1778
  rgi_artifacts.xi_indices[:, mask] = rgi_sl.xi_indices
1782
1779
  rgi_artifacts.norm_distances[:, mask] = rgi_sl.norm_distances
1783
1780
  rgi_artifacts.out_of_bounds[mask] = rgi_sl.out_of_bounds
1784
1781
  else:
1785
- out[mask] = tmp
1782
+ out[mask] = interpolation.interp(
1783
+ longitude=lon_sl,
1784
+ latitude=lat_sl,
1785
+ level=lev_sl,
1786
+ time=t_sl,
1787
+ da=da,
1788
+ method=method,
1789
+ bounds_error=bounds_error,
1790
+ fill_value=fill_value,
1791
+ localize=False, # would be no-op; da is localized already
1792
+ indices=indices_sl,
1793
+ return_indices=return_indices,
1794
+ )
1786
1795
 
1787
1796
  if return_indices:
1788
1797
  return out, rgi_artifacts
@@ -1878,7 +1887,7 @@ class MetDataArray(MetBase):
1878
1887
  if not self.binary:
1879
1888
  raise NotImplementedError("proportion method is only implemented for binary fields")
1880
1889
 
1881
- return self.data.sum().values.item() / self.data.count().values.item()
1890
+ return self.data.sum().values.item() / self.data.count().values.item() # type: ignore[operator]
1882
1891
 
1883
1892
  def find_edges(self) -> MetDataArray:
1884
1893
  """Find edges of regions.
@@ -2592,9 +2601,9 @@ def _extract_2d_arr_and_altitude(
2592
2601
  except KeyError:
2593
2602
  altitude = None
2594
2603
  else:
2595
- altitude = round(altitude)
2604
+ altitude = round(altitude) # type: ignore[call-overload]
2596
2605
 
2597
- return arr, altitude
2606
+ return arr, altitude # type: ignore[return-value]
2598
2607
 
2599
2608
 
2600
2609
  def downselect(data: XArrayType, bbox: tuple[float, ...]) -> XArrayType:
@@ -135,6 +135,20 @@ class ModelParams:
135
135
  return {(name := field.name): getattr(self, name) for field in fields(self)}
136
136
 
137
137
 
138
+ @dataclass
139
+ class AdvectionBuffers(ModelParams):
140
+ """Override buffers in :class:`ModelParams` for advection models."""
141
+
142
+ #: Met longitude [WGS84] buffer for evolution by advection.
143
+ met_longitude_buffer: tuple[float, float] = (10.0, 10.0)
144
+
145
+ #: Met latitude buffer [WGS84] for evolution by advection.
146
+ met_latitude_buffer: tuple[float, float] = (10.0, 10.0)
147
+
148
+ #: Met level buffer [:math:`hPa`] for evolution by advection.
149
+ met_level_buffer: tuple[float, float] = (40.0, 40.0)
150
+
151
+
138
152
  # ------
139
153
  # Models
140
154
  # ------
@@ -146,7 +160,7 @@ class Model(ABC):
146
160
  Implementing classes must implement the :meth:`eval` method
147
161
  """
148
162
 
149
- __slots__ = ("params", "met", "source")
163
+ __slots__ = ("met", "params", "source")
150
164
 
151
165
  #: Default model parameter dataclass
152
166
  default_params: type[ModelParams] = ModelParams
@@ -825,7 +839,7 @@ def interpolate_met(
825
839
  *,
826
840
  q_method: str | None = None,
827
841
  **interp_kwargs: Any,
828
- ) -> npt.NDArray[np.float64]:
842
+ ) -> npt.NDArray[np.floating]:
829
843
  """Interpolate ``vector`` against ``met`` gridded data.
830
844
 
831
845
  If ``vector_key`` (=``met_key`` by default) already exists,
@@ -854,7 +868,7 @@ def interpolate_met(
854
868
 
855
869
  Returns
856
870
  -------
857
- npt.NDArray[np.float64]
871
+ npt.NDArray[np.floating]
858
872
  Interpolated values.
859
873
 
860
874
  Raises
@@ -933,15 +947,15 @@ def _extract_q(met: MetDataset, met_key: str, q_method: str) -> tuple[MetDataArr
933
947
 
934
948
 
935
949
  def _prepare_q(
936
- mda: MetDataArray, level: npt.NDArray[np.float64], q_method: str, log_applied: bool
937
- ) -> tuple[MetDataArray, npt.NDArray[np.float64]]:
950
+ mda: MetDataArray, level: npt.NDArray[np.floating], q_method: str, log_applied: bool
951
+ ) -> tuple[MetDataArray, npt.NDArray[np.floating]]:
938
952
  """Prepare specific humidity for interpolation with experimental ``q_method``.
939
953
 
940
954
  Parameters
941
955
  ----------
942
956
  mda : MetDataArray
943
957
  MetDataArray of specific humidity.
944
- level : npt.NDArray[np.float64]
958
+ level : npt.NDArray[np.floating]
945
959
  Levels to interpolate to, [:math:`hPa`].
946
960
  q_method : str
947
961
  One of ``"log-q-log-p"`` or ``"cubic-spline"``.
@@ -952,7 +966,7 @@ def _prepare_q(
952
966
  -------
953
967
  mda : MetDataArray
954
968
  MetDataArray of specific humidity transformed for interpolation.
955
- level : npt.NDArray[np.float64]
969
+ level : npt.NDArray[np.floating]
956
970
  Transformed levels for interpolation.
957
971
  """
958
972
  da = mda.data
@@ -975,8 +989,8 @@ def _prepare_q(
975
989
 
976
990
 
977
991
  def _prepare_q_log_q_log_p(
978
- da: xr.DataArray, level: npt.NDArray[np.float64], log_applied: bool
979
- ) -> tuple[MetDataArray, npt.NDArray[np.float64]]:
992
+ da: xr.DataArray, level: npt.NDArray[np.floating], log_applied: bool
993
+ ) -> tuple[MetDataArray, npt.NDArray[np.floating]]:
980
994
  da = da.assign_coords(level=np.log(da["level"]))
981
995
 
982
996
  if not log_applied:
@@ -994,8 +1008,8 @@ def _prepare_q_log_q_log_p(
994
1008
 
995
1009
 
996
1010
  def _prepare_q_cubic_spline(
997
- da: xr.DataArray, level: npt.NDArray[np.float64]
998
- ) -> tuple[MetDataArray, npt.NDArray[np.float64]]:
1011
+ da: xr.DataArray, level: npt.NDArray[np.floating]
1012
+ ) -> tuple[MetDataArray, npt.NDArray[np.floating]]:
999
1013
  if da["level"][0] < 50.0 or da["level"][-1] > 1000.0:
1000
1014
  msg = "Cubic spline interpolation requires data to span 50-1000 hPa."
1001
1015
  raise ValueError(msg)