Regional Ancillary Suite workflow#

A notebook to document and check the outputs of the Regional Ancillary Suite (RAS).

This notebook is located at

21centuryweather/RAS_minimum_working_example

Here we breakdown the (complicated) ancillary workflow to help provide insights when things go wrong.

The rose/cylc task graph for the RAS is quite complex (see below), but in this notebook we will step through each task separately and document its outputs. This will help you understand the dependencies and help you trace any errors if they occur when you create new ancillaries for your own experiments

Graph

The firsts tasks that run in this suite are INSTALL_COLD, ANCIL_ANTS andANCIL_ANTS. These install a local version of the ants python module in your ~/cylc-run/RAS_minimum_working_example directory, along with various global ancillary datasets required to genreate regional information.

Once these set-up tasks have been complete, the suite will begin to generate ancillaries for every designed region and resolution defined in the suite’s rose-suite.conf file.

Our rose-suite.conf contains one region:

rg01_name="Lismore-tiny"

which contains two resolutions:

rg01_rs01_name="era5"
rg01_rs02_name="d1100"

You can see from the above image that the suite has generated a seperate task family for each resolution:

Lismore-tiny_era5_ancil
Lismore-tiny_d1100_ancil

Both task families contain and identical set of tasks. In this workbook we will step through the second task family, Lismore-tiny_d1100_ancil

Step 1. Install the grid definition namelists.#

Running the task Lismore-tiny_d1100_ancil_top installs the following files into ~cylc-run/RAS_minimum_working_example/share/data/ancils/Lismore-tiny/d1100

  • grid.nl

  • grid_eg.nl

  • L70_80km

  • vertlevs.nl

The first two files are Fortran ‘namelist’ files that contain information of the horizontal latitute/longitude grid (i.e. its bounds, number of points and grid spacing). The latter two files provide the vertical information of the grid.

Step 2. Generate the land-sea mask and vegetation ancillaries on the defined grid.#

The Lismore-tiny_d1100_ancil_lct task generates the land-sea mask and vegetation ancillaries that are consistent with the grid definition contained in the grid namelist files.

This task generates the following files:

  • qrparm.mask_cci (the land-sea binary mask in UM ancillary binary format)

  • qrparm.mask_cci.nc(as above, but in netCDF format)

  • qrparm.landfrac (the land fraction mask in UM ancillary binary format)

  • qrparm.landfrac.nc(as above, but in netCDF format)

  • qrparm.mask_sea(another land-sea binary mask using different coastline defintion in UM ancillary binary format - not used by the standard RAS suite)

  • qrparm.mask_sea.nc(as above, but in netCDF format)

  • qrparm.veg.frac_cci_pre_c4 (9 level vegetation grids in UM ancillary binary format)

  • qrparm.veg.frac_cci_pre_c4.nc (as above, but in netCDF format)

It also generates a symbolic link to qrparm.mask to point toqrparm.mask_cci. This is done to track providence of the mask generation (i.e. using CCI datasets).

Let’s examine the binary land-sea mask and the vegetation grids.

from pathlib import Path
import iris
import numpy as np
import warnings
warnings.filterwarnings("ignore", category=FutureWarning, module="xarray")
import xarray as xr
import matplotlib.pyplot as plt
import os
home_dir=os.environ['HOME']
HOME=Path(home_dir)
ANCIL_DIR = Path( HOME / 'cylc-run/RAS_minimum_working_example/share/data/ancils/Lismore-tiny/d1100')
lsm, = iris.load( ANCIL_DIR / 'qrparm.mask')
xr.DataArray.from_iris(lsm).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d315bbba40>
../_images/c1063d4ecc8f87381d62327bb4272de2e6d667ea4bd64d3248fcce7004438c66.png
veg_frac_pre_c4, = iris.load( ANCIL_DIR / 'qrparm.veg.frac_cci_pre_c4')
xr.DataArray.from_iris(veg_frac_pre_c4[0]).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d3150df500>
../_images/2c3d872d50a09eaace335c0dc27c3075c012dc6a3f903c3c700c05ccc7bf59d8.png

Step 3. Include World Cover data (optional).#

This task will run if you have set WC_URBAN=True in your rose-suite.conf file.

If applicable, this tasks modifies the vegetation ancillaries to include the lastest ‘World Cover’ data. This step allows better representation of urban areas. This step uses the task Lismore-tiny_d1100_ancil_lct_postproc_wc_urban and will update the files:

  • qrparm.veg.frac_cci_pre_c4, qrparm.veg.frac_cci_pre_c4.nc,

and generate the files

  • qrparm.veg.frac_cci_pre_c4_pre_wc, qrparm.veg.frac_cci_pre_c4_pre_wc.nc

veg_frac_pre_c4_wc, = iris.load( ANCIL_DIR / 'qrparm.veg.frac_cci_pre_c4_pre_wc')
xr.DataArray.from_iris(veg_frac_pre_c4_wc[0]).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d314f97500>
../_images/5956a39127a5b0f1d5f6d493dd40f1dab7a678400284dd4517e81b0c25a92f5e.png

Step 4. Install C4 land cover data#

The vegetation processing is completed with the task Lismore-tiny_d1100_ancil_lct_postproc_c4. This injects ‘C4’ data into the land cover type fraction dataset, and produces the output files:

  • qrparm.veg.frac_cci, qrparm.veg.frac_cci.nc

A symbolic link is created to both of these files which removes the last suffix, i.e.

  • qrparm.veg.frac -> qrparm.veg.frac_cci

  • qrparm.veg.frac.nc -> qrparm.veg.frac_cci.nc

veg_frac, = iris.load( ANCIL_DIR / 'qrparm.veg.frac_cci')
xr.DataArray.from_iris(veg_frac[0]).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d314f974a0>
../_images/bdd5843a5afdc80af85b4782fc04efef40bc8a509730b4f971e29898d81a27d2.png

The following flowchart summarises the task flow to generate the vegetation land cover classification ancillaries.

LCT flow

We have now run all the major master, ‘umbrella’ tasks for the ancilliary suite.

Now the final vegetation land cover classification ancillaries have been created, the suite splits and launches many tasks in parallel. Some tasks are grouped into their own subclasses with their own dependencies, such as

  • orography

  • soil characteristics

  • leaf areas and canopy heights

  • ice and snow

  • moruses

Let’s review the orography set of tasks first.

The first orography task is Lismore-tiny_d1100_ancil_cap_orog. Any tasks that contain cap in their task name do not use the python ants library. Rather they use the older UM binary. E.g. this task is launched with the command

$ more app/ancil_cap_orog/rose-app.conf 
meta=ancilOrog

[command]
default=rose mpi-launch -v central_ancillary.exe

Step 5. Generate orography.#

Triggering the task Lismore-tiny_d1100_ancil_cap_orog will generate the file qrparm.orog.

orog = iris.load( ANCIL_DIR / 'qrparm.orog')
xr.DataArray.from_iris(orog[0]).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d314d3f500>
../_images/25677b7856a63cb97fa10306f9d6b79b83aaeebb7a39882cf55d85be8d58cf22.png

The co-ordinates of qrparm.orog are produced by an older Fortan CAP exe and are 32-bit co-ordinates by default.

The next orography task is Lismore-tiny_d1100_ancil_mean_orog. This is two-step task that firstly

  • produces a concatentated SRTM orography file orog_srtm/SRTM_concat.nc (which is a global dataset)

  • then produces the file orog_srtm/qrparm.orog.srtm.nc

NOTE! The file orog_srtm/qrparm.orog.srtm.nc is a temporary file that will be deleted when the next task, Lismore-tiny_d1100_ancil_mean_orog_smooth,is executed. It will only be visible if you trigger the task Lismore-tiny_d1100_ancil_mean_orog manually and hold the subsequent Lismore-tiny_d1100_ancil_mean_orog_smooth task.

orog_srtm=iris.load_cube(ANCIL_DIR / 'orog_srtm/qrparm.orog.srtm.nc')
xr.DataArray.from_iris(orog_srtm).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d3003d48c0>
../_images/0680c5fadf3e85e38227ccaca7a5a7b7d62629b83d07fda13bd8f43d8d4291a4.png

IMPORTANT!! The SRTM orography dataset is not defined beyond +/- 60 latitude!! If you want to run an experiment close to the poles, you’ll need to change the default suite behaviour. See here for more details:

https://forum.access-hive.org.au/t/regional-ancillary-suite-error-srtm-data-not-available-for-regions-above-60-deg/

The final orography task is Lismore-tiny_d1100_ancil_mean_orog_smooth, which smooths the SRTM data according to a variety of algorithms. This produces the folowing files in ./orog_srtm/:

