Tutorial#

Intake-thredds provides an interface that combines functionality from siphon and intake to retrieve data from THREDDS data servers. This tutorial provides an introduction to the API and features of intake-thredds. Let’s begin by importing intake.

import intake

Loading a catalog#

You can load data from a THREDDS catalog by providing the URL to a valid THREDDS catalog:

cat_url = 'https://psl.noaa.gov/thredds/catalog/Datasets/noaa.ersst/catalog.xml'
catalog = intake.open_thredds_cat(cat_url, name='noaa-ersst-catalog')
catalog
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm
noaa-ersst-catalog:
  args:
    name: noaa-ersst-catalog
    url: https://psl.noaa.gov/thredds/catalog/Datasets/noaa.ersst/catalog.xml
  description: ''
  driver: intake_thredds.cat.ThreddsCatalog
  metadata:
    dataType: Grid
    inherited: true
    serviceName: all

Using the catalog#

Once you’ve loaded a catalog, you can display its contents by iterating over its entries:

list(catalog)
['err.mnmean.v3.nc',
 'sst.mnmean.v3.nc',
 'sst.mnmean.v4.nc',
 'sst.mon.1971-2000.ltm.v4.nc',
 'sst.mon.19712000.ltm.v3.nc',
 'sst.mon.1981-2010.ltm.v3.nc',
 'sst.mon.1981-2010.ltm.v4.nc',
 'sst.mon.v4.ltm.1971-2000.nc',
 'sst.mon.v4.ltm.1981-2010.nc',
 'sst.mon.v4.ltm.nc']

Once you’ve identified a dataset of interest, you can access it as follows:

source = catalog['err.mnmean.v3.nc']
print(source)
sources:
  err.mnmean.v3.nc:
    args:
      chunks: {}
      urlpath: https://psl.noaa.gov/thredds/dodsC/Datasets/noaa.ersst/err.mnmean.v3.nc
    description: THREDDS data
    driver: intake_xarray.opendap.OpenDapSource
    metadata:
      catalog_dir: null

Loading a dataset#

To load a dataset of interest, you can use the to_dask() method which is available on a source object:

%%time
ds = source().to_dask()
ds
CPU times: user 454 ms, sys: 16.5 ms, total: 470 ms
Wall time: 2.71 s
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),
<xarray.Dataset> Size: 128MB
Dimensions:    (lat: 89, lon: 180, time: 1994, nbnds: 2)
Coordinates:
  * lat        (lat) float32 356B 88.0 86.0 84.0 82.0 ... -84.0 -86.0 -88.0
  * lon        (lon) float32 720B 0.0 2.0 4.0 6.0 ... 352.0 354.0 356.0 358.0
  * time       (time) datetime64[ns] 16kB 1854-01-01 1854-02-01 ... 2020-02-01
Dimensions without coordinates: nbnds
Data variables:
    time_bnds  (time, nbnds) float64 32kB dask.array<chunksize=(1994, 2), meta=np.ndarray>
    err        (time, lat, lon) float32 128MB dask.array<chunksize=(1994, 89, 180), meta=np.ndarray>
Attributes: (12/13)
    title:                           NOAA Extended Reconstructed SST V3
    Conventions:                     CF-1.0
    history:                         Thu Jul  1 14:04:15 2010: ncatted -O -a ...
    comments:                        The extended reconstructed sea surface t...
    platform:                        Model
    source:                          NOAA/NESDIS/National Climatic Data Center
    ...                              ...
    citation:                        Smith, T.M., R.W. Reynolds, Thomas C. Pe...
    dataset_title:                   Extended Reconstructed Sea Surface Tempe...
    source_doc:                      https://www.ncdc.noaa.gov/data-access/ma...
    _NCProperties:                   version=2,netcdf=4.6.3,hdf5=1.10.5
    References:                      https://www.psl.noaa.gov/data/gridded/da...
    DODS_EXTRA.Unlimited_Dimension:  time

The to_dask() reads only metadata needed to construct an xarray.Dataset. The actual data are streamed over the network when computation routines are invoked on the dataset. By default, intake-thredds uses chunks={} to load the dataset with dask using a single chunk for all arrays. You can use a different chunking scheme by prividing a custom value of chunks before calling .to_dask():

