Quickstart

A quick starting guide to get you using cube_helper in a matter of minutes.

Loading a cube

To load a cube from a directory of netCDF files:

>>> import cube_helper as ch
>>> cube = ch.load('/path/to/cmip/data/HadGEM3-GC31-LL/piControl/r1i1p1f1/Amon/tasmin/gn/v20190628')

To load a cube from files that are matched by a pattern:

>>> import glob
>>> filenames = glob.glob('/path/to/cmip/data/tasmin*.nc')
>>> cube = ch.load(filenames)

To load a cube from a single file (or files) then include the full path of each required file in a list:

>>> cube = ch.load(['/path/to/cmip/data/tasmin_Amon_HadGEM3-GC31-LL_piControl_r1i1p1f1_gn_185001-194912.nc'])

Loading a cube with constraints

>>> import iris
>>> longitude_constraint = iris.Constraint(longitude = lambda cell : cell > 0 and cell < 180)
>>> cube = ch.load('/path/to/cmip/data/HadGEM3-GC31-LL/piControl/r1i1p1f1/Amon/tasmin/gn/v20190628', constraints=longitude_constraint)

Loading a cube without output

Sometimes, in production systems you may not need the full output from cube_helper. You can load cubes and suppress output with ch.muffle_logger(). You can reset to the default logging settings with ch.reset_logger()

>>> cube = ch.load('/path/to/cmip/data/output1/ICHEC/EC-EARTH/historical/mon/atmos/Amon/r1i1p1/v20131231/tas/')
cube attributes differ:

        tracking_id, history and creation_date attibutes inconsistent

cube time coordinates differ:

        time start date inconsistent

Deleting tracking_id, history and creation_date attributes from cubes

New time origin set to days since 1850-01-01 00:00:00
>>> ch.muffle_logger()
>>> cube = ch.load('/path/to/cmip/data/output1/ICHEC/EC-EARTH/historical/mon/atmos/Amon/r1i1p1/v20131231/tas/', silent=True)
>>> ch.reset_logger()
>>> cube = ch.load('/path/to/cmip/data/output1/ICHEC/EC-EARTH/historical/mon/atmos/Amon/r1i1p1/v20131231/tas/')
cube attributes differ:

        tracking_id, history and creation_date attibutes inconsistent

cube time coordinates differ:

        time start date inconsistent

Deleting tracking_id, history and creation_date attributes from cubes

New time origin set to days since 1850-01-01 00:00:00

Concatenating a cube

If you are dealing with cubes that have already been loaded, for CubeLists and list of loaded cubes.

>>> cubes
[<iris 'Cube' of air_temperature / (K) (time: 1200; latitude: 144; longitude: 192)>,
<iris 'Cube' of air_temperature / (K) (time: 1200; latitude: 144; longitude: 192)>,
<iris 'Cube' of air_temperature / (K) (time: 1200; latitude: 144; longitude: 192)>,
<iris 'Cube' of air_temperature / (K) (time: 1200; latitude: 144; longitude: 192)>,
<iris 'Cube' of air_temperature / (K) (time: 1200; latitude: 144; longitude: 192)>]

>>> cube = ch.concatenate(cubes)
Deleting history, creation_date, and tracking_id attributes from cubes


>>> cube
<iris 'Cube' of air_temperature / (K) (time: 6000; latitude: 144; longitude: 192)>

Adding a categorical to a cube

Add a categorical coordinate to an iterable of iris cubes or a standalone cube.

>>> cube
<iris 'Cube' of air_temperature / (K) (time: 1919; latitude: 160; longitude: 320)>
>>> cube = ch.add_categorical(cube, 'clim_season')
>>> print(cube)
air_temperature / (K)               (time: 1919; latitude: 160; longitude: 320)
     Dimension coordinates:
          time                           x               -               -
          latitude                       -               x               -
          longitude                      -               -               x
     Auxiliary coordinates:
          clim_season                    x               -               -
     Attributes:
          CDI: Climate Data Interface version 1.4.4 (http://code.zmaw.de/projects/cdi...
          CDO: Climate Data Operators version 1.4.4 (http://code.zmaw.de/projects/cdo...
          Conventions: CF-1.4
          associated_files: baseURL: http://cmip-pcmdi.llnl.gov/CMIP5/dataLocation gridspecFile: gridspec_atmos_fx_EC-EARTH_historical_r0i0p0.nc...
          branch_time: 2125.0
          cmor_version: 2.8.0
          comment: Equilibrium reached after preindustrial spin-up after which data were output...
          contact: Alastair McKinstry <alastair.mckinstry@ichec.ie>
          experiment: historical
          experiment_id: historical
          forcing: Nat,Ant
          frequency: mon
          grid_type: gaussian
          initialization_method: 1
          institute_id: ICHEC
          institution: EC-Earth (European Earth System Model)
          model_id: EC-EARTH
          modeling_realm: atmos
          original_name: 2T
          parent_experiment: pre-industrial control
          parent_experiment_id: piControl
          parent_experiment_rip: r1i1p1
          physics_version: 1
          product: output
          project_id: CMIP5
          realization: 1
          references: Model described by Hazeleger et al. (Bull. Amer. Meteor. Soc., 2010, 91,...
          table_id: Table Amon (26 July 2011) b26379e76858ab98b927917878a63d01
          title: EC-EARTH model output prepared for CMIP5 historical
     Cell methods:
          mean: time (3 hours)

Adding multiple categoricals to a cube

>>> cube
<iris 'Cube' of air_temperature / (K) (time: 1919; latitude: 160; longitude: 320)>
>>> cube = ch.add_categorical(cube, ['clim_season', 'season_year'])
>>> print(cube)
air_temperature / (K)               (time: 1919; latitude: 160; longitude: 320)
     Dimension coordinates:
          time                           x               -               -
          latitude                       -               x               -
          longitude                      -               -               x
     Auxiliary coordinates:
          clim_season                    x               -               -
          season_year                    x               -               -
     Attributes:
          CDI: Climate Data Interface version 1.4.4 (http://code.zmaw.de/projects/cdi...
          CDO: Climate Data Operators version 1.4.4 (http://code.zmaw.de/projects/cdo...
          Conventions: CF-1.4
          associated_files: baseURL: http://cmip-pcmdi.llnl.gov/CMIP5/dataLocation gridspecFile: gridspec_atmos_fx_EC-EARTH_historical_r0i0p0.nc...
          branch_time: 2125.0
          cmor_version: 2.8.0
          comment: Equilibrium reached after preindustrial spin-up after which data were output...
          contact: Alastair McKinstry <alastair.mckinstry@ichec.ie>
          experiment: historical
          experiment_id: historical
          forcing: Nat,Ant
          frequency: mon
          grid_type: gaussian
          initialization_method: 1
          institute_id: ICHEC
          institution: EC-Earth (European Earth System Model)
          model_id: EC-EARTH
          modeling_realm: atmos
          original_name: 2T
          parent_experiment: pre-industrial control
          parent_experiment_id: piControl
          parent_experiment_rip: r1i1p1
          physics_version: 1
          product: output
          project_id: CMIP5
          realization: 1
          references: Model described by Hazeleger et al. (Bull. Amer. Meteor. Soc., 2010, 91,...
          table_id: Table Amon (26 July 2011) b26379e76858ab98b927917878a63d01
          title: EC-EARTH model output prepared for CMIP5 historical
     Cell methods:
          mean: time (3 hours)

Adding a compound categorical to a cube

If the categoricals you are adding are part of a compound categorical, you can use special calls such as:

>>> cube
<iris 'Cube' of air_temperature / (K) (time: 1919; latitude: 160; longitude: 320)>
>>> annual_seasonal_mean = ch.add_categorical(cube, 'annual_seasonal_mean')
>>> print(annual_seasonal_mean)
air_temperature / (K)               (time: 1919; latitude: 160; longitude: 320)
     Dimension coordinates:
          time                           x               -               -
          latitude                       -               x               -
          longitude                      -               -               x
     Auxiliary coordinates:
          clim_season                    x               -               -
          season_year                    x               -               -
     Attributes:
          CDI: Climate Data Interface version 1.4.4 (http://code.zmaw.de/projects/cdi...
          CDO: Climate Data Operators version 1.4.4 (http://code.zmaw.de/projects/cdo...
          Conventions: CF-1.4
          associated_files: baseURL: http://cmip-pcmdi.llnl.gov/CMIP5/dataLocation gridspecFile: gridspec_atmos_fx_EC-EARTH_historical_r0i0p0.nc...
          branch_time: 2125.0
          cmor_version: 2.8.0
          comment: Equilibrium reached after preindustrial spin-up after which data were output...
          contact: Alastair McKinstry <alastair.mckinstry@ichec.ie>
          experiment: historical
          experiment_id: historical
          forcing: Nat,Ant
          frequency: mon
          grid_type: gaussian
          initialization_method: 1
          institute_id: ICHEC
          institution: EC-Earth (European Earth System Model)
          model_id: EC-EARTH
          modeling_realm: atmos
          original_name: 2T
          parent_experiment: pre-industrial control
          parent_experiment_id: piControl
          parent_experiment_rip: r1i1p1
          physics_version: 1
          product: output
          project_id: CMIP5
          realization: 1
          references: Model described by Hazeleger et al. (Bull. Amer. Meteor. Soc., 2010, 91,...
          table_id: Table Amon (26 July 2011) b26379e76858ab98b927917878a63d01
          title: EC-EARTH model output prepared for CMIP5 historical
     Cell methods:
          mean: time (3 hours)

Aggregating by categoricals

Returns an aggregated cube.

>>> cube
<iris 'Cube' of air_temperature / (K) (time: 1919; latitude: 160; longitude: 320)>
>>> cube = ch.aggregate_categorical(cube, 'clim_season')
>>> print(cube)
air_temperature / (K)               (time: 4; latitude: 160; longitude: 320)
     Dimension coordinates:
          time                           x            -               -
          latitude                       -            x               -
          longitude                      -            -               x
     Auxiliary coordinates:
          clim_season                    x            -               -
     Attributes:
          CDI: Climate Data Interface version 1.4.4 (http://code.zmaw.de/projects/cdi...
          CDO: Climate Data Operators version 1.4.4 (http://code.zmaw.de/projects/cdo...
          Conventions: CF-1.4
          associated_files: baseURL: http://cmip-pcmdi.llnl.gov/CMIP5/dataLocation gridspecFile: gridspec_atmos_fx_EC-EARTH_historical_r0i0p0.nc...
          branch_time: 2125.0
          cmor_version: 2.8.0
          comment: Equilibrium reached after preindustrial spin-up after which data were output...
          contact: Alastair McKinstry <alastair.mckinstry@ichec.ie>
          experiment: historical
          experiment_id: historical
          forcing: Nat,Ant
          frequency: mon
          grid_type: gaussian
          initialization_method: 1
          institute_id: ICHEC
          institution: EC-Earth (European Earth System Model)
          model_id: EC-EARTH
          modeling_realm: atmos
          original_name: 2T
          parent_experiment: pre-industrial control
          parent_experiment_id: piControl
          parent_experiment_rip: r1i1p1
          physics_version: 1
          product: output
          project_id: CMIP5
         realization: 1
          references: Model described by Hazeleger et al. (Bull. Amer. Meteor. Soc., 2010, 91,...
          table_id: Table Amon (26 July 2011) b26379e76858ab98b927917878a63d01
          title: EC-EARTH model output prepared for CMIP5 historical
     Cell methods:
          mean: time (3 hours)
          mean: clim_season

Extracting categoricals

Aggregates and extracts with a given constraint.

>>> cube
<iris 'Cube' of air_temperature / (K) (time: 1919; latitude: 160; longitude: 320)>
>>> tdelta_3mth = datetime.timedelta(hours=3*28*24.0)
>>> spans_three_months = lambda t: (t.bound[1] - t.bound[0]) > tdelta_3mth
>>> three_months_bound = iris.Constraint(time=spans_three_months)
>>> annual_seasonal_mean = ch.extract_categorical(cube, 'annual_seasonal_mean', three_months_bound)
>>> annual_seasonal_mean
<iris 'Cube' of air_temperature / (K) (time: 639; latitude: 160; longitude: 320)>

Loading a cube from a list of files

To load from a list of fname strings. Useful when combining datasets.

>>> from glob import glob
>>> fnames = glob('/path/to/cmip/data/output1/ICHEC/EC-EARTH/historical/mon/atmos/Amon/r1i1p1/v20131231/tas/*.nc')
>>> cube = ch.load(fnames)

Extracting constraints

Extracts a constraint from a cube. Time constraints work irrespective of whether the cube’s time coordinate has bounds or not.

>>> cube
<iris 'Cube' of air_temperature / (K) (time: 1752; latitude: 145; longitude: 192)>
>>> constraint = iris.Constraint(time=iris.time.PartialDateTime(month=2))
>>> extracted_cube = ch.extract(cube, constraint)
>>> extracted_cube
<iris 'Cube' of air_temperature / (K) (time: 146; latitude: 145; longitude: 192)>

Fixing known issues

There are some errors in CMIP data that are known about and can be fixed automatically. For details on the errors that can currently be fixed please see the cube_helper.fix_known_issues() documentation.

>>> cube = ch.load('/path/to/data/CMIP6/CMIP/CAS/FGOALS-f3-L/historical/r1i1p1f1/day/psl/gr/v20191019/')
>>> cube.coord('latitude').is_contiguous()
False
>>> ch.fix_known_issues(cube)
Applying FixCmip6CasFgoals. Fixing latitude and longitude bounds.
>>> cube.coord('latitude').is_contiguous()
True