These examples are based on the CMOR repository’s examples/c directory. They use the same shared CMIP7 user input file as the Python and Fortran examples and load CMIP7 tables from a local clone of WCRP-CMIP/cmip7-cmor-tables.

Create and activate a Conda or Mamba environment with CMOR and a C compiler:

mamba create -n cmor-c -c conda-forge cmor c-compiler libnetcdf udunits2 json-c libuuid
mamba activate cmor-c

If you use Conda instead of Mamba, use the same package list:

conda create -n cmor-c -c conda-forge cmor c-compiler libnetcdf udunits2 json-c libuuid
conda activate cmor-c

Install the CMIP7 tables in the working directory where you will run the examples:

git clone https://github.com/WCRP-CMIP/cmip7-cmor-tables.git

Run the examples from a working directory that contains the cmip7-cmor-tables repository using the run_examples.sh script:

chmod a+x run_examples.sh
./run_examples.sh

The examples expect tables under ./cmip7-cmor-tables/tables in the directory where you run the script. To use a different table location, set CMOR_TABLES_PATH to the directory containing the CMIP7 table JSON files. To use a different user input file, set CMOR_INPUT_PATH.

Each example builds the CMIP7 compound variable name and uses it to read CMIP7_cell_measures.json and CMIP7_long_name_overrides.json before writing data. The fixed-field example overrides frequency from the shared user input file to fx.

CMOR Input Files

Click to expand shared JSON input
{
  "_AXIS_ENTRY_FILE": "CMIP7_coordinate.json",
  "_FORMULA_VAR_FILE": "CMIP7_formula_terms.json",
  "_cmip7_option": 1,
  "_controlled_vocabulary_file": "../tables-cvs/cmor-cvs.json",
  "activity_id": "CMIP",
  "archive_id": "WCRP",
  "calendar": "360_day",
  "experiment_id": "amip",
  "forcing_index": "f1",
  "frequency": "mon",
  "grid_label": "g999",
  "host_collection": "CMIP7",
  "initialization_index": "i1",
  "institution_id": "MOHC",
  "license_id": "CC-BY-4.0",
  "nominal_resolution": "100 km",
  "outpath": "output",
  "physics_index": "p1",
  "realization_index": "r1",
  "region": "glb",
  "source_id": "ACCESS-ESM1-6"
}

Common C Utilities

Click to expand common C header
#ifndef CMIP7_C_COMMON_H
#define CMIP7_C_COMMON_H

#include "cmor.h"
#include <stddef.h>

#define CMIP7_NLON 4
#define CMIP7_NLAT 3
#define CMIP7_NTIMES 2
#define CMIP7_MISSING_VALUE 1.0e20f
#define CMIP7_PATH_MAX 4096

void cmip7_get_example_args(int argc, char **argv, const char **tables_path,
                            const char **input_path, const char **output_dir);
void cmip7_load_shared_user_input(const char *input_path,
                                  const char *output_dir,
                                  const char *frequency,
                                  const char *realization_index,
                                  const char *forcing_index);
void cmip7_get_cell_measures(const char *tables_path, const char *realm,
                             const char *table_entry, const char *frequency,
                             const char *region, char *value,
                             size_t value_size);
int cmip7_get_long_name_override(const char *tables_path, const char *realm,
                                 const char *table_entry, const char *frequency,
                                 const char *region, char *value,
                                 size_t value_size);

#endif

Click to expand common C code
#include "cmip7_c_common.h"

#include <json-c/json.h>
#include <string.h>

static void copy_string(char *out, size_t out_size, const char *value) {
  if (out_size > 0) {
    snprintf(out, out_size, "%s", value);
  }
}

static void join_path(char *out, size_t out_size, const char *left,
                      const char *right) {
  size_t left_len = strlen(left);

  if (left_len > 0 && left[left_len - 1] == '/') {
    snprintf(out, out_size, "%s%s", left, right);
  } else {
    snprintf(out, out_size, "%s/%s", left, right);
  }
}

static void compound_name(char *out, size_t out_size, const char *realm,
                          const char *table_entry, const char *frequency,
                          const char *region) {
  char normalized[CMOR_MAX_STRING];
  size_t i;

  copy_string(normalized, sizeof(normalized), table_entry);
  for (i = 0; normalized[i] != '\0'; ++i) {
    if (normalized[i] == '_') {
      normalized[i] = '.';
    }
  }
  snprintf(out, out_size, "%s.%s.%s.%s", realm, normalized, frequency, region);
}

static void check_status(const char *call_name, int status) {
  if (status != 0) {
    fprintf(stderr, "%s failed with status %d\n", call_name, status);
    exit(1);
  }
}

void cmip7_get_example_args(int argc, char **argv, const char **tables_path,
                            const char **input_path, const char **output_dir) {
  *tables_path = argc > 1 && argv[1][0] != '\0' ? argv[1]
                                                 : "./cmip7-cmor-tables/tables";
  *input_path = argc > 2 && argv[2][0] != '\0' ? argv[2]
                                               : "./CMIP7_input_example.json";
  *output_dir = argc > 3 && argv[3][0] != '\0' ? argv[3] : "output";
}

void cmip7_load_shared_user_input(const char *input_path,
                                  const char *output_dir,
                                  const char *frequency,
                                  const char *realization_index,
                                  const char *forcing_index) {
  check_status("cmor_dataset_json", cmor_dataset_json((char *)input_path));
  check_status("cmor_set_cur_dataset_attribute(outpath)",
               cmor_set_cur_dataset_attribute("outpath", (char *)output_dir,
                                              1));
  if (frequency != NULL) {
    check_status("cmor_set_cur_dataset_attribute(frequency)",
                 cmor_set_cur_dataset_attribute("frequency", (char *)frequency,
                                                1));
  }
  if (realization_index != NULL) {
    check_status("cmor_set_cur_dataset_attribute(realization_index)",
                 cmor_set_cur_dataset_attribute(
                     "realization_index", (char *)realization_index, 1));
  }
  if (forcing_index != NULL) {
    check_status("cmor_set_cur_dataset_attribute(forcing_index)",
                 cmor_set_cur_dataset_attribute(
                     "forcing_index", (char *)forcing_index, 1));
  }
}

static int lookup_json_string(const char *path, const char *root_name,
                              const char *key, char *value, size_t value_size) {
  json_object *document = json_object_from_file(path);
  json_object *root = NULL;
  json_object *entry = NULL;

  value[0] = '\0';
  if (document == NULL) {
    fprintf(stderr, "Could not open CMIP7 metadata table %s\n", path);
    exit(1);
  }

  if (json_object_object_get_ex(document, root_name, &root) &&
      json_object_object_get_ex(root, key, &entry)) {
    copy_string(value, value_size, json_object_get_string(entry));
    json_object_put(document);
    return 1;
  }

  json_object_put(document);
  return 0;
}

void cmip7_get_cell_measures(const char *tables_path, const char *realm,
                             const char *table_entry, const char *frequency,
                             const char *region, char *value,
                             size_t value_size) {
  char key[CMOR_MAX_STRING];
  char path[CMIP7_PATH_MAX];

  compound_name(key, sizeof(key), realm, table_entry, frequency, region);
  join_path(path, sizeof(path), tables_path, "CMIP7_cell_measures.json");
  lookup_json_string(path, "cell_measures", key, value, value_size);
}

int cmip7_get_long_name_override(const char *tables_path, const char *realm,
                                 const char *table_entry, const char *frequency,
                                 const char *region, char *value,
                                 size_t value_size) {
  char key[CMOR_MAX_STRING];
  char path[CMIP7_PATH_MAX];

  compound_name(key, sizeof(key), realm, table_entry, frequency, region);
  join_path(path, sizeof(path), tables_path, "CMIP7_long_name_overrides.json");
  return lookup_json_string(path, "long_name_overrides", key, value,
                            value_size);
}

Click to expand runner script
#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
RUN_DIR="${RUN_DIR:-$PWD}"
TABLES_PATH="${CMOR_TABLES_PATH:-$RUN_DIR/cmip7-cmor-tables/tables}"
INPUT_PATH="${CMOR_INPUT_PATH:-$RUN_DIR/CMIP7_input_example.json}"
OUTPUT_ROOT="$SCRIPT_DIR/output"
BUILD_DIR="${BUILD_DIR:-$SCRIPT_DIR/build}"

cd "$SCRIPT_DIR"

if [[ -z "${CONDA_PREFIX:-}" ]]; then
  echo "Activate your conda environment or run: conda run -n <env-name> $0" >&2
  exit 2
fi

detect_c_compiler() {
  if [[ -n "${CC:-}" ]]; then
    command -v "$CC" >/dev/null 2>&1 || {
      echo "CC is set to '$CC', but that compiler was not found" >&2
      exit 2
    }
    echo "$CC"
    return
  fi

  local compiler
  for compiler in "$CONDA_PREFIX"/bin/*-cc "$CONDA_PREFIX"/bin/*-gcc "$CONDA_PREFIX"/bin/clang "$CONDA_PREFIX"/bin/gcc "$CONDA_PREFIX"/bin/cc; do
    if [[ -x "$compiler" ]]; then
      echo "$compiler"
      return
    fi
  done

  if command -v cc >/dev/null 2>&1; then
    command -v cc
    return
  fi

  echo "Could not find a C compiler. Install c-compiler in the active conda environment or set CC." >&2
  exit 2
}

mkdir -p "$BUILD_DIR" "$OUTPUT_ROOT"

if [[ ! -d "$TABLES_PATH" ]]; then
  echo "Could not find CMIP7 tables under $TABLES_PATH. Clone cmip7-cmor-tables or set CMOR_TABLES_PATH." >&2
  exit 2
fi

if [[ ! -f "$INPUT_PATH" ]]; then
  echo "Could not find CMIP7 user input JSON at $INPUT_PATH. Set CMOR_INPUT_PATH to override it." >&2
  exit 2
fi

CC="$(detect_c_compiler)"
CMOR_PREFIX="${CMOR_PREFIX:-$CONDA_PREFIX}"
CMOR_INCLUDE_DIR="${CMOR_INCLUDE_DIR:-$CMOR_PREFIX/include}"
CMOR_CDTIME_INCLUDE_DIR="${CMOR_CDTIME_INCLUDE_DIR:-$CMOR_INCLUDE_DIR/cdTime}"

if [[ -n "${CMOR_LIB:-}" ]]; then
  CMOR_LINK_FLAGS=("$CMOR_LIB")
elif [[ -f "$CMOR_PREFIX/lib/libcmor.a" ]]; then
  CMOR_LINK_FLAGS=("$CMOR_PREFIX/lib/libcmor.a")
elif [[ -f "$CMOR_PREFIX/lib/libcmor.dylib" || -f "$CMOR_PREFIX/lib/libcmor.so" ]]; then
  CMOR_LINK_FLAGS=("-L$CMOR_PREFIX/lib" "-lcmor")
else
  echo "Could not find CMOR in $CMOR_PREFIX. Install cmor in the active conda environment or set CMOR_PREFIX/CMOR_LIB." >&2
  exit 2
fi

if [[ ! -f "$CMOR_INCLUDE_DIR/cmor.h" ]]; then
  echo "Could not find cmor.h in $CMOR_INCLUDE_DIR. Install cmor in the active conda environment or set CMOR_INCLUDE_DIR." >&2
  exit 2
fi
if [[ ! -f "$CMOR_INCLUDE_DIR/cdmsint.h" && ! -f "$CMOR_CDTIME_INCLUDE_DIR/cdmsint.h" ]]; then
  echo "Could not find cdmsint.h in $CMOR_INCLUDE_DIR or $CMOR_CDTIME_INCLUDE_DIR. Install cmor in the active conda environment or set CMOR_CDTIME_INCLUDE_DIR." >&2
  exit 2
fi

CFLAGS_DEFAULT="-g -O2 -Wall -Wextra"
CFLAGS="${CFLAGS:-$CFLAGS_DEFAULT}"
EXTRA_LDFLAGS="${EXTRA_LDFLAGS:-}"
LINK_DIRS=("$CMOR_PREFIX/lib")
if [[ "$CONDA_PREFIX/lib" != "$CMOR_PREFIX/lib" ]]; then
  LINK_DIRS+=("$CONDA_PREFIX/lib")
fi

LINK_FLAGS=("${CMOR_LINK_FLAGS[@]}")
for link_dir in "${LINK_DIRS[@]}"; do
  LINK_FLAGS+=("-L$link_dir")
done
LINK_FLAGS+=("-lnetcdf" "-ludunits2" "-ljson-c" "-luuid" "-lm")
for link_dir in "${LINK_DIRS[@]}"; do
  LINK_FLAGS+=("-Wl,-rpath,$link_dir")
done

INCLUDES=("-I$SCRIPT_DIR" "-I$CMOR_INCLUDE_DIR" "-I$CMOR_CDTIME_INCLUDE_DIR" "-I$CONDA_PREFIX/include")
COMMON_SRC="$SCRIPT_DIR/cmip7_c_common.c"

examples=(
  example_01_regular_grid_tos
  example_02_pressure_levels
  example_03_scalar_height_tas
  example_04_basin_axis
  example_05_hybrid_sigma_levels
  example_06_curvilinear_grid
  example_07_fixed_field_rootd
)

for example in "${examples[@]}"; do
  src="$SCRIPT_DIR/$example.c"
  exe="$BUILD_DIR/$example"

  echo "Compiling $example"
  "$CC" $CFLAGS "${INCLUDES[@]}" "$COMMON_SRC" "$src" "${LINK_FLAGS[@]}" $EXTRA_LDFLAGS -o "$exe"

  echo "Running $example"
  "$exe" "$TABLES_PATH" "$INPUT_PATH" "$OUTPUT_ROOT"
done

echo "Wrote CMIP7 example output under $OUTPUT_ROOT"

Example 1: Regular Grid Ocean Field

Click to expand C code
#include "cmip7_c_common.h"

#include <stdio.h>

int main(int argc, char **argv) {
  const char *tables_path;
  const char *input_path;
  const char *output_dir;
  char cell_measures[CMOR_MAX_STRING];
  char long_name[CMOR_MAX_STRING];
  char filename[CMOR_MAX_STRING];
  int file_action = CMOR_REPLACE;
  int exit_control = CMOR_EXIT_ON_MAJOR;
  int table_id, lon_id, lat_id, time_id, var_id;
  int axes[3];
  double lat[CMIP7_NLAT] = {10.0, 20.0, 30.0};
  double lat_bnds[CMIP7_NLAT + 1] = {5.0, 15.0, 25.0, 35.0};
  double lon[CMIP7_NLON] = {0.0, 90.0, 180.0, 270.0};
  double lon_bnds[CMIP7_NLON + 1] = {-45.0, 45.0, 135.0, 225.0, 315.0};
  double time[CMIP7_NTIMES] = {15.5, 45.5};
  double time_bnds[CMIP7_NTIMES + 1] = {0.0, 31.0, 60.0};
  float tos[CMIP7_NTIMES * CMIP7_NLAT * CMIP7_NLON] = {
      254.0895f, 258.4085f, CMIP7_MISSING_VALUE, 258.7101f,
      258.6680f, 258.2990f, CMIP7_MISSING_VALUE, 255.0432f,
      253.7254f, 251.2460f, CMIP7_MISSING_VALUE, 255.4808f,
      254.0995f, 258.5085f, CMIP7_MISSING_VALUE, 258.8101f,
      258.8680f, 258.4990f, CMIP7_MISSING_VALUE, 255.2432f,
      254.0254f, 251.5460f, CMIP7_MISSING_VALUE, 255.7808f};
  float missing = CMIP7_MISSING_VALUE;

  cmip7_get_example_args(argc, argv, &tables_path, &input_path, &output_dir);

  cmor_setup((char *)tables_path, &file_action, NULL, &exit_control, NULL,
             NULL);
  cmip7_load_shared_user_input(input_path, output_dir, NULL, NULL, NULL);
  cmor_load_table("CMIP7_ocean.json", &table_id);

  cmor_axis(&lon_id, "longitude", "degrees_east", CMIP7_NLON, lon, 'd',
            lon_bnds, 1, NULL);
  cmor_axis(&lat_id, "latitude", "degrees_north", CMIP7_NLAT, lat, 'd',
            lat_bnds, 1, NULL);
  cmor_axis(&time_id, "time", "days since 1979-01-01", CMIP7_NTIMES, time, 'd',
            time_bnds, 1, NULL);

  axes[0] = time_id;
  axes[1] = lat_id;
  axes[2] = lon_id;
  cmor_variable(&var_id, "tos_tavg-u-hxy-sea", "degC", 3, axes, 'f', &missing,
                NULL, NULL, NULL, NULL, NULL);

  cmip7_get_cell_measures(tables_path, "ocean", "tos_tavg-u-hxy-sea", "mon",
                          "glb", cell_measures, sizeof(cell_measures));
  cmor_set_variable_attribute(var_id, "cell_measures", 'c', cell_measures);
  if (cmip7_get_long_name_override(tables_path, "ocean", "tos_tavg-u-hxy-sea",
                                   "mon", "glb", long_name,
                                   sizeof(long_name))) {
    cmor_set_variable_attribute(var_id, "long_name", 'c', long_name);
  }

  cmor_write(var_id, tos, 'f', NULL, CMIP7_NTIMES, NULL, NULL, NULL);
  filename[0] = '\0';
  cmor_close_variable(var_id, filename, NULL);
  printf("%s\n", filename);
  cmor_close();
  return 0;
}

Click to expand NetCDF dump
netcdf tos_tavg-u-hxy-sea_mon_glb_g999_ACCESS-ESM1-6_amip_r1i1p1f1_197901-197902 {
dimensions:
	time = UNLIMITED ; // (2 currently)
	lat = 3 ;
	lon = 4 ;
	bnds = 2 ;
variables:
	double time(time) ;
		time:bounds = "time_bnds" ;
		time:units = "days since 1979-01-01" ;
		time:calendar = "360_day" ;
		time:axis = "T" ;
		time:long_name = "Time Intervals" ;
		time:standard_name = "time" ;
	double time_bnds(time, bnds) ;
	double lat(lat) ;
		lat:bounds = "lat_bnds" ;
		lat:units = "degrees_north" ;
		lat:axis = "Y" ;
		lat:long_name = "Latitude" ;
		lat:standard_name = "latitude" ;
	double lat_bnds(lat, bnds) ;
	double lon(lon) ;
		lon:bounds = "lon_bnds" ;
		lon:units = "degrees_east" ;
		lon:axis = "X" ;
		lon:long_name = "Longitude" ;
		lon:standard_name = "longitude" ;
	double lon_bnds(lon, bnds) ;
	float tos(time, lat, lon) ;
		tos:standard_name = "sea_surface_temperature" ;
		tos:long_name = "Sea Surface Temperature" ;
		tos:units = "degC" ;
		tos:cell_methods = "area: mean where sea time: mean" ;
		tos:missing_value = 1.e+20f ;
		tos:_FillValue = 1.e+20f ;
		tos:cell_measures = "area: areacello" ;

// global attributes:
		:Conventions = "CF-1.12" ;
		:activity_id = "CMIP" ;
		:archive_id = "WCRP" ;
		:area_label = "sea" ;
		:branded_variable = "tos_tavg-u-hxy-sea" ;
		:branding_suffix = "tavg-u-hxy-sea" ;
		:creation_date = "2026-08-07T00:48:05Z" ;
		:data_specs_version = "MIP-DS7.1.0.0" ;
		:description = "Simulation of the climate of the recent past with prescribed sea surface temperatures and sea ice concentrations." ;
		:drs_specs = "MIP-DRS7" ;
		:experiment = "Simulation of the climate of the recent past with prescribed sea surface temperatures and sea ice concentrations." ;
		:experiment_id = "amip" ;
		:external_variables = "areacello" ;
		:forcing_index = "f1" ;
		:frequency = "mon" ;
		:grid_label = "g999" ;
		:history = "2026-08-07T00:48:05Z ; CMOR rewrote data to be consistent with CF-1.12 and CMIP7 data requirements." ;
		:horizontal_label = "hxy" ;
		:host_collection = "CMIP7" ;
		:initialization_index = "i1" ;
		:institution = "Met Office Hadley Centre" ;
		:institution_id = "MOHC" ;
		:license_id = "CC-BY-4.0" ;
		:mip_era = "CMIP7" ;
		:nominal_resolution = "100 km" ;
		:outpath = "/Users/mauzey1/Desktop/github/cmor3_documentation/mydoc/examples/c/output" ;
		:physics_index = "p1" ;
		:product = "model-output" ;
		:realization_index = "r1" ;
		:realm = "ocean" ;
		:region = "glb" ;
		:source = "ACCESS-ESM1-6: aerosol: classic; atmosphere: um7-3; land-surface: cable3; ocean-biogeochemistry: wombatlite; ocean: mom5; sea-ice: cice5" ;
		:source_id = "ACCESS-ESM1-6" ;
		:table_info = "Name: CMIP7_ocean.json; Creation Date:(2026-07-21 13:16:24) MD5:734c6f53560fa60b7c1c21b38e5b9a3f" ;
		:temporal_label = "tavg" ;
		:title = "ACCESS-ESM1-6 output prepared for CMIP7" ;
		:tracking_id = "hdl:21.14107/dceb0758-67b2-4935-8284-f247403bfec5" ;
		:variable_id = "tos" ;
		:variant_label = "r1i1p1f1" ;
		:vertical_label = "u" ;
		:license = "CC-BY-4.0; CMIP7 data produced by MOHC is licensed under a Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0). Consult https://wcrp-cmip.github.io/cmip7-guidance/docs/CMIP7/Guidance_for_users/#2-terms-of-use-and-citations-requirements for terms of use governing CMIP7 output, including citation requirements and proper acknowledgment. The data producers and data providers make no warranty, either express or implied, including, but not limited to, warranties of merchantability and fitness for a particular purpose. All liabilities arising from the supply of the information (including any liability arising in negligence) are excluded to the fullest extent permitted by law." ;
		:cmor_version = "3.15.2" ;
data:

 time = 15.5, 45.5 ;

 time_bnds =
  0, 31,
  31, 60 ;

 lat = 10, 20, 30 ;

 lat_bnds =
  5, 15,
  15, 25,
  25, 35 ;

 lon = 0, 90, 180, 270 ;

 lon_bnds =
  -45, 45,
  45, 135,
  135, 225,
  225, 315 ;

 tos =
  254.0895, 258.4085, _, 258.7101,
  258.668, 258.299, _, 255.0432,
  253.7254, 251.246, _, 255.4808,
  254.0995, 258.5085, _, 258.8101,
  258.868, 258.499, _, 255.2432,
  254.0254, 251.546, _, 255.7808 ;
}


Example 2: 3-D Field on Pressure Levels

Click to expand C code
#include "cmip7_c_common.h"

#include <stdio.h>

#define NPLEV 19

int main(int argc, char **argv) {
  const char *tables_path;
  const char *input_path;
  const char *output_dir;
  char cell_measures[CMOR_MAX_STRING];
  char long_name[CMOR_MAX_STRING];
  char filename[CMOR_MAX_STRING];
  int file_action = CMOR_REPLACE;
  int exit_control = CMOR_EXIT_ON_MAJOR;
  int table_id, lon_id, lat_id, time_id, plev_id, var_id;
  int axes[4];
  int i, j, k, t;
  double lat[CMIP7_NLAT] = {10.0, 20.0, 30.0};
  double lat_bnds[CMIP7_NLAT + 1] = {5.0, 15.0, 25.0, 35.0};
  double lon[CMIP7_NLON] = {0.0, 90.0, 180.0, 270.0};
  double lon_bnds[CMIP7_NLON + 1] = {-45.0, 45.0, 135.0, 225.0, 315.0};
  double time[CMIP7_NTIMES] = {15.5, 45.5};
  double time_bnds[CMIP7_NTIMES + 1] = {0.0, 31.0, 60.0};
  double plev[NPLEV] = {100000.0, 92500.0, 85000.0, 70000.0, 60000.0,
                        50000.0,  40000.0, 30000.0, 25000.0, 20000.0,
                        15000.0,  10000.0, 7000.0,  5000.0,  3000.0,
                        2000.0,   1000.0,  500.0,   100.0};
  float ta[CMIP7_NTIMES * NPLEV * CMIP7_NLAT * CMIP7_NLON];
  float missing = CMIP7_MISSING_VALUE;

  cmip7_get_example_args(argc, argv, &tables_path, &input_path, &output_dir);

  cmor_setup((char *)tables_path, &file_action, NULL, &exit_control, NULL,
             NULL);
  cmip7_load_shared_user_input(input_path, output_dir, NULL, NULL, NULL);
  cmor_load_table("CMIP7_atmos.json", &table_id);

  cmor_axis(&lon_id, "longitude", "degrees_east", CMIP7_NLON, lon, 'd',
            lon_bnds, 1, NULL);
  cmor_axis(&lat_id, "latitude", "degrees_north", CMIP7_NLAT, lat, 'd',
            lat_bnds, 1, NULL);
  cmor_axis(&time_id, "time", "days since 1979-01-01", CMIP7_NTIMES, time, 'd',
            time_bnds, 1, NULL);
  cmor_axis(&plev_id, "plev19", "Pa", NPLEV, plev, 'd', NULL, 0, NULL);

  for (t = 0; t < CMIP7_NTIMES; ++t) {
    for (k = 0; k < NPLEV; ++k) {
      for (j = 0; j < CMIP7_NLAT; ++j) {
        for (i = 0; i < CMIP7_NLON; ++i) {
          int idx = ((t * NPLEV + k) * CMIP7_NLAT + j) * CMIP7_NLON + i;
          ta[idx] = 250.0f +
                    25.0f *
                        (float)(i + 1 + 4 * (j + 1) + 12 * (k + 1) + 228 * t) /
                        (float)(CMIP7_NLON * CMIP7_NLAT * NPLEV * CMIP7_NTIMES);
        }
      }
    }
  }
  ta[0] = CMIP7_MISSING_VALUE;

  axes[0] = time_id;
  axes[1] = plev_id;
  axes[2] = lat_id;
  axes[3] = lon_id;
  cmor_variable(&var_id, "ta_tavg-p19-hxy-air", "K", 4, axes, 'f', &missing,
                NULL, NULL, NULL, NULL, NULL);

  cmip7_get_cell_measures(tables_path, "atmos", "ta_tavg-p19-hxy-air", "mon",
                          "glb", cell_measures, sizeof(cell_measures));
  cmor_set_variable_attribute(var_id, "cell_measures", 'c', cell_measures);
  if (cmip7_get_long_name_override(tables_path, "atmos", "ta_tavg-p19-hxy-air",
                                   "mon", "glb", long_name,
                                   sizeof(long_name))) {
    cmor_set_variable_attribute(var_id, "long_name", 'c', long_name);
  }

  cmor_write(var_id, ta, 'f', NULL, CMIP7_NTIMES, NULL, NULL, NULL);
  filename[0] = '\0';
  cmor_close_variable(var_id, filename, NULL);
  printf("%s\n", filename);
  cmor_close();
  return 0;
}

Click to expand NetCDF dump
netcdf ta_tavg-p19-hxy-air_mon_glb_g999_ACCESS-ESM1-6_amip_r1i1p1f1_197901-197902 {
dimensions:
	time = UNLIMITED ; // (2 currently)
	plev = 19 ;
	lat = 3 ;
	lon = 4 ;
	bnds = 2 ;
variables:
	double time(time) ;
		time:bounds = "time_bnds" ;
		time:units = "days since 1979-01-01" ;
		time:calendar = "360_day" ;
		time:axis = "T" ;
		time:long_name = "Time Intervals" ;
		time:standard_name = "time" ;
	double time_bnds(time, bnds) ;
	double plev(plev) ;
		plev:units = "Pa" ;
		plev:axis = "Z" ;
		plev:positive = "down" ;
		plev:long_name = "Pressure Levels (19)" ;
		plev:standard_name = "air_pressure" ;
	double lat(lat) ;
		lat:bounds = "lat_bnds" ;
		lat:units = "degrees_north" ;
		lat:axis = "Y" ;
		lat:long_name = "Latitude" ;
		lat:standard_name = "latitude" ;
	double lat_bnds(lat, bnds) ;
	double lon(lon) ;
		lon:bounds = "lon_bnds" ;
		lon:units = "degrees_east" ;
		lon:axis = "X" ;
		lon:long_name = "Longitude" ;
		lon:standard_name = "longitude" ;
	double lon_bnds(lon, bnds) ;
	float ta(time, plev, lat, lon) ;
		ta:standard_name = "air_temperature" ;
		ta:long_name = "Air Temperature" ;
		ta:units = "K" ;
		ta:cell_methods = "area: time: mean where air" ;
		ta:missing_value = 1.e+20f ;
		ta:_FillValue = 1.e+20f ;
		ta:cell_measures = "area: areacella" ;

// global attributes:
		:Conventions = "CF-1.12" ;
		:activity_id = "CMIP" ;
		:archive_id = "WCRP" ;
		:area_label = "air" ;
		:branded_variable = "ta_tavg-p19-hxy-air" ;
		:branding_suffix = "tavg-p19-hxy-air" ;
		:creation_date = "2026-08-07T00:48:05Z" ;
		:data_specs_version = "MIP-DS7.1.0.0" ;
		:description = "Simulation of the climate of the recent past with prescribed sea surface temperatures and sea ice concentrations." ;
		:drs_specs = "MIP-DRS7" ;
		:experiment = "Simulation of the climate of the recent past with prescribed sea surface temperatures and sea ice concentrations." ;
		:experiment_id = "amip" ;
		:external_variables = "areacella" ;
		:forcing_index = "f1" ;
		:frequency = "mon" ;
		:grid_label = "g999" ;
		:history = "2026-08-07T00:48:05Z ; CMOR rewrote data to be consistent with CF-1.12 and CMIP7 data requirements." ;
		:horizontal_label = "hxy" ;
		:host_collection = "CMIP7" ;
		:initialization_index = "i1" ;
		:institution = "Met Office Hadley Centre" ;
		:institution_id = "MOHC" ;
		:license_id = "CC-BY-4.0" ;
		:mip_era = "CMIP7" ;
		:nominal_resolution = "100 km" ;
		:outpath = "/Users/mauzey1/Desktop/github/cmor3_documentation/mydoc/examples/c/output" ;
		:physics_index = "p1" ;
		:product = "model-output" ;
		:realization_index = "r1" ;
		:realm = "atmos" ;
		:region = "glb" ;
		:source = "ACCESS-ESM1-6: aerosol: classic; atmosphere: um7-3; land-surface: cable3; ocean-biogeochemistry: wombatlite; ocean: mom5; sea-ice: cice5" ;
		:source_id = "ACCESS-ESM1-6" ;
		:table_info = "Name: CMIP7_atmos.json; Creation Date:(2026-07-21 13:16:24) MD5:28339aa355908b9331150e1536f5e384" ;
		:temporal_label = "tavg" ;
		:title = "ACCESS-ESM1-6 output prepared for CMIP7" ;
		:tracking_id = "hdl:21.14107/98acdd2d-a903-4e53-9f2b-3c61856d3f2d" ;
		:variable_id = "ta" ;
		:variant_label = "r1i1p1f1" ;
		:vertical_label = "p19" ;
		:license = "CC-BY-4.0; CMIP7 data produced by MOHC is licensed under a Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0). Consult https://wcrp-cmip.github.io/cmip7-guidance/docs/CMIP7/Guidance_for_users/#2-terms-of-use-and-citations-requirements for terms of use governing CMIP7 output, including citation requirements and proper acknowledgment. The data producers and data providers make no warranty, either express or implied, including, but not limited to, warranties of merchantability and fitness for a particular purpose. All liabilities arising from the supply of the information (including any liability arising in negligence) are excluded to the fullest extent permitted by law." ;
		:cmor_version = "3.15.2" ;
data:

 time = 15.5, 45.5 ;

 time_bnds =
  0, 31,
  31, 60 ;

 plev = 100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 
    20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000, 500, 100 ;

 lat = 10, 20, 30 ;

 lat_bnds =
  5, 15,
  15, 25,
  25, 35 ;

 lon = 0, 90, 180, 270 ;

 lon_bnds =
  -45, 45,
  45, 135,
  135, 225,
  225, 315 ;

 ta =
  _, 250.9868, 251.0417, 251.0965,
  251.1513, 251.2061, 251.261, 251.3158,
  251.3706, 251.4254, 251.4803, 251.5351,
  251.5899, 251.6447, 251.6996, 251.7544,
  251.8092, 251.864, 251.9189, 251.9737,
  252.0285, 252.0833, 252.1382, 252.193,
  252.2478, 252.3026, 252.3575, 252.4123,
  252.4671, 252.5219, 252.5768, 252.6316,
  252.6864, 252.7412, 252.7961, 252.8509,
  252.9057, 252.9605, 253.0154, 253.0702,
  253.125, 253.1798, 253.2346, 253.2895,
  253.3443, 253.3991, 253.4539, 253.5088,
  253.5636, 253.6184, 253.6732, 253.7281,
  253.7829, 253.8377, 253.8925, 253.9474,
  254.0022, 254.057, 254.1118, 254.1667,
  254.2215, 254.2763, 254.3311, 254.386,
  254.4408, 254.4956, 254.5504, 254.6053,
  254.6601, 254.7149, 254.7697, 254.8246,
  254.8794, 254.9342, 254.989, 255.0439,
  255.0987, 255.1535, 255.2083, 255.2632,
  255.318, 255.3728, 255.4276, 255.4825,
  255.5373, 255.5921, 255.6469, 255.7018,
  255.7566, 255.8114, 255.8662, 255.9211,
  255.9759, 256.0307, 256.0855, 256.1404,
  256.1952, 256.25, 256.3048, 256.3596,
  256.4145, 256.4693, 256.5241, 256.5789,
  256.6338, 256.6886, 256.7434, 256.7982,
  256.8531, 256.9079, 256.9627, 257.0175,
  257.0724, 257.1272, 257.182, 257.2368,
  257.2917, 257.3465, 257.4013, 257.4561,
  257.511, 257.5658, 257.6206, 257.6754,
  257.7303, 257.7851, 257.8399, 257.8947,
  257.9496, 258.0044, 258.0592, 258.114,
  258.1689, 258.2237, 258.2785, 258.3333,
  258.3882, 258.443, 258.4978, 258.5526,
  258.6075, 258.6623, 258.7171, 258.7719,
  258.8268, 258.8816, 258.9364, 258.9912,
  259.0461, 259.1009, 259.1557, 259.2105,
  259.2654, 259.3202, 259.375, 259.4298,
  259.4846, 259.5395, 259.5943, 259.6491,
  259.7039, 259.7588, 259.8136, 259.8684,
  259.9232, 259.9781, 260.0329, 260.0877,
  260.1425, 260.1974, 260.2522, 260.307,
  260.3618, 260.4167, 260.4715, 260.5263,
  260.5811, 260.636, 260.6908, 260.7456,
  260.8004, 260.8553, 260.9101, 260.9649,
  261.0197, 261.0746, 261.1294, 261.1842,
  261.239, 261.2939, 261.3487, 261.4035,
  261.4583, 261.5132, 261.568, 261.6228,
  261.6776, 261.7325, 261.7873, 261.8421,
  261.8969, 261.9518, 262.0066, 262.0614,
  262.1162, 262.1711, 262.2259, 262.2807,
  262.3355, 262.3904, 262.4452, 262.5,
  262.5548, 262.6096, 262.6645, 262.7193,
  262.7741, 262.8289, 262.8838, 262.9386,
  262.9934, 263.0482, 263.1031, 263.1579,
  263.2127, 263.2675, 263.3224, 263.3772,
  263.432, 263.4868, 263.5417, 263.5965,
  263.6513, 263.7061, 263.761, 263.8158,
  263.8706, 263.9254, 263.9803, 264.0351,
  264.0899, 264.1447, 264.1996, 264.2544,
  264.3092, 264.364, 264.4189, 264.4737,
  264.5285, 264.5833, 264.6382, 264.693,
  264.7478, 264.8026, 264.8575, 264.9123,
  264.9671, 265.0219, 265.0768, 265.1316,
  265.1864, 265.2412, 265.2961, 265.3509,
  265.4057, 265.4605, 265.5154, 265.5702,
  265.625, 265.6798, 265.7346, 265.7895,
  265.8443, 265.8991, 265.9539, 266.0088,
  266.0636, 266.1184, 266.1732, 266.2281,
  266.2829, 266.3377, 266.3925, 266.4474,
  266.5022, 266.557, 266.6118, 266.6667,
  266.7215, 266.7763, 266.8311, 266.886,
  266.9408, 266.9956, 267.0504, 267.1053,
  267.1601, 267.2149, 267.2697, 267.3246,
  267.3794, 267.4342, 267.489, 267.5439,
  267.5987, 267.6535, 267.7083, 267.7632,
  267.818, 267.8728, 267.9276, 267.9825,
  268.0373, 268.0921, 268.1469, 268.2018,
  268.2566, 268.3114, 268.3662, 268.4211,
  268.4759, 268.5307, 268.5855, 268.6404,
  268.6952, 268.75, 268.8048, 268.8596,
  268.9145, 268.9693, 269.0241, 269.0789,
  269.1338, 269.1886, 269.2434, 269.2982,
  269.3531, 269.4079, 269.4627, 269.5175,
  269.5724, 269.6272, 269.682, 269.7368,
  269.7917, 269.8465, 269.9013, 269.9561,
  270.011, 270.0658, 270.1206, 270.1754,
  270.2303, 270.2851, 270.3399, 270.3947,
  270.4496, 270.5044, 270.5592, 270.614,
  270.6689, 270.7237, 270.7785, 270.8333,
  270.8882, 270.943, 270.9978, 271.0526,
  271.1075, 271.1623, 271.2171, 271.2719,
  271.3268, 271.3816, 271.4364, 271.4912,
  271.5461, 271.6009, 271.6557, 271.7105,
  271.7654, 271.8202, 271.875, 271.9298,
  271.9846, 272.0395, 272.0943, 272.1491,
  272.2039, 272.2588, 272.3136, 272.3684,
  272.4232, 272.4781, 272.5329, 272.5877,
  272.6425, 272.6974, 272.7522, 272.807,
  272.8618, 272.9167, 272.9715, 273.0263,
  273.0811, 273.136, 273.1908, 273.2456,
  273.3004, 273.3553, 273.4101, 273.4649,
  273.5197, 273.5746, 273.6294, 273.6842,
  273.739, 273.7939, 273.8487, 273.9035,
  273.9583, 274.0132, 274.068, 274.1228,
  274.1776, 274.2325, 274.2873, 274.3421,
  274.3969, 274.4518, 274.5066, 274.5614,
  274.6162, 274.6711, 274.7259, 274.7807,
  274.8355, 274.8904, 274.9452, 275,
  275.0548, 275.1096, 275.1645, 275.2193,
  275.2741, 275.3289, 275.3838, 275.4386,
  275.4934, 275.5482, 275.6031, 275.6579,
  275.7127, 275.7675, 275.8224, 275.8772 ;
}


Example 3: Scalar Height Coordinate

Click to expand C code
#include "cmip7_c_common.h"

#include <stdio.h>

int main(int argc, char **argv) {
  const char *tables_path;
  const char *input_path;
  const char *output_dir;
  char cell_measures[CMOR_MAX_STRING];
  char long_name[CMOR_MAX_STRING];
  char filename[CMOR_MAX_STRING];
  int file_action = CMOR_REPLACE;
  int exit_control = CMOR_EXIT_ON_MAJOR;
  int table_id, lon_id, lat_id, time_id, height_id, var_id;
  int axes[3];
  double lat[CMIP7_NLAT] = {10.0, 20.0, 30.0};
  double lat_bnds[CMIP7_NLAT + 1] = {5.0, 15.0, 25.0, 35.0};
  double lon[CMIP7_NLON] = {0.0, 90.0, 180.0, 270.0};
  double lon_bnds[CMIP7_NLON + 1] = {-45.0, 45.0, 135.0, 225.0, 315.0};
  double time[CMIP7_NTIMES] = {15.5, 45.5};
  double time_bnds[CMIP7_NTIMES + 1] = {0.0, 31.0, 60.0};
  double height = 2.0;
  float tas[CMIP7_NTIMES * CMIP7_NLAT * CMIP7_NLON] = {
      254.0895f, 258.4085f, 250.5549f, 258.7101f, 258.6680f, 258.2990f,
      252.1237f, 255.0432f, 253.7254f, 251.2460f, 254.3168f, 255.4808f,
      259.7908f, 252.2754f, 257.1892f, 253.3132f, 253.8823f, 253.4698f,
      253.5381f, 254.9730f, 256.1002f, 251.8168f, 259.3698f, 250.2994f};
  float missing = CMIP7_MISSING_VALUE;

  cmip7_get_example_args(argc, argv, &tables_path, &input_path, &output_dir);

  cmor_setup((char *)tables_path, &file_action, NULL, &exit_control, NULL,
             NULL);
  cmip7_load_shared_user_input(input_path, output_dir, NULL, "r9", "f2");
  cmor_load_table("CMIP7_atmos.json", &table_id);

  cmor_axis(&lon_id, "longitude", "degrees_east", CMIP7_NLON, lon, 'd',
            lon_bnds, 1, NULL);
  cmor_axis(&lat_id, "latitude", "degrees_north", CMIP7_NLAT, lat, 'd',
            lat_bnds, 1, NULL);
  cmor_axis(&time_id, "time", "days since 1979-01-01", CMIP7_NTIMES, time, 'd',
            time_bnds, 1, NULL);
  cmor_axis(&height_id, "height2m", "m", 1, &height, 'd', NULL, 0, NULL);

  axes[0] = time_id;
  axes[1] = lat_id;
  axes[2] = lon_id;
  cmor_variable(&var_id, "tas_tavg-h2m-hxy-u", "K", 3, axes, 'f', &missing,
                NULL, NULL, NULL, NULL, NULL);

  cmip7_get_cell_measures(tables_path, "atmos", "tas_tavg-h2m-hxy-u", "mon",
                          "glb", cell_measures, sizeof(cell_measures));
  cmor_set_variable_attribute(var_id, "cell_measures", 'c', cell_measures);
  if (cmip7_get_long_name_override(tables_path, "atmos", "tas_tavg-h2m-hxy-u",
                                   "mon", "glb", long_name,
                                   sizeof(long_name))) {
    cmor_set_variable_attribute(var_id, "long_name", 'c', long_name);
  }

  cmor_write(var_id, tas, 'f', NULL, CMIP7_NTIMES, NULL, NULL, NULL);
  filename[0] = '\0';
  cmor_close_variable(var_id, filename, NULL);
  printf("%s\n", filename);
  cmor_close();
  return 0;
}

Click to expand NetCDF dump
netcdf tas_tavg-h2m-hxy-u_mon_glb_g999_ACCESS-ESM1-6_amip_r9i1p1f2_197901-197902 {
dimensions:
	time = UNLIMITED ; // (2 currently)
	lat = 3 ;
	lon = 4 ;
	bnds = 2 ;
variables:
	double time(time) ;
		time:bounds = "time_bnds" ;
		time:units = "days since 1979-01-01" ;
		time:calendar = "360_day" ;
		time:axis = "T" ;
		time:long_name = "Time Intervals" ;
		time:standard_name = "time" ;
	double time_bnds(time, bnds) ;
	double lat(lat) ;
		lat:bounds = "lat_bnds" ;
		lat:units = "degrees_north" ;
		lat:axis = "Y" ;
		lat:long_name = "Latitude" ;
		lat:standard_name = "latitude" ;
	double lat_bnds(lat, bnds) ;
	double lon(lon) ;
		lon:bounds = "lon_bnds" ;
		lon:units = "degrees_east" ;
		lon:axis = "X" ;
		lon:long_name = "Longitude" ;
		lon:standard_name = "longitude" ;
	double lon_bnds(lon, bnds) ;
	double height ;
		height:units = "m" ;
		height:axis = "Z" ;
		height:positive = "up" ;
		height:long_name = "height" ;
		height:standard_name = "height" ;
	float tas(time, lat, lon) ;
		tas:standard_name = "air_temperature" ;
		tas:long_name = "Near-Surface Air Temperature" ;
		tas:units = "K" ;
		tas:cell_methods = "area: time: mean" ;
		tas:history = "2026-08-07T00:48:06Z altered by CMOR: Treated scalar dimension: \'height\'." ;
		tas:coordinates = "height" ;
		tas:missing_value = 1.e+20f ;
		tas:_FillValue = 1.e+20f ;
		tas:cell_measures = "area: areacella" ;

// global attributes:
		:Conventions = "CF-1.12" ;
		:activity_id = "CMIP" ;
		:archive_id = "WCRP" ;
		:area_label = "u" ;
		:branded_variable = "tas_tavg-h2m-hxy-u" ;
		:branding_suffix = "tavg-h2m-hxy-u" ;
		:creation_date = "2026-08-07T00:48:06Z" ;
		:data_specs_version = "MIP-DS7.1.0.0" ;
		:description = "Simulation of the climate of the recent past with prescribed sea surface temperatures and sea ice concentrations." ;
		:drs_specs = "MIP-DRS7" ;
		:experiment = "Simulation of the climate of the recent past with prescribed sea surface temperatures and sea ice concentrations." ;
		:experiment_id = "amip" ;
		:external_variables = "areacella" ;
		:forcing_index = "f2" ;
		:frequency = "mon" ;
		:grid_label = "g999" ;
		:history = "2026-08-07T00:48:06Z ; CMOR rewrote data to be consistent with CF-1.12 and CMIP7 data requirements." ;
		:horizontal_label = "hxy" ;
		:host_collection = "CMIP7" ;
		:initialization_index = "i1" ;
		:institution = "Met Office Hadley Centre" ;
		:institution_id = "MOHC" ;
		:license_id = "CC-BY-4.0" ;
		:mip_era = "CMIP7" ;
		:nominal_resolution = "100 km" ;
		:outpath = "/Users/mauzey1/Desktop/github/cmor3_documentation/mydoc/examples/c/output" ;
		:physics_index = "p1" ;
		:product = "model-output" ;
		:realization_index = "r9" ;
		:realm = "atmos" ;
		:region = "glb" ;
		:source = "ACCESS-ESM1-6: aerosol: classic; atmosphere: um7-3; land-surface: cable3; ocean-biogeochemistry: wombatlite; ocean: mom5; sea-ice: cice5" ;
		:source_id = "ACCESS-ESM1-6" ;
		:table_info = "Name: CMIP7_atmos.json; Creation Date:(2026-07-21 13:16:24) MD5:28339aa355908b9331150e1536f5e384" ;
		:temporal_label = "tavg" ;
		:title = "ACCESS-ESM1-6 output prepared for CMIP7" ;
		:tracking_id = "hdl:21.14107/3480b915-1e6f-4762-94ef-e3e1a2c5a94b" ;
		:variable_id = "tas" ;
		:variant_label = "r9i1p1f2" ;
		:vertical_label = "h2m" ;
		:license = "CC-BY-4.0; CMIP7 data produced by MOHC is licensed under a Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0). Consult https://wcrp-cmip.github.io/cmip7-guidance/docs/CMIP7/Guidance_for_users/#2-terms-of-use-and-citations-requirements for terms of use governing CMIP7 output, including citation requirements and proper acknowledgment. The data producers and data providers make no warranty, either express or implied, including, but not limited to, warranties of merchantability and fitness for a particular purpose. All liabilities arising from the supply of the information (including any liability arising in negligence) are excluded to the fullest extent permitted by law." ;
		:cmor_version = "3.15.2" ;
data:

 time = 15.5, 45.5 ;

 time_bnds =
  0, 31,
  31, 60 ;

 lat = 10, 20, 30 ;

 lat_bnds =
  5, 15,
  15, 25,
  25, 35 ;

 lon = 0, 90, 180, 270 ;

 lon_bnds =
  -45, 45,
  45, 135,
  135, 225,
  225, 315 ;

 height = 2 ;

 tas =
  254.0895, 258.4085, 250.5549, 258.7101,
  258.668, 258.299, 252.1237, 255.0432,
  253.7254, 251.246, 254.3168, 255.4808,
  259.7908, 252.2754, 257.1892, 253.3132,
  253.8823, 253.4698, 253.5381, 254.973,
  256.1002, 251.8168, 259.3698, 250.2994 ;
}


Example 4: Basin Axis

Click to expand C code
#include "cmip7_c_common.h"

#include <stdio.h>

#define NBASIN 3

int main(int argc, char **argv) {
  const char *tables_path;
  const char *input_path;
  const char *output_dir;
  char cell_measures[CMOR_MAX_STRING];
  char long_name[CMOR_MAX_STRING];
  char filename[CMOR_MAX_STRING];
  char basin_names[NBASIN][CMOR_MAX_STRING] = {
      "atlantic_arctic_ocean", "indian_pacific_ocean", "global_ocean"};
  int file_action = CMOR_REPLACE;
  int exit_control = CMOR_EXIT_ON_MAJOR;
  int table_id, lat_id, time_id, basin_id, var_id;
  int axes[3];
  double lat[CMIP7_NLAT] = {10.0, 20.0, 30.0};
  double lat_bnds[CMIP7_NLAT + 1] = {5.0, 15.0, 25.0, 35.0};
  double time[CMIP7_NTIMES] = {15.5, 45.5};
  double time_bnds[CMIP7_NTIMES + 1] = {0.0, 31.0, 60.0};
  float heat_transport[CMIP7_NTIMES * NBASIN * CMIP7_NLAT] = {
      -80.0f,  -84.0f,  -88.0f, -100.0f, -104.0f, -76.0f,
      -120.0f, -92.0f,  -96.0f, -79.0f,  -83.0f,  -87.0f,
      -99.0f,  -103.0f, -75.0f, -107.0f, -111.0f, -115.0f};
  float missing = CMIP7_MISSING_VALUE;

  cmip7_get_example_args(argc, argv, &tables_path, &input_path, &output_dir);

  cmor_setup((char *)tables_path, &file_action, NULL, &exit_control, NULL,
             NULL);
  cmip7_load_shared_user_input(input_path, output_dir, NULL, NULL, NULL);
  cmor_load_table("CMIP7_ocean.json", &table_id);

  cmor_axis(&lat_id, "latitude", "degrees_north", CMIP7_NLAT, lat, 'd',
            lat_bnds, 1, NULL);
  cmor_axis(&time_id, "time", "days since 1979-01-01", CMIP7_NTIMES, time, 'd',
            time_bnds, 1, NULL);
  cmor_axis(&basin_id, "basin", "", NBASIN, basin_names, 'c', NULL,
            CMOR_MAX_STRING, NULL);

  axes[0] = time_id;
  axes[1] = basin_id;
  axes[2] = lat_id;
  cmor_variable(&var_id, "htovgyre_tavg-u-hyb-sea", "W", 3, axes, 'f', &missing,
                NULL, NULL, NULL, NULL, NULL);

  cmip7_get_cell_measures(tables_path, "ocean", "htovgyre_tavg-u-hyb-sea",
                          "mon", "glb", cell_measures, sizeof(cell_measures));
  cmor_set_variable_attribute(var_id, "cell_measures", 'c', cell_measures);
  if (cmip7_get_long_name_override(tables_path, "ocean",
                                   "htovgyre_tavg-u-hyb-sea", "mon", "glb",
                                   long_name, sizeof(long_name))) {
    cmor_set_variable_attribute(var_id, "long_name", 'c', long_name);
  }

  cmor_write(var_id, heat_transport, 'f', NULL, CMIP7_NTIMES, NULL, NULL, NULL);
  filename[0] = '\0';
  cmor_close_variable(var_id, filename, NULL);
  printf("%s\n", filename);
  cmor_close();
  return 0;
}

Click to expand NetCDF dump
netcdf htovgyre_tavg-u-hyb-sea_mon_glb_g999_ACCESS-ESM1-6_amip_r1i1p1f1_197901-197902 {
dimensions:
	time = UNLIMITED ; // (2 currently)
	basin = 3 ;
	lat = 3 ;
	bnds = 2 ;
	strlen = 21 ;
variables:
	double time(time) ;
		time:bounds = "time_bnds" ;
		time:units = "days since 1979-01-01" ;
		time:calendar = "360_day" ;
		time:axis = "T" ;
		time:long_name = "Time Intervals" ;
		time:standard_name = "time" ;
	double time_bnds(time, bnds) ;
	char sector(basin, strlen) ;
		sector:long_name = "Ocean Basin" ;
		sector:standard_name = "region" ;
	double lat(lat) ;
		lat:bounds = "lat_bnds" ;
		lat:units = "degrees_north" ;
		lat:axis = "Y" ;
		lat:long_name = "Latitude" ;
		lat:standard_name = "latitude" ;
	double lat_bnds(lat, bnds) ;
	float htovgyre(time, basin, lat) ;
		htovgyre:standard_name = "northward_ocean_heat_transport_due_to_gyre" ;
		htovgyre:long_name = "Northward Ocean Heat Transport Due to Gyre" ;
		htovgyre:units = "W" ;
		htovgyre:cell_methods = "depth: longitude: sum where sea (along a zig-zag grid path spanning a basin)  time: mean" ;
		htovgyre:missing_value = 1.e+20f ;
		htovgyre:_FillValue = 1.e+20f ;
		htovgyre:coordinates = "sector" ;

// global attributes:
		:Conventions = "CF-1.12" ;
		:activity_id = "CMIP" ;
		:archive_id = "WCRP" ;
		:area_label = "sea" ;
		:branded_variable = "htovgyre_tavg-u-hyb-sea" ;
		:branding_suffix = "tavg-u-hyb-sea" ;
		:creation_date = "2026-08-07T00:48:06Z" ;
		:data_specs_version = "MIP-DS7.1.0.0" ;
		:description = "Simulation of the climate of the recent past with prescribed sea surface temperatures and sea ice concentrations." ;
		:drs_specs = "MIP-DRS7" ;
		:experiment = "Simulation of the climate of the recent past with prescribed sea surface temperatures and sea ice concentrations." ;
		:experiment_id = "amip" ;
		:forcing_index = "f1" ;
		:frequency = "mon" ;
		:grid_label = "g999" ;
		:history = "2026-08-07T00:48:06Z ; CMOR rewrote data to be consistent with CF-1.12 and CMIP7 data requirements." ;
		:horizontal_label = "hyb" ;
		:host_collection = "CMIP7" ;
		:initialization_index = "i1" ;
		:institution = "Met Office Hadley Centre" ;
		:institution_id = "MOHC" ;
		:license_id = "CC-BY-4.0" ;
		:mip_era = "CMIP7" ;
		:nominal_resolution = "100 km" ;
		:outpath = "/Users/mauzey1/Desktop/github/cmor3_documentation/mydoc/examples/c/output" ;
		:physics_index = "p1" ;
		:product = "model-output" ;
		:realization_index = "r1" ;
		:realm = "ocean" ;
		:region = "glb" ;
		:source = "ACCESS-ESM1-6: aerosol: classic; atmosphere: um7-3; land-surface: cable3; ocean-biogeochemistry: wombatlite; ocean: mom5; sea-ice: cice5" ;
		:source_id = "ACCESS-ESM1-6" ;
		:table_info = "Name: CMIP7_ocean.json; Creation Date:(2026-07-21 13:16:24) MD5:734c6f53560fa60b7c1c21b38e5b9a3f" ;
		:temporal_label = "tavg" ;
		:title = "ACCESS-ESM1-6 output prepared for CMIP7" ;
		:tracking_id = "hdl:21.14107/14644abe-e7dd-40b8-bee6-1bc8e4fd5242" ;
		:variable_id = "htovgyre" ;
		:variant_label = "r1i1p1f1" ;
		:vertical_label = "u" ;
		:license = "CC-BY-4.0; CMIP7 data produced by MOHC is licensed under a Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0). Consult https://wcrp-cmip.github.io/cmip7-guidance/docs/CMIP7/Guidance_for_users/#2-terms-of-use-and-citations-requirements for terms of use governing CMIP7 output, including citation requirements and proper acknowledgment. The data producers and data providers make no warranty, either express or implied, including, but not limited to, warranties of merchantability and fitness for a particular purpose. All liabilities arising from the supply of the information (including any liability arising in negligence) are excluded to the fullest extent permitted by law." ;
		:cmor_version = "3.15.2" ;
data:

 time = 15.5, 45.5 ;

 time_bnds =
  0, 31,
  31, 60 ;

 sector =
  "atlantic_arctic_ocean",
  "indian_pacific_ocean",
  "global_ocean" ;

 lat = 10, 20, 30 ;

 lat_bnds =
  5, 15,
  15, 25,
  25, 35 ;

 htovgyre =
  -80, -84, -88,
  -100, -104, -76,
  -120, -92, -96,
  -79, -83, -87,
  -99, -103, -75,
  -107, -111, -115 ;
}


Example 5: Hybrid Sigma Model Levels

Click to expand C code
#include "cmip7_c_common.h"

#include <stdio.h>

#define NLEV 5

int main(int argc, char **argv) {
  const char *tables_path;
  const char *input_path;
  const char *output_dir;
  char cell_measures[CMOR_MAX_STRING];
  char long_name[CMOR_MAX_STRING];
  char filename[CMOR_MAX_STRING];
  int file_action = CMOR_REPLACE;
  int exit_control = CMOR_EXIT_ON_MAJOR;
  int table_id, lon_id, lat_id, time_id, lev_id, ps_id, zfactor_id, var_id;
  int axes[4];
  int lev_axis[1];
  int ps_axes[3];
  int i, j, k, t;
  double lat[CMIP7_NLAT] = {10.0, 20.0, 30.0};
  double lat_bnds[CMIP7_NLAT + 1] = {5.0, 15.0, 25.0, 35.0};
  double lon[CMIP7_NLON] = {0.0, 90.0, 180.0, 270.0};
  double lon_bnds[CMIP7_NLON + 1] = {-45.0, 45.0, 135.0, 225.0, 315.0};
  double time[CMIP7_NTIMES] = {15.5, 45.5};
  double time_bnds[CMIP7_NTIMES + 1] = {0.0, 31.0, 60.0};
  double lev[NLEV] = {0.92, 0.72, 0.50, 0.30, 0.10};
  double lev_bnds[NLEV + 1] = {1.00, 0.83, 0.61, 0.40, 0.20, 0.00};
  double a_coeff[NLEV] = {0.12, 0.22, 0.30, 0.20, 0.10};
  double b_coeff[NLEV] = {0.80, 0.50, 0.20, 0.10, 0.00};
  double a_bnds[NLEV + 1] = {0.06, 0.18, 0.26, 0.25, 0.15, 0.00};
  double b_bnds[NLEV + 1] = {0.94, 0.65, 0.35, 0.15, 0.05, 0.00};
  double p0[1] = {100000.0};
  float cl[CMIP7_NTIMES * NLEV * CMIP7_NLAT * CMIP7_NLON];
  float ps[CMIP7_NTIMES * CMIP7_NLAT * CMIP7_NLON];
  float missing = CMIP7_MISSING_VALUE;

  cmip7_get_example_args(argc, argv, &tables_path, &input_path, &output_dir);

  cmor_setup((char *)tables_path, &file_action, NULL, &exit_control, NULL,
             NULL);
  cmip7_load_shared_user_input(input_path, output_dir, NULL, NULL, NULL);
  cmor_load_table("CMIP7_atmos.json", &table_id);

  cmor_axis(&lon_id, "longitude", "degrees_east", CMIP7_NLON, lon, 'd',
            lon_bnds, 1, NULL);
  cmor_axis(&lat_id, "latitude", "degrees_north", CMIP7_NLAT, lat, 'd',
            lat_bnds, 1, NULL);
  cmor_axis(&time_id, "time", "days since 1979-01-01", CMIP7_NTIMES, time, 'd',
            time_bnds, 1, NULL);
  cmor_axis(&lev_id, "standard_hybrid_sigma", "1", NLEV, lev, 'd', lev_bnds, 1,
            NULL);

  lev_axis[0] = lev_id;
  cmor_zfactor(&zfactor_id, lev_id, "a", "", 1, lev_axis, 'd', a_coeff, a_bnds);
  cmor_zfactor(&zfactor_id, lev_id, "b", "", 1, lev_axis, 'd', b_coeff, b_bnds);
  cmor_zfactor(&zfactor_id, lev_id, "p0", "Pa", 0, NULL, 'd', p0, NULL);

  ps_axes[0] = time_id;
  ps_axes[1] = lat_id;
  ps_axes[2] = lon_id;
  cmor_zfactor(&ps_id, lev_id, "ps", "Pa", 3, ps_axes, 'f', NULL, NULL);

  for (t = 0; t < CMIP7_NTIMES; ++t) {
    for (j = 0; j < CMIP7_NLAT; ++j) {
      for (i = 0; i < CMIP7_NLON; ++i) {
        int idx = (t * CMIP7_NLAT + j) * CMIP7_NLON + i;
        ps[idx] = 97000.0f + 400.0f * (float)i + 1600.0f * (float)j +
                  100.0f * (float)t;
      }
    }
  }
  for (t = 0; t < CMIP7_NTIMES; ++t) {
    for (k = 0; k < NLEV; ++k) {
      for (j = 0; j < CMIP7_NLAT; ++j) {
        for (i = 0; i < CMIP7_NLON; ++i) {
          int idx = ((t * NLEV + k) * CMIP7_NLAT + j) * CMIP7_NLON + i;
          cl[idx] = 75.0f - 5.0f * (float)(k + 1) - 1.2f * (float)j +
                    0.4f * (float)i + 0.1f * (float)t;
        }
      }
    }
  }

  axes[0] = time_id;
  axes[1] = lev_id;
  axes[2] = lat_id;
  axes[3] = lon_id;
  cmor_variable(&var_id, "cl_tavg-al-hxy-u", "%", 4, axes, 'f', &missing, NULL,
                NULL, NULL, NULL, NULL);

  cmip7_get_cell_measures(tables_path, "atmos", "cl_tavg-al-hxy-u", "mon",
                          "glb", cell_measures, sizeof(cell_measures));
  cmor_set_variable_attribute(var_id, "cell_measures", 'c', cell_measures);
  if (cmip7_get_long_name_override(tables_path, "atmos", "cl_tavg-al-hxy-u",
                                   "mon", "glb", long_name,
                                   sizeof(long_name))) {
    cmor_set_variable_attribute(var_id, "long_name", 'c', long_name);
  }

  cmor_write(var_id, cl, 'f', NULL, CMIP7_NTIMES, NULL, NULL, NULL);
  cmor_write(ps_id, ps, 'f', NULL, CMIP7_NTIMES, NULL, NULL, &var_id);
  filename[0] = '\0';
  cmor_close_variable(var_id, filename, NULL);
  printf("%s\n", filename);
  cmor_close();
  return 0;
}

Click to expand NetCDF dump
netcdf cl_tavg-al-hxy-u_mon_glb_g999_ACCESS-ESM1-6_amip_r1i1p1f1_197901-197902 {
dimensions:
	time = UNLIMITED ; // (2 currently)
	lev = 5 ;
	lat = 3 ;
	lon = 4 ;
	bnds = 2 ;
variables:
	double time(time) ;
		time:bounds = "time_bnds" ;
		time:units = "days since 1979-01-01" ;
		time:calendar = "360_day" ;
		time:axis = "T" ;
		time:long_name = "Time Intervals" ;
		time:standard_name = "time" ;
	double time_bnds(time, bnds) ;
	double lev(lev) ;
		lev:bounds = "lev_bnds" ;
		lev:units = "1" ;
		lev:axis = "Z" ;
		lev:positive = "down" ;
		lev:long_name = "hybrid sigma pressure coordinate" ;
		lev:standard_name = "atmosphere_hybrid_sigma_pressure_coordinate" ;
		lev:formula = "p = a*p0 + b*ps" ;
		lev:formula_terms = "p0: p0 a: a b: b ps: ps" ;
	double lev_bnds(lev, bnds) ;
		lev_bnds:formula = "p = a*p0 + b*ps" ;
		lev_bnds:standard_name = "atmosphere_hybrid_sigma_pressure_coordinate" ;
		lev_bnds:units = "1" ;
		lev_bnds:formula_terms = "p0: p0 a: a_bnds b: b_bnds ps: ps" ;
	double p0 ;
		p0:standard_name = "reference_air_pressure_for_atmosphere_vertical_coordinate" ;
		p0:long_name = "vertical coordinate formula term: reference pressure" ;
		p0:units = "Pa" ;
	double a(lev) ;
		a:long_name = "vertical coordinate formula term: a" ;
	double b(lev) ;
		b:long_name = "vertical coordinate formula term: b" ;
	float ps(time, lat, lon) ;
		ps:standard_name = "air_pressure" ;
		ps:long_name = "Surface Air Pressure" ;
		ps:units = "Pa" ;
	double a_bnds(lev, bnds) ;
		a_bnds:long_name = "vertical coordinate formula term: a(k+1/2)" ;
	double b_bnds(lev, bnds) ;
		b_bnds:long_name = "vertical coordinate formula term: b(k+1/2)" ;
	double lat(lat) ;
		lat:bounds = "lat_bnds" ;
		lat:units = "degrees_north" ;
		lat:axis = "Y" ;
		lat:long_name = "Latitude" ;
		lat:standard_name = "latitude" ;
	double lat_bnds(lat, bnds) ;
	double lon(lon) ;
		lon:bounds = "lon_bnds" ;
		lon:units = "degrees_east" ;
		lon:axis = "X" ;
		lon:long_name = "Longitude" ;
		lon:standard_name = "longitude" ;
	double lon_bnds(lon, bnds) ;
	float cl(time, lev, lat, lon) ;
		cl:standard_name = "cloud_area_fraction_in_atmosphere_layer" ;
		cl:long_name = "Percentage Cloud Cover" ;
		cl:units = "%" ;
		cl:cell_methods = "area: time: mean" ;
		cl:missing_value = 1.e+20f ;
		cl:_FillValue = 1.e+20f ;
		cl:cell_measures = "area: areacella" ;

// global attributes:
		:Conventions = "CF-1.12" ;
		:activity_id = "CMIP" ;
		:archive_id = "WCRP" ;
		:area_label = "u" ;
		:branded_variable = "cl_tavg-al-hxy-u" ;
		:branding_suffix = "tavg-al-hxy-u" ;
		:creation_date = "2026-08-07T00:48:07Z" ;
		:data_specs_version = "MIP-DS7.1.0.0" ;
		:description = "Simulation of the climate of the recent past with prescribed sea surface temperatures and sea ice concentrations." ;
		:drs_specs = "MIP-DRS7" ;
		:experiment = "Simulation of the climate of the recent past with prescribed sea surface temperatures and sea ice concentrations." ;
		:experiment_id = "amip" ;
		:external_variables = "areacella" ;
		:forcing_index = "f1" ;
		:frequency = "mon" ;
		:grid_label = "g999" ;
		:history = "2026-08-07T00:48:07Z ; CMOR rewrote data to be consistent with CF-1.12 and CMIP7 data requirements." ;
		:horizontal_label = "hxy" ;
		:host_collection = "CMIP7" ;
		:initialization_index = "i1" ;
		:institution = "Met Office Hadley Centre" ;
		:institution_id = "MOHC" ;
		:license_id = "CC-BY-4.0" ;
		:mip_era = "CMIP7" ;
		:nominal_resolution = "100 km" ;
		:outpath = "/Users/mauzey1/Desktop/github/cmor3_documentation/mydoc/examples/c/output" ;
		:physics_index = "p1" ;
		:product = "model-output" ;
		:realization_index = "r1" ;
		:realm = "atmos" ;
		:region = "glb" ;
		:source = "ACCESS-ESM1-6: aerosol: classic; atmosphere: um7-3; land-surface: cable3; ocean-biogeochemistry: wombatlite; ocean: mom5; sea-ice: cice5" ;
		:source_id = "ACCESS-ESM1-6" ;
		:table_info = "Name: CMIP7_atmos.json; Creation Date:(2026-07-21 13:16:24) MD5:28339aa355908b9331150e1536f5e384" ;
		:temporal_label = "tavg" ;
		:title = "ACCESS-ESM1-6 output prepared for CMIP7" ;
		:variable_id = "cl" ;
		:variant_label = "r1i1p1f1" ;
		:vertical_label = "al" ;
		:license = "CC-BY-4.0; CMIP7 data produced by MOHC is licensed under a Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0). Consult https://wcrp-cmip.github.io/cmip7-guidance/docs/CMIP7/Guidance_for_users/#2-terms-of-use-and-citations-requirements for terms of use governing CMIP7 output, including citation requirements and proper acknowledgment. The data producers and data providers make no warranty, either express or implied, including, but not limited to, warranties of merchantability and fitness for a particular purpose. All liabilities arising from the supply of the information (including any liability arising in negligence) are excluded to the fullest extent permitted by law." ;
		:cmor_version = "3.15.2" ;
		:tracking_id = "hdl:21.14107/0780a6fd-61bc-455b-8cd2-39e1c599f1cd" ;
data:

 time = 15.5, 45.5 ;

 time_bnds =
  0, 31,
  31, 60 ;

 lev = 0.92, 0.72, 0.5, 0.3, 0.1 ;

 lev_bnds =
  1, 0.83,
  0.83, 0.61,
  0.61, 0.4,
  0.4, 0.2,
  0.2, 0 ;

 p0 = 100000 ;

 a = 0.12, 0.22, 0.3, 0.2, 0.1 ;

 b = 0.8, 0.5, 0.2, 0.1, 0 ;

 ps =
  97000, 97400, 97800, 98200,
  98600, 99000, 99400, 99800,
  100200, 100600, 101000, 101400,
  97100, 97500, 97900, 98300,
  98700, 99100, 99500, 99900,
  100300, 100700, 101100, 101500 ;

 a_bnds =
  0.06, 0.18,
  0.18, 0.26,
  0.26, 0.25,
  0.25, 0.15,
  0.15, 0 ;

 b_bnds =
  0.94, 0.65,
  0.65, 0.35,
  0.35, 0.15,
  0.15, 0.05,
  0.05, 0 ;

 lat = 10, 20, 30 ;

 lat_bnds =
  5, 15,
  15, 25,
  25, 35 ;

 lon = 0, 90, 180, 270 ;

 lon_bnds =
  -45, 45,
  45, 135,
  135, 225,
  225, 315 ;

 cl =
  70, 70.4, 70.8, 71.2,
  68.8, 69.2, 69.60001, 70,
  67.6, 68, 68.4, 68.8,
  65, 65.4, 65.8, 66.2,
  63.8, 64.2, 64.6, 65,
  62.6, 63, 63.4, 63.8,
  60, 60.4, 60.8, 61.2,
  58.8, 59.2, 59.6, 60,
  57.6, 58, 58.4, 58.8,
  55, 55.4, 55.8, 56.2,
  53.8, 54.2, 54.6, 55,
  52.6, 53, 53.4, 53.8,
  50, 50.4, 50.8, 51.2,
  48.8, 49.2, 49.6, 50,
  47.6, 48, 48.4, 48.8,
  70.1, 70.5, 70.9, 71.3,
  68.9, 69.3, 69.7, 70.1,
  67.7, 68.1, 68.5, 68.89999,
  65.1, 65.5, 65.9, 66.3,
  63.9, 64.3, 64.7, 65.1,
  62.7, 63.1, 63.5, 63.9,
  60.1, 60.5, 60.9, 61.3,
  58.9, 59.3, 59.7, 60.1,
  57.7, 58.1, 58.5, 58.9,
  55.1, 55.5, 55.9, 56.3,
  53.9, 54.3, 54.7, 55.1,
  52.7, 53.1, 53.5, 53.9,
  50.1, 50.5, 50.9, 51.3,
  48.9, 49.3, 49.7, 50.1,
  47.7, 48.1, 48.5, 48.9 ;
}


Example 6: Curvilinear Grid

Click to expand C code
#include "cmip7_c_common.h"

#include <stdio.h>

#define NX 4
#define NY 3
#define NVERTICES 4
#define NPARAMS 6
#define PARAM_LEN 32
#define UNIT_LEN 2

int main(int argc, char **argv) {
  const char *tables_path;
  const char *input_path;
  const char *output_dir;
  char cell_measures[CMOR_MAX_STRING];
  char long_name[CMOR_MAX_STRING];
  char filename[CMOR_MAX_STRING];
  int file_action = CMOR_REPLACE;
  int exit_control = CMOR_EXIT_ON_MAJOR;
  int table_id, grid_table_id, x_id, y_id, time_id, grid_id, var_id;
  int grid_axes[2];
  int axes[2];
  int i, j, t;
  double x[NX] = {0.0, 10000.0, 20000.0, 30000.0};
  double y[NY] = {0.0, 10000.0, 20000.0};
  double x_bnds[NX + 1] = {-5000.0, 5000.0, 15000.0, 25000.0, 35000.0};
  double y_bnds[NY + 1] = {-5000.0, 5000.0, 15000.0, 25000.0};
  double latitude[NY * NX];
  double longitude[NY * NX];
  double latitude_vertices[NY * NX * NVERTICES];
  double longitude_vertices[NY * NX * NVERTICES];
  double time[CMIP7_NTIMES] = {15.5, 45.5};
  double time_bnds[CMIP7_NTIMES + 1] = {0.0, 31.0, 60.0};
  char parameter_names[NPARAMS][PARAM_LEN] = {"standard_parallel1",
                                              "longitude_of_central_meridian",
                                              "latitude_of_projection_origin",
                                              "false_easting",
                                              "false_northing",
                                              "standard_parallel2"};
  char parameter_units[NPARAMS][UNIT_LEN] = {"", "", "", "", "", ""};
  double parameter_values[CMOR_MAX_GRID_ATTRIBUTES] = {-20.0, 175.0, 13.0,
                                                       8.0,   0.0,   20.0};
  float hfls[CMIP7_NTIMES * NY * NX];
  float missing = CMIP7_MISSING_VALUE;

  cmip7_get_example_args(argc, argv, &tables_path, &input_path, &output_dir);

  cmor_setup((char *)tables_path, &file_action, NULL, &exit_control, NULL,
             NULL);
  cmip7_load_shared_user_input(input_path, output_dir, NULL, NULL, NULL);

  cmor_load_table("CMIP7_grids.json", &grid_table_id);
  cmor_set_table(grid_table_id);
  cmor_axis(&y_id, "y", "m", NY, y, 'd', y_bnds, 1, NULL);
  cmor_axis(&x_id, "x", "m", NX, x, 'd', x_bnds, 1, NULL);

  for (j = 0; j < NY; ++j) {
    for (i = 0; i < NX; ++i) {
      int idx = j * NX + i;
      int vertex_idx = idx * NVERTICES;

      latitude[idx] = 10.0 * (double)(j + 1) - 2.0 * (double)i;
      longitude[idx] = 280.0 + 10.0 * (double)i + 2.0 * (double)j;
      latitude_vertices[vertex_idx + 0] = latitude[idx] - 5.0;
      latitude_vertices[vertex_idx + 1] = latitude[idx] - 4.0;
      latitude_vertices[vertex_idx + 2] = latitude[idx] + 5.0;
      latitude_vertices[vertex_idx + 3] = latitude[idx] + 4.0;
      longitude_vertices[vertex_idx + 0] = longitude[idx] - 5.0;
      longitude_vertices[vertex_idx + 1] = longitude[idx] + 5.0;
      longitude_vertices[vertex_idx + 2] = longitude[idx] + 5.0;
      longitude_vertices[vertex_idx + 3] = longitude[idx] - 5.0;
    }
  }

  grid_axes[0] = y_id;
  grid_axes[1] = x_id;
  cmor_grid(&grid_id, 2, grid_axes, 'd', latitude, longitude, NVERTICES,
            latitude_vertices, longitude_vertices);
  cmor_set_grid_mapping(grid_id, "lambert_conformal_conic", NPARAMS,
                        &parameter_names[0][0], PARAM_LEN, parameter_values,
                        &parameter_units[0][0], UNIT_LEN);

  cmor_load_table("CMIP7_atmos.json", &table_id);
  cmor_axis(&time_id, "time", "days since 1979-01-01", CMIP7_NTIMES, time, 'd',
            time_bnds, 1, NULL);

  for (t = 0; t < CMIP7_NTIMES; ++t) {
    for (j = 0; j < NY; ++j) {
      for (i = 0; i < NX; ++i) {
        int idx = (t * NY + j) * NX + i;
        hfls[idx] = 80.0f + 2.0f * (float)i + 8.0f * (float)j + (float)t;
      }
    }
  }

  axes[0] = time_id;
  axes[1] = grid_id;
  cmor_variable(&var_id, "hfls_tavg-u-hxy-u", "W m-2", 2, axes, 'f', &missing,
                NULL, "up", NULL, NULL, NULL);

  cmip7_get_cell_measures(tables_path, "atmos", "hfls_tavg-u-hxy-u", "mon",
                          "glb", cell_measures, sizeof(cell_measures));
  cmor_set_variable_attribute(var_id, "cell_measures", 'c', cell_measures);
  if (cmip7_get_long_name_override(tables_path, "atmos", "hfls_tavg-u-hxy-u",
                                   "mon", "glb", long_name,
                                   sizeof(long_name))) {
    cmor_set_variable_attribute(var_id, "long_name", 'c', long_name);
  }

  cmor_write(var_id, hfls, 'f', NULL, CMIP7_NTIMES, NULL, NULL, NULL);
  filename[0] = '\0';
  cmor_close_variable(var_id, filename, NULL);
  printf("%s\n", filename);
  cmor_close();
  return 0;
}

Click to expand NetCDF dump
netcdf hfls_tavg-u-hxy-u_mon_glb_g999_ACCESS-ESM1-6_amip_r1i1p1f1_197901-197902 {
dimensions:
	time = UNLIMITED ; // (2 currently)
	x = 4 ;
	y = 3 ;
	bnds = 2 ;
	vertices = 4 ;
variables:
	double time(time) ;
		time:bounds = "time_bnds" ;
		time:units = "days since 1979-01-01" ;
		time:calendar = "360_day" ;
		time:axis = "T" ;
		time:long_name = "Time Intervals" ;
		time:standard_name = "time" ;
	double time_bnds(time, bnds) ;
	double x(x) ;
		x:bounds = "x_bnds" ;
		x:units = "m" ;
		x:axis = "X" ;
		x:long_name = "x coordinate of projection" ;
		x:standard_name = "projection_x_coordinate" ;
	double x_bnds(x, bnds) ;
	double y(y) ;
		y:bounds = "y_bnds" ;
		y:units = "m" ;
		y:axis = "Y" ;
		y:long_name = "y coordinate of projection" ;
		y:standard_name = "projection_y_coordinate" ;
	double y_bnds(y, bnds) ;
	int lambert_conformal_conic ;
		lambert_conformal_conic:grid_mapping_name = "lambert_conformal_conic" ;
		lambert_conformal_conic:standard_parallel = -20., 20. ;
		lambert_conformal_conic:longitude_of_central_meridian = 175. ;
		lambert_conformal_conic:latitude_of_projection_origin = 13. ;
		lambert_conformal_conic:false_easting = 8. ;
		lambert_conformal_conic:false_northing = 0. ;
	double latitude(x, y) ;
		latitude:standard_name = "latitude" ;
		latitude:long_name = "latitude" ;
		latitude:units = "degrees_north" ;
		latitude:missing_value = 1.e+20 ;
		latitude:_FillValue = 1.e+20 ;
		latitude:bounds = "vertices_latitude" ;
	double longitude(x, y) ;
		longitude:standard_name = "longitude" ;
		longitude:long_name = "longitude" ;
		longitude:units = "degrees_east" ;
		longitude:missing_value = 1.e+20 ;
		longitude:_FillValue = 1.e+20 ;
		longitude:bounds = "vertices_longitude" ;
	double vertices_latitude(x, y, vertices) ;
		vertices_latitude:units = "degrees_north" ;
		vertices_latitude:missing_value = 1.e+20 ;
		vertices_latitude:_FillValue = 1.e+20 ;
	double vertices_longitude(x, y, vertices) ;
		vertices_longitude:units = "degrees_east" ;
		vertices_longitude:missing_value = 1.e+20 ;
		vertices_longitude:_FillValue = 1.e+20 ;
	float hfls(time, x, y) ;
		hfls:standard_name = "surface_upward_latent_heat_flux" ;
		hfls:long_name = "Surface Upward Latent Heat Flux" ;
		hfls:units = "W m-2" ;
		hfls:cell_methods = "area: time: mean" ;
		hfls:history = "2026-08-07T00:48:07Z altered by CMOR: Reordered dimensions, original order: time y x." ;
		hfls:missing_value = 1.e+20f ;
		hfls:_FillValue = 1.e+20f ;
		hfls:cell_measures = "area: areacella" ;
		hfls:grid_mapping = "lambert_conformal_conic" ;
		hfls:coordinates = "latitude longitude" ;

// global attributes:
		:Conventions = "CF-1.12" ;
		:activity_id = "CMIP" ;
		:archive_id = "WCRP" ;
		:area_label = "u" ;
		:branded_variable = "hfls_tavg-u-hxy-u" ;
		:branding_suffix = "tavg-u-hxy-u" ;
		:creation_date = "2026-08-07T00:48:07Z" ;
		:data_specs_version = "MIP-DS7.1.0.0" ;
		:description = "Simulation of the climate of the recent past with prescribed sea surface temperatures and sea ice concentrations." ;
		:drs_specs = "MIP-DRS7" ;
		:experiment = "Simulation of the climate of the recent past with prescribed sea surface temperatures and sea ice concentrations." ;
		:experiment_id = "amip" ;
		:external_variables = "areacella" ;
		:forcing_index = "f1" ;
		:frequency = "mon" ;
		:grid_label = "g999" ;
		:history = "2026-08-07T00:48:07Z ; CMOR rewrote data to be consistent with CF-1.12 and CMIP7 data requirements." ;
		:horizontal_label = "hxy" ;
		:host_collection = "CMIP7" ;
		:initialization_index = "i1" ;
		:institution = "Met Office Hadley Centre" ;
		:institution_id = "MOHC" ;
		:license_id = "CC-BY-4.0" ;
		:mip_era = "CMIP7" ;
		:nominal_resolution = "100 km" ;
		:outpath = "/Users/mauzey1/Desktop/github/cmor3_documentation/mydoc/examples/c/output" ;
		:physics_index = "p1" ;
		:product = "model-output" ;
		:realization_index = "r1" ;
		:realm = "atmos" ;
		:region = "glb" ;
		:source = "ACCESS-ESM1-6: aerosol: classic; atmosphere: um7-3; land-surface: cable3; ocean-biogeochemistry: wombatlite; ocean: mom5; sea-ice: cice5" ;
		:source_id = "ACCESS-ESM1-6" ;
		:table_info = "Name: CMIP7_atmos.json; Creation Date:(2026-07-21 13:16:24) MD5:28339aa355908b9331150e1536f5e384" ;
		:temporal_label = "tavg" ;
		:title = "ACCESS-ESM1-6 output prepared for CMIP7" ;
		:tracking_id = "hdl:21.14107/1661b667-53d8-4a11-a29b-c0b0d91ec71c" ;
		:variable_id = "hfls" ;
		:variant_label = "r1i1p1f1" ;
		:vertical_label = "u" ;
		:license = "CC-BY-4.0; CMIP7 data produced by MOHC is licensed under a Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0). Consult https://wcrp-cmip.github.io/cmip7-guidance/docs/CMIP7/Guidance_for_users/#2-terms-of-use-and-citations-requirements for terms of use governing CMIP7 output, including citation requirements and proper acknowledgment. The data producers and data providers make no warranty, either express or implied, including, but not limited to, warranties of merchantability and fitness for a particular purpose. All liabilities arising from the supply of the information (including any liability arising in negligence) are excluded to the fullest extent permitted by law." ;
		:cmor_version = "3.15.2" ;
data:

 time = 15.5, 45.5 ;

 time_bnds =
  0, 31,
  31, 60 ;

 x = 0, 10000, 20000, 30000 ;

 x_bnds =
  -5000, 5000,
  5000, 15000,
  15000, 25000,
  25000, 35000 ;

 y = 0, 10000, 20000 ;

 y_bnds =
  -5000, 5000,
  5000, 15000,
  15000, 25000 ;

 lambert_conformal_conic = _ ;

 latitude =
  10, 20, 30,
  8, 18, 28,
  6, 16, 26,
  4, 14, 24 ;

 longitude =
  280, 282, 284,
  290, 292, 294,
  300, 302, 304,
  310, 312, 314 ;

 vertices_latitude =
  5, 6, 15, 14,
  15, 16, 25, 24,
  25, 26, 35, 34,
  3, 4, 13, 12,
  13, 14, 23, 22,
  23, 24, 33, 32,
  1, 2, 11, 10,
  11, 12, 21, 20,
  21, 22, 31, 30,
  -1, 0, 9, 8,
  9, 10, 19, 18,
  19, 20, 29, 28 ;

 vertices_longitude =
  275, 285, 285, 275,
  277, 287, 287, 277,
  279, 289, 289, 279,
  285, 295, 295, 285,
  287, 297, 297, 287,
  289, 299, 299, 289,
  295, 305, 305, 295,
  297, 307, 307, 297,
  299, 309, 309, 299,
  305, 315, 315, 305,
  307, 317, 317, 307,
  309, 319, 319, 309 ;

 hfls =
  80, 88, 96,
  82, 90, 98,
  84, 92, 100,
  86, 94, 102,
  81, 89, 97,
  83, 91, 99,
  85, 93, 101,
  87, 95, 103 ;
}


Example 7: Fixed Field

Click to expand C code
#include "cmip7_c_common.h"

#include <stdio.h>

int main(int argc, char **argv) {
  const char *tables_path;
  const char *input_path;
  const char *output_dir;
  char cell_measures[CMOR_MAX_STRING];
  char long_name[CMOR_MAX_STRING];
  char filename[CMOR_MAX_STRING];
  int file_action = CMOR_REPLACE;
  int exit_control = CMOR_EXIT_ON_MAJOR;
  int table_id, lon_id, lat_id, var_id;
  int axes[2];
  double lat[CMIP7_NLAT] = {10.0, 20.0, 30.0};
  double lat_bnds[CMIP7_NLAT + 1] = {5.0, 15.0, 25.0, 35.0};
  double lon[CMIP7_NLON] = {0.0, 90.0, 180.0, 270.0};
  double lon_bnds[CMIP7_NLON + 1] = {-45.0, 45.0, 135.0, 225.0, 315.0};
  float rootd[CMIP7_NLAT * CMIP7_NLON] = {0.50f,
                                          0.45f,
                                          CMIP7_MISSING_VALUE,
                                          0.55f,
                                          0.60f,
                                          0.60f,
                                          CMIP7_MISSING_VALUE,
                                          0.55f,
                                          CMIP7_MISSING_VALUE,
                                          0.45f,
                                          0.50f,
                                          0.50f};
  float missing = CMIP7_MISSING_VALUE;

  cmip7_get_example_args(argc, argv, &tables_path, &input_path, &output_dir);

  cmor_setup((char *)tables_path, &file_action, NULL, &exit_control, NULL,
             NULL);
  cmip7_load_shared_user_input(input_path, output_dir, "fx", NULL, NULL);
  cmor_load_table("CMIP7_land.json", &table_id);

  cmor_axis(&lon_id, "longitude", "degrees_east", CMIP7_NLON, lon, 'd',
            lon_bnds, 1, NULL);
  cmor_axis(&lat_id, "latitude", "degrees_north", CMIP7_NLAT, lat, 'd',
            lat_bnds, 1, NULL);

  axes[0] = lat_id;
  axes[1] = lon_id;
  cmor_variable(&var_id, "rootd_ti-u-hxy-lnd", "m", 2, axes, 'f', &missing,
                NULL, NULL, NULL, NULL, NULL);

  cmip7_get_cell_measures(tables_path, "land", "rootd_ti-u-hxy-lnd", "fx",
                          "glb", cell_measures, sizeof(cell_measures));
  cmor_set_variable_attribute(var_id, "cell_measures", 'c', cell_measures);
  if (cmip7_get_long_name_override(tables_path, "land", "rootd_ti-u-hxy-lnd",
                                   "fx", "glb", long_name, sizeof(long_name))) {
    cmor_set_variable_attribute(var_id, "long_name", 'c', long_name);
  }

  cmor_write(var_id, rootd, 'f', NULL, 0, NULL, NULL, NULL);
  filename[0] = '\0';
  cmor_close_variable(var_id, filename, NULL);
  printf("%s\n", filename);
  cmor_close();
  return 0;
}

Click to expand NetCDF dump
netcdf rootd_ti-u-hxy-lnd_fx_glb_g999_ACCESS-ESM1-6_amip_r1i1p1f1 {
dimensions:
	lat = 3 ;
	lon = 4 ;
	bnds = 2 ;
variables:
	double lat(lat) ;
		lat:bounds = "lat_bnds" ;
		lat:units = "degrees_north" ;
		lat:axis = "Y" ;
		lat:long_name = "Latitude" ;
		lat:standard_name = "latitude" ;
	double lat_bnds(lat, bnds) ;
	double lon(lon) ;
		lon:bounds = "lon_bnds" ;
		lon:units = "degrees_east" ;
		lon:axis = "X" ;
		lon:long_name = "Longitude" ;
		lon:standard_name = "longitude" ;
	double lon_bnds(lon, bnds) ;
	float rootd(lat, lon) ;
		rootd:standard_name = "root_depth" ;
		rootd:long_name = "Maximum Root Depth" ;
		rootd:units = "m" ;
		rootd:cell_methods = "area: mean where land" ;
		rootd:missing_value = 1.e+20f ;
		rootd:_FillValue = 1.e+20f ;
		rootd:cell_measures = "area: areacella" ;

// global attributes:
		:Conventions = "CF-1.12" ;
		:activity_id = "CMIP" ;
		:archive_id = "WCRP" ;
		:area_label = "lnd" ;
		:branded_variable = "rootd_ti-u-hxy-lnd" ;
		:branding_suffix = "ti-u-hxy-lnd" ;
		:creation_date = "2026-08-07T00:48:08Z" ;
		:data_specs_version = "MIP-DS7.1.0.0" ;
		:description = "Simulation of the climate of the recent past with prescribed sea surface temperatures and sea ice concentrations." ;
		:drs_specs = "MIP-DRS7" ;
		:experiment = "Simulation of the climate of the recent past with prescribed sea surface temperatures and sea ice concentrations." ;
		:experiment_id = "amip" ;
		:external_variables = "areacella" ;
		:forcing_index = "f1" ;
		:frequency = "fx" ;
		:grid_label = "g999" ;
		:history = "2026-08-07T00:48:08Z ; CMOR rewrote data to be consistent with CF-1.12 and CMIP7 data requirements." ;
		:horizontal_label = "hxy" ;
		:host_collection = "CMIP7" ;
		:initialization_index = "i1" ;
		:institution = "Met Office Hadley Centre" ;
		:institution_id = "MOHC" ;
		:license_id = "CC-BY-4.0" ;
		:mip_era = "CMIP7" ;
		:nominal_resolution = "100 km" ;
		:outpath = "/Users/mauzey1/Desktop/github/cmor3_documentation/mydoc/examples/c/output" ;
		:physics_index = "p1" ;
		:product = "model-output" ;
		:realization_index = "r1" ;
		:realm = "land" ;
		:region = "glb" ;
		:source = "ACCESS-ESM1-6: aerosol: classic; atmosphere: um7-3; land-surface: cable3; ocean-biogeochemistry: wombatlite; ocean: mom5; sea-ice: cice5" ;
		:source_id = "ACCESS-ESM1-6" ;
		:table_info = "Name: CMIP7_land.json; Creation Date:(2026-07-21 13:16:24) MD5:ea523449976b1c3cc3c14c1492f2fb74" ;
		:temporal_label = "ti" ;
		:title = "ACCESS-ESM1-6 output prepared for CMIP7" ;
		:tracking_id = "hdl:21.14107/5626edc0-7233-466f-bd17-52a4304c3ad9" ;
		:variable_id = "rootd" ;
		:variant_label = "r1i1p1f1" ;
		:vertical_label = "u" ;
		:license = "CC-BY-4.0; CMIP7 data produced by MOHC is licensed under a Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0). Consult https://wcrp-cmip.github.io/cmip7-guidance/docs/CMIP7/Guidance_for_users/#2-terms-of-use-and-citations-requirements for terms of use governing CMIP7 output, including citation requirements and proper acknowledgment. The data producers and data providers make no warranty, either express or implied, including, but not limited to, warranties of merchantability and fitness for a particular purpose. All liabilities arising from the supply of the information (including any liability arising in negligence) are excluded to the fullest extent permitted by law." ;
		:cmor_version = "3.15.2" ;
data:

 lat = 10, 20, 30 ;

 lat_bnds =
  5, 15,
  15, 25,
  25, 35 ;

 lon = 0, 90, 180, 270 ;

 lon_bnds =
  -45, 45,
  45, 135,
  135, 225,
  225, 315 ;

 rootd =
  0.5, 0.45, _, 0.55,
  0.6, 0.6, _, 0.55,
  _, 0.45, 0.5, 0.5 ;
}


Tags: examples c cmip7