cmor_setup()

Fortran: error_flag = cmor_setup(inpath=’./’, netcdf_file_action=CMOR_PRESERVE, set_verbosity=CMOR_NORMAL, exit_control=CMOR_NORMAL, logfile, create_subdirectories)

C: error_flag = cmor_setup(char *inpath, int *netcdf_file_action, int *set_verbosity, int *exit_control, char *logfile, int *create_subdirectories)

Python: setup(inpath=’.’, netcdf_file_action=CMOR_PRESERVE, set_verbosity=CMOR_NORMAL, exit_control=CMOR_NORMAL, logfile=None, create_subdirectories=1)

Description: Initialize CMOR, specify path to MIP table(s) that will be read by CMOR, specify whether existing output files will be overwritten, and specify how error messages will be handled

Arguments:

  • [inpath] = a character string specifying the path to the directory where the needed MIP-specific tables reside.

  • [netcdf_file_action] = controls handling of existing netCDF files. If the value passed is CMOR_REPLACE, a new file will be created; any existing file with the same name as the one CMOR is trying to create will be overwritten. If the value is CMOR_APPEND, an existing file will be appended; if the file does not exist, it will be created. If the value is CMOR_PRESERVE, a new file will be created unless a file by the same name already exists, in which case the program will error exit.[8] To generate a NetCDF file in the “CLASSIC” NetCDF3 format, a “_3” should be appended to the above parameters (e.g., CMOR_APPEND would become CMOR_APPEND_3). To generate a NetCDF file in the “CLASSIC” NetCDF4 format, a “_4” should be appended to the above parameters (e.g., CMOR_APPEND would become CMOR_APPEND_4), this allows the user to take advantage of NetCDF4 compression and chunking capabilities. The default values (no underscore) are aliased to the _4 values (satisfying the requirements of CMIP6).

  • [set_verbosity] controls how informational messages and error messages generated by CMOR are handled. If set_verbosity=CMOR_NORMAL, errors and warnings will be sent to the standard error device (typically the user’s screen). If verbosity=CMOR_QUIET, then only error messages will be sent (and warnings will be suppressed).

  • [exit_control] determines if errors will trigger program to exit:
  • CMOR_EXIT_ON_MAJOR = stop only on critical error;
  • CMOR_NORMAL = stop only if severe errors;
  • CMOR_EXIT_ON_WARNING = stop even after minor errors detected.

  • [logfile] where CMOR will write its messages – default is “standard error” (stderr).

  • [create_subdirectories] do we want to create the correct path subdirectory structure or simply dump the files wherever cmor_dataset will point to.

Returns upon success:

  • Fortran: 0
  • C: 0
  • Python: None

cmor_dataset_json()

Fortran: cmor_dataset_json(filename)

C: cmor_dataset_json(char *name)

Python: dataset_json(name)

Description: This function provides information to CMOR that is common to all output files that will be written. The “dataset” defined by this function refers to some or all of the output from a single model simulation (i.e., output from a single realization of a single experiment from a single model). Only one dataset can be defined at any time, but the dataset can be closed (by calling cmor_close()), and then another dataset can be defined by calling cmor_dataset. Note that after a new dataset is defined, all axes and variables must be defined; axes and variables defined earlier are not associated with the new dataset.

Arguments:

  • name: JSON file which contains all information needed by CMOR in the form of key:value. Here is an example: CMIP6_input_example.json

Returns upon success:

  • Fortran: 0
  • C: 0
  • Python: 0

cmor_set_cur_dataset_attribute()

Fortran: error_flag = cmor_set_cur_dataset_attribute(name,value)

C: error_flag = cmor_set_cur_dataset_attribute(char *name, char *value, int optional)

Python: set_cur_dataset_attribute(name,value)

Description: Associate a global attribute with the current dataset. In CMIP5, this function can be called to set, for example, “institute_id”, “initialization” and “physics”.

Arguments:

  • name = name of the global attribute to set.

  • value = character string containing the value of this attribute.

  • optional = an argument that is ignored. (Internally, CMOR calls this function and needs this argument.)

Returns upon success:

  • Fortran: 0
  • C: 0
  • Python: None

cmor_get_cur_dataset_attribute()

Fortran: error_flag = cmor_get_cur_dataset_attribute(name,result)

C: error_flag = cmor_get_cur_dataset_attribute(char *name, char *result)

Python: result = get_cur_dataset_attribute(name)

Description: Retrieves a global attribute associated with the current dataset.

Arguments:

  • name = name of the global attribute to retrieve.

  • result = string (or pointer to a string), which is returned by the function and contains the retrieved global attribute (not for Python).

Returns upon success:

  • Fortran: 0
  • C: 0
  • Python: None

cmor_has_cur_dataset_attribute()

Fortran: error_flag = cmor_has_cur_dataset_attribute(name)

C: error_flag = cmor_has_cur_dataset_attribute(char *name)

Python: error_flag = has_cur_dataset_attribute(name)

Description: Determines whether a global attribute is associated with the current dataset.

Arguments:

  • name = name of the global attribute of interest.

Returns:

  • a negative integer if an error is encountered; otherwise returns 0.
  • 0 upon success
  • True if the attribute exists, False otherwise.

cmor_load_table()

Fortran: table_id = cmor_load_table(table)

C: error_flag = cmor_load_table(char *table, int *table_id)

Python: table_id = load_table(table)

Description: Loads a table and returns a “handle” (table_id) to use later when defining CMOR components. CMOR will look for the table first following the path as specified by the “table” argument passed to this function. If it doesn’t find a file there it will prepend the outpath defined in calling cmor_dataset. If it still doesn’t find it, it will use the “prefix” where the library CMOR is to be installed (from configure time) followed by share (e.g /usr/local/cmor/share). If it stills fails an error will be raised.


cmor_set_table()

Fortran: cmor_set_table(table_id)

C: error_flag = cmor_set_table(int table_id)

Python: table_id = set_table(table_id)

Description: Sets the table referred to by table_id as the table to obtain needed information when defining CMOR components (variables, axes, grids, etc…).


cmor_axis()

Fortran: axis_id = cmor_axis([table], table_entry, units, [length], [coord_vals], [cell_bounds], [interval])

C: error_flag = cmor_axis(int *axis_id, char *table_entry, char *units, int length, void *coord_vals, char type, void *cell_bounds, int cell_bounds_ndim, char *interval)

Python: axis_id = axis(table_entry, length=??, coord_vals=None, units=None, cell_bounds=None, interval=None)

Description: Define an axis and pass the coordinate values associated with one of the dimensions of the data to be written. This function returns a “handle” (axis_id) that uniquely identifies the axis to be written. The axis_id will subsequently be passed by the user to other CMOR functions. The cmor_axis function will typically be repeatedly invoked to define all axes. The axis specified by the table_entry argument must be found in the currently “set” CMOR table, as specified by the cmor_load_table and cmor_set_table functions, or as an option, it can be provided in the Fortran version (for backward compatibility) by the now deprecated “table” keyword argument. There normally is no need to call this function in the case of a singleton (scalar) dimension unless the MIP recommended (or required) coordinate value (or cell_bounds) are inconsistent with what the user can supply, or unless the user wants to define the “interval” attribute. When defining a time axis in CMOR “Append mode” (in case the file already existed before a call to cmor_setup), time values and bounds should be set to NULL and instead be passed via cmor_write when writing data.

Arguments:

  • [table] = character string containing the filename of the MIP-specific table where the axis defined here appears. (e.g., ‘CMIP5_table_Amon’, ‘IPCC_table_A1’, ‘AMIP_table_1a’, ‘AMIP_table_2’, ‘CMIP_table_2’, etc.). In CMOR2 this is an optional argument and is deprecated because the table can be specified through the cmor_load_table and cmor_set_table functions.

  • axis_id = the “handle”: a positive integer returned by CMOR, which uniquely identifies the axis stored in this call to cmor_axis and subsequently can be used in calls to cmor_write.

  • table_entry = name of the axis (as it appears in the MIP table) that will be defined by this function. units = units associated with the coordinates passed in coord_vals and cell_bounds. (These are the units of the user’s coordinate values, which, if CMOR is built with udunits (as is required in version 2), may differ from the units of the coordinates written to the netCDF file by CMOR.) These units must be recognized by udunits or must be identical to the units specified in the MIP table. In the case of a dimensionless vertical coordinate or in the case of a non-numerical axis (like geographical region), either set units=’none’, or, optionally, set units=’1’.

  • [length] = integer specifying the number of elements that CMOR should extract from the coord_vals array (normally length will be the size of the array itself). For a simple “index axis” (i.e., an axis without coordinate values), this specifies the length of the dimension. In the Fortran and Python versions of the function, this argument is not always required (except in the case of a simple index axis); if omitted “length” will be the size of the coord_vals array,

  • [coord_vals] = 1-d array (single precision float, double precision float, or, for labels, character strings) containing coordinate values, ordered consistently with the data array that will be passed by the user to CMOR through function cmor_write (see documentation below). This argument is required except if: 1) the axis is a simple “index axis” (i.e., an axis without coordinate values), or 2) for a time coordinate, the user intends to pass the coordinate values when the cmor_write function is called. Note that the coordinate values must be ordered monotonically, so, for example, in the case of longitudes that might have the values, 0., 10., 20, … 170., 180., 190., 200., … 340., 350., passing the (equivalent) values, 0., 10., 20, … 170., 180., -170., -160., … -20., -10. is forbidden. In the case of time-coordinate values, if cell bounds are also passed, then CMOR will first check that each coordinate value is not outside its associated cell bounds; subsequently, however, the user-defined coordinate value will be replaced by the mid-point of the interval defined by its bounds, and it is this value that will be written to the netCDF file. In the case of character string coord_vals there are no cell_bounds, but for the C version of the function, the argument cell_bounds_ndim is used to specify the length of the strings in the coord_val array (i.e., the array will be dimensioned [length][cell_bounds_ndim]).

  • type = type of the coord_vals/bnds passed, which can be ‘d’ (double), ‘f’ (float), ‘l’ (long) or ‘i’ (int).

  • [cell_bounds] = 1-d or 2-d array (of the same type as coord_vals) containing cell bounds, which should be in the same units as coord_vals (specified in the “units” argument above) and should be ordered in the same way as coord_vals. In the case of a 1-d array, the size is one more than the size of coord_vals and the cells must be contiguous. In the case of a 2-d array, it is dimensioned (2, n) where n is the size of coord_vals (see CF standard document, http://www.cgd.ucar.edu/cms/eaton/cf-metadata, for further information). This argument may be omitted when cell bounds are not required. It must be omitted if coord_vals is omitted.

  • cell_bounds_ndim = This argument only appears in the the C version of this function. Except in the case of a character string axis, it specifies the rank of the cell_bounds array: if 1, the bounds array will contain n+1 elements, where n is length of coords and the cells must be contiguous, whereas if 2, the dimension will be (n,2) in C order. Pass 0 if no cell_bounds values have been passed. In the special case of a character string axis, this argument is used to specify the length of the strings in the coord_val array (i.e., the array will be dimensioned [length] [cell_bounds_ndim]).

  • [interval] = Supplemental information that will be included in the cell_methods attribute, which is typically defined for the time axis in order to describe the sampling interval. This string should be of the form: “value unit comment: anything” (where “comment:” and anything may always be omitted). For monthly mean data sampled every 15 minutes, for example, interval = “15 minutes”.

Returns:

  • Fortran: a negative integer if an error is encountered; otherwise returns a positive integer (the “handle”) uniquely identifying the axis ..
  • C: 0 upon success.
  • Python: upon success, a positive integer (the “handle”) uniquely identifying the axis, or if an error is encountered an exception is raised.

cmor_grid()

Fortran: grid_id = cmor_grid(axis_ids, latitude, longitude, [latitude_vertices], [longitude_vertices], [area])

C: error_flag = cmor_grid(int *grid_id, int ndims, int *axis_ids, char type, void *latitude, void *longitude, int nvertices, void *latitude_vertices, void *longitude_vertices, void *area)

Python: grid_id = grid( axis_ids, latitude, longitude, latitude_vertices=None, longitude_vertices=None, area=None)

Description: Define a grid to be associated with data, including the latitude and longitude arrays. The grid can be structured with up to 6 dimensions. These dimensions, which may be simple “index” axes, must be defined via cmor_axis prior to calling cmor_grid. This function returns a “handle” (grid_id) that uniquely identifies the grid (and its data/metadata) to be written. The grid_id will subsequently be passed by the user to other CMOR functions. The cmor_grid function will typically be invoked to define each grid necessary for the experiment (e.g ocean grid, vegetation grid, atmosphere grid, etc…). There is no need to call this function in the case of a Cartesian lat/lon grid. In this case, simply define the latitude and longitude axes and pass their id’s (“handles”) to cmor_variable.

Arguments:

  • grid_id = the “handle”: a positive integer returned by CMOR, which uniquely identifies the grid defined in this call to CMOR and subsequently can be used in calls to CMOR.

  • ndims = number of dimensions needed to define the grid. Namely the number of elements from axis_ids that will be used.

  • axis_ids = array containing the axis_s returned by cmor_axis when defining the axes constituing the grid.

  • latitude = array containing the grid’s latitude information (ndim dimensions)

  • longitude = array containing the grid’s longitude information (ndim dimensions)

  • [latitude_vertices] = array containing the grid’s latitude vertices information (ndim+1 dimensions). The vertices dimension must be the fastest varying dimension of the array (i.e first one in Fortran, last one in C, last one in Python)

  • [longitude_vertices] = array containing the grid’s longitude vertices information (ndim+1 dimensions). The vertices dimension must be the fastest varying dimension of the array (i.e first one in Fortran, last one in C, last one in Python)

  • [area] = array containing the grid’s area information (ndim)

Returns:

  • Fortran: a positive integer if an error is encountered; otherwise returns a negative integer (the “handle”) uniquely identifying the grid.
  • C: 0 upon success.
  • Python: upon success, a positive integer (the “handle”) uniquely identifying the axis, or if an error is encountered an exception is raised.

cmor_set_grid_mapping()

Fortran: error_flag = cmor_set_grid_mapping(grid_id, mapping_name, parameter_names, parameter_values, parameter_units)

C: error_flag = cmor_set_grid_mapping(int grid_id, char *mapping_name, int nparameters, char **parameter_names, int lparameters, double parameter_values[], char **parameter_units, int lunits)

Python: set_grid_mapping(grid_id, mapping_name, parameter_names, parameter_values=None, parameter_units=None)

Description: Define the grid mapping parameters associated with a grid (see CF conventions for more info on which parameters to set). Check validity of parameter names and units. Additional mapping names and parameter names can be defined via the MIP table.

Arguments:

  • grid_id = the “handle” returned by a previous call to cmor_grid, indicating which grid the mapping parameters should be associated with.

  • mapping_name = name of the mapping (see CF conventions). This name dictates which parameters should be set and for some parameters restricts their possible values or range. New mapping names can be added via MIP tables.

  • nparameters = number of parameters set.

  • parameter_names = array (list for Python) of strings containing the names of the parameters to set. In the case of “standard_parallel”, CF allows either 1 or 2 parallels to be specified (i.e. the attribute standard_parallel may be an array of length 2). In the case of 2 parallels, CMOR requires the user to specify these as separate parameters, named standard_parallel_1 and standard_parallel_2, but then the two parameters will be stored in an array, consistent with CF. In the case of a single parallel, the name standard_parallel should be specified. In the C version of this function, parameter_names is declared of length [nparameters][lparameters], where lparameters in the length of each string array element (see below). In Python parameter_names can be defined as a dictionary containing the keys that represent the parameter_names. The value associated with each key can be either a list [float, str] (or [str, float]) representing the value/units of each parameter, or another dictionary containing the keys “value” and “units”. If these conditions are fulfilled, then parameter_units and parameter_values are optional and would be ignored if passed.

  • lparameters = length of each element of the string array. If, for example, parameter_names includes 5 parameters, each 24 characters long (i.e., it is declared [5][24]), you would pass lparameters=24.

  • parameter_values = array containing the values associated with each parameter. In Python this is optional if parameter_names is a dictionary containing the values and units.

  • parameter_units = array (list for Python) of string containing the units of the parameters to set. In C parameter_units is declared of length [nparameters][lunits]. In Python it is optional if parameter_names is a dictionary containing the value and units.

  • lunits = length of each elements of the units string array (e.g., if parameters_units is declared [5][24], you would pass 24 because each elements has 24 characters).

Returns upon success:

  • Fortran: 0
  • C: 0
  • Python: None

cmor_time_varying_grid_coordinate()

Fortran: coord_var_id = cmor_time_varying_grid_coordinate(grid_id, table_entry, units, missing_value)

C: error_flag = cmor_time_varying_grid_coordinate(int *coord_var_id, int grid_id, char *table_entry, char *units, char type, void *missing, [int *coordinate_type])

Python: coord_var_id = time_varying_grid_coordinate(grid_id, table_entry, units, [missing_value])

Description: Define a grid to be associated with data, including the latitude and longitude arrays. Note that in CMIP5 this function must be called to store the variables called for in the cf3hr MIP table. The grid can be structured with up to 6 dimensions. These dimensions, which may be simple “index” axes, must be defined via cmor_axis prior to calling cmor_grid. This function returns a “handle” (grid_id) that uniquely identifies the grid (and its data/metadata) to be written. The grid_id will subsequently be passed by the user to other CMOR functions. The cmor_grid function will typically be invoked to define each grid necessary for the experiment (e.g., ocean grid, vegetation grid, atmosphere grid, etc.). There is no need to call this function in the case of a Cartesian lat/lon grid. In this case, simply define the latitude and longitude axes and pass their id’s (“handles”) to cmor_variable.

Arguments:

  • coord_var_id = the “handle”: a positive integer returned by this function, which uniquely identifies the variable and can be used in subsequent calls to CMOR.

  • grid_id = the value returned by cmor_grid when the grid was created.

  • table_entry = name of the variable (as it appears in the MIP table) that this function defines.

  • units = units of the data that will be passed to CMOR by function cmor_write. These units may differ from the units of the data output by CMOR. Whenever possible, this string should be interpretable by udunits (see http://my.unitdata.ucar.edu/content/software/udunits/). In the case of dimensionless quantities the units should be specified consistent with the CF conventions, so for example: percent, units=’%’; for a fraction, units=’1’; for parts per million, units=’1e-6’, etc.).

  • type = type of the missing_value, which must be the same as the type of the array that will be passed to cmor_write. The options are: ‘d’ (double), ‘f’ (float), ‘l’ (long) or ‘i’ (int).

  • [missing_value] = scalar that is used to indicate missing data for this variable. It must be the same type as the data that will be passed to cmor_write. This missing_value will in general be replaced by a standard missing_value specified in the MIP table. If there are no missing data, and the user chooses not to declare the missing value, then this argument may be omitted.

  • [coordinate_type] = place holder for future implementation, unused, pass NULL

Returns:

  • Fortran: a positive integer if an error is encountered; otherwise returns a negative integer (the “handle”) uniquely identifying the grid.
  • C: 0 upon success.
  • Python: upon success, a positive integer (the “handle”) uniquely identifying the axis, or if an error is encountered an exception is raised.

cmor_zfactor()

Fortran: zfactor_id = cmor_zfactor(zaxis_id, zfactor_name, [axis_ids], [units], zfactor_values, zfactor_bounds)

C: error_flag = cmor_zfactor (int *zfactor_id, int zaxis_id, char *zfactor_name, char *units, int ndims, int axis_ids[], char type, void *zfactor_values, void *zfactor_bounds)

Python: zfactor_id = zfactor(zaxis_id, zfactor_name, units, axis_ids, data_type, zfactor_values=None, zfactor_bounds=None)

Description: Define a factor needed to convert a non-dimensional vertical coordinate (model level) to a physical location. For pressure, height, or depth, this function is unnecessary, but for dimensionless coordinates it is needed. In the case of atmospheric sigma coordinates, for example, a scalar parameter must be defined indicating the top of the model, and the variable containing the surface pressure must be identified. The parameters that must be defined for different vertical dimensionless coordinates are listed in Appendix D of the CF convention document (http://www.cgd.ucar.edu/cms/eaton/cf-metadata). Often bounds for the zfactors will be needed (e.g., for hybrid sigma coordinates, “A’s” and “B’s” must be defined both for the layers and, often more importantly, for the layer interfaces). This function must be invoked for each z-factor required.

Arguments:

  • zfactor_id = the “handle”: a positive integer returned by this function which uniquely identifies the grid defined in this call to CMOR and can subsequently be used in calls to CMOR.

  • zaxis_id = an integer (“handle”) returned by cmor_axis (which must have been previously called) indicating which axis requires this factor.

  • zfactor_name = name of the z-factor that will be defined by this function. This should correspond to an entry in the MIP table.

  • [axis_ids] = an integer array containing the list of axis_id’s (individually defined by calls to cmor_axis), which the z-factor defined here is a function of (e.g. for surface pressure, the array of i.d.’s would usually include the longitude, latitude, and time axes.) The order of the axes must be consistent with the array passed as param_values. If the z-factor parameter is a function of a single dimension (e.g., model level), the single axis_id should be passed as an array of rank one and length 1, not as a scalar. If the parameter is a scalar, then this parameter may be omitted. If this parameter is carried on a non-cartesian latitude-longitude grid, then the grid_id should be passed instead of axis_ids, for latitude/longitude. Again if axis_ids collapses to a scalar, it should be passed as an array of rank one and length 1, not as a scalar.

  • [units] = units associated with the z-factor passed in zfactor_values and zfactor_bounds. (These are the units of the user’s z-factors, which may differ from the units of the z-factors written to the netCDF file by CMOR.) . These units must be recognized by udunits or must be identical to the units specified in the MIP table. In the case of a dimensionless z-factors, either omit this argument, or set units=’’, or set units=’1’.

  • type = type of the zfactor_values and zfactor_bounds (if present) passed to this function. This can be ‘d’ (double), ‘f’ (float), ‘l’ (long), ‘i’ (int), or ‘c’ (char).

  • [zfactor_values] = z-factor values associated with dimensionless vertical coordinate identified by zaxis_id. If this z-factor is a function of time (e.g., surface pressure for sigma coordinates), the user can omit this argument and instead store the z-factor values by calling cmor_write. In that case the cmor_write argument, “var_id”, should be set to zfactor_id (returned by this function) and the argument, “store_with”, should be set to the variable id of the output field that requires zfactor as part of its metadata. When many fields are a function of the (dimensionless) model level, cmor_write will have to be called several times, with the same zfactor_id, but with different variable ids. If no values are passed, omit this argument.

  • [zfactor_bounds] = z-factor values associated with the cell bounds of the vertical dimensionless coordinate. These values should be of the same type as the zfactor_values (e.g., if zfactor_values is double precision, then zfactor_bounds must also be double precision). If no bounds values are passed, omit this argument or set zfactor = ‘none’. This is a ONE dimensional array of length nlevs+1.

Returns:

  • Fortran: a negative integer if an error is encountered; otherwise returns a positive integer (the “handle”) uniquely identifying the z-factor.
  • C: 0 upon success.
  • Python: upon success, a positive integer (the “handle”) uniquely identifying the z-factor, or if an error is encountered an exception is raised.

cmor_variable()

Fortran: var_id = cmor_variable([table], table_entry, units, axis_ids, [missing_value], [tolerance], [positive], [original_name], [history], [comment])

C: error_flag = int cmor_variable(int var_id, char *table_entry, char *units, int ndims, int axis_ids[], char type, void *missing, double *tolerance, char *positive, charoriginal_name, char *history, char *comment)

Python: var_id = variable(table_entry, units, axis_ids, data_type=’f’, missing_value=None, tolerance = 1.e-4, positive=None, original_name=None, history=None, comment=None)

Description: Define a variable to be written by CMOR and indicate which axes are associated with it. This function prepares CMOR to write the file that will contain the data for this variable. This function returns a “handle” (var_id), uniquely identifying the variable, which will subsequently be passed as an argument to the cmor_write function. The variable specified by the table_entry argument must be found in the currently “set” CMOR table, as specified by the cmor_load_table and cmor_set_table functions, or as an option, it can be provided in the Fortran version (for backward compatibility) by the now deprecated “table” keyword argument. The cmor_variable function will typically be repeatedly invoked to define other variables. Note that backward compatibility was kept with the Fortran-only optional “table” keyword. But it is now recommended to use cmor_load_table and cmor_set_table instead (and necessary for C/Python).

Arguments:

  • var_id = the “handle”: a positive integer returned by this function, which uniquely identifies the variable and can be used in subsequent calls to CMOR.

  • [table] = character string containing the filename of the MIP-specific table where table_entry (described next) can be found (e.g., “CMIP5_table_amon”, ‘IPCC_table_A1’, ‘AMIP_table_1a’, ‘AMIP_table_2’, ‘CMIP_table_2’, etc.) In CMOR2 this is an optional argument and is deprecated because the table can be specified through the cmor_load_table and cmor_set_table functions.

  • table_entry = name of the variable (as it appears in the MIP table) that this function defines.

  • units = units of the data that will be passed to CMOR by function cmor_write. These units may differ from the units of the data output by CMOR. Whenever possible, this string should be interpretable by udunits (see http://my.unitdata.ucar.edu/content/software/udunits/). In the case of dimensionless quantities the units should be specified consistent with the CF conventions, so for example: percent, units=’%’; for a fraction, units=’1’; for parts per million, units=’1e-6’, etc.).

  • ndims = number of axes the variable contains (i.e., the rank of the array), which in fact is the number of elements in the axis_ids array that will be processed by CMOR.

  • axis_ids = 1-d array containing integers returned by cmor_axis, which specifies, via their “handles” (i.e., axis_ids), the axes associated with the variable that this function defines. These handles should be ordered consistently with the data that will be passed to CMOR through function cmor_write (see documentation below). If the size of the 1-d array is larger than the number of dimensions, the ‘unused’ dimension handles must be set to 0. Note that if the handle of a single axis is passed, it must not be passed as a scalar but as a rank 1 array of length 1. Scalar (“singleton”) dimensions defined in the MIP table may be omitted from axis_ids unless they have been explicitly redefined by the user through calls to cmor_axis. A “singleton” dimension that has been explicitly defined by the user should appear last in the list of axis_ids if the array of data passed to cmor_write for this variable actually omits this dimension; otherwise it should appear consistent with the position of the axis in the array of data passed to cmor_write. In the case of a non-Cartesian grid, replace the values of the grid specific axes (representing the lat/lon axes) with the single grid_id returned by cmor_grid.

  • type = type of the missing_value, which must be the same as the type of the array that will be passed to cmor_write. The options are: ‘d’ (double), ‘f’ (float), ‘l’ (long) or ‘i’ (int).

  • [missing_value] = scalar that is used to indicate missing data for this variable. It must be the same type as the data that will be passed to cmor_write. This missing_value will in general be replaced by a standard missing_value specified in the MIP table. If there are no missing data, and the user chooses not to declare the missing value, then this argument may be omitted or assigned the value ‘none’ (i.e., missing_value=’none’).

  • [tolerance] = scalar (type real) indicating fractional tolerance allowed in missing values found in the data. A value will be considered missing if it lies within ±tolerance*missing_value of missing_value. The default tolerance for real and double precision missing values is 1.0e-4 and for integers 0. This argument is ignored if the missing_value argument is not present.

  • [positive] = ‘up’ or ‘down’ depending on whether a user-passed vertical energy (heat) flux or surface momentum flux (stress) input to CMOR is positive when it is directed upward or downward, respectively. This information will be used by CMOR to determine whether a sign change is necessary to make the data consistent with the MIP requirements. This argument is required for vertical energy and salt fluxes, for “flux correction” fields, and for surface stress; it is ignored for all other variables.

  • [original_name] = the name of the variable as it is commonly known at the user’s home institute. If the variable passed to CMOR was computed in some simple way from two or more original fields (e.g., subtracting the upwelling and downwelling fluxes to get a net flux), then it is recommended that this be indicated in the “original_name” (e.g., “irup – irdown”, where “irup” and “irdown” are the names of the original fields that were subtracted). If more complicated processing was required, this information would more naturally be included in a “history” attribute for this variable, described next.

  • [history] = how the variable was processed before outputting through CMOR (e.g., give name(s) of the file(s) from which the data were read and indicate what calculations were performed, such as interpolating to standard pressure levels or adding 2 fluxes together). This information should allow someone at the user’s institute to reproduce the procedure that created the CMOR output. Note that this history attribute is variable-specific, whereas the history attribute defined by cmor_dataset provides information concerning the model simulation itself or refers to processing procedures common to all variables (for example, mapping model output from an irregular grid to a Cartesian coordinate grid). Note that when appropriate, CMOR will also indicate in the “history” attribute any operations it performs on the data (e.g., scaling the data, changing the sign, changing its type, reordering the dimensions, reversing a coordinate’s direction or offsetting longitude). Any user-defined history will precede the information generated by CMOR.

  • [comment] = additional notes concerning this variable can be included here.

Returns:

  • Fortran: a negative integer if an error is encountered; otherwise returns a positive integer (the “handle”) uniquely identifying the variable.
  • C: 0 upon success.
  • Python: upon success, a positive integer (the “handle”) uniquely identifying the variable, or if an error is encountered an exception is raised.

cmor_set_deflate()

Fortran: error_flag = cmor_set_deflate(var_id, shuffle, deflate, deflate_level)

C: error_flag = cmor_set_deflate(int var_id, int shuffle, int deflate, int deflate_level)

Python: set_deflate(var_id, shuffle, deflate, deflate_level)

Description: Sets netCDF4 shuffle and compression on a CMOR variable.

Arguments:

  • var_id = the cmor variable id

  • shuffle = if true, turn on netCDF the shuffle filter

  • deflate = if true, turn on the deflate filter at the level specified by the deflate_level parameter

  • deflate_level = if the deflate parameter is non-zero, deflate variable using value. Must be between 0 and 9

Returns upon success:

  • Fortran: 0
  • C: 0
  • Python: 0

cmor_set_zstandard()

Fortran: error_flag = cmor_set_zstandard(var_id, zstandard_level)

C: error_flag = cmor_set_zstandard(int var_id, int zstandard_level)

Python: set_zstandard(var_id, zstandard_level)

Description: Sets netCDF4 Zstandard compression level on a CMOR variable. CMOR’s deflate compression must be disabled (use cmor_set_deflate to set to false) to enable the use of Zstandard compression on the netCDF file’s data variable.

Arguments:

  • var_id = the cmor variable id

  • zstandard_level = Compression level. Must be between -131072 and 22

Returns upon success:

  • Fortran: 0
  • C: 0
  • Python: 0

cmor_set_quantize()

Fortran: error_flag = cmor_set_quantize(var_id, quantize_mode, quantize_nsd)

C: error_flag = cmor_set_quantize(int var_id, int quantize_mode, int quantize_nsd)

Python: set_quantize(var_id, quantize_mode, quantize_nsd)

Description: Sets netCDF4 quantization mode and number of significant digits/bits preserved.

Arguments:

  • var_id = the cmor variable id

  • quantize_mode = Quantization mode. Can be set to the following values.
    • 0: No quantization mode
    • 1: BitGroom
    • 2: Granular BitRound
    • 3: BitRound
  • quantize_nsd = Number of significant digits. If quantize_mode is set to 1 or 2, then the value can be set from 1 to 7 for floats and 1 to 23 for doubles. If quantize_mode is set to 3, then the value can be set from 1 to 15 for floats and 1 to 52 for doubles. The value is ignore if quantize_mode is 0.

Returns upon success:

  • Fortran: 0
  • C: 0
  • Python: 0

cmor_set_variable_attribute()

Fortran: error_flag = cmor_set_variable_attribute(integer var_id, character(*) name, character(*) type, character(*) value)

C: error_flag = cmor_set_variable_attribute(int variable_id, char *attribute_name, char type, void *value)

Python: set_variable_attribute(var_id,name,data_type,value)

Description: Defines an attribute to be associated with the variable specified by the variable_id. This function is unlikely to be called in preparing CMIP5 output, except to delete the “ext_cell_measures” attribute (setting it to a empty string). For this reason you can only set character type attributes at the moment via Python and Fortran.

Arguments:

  • variable_id = the “handle” returned by cmor_variable (when the variable was defined), which will become better described by the attribute defined in this function.

  • attribute_name = name of the attribute

  • type = type of the attribute value passed, which can be ‘d’ (double), ‘f’ (float), ‘l’ (long), ‘i’ (int), or ‘c’ (char).

  • value = whatever value you wish to set the attribute to (type defined by type argument).

Returns upon success:

  • Fortran: 0
  • C: 0
  • Python: 0

cmor_get_variable_attribute()

Fortran: error_flag = cmor_get_variable_attribute(integer var_id, character(*) name, character *value)

C: error_flag = cmor_get_variable_attribute(int variable_id, char *attribute_name, char type, void *value)

Python: get_variable_attribute(var_id,name)

Description: retrieves an attribute value set for the variable specified by the variable_id. This function is unlikely to be called in preparing CMIP5 output. The Python and Fortran version will only work on attribute of character (string) type, otherwise chaotic results should be expected

Arguments:

  • variable_id = the “handle” returned by cmor_variable (when the variable was defined) identifying which variable the attribute is associated with.

  • attribute_name = name of the attribute

  • type = type of the attribute value to be retrieved. This can be ‘d’ (double), ‘f’ (float), ‘l’ (long), ‘i’ (int), or ‘c’ (char)

  • value = the argument that will accept the retrieved attribute.

Returns upon success:

  • Fortran: 0
  • C: 0
  • Python: The attribute value

cmor_has_variable_attribute()

Fortran: error_flag = cmor_has_variable_attribute(integer var_id, character(*) name)

C: error_flag = cmor_has_variable_attribute(int variable_id, char *attribute_name)

Python: has_variable_attribute(var_id,name)

Description: Determines whether an attribute exists and is associated with the variable specified by variable_id, which is a handle returned to the user by a previous call to cmor_variable. This function is unlikely to be called in preparing CMIP5 output.

Arguments:

  • variable_id = the “handle” specifying which variable is of interest. A variable_id is returned by cmor_variable each time a variable is defined.

  • attribute_name = name of the attribute of interest.

Returns upon success (i.e., if the attribute is found):

  • Fortran: 0
  • C: 0
  • Python: True

cmor_create_output_path()

Fortran: call cmor_create_output_path(var_id, path)

C : isfixed = cmor_create_output_path(int var_id, char *path)

Python: path = create_output_path(var_id)

Description: construct the output path, consistent with CMIP5 specifications, where the file will be stored.

Arguments:

  • var_id = variable identification (as returned from cmor_variable) you wish to get the output path for.

  • path = string (or pointer to a string), which is returned by the function and contains the output path.

Returns:

  • Fortran: nothing it is a subroutine
  • C: 0 upon success or 1 if the filed is a fixed field
  • Python: the full path to the output file

cmor_write()

Fortran: error_flag = cmor_write(var_id, data, [file_suffix], [ntimes_passed], [time_vals], [time_bnds], [store_with])

C: error_flag = cmor_write(int var_id, void *data, char type, char *file_suffix, int ntimes_passed, double *time_vals, double *time_bounds, int *store_with)

Python: write(var_id, data, ntimes_passed=None, file_suffix=””, time_vals=None, time_bnds=None, store_with=None)

Description: For the variable identified by var_id, write an array of data that includes one or more time samples. This function will typically be repeatedly invoked to write other variables or append additional time samples of data. Note that time-slices of data must be written chronologically.

Arguments:

  • var_id = integer returned by cmor_variable identifying the variable that will be written by this function.

  • data = array of data written by this function (of rank<8). The rank of this array should either be: (a) consistent with the number of axes that were defined for it, or (b) it should be 1-dimensional, in which case the data must be stored contiguously in memory. In case (a), an exception is that for a variable that is a function of time and when only one “time-slice” is passed, then the array can optionally omit this dimension. Thus, for a variable that is a function of longitude, latitude, and time, for example, if only a single time-slice is passed to cmor_write, the rank of array “data” may be declared as either 2 or 3; when declared rank 3, the time-dimension will be size 1. It is recommended (but not required) that the shape of data (i.e., the size of each dimension) be consistent with those expected for this variable (based on the axis definitions), but they are allowed to be larger (the extra values beyond the defined dimension domain will be ignored). In any case the dimension sizes (lengths) must obviously not be smaller than those defined by the calls to cmor_axis.

  • type = type of variable array (“data”), which can be ‘d’ (double), ‘f’ (float), ‘l’ (long) or ‘i’ (int).

  • [file_suffix] = string that will be concatenated with a string automatically generated by CMOR to form a unique filename where the output is written. This suffix is only required when a time-sequence of output fields will not all be written into a single file (i.e., two or more files will contain the output for the variable). The file prefix generated by CMOR is of the form variable_table, where variable is replaced by table_entry (i.e., the name of the variable), and table is replaced by the table number (e.g., tas_A1 refers to surface air temperature as specified in table A1). Permitted characters will be: a-z, A-Z, 0-9, and “-”. There are no restrictions on the suffix except that it must yield unique filenames and that it cannot contain any “”. If the user supplies a suffix, the leading ‘’ should be omitted (e.g., pass ‘1979-1988’, not ‘_1979-1988’). Note that the suffix passed through cmor_write remains in effect for the particular variable until (optionally) redefined by a subsequent call. In the case of CMOR “Append mode” (in case the file already existed before a call to cmor_setup), then file_suffix is to be used to point to the original file, this value should reflect the FULL path where the file can be found, not just the file name. CMOR2 will be smart enough to figure out if a suffix was used when creating that file. Note that this file will be first moved to a temporary file and eventually renamed to reflect the additional times written to it.

  • [ntimes_passed] = integer number of time slices passed on this call. If omitted, the number will be assumed to be the size of the time dimension of the data (if there is a time dimension).

  • [time_vals] = 1-d array (must be double precision) time coordinate values associated with the data array. This argument should appear only if the time coordinate values were not passed in defining the time axis (i.e., in calling cmor_axis) such as when CMOR is set to “Append mode.” The units should be consistent with those passed as an argument to cmor_axis in defining the time axis. If cell bounds are also passed (see next argument, ‘[time_bnds]’), then CMOR will first check that each coordinate value is not outside its associated cell bounds; subsequently, however, the user-defined coordinate value will be replaced by the mid-point of the interval defined by its bounds, and it is this value that will be written to the netCDF file.

  • [time_bnds] = 2-d array (must be double precision) containing time bounds, which should be in the same units as time_vals. If the time_vals argument is omitted, this argument should also be omitted. The array should be dimensioned (2, n) in Fortran, and (n,2) in C/Python, where n is the size of time_vals (see CF standard document, http://www.cgd.ucar.edu/cms/eaton/cf-metadata, for further information).

  • [store_with] = integer returned by cmor_variable identifying the variable that the zfactor should be stored with. This argument must be defined when and only when writing a z-factor. (See description of the zfactor function above.)

Returns upon success:

  • Fortran: 0
  • C: 0
  • Python: None

cmor_close()

Fortran: error_flag = cmor_close(var_id, file_name, preserve)

C: error_flag = cmor_close(void) or

C: error_flag = cmor_close_variable(int var_id, char *file_name, int *preserve)

Python: error_flag (or if name=True, returns the name of the file) = close(var_id=None, file_name=False, preserve=False)

Description: Close a single file specified by optional argument var_id, or if this argument is omitted, close all files created by CMOR (including log files). To be safe, before exiting any program that invokes CMOR, it is best to call this function with the argument omitted. In C to close a single variable, use: cmor_close_variable(var_id). When using this function to close a single file, an additional optional argument (of type “string”) can be included, into which will be returned the file name created by CMOR. [In python, the string is returned by the function.] Another additional optional argument can be passed specifying if the variable should be preserved for future use (e.g., if you want to write additional data but to a new file). Note that when preserve is true, the original var_id is preserved.

Arguments:

  • [var_id] = the “handle” identifying an individual variable and the associated output file that will be closed by this function.

  • [file_name] = a string where the output file name will be stored. The file_name is returned only if its var_id has been included in the close_cmor argument list. This option provides a convenient method for the user to record the filename, which might be needed on a subsequent call to CMOR, for example, in order to append additional time samples to the file.

  • [preserve] = Do you want to preserve the var definition? (0/1) If true, the original var_id is preserved.

Returns:

  • Fortran: 0 upon success
  • C: 0 upon success
  • Python: None if file_name=False, or the name of the file if file_name=True and a var_id is passed as an argument.

cmor_get_terminate_signal()

Fortran: signal_code = cmor_get_terminate_signal()

C: signal_code = cmor_get_terminate_signal()

Python: signal_code = get_terminate_signal()

Description: Get the current value of the signal code issue by CMOR’s C when encountering a termination error. Initially this is set to -999. If the user does not set it then the first call to cmor_setup will set the signal to SIGTERM for C and Python and to SIGINT for FORTRAN. FORTRAN does exit nicely with SIGTERM, hence the different default values

Returns upon success:

  • Fortran: the current signal code
  • C: the current signal code
  • Python: the current signal code

cmor_set_terminate_signal()

Fortran: cmor_set_terminate_signal(signal)

C: cmor_set_terminate_signal(int signal)

Python: set_terminate_signal(signal)

Description: Set sthe signal code to send uppon termination from an error

Arguments:

  • [signal] = an integer representing the signal code desired