%%time
# Use a custom chunking scheme
ds = source(chunks={'time': 100, 'lon': 90}).to_dask()
ds
CPU times: user 245 ms, sys: 5.74 ms, total: 250 ms
Wall time: 2.48 s
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),
<xarray.Dataset> Size: 128MB
Dimensions:    (lat: 89, lon: 180, time: 1994, nbnds: 2)
Coordinates:
  * lat        (lat) float32 356B 88.0 86.0 84.0 82.0 ... -84.0 -86.0 -88.0
  * lon        (lon) float32 720B 0.0 2.0 4.0 6.0 ... 352.0 354.0 356.0 358.0
  * time       (time) datetime64[ns] 16kB 1854-01-01 1854-02-01 ... 2020-02-01
Dimensions without coordinates: nbnds
Data variables:
    time_bnds  (time, nbnds) float64 32kB dask.array<chunksize=(100, 2), meta=np.ndarray>
    err        (time, lat, lon) float32 128MB dask.array<chunksize=(100, 89, 90), meta=np.ndarray>
Attributes: (12/13)
    title:                           NOAA Extended Reconstructed SST V3
    Conventions:                     CF-1.0
    history:                         Thu Jul  1 14:04:15 2010: ncatted -O -a ...
    comments:                        The extended reconstructed sea surface t...
    platform:                        Model
    source:                          NOAA/NESDIS/National Climatic Data Center
    ...                              ...
    citation:                        Smith, T.M., R.W. Reynolds, Thomas C. Pe...
    dataset_title:                   Extended Reconstructed Sea Surface Tempe...
    source_doc:                      https://www.ncdc.noaa.gov/data-access/ma...
    _NCProperties:                   version=2,netcdf=4.6.3,hdf5=1.10.5
    References:                      https://www.psl.noaa.gov/data/gridded/da...
    DODS_EXTRA.Unlimited_Dimension:  time

Working with nested catalogs#

In some scenarious, a THREDDS catalog can reference another THREDDS catalog. This results into a nested structure consisting of a parent catalog and children catalogs:

cat_url = 'https://psl.noaa.gov/thredds/catalog.xml'
catalog = intake.open_thredds_cat(cat_url)
list(catalog)
['Datasets', 'Projects', 'Aggregations']
print(list(catalog['Datasets']))
['20thC_ReanV2', '20thC_ReanV2c', '20thC_ReanV3', 'ATOMIC', 'COBE', 'COBE2', 'CarbonTracker', 'E3SM', 'E3SM_LE', 'ICOADS3.0.0_2015-2021', 'LIM', 'NARR', 'S2S', 'SERDP_regimeshifts', 'Timeseries', 'cmap', 'cmems', 'coads', 'cpc_blended_olr-1deg', 'cpc_blended_olr-2.5deg', 'cpc_global_precip', 'cpc_global_temp', 'cpc_us_hour_precip', 'cpc_us_precip', 'cpcsoil', 'cru', 'dai_pdsi', 'ghcncams', 'ghcngridded', 'gistemp', 'godas', 'gpcc', 'gpcp', 'icoads', 'icoads2.5', 'interp_OLR', 'jmatemp', 'kaplan_sst', 'livneh', 'marinehw', 'mlost', 'mlostv3b', 'ncep', 'ncep.marine', 'ncep.pac.ocean', 'ncep.reanalysis', 'ncep.reanalysis.dailyavgs', 'ncep.reanalysis.derived', 'ncep.reanalysis2', 'ncep.reanalysis2.dailyavgs', 'ncep.reanalysis2.derived', 'noaa.ersst', 'noaa.ersst.v3', 'noaa.ersst.v4', 'noaa.ersst.v5', 'noaa.oisst.v2', 'noaa.oisst.v2.derived', 'noaa.oisst.v2.highres', 'noaa_hrc', 'noaaglobaltemp', 'noaamergedtemp', 'nodc.woa94', 'nodc.woa98', 'olrcdr', 'prec', 'precl', 'rte-rrtmgp', 'snowcover', 'udel.airt.precip', 'uninterp_OLR']
print(list(catalog['Datasets']['ncep.reanalysis.dailyavgs']))
['other_gauss', 'pressure', 'surface', 'surface_gauss', 'tropopause']

To load data from such a nested catalog, intake-thredds provides a special source object THREDDSMergedSource accessible via the .open_thredds_merged() function. The inputs for this function consists of:

  • url: top level URL of the THREDDS catalog

  • path: a list of paths for child catalogs to descend down. The paths can include glob characters (*, ?). These glob characters are used for matching.

source = intake.open_thredds_merged(
    cat_url, path=['Datasets', 'ncep.reanalysis.dailyavgs', 'surface', 'air*sig995*194*.nc']
)
print(source)
sources:
  thredds_merged:
    args:
      path:
      - Datasets
      - ncep.reanalysis.dailyavgs
      - surface
      - air*sig995*194*.nc
      url: https://psl.noaa.gov/thredds/catalog.xml
    description: ''
    driver: intake_thredds.source.THREDDSMergedSource
    metadata: {}

To load the data into an xarray Dataset, you can invoke the .to_dask() method. Internally, THREDDSMergedSource does the following:

  • descend down the given paths and collect all available datasets.

  • load each dataset in a dataset.

  • combine all loaded datasets into a single dataset.

%%time
ds = source.to_dask()
ds
Dataset(s):   0%|                                        | 0/2 [00:00<?, ?it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  50%|████████████████                | 1/2 [00:02<00:02,  2.43s/it]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s): 100%|████████████████████████████████| 2/2 [00:04<00:00,  2.44s/it]
Dataset(s): 100%|████████████████████████████████| 2/2 [00:04<00:00,  2.44s/it]
CPU times: user 904 ms, sys: 34.9 ms, total: 939 ms
Wall time: 6.49 s
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),
<xarray.Dataset> Size: 31MB
Dimensions:    (lon: 144, time: 731, lat: 73, nbnds: 2)
Coordinates:
  * lon        (lon) float32 576B 0.0 2.5 5.0 7.5 ... 350.0 352.5 355.0 357.5
  * time       (time) datetime64[ns] 6kB 1948-01-01 1948-01-02 ... 1949-12-31
  * lat        (lat) float32 292B 90.0 87.5 85.0 82.5 ... -85.0 -87.5 -90.0
Dimensions without coordinates: nbnds
Data variables:
    air        (time, lat, lon) float32 31MB dask.array<chunksize=(366, 73, 144), meta=np.ndarray>
    time_bnds  (time, nbnds) float64 12kB dask.array<chunksize=(366, 2), meta=np.ndarray>
Attributes:
    Conventions:                     COARDS
    title:                           mean daily NMC reanalysis (1948)
    description:                     Data is from NMC initialized reanalysis\...
    platform:                        Model
    history:                         created 99/05/11 by Hoop (netCDF2.3)\nCo...
    dataset_title:                   NCEP-NCAR Reanalysis 1
    References:                      http://www.psl.noaa.gov/data/gridded/dat...
    _NCProperties:                   version=2,netcdf=4.6.3,hdf5=1.10.5
    DODS_EXTRA.Unlimited_Dimension:  time

Caching#

Under the hood intake-thredds uses the driver='opendap' from intake-xarray by default. You can also choose driver='netcdf', which in combination with fsspec caches files by appending simplecache:: to the url, see fsspec docs.

import os

import fsspec

# specify caching location, where to store files to with their original names
fsspec.config.conf['simplecache'] = {'cache_storage': 'my_caching_folder', 'same_names': True}

cat_url = 'https://psl.noaa.gov/thredds/catalog.xml'
source = intake.open_thredds_merged(
    f'simplecache::{cat_url}',
    path=['Datasets', 'ncep.reanalysis.dailyavgs', 'surface', 'air.sig995.194*.nc'],
    driver='netcdf',  # specify netcdf driver to open HTTPServer
)
print(source)
sources:
  thredds_merged:
    args:
      driver: netcdf
      path:
      - Datasets
      - ncep.reanalysis.dailyavgs
      - surface
      - air.sig995.194*.nc
      url: simplecache::https://psl.noaa.gov/thredds/catalog.xml
    description: ''
    driver: intake_thredds.source.THREDDSMergedSource
    metadata:
      fsspec_pre_url: 'simplecache::'
%time ds = source.to_dask()
Dataset(s):   0%|                                        | 0/2 [00:00<?, ?it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  50%|████████████████                | 1/2 [00:00<00:00,  1.60it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s): 100%|████████████████████████████████| 2/2 [00:00<00:00,  2.66it/s]
Dataset(s): 100%|████████████████████████████████| 2/2 [00:00<00:00,  2.42it/s]
CPU times: user 568 ms, sys: 58.7 ms, total: 626 ms
Wall time: 2.39 s
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),
assert os.path.exists('my_caching_folder/air.sig995.1949.nc')
# after caching very fast
%time ds = source.to_dask()
CPU times: user 6 µs, sys: 0 ns, total: 6 µs
Wall time: 8.82 µs

