Note

Download this example as a Jupyter notebook here: https://github.com/pypsa/atlite/examples/create_cutout.ipynb

Creating a Cutout with ERA5

In this example we download ERA5 data on-demand for a cutout we want to create. (Atlite does also work with other datasources, but ERA5 is the easiest one to get started.)

This only works if you have in before

  • Installed the Copernicus Climate Data Store cdsapi package

  • Registered and setup your CDS API key as described on their website here

Import the package first:

[1]:
import atlite
Disable urllib3 and cdsapi warnings.

We implement notifications in atlite using loggers from the logging library.

We recommend you always launch a logger to get information on what is going on. For debugging, you can use the more verbose level=logging.DEBUG:

[2]:
import logging
logging.basicConfig(level=logging.INFO)

Defining the Cutout extent

This will not yet trigger any major operations.

A cutout is the basis for any of your work and calculations.

The cutout is created in the directory and file specified by the relative path If a cutout at the given location already exists, then this command will simply load the cutout again. If the cutout does not yet exist, it will specify the new to-be-created cutout.

[3]:
cutout = atlite.Cutout(path="western-europe-2011-01.nc",
                       module="era5",
                       x=slice(-13.6913, 1.7712),
                       y=slice(49.9096, 60.8479),
                       time="2011-01"
                       )
INFO:atlite.cutout:Building new cutout western-europe-2011-01.nc

For creating the cutout, you need to specify

  • The dataset to create the cutout with (era5)

  • The time period it covers

  • The longitude x and latitude y it stretches

Here we went with the ERA5 dataset from ECMWF

module="era5"

Here we decided to provide the time period of the cutout as a string, because it is only a month. You could have also specify it as a time range

slice("2011-01","2011-01")

The regional bounds (space the cutout stretches) where specified by the

x=slice(-13.6913, 1.7712) # Longitude
y=slice(49.9096, 60.8479) # Latitude

and describe a rectangle’s edges. In this case we drew a rectangle containing some parts of the atlantic ocean, the Republic of Ireland and the UK.

Preparing the Cutout

If the cutout does not yet exist or has some features which are not yet included (“The cutout is not prepared”), then we have to tell atlite to go ahead an do so.

No matter which dataset you use, this is where all the work actually happens. This can be fast or take some or a lot of time and resources, among others depending on your computer ressources and (for downloading e.g. ERA5 data) your internet connection.

[4]:
cutout.prepare()
INFO:atlite.data:Calculating and writing with module era5:
INFO:atlite.datasets.era5:Downloading data for feature 'height' to /tmp/tmp6cca5m4s.
INFO:atlite.datasets.era5:Downloading data for feature 'wind' to /tmp/tmp6cca5m4s.
[########################################] | 100% Completed |  6.2s
INFO:atlite.datasets.era5:Downloading data for feature 'influx' to /tmp/tmp6cca5m4s.
[########################################] | 100% Completed |  4.8s
INFO:atlite.datasets.era5:Downloading data for feature 'temperature' to /tmp/tmp6cca5m4s.
[########################################] | 100% Completed |  5.5s
INFO:atlite.datasets.era5:Downloading data for feature 'runoff' to /tmp/tmp6cca5m4s.
[########################################] | 100% Completed |  2.9s
[########################################] | 100% Completed |  2.7s
[4]:
<Cutout "western-europe-2011-01">
 x = -13.50 ⟷ 1.75, dx = 0.25
 y = 50.00 ⟷ 60.75, dy = 0.25
 time = 2011-01-01 ⟷ 2011-01-31, dt = H
 prepared_features = ['height', 'wind', 'influx', 'temperature', 'runoff']

Querying the cutout gives us some basic information on which data is contained in it an can already be used.

[5]:
cutout
[5]:
<Cutout "western-europe-2011-01">
 x = -13.50 ⟷ 1.75, dx = 0.25
 y = 50.00 ⟷ 60.75, dy = 0.25
 time = 2011-01-01 ⟷ 2011-01-31, dt = H
 prepared_features = ['height', 'wind', 'influx', 'temperature', 'runoff']

We can access some information more specifically

[6]:
cutout.prepared_features
[6]:
module  feature
era5    height                   height
        wind                    wnd100m
        wind                  roughness
        influx               influx_toa
        influx            influx_direct
        influx           influx_diffuse
        influx                   albedo
        temperature         temperature
        temperature    soil temperature
        runoff                   runoff
Name: variables, dtype: object

And the metadata used to create the cutout

[7]:
cutout.data.attrs
[7]:
{'module': 'era5',
 'prepared_features': ['runoff', 'temperature', 'wind', 'influx', 'height'],
 'chunksize_time': 20}

We can access the underlying data (as a xarray). This library implements lazy loading, so while we can preview the data, it is usually only partially or fully loaded when we request specific information or do operations on a whole feature parameter. Information not loaded is indicated by the ...:

[8]:
cutout.data
[8]:
Show/Hide data repr Show/Hide attributes
xarray.Dataset
    • time: 744
    • x: 62
    • y: 44
    • lon
      (x)
      float32
      dask.array<chunksize=(62,), meta=np.ndarray>
      units :
      degrees_east
      long_name :
      longitude
      Array Chunk
      Bytes 248 B 248 B
      Shape (62,) (62,)
      Count 2 Tasks 1 Chunks
      Type float32 numpy.ndarray
      62 1
    • time
      (time)
      datetime64[ns]
      2011-01-01 ... 2011-01-31T23:00:00
      long_name :
      time
      array(['2011-01-01T00:00:00.000000000', '2011-01-01T01:00:00.000000000',
             '2011-01-01T02:00:00.000000000', ..., '2011-01-31T21:00:00.000000000',
             '2011-01-31T22:00:00.000000000', '2011-01-31T23:00:00.000000000'],
            dtype='datetime64[ns]')
    • y
      (y)
      float32
      50.0 50.25 50.5 ... 60.5 60.75
      units :
      degrees_north
      long_name :
      latitude
      array([50.  , 50.25, 50.5 , 50.75, 51.  , 51.25, 51.5 , 51.75, 52.  , 52.25,
             52.5 , 52.75, 53.  , 53.25, 53.5 , 53.75, 54.  , 54.25, 54.5 , 54.75,
             55.  , 55.25, 55.5 , 55.75, 56.  , 56.25, 56.5 , 56.75, 57.  , 57.25,
             57.5 , 57.75, 58.  , 58.25, 58.5 , 58.75, 59.  , 59.25, 59.5 , 59.75,
             60.  , 60.25, 60.5 , 60.75], dtype=float32)
    • x
      (x)
      float32
      -13.5 -13.25 -13.0 ... 1.5 1.75
      units :
      degrees_east
      long_name :
      longitude
      array([-13.5 , -13.25, -13.  , -12.75, -12.5 , -12.25, -12.  , -11.75, -11.5 ,
             -11.25, -11.  , -10.75, -10.5 , -10.25, -10.  ,  -9.75,  -9.5 ,  -9.25,
              -9.  ,  -8.75,  -8.5 ,  -8.25,  -8.  ,  -7.75,  -7.5 ,  -7.25,  -7.  ,
              -6.75,  -6.5 ,  -6.25,  -6.  ,  -5.75,  -5.5 ,  -5.25,  -5.  ,  -4.75,
              -4.5 ,  -4.25,  -4.  ,  -3.75,  -3.5 ,  -3.25,  -3.  ,  -2.75,  -2.5 ,
              -2.25,  -2.  ,  -1.75,  -1.5 ,  -1.25,  -1.  ,  -0.75,  -0.5 ,  -0.25,
               0.  ,   0.25,   0.5 ,   0.75,   1.  ,   1.25,   1.5 ,   1.75],
            dtype=float32)
    • lat
      (y)
      float32
      dask.array<chunksize=(44,), meta=np.ndarray>
      units :
      degrees_north
      long_name :
      latitude
      Array Chunk
      Bytes 176 B 176 B
      Shape (44,) (44,)
      Count 2 Tasks 1 Chunks
      Type float32 numpy.ndarray
      44 1
    • height
      (y, x)
      float32
      dask.array<chunksize=(44, 62), meta=np.ndarray>
      module :
      era5
      Array Chunk
      Bytes 10.91 kB 10.91 kB
      Shape (44, 62) (44, 62)
      Count 2 Tasks 1 Chunks
      Type float32 numpy.ndarray
      62 44
    • wnd100m
      (time, y, x)
      float32
      dask.array<chunksize=(20, 44, 62), meta=np.ndarray>
      units :
      m s**-1
      long_name :
      100 metre wind speed
      module :
      era5
      Array Chunk
      Bytes 8.12 MB 218.24 kB
      Shape (744, 44, 62) (20, 44, 62)
      Count 39 Tasks 38 Chunks
      Type float32 numpy.ndarray
      62 44 744
    • roughness
      (time, y, x)
      float32
      dask.array<chunksize=(20, 44, 62), meta=np.ndarray>
      units :
      m
      long_name :
      Forecast surface roughness
      module :
      era5
      Array Chunk
      Bytes 8.12 MB 218.24 kB
      Shape (744, 44, 62) (20, 44, 62)
      Count 39 Tasks 38 Chunks
      Type float32 numpy.ndarray
      62 44 744
    • influx_toa
      (time, y, x)
      float32
      dask.array<chunksize=(20, 44, 62), meta=np.ndarray>
      units :
      W m**-2
      module :
      era5
      Array Chunk
      Bytes 8.12 MB 218.24 kB
      Shape (744, 44, 62) (20, 44, 62)
      Count 39 Tasks 38 Chunks
      Type float32 numpy.ndarray
      62 44 744
    • influx_direct
      (time, y, x)
      float32
      dask.array<chunksize=(20, 44, 62), meta=np.ndarray>
      units :
      W m**-2
      module :
      era5
      Array Chunk
      Bytes 8.12 MB 218.24 kB
      Shape (744, 44, 62) (20, 44, 62)
      Count 39 Tasks 38 Chunks
      Type float32 numpy.ndarray
      62 44 744
    • influx_diffuse
      (time, y, x)
      float32
      dask.array<chunksize=(20, 44, 62), meta=np.ndarray>
      units :
      W m**-2
      module :
      era5
      Array Chunk
      Bytes 8.12 MB 218.24 kB
      Shape (744, 44, 62) (20, 44, 62)
      Count 39 Tasks 38 Chunks
      Type float32 numpy.ndarray
      62 44 744
    • albedo
      (time, y, x)
      float32
      dask.array<chunksize=(20, 44, 62), meta=np.ndarray>
      units :
      (0 - 1)
      long_name :
      Albedo
      module :
      era5
      Array Chunk
      Bytes 8.12 MB 218.24 kB
      Shape (744, 44, 62) (20, 44, 62)
      Count 39 Tasks 38 Chunks
      Type float32 numpy.ndarray
      62 44 744
    • temperature
      (time, y, x)
      float32
      dask.array<chunksize=(20, 44, 62), meta=np.ndarray>
      units :
      K
      long_name :
      2 metre temperature
      module :
      era5
      Array Chunk
      Bytes 8.12 MB 218.24 kB
      Shape (744, 44, 62) (20, 44, 62)
      Count 39 Tasks 38 Chunks
      Type float32 numpy.ndarray
      62 44 744
    • soil temperature
      (time, y, x)
      float32
      dask.array<chunksize=(20, 44, 62), meta=np.ndarray>
      units :
      K
      long_name :
      Soil temperature level 4
      module :
      era5
      Array Chunk
      Bytes 8.12 MB 218.24 kB
      Shape (744, 44, 62) (20, 44, 62)
      Count 39 Tasks 38 Chunks
      Type float32 numpy.ndarray
      62 44 744
    • runoff
      (time, y, x)
      float32
      dask.array<chunksize=(20, 44, 62), meta=np.ndarray>
      module :
      era5
      Array Chunk
      Bytes 8.12 MB 218.24 kB
      Shape (744, 44, 62) (20, 44, 62)
      Count 39 Tasks 38 Chunks
      Type float32 numpy.ndarray
      62 44 744
  • module :
    era5
    prepared_features :
    ['runoff', 'temperature', 'wind', 'influx', 'height']
    chunksize_time :
    20

If you have matplotlib installed, you can directly use the plotting functionality from xarray to plot features from the cutout’s data.

Warning: This will trigger xarray to load all the height data from disk into memory!