In [1]:
import xarray as xr
import numpy as np

In [15]:
ds0 = xr.open_dataset("C:\\Users\\Norman\\.cate\\data_stores\\local\\local.esacci.SEALEVEL.mon.IND.MSLAMPH.multi-sensor.multi-platform.MERGED.2-0.r1.6ba656f9-7c90-3b15-aad2-c137f8b61909\\ESACCI-SEALEVEL-IND-MSLAMPH-MERGED-20161202000000-fv02.nc")
ds0


Out[15]:
<xarray.Dataset>
Dimensions:  (lat: 720, lon: 1440, period: 2, time: 276)
Coordinates:
  * time     (time) datetime64[ns] 1993-01-15 1993-02-15 1993-03-15 ...
  * period   (period) float32 1.0 0.5
  * lat      (lat) float32 -89.875 -89.625 -89.375 -89.125 -88.875 -88.625 ...
  * lon      (lon) float32 0.125 0.375 0.625 0.875 1.125 1.375 1.625 1.875 ...
Data variables:
    ampl     (lat, lon, period) float32 ...
    phase    (lat, lon, period) float32 ...
Attributes:
    title:                      Mean Sea Level changes amplitude and phases
    institution:                ESA, CLS, CNES
    references:                 http://www.esa-sealevel-cci.org/products
    tracking_id:                
    source:                     ERS-1 Phase C OPR V6, ERS-1 Phase E OPR V3, E...
    platform:                   ERS-1, ERS-2, ENVISAT, TOPEX/Poseidon, Jason-...
    sensor:                     RA, RA2, Poseidon-1, Poseidon-2, Poseidon-3, ...
    Conventions:                CF-1.6
    product_version:            2.0
    summary:                    This dataset contains global maps of mean sea...
    keywords:                   altimetry
    id:                         GLO-MSL-AMPH-MERGED
    naming_authority:           ESA CCI
    keywords_vocabulary:        NetCDF COARDS Climate and Forecast Standard N...
    standard_name_vocabulary:   NetCDF Climate and Forecast (CF) Metadata Con...
    cdm_data_type:              Grid
    comment:                    These data were produced at CLS as part of th...
    license:                    ESA CCI Data Policy: free and open access.
    date_created:               2016-12-02 00:00:00
    history:                    2016-12-02 00:00:00 : creation
    contact:                    info-sealevel@esa-sealevel-cci.org
    project:                    Climate Change Initiative - European Space Ag...
    creator_name:               ESA, CLS
    creator_url:                http://www.esa-sealevel-cci.org/
    creator_email:              info-sealevel@esa-sealevel-cci.org
    geospatial_lat_min:         -89.875
    geospatial_lat_max:         89.875
    geospatial_lon_min:         0.125
    geospatial_lon_max:         359.875
    geospatial_vertical_min:    0.0
    geospatial_vertical_max:    0.0
    geospatial_lat_units:       degrees_north
    geospatial_lon_units:       degrees_east
    geospatial_lat_resolution:  0.25
    geospatial_lon_resolution:  0.25
    time_coverage_start:        1993-01-01 00:00:00
    time_coverage_end:          2015-12-31 23:59:59
    time_coverage_duration:     P23Y
    time_coverage_resolution:   P1M

In [25]:
ds0['phase'] is ds0['phase']


Out[25]:
False

We observe two issues here which make it hard to work with this data in the current version of Cate:

  1. Cate can only display dataset variables whose last dimensions are lat and lon, in this order;
  2. there is a dimension and coordinate variable time, which is not used by any data variable. Instead it seems, it provides the individual time steps of the data within the temporal coverage that was used to produce the dataset. If we want to concatenate multiple Sea-Level datasets to form a time series, this will later on fail, because Cate interprets the time as an axis as defined by the CF-Conventions.

We address the first the 2nd issue by simply renaming the time variable into time_step using the xarray Dataset method rename():


In [5]:
ds = ds0.rename(time='time_step')
ds.time_step