Multi-file concat_kwargs with cfgrib engine#

Another example demonstrating how to use caching consists of reading in ensemble members in parallel for GEFS. The example below reads in 21 ensemble members for a single timestep. It also demonstrates usage of xarray_kwargs which are passed on to xarray for opening the files, which in this cases uses the cfgrib engine:

cat_url = 'https://www.ncei.noaa.gov/thredds/catalog/model-gefs-003/202008/20200831/catalog.xml'
source = intake.open_thredds_merged(
    f'simplecache::{cat_url}',
    path=["NCEP gens-a Grid 3 Member-Forecast *-372 for 2020-08-31 00:00*"],
    driver="netcdf",
    concat_kwargs={"dim": "number"},
    xarray_kwargs=dict(
        engine="cfgrib",
        backend_kwargs=dict(
            filter_by_keys={"typeOfLevel": "heightAboveGround", "cfVarName": "t2m"}
        ),
    ),
)
source.to_dask()
Dataset(s):   0%|                                       | 0/21 [00:00<?, ?it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):   5%|█▍                             | 1/21 [00:00<00:18,  1.08it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  10%|██▉                            | 2/21 [00:01<00:14,  1.30it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  14%|████▍                          | 3/21 [00:02<00:12,  1.45it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  19%|█████▉                         | 4/21 [00:02<00:11,  1.53it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  24%|███████▍                       | 5/21 [00:03<00:09,  1.60it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  29%|████████▊                      | 6/21 [00:03<00:09,  1.62it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  33%|██████████▎                    | 7/21 [00:04<00:08,  1.63it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  38%|███████████▊                   | 8/21 [00:05<00:07,  1.65it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  43%|█████████████▎                 | 9/21 [00:05<00:07,  1.68it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  48%|██████████████▎               | 10/21 [00:06<00:06,  1.68it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  52%|███████████████▋              | 11/21 [00:07<00:07,  1.43it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  57%|█████████████████▏            | 12/21 [00:07<00:06,  1.50it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  62%|██████████████████▌           | 13/21 [00:08<00:05,  1.54it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  67%|████████████████████          | 14/21 [00:09<00:04,  1.54it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  71%|█████████████████████▍        | 15/21 [00:09<00:03,  1.60it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  76%|██████████████████████▊       | 16/21 [00:10<00:03,  1.62it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  81%|████████████████████████▎     | 17/21 [00:10<00:02,  1.64it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  86%|█████████████████████████▋    | 18/21 [00:11<00:01,  1.65it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  90%|███████████████████████████▏  | 19/21 [00:12<00:01,  1.60it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s):  95%|████████████████████████████▌ | 20/21 [00:12<00:00,  1.62it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),

Dataset(s): 100%|██████████████████████████████| 21/21 [00:13<00:00,  1.65it/s]
Dataset(s): 100%|██████████████████████████████| 21/21 [00:13<00:00,  1.58it/s]
/home/docs/checkouts/readthedocs.org/user_builds/intake-thredds/conda/latest/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  'dims': dict(self._ds.dims),
<xarray.Dataset> Size: 5MB
Dimensions:            (number: 21, latitude: 181, longitude: 360)
Coordinates:
  * number             (number) int64 168B 20 19 18 17 16 15 14 ... 5 4 3 2 1 0
    time               datetime64[ns] 8B 2020-08-31
    step               timedelta64[ns] 8B 15 days 12:00:00
    heightAboveGround  float64 8B 2.0
  * latitude           (latitude) float64 1kB 90.0 89.0 88.0 ... -89.0 -90.0
  * longitude          (longitude) float64 3kB 0.0 1.0 2.0 ... 357.0 358.0 359.0
    valid_time         datetime64[ns] 8B 2020-09-15T12:00:00
Data variables:
    t2m                (number, latitude, longitude) float32 5MB dask.array<chunksize=(1, 181, 360), meta=np.ndarray>
Attributes:
    GRIB_edition:            2
    GRIB_centre:             kwbc
    GRIB_centreDescription:  US National Weather Service - NCEP
    GRIB_subCentre:          2
    Conventions:             CF-1.7
    institution:             US National Weather Service - NCEP
    history:                 2024-04-01T18:19 GRIB to CDM+CF via cfgrib-0.9.1...