qrparm.orog.srtm.121x1
qrparm.orog.srtm.121x10
qrparm.orog.srtm.121x100
qrparm.orog.srtm.121x20
qrparm.orog.srtm.121x35
qrparm.orog.srtm.121x5
qrparm.orog.srtm.121x50
qrparm.orog.srtm.121x75

In the main ancilliary directory, a symbolic link qrparm.orog.mn links to orog_srtm/qrparm.orog.srtm.121x1

orog_smooth, = iris.load( ANCIL_DIR / 'qrparm.orog.mn')
xr.DataArray.from_iris(orog_smooth).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d31492c8c0>
../_images/931f14c947e3063d29cb39dc908383e17f562127678f5a08c6ddb9566068ca82.png

The following flowchart describes the task flows for orography related tasks.

Orog task flow

Step 7. Process soil characteristics#

The next set of multi-step tasks are related to generating soil characteristics. First, we begin with <Region>_<Resolution>_ancil_soils_hydr. This reads in the global soils_hydrology.nc file, regrids it to our target domain and saves it to soil_hydrology

hydro = iris.load(ANCIL_DIR / 'soil_hydrology')
xr.DataArray.from_iris(hydro[0]).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d31506e6f0>
../_images/ffc4e2e5e87a2984096653baf84d81b7e7cf4503d67fce119a95732f84cc3aa2.png

Next we process the soil albedo with the task <Region>_<Resolution>_ancil_soil_albedo. This reads in the global dataset soil_albedo.nc along with the existing files:

  • soil_hydrology

  • qrparm.veg.frac.nc and outputs qrparm.soil_cci

The global albedo dataset may require manual inputs to provide data for small islands. It is defined on 0.05 degree grid.

albedo = xr.open_dataset('/home/548/pag548/cylc-run/rCM3-ancil-suite/share/data/etc/ancil_master_ants/soil_albedo/classic/v3/soil_albedo.nc')
albedo.soil_albedo.sel(latitude=slice(-26,-32),longitude=slice(150,156)).plot()
<matplotlib.collections.QuadMesh at 0x14d301a9c8c0>
../_images/6b91dbd3ccfb8d7c83775c063d80a409c391cf5437559eb0c2d7217592b36c0b.png
soil = iris.load( ANCIL_DIR / 'qrparm.soil_cci')
xr.DataArray.from_iris(soil[0]).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d301a348c0>
../_images/bdfa92e974abeb939b9027a3b7dd82c91bfb5b02e240069f03105ec8d14ad199.png

The last task in this dependency is <Region>_<Resolution>_ancil_soil_dust. This processes the qrparm.soil_cci and qrparm.veg.frac ancillary files and generates the ancillary qrparm.soil.dust

dust = iris.load( ANCIL_DIR / 'qrparm.soil.dust')
xr.DataArray.from_iris(dust[0]).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d301a34710>
../_images/241835258c8f7a607dbe846dc18a2c6e3659b34dee6e023ef4a52eadf12848a2.png

The flowchart below describes the dependencies of the above soil-related tasks.

Soil task flow

There are two stand-alone soils tasks.

The first is<Region>_<Resolution>_ancil_soil_roughness which uses the existing qrparm.veg.frac.nc file along with global MODIS leaf area index data and global soil roughness data to produce qrparm.soil_roughness.

rough, = iris.load( ANCIL_DIR / 'qrparm.soil_roughness')
/home/548/pag548/.local/lib/python3.12/site-packages/iris/fileformats/_ff.py:737: _WarnComboLoadingDefaulting: The stash code m01s00i097 is on a grid 0 which has not been explicitly handled by the fieldsfile loader. Assuming the data is on a P grid.
  warnings.warn(
xr.DataArray.from_iris(rough).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d3018948c0>
../_images/339a0fa265f4ea843604769242f7841eb011325b7a6a795c2ce5c73352952d8f.png

The second task is related to soil hydrology and is called<Region>_<Resolution>_ancil_topographic_index. It also uses qrparm.veg.frac.nc file along with global topographic wetness index data to produce qrparm.hydtop.

topo = iris.load( ANCIL_DIR / 'qrparm.hydtop')
xr.DataArray.from_iris(topo[0]).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d300b87500>
../_images/613c0da18cdfbfbd5c4586a3eeef345444c134dc462af5bc80438852aee8c143.png

Step 8. Process leaf and canopy data.#

We need to populate the vegetation with leaf and canopy data. The first task is <Region>_<Resolution>_ancil_lai which processes ‘Leaf Area Index’ and produces a temporary file lai.

lai, = iris.load( ANCIL_DIR / 'lai')
xr.DataArray.from_iris(lai)[0,0].plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d300abe300>
../_images/28bcab265e356647a93986f33d970719b724514124a54399de0cbd0e7446a3db.png

The next task <Region>_<Resolution>_ancil_canopy_heights combines the lai ancillary with tree data and canopy height factors and writes the data to qrparm.veg.func

lai_canopy = iris.load( ANCIL_DIR / 'qrparm.veg.func')
xr.DataArray.from_iris(lai_canopy[0][0,0]).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d300827620>
../_images/38dbaddeb32d31c055d4ca2e20250b4dfb39bd1d70b56fdb327d608a55db4c9f.png

The flowchart below describes the dependencies of the above soil-related tasks.

LAI flow

Step 9. Process SST/ice and snow#

The last multi-step tasks which contain a chain of dependencies begins with <Region>_<Resolution>_ancil_cap_vegfrac. Like the previous ancil_cap task, this uses an older FORTRAN binary and is independent of the python-based ants workflow.

This task outputs

  • qrparm.veg.func_igbp

  • qrparm.veg.frac_igbp

  • qrparm.veg.dist

  • qrparm.soil.dust_igbp

And it updates qrparm.soil.

veg_frac_igbp, = iris.load( ANCIL_DIR / 'qrparm.veg.frac_igbp')
xr.DataArray.from_iris(veg_frac_igbp)[3].plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d30082de80>
../_images/6ff5803ac43a7c90cb30c85c499aa6130c946afb02046ba9c983c0a124305ace.png
soil_dust = iris.load( ANCIL_DIR / 'qrparm.soil.dust_igbp')
xr.DataArray.from_iris(soil_dust[0]).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d3008451f0>
../_images/a71e9353b6d463dc7d8a1b20a285e1d595e6aa85d1801d823549e57f7dba717d.png
soil = iris.load( ANCIL_DIR / 'qrparm.soil')
xr.DataArray.from_iris(soil_dust[4]).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d30184a270>
../_images/2e70f134f0da5fdb15280271b161eff204da8c10dff978018e853970b0b710c6.png

There are two tasks downstream of <Region>_<Resolution>_ancil_cap_vegfrac. One is <Region>_<Resolution>_ancil_cap_sstice. This task processes global climatologies for seaice and SSTs

  • qrclim.sst

  • qrclim.seaice

seaice = iris.load( ANCIL_DIR / 'qrclim.seaice')
xr.DataArray.from_iris(seaice[1][0]).plot(edgecolor='grey',linewidth=0.5)
/jobfs/179310500.gadi-pbs/ipykernel_848699/979677363.py:1: FutureWarning: In a future version, xarray will not decode the variable 'forecast_period' into a timedelta64 dtype based on the presence of a timedelta-like 'units' attribute by default. Instead it will rely on the presence of a timedelta64 'dtype' attribute, which is now xarray's default way of encoding timedelta64 values.
To continue decoding into a timedelta64 dtype, either set `decode_timedelta=True` when opening this dataset, or add the attribute `dtype='timedelta64[ns]'` to this variable on disk.
To opt-in to future behavior, set `decode_timedelta=False`.
  xr.DataArray.from_iris(seaice[1][0]).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d300b6e630>
../_images/3d88fb7214a3ba37125598d32c6d1faaecc1c5ab1ac7d03e2b1f9c026bd1f2a7.png
sst = iris.load( ANCIL_DIR / 'qrclim.sst')
xr.DataArray.from_iris(sst[0][0]).plot(edgecolor='grey',linewidth=0.5)
/jobfs/179310500.gadi-pbs/ipykernel_848699/1747977962.py:1: FutureWarning: In a future version, xarray will not decode the variable 'forecast_period' into a timedelta64 dtype based on the presence of a timedelta-like 'units' attribute by default. Instead it will rely on the presence of a timedelta64 'dtype' attribute, which is now xarray's default way of encoding timedelta64 values.
To continue decoding into a timedelta64 dtype, either set `decode_timedelta=True` when opening this dataset, or add the attribute `dtype='timedelta64[ns]'` to this variable on disk.
To opt-in to future behavior, set `decode_timedelta=False`.
  xr.DataArray.from_iris(sst[0][0]).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d3005743e0>
../_images/f3766326985c99555ac4da8eaa7f0af270e089a484d57d1801de3bf595e93895.png

The other task is <Region>_<Resolution>_ancil_cap_smcsnow. This task processes global climatologies for soil moisture content and snow. The output is qrclim.smow

smow = iris.load( ANCIL_DIR / 'qrclim.smow')
/home/548/pag548/.local/lib/python3.12/site-packages/iris/fileformats/pp.py:1490: CFWarning: this date/calendar/year zero convention is not supported by CF
  self._t1 = cftime.datetime(
/home/548/pag548/.local/lib/python3.12/site-packages/iris/fileformats/pp.py:1523: CFWarning: this date/calendar/year zero convention is not supported by CF
  self._t2 = cftime.datetime(
xr.DataArray.from_iris(smow[6][0]).plot(edgecolor='grey',linewidth=0.5)
/jobfs/179310500.gadi-pbs/ipykernel_848699/217714727.py:1: FutureWarning: In a future version, xarray will not decode the variable 'forecast_period' into a timedelta64 dtype based on the presence of a timedelta-like 'units' attribute by default. Instead it will rely on the presence of a timedelta64 'dtype' attribute, which is now xarray's default way of encoding timedelta64 values.
To continue decoding into a timedelta64 dtype, either set `decode_timedelta=True` when opening this dataset, or add the attribute `dtype='timedelta64[ns]'` to this variable on disk.
To opt-in to future behavior, set `decode_timedelta=False`.
  xr.DataArray.from_iris(smow[6][0]).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d300399fd0>
../_images/127ee12e1420e69867e5b4a1fc31de647fd15d652ea162e453babce16b494459.png

The flowchart below shows the task dependencies for all cap related tasks.

Cap flow

Step 10. Process remaining stand-alone tasks.#

The last stand-alone tasks can be divided into three sections. The first is ozone processing:

  • <Region>_<Resolution>_ancil_cap_ozone

which uses the FORTRAN exectuable. The next group of tasks compute aerosol climatologies as specified in the suite.rc

{% set AERO_CLIMS = ["biog", "biom", "blck", "dust", "ocff", "sslt", "sulp"] %}
  • <Region>_<Resolution>_ancil_ocff

  • <Region>_<Resolution>_ancil_biog

  • <Region>_<Resolution>_ancil_biom

  • <Region>_<Resolution>_ancil_blck

  • <Region>_<Resolution>_ancil_sslt

  • <Region>_<Resolution>_ancil_sulp

  • <Region>_<Resolution>_ancil_dust

They simply regrid the global climatologies of these quantities onto the local lat/lon grid and the specified vertical levels. They output both UM ancillary format and netCDF files.

These are the remaining tasks that use the python ants workflows.

  • <Region>_<Resolution>_ancil_topographic_index

  • <Region>_<Resolution>_ancil_clim_sea

  • <Region>_<Resolution>_ancil_lake

Let’s examine the outputs of these tasks.

<Region>_<Resolution>_ancil_cap_ozone produces the local ozone climatology qrclim.ozone.unfix

ozone, = iris.load( ANCIL_DIR / 'qrclim.ozone.unfix')
/home/548/pag548/.local/lib/python3.12/site-packages/iris/fileformats/_ff.py:737: _WarnComboLoadingDefaulting: The stash code m01s00i060 is on a grid 22 which has not been explicitly handled by the fieldsfile loader. Assuming the data is on a P grid.
  warnings.warn(
/home/548/pag548/.local/lib/python3.12/site-packages/iris/fileformats/rules.py:376: IrisUserWarning: Unable to create instance of HybridPressureFactory. The source data contains no field(s) for 'surface_air_pressure'.
  warnings.warn(
xr.DataArray.from_iris(ozone[0]).plot(edgecolor='grey',linewidth=0.5)
/jobfs/179310500.gadi-pbs/ipykernel_848699/2504981220.py:1: FutureWarning: In a future version, xarray will not decode the variable 'forecast_period' into a timedelta64 dtype based on the presence of a timedelta-like 'units' attribute by default. Instead it will rely on the presence of a timedelta64 'dtype' attribute, which is now xarray's default way of encoding timedelta64 values.
To continue decoding into a timedelta64 dtype, either set `decode_timedelta=True` when opening this dataset, or add the attribute `dtype='timedelta64[ns]'` to this variable on disk.
To opt-in to future behavior, set `decode_timedelta=False`.
  xr.DataArray.from_iris(ozone[0]).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d30081c8c0>
../_images/62cab4063b6861163da6114fec36b2fa2cf3a0c88c88f92fd93c549abd06cc2b.png

Let’s now examine the aerosol climatologies:

  • <Region>_<Resolution>_ancil_ocff produces dry aerosol climatologies of organic carbon from fossil fuels and is stored in qrclim.ocff.

  • <Region>_<Resolution>_ancil_sulp produces dry aerosol climatologies of sulfate and is stored in qrclim.sulp.

  • <Region>_<Resolution>_ancil_biog produces aerosol climatologies of biogenic Non-Methane Volatile Organic Compounds and is stored in qrclim.biog.

  • <Region>_<Resolution>_ancil_blk produces aerosol climatologies of black carbon and are stored in qrclim.blck.

  • <Region>_<Resolution>_ancil_biom produces aerosol climatologies of fresh burning biomass and is stored in qrclim.biom.

  • <Region>_<Resolution>_ancil_sslt produces aerosol climatologies of sea salt particles and is stored in qrclim.sslt.

  • <Region>_<Resolution>_ancil_dust produces aerosol climatologies of dust and is stored in qrclim.dust.

AERO_CLIMS = ["biog", "biom", "blck", "dust", "ocff", "sslt", "sulp"]

fig = plt.figure(figsize=(12,10))
num_rows=3
num_columns=3
Position=range(1,len(AERO_CLIMS)+1)
k=0
for CLIM in AERO_CLIMS:
    clim = iris.load( ANCIL_DIR / f'qrclim.{CLIM}')
    ax = fig.add_subplot(num_rows, num_columns, Position[k])
    xr.DataArray.from_iris(clim[0][0,0]).plot(ax=ax)
    ax.set_title(CLIM)
    k+=1
plt.tight_layout()
/home/548/pag548/.local/lib/python3.12/site-packages/iris/fileformats/rules.py:376: IrisUserWarning: Unable to create instance of HybridHeightFactory. The source data contains no field(s) for 'orography'.
  warnings.warn(
/jobfs/179310500.gadi-pbs/ipykernel_848699/2672610593.py:11: FutureWarning: In a future version, xarray will not decode the variable 'forecast_period' into a timedelta64 dtype based on the presence of a timedelta-like 'units' attribute by default. Instead it will rely on the presence of a timedelta64 'dtype' attribute, which is now xarray's default way of encoding timedelta64 values.
To continue decoding into a timedelta64 dtype, either set `decode_timedelta=True` when opening this dataset, or add the attribute `dtype='timedelta64[ns]'` to this variable on disk.
To opt-in to future behavior, set `decode_timedelta=False`.
  xr.DataArray.from_iris(clim[0][0,0]).plot(ax=ax)
/home/548/pag548/.local/lib/python3.12/site-packages/iris/fileformats/rules.py:376: IrisUserWarning: Unable to create instance of HybridHeightFactory. The source data contains no field(s) for 'orography'.
  warnings.warn(
/jobfs/179310500.gadi-pbs/ipykernel_848699/2672610593.py:11: FutureWarning: In a future version, xarray will not decode the variable 'forecast_period' into a timedelta64 dtype based on the presence of a timedelta-like 'units' attribute by default. Instead it will rely on the presence of a timedelta64 'dtype' attribute, which is now xarray's default way of encoding timedelta64 values.
To continue decoding into a timedelta64 dtype, either set `decode_timedelta=True` when opening this dataset, or add the attribute `dtype='timedelta64[ns]'` to this variable on disk.
To opt-in to future behavior, set `decode_timedelta=False`.
  xr.DataArray.from_iris(clim[0][0,0]).plot(ax=ax)
/home/548/pag548/.local/lib/python3.12/site-packages/iris/fileformats/rules.py:376: IrisUserWarning: Unable to create instance of HybridHeightFactory. The source data contains no field(s) for 'orography'.
  warnings.warn(
/jobfs/179310500.gadi-pbs/ipykernel_848699/2672610593.py:11: FutureWarning: In a future version, xarray will not decode the variable 'forecast_period' into a timedelta64 dtype based on the presence of a timedelta-like 'units' attribute by default. Instead it will rely on the presence of a timedelta64 'dtype' attribute, which is now xarray's default way of encoding timedelta64 values.
To continue decoding into a timedelta64 dtype, either set `decode_timedelta=True` when opening this dataset, or add the attribute `dtype='timedelta64[ns]'` to this variable on disk.
To opt-in to future behavior, set `decode_timedelta=False`.
  xr.DataArray.from_iris(clim[0][0,0]).plot(ax=ax)
/home/548/pag548/.local/lib/python3.12/site-packages/iris/fileformats/rules.py:376: IrisUserWarning: Unable to create instance of HybridHeightFactory. The source data contains no field(s) for 'orography'.
  warnings.warn(
/jobfs/179310500.gadi-pbs/ipykernel_848699/2672610593.py:11: FutureWarning: In a future version, xarray will not decode the variable 'forecast_period' into a timedelta64 dtype based on the presence of a timedelta-like 'units' attribute by default. Instead it will rely on the presence of a timedelta64 'dtype' attribute, which is now xarray's default way of encoding timedelta64 values.
To continue decoding into a timedelta64 dtype, either set `decode_timedelta=True` when opening this dataset, or add the attribute `dtype='timedelta64[ns]'` to this variable on disk.
To opt-in to future behavior, set `decode_timedelta=False`.
  xr.DataArray.from_iris(clim[0][0,0]).plot(ax=ax)
/home/548/pag548/.local/lib/python3.12/site-packages/iris/fileformats/rules.py:376: IrisUserWarning: Unable to create instance of HybridHeightFactory. The source data contains no field(s) for 'orography'.
  warnings.warn(
/jobfs/179310500.gadi-pbs/ipykernel_848699/2672610593.py:11: FutureWarning: In a future version, xarray will not decode the variable 'forecast_period' into a timedelta64 dtype based on the presence of a timedelta-like 'units' attribute by default. Instead it will rely on the presence of a timedelta64 'dtype' attribute, which is now xarray's default way of encoding timedelta64 values.
To continue decoding into a timedelta64 dtype, either set `decode_timedelta=True` when opening this dataset, or add the attribute `dtype='timedelta64[ns]'` to this variable on disk.
To opt-in to future behavior, set `decode_timedelta=False`.
  xr.DataArray.from_iris(clim[0][0,0]).plot(ax=ax)
/home/548/pag548/.local/lib/python3.12/site-packages/iris/fileformats/rules.py:376: IrisUserWarning: Unable to create instance of HybridHeightFactory. The source data contains no field(s) for 'orography'.
  warnings.warn(
/jobfs/179310500.gadi-pbs/ipykernel_848699/2672610593.py:11: FutureWarning: In a future version, xarray will not decode the variable 'forecast_period' into a timedelta64 dtype based on the presence of a timedelta-like 'units' attribute by default. Instead it will rely on the presence of a timedelta64 'dtype' attribute, which is now xarray's default way of encoding timedelta64 values.
To continue decoding into a timedelta64 dtype, either set `decode_timedelta=True` when opening this dataset, or add the attribute `dtype='timedelta64[ns]'` to this variable on disk.
To opt-in to future behavior, set `decode_timedelta=False`.
  xr.DataArray.from_iris(clim[0][0,0]).plot(ax=ax)
/home/548/pag548/.local/lib/python3.12/site-packages/iris/fileformats/rules.py:376: IrisUserWarning: Unable to create instance of HybridHeightFactory. The source data contains no field(s) for 'orography'.
  warnings.warn(
/jobfs/179310500.gadi-pbs/ipykernel_848699/2672610593.py:11: FutureWarning: In a future version, xarray will not decode the variable 'forecast_period' into a timedelta64 dtype based on the presence of a timedelta-like 'units' attribute by default. Instead it will rely on the presence of a timedelta64 'dtype' attribute, which is now xarray's default way of encoding timedelta64 values.
To continue decoding into a timedelta64 dtype, either set `decode_timedelta=True` when opening this dataset, or add the attribute `dtype='timedelta64[ns]'` to this variable on disk.
To opt-in to future behavior, set `decode_timedelta=False`.
  xr.DataArray.from_iris(clim[0][0,0]).plot(ax=ax)
../_images/6aa670f710cb6479947779864918dd09396a2dc9e60dd6eb62a77a395f6a4498.png

The remainings tasks are :

  • <Region>_<Resolution>_ancil_clim_sea which produces climatology of ocean chlorophyll concentrations which are stored in qrclim.sea

sea, = iris.load( ANCIL_DIR / 'qrclim.sea')
xr.DataArray.from_iris(sea[0]).plot(edgecolor='grey',linewidth=0.5)
/jobfs/179310500.gadi-pbs/ipykernel_848699/3069948462.py:1: FutureWarning: In a future version, xarray will not decode the variable 'forecast_period' into a timedelta64 dtype based on the presence of a timedelta-like 'units' attribute by default. Instead it will rely on the presence of a timedelta64 'dtype' attribute, which is now xarray's default way of encoding timedelta64 values.
To continue decoding into a timedelta64 dtype, either set `decode_timedelta=True` when opening this dataset, or add the attribute `dtype='timedelta64[ns]'` to this variable on disk.
To opt-in to future behavior, set `decode_timedelta=False`.
  xr.DataArray.from_iris(sea[0]).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d2fbff4710>
../_images/bf74837dd5e9db65ee3eb8867356c567e8ede1d2d91d6132dd314ee311e604a6.png
  • <Region>_<Resolution>_ancil_lake which regrids the global lake mask dataset and produces the local ancillary file qrparm.lake.

global_lake_file = Path('/home/548/pag548/cylc-run/rCM3-ancil-suite/share/data/etc/ancil_master_ants//lake/ARClake/v2/qrdata.mask.nc')
global_lake = xr.load_dataset(global_lake_file)
global_lake.lake_mask.plot()
<matplotlib.collections.QuadMesh at 0x14d2fbff64b0>
../_images/7a8ecc0c1c33f05d41fa4a6c772a3707554584556c7dd020317ce2db69cf38ba.png
lake, = iris.load( ANCIL_DIR / 'qrparm.lake')
xr.DataArray.from_iris(lake).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d2fbde3f50>
../_images/5e405422e31675b0fcb49dbaa2b4f9fadfc448e19a4e13cd8e373119780b5230.png

The global lake dataset identifies large inland lakes (e.g. Caspian Sea, The Great Lakes) and sets a mask value of -128 everywhere else

  • <Region>_<Resolution>_ancil_lct_postproc_moruses performs a two-type urban fraction and urban morphology post-processor to implement the Met Office–Reading Urban Surface Exchange Scheme (MORUSES). The intermediate output file is qrparm.MORUSES.morph

moru = iris.load( ANCIL_DIR / 'qrparm.MORUSES.morph')
xr.DataArray.from_iris(moru[0]).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d2fbfac8c0>
../_images/1e0b0209b959c7bdccc89937959d590b702ad8b08d8843f3bfae62208d08e88b.png
  • <Region>_<Resolution>_ancil_lct_land runs the application app/ancil_snowfree_albedo/rose-app.conf. The suite logic in suite-runtime/ants.rc states:

    [[{{ancil(regn, resln)}}_land]]
        # SW snow-free surface albedo.
        inherit = {{ancil(regn, resln)}},ANCIL_SNOWFREE_ALBEDO

and

    [[ANCIL_SNOWFREE_ALBEDO]]
        inherit = ANCIL_ANTS, HOST_ANTS_MPP
        [[[environment]]]
            ROSE_TASK_APP=ancil_snowfree_albedo

The output of this task is qrclim.land

land = iris.load( ANCIL_DIR / 'qrclim.land')
xr.DataArray.from_iris(land[0][0]).plot(edgecolor='grey',linewidth=0.5)
/jobfs/179310500.gadi-pbs/ipykernel_848699/2023900724.py:1: FutureWarning: In a future version, xarray will not decode the variable 'forecast_period' into a timedelta64 dtype based on the presence of a timedelta-like 'units' attribute by default. Instead it will rely on the presence of a timedelta64 'dtype' attribute, which is now xarray's default way of encoding timedelta64 values.
To continue decoding into a timedelta64 dtype, either set `decode_timedelta=True` when opening this dataset, or add the attribute `dtype='timedelta64[ns]'` to this variable on disk.
To opt-in to future behavior, set `decode_timedelta=False`.
  xr.DataArray.from_iris(land[0][0]).plot(edgecolor='grey',linewidth=0.5)
<matplotlib.collections.QuadMesh at 0x14d2fbdaaea0>
../_images/bff07dbc9b3f0858e0312ba4cb0d385c761554bdc195128592352846e25b40fa.png

How do I check the validity of the ancillaries?#

Now run the notebook ‘Check_UM_ancils.ipynb’ to confirm:

  • Your ancillaries generated with the python ants and Fortran cap workflows have the same co-ordinates (to within reasonable precision).

  • There are no empty (or NaN values) over the land area defined by the land-sea mask

You can access the notebook here : 21centuryweather/UM_configuration_tools

and in Cell 7, set

ROSE=RAS_minimum_working_example