Out[5]:
<xarray.DataArray 'time_step' (time_step: 276)>
array(['1993-01-15T00:00:00.000000000', '1993-02-15T00:00:00.000000000',
       '1993-03-15T00:00:00.000000000', ..., '2015-10-15T00:00:00.000000000',
       '2015-11-15T00:00:00.000000000', '2015-12-15T00:00:00.000000000'],
      dtype='datetime64[ns]')
Coordinates:
  * time_step  (time_step) datetime64[ns] 1993-01-15 1993-02-15 1993-03-15 ...
Attributes:
    long_name:      time
    standard_name:  time

Then we add the time and time_bnds coordinate variables using the xarray Dataset method assign_coords() according to the CF-Conventions.


In [6]:
ds.time_step.encoding


Out[6]:
{'source': 'C:\\Users\\Norman\\.cate\\data_stores\\local\\local.esacci.SEALEVEL.mon.IND.MSLAMPH.multi-sensor.multi-platform.MERGED.2-0.r1.6ba656f9-7c90-3b15-aad2-c137f8b61909\\ESACCI-SEALEVEL-IND-MSLAMPH-MERGED-20161202000000-fv02.nc',
 'original_shape': (276,),
 'dtype': dtype('float32'),
 'units': 'days since 1950-01-01'}

In [7]:
# Time encoding properties
dtype = ds.time_step.encoding['dtype']
units = ds.time_step.encoding['units']

# Get the time boundary values
ts       = ds.time_step.values
ts_start = ts[0]
ts_end   = ts[-1]
ts_mid   = ts_start + 0.5 * (ts_end - ts_start)

# New coordinate variables according to CF
time      = xr.DataArray(np.array([ts_mid]), dims='time')
time_bnds = xr.DataArray(np.array([[ts_start, ts_end]]), dims=['time', 'bnds'])

# Assign coordinate variables
ds = ds.assign_coords(time=time, time_bnds=time_bnds)

# Update coordinate variable attributes according to CF
ds.time.attrs.update(bounds='time_bnds')

# Set coordinate variable encodings
ds.time.encoding.update(units=units, dtype=dtype)
ds.time_bnds.encoding.update(units=units, dtype=dtype)

ds


Out[7]:
<xarray.Dataset>
Dimensions:    (bnds: 2, lat: 720, lon: 1440, period: 2, time: 1, time_step: 276)
Coordinates:
  * time_step  (time_step) datetime64[ns] 1993-01-15 1993-02-15 1993-03-15 ...
  * period     (period) float32 1.0 0.5
  * lat        (lat) float32 -89.875 -89.625 -89.375 -89.125 -88.875 -88.625 ...
  * lon        (lon) float32 0.125 0.375 0.625 0.875 1.125 1.375 1.625 1.875 ...
  * time       (time) datetime64[ns] 2004-06-30T12:00:00
    time_bnds  (time, bnds) datetime64[ns] 1993-01-15 2015-12-15
Dimensions without coordinates: bnds
Data variables:
    ampl       (lat, lon, period) float32 ...
    phase      (lat, lon, period) float32 ...
Attributes:
    title:                      Mean Sea Level changes amplitude and phases
    institution:                ESA, CLS, CNES
    references:                 http://www.esa-sealevel-cci.org/products
    tracking_id:                
    source:                     ERS-1 Phase C OPR V6, ERS-1 Phase E OPR V3, E...
    platform:                   ERS-1, ERS-2, ENVISAT, TOPEX/Poseidon, Jason-...
    sensor:                     RA, RA2, Poseidon-1, Poseidon-2, Poseidon-3, ...
    Conventions:                CF-1.6
    product_version:            2.0
    summary:                    This dataset contains global maps of mean sea...
    keywords:                   altimetry
    id:                         GLO-MSL-AMPH-MERGED
    naming_authority:           ESA CCI
    keywords_vocabulary:        NetCDF COARDS Climate and Forecast Standard N...
    standard_name_vocabulary:   NetCDF Climate and Forecast (CF) Metadata Con...
    cdm_data_type:              Grid
    comment:                    These data were produced at CLS as part of th...
    license:                    ESA CCI Data Policy: free and open access.
    date_created:               2016-12-02 00:00:00
    history:                    2016-12-02 00:00:00 : creation
    contact:                    info-sealevel@esa-sealevel-cci.org
    project:                    Climate Change Initiative - European Space Ag...
    creator_name:               ESA, CLS
    creator_url:                http://www.esa-sealevel-cci.org/
    creator_email:              info-sealevel@esa-sealevel-cci.org
    geospatial_lat_min:         -89.875
    geospatial_lat_max:         89.875
    geospatial_lon_min:         0.125
    geospatial_lon_max:         359.875
    geospatial_vertical_min:    0.0
    geospatial_vertical_max:    0.0
    geospatial_lat_units:       degrees_north
    geospatial_lon_units:       degrees_east
    geospatial_lat_resolution:  0.25
    geospatial_lon_resolution:  0.25
    time_coverage_start:        1993-01-01 00:00:00
    time_coverage_end:          2015-12-31 23:59:59
    time_coverage_duration:     P23Y
    time_coverage_resolution:   P1M

Then we insert a time axis of size one into the data variables using the xarray DataArray method expand_dims(), so we can later easily concatenate multiple Sea-Level datasets along the time dimension.


In [35]:
ds['ampl'] = ds.ampl.expand_dims('time')
ds['phase'] = ds.phase.expand_dims('time')
ds


Out[35]:
<xarray.Dataset>
Dimensions:    (bnds: 2, lat: 720, lon: 1440, period: 2, time: 1, time_step: 276)
Coordinates:
  * time       (time) datetime64[ns] 2004-06-30T12:00:00
  * time_step  (time_step) datetime64[ns] 1993-01-15 1993-02-15 1993-03-15 ...
  * period     (period) float32 1.0 0.5
  * lat        (lat) float32 -89.875 -89.625 -89.375 -89.125 -88.875 -88.625 ...
  * lon        (lon) float32 0.125 0.375 0.625 0.875 1.125 1.375 1.625 1.875 ...
    time_bnds  (time, bnds) datetime64[ns] 1993-01-15 2015-12-15
Dimensions without coordinates: bnds
Data variables:
    ampl       (time, lat, lon, period) float32 nan nan nan nan nan nan nan ...
    phase      (time, lat, lon, period) float32 nan nan nan nan nan nan nan ...
Attributes:
    title:                      Mean Sea Level changes amplitude and phases
    institution:                ESA, CLS, CNES
    references:                 http://www.esa-sealevel-cci.org/products
    tracking_id:                
    source:                     ERS-1 Phase C OPR V6, ERS-1 Phase E OPR V3, E...
    platform:                   ERS-1, ERS-2, ENVISAT, TOPEX/Poseidon, Jason-...
    sensor:                     RA, RA2, Poseidon-1, Poseidon-2, Poseidon-3, ...
    Conventions:                CF-1.6
    product_version:            2.0
    summary:                    This dataset contains global maps of mean sea...
    keywords:                   altimetry
    id:                         GLO-MSL-AMPH-MERGED
    naming_authority:           ESA CCI
    keywords_vocabulary:        NetCDF COARDS Climate and Forecast Standard N...
    standard_name_vocabulary:   NetCDF Climate and Forecast (CF) Metadata Con...
    cdm_data_type:              Grid
    comment:                    These data were produced at CLS as part of th...
    license:                    ESA CCI Data Policy: free and open access.
    date_created:               2016-12-02 00:00:00
    history:                    2016-12-02 00:00:00 : creation
    contact:                    info-sealevel@esa-sealevel-cci.org
    project:                    Climate Change Initiative - European Space Ag...
    creator_name:               ESA, CLS
    creator_url:                http://www.esa-sealevel-cci.org/
    creator_email:              info-sealevel@esa-sealevel-cci.org
    geospatial_lat_min:         -89.875
    geospatial_lat_max:         89.875
    geospatial_lon_min:         0.125
    geospatial_lon_max:         359.875
    geospatial_vertical_min:    0.0
    geospatial_vertical_max:    0.0
    geospatial_lat_units:       degrees_north
    geospatial_lon_units:       degrees_east
    geospatial_lat_resolution:  0.25
    geospatial_lon_resolution:  0.25
    time_coverage_start:        1993-01-01 00:00:00
    time_coverage_end:          2015-12-31 23:59:59
    time_coverage_duration:     P23Y
    time_coverage_resolution:   P1M

We now address the 1st issue by changing the order of the data variables' dimensions so that Cate can display them. We use the xarray Dataset method transpose():


In [36]:
ds = ds.transpose('time', 'bnds', 'time_step', 'period', 'lat', 'lon')
ds


Out[36]:
<xarray.Dataset>
Dimensions:    (bnds: 2, lat: 720, lon: 1440, period: 2, time: 1, time_step: 276)
Coordinates:
  * time       (time) datetime64[ns] 2004-06-30T12:00:00
  * time_step  (time_step) datetime64[ns] 1993-01-15 1993-02-15 1993-03-15 ...
  * period     (period) float32 1.0 0.5
  * lat        (lat) float32 -89.875 -89.625 -89.375 -89.125 -88.875 -88.625 ...
  * lon        (lon) float32 0.125 0.375 0.625 0.875 1.125 1.375 1.625 1.875 ...
    time_bnds  (time, bnds) datetime64[ns] 1993-01-15 2015-12-15
Dimensions without coordinates: bnds
Data variables:
    ampl       (time, period, lat, lon) float32 nan nan nan nan nan nan nan ...
    phase      (time, period, lat, lon) float32 nan nan nan nan nan nan nan ...
Attributes:
    title:                      Mean Sea Level changes amplitude and phases
    institution:                ESA, CLS, CNES
    references:                 http://www.esa-sealevel-cci.org/products
    tracking_id:                
    source:                     ERS-1 Phase C OPR V6, ERS-1 Phase E OPR V3, E...
    platform:                   ERS-1, ERS-2, ENVISAT, TOPEX/Poseidon, Jason-...
    sensor:                     RA, RA2, Poseidon-1, Poseidon-2, Poseidon-3, ...
    Conventions:                CF-1.6
    product_version:            2.0
    summary:                    This dataset contains global maps of mean sea...
    keywords:                   altimetry
    id:                         GLO-MSL-AMPH-MERGED
    naming_authority:           ESA CCI
    keywords_vocabulary:        NetCDF COARDS Climate and Forecast Standard N...
    standard_name_vocabulary:   NetCDF Climate and Forecast (CF) Metadata Con...
    cdm_data_type:              Grid
    comment:                    These data were produced at CLS as part of th...
    license:                    ESA CCI Data Policy: free and open access.
    date_created:               2016-12-02 00:00:00
    history:                    2016-12-02 00:00:00 : creation
    contact:                    info-sealevel@esa-sealevel-cci.org
    project:                    Climate Change Initiative - European Space Ag...
    creator_name:               ESA, CLS
    creator_url:                http://www.esa-sealevel-cci.org/
    creator_email:              info-sealevel@esa-sealevel-cci.org
    geospatial_lat_min:         -89.875
    geospatial_lat_max:         89.875
    geospatial_lon_min:         0.125
    geospatial_lon_max:         359.875
    geospatial_vertical_min:    0.0
    geospatial_vertical_max:    0.0
    geospatial_lat_units:       degrees_north
    geospatial_lon_units:       degrees_east
    geospatial_lat_resolution:  0.25
    geospatial_lon_resolution:  0.25
    time_coverage_start:        1993-01-01 00:00:00
    time_coverage_end:          2015-12-31 23:59:59
    time_coverage_duration:     P23Y
    time_coverage_resolution:   P1M

Finally we write the modified dataset as a new NetCDF file using the xarray Dataset method to_netcdf():


In [37]:
ds.to_netcdf('ESACCI-SEALEVEL-IND-MSLAMPH-MERGED-20161202000000-fv02-Cate.nc')

In [ ]: