These examples are based on the CMOR repository’s examples/fortran directory. They use the same shared CMIP7 user input file as the Python 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 Fortran compiler:
mamba create -n cmor-fortran -c conda-forge cmor fortran-compiler udunits2
mamba activate cmor-fortran
If you use Conda instead of Mamba, use the same package list:
conda create -n cmor-fortran -c conda-forge cmor fortran-compiler udunits2
conda activate cmor-fortran
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
- CMIP7_input_example.json
- CMIP7_coordinate.json
- CMIP7_formula_terms.json
- CMIP7_cell_measures.json
- CMIP7_long_name_overrides.json
- cmor-cvs.json
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 Fortran Utilities
Click to expand common Fortran code
module cmip7_fortran_common
use cmor_users_functions
implicit none
integer, parameter :: nlon = 4
integer, parameter :: nlat = 3
integer, parameter :: ntimes = 2
real, parameter :: missing_value = 1.0e20
contains
subroutine get_example_args(tables_path, input_path, output_dir)
character(len=*), intent(out) :: tables_path
character(len=*), intent(out) :: input_path
character(len=*), intent(out) :: output_dir
call get_command_argument(1, tables_path)
call get_command_argument(2, input_path)
call get_command_argument(3, output_dir)
if (len_trim(tables_path) == 0) tables_path = "./cmip7-cmor-tables/tables"
if (len_trim(input_path) == 0) input_path = "./CMIP7_input_example.json"
if (len_trim(output_dir) == 0) output_dir = "output"
end subroutine get_example_args
subroutine load_shared_user_input(input_path, output_dir, frequency, &
realization_index, forcing_index)
character(len=*), intent(in) :: input_path
character(len=*), intent(in) :: output_dir
character(len=*), intent(in), optional :: frequency
character(len=*), intent(in), optional :: realization_index
character(len=*), intent(in), optional :: forcing_index
integer :: ierr
ierr = cmor_dataset_json(trim(input_path))
call check_status("cmor_dataset_json", ierr)
ierr = cmor_set_cur_dataset_attribute("outpath", trim(output_dir), 1)
call check_status("cmor_set_cur_dataset_attribute(outpath)", ierr)
if (present(frequency)) then
ierr = cmor_set_cur_dataset_attribute("frequency", trim(frequency), 1)
call check_status("cmor_set_cur_dataset_attribute(frequency)", ierr)
endif
if (present(realization_index)) then
ierr = cmor_set_cur_dataset_attribute("realization_index", &
trim(realization_index), 1)
call check_status("cmor_set_cur_dataset_attribute(realization_index)", ierr)
endif
if (present(forcing_index)) then
ierr = cmor_set_cur_dataset_attribute("forcing_index", &
trim(forcing_index), 1)
call check_status("cmor_set_cur_dataset_attribute(forcing_index)", ierr)
endif
end subroutine load_shared_user_input
subroutine check_status(call_name, ierr)
character(len=*), intent(in) :: call_name
integer, intent(in) :: ierr
if (ierr /= 0) then
write(*, '(a, i0)') trim(call_name)//" failed with status ", ierr
stop 1
endif
end subroutine check_status
subroutine check_id(call_name, cmor_id)
character(len=*), intent(in) :: call_name
integer, intent(in) :: cmor_id
if (cmor_id < 0) then
write(*, '(a, i0)') trim(call_name)//" failed with id ", cmor_id
stop 1
endif
end subroutine check_id
subroutine check_grid_id(call_name, cmor_id)
character(len=*), intent(in) :: call_name
integer, intent(in) :: cmor_id
if (cmor_id > -CMOR_MAX_GRIDS) then
write(*, '(a, i0)') trim(call_name)//" failed with grid id ", cmor_id
stop 1
endif
end subroutine check_grid_id
subroutine apply_cmip7_variable_metadata(var_id, tables_path, realm, &
table_entry, frequency, region)
integer, intent(in) :: var_id
character(len=*), intent(in) :: tables_path
character(len=*), intent(in) :: realm
character(len=*), intent(in) :: table_entry
character(len=*), intent(in) :: frequency
character(len=*), intent(in) :: region
character(len=2048) :: compound_name
character(len=2048) :: cell_measures
character(len=2048) :: long_name
integer :: ierr
logical :: found
call cmip7_compound_name(realm, table_entry, frequency, region, &
compound_name)
cell_measures = ""
call lookup_json_string(trim(tables_path)//"/CMIP7_cell_measures.json", &
trim(compound_name), cell_measures, found)
ierr = cmor_set_variable_attribute(var_id, "cell_measures", &
trim(cell_measures))
call check_status("cmor_set_variable_attribute(cell_measures)", ierr)
long_name = ""
call lookup_json_string(trim(tables_path)//"/CMIP7_long_name_overrides.json", &
trim(compound_name), long_name, found)
if (found) then
ierr = cmor_set_variable_attribute(var_id, "long_name", trim(long_name))
call check_status("cmor_set_variable_attribute(long_name)", ierr)
endif
end subroutine apply_cmip7_variable_metadata
subroutine cmip7_compound_name(realm, table_entry, frequency, region, &
compound_name)
character(len=*), intent(in) :: realm
character(len=*), intent(in) :: table_entry
character(len=*), intent(in) :: frequency
character(len=*), intent(in) :: region
character(len=*), intent(out) :: compound_name
character(len=1024) :: normalized_entry
integer :: i
normalized_entry = table_entry
do i = 1, len_trim(normalized_entry)
if (normalized_entry(i:i) == "_") normalized_entry(i:i) = "."
enddo
compound_name = trim(realm)//"."//trim(normalized_entry)//"."// &
trim(frequency)//"."//trim(region)
end subroutine cmip7_compound_name
subroutine lookup_json_string(path, key, value, found)
character(len=*), intent(in) :: path
character(len=*), intent(in) :: key
character(len=*), intent(out) :: value
logical, intent(out) :: found
character(len=8192) :: line
character(len=2050) :: search_key
integer :: colon_pos
integer :: ierr
integer :: quote_1
integer :: quote_2
integer :: start_pos
integer :: unit
value = ""
found = .false.
search_key = '"'//trim(key)//'"'
open(newunit=unit, file=trim(path), status="old", action="read", &
iostat=ierr)
if (ierr /= 0) then
write(*, '(a)') "Could not open CMIP7 metadata table: "//trim(path)
stop 1
endif
do
read(unit, '(a)', iostat=ierr) line
if (ierr /= 0) exit
if (index(line, trim(search_key)) == 0) cycle
colon_pos = index(line, ":")
if (colon_pos == 0) exit
quote_1 = index(line(colon_pos + 1:), '"')
if (quote_1 == 0) exit
start_pos = colon_pos + quote_1
quote_2 = index(line(start_pos + 1:), '"')
if (quote_2 == 0) exit
value = line(start_pos + 1:start_pos + quote_2 - 1)
found = .true.
exit
enddo
close(unit)
end subroutine lookup_json_string
end module cmip7_fortran_common
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_fortran_compiler() {
if [[ -n "${FC:-}" ]]; then
command -v "$FC" >/dev/null 2>&1 || {
echo "FC is set to '$FC', but that compiler was not found" >&2
exit 2
}
echo "$FC"
return
fi
local compiler
for compiler in "$CONDA_PREFIX"/bin/*gfortran "$CONDA_PREFIX"/bin/gfortran; do
if [[ -x "$compiler" ]]; then
echo "$compiler"
return
fi
done
if command -v gfortran >/dev/null 2>&1; then
command -v gfortran
return
fi
echo "Could not find a Fortran compiler. Install gfortran in the active conda environment or set FC." >&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
FC="$(detect_fortran_compiler)"
CMOR_PREFIX="${CMOR_PREFIX:-$CONDA_PREFIX}"
CMOR_MOD_DIR="${CMOR_MOD_DIR:-$CMOR_PREFIX/include}"
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_MOD_DIR/cmor_users_functions.mod" ]]; then
echo "Could not find cmor_users_functions.mod in $CMOR_MOD_DIR. Install cmor in the active conda environment or set CMOR_MOD_DIR." >&2
exit 2
fi
FFLAGS_DEFAULT="-g -O2 -ffree-line-length-none"
FFLAGS="${FFLAGS:-$FFLAGS_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
if [[ "$(uname -s)" != "Darwin" || "$link_dir" != "$CONDA_PREFIX/lib" ]]; then
LINK_FLAGS+=("-Wl,-rpath,$link_dir")
fi
done
INCLUDES=("-I$CMOR_MOD_DIR" "-I$BUILD_DIR" "-I$CONDA_PREFIX/include")
COMMON_SRC="$SCRIPT_DIR/cmip7_fortran_common.f90"
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.f90"
exe="$BUILD_DIR/$example"
run_output="$OUTPUT_ROOT/$example"
mkdir -p "$run_output"
echo "Compiling $example"
"$FC" $FFLAGS -J "$BUILD_DIR" "${INCLUDES[@]}" "$COMMON_SRC" "$src" "${LINK_FLAGS[@]}" $EXTRA_LDFLAGS -o "$exe"
echo "Running $example"
"$exe" "$TABLES_PATH" "$INPUT_PATH" "$run_output"
done
echo "Wrote CMIP7 example output under $OUTPUT_ROOT"
Example 1: Regular Grid Ocean Field
Click to expand Fortran code
program example_01_regular_grid_tos
use cmip7_fortran_common
implicit none
character(len=1024) :: output_dir
character(len=2048) :: tables_path
character(len=2048) :: input_path
integer :: lat_id
integer :: lon_id
integer :: time_id
integer :: var_id
integer :: ierr
integer :: nul_pos
real :: tos(nlon, nlat, ntimes)
character(len=2048) :: filename
double precision :: lat(nlat)
double precision :: lon(nlon)
double precision :: time(ntimes)
double precision :: lat_bnds(2, nlat)
double precision :: lon_bnds(2, nlon)
double precision :: time_bnds(2, ntimes)
call get_example_args(tables_path, input_path, output_dir)
ierr = cmor_setup(inpath=trim(tables_path), &
netcdf_file_action=CMOR_REPLACE, &
exit_control=CMOR_EXIT_ON_MAJOR)
call check_status("cmor_setup", ierr)
call load_shared_user_input(input_path, output_dir)
ierr = cmor_load_table("CMIP7_ocean.json")
call check_id("cmor_load_table(CMIP7_ocean)", ierr)
lat = (/ 10.0d0, 20.0d0, 30.0d0 /)
lat_bnds(:, 1) = (/ 5.0d0, 15.0d0 /)
lat_bnds(:, 2) = (/ 15.0d0, 25.0d0 /)
lat_bnds(:, 3) = (/ 25.0d0, 35.0d0 /)
lon = (/ 0.0d0, 90.0d0, 180.0d0, 270.0d0 /)
lon_bnds(:, 1) = (/ -45.0d0, 45.0d0 /)
lon_bnds(:, 2) = (/ 45.0d0, 135.0d0 /)
lon_bnds(:, 3) = (/ 135.0d0, 225.0d0 /)
lon_bnds(:, 4) = (/ 225.0d0, 315.0d0 /)
time = (/ 15.5d0, 45.5d0 /)
time_bnds(:, 1) = (/ 0.0d0, 31.0d0 /)
time_bnds(:, 2) = (/ 31.0d0, 60.0d0 /)
lon_id = cmor_axis(table="CMIP7_ocean.json", &
table_entry="longitude", &
units="degrees_east", &
length=nlon, &
coord_vals=lon, &
cell_bounds=lon_bnds)
call check_id("cmor_axis(longitude)", lon_id)
lat_id = cmor_axis(table="CMIP7_ocean.json", &
table_entry="latitude", &
units="degrees_north", &
length=nlat, &
coord_vals=lat, &
cell_bounds=lat_bnds)
call check_id("cmor_axis(latitude)", lat_id)
time_id = cmor_axis(table="CMIP7_ocean.json", &
table_entry="time", &
units="days since 1979-01-01", &
length=ntimes, &
coord_vals=time, &
cell_bounds=time_bnds)
call check_id("cmor_axis(time)", time_id)
tos(:, :, 1) = reshape((/ &
254.0895, 258.4085, missing_value, 258.7101, &
258.6680, 258.2990, missing_value, 255.0432, &
253.7254, 251.2460, missing_value, 255.4808 /), &
(/ nlon, nlat /))
tos(:, :, 2) = reshape((/ &
254.0995, 258.5085, missing_value, 258.8101, &
258.8680, 258.4990, missing_value, 255.2432, &
254.0254, 251.5460, missing_value, 255.7808 /), &
(/ nlon, nlat /))
var_id = cmor_variable(table="CMIP7_ocean.json", &
table_entry="tos_tavg-u-hxy-sea", &
units="degC", &
axis_ids=(/ lon_id, lat_id, time_id /), &
missing_value=missing_value)
call check_id("cmor_variable(tos)", var_id)
call apply_cmip7_variable_metadata(var_id, tables_path, "ocean", &
"tos_tavg-u-hxy-sea", "mon", "glb")
ierr = cmor_write(var_id, tos)
call check_status("cmor_write", ierr)
filename = ""
ierr = cmor_close(var_id, file_name=filename)
call check_status("cmor_close(var)", ierr)
nul_pos = index(filename, char(0))
if (nul_pos > 0) filename(nul_pos:) = " "
write(*, '(a)') trim(filename)
ierr = cmor_close()
call check_status("cmor_close", ierr)
end program example_01_regular_grid_tos
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:47:26Z" ;
: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:47:26Z ; 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/fortran/output/example_01_regular_grid_tos" ;
: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/2edfc3a9-7309-4cd4-be00-0ab3b26a8ef8" ;
: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 Fortran code
program example_02_pressure_levels
use cmip7_fortran_common
implicit none
integer, parameter :: nplev = 19
character(len=1024) :: output_dir
character(len=2048) :: tables_path
character(len=2048) :: input_path
integer :: lat_id
integer :: lon_id
integer :: time_id
integer :: plev_id
integer :: var_id
integer :: ierr
integer :: nul_pos
integer :: i
integer :: j
integer :: k
integer :: t
real :: ta(nlon, nlat, nplev, ntimes)
character(len=2048) :: filename
double precision :: lat(nlat)
double precision :: lon(nlon)
double precision :: time(ntimes)
double precision :: lat_bnds(2, nlat)
double precision :: lon_bnds(2, nlon)
double precision :: time_bnds(2, ntimes)
double precision :: plev(nplev)
call get_example_args(tables_path, input_path, output_dir)
ierr = cmor_setup(inpath=trim(tables_path), &
netcdf_file_action=CMOR_REPLACE, &
exit_control=CMOR_EXIT_ON_MAJOR)
call check_status("cmor_setup", ierr)
call load_shared_user_input(input_path, output_dir)
ierr = cmor_load_table("CMIP7_atmos.json")
call check_id("cmor_load_table(CMIP7_atmos)", ierr)
lat = (/ 10.0d0, 20.0d0, 30.0d0 /)
lat_bnds(:, 1) = (/ 5.0d0, 15.0d0 /)
lat_bnds(:, 2) = (/ 15.0d0, 25.0d0 /)
lat_bnds(:, 3) = (/ 25.0d0, 35.0d0 /)
lon = (/ 0.0d0, 90.0d0, 180.0d0, 270.0d0 /)
lon_bnds(:, 1) = (/ -45.0d0, 45.0d0 /)
lon_bnds(:, 2) = (/ 45.0d0, 135.0d0 /)
lon_bnds(:, 3) = (/ 135.0d0, 225.0d0 /)
lon_bnds(:, 4) = (/ 225.0d0, 315.0d0 /)
time = (/ 15.5d0, 45.5d0 /)
time_bnds(:, 1) = (/ 0.0d0, 31.0d0 /)
time_bnds(:, 2) = (/ 31.0d0, 60.0d0 /)
lon_id = cmor_axis(table="CMIP7_atmos.json", &
table_entry="longitude", &
units="degrees_east", &
length=nlon, &
coord_vals=lon, &
cell_bounds=lon_bnds)
call check_id("cmor_axis(longitude)", lon_id)
lat_id = cmor_axis(table="CMIP7_atmos.json", &
table_entry="latitude", &
units="degrees_north", &
length=nlat, &
coord_vals=lat, &
cell_bounds=lat_bnds)
call check_id("cmor_axis(latitude)", lat_id)
time_id = cmor_axis(table="CMIP7_atmos.json", &
table_entry="time", &
units="days since 1979-01-01", &
length=ntimes, &
coord_vals=time, &
cell_bounds=time_bnds)
call check_id("cmor_axis(time)", time_id)
plev = (/ 100000.0d0, 92500.0d0, 85000.0d0, 70000.0d0, 60000.0d0, &
50000.0d0, 40000.0d0, 30000.0d0, 25000.0d0, 20000.0d0, &
15000.0d0, 10000.0d0, 7000.0d0, 5000.0d0, 3000.0d0, &
2000.0d0, 1000.0d0, 500.0d0, 100.0d0 /)
plev_id = cmor_axis(table="CMIP7_atmos.json", &
table_entry="plev19", &
units="Pa", &
length=nplev, &
coord_vals=plev)
call check_id("cmor_axis(plev19)", plev_id)
do t = 1, ntimes
do k = 1, nplev
do j = 1, nlat
do i = 1, nlon
ta(i, j, k, t) = 250.0 + 25.0 * real(i + 4*j + 12*k + 228*(t-1)) &
/ real(nlon*nlat*nplev*ntimes)
enddo
enddo
enddo
enddo
ta(1, 1, 1, 1) = missing_value
var_id = cmor_variable(table="CMIP7_atmos.json", &
table_entry="ta_tavg-p19-hxy-air", &
units="K", &
axis_ids=(/ lon_id, lat_id, plev_id, time_id /), &
missing_value=missing_value)
call check_id("cmor_variable(ta)", var_id)
call apply_cmip7_variable_metadata(var_id, tables_path, "atmos", &
"ta_tavg-p19-hxy-air", "mon", "glb")
ierr = cmor_write(var_id, ta)
call check_status("cmor_write", ierr)
filename = ""
ierr = cmor_close(var_id, file_name=filename)
call check_status("cmor_close(var)", ierr)
nul_pos = index(filename, char(0))
if (nul_pos > 0) filename(nul_pos:) = " "
write(*, '(a)') trim(filename)
ierr = cmor_close()
call check_status("cmor_close", ierr)
end program example_02_pressure_levels
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:47:27Z" ;
: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:47:27Z ; 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/fortran/output/example_02_pressure_levels" ;
: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/597d2d8a-e397-436a-b4fa-216cdba9b904" ;
: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 Fortran code
program example_03_scalar_height_tas
use cmip7_fortran_common
implicit none
character(len=1024) :: output_dir
character(len=2048) :: tables_path
character(len=2048) :: input_path
integer :: lat_id
integer :: lon_id
integer :: time_id
integer :: height_id
integer :: var_id
integer :: ierr
integer :: nul_pos
real :: tas(nlon, nlat, ntimes)
character(len=2048) :: filename
double precision :: lat(nlat)
double precision :: lon(nlon)
double precision :: time(ntimes)
double precision :: lat_bnds(2, nlat)
double precision :: lon_bnds(2, nlon)
double precision :: time_bnds(2, ntimes)
call get_example_args(tables_path, input_path, output_dir)
ierr = cmor_setup(inpath=trim(tables_path), &
netcdf_file_action=CMOR_REPLACE, &
exit_control=CMOR_EXIT_ON_MAJOR)
call check_status("cmor_setup", ierr)
call load_shared_user_input(input_path, output_dir, &
realization_index="r9", forcing_index="f2")
ierr = cmor_load_table("CMIP7_atmos.json")
call check_id("cmor_load_table(CMIP7_atmos)", ierr)
lat = (/ 10.0d0, 20.0d0, 30.0d0 /)
lat_bnds(:, 1) = (/ 5.0d0, 15.0d0 /)
lat_bnds(:, 2) = (/ 15.0d0, 25.0d0 /)
lat_bnds(:, 3) = (/ 25.0d0, 35.0d0 /)
lon = (/ 0.0d0, 90.0d0, 180.0d0, 270.0d0 /)
lon_bnds(:, 1) = (/ -45.0d0, 45.0d0 /)
lon_bnds(:, 2) = (/ 45.0d0, 135.0d0 /)
lon_bnds(:, 3) = (/ 135.0d0, 225.0d0 /)
lon_bnds(:, 4) = (/ 225.0d0, 315.0d0 /)
time = (/ 15.5d0, 45.5d0 /)
time_bnds(:, 1) = (/ 0.0d0, 31.0d0 /)
time_bnds(:, 2) = (/ 31.0d0, 60.0d0 /)
lon_id = cmor_axis(table="CMIP7_atmos.json", &
table_entry="longitude", &
units="degrees_east", &
length=nlon, &
coord_vals=lon, &
cell_bounds=lon_bnds)
call check_id("cmor_axis(longitude)", lon_id)
lat_id = cmor_axis(table="CMIP7_atmos.json", &
table_entry="latitude", &
units="degrees_north", &
length=nlat, &
coord_vals=lat, &
cell_bounds=lat_bnds)
call check_id("cmor_axis(latitude)", lat_id)
time_id = cmor_axis(table="CMIP7_atmos.json", &
table_entry="time", &
units="days since 1979-01-01", &
length=ntimes, &
coord_vals=time, &
cell_bounds=time_bnds)
call check_id("cmor_axis(time)", time_id)
height_id = cmor_axis(table="CMIP7_atmos.json", &
table_entry="height2m", &
units="m", &
length=1, &
coord_vals=(/ 2.0d0 /))
call check_id("cmor_axis(height2m)", height_id)
tas(:, :, 1) = reshape((/ &
254.0895, 258.4085, 250.5549, 258.7101, &
258.6680, 258.2990, 252.1237, 255.0432, &
253.7254, 251.2460, 254.3168, 255.4808 /), &
(/ nlon, nlat /))
tas(:, :, 2) = reshape((/ &
259.7908, 252.2754, 257.1892, 253.3132, &
253.8823, 253.4698, 253.5381, 254.9730, &
256.1002, 251.8168, 259.3698, 250.2994 /), &
(/ nlon, nlat /))
var_id = cmor_variable(table="CMIP7_atmos.json", &
table_entry="tas_tavg-h2m-hxy-u", &
units="K", &
axis_ids=(/ lon_id, lat_id, time_id /), &
missing_value=missing_value)
call check_id("cmor_variable(tas)", var_id)
call apply_cmip7_variable_metadata(var_id, tables_path, "atmos", &
"tas_tavg-h2m-hxy-u", "mon", "glb")
ierr = cmor_write(var_id, tas)
call check_status("cmor_write", ierr)
filename = ""
ierr = cmor_close(var_id, file_name=filename)
call check_status("cmor_close(var)", ierr)
nul_pos = index(filename, char(0))
if (nul_pos > 0) filename(nul_pos:) = " "
write(*, '(a)') trim(filename)
ierr = cmor_close()
call check_status("cmor_close", ierr)
end program example_03_scalar_height_tas
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:47:27Z 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:47:27Z" ;
: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:47:27Z ; 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/fortran/output/example_03_scalar_height_tas" ;
: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/f42fe7e0-84a9-4319-8e0e-a992e2ab3383" ;
: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 Fortran code
program example_04_basin_axis
use cmip7_fortran_common
implicit none
integer, parameter :: nbasin = 3
character(len=1024) :: output_dir
character(len=2048) :: tables_path
character(len=2048) :: input_path
character(len=21) :: basin_names(nbasin)
integer :: lat_id
integer :: time_id
integer :: basin_id
integer :: var_id
integer :: ierr
integer :: nul_pos
real :: heat_transport(nlat, nbasin, ntimes)
character(len=2048) :: filename
double precision :: lat(nlat)
double precision :: lat_bnds(2, nlat)
double precision :: time(ntimes)
double precision :: time_bnds(2, ntimes)
call get_example_args(tables_path, input_path, output_dir)
ierr = cmor_setup(inpath=trim(tables_path), &
netcdf_file_action=CMOR_REPLACE, &
exit_control=CMOR_EXIT_ON_MAJOR)
call check_status("cmor_setup", ierr)
call load_shared_user_input(input_path, output_dir)
ierr = cmor_load_table("CMIP7_ocean.json")
call check_id("cmor_load_table(CMIP7_ocean)", ierr)
lat = (/ 10.0d0, 20.0d0, 30.0d0 /)
lat_bnds(:, 1) = (/ 5.0d0, 15.0d0 /)
lat_bnds(:, 2) = (/ 15.0d0, 25.0d0 /)
lat_bnds(:, 3) = (/ 25.0d0, 35.0d0 /)
lat_id = cmor_axis(table="CMIP7_ocean.json", &
table_entry="latitude", &
units="degrees_north", &
length=nlat, &
coord_vals=lat, &
cell_bounds=lat_bnds)
call check_id("cmor_axis(latitude)", lat_id)
time = (/ 15.5d0, 45.5d0 /)
time_bnds(:, 1) = (/ 0.0d0, 31.0d0 /)
time_bnds(:, 2) = (/ 31.0d0, 60.0d0 /)
time_id = cmor_axis(table="CMIP7_ocean.json", &
table_entry="time", &
units="days since 1979-01-01", &
length=ntimes, &
coord_vals=time, &
cell_bounds=time_bnds)
call check_id("cmor_axis(time)", time_id)
basin_names(1) = "atlantic_arctic_ocean"
basin_names(2) = "indian_pacific_ocean"
basin_names(3) = "global_ocean"
basin_id = cmor_axis(table="CMIP7_ocean.json", &
table_entry="basin", &
units="", &
length=nbasin, &
coord_vals=basin_names)
call check_id("cmor_axis(basin)", basin_id)
heat_transport(:, :, 1) = reshape((/ &
-80.0, -84.0, -88.0, &
-100.0, -104.0, -76.0, &
-120.0, -92.0, -96.0 /), &
(/ nlat, nbasin /))
heat_transport(:, :, 2) = reshape((/ &
-79.0, -83.0, -87.0, &
-99.0, -103.0, -75.0, &
-107.0, -111.0, -115.0 /), &
(/ nlat, nbasin /))
var_id = cmor_variable(table="CMIP7_ocean.json", &
table_entry="htovgyre_tavg-u-hyb-sea", &
units="W", &
axis_ids=(/ lat_id, basin_id, time_id /), &
missing_value=missing_value)
call check_id("cmor_variable(htovgyre)", var_id)
call apply_cmip7_variable_metadata(var_id, tables_path, "ocean", &
"htovgyre_tavg-u-hyb-sea", "mon", "glb")
ierr = cmor_write(var_id, heat_transport)
call check_status("cmor_write", ierr)
filename = ""
ierr = cmor_close(var_id, file_name=filename)
call check_status("cmor_close(var)", ierr)
nul_pos = index(filename, char(0))
if (nul_pos > 0) filename(nul_pos:) = " "
write(*, '(a)') trim(filename)
ierr = cmor_close()
call check_status("cmor_close", ierr)
end program example_04_basin_axis
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:47:28Z" ;
: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:47:28Z ; 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/fortran/output/example_04_basin_axis" ;
: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/4c90e087-f0ec-4b17-b053-075386b92c40" ;
: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 Fortran code
program example_05_hybrid_sigma_levels
use cmip7_fortran_common
implicit none
integer, parameter :: nlev = 5
character(len=1024) :: output_dir
character(len=2048) :: tables_path
character(len=2048) :: input_path
integer :: lat_id
integer :: lon_id
integer :: time_id
integer :: lev_id
integer :: ps_id
integer :: var_id
integer :: ierr
integer :: nul_pos
integer :: i
integer :: j
integer :: k
integer :: t
real :: cl(nlon, nlat, nlev, ntimes)
real :: ps(nlon, nlat, ntimes)
character(len=2048) :: filename
double precision :: lat(nlat)
double precision :: lon(nlon)
double precision :: time(ntimes)
double precision :: lat_bnds(2, nlat)
double precision :: lon_bnds(2, nlon)
double precision :: time_bnds(2, ntimes)
double precision :: lev(nlev)
double precision :: lev_bnds(nlev + 1)
double precision :: a_coeff(nlev)
double precision :: b_coeff(nlev)
double precision :: a_bnds(nlev + 1)
double precision :: b_bnds(nlev + 1)
double precision :: p0
call get_example_args(tables_path, input_path, output_dir)
ierr = cmor_setup(inpath=trim(tables_path), &
netcdf_file_action=CMOR_REPLACE, &
exit_control=CMOR_EXIT_ON_MAJOR)
call check_status("cmor_setup", ierr)
call load_shared_user_input(input_path, output_dir)
ierr = cmor_load_table("CMIP7_atmos.json")
call check_id("cmor_load_table(CMIP7_atmos)", ierr)
lat = (/ 10.0d0, 20.0d0, 30.0d0 /)
lat_bnds(:, 1) = (/ 5.0d0, 15.0d0 /)
lat_bnds(:, 2) = (/ 15.0d0, 25.0d0 /)
lat_bnds(:, 3) = (/ 25.0d0, 35.0d0 /)
lon = (/ 0.0d0, 90.0d0, 180.0d0, 270.0d0 /)
lon_bnds(:, 1) = (/ -45.0d0, 45.0d0 /)
lon_bnds(:, 2) = (/ 45.0d0, 135.0d0 /)
lon_bnds(:, 3) = (/ 135.0d0, 225.0d0 /)
lon_bnds(:, 4) = (/ 225.0d0, 315.0d0 /)
time = (/ 15.5d0, 45.5d0 /)
time_bnds(:, 1) = (/ 0.0d0, 31.0d0 /)
time_bnds(:, 2) = (/ 31.0d0, 60.0d0 /)
lon_id = cmor_axis(table="CMIP7_atmos.json", &
table_entry="longitude", &
units="degrees_east", &
length=nlon, &
coord_vals=lon, &
cell_bounds=lon_bnds)
call check_id("cmor_axis(longitude)", lon_id)
lat_id = cmor_axis(table="CMIP7_atmos.json", &
table_entry="latitude", &
units="degrees_north", &
length=nlat, &
coord_vals=lat, &
cell_bounds=lat_bnds)
call check_id("cmor_axis(latitude)", lat_id)
time_id = cmor_axis(table="CMIP7_atmos.json", &
table_entry="time", &
units="days since 1979-01-01", &
length=ntimes, &
coord_vals=time, &
cell_bounds=time_bnds)
call check_id("cmor_axis(time)", time_id)
lev = (/ 0.92d0, 0.72d0, 0.50d0, 0.30d0, 0.10d0 /)
lev_bnds = (/ 1.00d0, 0.83d0, 0.61d0, 0.40d0, 0.20d0, 0.00d0 /)
lev_id = cmor_axis(table="CMIP7_atmos.json", &
table_entry="standard_hybrid_sigma", &
units="1", &
length=nlev, &
coord_vals=lev, &
cell_bounds=lev_bnds)
call check_id("cmor_axis(standard_hybrid_sigma)", lev_id)
a_coeff = (/ 0.12d0, 0.22d0, 0.30d0, 0.20d0, 0.10d0 /)
b_coeff = (/ 0.80d0, 0.50d0, 0.20d0, 0.10d0, 0.00d0 /)
a_bnds = (/ 0.06d0, 0.18d0, 0.26d0, 0.25d0, 0.15d0, 0.00d0 /)
b_bnds = (/ 0.94d0, 0.65d0, 0.35d0, 0.15d0, 0.05d0, 0.00d0 /)
p0 = 100000.0d0
ierr = cmor_zfactor(zaxis_id=lev_id, &
zfactor_name="a", &
axis_ids=(/ lev_id /), &
zfactor_values=a_coeff, &
zfactor_bounds=a_bnds)
call check_id("cmor_zfactor(a)", ierr)
ierr = cmor_zfactor(zaxis_id=lev_id, &
zfactor_name="b", &
axis_ids=(/ lev_id /), &
zfactor_values=b_coeff, &
zfactor_bounds=b_bnds)
call check_id("cmor_zfactor(b)", ierr)
ierr = cmor_zfactor(zaxis_id=lev_id, &
zfactor_name="p0", &
units="Pa", &
zfactor_values=p0)
call check_id("cmor_zfactor(p0)", ierr)
ps_id = cmor_zfactor(zaxis_id=lev_id, &
zfactor_name="ps", &
axis_ids=(/ lon_id, lat_id, time_id /), &
units="Pa")
call check_id("cmor_zfactor(ps)", ps_id)
do t = 1, ntimes
do j = 1, nlat
do i = 1, nlon
ps(i, j, t) = 97000.0 + 400.0 * real(i - 1) &
+ 1600.0 * real(j - 1) + 100.0 * real(t - 1)
enddo
enddo
enddo
do t = 1, ntimes
do k = 1, nlev
do j = 1, nlat
do i = 1, nlon
cl(i, j, k, t) = 75.0 - 5.0 * real(k) - 1.2 * real(j - 1) &
+ 0.4 * real(i - 1) + 0.1 * real(t - 1)
enddo
enddo
enddo
enddo
var_id = cmor_variable(table="CMIP7_atmos.json", &
table_entry="cl_tavg-al-hxy-u", &
units="%", &
axis_ids=(/ lon_id, lat_id, lev_id, time_id /), &
missing_value=missing_value)
call check_id("cmor_variable(cl)", var_id)
call apply_cmip7_variable_metadata(var_id, tables_path, "atmos", &
"cl_tavg-al-hxy-u", "mon", "glb")
ierr = cmor_write(var_id, cl)
call check_status("cmor_write(cl)", ierr)
ierr = cmor_write(ps_id, ps, store_with=var_id)
call check_status("cmor_write(ps)", ierr)
filename = ""
ierr = cmor_close(var_id, file_name=filename)
call check_status("cmor_close(var)", ierr)
nul_pos = index(filename, char(0))
if (nul_pos > 0) filename(nul_pos:) = " "
write(*, '(a)') trim(filename)
ierr = cmor_close()
call check_status("cmor_close", ierr)
end program example_05_hybrid_sigma_levels
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:47:29Z" ;
: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:47:29Z ; 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/fortran/output/example_05_hybrid_sigma_levels" ;
: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/a775c733-b6ab-40b3-af61-4e1ce146fd92" ;
: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" ;
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 Fortran code
program example_06_curvilinear_grid
use cmip7_fortran_common
implicit none
integer, parameter :: nx = 4
integer, parameter :: ny = 3
integer, parameter :: nvertices = 4
character(len=1024) :: output_dir
character(len=2048) :: tables_path
character(len=2048) :: input_path
integer :: x_id
integer :: y_id
integer :: time_id
integer :: grid_id
integer :: grid_table_id
integer :: var_id
integer :: ierr
integer :: nul_pos
integer :: i
integer :: j
integer :: t
real :: hfls(nx, ny, ntimes)
character(len=2048) :: filename
double precision :: x(nx)
double precision :: y(ny)
double precision :: x_bnds(2, nx)
double precision :: y_bnds(2, ny)
double precision :: latitude(nx, ny)
double precision :: longitude(nx, ny)
double precision :: latitude_vertices(nvertices, nx, ny)
double precision :: longitude_vertices(nvertices, nx, ny)
double precision :: time(ntimes)
double precision :: time_bnds(2, ntimes)
character(len=30) :: parameter_names(6)
character(len=1) :: parameter_units(6)
double precision :: parameter_values(6)
call get_example_args(tables_path, input_path, output_dir)
ierr = cmor_setup(inpath=trim(tables_path), &
netcdf_file_action=CMOR_REPLACE, &
exit_control=CMOR_EXIT_ON_MAJOR)
call check_status("cmor_setup", ierr)
call load_shared_user_input(input_path, output_dir)
grid_table_id = cmor_load_table("CMIP7_grids.json")
call check_id("cmor_load_table(CMIP7_grids)", grid_table_id)
call cmor_set_table(grid_table_id)
x = (/ 0.0d0, 10000.0d0, 20000.0d0, 30000.0d0 /)
x_bnds(:, 1) = (/ -5000.0d0, 5000.0d0 /)
x_bnds(:, 2) = (/ 5000.0d0, 15000.0d0 /)
x_bnds(:, 3) = (/ 15000.0d0, 25000.0d0 /)
x_bnds(:, 4) = (/ 25000.0d0, 35000.0d0 /)
y = (/ 0.0d0, 10000.0d0, 20000.0d0 /)
y_bnds(:, 1) = (/ -5000.0d0, 5000.0d0 /)
y_bnds(:, 2) = (/ 5000.0d0, 15000.0d0 /)
y_bnds(:, 3) = (/ 15000.0d0, 25000.0d0 /)
x_id = cmor_axis(table_entry="x", units="m", length=nx, &
coord_vals=x, cell_bounds=x_bnds)
call check_id("cmor_axis(x)", x_id)
y_id = cmor_axis(table_entry="y", units="m", length=ny, &
coord_vals=y, cell_bounds=y_bnds)
call check_id("cmor_axis(y)", y_id)
do j = 1, ny
do i = 1, nx
latitude(i, j) = 10.0d0 * dble(j) - 2.0d0 * dble(i - 1)
longitude(i, j) = 280.0d0 + 10.0d0 * dble(i - 1) &
+ 2.0d0 * dble(j - 1)
latitude_vertices(:, i, j) = (/ latitude(i, j) - 5.0d0, &
latitude(i, j) - 4.0d0, latitude(i, j) + 5.0d0, &
latitude(i, j) + 4.0d0 /)
longitude_vertices(:, i, j) = (/ longitude(i, j) - 5.0d0, &
longitude(i, j) + 5.0d0, longitude(i, j) + 5.0d0, &
longitude(i, j) - 5.0d0 /)
enddo
enddo
grid_id = cmor_grid(axis_ids=(/ x_id, y_id /), &
latitude=latitude, &
longitude=longitude, &
latitude_vertices=latitude_vertices, &
longitude_vertices=longitude_vertices)
call check_grid_id("cmor_grid", grid_id)
parameter_names = (/ "standard_parallel1 ", &
"longitude_of_central_meridian", &
"latitude_of_projection_origin", &
"false_easting ", &
"false_northing ", &
"standard_parallel2 " /)
parameter_units = (/ " ", " ", " ", " ", " ", " " /)
parameter_values = (/ -20.0d0, 175.0d0, 13.0d0, 8.0d0, 0.0d0, 20.0d0 /)
ierr = cmor_set_grid_mapping(grid_id, "lambert_conformal_conic", &
parameter_names, parameter_values, parameter_units)
call check_status("cmor_set_grid_mapping", ierr)
ierr = cmor_load_table("CMIP7_atmos.json")
call check_id("cmor_load_table(CMIP7_atmos)", ierr)
time = (/ 15.5d0, 45.5d0 /)
time_bnds(:, 1) = (/ 0.0d0, 31.0d0 /)
time_bnds(:, 2) = (/ 31.0d0, 60.0d0 /)
time_id = cmor_axis(table="CMIP7_atmos.json", &
table_entry="time", &
units="days since 1979-01-01", &
length=ntimes, &
coord_vals=time, &
cell_bounds=time_bnds)
call check_id("cmor_axis(time)", time_id)
do t = 1, ntimes
do j = 1, ny
do i = 1, nx
hfls(i, j, t) = 80.0 + 2.0 * real(i - 1) + 8.0 * real(j - 1) &
+ real(t - 1)
enddo
enddo
enddo
var_id = cmor_variable(table="CMIP7_atmos.json", &
table_entry="hfls_tavg-u-hxy-u", &
units="W m-2", &
axis_ids=(/ grid_id, time_id /), &
positive="up", &
missing_value=missing_value)
call check_id("cmor_variable(hfls)", var_id)
call apply_cmip7_variable_metadata(var_id, tables_path, "atmos", &
"hfls_tavg-u-hxy-u", "mon", "glb")
ierr = cmor_write(var_id, hfls)
call check_status("cmor_write", ierr)
filename = ""
ierr = cmor_close(var_id, file_name=filename)
call check_status("cmor_close(var)", ierr)
nul_pos = index(filename, char(0))
if (nul_pos > 0) filename(nul_pos:) = " "
write(*, '(a)') trim(filename)
ierr = cmor_close()
call check_status("cmor_close", ierr)
end program example_06_curvilinear_grid
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:47:29Z 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:47:29Z" ;
: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:47:29Z ; 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/fortran/output/example_06_curvilinear_grid" ;
: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/75423cc2-95fe-459f-ab52-920d50b42956" ;
: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 Fortran code
program example_07_fixed_field_rootd
use cmip7_fortran_common
implicit none
character(len=1024) :: output_dir
character(len=2048) :: tables_path
character(len=2048) :: input_path
integer :: lat_id
integer :: lon_id
integer :: var_id
integer :: ierr
integer :: nul_pos
real :: rootd(nlon, nlat)
character(len=2048) :: filename
double precision :: lat(nlat)
double precision :: lon(nlon)
double precision :: lat_bnds(2, nlat)
double precision :: lon_bnds(2, nlon)
call get_example_args(tables_path, input_path, output_dir)
ierr = cmor_setup(inpath=trim(tables_path), &
netcdf_file_action=CMOR_REPLACE, &
exit_control=CMOR_EXIT_ON_MAJOR)
call check_status("cmor_setup", ierr)
call load_shared_user_input(input_path, output_dir, "fx")
ierr = cmor_load_table("CMIP7_land.json")
call check_id("cmor_load_table(CMIP7_land)", ierr)
lat = (/ 10.0d0, 20.0d0, 30.0d0 /)
lat_bnds(:, 1) = (/ 5.0d0, 15.0d0 /)
lat_bnds(:, 2) = (/ 15.0d0, 25.0d0 /)
lat_bnds(:, 3) = (/ 25.0d0, 35.0d0 /)
lon = (/ 0.0d0, 90.0d0, 180.0d0, 270.0d0 /)
lon_bnds(:, 1) = (/ -45.0d0, 45.0d0 /)
lon_bnds(:, 2) = (/ 45.0d0, 135.0d0 /)
lon_bnds(:, 3) = (/ 135.0d0, 225.0d0 /)
lon_bnds(:, 4) = (/ 225.0d0, 315.0d0 /)
lon_id = cmor_axis(table="CMIP7_land.json", &
table_entry="longitude", &
units="degrees_east", &
length=nlon, &
coord_vals=lon, &
cell_bounds=lon_bnds)
call check_id("cmor_axis(longitude)", lon_id)
lat_id = cmor_axis(table="CMIP7_land.json", &
table_entry="latitude", &
units="degrees_north", &
length=nlat, &
coord_vals=lat, &
cell_bounds=lat_bnds)
call check_id("cmor_axis(latitude)", lat_id)
rootd = reshape((/ &
0.50, 0.45, missing_value, 0.55, &
0.60, 0.60, missing_value, 0.55, &
missing_value, 0.45, 0.50, 0.50 /), &
(/ nlon, nlat /))
var_id = cmor_variable(table="CMIP7_land.json", &
table_entry="rootd_ti-u-hxy-lnd", &
units="m", &
axis_ids=(/ lon_id, lat_id /), &
missing_value=missing_value)
call check_id("cmor_variable(rootd)", var_id)
call apply_cmip7_variable_metadata(var_id, tables_path, "land", &
"rootd_ti-u-hxy-lnd", "fx", "glb")
ierr = cmor_write(var_id, rootd)
call check_status("cmor_write", ierr)
filename = ""
ierr = cmor_close(var_id, file_name=filename)
call check_status("cmor_close(var)", ierr)
nul_pos = index(filename, char(0))
if (nul_pos > 0) filename(nul_pos:) = " "
write(*, '(a)') trim(filename)
ierr = cmor_close()
call check_status("cmor_close", ierr)
end program example_07_fixed_field_rootd
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:47:30Z" ;
: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:47:30Z ; 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/fortran/output/example_07_fixed_field_rootd" ;
: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/fc175e85-c7a1-4461-a35b-6bd44fcb66db" ;
: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 ;
}