pycontrails 0.51.1__cp310-cp310-macosx_11_0_arm64.whl → 0.52.0__cp310-cp310-macosx_11_0_arm64.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 (40) hide show
  1. pycontrails/__init__.py +1 -1
  2. pycontrails/_version.py +2 -2
  3. pycontrails/core/__init__.py +1 -1
  4. pycontrails/core/cache.py +1 -1
  5. pycontrails/core/flight.py +32 -28
  6. pycontrails/core/polygon.py +1 -1
  7. pycontrails/core/rgi_cython.cpython-310-darwin.so +0 -0
  8. pycontrails/datalib/__init__.py +4 -1
  9. pycontrails/datalib/_leo_utils/search.py +250 -0
  10. pycontrails/datalib/_leo_utils/static/bq_roi_query.sql +6 -0
  11. pycontrails/datalib/_leo_utils/vis.py +60 -0
  12. pycontrails/{core/datalib.py → datalib/_met_utils/metsource.py} +1 -1
  13. pycontrails/datalib/ecmwf/arco_era5.py +8 -7
  14. pycontrails/datalib/ecmwf/common.py +3 -2
  15. pycontrails/datalib/ecmwf/era5.py +12 -11
  16. pycontrails/datalib/ecmwf/era5_model_level.py +12 -11
  17. pycontrails/datalib/ecmwf/hres.py +14 -13
  18. pycontrails/datalib/ecmwf/hres_model_level.py +15 -14
  19. pycontrails/datalib/ecmwf/ifs.py +14 -13
  20. pycontrails/datalib/gfs/gfs.py +15 -14
  21. pycontrails/datalib/goes.py +2 -2
  22. pycontrails/datalib/landsat.py +567 -0
  23. pycontrails/datalib/sentinel.py +512 -0
  24. pycontrails/models/apcemm/__init__.py +8 -0
  25. pycontrails/models/apcemm/apcemm.py +983 -0
  26. pycontrails/models/apcemm/inputs.py +226 -0
  27. pycontrails/models/apcemm/static/apcemm_yaml_template.yaml +183 -0
  28. pycontrails/models/apcemm/utils.py +437 -0
  29. pycontrails/models/cocip/__init__.py +2 -0
  30. pycontrails/models/cocip/output_formats.py +165 -0
  31. pycontrails/models/cocipgrid/cocip_grid.py +7 -6
  32. pycontrails/models/dry_advection.py +14 -5
  33. {pycontrails-0.51.1.dist-info → pycontrails-0.52.0.dist-info}/METADATA +20 -11
  34. {pycontrails-0.51.1.dist-info → pycontrails-0.52.0.dist-info}/RECORD +39 -30
  35. pycontrails/datalib/spire/__init__.py +0 -19
  36. /pycontrails/datalib/{spire/spire.py → spire.py} +0 -0
  37. {pycontrails-0.51.1.dist-info → pycontrails-0.52.0.dist-info}/LICENSE +0 -0
  38. {pycontrails-0.51.1.dist-info → pycontrails-0.52.0.dist-info}/NOTICE +0 -0
  39. {pycontrails-0.51.1.dist-info → pycontrails-0.52.0.dist-info}/WHEEL +0 -0
  40. {pycontrails-0.51.1.dist-info → pycontrails-0.52.0.dist-info}/top_level.txt +0 -0
@@ -40,8 +40,9 @@ import pandas as pd
40
40
  import xarray as xr
41
41
 
42
42
  import pycontrails
43
- from pycontrails.core import cache, datalib
43
+ from pycontrails.core import cache
44
44
  from pycontrails.core.met import MetDataset, MetVariable
45
+ from pycontrails.datalib._met_utils import metsource
45
46
  from pycontrails.datalib.ecmwf.common import ECMWFAPI, CDSCredentialsNotFound
46
47
  from pycontrails.datalib.ecmwf.model_levels import pressure_levels_at_model_levels
47
48
  from pycontrails.datalib.ecmwf.variables import MODEL_LEVEL_VARIABLES
@@ -73,7 +74,7 @@ class ERA5ModelLevel(ECMWFAPI):
73
74
 
74
75
  Parameters
75
76
  ----------
76
- time : datalib.TimeInput | None
77
+ time : metsource.TimeInput | None
77
78
  The time range for data retrieval, either a single datetime or (start, end) datetime range.
78
79
  Input must be datetime-like or tuple of datetime-like
79
80
  (:py:class:`datetime.datetime`, :class:`pandas.Timestamp`, :class:`numpy.datetime64`)
@@ -82,9 +83,9 @@ class ERA5ModelLevel(ECMWFAPI):
82
83
  for the nominal reanalysis and no larger than 1 day for ensemble members.
83
84
  This ensures that exactly one request is submitted per file on tape accessed.
84
85
  If None, ``paths`` must be defined and all time coordinates will be loaded from files.
85
- variables : datalib.VariableInput
86
+ variables : metsource.VariableInput
86
87
  Variable name (i.e. "t", "air_temperature", ["air_temperature, specific_humidity"])
87
- pressure_levels : datalib.PressureLevelInput, optional
88
+ pressure_levels : metsource.PressureLevelInput, optional
88
89
  Pressure levels for data, in hPa (mbar).
89
90
  To download surface-level parameters, use :class:`pycontrails.datalib.ecmwf.ERA5`.
90
91
  Defaults to pressure levels that match model levels at a nominal surface pressure.
@@ -123,9 +124,9 @@ class ERA5ModelLevel(ECMWFAPI):
123
124
 
124
125
  def __init__(
125
126
  self,
126
- time: datalib.TimeInput,
127
- variables: datalib.VariableInput,
128
- pressure_levels: datalib.PressureLevelInput | None = None,
127
+ time: metsource.TimeInput,
128
+ variables: metsource.VariableInput,
129
+ pressure_levels: metsource.PressureLevelInput | None = None,
129
130
  timestep_freq: str | None = None,
130
131
  product_type: str = "reanalysis",
131
132
  grid: float | None = None,
@@ -186,18 +187,18 @@ class ERA5ModelLevel(ECMWFAPI):
186
187
  datasource_timestep_freq = "1h" if product_type == "reanalysis" else "3h"
187
188
  if timestep_freq is None:
188
189
  timestep_freq = datasource_timestep_freq
189
- if not datalib.validate_timestep_freq(timestep_freq, datasource_timestep_freq):
190
+ if not metsource.validate_timestep_freq(timestep_freq, datasource_timestep_freq):
190
191
  msg = (
191
192
  f"Product {self.product_type} has timestep frequency of {datasource_timestep_freq} "
192
193
  f"and cannot support requested timestep frequency of {timestep_freq}."
193
194
  )
194
195
  raise ValueError(msg)
195
196
 
196
- self.timesteps = datalib.parse_timesteps(time, freq=timestep_freq)
197
+ self.timesteps = metsource.parse_timesteps(time, freq=timestep_freq)
197
198
  if pressure_levels is None:
198
199
  pressure_levels = pressure_levels_at_model_levels(20_000.0, 50_000.0)
199
- self.pressure_levels = datalib.parse_pressure_levels(pressure_levels)
200
- self.variables = datalib.parse_variables(variables, self.pressure_level_variables)
200
+ self.pressure_levels = metsource.parse_pressure_levels(pressure_levels)
201
+ self.variables = metsource.parse_variables(variables, self.pressure_level_variables)
201
202
 
202
203
  def __repr__(self) -> str:
203
204
  base = super().__repr__()
@@ -17,8 +17,9 @@ import xarray as xr
17
17
  from overrides import overrides
18
18
 
19
19
  import pycontrails
20
- from pycontrails.core import cache, datalib
20
+ from pycontrails.core import cache
21
21
  from pycontrails.core.met import MetDataset, MetVariable
22
+ from pycontrails.datalib._met_utils import metsource
22
23
  from pycontrails.datalib.ecmwf.common import ECMWFAPI
23
24
  from pycontrails.datalib.ecmwf.variables import PRESSURE_LEVEL_VARIABLES, SURFACE_VARIABLES
24
25
  from pycontrails.utils import dependencies, iteration, temp
@@ -120,7 +121,7 @@ class HRES(ECMWFAPI):
120
121
 
121
122
  Parameters
122
123
  ----------
123
- time : datalib.TimeInput | None
124
+ time : metsource.TimeInput | None
124
125
  The time range for data retrieval, either a single datetime or (start, end) datetime range.
125
126
  Input must be a datetime-like or tuple of datetime-like
126
127
  (datetime, :class:`pandas.Timestamp`, :class:`numpy.datetime64`)
@@ -129,10 +130,10 @@ class HRES(ECMWFAPI):
129
130
  be assumed to be the nearest synoptic hour: 00, 06, 12, 18.
130
131
  All subsequent times will be downloaded for relative to :attr:`forecast_time`.
131
132
  If None, ``paths`` must be defined and all time coordinates will be loaded from files.
132
- variables : datalib.VariableInput
133
+ variables : metsource.VariableInput
133
134
  Variable name (i.e. "air_temperature", ["air_temperature, relative_humidity"])
134
135
  See :attr:`pressure_level_variables` for the list of available variables.
135
- pressure_levels : datalib.PressureLevelInput, optional
136
+ pressure_levels : metsource.PressureLevelInput, optional
136
137
  Pressure levels for data, in hPa (mbar)
137
138
  Set to -1 for to download surface level parameters.
138
139
  Defaults to -1.
@@ -241,9 +242,9 @@ class HRES(ECMWFAPI):
241
242
 
242
243
  def __init__(
243
244
  self,
244
- time: datalib.TimeInput | None,
245
- variables: datalib.VariableInput,
246
- pressure_levels: datalib.PressureLevelInput = -1,
245
+ time: metsource.TimeInput | None,
246
+ variables: metsource.VariableInput,
247
+ pressure_levels: metsource.PressureLevelInput = -1,
247
248
  paths: str | list[str] | pathlib.Path | list[pathlib.Path] | None = None,
248
249
  cachepath: str | list[str] | pathlib.Path | list[pathlib.Path] | None = None,
249
250
  grid: float = 0.25,
@@ -277,13 +278,13 @@ class HRES(ECMWFAPI):
277
278
  if time is None and paths is None:
278
279
  raise ValueError("Time input is required when paths is None")
279
280
 
280
- self.timesteps = datalib.parse_timesteps(time, freq="1h")
281
- self.pressure_levels = datalib.parse_pressure_levels(
281
+ self.timesteps = metsource.parse_timesteps(time, freq="1h")
282
+ self.pressure_levels = metsource.parse_pressure_levels(
282
283
  pressure_levels, self.supported_pressure_levels
283
284
  )
284
- self.variables = datalib.parse_variables(variables, self.supported_variables)
285
+ self.variables = metsource.parse_variables(variables, self.supported_variables)
285
286
 
286
- self.grid = datalib.parse_grid(grid, [0.1, 0.25, 0.5, 1]) # lat/lon degree resolution
287
+ self.grid = metsource.parse_grid(grid, [0.1, 0.25, 0.5, 1]) # lat/lon degree resolution
287
288
 
288
289
  # "enfo" = ensemble forecast
289
290
  # "oper" = atmospheric model/HRES
@@ -309,12 +310,12 @@ class HRES(ECMWFAPI):
309
310
  if forecast_time_pd.hour % 6:
310
311
  raise ValueError("Forecast hour must be on one of 00, 06, 12, 18")
311
312
 
312
- self.forecast_time = datalib.round_hour(forecast_time_pd.to_pydatetime(), 6)
313
+ self.forecast_time = metsource.round_hour(forecast_time_pd.to_pydatetime(), 6)
313
314
 
314
315
  # if no specific forecast is requested, set the forecast time using timesteps
315
316
  elif self.timesteps:
316
317
  # round first element to the nearest 6 hour time (00, 06, 12, 18 UTC) for forecast_time
317
- self.forecast_time = datalib.round_hour(self.timesteps[0], 6)
318
+ self.forecast_time = metsource.round_hour(self.timesteps[0], 6)
318
319
 
319
320
  # when no forecast_time or time input, forecast_time is defined in _open_and_cache
320
321
 
@@ -28,8 +28,9 @@ import xarray as xr
28
28
  from overrides import overrides
29
29
 
30
30
  import pycontrails
31
- from pycontrails.core import cache, datalib
31
+ from pycontrails.core import cache
32
32
  from pycontrails.core.met import MetDataset, MetVariable
33
+ from pycontrails.datalib._met_utils import metsource
33
34
  from pycontrails.datalib.ecmwf.common import ECMWFAPI
34
35
  from pycontrails.datalib.ecmwf.model_levels import pressure_levels_at_model_levels
35
36
  from pycontrails.datalib.ecmwf.variables import MODEL_LEVEL_VARIABLES
@@ -70,7 +71,7 @@ class HRESModelLevel(ECMWFAPI):
70
71
 
71
72
  Parameters
72
73
  ----------
73
- time : datalib.TimeInput
74
+ time : metsource.TimeInput
74
75
  The time range for data retrieval, either a single datetime or (start, end) datetime range.
75
76
  Input must be datetime-like or tuple of datetime-like
76
77
  (:py:class:`datetime.datetime`, :class:`pandas.Timestamp`, :class:`numpy.datetime64`)
@@ -80,9 +81,9 @@ class HRESModelLevel(ECMWFAPI):
80
81
  If ``forecast_time`` is unspecified, the forecast time will
81
82
  be assumed to be the nearest synoptic hour available in the operational archive (00 or 12).
82
83
  All subsequent times will be downloaded for relative to :attr:`forecast_time`.
83
- variables : datalib.VariableInput
84
+ variables : metsource.VariableInput
84
85
  Variable name (i.e. "t", "air_temperature", ["air_temperature, specific_humidity"])
85
- pressure_levels : datalib.PressureLevelInput, optional
86
+ pressure_levels : metsource.PressureLevelInput, optional
86
87
  Pressure levels for data, in hPa (mbar).
87
88
  To download surface-level parameters, use :class:`pycontrails.datalib.ecmwf.HRES`.
88
89
  Defaults to pressure levels that match model levels at a nominal surface pressure.
@@ -119,9 +120,9 @@ class HRESModelLevel(ECMWFAPI):
119
120
 
120
121
  def __init__(
121
122
  self,
122
- time: datalib.TimeInput,
123
- variables: datalib.VariableInput,
124
- pressure_levels: datalib.PressureLevelInput | None = None,
123
+ time: metsource.TimeInput,
124
+ variables: metsource.VariableInput,
125
+ pressure_levels: metsource.PressureLevelInput | None = None,
125
126
  timestep_freq: str | None = None,
126
127
  grid: float | None = None,
127
128
  forecast_time: DatetimeLike | None = None,
@@ -165,15 +166,15 @@ class HRESModelLevel(ECMWFAPI):
165
166
  raise ValueError(msg)
166
167
  self.levels = levels
167
168
 
168
- forecast_hours = datalib.parse_timesteps(time, freq="1h")
169
+ forecast_hours = metsource.parse_timesteps(time, freq="1h")
169
170
  if forecast_time is None:
170
- self.forecast_time = datalib.round_hour(forecast_hours[0], 12)
171
+ self.forecast_time = metsource.round_hour(forecast_hours[0], 12)
171
172
  else:
172
173
  forecast_time_pd = pd.to_datetime(forecast_time)
173
174
  if (hour := forecast_time_pd.hour) % 12:
174
175
  msg = f"Forecast hour must be one of 00 or 12 but is {hour:02d}."
175
176
  raise ValueError(msg)
176
- self.forecast_time = datalib.round_hour(forecast_time_pd.to_pydatetime(), 12)
177
+ self.forecast_time = metsource.round_hour(forecast_time_pd.to_pydatetime(), 12)
177
178
 
178
179
  last_step = (forecast_hours[-1] - self.forecast_time) / timedelta(hours=1)
179
180
  if last_step > LAST_STEP_6H:
@@ -188,7 +189,7 @@ class HRESModelLevel(ECMWFAPI):
188
189
  )
189
190
  if timestep_freq is None:
190
191
  timestep_freq = datasource_timestep_freq
191
- if not datalib.validate_timestep_freq(timestep_freq, datasource_timestep_freq):
192
+ if not metsource.validate_timestep_freq(timestep_freq, datasource_timestep_freq):
192
193
  msg = (
193
194
  f"Forecast out to step {last_step} "
194
195
  f"has timestep frequency of {datasource_timestep_freq} "
@@ -196,15 +197,15 @@ class HRESModelLevel(ECMWFAPI):
196
197
  )
197
198
  raise ValueError(msg)
198
199
 
199
- self.timesteps = datalib.parse_timesteps(time, freq=timestep_freq)
200
+ self.timesteps = metsource.parse_timesteps(time, freq=timestep_freq)
200
201
  if self.step_offset < 0:
201
202
  msg = f"Selected forecast time {self.forecast_time} is after first timestep."
202
203
  raise ValueError(msg)
203
204
 
204
205
  if pressure_levels is None:
205
206
  pressure_levels = pressure_levels_at_model_levels(20_000.0, 50_000.0)
206
- self.pressure_levels = datalib.parse_pressure_levels(pressure_levels)
207
- self.variables = datalib.parse_variables(variables, self.pressure_level_variables)
207
+ self.pressure_levels = metsource.parse_pressure_levels(pressure_levels)
208
+ self.variables = metsource.parse_variables(variables, self.pressure_level_variables)
208
209
 
209
210
  def __repr__(self) -> str:
210
211
  base = super().__repr__()
@@ -15,13 +15,14 @@ import pandas as pd
15
15
  import xarray as xr
16
16
  from overrides import overrides
17
17
 
18
- from pycontrails.core import datalib, met
18
+ from pycontrails.core import met
19
+ from pycontrails.datalib._met_utils import metsource
19
20
  from pycontrails.datalib.ecmwf.variables import ECMWF_VARIABLES
20
21
  from pycontrails.physics import constants
21
22
  from pycontrails.utils.types import DatetimeLike
22
23
 
23
24
 
24
- class IFS(datalib.MetDataSource):
25
+ class IFS(metsource.MetDataSource):
25
26
  """
26
27
  ECMWF Integrated Forecasting System (IFS) data source.
27
28
 
@@ -31,16 +32,16 @@ class IFS(datalib.MetDataSource):
31
32
 
32
33
  Parameters
33
34
  ----------
34
- time : datalib.TimeInput | None
35
+ time : metsource.TimeInput | None
35
36
  The time range for data retrieval, either a single datetime or (start, end) datetime range.
36
37
  Input must be a single datetime-like or tuple of datetime-like
37
38
  (datetime, :class:`pandas.Timestamp`, :class:`numpy.datetime64`)
38
39
  specifying the (start, end) of the date range, inclusive.
39
40
  If None, all time coordinates will be loaded.
40
- variables : datalib.VariableInput
41
+ variables : metsource.VariableInput
41
42
  Variable name (i.e. "air_temperature", ["air_temperature, relative_humidity"])
42
43
  See :attr:`pressure_level_variables` for the list of available variables.
43
- pressure_levels : datalib.PressureLevelInput, optional
44
+ pressure_levels : metsource.PressureLevelInput, optional
44
45
  Pressure level bounds for data (min, max), in hPa (mbar)
45
46
  Set to -1 for to download surface level parameters.
46
47
  Defaults to -1.
@@ -69,9 +70,9 @@ class IFS(datalib.MetDataSource):
69
70
 
70
71
  def __init__(
71
72
  self,
72
- time: datalib.TimeInput | None,
73
- variables: datalib.VariableInput,
74
- pressure_levels: datalib.PressureLevelInput = -1,
73
+ time: metsource.TimeInput | None,
74
+ variables: metsource.VariableInput,
75
+ pressure_levels: metsource.PressureLevelInput = -1,
75
76
  paths: str | list[str] | pathlib.Path | list[pathlib.Path] | None = None,
76
77
  grid: float | None = None,
77
78
  forecast_path: str | pathlib.Path | None = None,
@@ -89,9 +90,9 @@ class IFS(datalib.MetDataSource):
89
90
  self.forecast_date = pd.to_datetime(forecast_date).to_pydatetime()
90
91
 
91
92
  # parse inputs
92
- self.timesteps = datalib.parse_timesteps(time, freq="3h")
93
- self.pressure_levels = datalib.parse_pressure_levels(pressure_levels, None)
94
- self.variables = datalib.parse_variables(variables, self.supported_variables)
93
+ self.timesteps = metsource.parse_timesteps(time, freq="3h")
94
+ self.pressure_levels = metsource.parse_pressure_levels(pressure_levels, None)
95
+ self.variables = metsource.parse_variables(variables, self.supported_variables)
95
96
 
96
97
  def __repr__(self) -> str:
97
98
  base = super().__repr__()
@@ -221,8 +222,8 @@ class IFS(datalib.MetDataSource):
221
222
  LOG.debug(f"Loading IFS forecast date {date_str}")
222
223
 
223
224
  # load each dataset
224
- xr_kwargs.setdefault("chunks", datalib.DEFAULT_CHUNKS)
225
- xr_kwargs.setdefault("engine", datalib.NETCDF_ENGINE)
225
+ xr_kwargs.setdefault("chunks", metsource.DEFAULT_CHUNKS)
226
+ xr_kwargs.setdefault("engine", metsource.NETCDF_ENGINE)
226
227
  ds_full = xr.open_dataset(path_full, **xr_kwargs)
227
228
  ds_fl = xr.open_dataset(path_fl, **xr_kwargs)
228
229
  ds_surface = xr.open_dataset(path_surface, **xr_kwargs)
@@ -22,7 +22,8 @@ import xarray as xr
22
22
  from overrides import overrides
23
23
 
24
24
  import pycontrails
25
- from pycontrails.core import cache, datalib, met
25
+ from pycontrails.core import cache, met
26
+ from pycontrails.datalib._met_utils import metsource
26
27
  from pycontrails.datalib.gfs.variables import (
27
28
  PRESSURE_LEVEL_VARIABLES,
28
29
  SURFACE_VARIABLES,
@@ -43,12 +44,12 @@ logger = logging.getLogger(__name__)
43
44
  GFS_FORECAST_BUCKET = "noaa-gfs-bdp-pds"
44
45
 
45
46
 
46
- class GFSForecast(datalib.MetDataSource):
47
+ class GFSForecast(metsource.MetDataSource):
47
48
  """GFS Forecast data access.
48
49
 
49
50
  Parameters
50
51
  ----------
51
- time : `datalib.TimeInput`
52
+ time : `metsource.TimeInput`
52
53
  The time range for data retrieval, either a single datetime or (start, end) datetime range.
53
54
  Input must be a single datetime-like or tuple of datetime-like (datetime,
54
55
  :class:`pandas.Timestamp`, :class:`numpy.datetime64`)
@@ -56,10 +57,10 @@ class GFSForecast(datalib.MetDataSource):
56
57
  All times will be downloaded for a single forecast model run nearest to the start time
57
58
  (see :attr:`forecast_time`)
58
59
  If None, ``paths`` must be defined and all time coordinates will be loaded from files.
59
- variables : `datalib.VariableInput`
60
+ variables : `metsource.VariableInput`
60
61
  Variable name (i.e. "temperature", ["temperature, relative_humidity"])
61
62
  See :attr:`pressure_level_variables` for the list of available variables.
62
- pressure_levels : `datalib.PressureLevelInput`, optional
63
+ pressure_levels : `metsource.PressureLevelInput`, optional
63
64
  Pressure levels for data, in hPa (mbar)
64
65
  Set to [-1] for to download surface level parameters.
65
66
  Defaults to [-1].
@@ -132,9 +133,9 @@ class GFSForecast(datalib.MetDataSource):
132
133
 
133
134
  def __init__(
134
135
  self,
135
- time: datalib.TimeInput | None,
136
- variables: datalib.VariableInput,
137
- pressure_levels: datalib.PressureLevelInput = -1,
136
+ time: metsource.TimeInput | None,
137
+ variables: metsource.VariableInput,
138
+ pressure_levels: metsource.PressureLevelInput = -1,
138
139
  paths: str | list[str] | pathlib.Path | list[pathlib.Path] | None = None,
139
140
  grid: float = 0.25,
140
141
  forecast_time: DatetimeLike | None = None,
@@ -175,13 +176,13 @@ class GFSForecast(datalib.MetDataSource):
175
176
  # 3 hourly for 0.5 and 1 degree grid
176
177
  # https://www.nco.ncep.noaa.gov/pmb/products/gfs/
177
178
  freq = "1h" if grid == 0.25 else "3h"
178
- self.timesteps = datalib.parse_timesteps(time, freq=freq)
179
+ self.timesteps = metsource.parse_timesteps(time, freq=freq)
179
180
 
180
- self.pressure_levels = datalib.parse_pressure_levels(
181
+ self.pressure_levels = metsource.parse_pressure_levels(
181
182
  pressure_levels, self.supported_pressure_levels
182
183
  )
183
- self.variables = datalib.parse_variables(variables, self.supported_variables)
184
- self.grid = datalib.parse_grid(grid, (0.25, 0.5, 1))
184
+ self.variables = metsource.parse_variables(variables, self.supported_variables)
185
+ self.grid = metsource.parse_grid(grid, (0.25, 0.5, 1))
185
186
 
186
187
  # note GFS allows unsigned requests (no credentials)
187
188
  # https://stackoverflow.com/questions/34865927/can-i-use-boto3-anonymously/34866092#34866092
@@ -195,12 +196,12 @@ class GFSForecast(datalib.MetDataSource):
195
196
  if forecast_time_pd.hour % 6:
196
197
  raise ValueError("Forecast hour must be on one of 00, 06, 12, 18")
197
198
 
198
- self.forecast_time = datalib.round_hour(forecast_time_pd.to_pydatetime(), 6)
199
+ self.forecast_time = metsource.round_hour(forecast_time_pd.to_pydatetime(), 6)
199
200
 
200
201
  # if no specific forecast is requested, set the forecast time using timesteps
201
202
  else:
202
203
  # round first element to the nearest 6 hour time (00, 06, 12, 18 UTC) for forecast_time
203
- self.forecast_time = datalib.round_hour(self.timesteps[0], 6)
204
+ self.forecast_time = metsource.round_hour(self.timesteps[0], 6)
204
205
 
205
206
  def __repr__(self) -> str:
206
207
  base = super().__repr__()
@@ -35,7 +35,7 @@ except ModuleNotFoundError as exc:
35
35
  name="goes module",
36
36
  package_name="cartopy",
37
37
  module_not_found_error=exc,
38
- pycontrails_optional_package="goes",
38
+ pycontrails_optional_package="sat",
39
39
  )
40
40
 
41
41
  try:
@@ -45,7 +45,7 @@ except ModuleNotFoundError as exc:
45
45
  name="goes module",
46
46
  package_name="gcsfs",
47
47
  module_not_found_error=exc,
48
- pycontrails_optional_package="goes",
48
+ pycontrails_optional_package="sat",
49
49
  )
50
50
 
51
51