06 - Spatial Regridding and masking data cubes¶

A DeepESDL example notebook¶

This notebook demonstrates how to access two different data sets, transform one of them so that both share the same spatial grid, and mask one dataset by applying a condition from the other dataset.

Please, also refer to the DeepESDL documentation and visit the platform's website for further information!

Brockmann Consult, 2023


This notebook runs with the python environment deepesdl-xcube-1.1.2, please checkout the documentation for help on changing the environment.

In [1]:
# mandatory imports
from xcube.core.gridmapping import GridMapping
from xcube.core.resampling import resample_in_space
from xcube.core.store import new_data_store
from IPython.display import JSON
import numpy as np
import xarray as xr
import datetime

Open CCI store

In [2]:
cci_store = new_data_store('cciodp')

Open s3 store and list all datasets

In [3]:
root = "deep-esdl-public"
In [4]:
s3_store = new_data_store("s3", root=root)
In [5]:
list(s3_store.get_data_ids())
Out[5]:
['LC-1x2160x2160-1.0.0.levels',
 'SMOS-freezethaw-1x720x720-1.0.1.zarr',
 'SMOS-freezethaw-4267x10x10-1.0.1.zarr',
 'black-sea-1x1024x1024.levels',
 'black-sea-256x128x128.zarr',
 'esa-cci-permafrost-1x1151x1641-0.0.2.levels',
 'esdc-8d-0.25deg-1x720x1440-3.0.1.zarr',
 'esdc-8d-0.25deg-256x128x128-3.0.1.zarr',
 'ocean-1M-9km-1x1080x1080-1.4.0.levels',
 'ocean-1M-9km-64x256x256-1.4.0.zarr',
 'polar-100m-1x2048x2048-1.0.1.zarr']

Open Land Cover (LC) dataset from s3 bucket, which is saved as a multilevel dataset:

In [6]:
ml_LC = s3_store.open_data('LC-1x2160x2160-1.0.0.levels', decode_cf = True)

Lets open level 0, which is the base level and therefor has the highest resolution:

In [9]:
LC = ml_LC.get_dataset(0)
In [10]:
LC
Out[10]:
<xarray.Dataset>
Dimensions:              (time: 11, lat: 64800, lon: 129600, bounds: 2)
Coordinates:
  * lat                  (lat) float64 90.0 90.0 89.99 ... -89.99 -90.0 -90.0
  * lon                  (lon) float64 -180.0 -180.0 -180.0 ... 180.0 180.0
  * time                 (time) datetime64[ns] 2010-01-01 ... 2020-01-01
Dimensions without coordinates: bounds
Data variables:
    change_count         (time, lat, lon) uint8 dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
    crs                  (time) int32 dask.array<chunksize=(11,), meta=np.ndarray>
    current_pixel_state  (time, lat, lon) float32 dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
    lat_bounds           (time, lat, bounds) float64 dask.array<chunksize=(1, 2160, 2), meta=np.ndarray>
    lccs_class           (time, lat, lon) uint8 dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
    lon_bounds           (time, lon, bounds) float64 dask.array<chunksize=(1, 2160, 2), meta=np.ndarray>
    observation_count    (time, lat, lon) uint16 dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
    processed_flag       (time, lat, lon) float32 dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
    time_bounds          (time, bounds) datetime64[ns] dask.array<chunksize=(1, 2), meta=np.ndarray>
Attributes: (12/38)
    Conventions:                CF-1.6
    TileSize:                   2025:2025
    cdm_data_type:              grid
    comment:                    
    contact:                    https://www.ecmwf.int/en/about/contact-us/get...
    creation_date:              20181130T095431Z
    ...                         ...
    time_coverage_end:          20101231
    time_coverage_resolution:   P1Y
    time_coverage_start:        20100101
    title:                      Land Cover Map of ESA CCI brokered by CDS
    tracking_id:                96ac9aca-1ca7-45c6-b4a5-ab448c692646
    type:                       ESACCI-LC-L4-LCCS-Map-300m-P1Y
xarray.Dataset
    • time: 11
    • lat: 64800
    • lon: 129600
    • bounds: 2
    • lat
      (lat)
      float64
      90.0 90.0 89.99 ... -90.0 -90.0
      axis :
      Y
      bounds :
      lat_bounds
      long_name :
      latitude
      standard_name :
      latitude
      units :
      degrees_north
      valid_max :
      90.0
      valid_min :
      -90.0
      array([ 89.998611,  89.995833,  89.993056, ..., -89.993056, -89.995833,
             -89.998611])
    • lon
      (lon)
      float64
      -180.0 -180.0 ... 180.0 180.0
      axis :
      X
      bounds :
      lon_bounds
      long_name :
      longitude
      standard_name :
      longitude
      units :
      degrees_east
      valid_max :
      180.0
      valid_min :
      -180.0
      array([-179.998611, -179.995833, -179.993056, ...,  179.993056,  179.995833,
              179.998611])
    • time
      (time)
      datetime64[ns]
      2010-01-01 ... 2020-01-01
      axis :
      T
      bounds :
      time_bounds
      long_name :
      time
      standard_name :
      time
      array(['2010-01-01T00:00:00.000000000', '2011-01-01T00:00:00.000000000',
             '2012-01-01T00:00:00.000000000', '2013-01-01T00:00:00.000000000',
             '2014-01-01T00:00:00.000000000', '2015-01-01T00:00:00.000000000',
             '2016-01-01T00:00:00.000000000', '2017-01-01T00:00:00.000000000',
             '2018-01-01T00:00:00.000000000', '2019-01-01T00:00:00.000000000',
             '2020-01-01T00:00:00.000000000'], dtype='datetime64[ns]')
    • change_count
      (time, lat, lon)
      uint8
      dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
      long_name :
      number of class changes
      valid_max :
      100
      valid_min :
      0
      Array Chunk
      Bytes 86.03 GiB 4.45 MiB
      Shape (11, 64800, 129600) (1, 2160, 2160)
      Dask graph 19800 chunks in 2 graph layers
      Data type uint8 numpy.ndarray
      129600 64800 11
    • crs
      (time)
      int32
      dask.array<chunksize=(11,), meta=np.ndarray>
      i2m :
      0.002777777777778,0.0,0.0,-0.002777777777778,-180.0,90.0
      wkt :
      GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]]
      Array Chunk
      Bytes 44 B 44 B
      Shape (11,) (11,)
      Dask graph 1 chunks in 2 graph layers
      Data type int32 numpy.ndarray
      11 1
    • current_pixel_state
      (time, lat, lon)
      float32
      dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
      flag_meanings :
      invalid clear_land clear_water clear_snow_ice cloud cloud_shadow
      flag_values :
      [0, 1, 2, 3, 4, 5]
      long_name :
      LC pixel type mask
      standard_name :
      land_cover_lccs status_flag
      valid_max :
      5
      valid_min :
      0
      Array Chunk
      Bytes 344.14 GiB 17.80 MiB
      Shape (11, 64800, 129600) (1, 2160, 2160)
      Dask graph 19800 chunks in 2 graph layers
      Data type float32 numpy.ndarray
      129600 64800 11
    • lat_bounds
      (time, lat, bounds)
      float64
      dask.array<chunksize=(1, 2160, 2), meta=np.ndarray>
      Array Chunk
      Bytes 10.88 MiB 33.75 kiB
      Shape (11, 64800, 2) (1, 2160, 2)
      Dask graph 330 chunks in 2 graph layers
      Data type float64 numpy.ndarray
      2 64800 11
    • lccs_class
      (time, lat, lon)
      uint8
      dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
      ancillary_variables :
      processed_flag current_pixel_state observation_count change_count
      flag_colors :
      #ffff64 #ffff64 #ffff00 #aaf0f0 #dcf064 #c8c864 #006400 #00a000 #00a000 #aac800 #003c00 #003c00 #005000 #285000 #285000 #286400 #788200 #8ca000 #be9600 #966400 #966400 #966400 #ffb432 #ffdcd2 #ffebaf #ffc864 #ffd278 #ffebaf #00785a #009678 #00dc82 #c31400 #fff5d7 #dcdcdc #fff5d7 #0046c8 #ffffff
      flag_meanings :
      no_data cropland_rainfed cropland_rainfed_herbaceous_cover cropland_rainfed_tree_or_shrub_cover cropland_irrigated mosaic_cropland mosaic_natural_vegetation tree_broadleaved_evergreen_closed_to_open tree_broadleaved_deciduous_closed_to_open tree_broadleaved_deciduous_closed tree_broadleaved_deciduous_open tree_needleleaved_evergreen_closed_to_open tree_needleleaved_evergreen_closed tree_needleleaved_evergreen_open tree_needleleaved_deciduous_closed_to_open tree_needleleaved_deciduous_closed tree_needleleaved_deciduous_open tree_mixed mosaic_tree_and_shrub mosaic_herbaceous shrubland shrubland_evergreen shrubland_deciduous grassland lichens_and_mosses sparse_vegetation sparse_tree sparse_shrub sparse_herbaceous tree_cover_flooded_fresh_or_brakish_water tree_cover_flooded_saline_water shrub_or_herbaceous_cover_flooded urban bare_areas bare_areas_consolidated bare_areas_unconsolidated water snow_and_ice
      flag_values :
      [0, 10, 11, 12, 20, 30, 40, 50, 60, 61, 62, 70, 71, 72, 80, 81, 82, 90, 100, 110, 120, 121, 122, 130, 140, 150, 151, 152, 153, 160, 170, 180, 190, 200, 201, 202, 210, 220]
      long_name :
      Land cover class defined in LCCS
      standard_name :
      land_cover_lccs
      valid_max :
      220
      valid_min :
      1
      Array Chunk
      Bytes 86.03 GiB 4.45 MiB
      Shape (11, 64800, 129600) (1, 2160, 2160)
      Dask graph 19800 chunks in 2 graph layers
      Data type uint8 numpy.ndarray
      129600 64800 11
    • lon_bounds
      (time, lon, bounds)
      float64
      dask.array<chunksize=(1, 2160, 2), meta=np.ndarray>
      Array Chunk
      Bytes 21.75 MiB 33.75 kiB
      Shape (11, 129600, 2) (1, 2160, 2)
      Dask graph 660 chunks in 2 graph layers
      Data type float64 numpy.ndarray
      2 129600 11
    • observation_count
      (time, lat, lon)
      uint16
      dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
      long_name :
      number of valid observations
      standard_name :
      land_cover_lccs number_of_observations
      valid_max :
      32767
      valid_min :
      0
      Array Chunk
      Bytes 172.07 GiB 8.90 MiB
      Shape (11, 64800, 129600) (1, 2160, 2160)
      Dask graph 19800 chunks in 2 graph layers
      Data type uint16 numpy.ndarray
      129600 64800 11
    • processed_flag
      (time, lat, lon)
      float32
      dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
      flag_meanings :
      not_processed processed
      flag_values :
      [0, 1]
      long_name :
      LC map processed area flag
      standard_name :
      land_cover_lccs status_flag
      valid_max :
      1
      valid_min :
      0
      Array Chunk
      Bytes 344.14 GiB 17.80 MiB
      Shape (11, 64800, 129600) (1, 2160, 2160)
      Dask graph 19800 chunks in 2 graph layers
      Data type float32 numpy.ndarray
      129600 64800 11
    • time_bounds
      (time, bounds)
      datetime64[ns]
      dask.array<chunksize=(1, 2), meta=np.ndarray>
      Array Chunk
      Bytes 176 B 16 B
      Shape (11, 2) (1, 2)
      Dask graph 11 chunks in 2 graph layers
      Data type datetime64[ns] numpy.ndarray
      2 11
    • lat
      PandasIndex
      PandasIndex(Float64Index([ 89.99861111111113,  89.99583333333334,  89.99305555555557,
                     89.99027777777778,  89.98750000000001,  89.98472222222222,
                     89.98194444444445,  89.97916666666669,  89.97638888888889,
                     89.97361111111113,
                    ...
                    -89.97361111111111, -89.97638888888889, -89.97916666666667,
                    -89.98194444444445, -89.98472222222222,           -89.9875,
                    -89.99027777777778, -89.99305555555556, -89.99583333333334,
                    -89.99861111111112],
                   dtype='float64', name='lat', length=64800))
    • lon
      PandasIndex
      PandasIndex(Float64Index([ -179.9986111111111, -179.99583333333334, -179.99305555555554,
                    -179.99027777777778,           -179.9875, -179.98472222222222,
                    -179.98194444444445, -179.97916666666666,  -179.9763888888889,
                     -179.9736111111111,
                    ...
                      179.9736111111111,   179.9763888888889,  179.97916666666669,
                     179.98194444444448,  179.98472222222222,            179.9875,
                      179.9902777777778,  179.99305555555554,  179.99583333333334,
                     179.99861111111113],
                   dtype='float64', name='lon', length=129600))
    • time
      PandasIndex
      PandasIndex(DatetimeIndex(['2010-01-01', '2011-01-01', '2012-01-01', '2013-01-01',
                     '2014-01-01', '2015-01-01', '2016-01-01', '2017-01-01',
                     '2018-01-01', '2019-01-01', '2020-01-01'],
                    dtype='datetime64[ns]', name='time', freq=None))
  • Conventions :
    CF-1.6
    TileSize :
    2025:2025
    cdm_data_type :
    grid
    comment :
    contact :
    https://www.ecmwf.int/en/about/contact-us/get-support
    creation_date :
    20181130T095431Z
    creator_email :
    landcover-cci@uclouvain.be
    creator_name :
    UCLouvain
    creator_url :
    http://www.uclouvain.be/
    geospatial_lat_max :
    90.0
    geospatial_lat_min :
    -90.0
    geospatial_lat_resolution :
    0.002778
    geospatial_lat_units :
    degrees_north
    geospatial_lon_max :
    180
    geospatial_lon_min :
    -180
    geospatial_lon_resolution :
    0.002778
    geospatial_lon_units :
    degrees_east
    history :
    amorgos-4,0, lc-sdr-1.0, lc-sr-1.0, lc-classification-1.0,lc-user-tools-3.13,lc-user-tools-4.3
    id :
    ESACCI-LC-L4-LCCS-Map-300m-P1Y-2010-v2.0.7cds
    institution :
    UCLouvain
    keywords :
    land cover classification,satellite,observation
    keywords_vocabulary :
    NASA Global Change Master Directory (GCMD) Science Keywords
    license :
    ESA CCI Data Policy: free and open access
    naming_authority :
    org.esa-cci
    product_version :
    2.0.7cds
    project :
    Climate Change Initiative - European Space Agency
    references :
    http://www.esa-landcover-cci.org/
    source :
    MERIS FR L1B version 5.05, MERIS RR L1B version 8.0, SPOT VGT P
    spatial_resolution :
    300m
    standard_name_vocabulary :
    NetCDF Climate and Forecast (CF) Standard Names version 21
    summary :
    This dataset characterizes the land cover of a particular year (see time_coverage). The land cover was derived from the analysis of satellite data time series of the full period.
    time_coverage_duration :
    P1Y
    time_coverage_end :
    20101231
    time_coverage_resolution :
    P1Y
    time_coverage_start :
    20100101
    title :
    Land Cover Map of ESA CCI brokered by CDS
    tracking_id :
    96ac9aca-1ca7-45c6-b4a5-ab448c692646
    type :
    ESACCI-LC-L4-LCCS-Map-300m-P1Y

Now let's search for fire datasets provided via the xcube cci store:

In [11]:
iterator = cci_store.search_data(cci_attrs=dict(ecv='FIRE'))
JSON([item.to_dict() for item in iterator])
/home/conda/deepesdl/4f055d4cb9f5a7bb59c11d4f960211d16d612f0f49fe5f6f4a110ccac09352f7-20230630-130445-100057-279-xcube-1.1.2/lib/python3.11/site-packages/xcube_cci/cciodp.py:1260: CciOdpWarning: Variable "vegetation_class_name" has no fill value, cannot set one. For parts where no data is available you will see random values. This is usually the case when data is missing for a time step.
  warnings.warn(f'Variable "{fixed_key}" has no fill value, '
Out[11]:
<IPython.core.display.JSON object>

Open Fire dataset from xcube cci store:

In [12]:
fire = cci_store.open_data('esacci.FIRE.mon.L4.BA.MODIS.Terra.MODIS_TERRA.v5-1.grid')
fire
/home/conda/deepesdl/4f055d4cb9f5a7bb59c11d4f960211d16d612f0f49fe5f6f4a110ccac09352f7-20230630-130445-100057-279-xcube-1.1.2/lib/python3.11/site-packages/xcube_cci/chunkstore.py:299: UserWarning: Variable 'vegetation_class_name' is encoded as string. Will omit it from the dataset.
  warnings.warn(f"Variable '{variable_name}' is encoded as "
Out[12]:
<xarray.Dataset>
Dimensions:                          (time: 240, lat: 720, lon: 1440,
                                      vegetation_class: 18, nv: 2, bnds: 2)
Coordinates:
  * lat                              (lat) float32 89.88 89.62 ... -89.62 -89.88
    lat_bnds                         (lat, nv) float32 dask.array<chunksize=(720, 2), meta=np.ndarray>
  * lon                              (lon) float32 -179.9 -179.6 ... 179.6 179.9
    lon_bnds                         (lon, nv) float32 dask.array<chunksize=(1440, 2), meta=np.ndarray>
  * time                             (time) datetime64[ns] 2001-01-16T12:00:0...
    time_bnds                        (time, bnds) datetime64[ns] dask.array<chunksize=(240, 2), meta=np.ndarray>
  * vegetation_class                 (vegetation_class) int32 10 20 ... 170 180
Dimensions without coordinates: nv, bnds
Data variables:
    burned_area                      (time, lat, lon) float32 dask.array<chunksize=(1, 720, 1440), meta=np.ndarray>
    burned_area_in_vegetation_class  (time, vegetation_class, lat, lon) float32 dask.array<chunksize=(1, 18, 360, 360), meta=np.ndarray>
    fraction_of_burnable_area        (time, lat, lon) float32 dask.array<chunksize=(1, 720, 1440), meta=np.ndarray>
    fraction_of_observed_area        (time, lat, lon) float32 dask.array<chunksize=(1, 720, 1440), meta=np.ndarray>
    number_of_patches                (time, lat, lon) float32 dask.array<chunksize=(1, 720, 1440), meta=np.ndarray>
    standard_error                   (time, lat, lon) float32 dask.array<chunksize=(1, 720, 1440), meta=np.ndarray>
Attributes:
    Conventions:             CF-1.7
    title:                   esacci.FIRE.mon.L4.BA.MODIS.Terra.MODIS_TERRA.v5...
    date_created:            2023-08-30T14:33:39.046347
    processing_level:        L4
    time_coverage_start:     2001-01-01T00:00:00
    time_coverage_end:       2021-01-01T00:00:00
    time_coverage_duration:  P7305DT0H0M0S
    history:                 [{'program': 'xcube_cci.chunkstore.CciChunkStore...
xarray.Dataset
    • time: 240
    • lat: 720
    • lon: 1440
    • vegetation_class: 18
    • nv: 2
    • bnds: 2
    • lat
      (lat)
      float32
      89.88 89.62 89.38 ... -89.62 -89.88
      units :
      degree_north
      standard_name :
      latitude
      long_name :
      latitude
      bounds :
      lat_bnds
      orig_data_type :
      float32
      fill_value :
      nan
      size :
      720
      shape :
      [720]
      chunk_sizes :
      [720]
      file_chunk_sizes :
      [720]
      data_type :
      float32
      dimensions :
      ['lat']
      file_dimensions :
      ['lat']
      array([ 89.875,  89.625,  89.375, ..., -89.375, -89.625, -89.875],
            dtype=float32)
    • lat_bnds
      (lat, nv)
      float32
      dask.array<chunksize=(720, 2), meta=np.ndarray>
      orig_data_type :
      float32
      fill_value :
      nan
      size :
      1440
      shape :
      [720, 2]
      chunk_sizes :
      [720, 2]
      file_chunk_sizes :
      [720, 2]
      data_type :
      float32
      dimensions :
      ['lat', 'nv']
      file_dimensions :
      ['lat', 'nv']
      Array Chunk
      Bytes 5.62 kiB 5.62 kiB
      Shape (720, 2) (720, 2)
      Dask graph 1 chunks in 2 graph layers
      Data type float32 numpy.ndarray
      2 720
    • lon
      (lon)
      float32
      -179.9 -179.6 ... 179.6 179.9
      units :
      degree_east
      standard_name :
      longitude
      long_name :
      longitude
      bounds :
      lon_bnds
      orig_data_type :
      float32
      fill_value :
      nan
      size :
      1440
      shape :
      [1440]
      chunk_sizes :
      [1440]
      file_chunk_sizes :
      [1440]
      data_type :
      float32
      dimensions :
      ['lon']
      file_dimensions :
      ['lon']
      array([-179.875, -179.625, -179.375, ...,  179.375,  179.625,  179.875],
            dtype=float32)
    • lon_bnds
      (lon, nv)
      float32
      dask.array<chunksize=(1440, 2), meta=np.ndarray>
      orig_data_type :
      float32
      fill_value :
      nan
      size :
      2880
      shape :
      [1440, 2]
      chunk_sizes :
      [1440, 2]
      file_chunk_sizes :
      [1440, 2]
      data_type :
      float32
      dimensions :
      ['lon', 'nv']
      file_dimensions :
      ['lon', 'nv']
      Array Chunk
      Bytes 11.25 kiB 11.25 kiB
      Shape (1440, 2) (1440, 2)
      Dask graph 1 chunks in 2 graph layers
      Data type float32 numpy.ndarray
      2 1440
    • time
      (time)
      datetime64[ns]
      2001-01-16T12:00:00 ... 2020-12-...
      standard_name :
      time
      bounds :
      time_bnds
      array(['2001-01-16T12:00:00.000000000', '2001-02-15T00:00:00.000000000',
             '2001-03-16T12:00:00.000000000', ..., '2020-10-16T12:00:00.000000000',
             '2020-11-16T00:00:00.000000000', '2020-12-16T12:00:00.000000000'],
            dtype='datetime64[ns]')
    • time_bnds
      (time, bnds)
      datetime64[ns]
      dask.array<chunksize=(240, 2), meta=np.ndarray>
      standard_name :
      time_bnds
      Array Chunk
      Bytes 3.75 kiB 3.75 kiB
      Shape (240, 2) (240, 2)
      Dask graph 1 chunks in 2 graph layers
      Data type datetime64[ns] numpy.ndarray
      2 240
    • vegetation_class
      (vegetation_class)
      int32
      10 20 30 40 50 ... 150 160 170 180
      units :
      1
      long_name :
      vegetation class number
      orig_data_type :
      int32
      fill_value :
      9223372036854775807
      size :
      18
      shape :
      [18]
      chunk_sizes :
      [18]
      file_chunk_sizes :
      [18]
      data_type :
      int64
      dimensions :
      ['vegetation_class']
      file_dimensions :
      ['vegetation_class']
      array([ 10,  20,  30,  40,  50,  60,  70,  80,  90, 100, 110, 120, 130, 140,
             150, 160, 170, 180], dtype=int32)
    • burned_area
      (time, lat, lon)
      float32
      dask.array<chunksize=(1, 720, 1440), meta=np.ndarray>
      units :
      m2
      standard_name :
      burned_area
      long_name :
      total burned_area
      cell_methods :
      time: sum
      orig_data_type :
      float32
      fill_value :
      nan
      size :
      248832000
      shape :
      [240, 720, 1440]
      chunk_sizes :
      [1, 720, 1440]
      file_chunk_sizes :
      [1, 720, 1440]
      data_type :
      float32
      dimensions :
      ['time', 'lat', 'lon']
      file_dimensions :
      ['time', 'lat', 'lon']
      Array Chunk
      Bytes 0.93 GiB 3.96 MiB
      Shape (240, 720, 1440) (1, 720, 1440)
      Dask graph 240 chunks in 2 graph layers
      Data type float32 numpy.ndarray
      1440 720 240
    • burned_area_in_vegetation_class
      (time, vegetation_class, lat, lon)
      float32
      dask.array<chunksize=(1, 18, 360, 360), meta=np.ndarray>
      units :
      m2
      long_name :
      burned area in vegetation class
      cell_methods :
      time: sum
      comment :
      Burned area by land cover classes; land cover classes are from CCI Land Cover, http://www.esa-landcover-cci.org/
      orig_data_type :
      float32
      fill_value :
      nan
      size :
      4478976000
      shape :
      [240, 18, 720, 1440]
      chunk_sizes :
      [1, 18, 360, 360]
      file_chunk_sizes :
      [1, 18, 360, 360]
      data_type :
      float32
      dimensions :
      ['time', 'vegetation_class', 'lat', 'lon']
      file_dimensions :
      ['time', 'vegetation_class', 'lat', 'lon']
      Array Chunk
      Bytes 16.69 GiB 8.90 MiB
      Shape (240, 18, 720, 1440) (1, 18, 360, 360)
      Dask graph 1920 chunks in 2 graph layers
      Data type float32 numpy.ndarray
      240 1 1440 720 18
    • fraction_of_burnable_area
      (time, lat, lon)
      float32
      dask.array<chunksize=(1, 720, 1440), meta=np.ndarray>
      units :
      1
      long_name :
      fraction of burnable area
      comment :
      The fraction of burnable area is the fraction of the cell that corresponds to vegetated land covers that could burn. The land cover classes are those from CCI Land Cover, http://www.esa-landcover-cci.org/
      orig_data_type :
      float32
      fill_value :
      nan
      size :
      248832000
      shape :
      [240, 720, 1440]
      chunk_sizes :
      [1, 720, 1440]
      file_chunk_sizes :
      [1, 720, 1440]
      data_type :
      float32
      dimensions :
      ['time', 'lat', 'lon']
      file_dimensions :
      ['time', 'lat', 'lon']
      Array Chunk
      Bytes 0.93 GiB 3.96 MiB
      Shape (240, 720, 1440) (1, 720, 1440)
      Dask graph 240 chunks in 2 graph layers
      Data type float32 numpy.ndarray
      1440 720 240
    • fraction_of_observed_area
      (time, lat, lon)
      float32
      dask.array<chunksize=(1, 720, 1440), meta=np.ndarray>
      units :
      1
      long_name :
      fraction of observed area
      comment :
      The fraction of the total burnable area in the cell (fraction_of_burnable_area variable of this file) that was observed during the time interval, and was not marked as unsuitable/not observable. The latter refers to the area where it was not possible to obtain observational burned area information for the whole time interval because of lack of input data (non-existing data for that location and period).
      orig_data_type :
      float32
      fill_value :
      nan
      size :
      248832000
      shape :
      [240, 720, 1440]
      chunk_sizes :
      [1, 720, 1440]
      file_chunk_sizes :
      [1, 720, 1440]
      data_type :
      float32
      dimensions :
      ['time', 'lat', 'lon']
      file_dimensions :
      ['time', 'lat', 'lon']
      Array Chunk
      Bytes 0.93 GiB 3.96 MiB
      Shape (240, 720, 1440) (1, 720, 1440)
      Dask graph 240 chunks in 2 graph layers
      Data type float32 numpy.ndarray
      1440 720 240
    • number_of_patches
      (time, lat, lon)
      float32
      dask.array<chunksize=(1, 720, 1440), meta=np.ndarray>
      units :
      1
      long_name :
      number of burn patches
      comment :
      Number of contiguous groups of burned pixels.
      orig_data_type :
      float32
      fill_value :
      nan
      size :
      248832000
      shape :
      [240, 720, 1440]
      chunk_sizes :
      [1, 720, 1440]
      file_chunk_sizes :
      [1, 720, 1440]
      data_type :
      float32
      dimensions :
      ['time', 'lat', 'lon']
      file_dimensions :
      ['time', 'lat', 'lon']
      Array Chunk
      Bytes 0.93 GiB 3.96 MiB
      Shape (240, 720, 1440) (1, 720, 1440)
      Dask graph 240 chunks in 2 graph layers
      Data type float32 numpy.ndarray
      1440 720 240
    • standard_error
      (time, lat, lon)
      float32
      dask.array<chunksize=(1, 720, 1440), meta=np.ndarray>
      units :
      m2
      long_name :
      standard error of the estimation of burned area
      orig_data_type :
      float32
      fill_value :
      nan
      size :
      248832000
      shape :
      [240, 720, 1440]
      chunk_sizes :
      [1, 720, 1440]
      file_chunk_sizes :
      [1, 720, 1440]
      data_type :
      float32
      dimensions :
      ['time', 'lat', 'lon']
      file_dimensions :
      ['time', 'lat', 'lon']
      Array Chunk
      Bytes 0.93 GiB 3.96 MiB
      Shape (240, 720, 1440) (1, 720, 1440)
      Dask graph 240 chunks in 2 graph layers
      Data type float32 numpy.ndarray
      1440 720 240
    • lat
      PandasIndex
      PandasIndex(Float64Index([ 89.875,  89.625,  89.375,  89.125,  88.875,  88.625,  88.375,
                     88.125,  87.875,  87.625,
                    ...
                    -87.625, -87.875, -88.125, -88.375, -88.625, -88.875, -89.125,
                    -89.375, -89.625, -89.875],
                   dtype='float64', name='lat', length=720))
    • lon
      PandasIndex
      PandasIndex(Float64Index([-179.875, -179.625, -179.375, -179.125, -178.875, -178.625,
                    -178.375, -178.125, -177.875, -177.625,
                    ...
                     177.625,  177.875,  178.125,  178.375,  178.625,  178.875,
                     179.125,  179.375,  179.625,  179.875],
                   dtype='float64', name='lon', length=1440))
    • time
      PandasIndex
      PandasIndex(DatetimeIndex(['2001-01-16 12:00:00', '2001-02-15 00:00:00',
                     '2001-03-16 12:00:00', '2001-04-16 00:00:00',
                     '2001-05-16 12:00:00', '2001-06-16 00:00:00',
                     '2001-07-16 12:00:00', '2001-08-16 12:00:00',
                     '2001-09-16 00:00:00', '2001-10-16 12:00:00',
                     ...
                     '2020-03-16 12:00:00', '2020-04-16 00:00:00',
                     '2020-05-16 12:00:00', '2020-06-16 00:00:00',
                     '2020-07-16 12:00:00', '2020-08-16 12:00:00',
                     '2020-09-16 00:00:00', '2020-10-16 12:00:00',
                     '2020-11-16 00:00:00', '2020-12-16 12:00:00'],
                    dtype='datetime64[ns]', name='time', length=240, freq=None))
    • vegetation_class
      PandasIndex
      PandasIndex(Int64Index([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150,
                  160, 170, 180],
                 dtype='int64', name='vegetation_class'))
  • Conventions :
    CF-1.7
    title :
    esacci.FIRE.mon.L4.BA.MODIS.Terra.MODIS_TERRA.v5-1.grid
    date_created :
    2023-08-30T14:33:39.046347
    processing_level :
    L4
    time_coverage_start :
    2001-01-01T00:00:00
    time_coverage_end :
    2021-01-01T00:00:00
    time_coverage_duration :
    P7305DT0H0M0S
    history :
    [{'program': 'xcube_cci.chunkstore.CciChunkStore', 'cube_params': {'time_range': ['2001-01-01T00:00:00', '2020-12-31T23:59:59'], 'variable_names': ['burned_area', 'standard_error', 'fraction_of_burnable_area', 'fraction_of_observed_area', 'number_of_patches', 'burned_area_in_vegetation_class']}}]

Subsetting time and space for the sake of an efficient example

Temporal subset, entire 2020:

In [13]:
start_date = datetime.datetime(2020,1,1)
stop_date = datetime.datetime(2020,12,31)

Spatial subset, southern/central Europe:

In [14]:
min_lat = 52.5
max_lat = 36.9
min_lon = -10.
max_lon = 22.9

Subsetting the Land Cover dataset, results in only one time slice per year for LC:

In [15]:
LC = LC.sel(lat=slice(min_lat, max_lat), 
            lon=slice(min_lon, max_lon), 
            time=slice(start_date, stop_date))
In [14]:
LC.lccs_class.isel(time=0).plot.imshow()
Out[14]:
<matplotlib.image.AxesImage at 0x7f97b5d1dc50>
No description has been provided for this image
In [16]:
LC
Out[16]:
<xarray.Dataset>
Dimensions:              (time: 1, lat: 5616, lon: 11844, bounds: 2)
Coordinates:
  * lat                  (lat) float64 52.5 52.5 52.49 52.49 ... 36.91 36.9 36.9
  * lon                  (lon) float64 -9.999 -9.996 -9.993 ... 22.89 22.9 22.9
  * time                 (time) datetime64[ns] 2020-01-01
Dimensions without coordinates: bounds
Data variables:
    change_count         (time, lat, lon) uint8 dask.array<chunksize=(1, 1620, 1440), meta=np.ndarray>
    crs                  (time) int32 dask.array<chunksize=(1,), meta=np.ndarray>
    current_pixel_state  (time, lat, lon) float32 dask.array<chunksize=(1, 1620, 1440), meta=np.ndarray>
    lat_bounds           (time, lat, bounds) float64 dask.array<chunksize=(1, 1620, 2), meta=np.ndarray>
    lccs_class           (time, lat, lon) uint8 dask.array<chunksize=(1, 1620, 1440), meta=np.ndarray>
    lon_bounds           (time, lon, bounds) float64 dask.array<chunksize=(1, 1440, 2), meta=np.ndarray>
    observation_count    (time, lat, lon) uint16 dask.array<chunksize=(1, 1620, 1440), meta=np.ndarray>
    processed_flag       (time, lat, lon) float32 dask.array<chunksize=(1, 1620, 1440), meta=np.ndarray>
    time_bounds          (time, bounds) datetime64[ns] dask.array<chunksize=(1, 2), meta=np.ndarray>
Attributes: (12/38)
    Conventions:                CF-1.6
    TileSize:                   2025:2025
    cdm_data_type:              grid
    comment:                    
    contact:                    https://www.ecmwf.int/en/about/contact-us/get...
    creation_date:              20181130T095431Z
    ...                         ...
    time_coverage_end:          20101231
    time_coverage_resolution:   P1Y
    time_coverage_start:        20100101
    title:                      Land Cover Map of ESA CCI brokered by CDS
    tracking_id:                96ac9aca-1ca7-45c6-b4a5-ab448c692646
    type:                       ESACCI-LC-L4-LCCS-Map-300m-P1Y
xarray.Dataset
    • time: 1
    • lat: 5616
    • lon: 11844
    • bounds: 2
    • lat
      (lat)
      float64
      52.5 52.5 52.49 ... 36.91 36.9 36.9
      axis :
      Y
      bounds :
      lat_bounds
      long_name :
      latitude
      standard_name :
      latitude
      units :
      degrees_north
      valid_max :
      90.0
      valid_min :
      -90.0
      array([52.498611, 52.495833, 52.493056, ..., 36.906944, 36.904167, 36.901389])
    • lon
      (lon)
      float64
      -9.999 -9.996 -9.993 ... 22.9 22.9
      axis :
      X
      bounds :
      lon_bounds
      long_name :
      longitude
      standard_name :
      longitude
      units :
      degrees_east
      valid_max :
      180.0
      valid_min :
      -180.0
      array([-9.998611, -9.995833, -9.993056, ..., 22.893056, 22.895833, 22.898611])
    • time
      (time)
      datetime64[ns]
      2020-01-01
      axis :
      T
      bounds :
      time_bounds
      long_name :
      time
      standard_name :
      time
      array(['2020-01-01T00:00:00.000000000'], dtype='datetime64[ns]')
    • change_count
      (time, lat, lon)
      uint8
      dask.array<chunksize=(1, 1620, 1440), meta=np.ndarray>
      long_name :
      number of class changes
      valid_max :
      100
      valid_min :
      0
      Array Chunk
      Bytes 63.43 MiB 4.45 MiB
      Shape (1, 5616, 11844) (1, 2160, 2160)
      Dask graph 18 chunks in 3 graph layers
      Data type uint8 numpy.ndarray
      11844 5616 1
    • crs
      (time)
      int32
      dask.array<chunksize=(1,), meta=np.ndarray>
      i2m :
      0.002777777777778,0.0,0.0,-0.002777777777778,-180.0,90.0
      wkt :
      GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]]
      Array Chunk
      Bytes 4 B 4 B
      Shape (1,) (1,)
      Dask graph 1 chunks in 3 graph layers
      Data type int32 numpy.ndarray
      1 1
    • current_pixel_state
      (time, lat, lon)
      float32
      dask.array<chunksize=(1, 1620, 1440), meta=np.ndarray>
      flag_meanings :
      invalid clear_land clear_water clear_snow_ice cloud cloud_shadow
      flag_values :
      [0, 1, 2, 3, 4, 5]
      long_name :
      LC pixel type mask
      standard_name :
      land_cover_lccs status_flag
      valid_max :
      5
      valid_min :
      0
      Array Chunk
      Bytes 253.74 MiB 17.80 MiB
      Shape (1, 5616, 11844) (1, 2160, 2160)
      Dask graph 18 chunks in 3 graph layers
      Data type float32 numpy.ndarray
      11844 5616 1
    • lat_bounds
      (time, lat, bounds)
      float64
      dask.array<chunksize=(1, 1620, 2), meta=np.ndarray>
      Array Chunk
      Bytes 87.75 kiB 33.75 kiB
      Shape (1, 5616, 2) (1, 2160, 2)
      Dask graph 3 chunks in 3 graph layers
      Data type float64 numpy.ndarray
      2 5616 1
    • lccs_class
      (time, lat, lon)
      uint8
      dask.array<chunksize=(1, 1620, 1440), meta=np.ndarray>
      ancillary_variables :
      processed_flag current_pixel_state observation_count change_count
      flag_colors :
      #ffff64 #ffff64 #ffff00 #aaf0f0 #dcf064 #c8c864 #006400 #00a000 #00a000 #aac800 #003c00 #003c00 #005000 #285000 #285000 #286400 #788200 #8ca000 #be9600 #966400 #966400 #966400 #ffb432 #ffdcd2 #ffebaf #ffc864 #ffd278 #ffebaf #00785a #009678 #00dc82 #c31400 #fff5d7 #dcdcdc #fff5d7 #0046c8 #ffffff
      flag_meanings :
      no_data cropland_rainfed cropland_rainfed_herbaceous_cover cropland_rainfed_tree_or_shrub_cover cropland_irrigated mosaic_cropland mosaic_natural_vegetation tree_broadleaved_evergreen_closed_to_open tree_broadleaved_deciduous_closed_to_open tree_broadleaved_deciduous_closed tree_broadleaved_deciduous_open tree_needleleaved_evergreen_closed_to_open tree_needleleaved_evergreen_closed tree_needleleaved_evergreen_open tree_needleleaved_deciduous_closed_to_open tree_needleleaved_deciduous_closed tree_needleleaved_deciduous_open tree_mixed mosaic_tree_and_shrub mosaic_herbaceous shrubland shrubland_evergreen shrubland_deciduous grassland lichens_and_mosses sparse_vegetation sparse_tree sparse_shrub sparse_herbaceous tree_cover_flooded_fresh_or_brakish_water tree_cover_flooded_saline_water shrub_or_herbaceous_cover_flooded urban bare_areas bare_areas_consolidated bare_areas_unconsolidated water snow_and_ice
      flag_values :
      [0, 10, 11, 12, 20, 30, 40, 50, 60, 61, 62, 70, 71, 72, 80, 81, 82, 90, 100, 110, 120, 121, 122, 130, 140, 150, 151, 152, 153, 160, 170, 180, 190, 200, 201, 202, 210, 220]
      long_name :
      Land cover class defined in LCCS
      standard_name :
      land_cover_lccs
      valid_max :
      220
      valid_min :
      1
      Array Chunk
      Bytes 63.43 MiB 4.45 MiB
      Shape (1, 5616, 11844) (1, 2160, 2160)
      Dask graph 18 chunks in 3 graph layers
      Data type uint8 numpy.ndarray
      11844 5616 1
    • lon_bounds
      (time, lon, bounds)
      float64
      dask.array<chunksize=(1, 1440, 2), meta=np.ndarray>
      Array Chunk
      Bytes 185.06 kiB 33.75 kiB
      Shape (1, 11844, 2) (1, 2160, 2)
      Dask graph 6 chunks in 3 graph layers
      Data type float64 numpy.ndarray
      2 11844 1
    • observation_count
      (time, lat, lon)
      uint16
      dask.array<chunksize=(1, 1620, 1440), meta=np.ndarray>
      long_name :
      number of valid observations
      standard_name :
      land_cover_lccs number_of_observations
      valid_max :
      32767
      valid_min :
      0
      Array Chunk
      Bytes 126.87 MiB 8.90 MiB
      Shape (1, 5616, 11844) (1, 2160, 2160)
      Dask graph 18 chunks in 3 graph layers
      Data type uint16 numpy.ndarray
      11844 5616 1
    • processed_flag
      (time, lat, lon)
      float32
      dask.array<chunksize=(1, 1620, 1440), meta=np.ndarray>
      flag_meanings :
      not_processed processed
      flag_values :
      [0, 1]
      long_name :
      LC map processed area flag
      standard_name :
      land_cover_lccs status_flag
      valid_max :
      1
      valid_min :
      0
      Array Chunk
      Bytes 253.74 MiB 17.80 MiB
      Shape (1, 5616, 11844) (1, 2160, 2160)
      Dask graph 18 chunks in 3 graph layers
      Data type float32 numpy.ndarray
      11844 5616 1
    • time_bounds
      (time, bounds)
      datetime64[ns]
      dask.array<chunksize=(1, 2), meta=np.ndarray>
      Array Chunk
      Bytes 16 B 16 B
      Shape (1, 2) (1, 2)
      Dask graph 1 chunks in 3 graph layers
      Data type datetime64[ns] numpy.ndarray
      2 1
    • lat
      PandasIndex
      PandasIndex(Float64Index([  52.4986111111111,  52.49583333333334,  52.49305555555557,
                     52.49027777777778,  52.48750000000001,  52.48472222222222,
                     52.48194444444445, 52.479166666666686,  52.47638888888889,
                    52.473611111111126,
                    ...
                    36.926388888888894, 36.923611111111114, 36.920833333333334,
                    36.918055555555554,  36.91527777777779,  36.91250000000001,
                     36.90972222222223,  36.90694444444445,  36.90416666666667,
                     36.90138888888889],
                   dtype='float64', name='lat', length=5616))
    • lon
      PandasIndex
      PandasIndex(Float64Index([-9.998611111111103, -9.995833333333337, -9.993055555555543,
                    -9.990277777777777, -9.987499999999983, -9.984722222222217,
                    -9.981944444444451, -9.979166666666657, -9.976388888888891,
                    -9.973611111111097,
                    ...
                     22.87361111111113, 22.876388888888897, 22.879166666666663,
                    22.881944444444457, 22.884722222222223, 22.887500000000017,
                    22.890277777777783, 22.893055555555577, 22.895833333333343,
                     22.89861111111111],
                   dtype='float64', name='lon', length=11844))
    • time
      PandasIndex
      PandasIndex(DatetimeIndex(['2020-01-01'], dtype='datetime64[ns]', name='time', freq=None))
  • Conventions :
    CF-1.6
    TileSize :
    2025:2025
    cdm_data_type :
    grid
    comment :
    contact :
    https://www.ecmwf.int/en/about/contact-us/get-support
    creation_date :
    20181130T095431Z
    creator_email :
    landcover-cci@uclouvain.be
    creator_name :
    UCLouvain
    creator_url :
    http://www.uclouvain.be/
    geospatial_lat_max :
    90.0
    geospatial_lat_min :
    -90.0
    geospatial_lat_resolution :
    0.002778
    geospatial_lat_units :
    degrees_north
    geospatial_lon_max :
    180
    geospatial_lon_min :
    -180
    geospatial_lon_resolution :
    0.002778
    geospatial_lon_units :
    degrees_east
    history :
    amorgos-4,0, lc-sdr-1.0, lc-sr-1.0, lc-classification-1.0,lc-user-tools-3.13,lc-user-tools-4.3
    id :
    ESACCI-LC-L4-LCCS-Map-300m-P1Y-2010-v2.0.7cds
    institution :
    UCLouvain
    keywords :
    land cover classification,satellite,observation
    keywords_vocabulary :
    NASA Global Change Master Directory (GCMD) Science Keywords
    license :
    ESA CCI Data Policy: free and open access
    naming_authority :
    org.esa-cci
    product_version :
    2.0.7cds
    project :
    Climate Change Initiative - European Space Agency
    references :
    http://www.esa-landcover-cci.org/
    source :
    MERIS FR L1B version 5.05, MERIS RR L1B version 8.0, SPOT VGT P
    spatial_resolution :
    300m
    standard_name_vocabulary :
    NetCDF Climate and Forecast (CF) Standard Names version 21
    summary :
    This dataset characterizes the land cover of a particular year (see time_coverage). The land cover was derived from the analysis of satellite data time series of the full period.
    time_coverage_duration :
    P1Y
    time_coverage_end :
    20101231
    time_coverage_resolution :
    P1Y
    time_coverage_start :
    20100101
    title :
    Land Cover Map of ESA CCI brokered by CDS
    tracking_id :
    96ac9aca-1ca7-45c6-b4a5-ab448c692646
    type :
    ESACCI-LC-L4-LCCS-Map-300m-P1Y

Subsetting the Fire dataset:

In [17]:
fire = fire.sel(lat=slice(min_lat, max_lat), 
                lon=slice(min_lon, max_lon), 
                time=slice(start_date, stop_date))
In [18]:
fire.burned_area.isel(time=0).plot.imshow(vmin=-1)
Out[18]:
<matplotlib.image.AxesImage at 0x7f38542adb90>
No description has been provided for this image

Resample to the same Grid

Here we use xcube's GridMapping method to extract the specification of both grids. Fire is the grid to be transformed.

In [19]:
source_gm = GridMapping.from_dataset(fire)
In [20]:
source_gm
Out[20]:

class: RegularGridMapping

  • is_regular: True
  • is_j_axis_up: False
  • is_lon_360: False
  • crs: EPSG:4326
  • xy_res: (0.25, 0.25)
  • xy_bbox: (-10, 37, 23, 52.5)
  • ij_bbox: (0, 0, 132, 62)
  • xy_dim_names: ('lon', 'lat')
  • xy_var_names: ('lon', 'lat')
  • size: (132, 62)
  • tile_size: (132, 62)

The target grid mapping is the one from the Land Cover dataset:

In [21]:
target_gm = GridMapping.from_dataset(LC)
In [22]:
target_gm
Out[22]:

class: RegularGridMapping

  • is_regular: True
  • is_j_axis_up: False
  • is_lon_360: False
  • crs: EPSG:4326
  • xy_res: (0.002777775, 0.002777775)
  • xy_bbox: (-10, 36.90000000138889, 22.899999998611108, 52.4999999986111)
  • ij_bbox: (0, 0, 11844, 5616)
  • xy_dim_names: ('lon', 'lat')
  • xy_var_names: ('lon', 'lat')
  • size: (11844, 5616)
  • tile_size: (2160, 2160)

Now we resample Fire to the grid provided by Land Cover:

In [23]:
resampled_fire = resample_in_space(fire,
                                   source_gm=source_gm, 
                                   target_gm=target_gm)

Lets compare the different grid mappings, to see whether the resampeled fire datasets has the desired grid mapping now:

Our source gridmapping, the original fire grid mapping:

In [24]:
source_gm.crs 
Out[24]:
<Geographic 2D CRS: EPSG:4326>
Name: WGS 84
Axis Info [ellipsoidal]:
- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)
Area of Use:
- name: World.
- bounds: (-180.0, -90.0, 180.0, 90.0)
Datum: World Geodetic System 1984 ensemble
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich

The grid mapping of Land Cover which was the target grid mapping:

In [28]:
target_gm.crs
Out[28]:
<Geographic 2D CRS: EPSG:4326>
Name: WGS 84
Axis Info [ellipsoidal]:
- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)
Area of Use:
- name: World.
- bounds: (-180.0, -90.0, 180.0, 90.0)
Datum: World Geodetic System 1984 ensemble
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich

The grid mapping of our resampeled Fire, which is as expeced the same as the target grid mapping.

In [29]:
GridMapping.from_dataset(resampled_fire).crs
Out[29]:
<Geographic 2D CRS: EPSG:4326>
Name: WGS 84
Axis Info [ellipsoidal]:
- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)
Area of Use:
- name: World.
- bounds: (-180.0, -90.0, 180.0, 90.0)
Datum: World Geodetic System 1984 ensemble
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich

Create a mask from LC classes

Now that we have our two datasets with the same gridmapping we can use the land cover classes to mask the Fire dataset.

In [25]:
LC.lccs_class.attrs['flag_values'] = np.array(LC.lccs_class.attrs['flag_values'])

Extracting only categories, which concern trees:

In [26]:
tree_categories = [[LC.lccs_class.attrs['flag_values'][i],j] for i,j in enumerate(LC.lccs_class.attrs["flag_meanings"].split(" ")) if "tree" in j]
In [27]:
tree_categories
Out[27]:
[[12, 'cropland_rainfed_tree_or_shrub_cover'],
 [50, 'tree_broadleaved_evergreen_closed_to_open'],
 [60, 'tree_broadleaved_deciduous_closed_to_open'],
 [61, 'tree_broadleaved_deciduous_closed'],
 [62, 'tree_broadleaved_deciduous_open'],
 [70, 'tree_needleleaved_evergreen_closed_to_open'],
 [71, 'tree_needleleaved_evergreen_closed'],
 [72, 'tree_needleleaved_evergreen_open'],
 [80, 'tree_needleleaved_deciduous_closed_to_open'],
 [81, 'tree_needleleaved_deciduous_closed'],
 [82, 'tree_needleleaved_deciduous_open'],
 [90, 'tree_mixed'],
 [100, 'mosaic_tree_and_shrub'],
 [151, 'sparse_tree'],
 [160, 'tree_cover_flooded_fresh_or_brakish_water'],
 [170, 'tree_cover_flooded_saline_water']]
In [28]:
LC_tree_mask = LC.lccs_class.isin([e[0] for e in tree_categories]).compute()

Although the coordiantes of the LC dataset and the resampled_fire dataset are almost identical, tiny numerical differences would prevent the masking from working. Thus, the coordinates from the resampled_fire dataset are assigned as the coordinates to the LC_tree_mask

In [29]:
LC_tree_mask = LC_tree_mask.assign_coords(lat = resampled_fire.lat, 
                                          lon = resampled_fire.lon).compute()
In [31]:
LC_tree_mask.plot()
Out[31]:
<matplotlib.collections.QuadMesh at 0x7fd8c2c6aed0>
No description has been provided for this image

For the masking to work, both data arrays must have identical coordinates, we thus enforce this condition by assigning coordinates and merging into one dataset

Because both dasets share the same spatial grid, we can mask the burned_area variable of the fire dataset with the LC_tree_mask and create a new data variable into the resampled_fire datacube. By selecting the only time slice, we remove the time information here.

In [30]:
resampled_fire['burned_tree_area'] = resampled_fire.burned_area.where(LC_tree_mask.isel(time=0))
In [31]:
resampled_fire
Out[31]:
<xarray.Dataset>
Dimensions:                          (time: 12, lat: 5616, lon: 11844,
                                      vegetation_class: 18, bnds: 2)
Coordinates:
  * time                             (time) datetime64[ns] 2020-01-16T12:00:0...
  * vegetation_class                 (vegetation_class) int32 10 20 ... 170 180
    time_bnds                        (time, bnds) datetime64[ns] dask.array<chunksize=(12, 2), meta=np.ndarray>
  * lon                              (lon) float64 -9.999 -9.996 ... 22.9 22.9
  * lat                              (lat) float64 52.5 52.5 52.49 ... 36.9 36.9
    lon_bnds                         (lon, bnds) float64 -10.0 -9.997 ... 22.9
    lat_bnds                         (lat, bnds) float64 52.5 52.5 ... 36.9 36.9
Dimensions without coordinates: bnds
Data variables:
    burned_area                      (time, lat, lon) float32 dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
    burned_area_in_vegetation_class  (time, vegetation_class, lat, lon) float32 dask.array<chunksize=(1, 1, 2160, 2160), meta=np.ndarray>
    fraction_of_burnable_area        (time, lat, lon) float32 dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
    fraction_of_observed_area        (time, lat, lon) float32 dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
    number_of_patches                (time, lat, lon) float32 dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
    standard_error                   (time, lat, lon) float32 dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
    burned_tree_area                 (time, lat, lon) float32 dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
Attributes:
    Conventions:             CF-1.7
    title:                   esacci.FIRE.mon.L4.BA.MODIS.Terra.MODIS_TERRA.v5...
    date_created:            2023-08-30T14:33:39.046347
    processing_level:        L4
    time_coverage_start:     2001-01-01T00:00:00
    time_coverage_end:       2021-01-01T00:00:00
    time_coverage_duration:  P7305DT0H0M0S
    history:                 [{'program': 'xcube_cci.chunkstore.CciChunkStore...
xarray.Dataset
    • time: 12
    • lat: 5616
    • lon: 11844
    • vegetation_class: 18
    • bnds: 2
    • time
      (time)
      datetime64[ns]
      2020-01-16T12:00:00 ... 2020-12-...
      standard_name :
      time
      bounds :
      time_bnds
      array(['2020-01-16T12:00:00.000000000', '2020-02-15T12:00:00.000000000',
             '2020-03-16T12:00:00.000000000', '2020-04-16T00:00:00.000000000',
             '2020-05-16T12:00:00.000000000', '2020-06-16T00:00:00.000000000',
             '2020-07-16T12:00:00.000000000', '2020-08-16T12:00:00.000000000',
             '2020-09-16T00:00:00.000000000', '2020-10-16T12:00:00.000000000',
             '2020-11-16T00:00:00.000000000', '2020-12-16T12:00:00.000000000'],
            dtype='datetime64[ns]')
    • vegetation_class
      (vegetation_class)
      int32
      10 20 30 40 50 ... 150 160 170 180
      units :
      1
      long_name :
      vegetation class number
      orig_data_type :
      int32
      fill_value :
      9223372036854775807
      size :
      18
      shape :
      [18]
      chunk_sizes :
      [18]
      file_chunk_sizes :
      [18]
      data_type :
      int64
      dimensions :
      ['vegetation_class']
      file_dimensions :
      ['vegetation_class']
      array([ 10,  20,  30,  40,  50,  60,  70,  80,  90, 100, 110, 120, 130, 140,
             150, 160, 170, 180], dtype=int32)
    • time_bnds
      (time, bnds)
      datetime64[ns]
      dask.array<chunksize=(12, 2), meta=np.ndarray>
      standard_name :
      time_bnds
      Array Chunk
      Bytes 192 B 192 B
      Shape (12, 2) (12, 2)
      Dask graph 1 chunks in 3 graph layers
      Data type datetime64[ns] numpy.ndarray
      2 12
    • lon
      (lon)
      float64
      -9.999 -9.996 -9.993 ... 22.9 22.9
      long_name :
      longitude coordinate
      standard_name :
      longitude
      units :
      degrees_east
      bounds :
      lon_bnds
      array([-9.998611, -9.995833, -9.993056, ..., 22.893056, 22.895833, 22.898611])
    • lat
      (lat)
      float64
      52.5 52.5 52.49 ... 36.91 36.9 36.9
      long_name :
      latitude coordinate
      standard_name :
      latitude
      units :
      degrees_north
      bounds :
      lat_bnds
      array([52.498611, 52.495833, 52.493056, ..., 36.906944, 36.904167, 36.901389])
    • lon_bnds
      (lon, bnds)
      float64
      -10.0 -9.997 -9.997 ... 22.9 22.9
      array([[-10.        ,  -9.99722222],
             [ -9.99722222,  -9.99444445],
             [ -9.99444444,  -9.99166667],
             ...,
             [ 22.89166667,  22.89444444],
             [ 22.89444445,  22.89722222],
             [ 22.89722222,  22.9       ]])
    • lat_bnds
      (lat, bnds)
      float64
      52.5 52.5 52.5 ... 36.9 36.9 36.9
      array([[52.5       , 52.49722222],
             [52.49722222, 52.49444445],
             [52.49444444, 52.49166667],
             ...,
             [36.90833333, 36.90555556],
             [36.90555555, 36.90277778],
             [36.90277778, 36.9       ]])
    • burned_area
      (time, lat, lon)
      float32
      dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
      units :
      m2
      standard_name :
      burned_area
      long_name :
      total burned_area
      cell_methods :
      time: sum
      orig_data_type :
      float32
      fill_value :
      nan
      size :
      248832000
      shape :
      [240, 720, 1440]
      chunk_sizes :
      [1, 720, 1440]
      file_chunk_sizes :
      [1, 720, 1440]
      data_type :
      float32
      dimensions :
      ['time', 'lat', 'lon']
      file_dimensions :
      ['time', 'lat', 'lon']
      Array Chunk
      Bytes 2.97 GiB 17.80 MiB
      Shape (12, 5616, 11844) (1, 2160, 2160)
      Dask graph 216 chunks in 220 graph layers
      Data type float32 numpy.ndarray
      11844 5616 12
    • burned_area_in_vegetation_class
      (time, vegetation_class, lat, lon)
      float32
      dask.array<chunksize=(1, 1, 2160, 2160), meta=np.ndarray>
      units :
      m2
      long_name :
      burned area in vegetation class
      cell_methods :
      time: sum
      comment :
      Burned area by land cover classes; land cover classes are from CCI Land Cover, http://www.esa-landcover-cci.org/
      orig_data_type :
      float32
      fill_value :
      nan
      size :
      4478976000
      shape :
      [240, 18, 720, 1440]
      chunk_sizes :
      [1, 18, 360, 360]
      file_chunk_sizes :
      [1, 18, 360, 360]
      data_type :
      float32
      dimensions :
      ['time', 'vegetation_class', 'lat', 'lon']
      file_dimensions :
      ['time', 'vegetation_class', 'lat', 'lon']
      Array Chunk
      Bytes 53.52 GiB 17.80 MiB
      Shape (12, 18, 5616, 11844) (1, 1, 2160, 2160)
      Dask graph 3888 chunks in 3892 graph layers
      Data type float32 numpy.ndarray
      12 1 11844 5616 18
    • fraction_of_burnable_area
      (time, lat, lon)
      float32
      dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
      units :
      1
      long_name :
      fraction of burnable area
      comment :
      The fraction of burnable area is the fraction of the cell that corresponds to vegetated land covers that could burn. The land cover classes are those from CCI Land Cover, http://www.esa-landcover-cci.org/
      orig_data_type :
      float32
      fill_value :
      nan
      size :
      248832000
      shape :
      [240, 720, 1440]
      chunk_sizes :
      [1, 720, 1440]
      file_chunk_sizes :
      [1, 720, 1440]
      data_type :
      float32
      dimensions :
      ['time', 'lat', 'lon']
      file_dimensions :
      ['time', 'lat', 'lon']
      Array Chunk
      Bytes 2.97 GiB 17.80 MiB
      Shape (12, 5616, 11844) (1, 2160, 2160)
      Dask graph 216 chunks in 220 graph layers
      Data type float32 numpy.ndarray
      11844 5616 12
    • fraction_of_observed_area
      (time, lat, lon)
      float32
      dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
      units :
      1
      long_name :
      fraction of observed area
      comment :
      The fraction of the total burnable area in the cell (fraction_of_burnable_area variable of this file) that was observed during the time interval, and was not marked as unsuitable/not observable. The latter refers to the area where it was not possible to obtain observational burned area information for the whole time interval because of lack of input data (non-existing data for that location and period).
      orig_data_type :
      float32
      fill_value :
      nan
      size :
      248832000
      shape :
      [240, 720, 1440]
      chunk_sizes :
      [1, 720, 1440]
      file_chunk_sizes :
      [1, 720, 1440]
      data_type :
      float32
      dimensions :
      ['time', 'lat', 'lon']
      file_dimensions :
      ['time', 'lat', 'lon']
      Array Chunk
      Bytes 2.97 GiB 17.80 MiB
      Shape (12, 5616, 11844) (1, 2160, 2160)
      Dask graph 216 chunks in 220 graph layers
      Data type float32 numpy.ndarray
      11844 5616 12
    • number_of_patches
      (time, lat, lon)
      float32
      dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
      units :
      1
      long_name :
      number of burn patches
      comment :
      Number of contiguous groups of burned pixels.
      orig_data_type :
      float32
      fill_value :
      nan
      size :
      248832000
      shape :
      [240, 720, 1440]
      chunk_sizes :
      [1, 720, 1440]
      file_chunk_sizes :
      [1, 720, 1440]
      data_type :
      float32
      dimensions :
      ['time', 'lat', 'lon']
      file_dimensions :
      ['time', 'lat', 'lon']
      Array Chunk
      Bytes 2.97 GiB 17.80 MiB
      Shape (12, 5616, 11844) (1, 2160, 2160)
      Dask graph 216 chunks in 220 graph layers
      Data type float32 numpy.ndarray
      11844 5616 12
    • standard_error
      (time, lat, lon)
      float32
      dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
      units :
      m2
      long_name :
      standard error of the estimation of burned area
      orig_data_type :
      float32
      fill_value :
      nan
      size :
      248832000
      shape :
      [240, 720, 1440]
      chunk_sizes :
      [1, 720, 1440]
      file_chunk_sizes :
      [1, 720, 1440]
      data_type :
      float32
      dimensions :
      ['time', 'lat', 'lon']
      file_dimensions :
      ['time', 'lat', 'lon']
      Array Chunk
      Bytes 2.97 GiB 17.80 MiB
      Shape (12, 5616, 11844) (1, 2160, 2160)
      Dask graph 216 chunks in 220 graph layers
      Data type float32 numpy.ndarray
      11844 5616 12
    • burned_tree_area
      (time, lat, lon)
      float32
      dask.array<chunksize=(1, 2160, 2160), meta=np.ndarray>
      units :
      m2
      standard_name :
      burned_area
      long_name :
      total burned_area
      cell_methods :
      time: sum
      orig_data_type :
      float32
      fill_value :
      nan
      size :
      248832000
      shape :
      [240, 720, 1440]
      chunk_sizes :
      [1, 720, 1440]
      file_chunk_sizes :
      [1, 720, 1440]
      data_type :
      float32
      dimensions :
      ['time', 'lat', 'lon']
      file_dimensions :
      ['time', 'lat', 'lon']
      Array Chunk
      Bytes 2.97 GiB 17.80 MiB
      Shape (12, 5616, 11844) (1, 2160, 2160)
      Dask graph 216 chunks in 223 graph layers
      Data type float32 numpy.ndarray
      11844 5616 12
    • time
      PandasIndex
      PandasIndex(DatetimeIndex(['2020-01-16 12:00:00', '2020-02-15 12:00:00',
                     '2020-03-16 12:00:00', '2020-04-16 00:00:00',
                     '2020-05-16 12:00:00', '2020-06-16 00:00:00',
                     '2020-07-16 12:00:00', '2020-08-16 12:00:00',
                     '2020-09-16 00:00:00', '2020-10-16 12:00:00',
                     '2020-11-16 00:00:00', '2020-12-16 12:00:00'],
                    dtype='datetime64[ns]', name='time', freq=None))
    • vegetation_class
      PandasIndex
      PandasIndex(Int64Index([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150,
                  160, 170, 180],
                 dtype='int64', name='vegetation_class'))
    • lon
      PandasIndex
      PandasIndex(Float64Index([     -9.9986111125, -9.995833334722105,  -9.99305555694421,
                    -9.990277779166316,  -9.98750000138842, -9.984722223610525,
                     -9.98194444583263, -9.979166668054736,  -9.97638889027684,
                    -9.973611112498945,
                    ...
                     22.87361111111005, 22.876388888887945,  22.87916666666584,
                     22.88194444444374, 22.884722222221633, 22.887499999999527,
                     22.89027777777742, 22.893055555555314, 22.895833333333215,
                     22.89861111111111],
                   dtype='float64', name='lon', length=11844))
    • lat
      PandasIndex
      PandasIndex(Float64Index([  52.4986111111111,  52.49583333333332,  52.49305555555555,
                     52.49027777777777,  52.48749999999999,  52.48472222222222,
                     52.48194444444444,  52.47916666666666,  52.47638888888888,
                    52.473611111111104,
                    ...
                     36.92638888888889,  36.92361111111111, 36.920833333333334,
                    36.918055555555554, 36.915277777777774, 36.912499999999994,
                     36.90972222222222,  36.90694444444444,  36.90416666666667,
                     36.90138888888889],
                   dtype='float64', name='lat', length=5616))
  • Conventions :
    CF-1.7
    title :
    esacci.FIRE.mon.L4.BA.MODIS.Terra.MODIS_TERRA.v5-1.grid
    date_created :
    2023-08-30T14:33:39.046347
    processing_level :
    L4
    time_coverage_start :
    2001-01-01T00:00:00
    time_coverage_end :
    2021-01-01T00:00:00
    time_coverage_duration :
    P7305DT0H0M0S
    history :
    [{'program': 'xcube_cci.chunkstore.CciChunkStore', 'cube_params': {'time_range': ['2001-01-01T00:00:00', '2020-12-31T23:59:59'], 'variable_names': ['burned_area', 'standard_error', 'fraction_of_burnable_area', 'fraction_of_observed_area', 'number_of_patches', 'burned_area_in_vegetation_class']}}]

Plot the burned area of the fire dataset for the first time stamp.

In [36]:
resampled_fire.burned_area.isel(time=0).plot.imshow(vmin=-1)
Out[36]:
<matplotlib.image.AxesImage at 0x7fe6a846a190>
No description has been provided for this image

Now lets plot the burned area with the Landcover information. Note, that burned area which is 0 but within the tree category will show up with the value 0 in the plot:

In [37]:
resampled_fire.burned_tree_area.isel(time=0).plot.imshow(vmin=-1)
Out[37]:
<matplotlib.image.AxesImage at 0x7fe6b039a990>
No description has been provided for this image

Lets save the resampled fire datacube locally, so we can visualize it faster.

In [38]:
resampled_fire.to_zarr("resampled_fire.zarr")
Out[38]:
<xarray.backends.zarr.ZarrStore at 0x7fe679a06260>
In [39]:
from xcube.webapi.viewer import Viewer
In [40]:
resampled_fire = xr.open_zarr("resampled_fire.zarr")
In [41]:
viewer = Viewer()
In [42]:
viewer.add_dataset(resampled_fire)
Out[42]:
'1d292bff-4857-455d-bb10-059ebea6843e'
In [43]:
viewer.info()
Server: https://deep.earthsystemdatalab.net/user/alicebalfanz/proxy/8003
Viewer: https://deep.earthsystemdatalab.net/user/alicebalfanz/proxy/8003/viewer/?serverUrl=https://deep.earthsystemdatalab.net/user/alicebalfanz/proxy/8003
In [44]:
viewer.show()
Out[44]:
WARNING:tornado.general:404 GET /viewer/config/config.json (127.0.0.1): xcube viewer has not been been configured
WARNING:tornado.general:404 GET /viewer/config/config.json (127.0.0.1): xcube viewer has not been been configured
WARNING:tornado.access:404 GET /viewer/config/config.json (127.0.0.1) 6.21ms
WARNING:tornado.access:404 GET /viewer/config/config.json (127.0.0.1) 6.21ms
WARNING:tornado.general:404 GET /viewer/config/config.json (127.0.0.1): xcube viewer has not been been configured
WARNING:tornado.general:404 GET /viewer/config/config.json (127.0.0.1): xcube viewer has not been been configured
WARNING:tornado.access:404 GET /viewer/config/config.json (127.0.0.1) 3.07ms
WARNING:tornado.access:404 GET /viewer/config/config.json (127.0.0.1) 3.07ms
In [ ]: