CMOR user input

{
           "_control_vocabulary_file": "CMIP6_CV.json",
           "_AXIS_ENTRY_FILE":         "CMIP6_coordinate.json",
           "_FORMULA_VAR_FILE":        "CMIP6_formula_terms.json",

           "#_cmip6_option":          "Trigger cmip6 specific validations",
           "_cmip6_option":           "CMIP6",

           "tracking_prefix":        "hdl:21.14100",
           "activity_id":            "ISMIP6",


           "#output":                "Output Path where files are written",
           "outpath":                "CMIP6",

           "#experiment_id":         "CMIP6 valid experiment_ids are found in CMIP6_CV.json",
           "experiment_id":          "piControl-withism",
           "sub_experiment_id":      "none",
           "sub_experiment":         "none",

           "source_type":            "AOGCM ISM AER",
           "parent_mip_era":         "N/A",
           "mip_era":                "CMIP6",
           "calendar":               "360_day",

           "realization_index":      "11",
           "initialization_index":   "1",
           "physics_index":          "1",
           "forcing_index":          "1",

           "#contact ":              "Not required",
           "contact ":              "Python Coder (coder@a.b.c.com)",

           "#history":               "not required, supplemented by CMOR",
           "history":                "Output from archivcl_A1.nce/giccm_03_std_2xCO2_2256.",

           "#comment":               "Not required",
           "comment":                "",

           "#references":            "Not required",
           "references":             "Model described by Koder and Tolkien (J. Geophys. Res., 2001, 576-591).  Also see http://www.GICC.su/giccm/doc/index.html  2XCO2 simulation described in Dorkey et al. '(Clim. Dyn., 2003, 323-357.)'",

           "grid":                   "gs1x1",
           "grid_label":             "gr",
           "nominal_resolution":     "5 km",

           "institution_id":         "PCMDI",

           "parent_experiment_id":   "histALL",
           "parent_activity_id":     "ISMIP6",
           "parent_mip_era":         "CMIP6",

           "parent_source_id":       "PCMDI-test-1-0",
           "parent_time_units":      "days since 1970-01-01",
           "parent_variant_label":   "r123i1p33f5",

           "branch_method":          "Spin-up documentation",
           "branch_time_in_child":   2310.0,
           "branch_time_in_parent":  12345.0,


           "#run_variant":           "Description of run variant (Recommended).",
           "run_variant":            "forcing: black carbon aerosol only",

           "#source_id":              "Model Source",
           "source_id":               "PCMDI-test-1-0",

           "#source":                "source title, first part is source_id",
           "source":                 "PCMDI-test 1.0",


           "#output_path_template":   "Template for output path directory using tables keys or global attributes",
           "output_path_template":    "<mip_era><activity_id><institution_id><source_id><experiment_id><_member_id><table><variable_id><grid_label><version>",
           "output_file_template":    "<variable_id><table><source_id><experiment_id><_member_id><grid_label>",

           "license":                 "CMIP6 model data produced by Lawrence Livermore PCMDI is licensed under a Creative Commons Attribution ShareAlike 4.0 International License (https://creativecommons.org/licenses). Consult https://pcmdi.llnl.gov/CMIP6/TermsOfUse for terms of use governing CMIP6 output, including citation requirements and proper acknowledgment. Further information about this data, including some limitations, can be found via the further_info_url (recorded as a global attribute in this file) and at https:///pcmdi.llnl.gov/. 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."

}

C source code

#include <time.h>
#include <stdio.h>
#include<string.h>
#include "cmor.h"
#include <stdlib.h>

void read_coords(alats, alons, plevs, bnds_lat, bnds_lon,lon,lat,lev)
     double *alats,*alons;
     int *plevs;
     double *bnds_lat,*bnds_lon;
     int lon,lat,lev;
{
  int i;
    
  for (i=0;i<lon;i++) {
    alons[i] = i*360./lon;
    bnds_lon[2*i] = (i - 0.5)*360./lon;
    bnds_lon[2*i+1] = (i + 0.5)*360./lon;
  };
  

  for (i=0;i<lat;i++) {
    alats[i] = (lat-i)*10;
    bnds_lat[2*i] = (lat-i)*10 + 5.;
    bnds_lat[2*i+1] = (lat-i)*10 - 5.;
  };
  

  plevs[0]=1000;
  plevs[1]=925;
  plevs[2]=850;
  plevs[3]=700;
  plevs[4]=600;
  plevs[5]=500;
  plevs[6]=400;
  plevs[7]=300;
  plevs[8]=250;
  plevs[9]=200;
  plevs[10]=150;
  plevs[11]=100;
  plevs[12]=70;
  plevs[13]=50;
  plevs[14]=30;
  plevs[15]=20;
  plevs[16]=10;
  plevs[17]=5;
  plevs[18]=1;
}

void read_time(it, time, time_bnds)
     int it;
     double time[];
     double time_bnds[];
{    
  time[0] = (it-0.5)*30.;
  time_bnds[0] = (it-1)*30.;
  time_bnds[1] = it*30.;

  time[0]=it;
  time_bnds[0] = it;
  time_bnds[1] = it+1;

}

void read_3d_input_files(it, varname, field,n0,n1,n2)
     int it,n0,n1,n2;
     char *varname;
     double field[];
{
  int i,j,k;
  float factor,offset,max,min;
  min=-1.e20;
  max=1.e20;
   
  if (strcmp(varname,"CLOUD")==0) {
    factor = 0.02;
    offset = -20.;
  }
  else if (strcmp(varname,"U")==0) {
    factor = .08;
    offset = 45.;
  }
  else if (strcmp(varname,"T")==0) {
    factor = 1.2;
    offset = -25.;
    min=161.;
    max=320.;
  }
    
  for (k=0;k<n2;k++) {
    for (j=0;j<n1;j++) {
      for (i=0;i<n0;i++) {
        field[k*(n0*n1)+j*n0+i] = (k*64 + j*16 + i*4 + it)*factor - offset;
    if (field[k*(n0*n1)+j*n0+i]<min) field[k*(n0*n1)+j*n0+i]=min;
    if (field[k*(n0*n1)+j*n0+i]>max) field[k*(n0*n1)+j*n0+i]=max;
      }
    }
  }
}

void read_2d_input_files(it, varname, field, n0, n1)
  int it,n0,n1;
  char *varname;
  double field[];
{    
  int i, j,k;
  double factor, offset,min,max;
  double tmp;
  
  min=-1.e20;
  max=1.e20;

  if (strcmp(varname,"LATENT")==0){
    factor = 5.;
    offset = 0.;
    min=-65;
    max=65.;
  }
  else if (strcmp(varname,"TSURF")==0){
    factor = 2.1;
    offset = -230.;
    max=320.;
  }
  else if (strcmp(varname,"SOIL_WET")==0){
    factor = 4.;
    offset = 0.;
    max=130.;
  }
  else if (strcmp(varname,"PSURF")==0){
    factor = 1.;
    offset = -9.4e2;
  }
  else if (strcmp(varname,"htov")==0){
    factor = .5e14;
    offset = 2.e13;
    max = 1.492e14;
    min = 1.46e14;
  }

  for (j=0;j<n0;j++){
    for (i=0;i<n1;i++) {
      tmp = ((double)j*16. + (double)(i)*4. + (double)it)*factor - offset;
      k= (n0-1-j)*n1+i;
      field[k] = tmp;
      if (field[k]<min) field[k]=min;
      if (field[k]>max) field[k]=max;
    }
  }
}
  

int main()
     /*
/*   Purpose:   To serve as a generic example of an application that */
/*       uses the "Climate Model Output Rewriter" (CMOR) */

/*    CMOR writes CF-compliant netCDF files. */
/*    Its use is strongly encouraged by the IPCC and is intended for use  */
/*       by those participating in many community-coordinated standard  */
/*       climate model experiments (e.g., AMIP, CMIP, CFMIP, PMIP, APE, */
/*       etc.) */

/*   Background information for this sample code: */

/*      Atmospheric standard output requested by IPCC are listed in  */
/*   tables available on the web.  Monthly mean output is found in */
/*   tables A1a and A1c.  This sample code processes only two 3-d  */
/*   variables listed in table A1c ("monthly mean atmosphere 3-D data"  */
/*   and only four 2-d variables listed in table A1a ("monthly mean  */
/*   atmosphere + land surface 2-D (latitude, longitude) data").  The  */
/*   extension to many more fields is trivial. */

/*      For this example, the user must fill in the sections of code that  */
/*   extract the 3-d and 2-d fields from his monthly mean "history"  */
/*   files (which usually contain many variables but only a single time  */
/*   slice).  The CMOR code will write each field in a separate file, but  */
/*   many monthly mean time-samples will be stored together.  These  */
/*   constraints partially determine the structure of the code. */


/*   Record of revisions: */

/*       Date        Programmer(s)           Description of change */
/*       ====        ==========              ===================== */
/*      10/22/03     Rusty Koder              Original code */
/*       1/28/04     Les R. Koder             Revised to be consistent */
/*                                            with evolving code design */
{

  /*   dimension parameters: */
  /* --------------------------------- */
#define   ntimes  2    /* number of time samples to process */
#define   lon  4       /* number of longitude grid cells   */
#define   lat  3       /* number of latitude grid cells */
#define   lev  19       /* number of standard pressure levels */
#define   n2d  4       /* number of IPCC Table A1a fields to be */                                      /*     output. */
#define n3d 3       /* number of IPCC Table A1c fields to  */
                     /*                                be output.   */

  /*   Tables associating the user's variables with IPCC standard output  */
  /*   variables.  The user may choose to make this association in a  */
  /*   different way (e.g., by defining values of pointers that allow him  */
  /*   to directly retrieve data from a data record containing many  */
  /*   different variables), but in some way the user will need to map his  */
  /*   model output onto the Tables specifying the MIP standard output. */

  /* ---------------------------------- */

  /* My variable names for IPCC Table A1c fields */
  char varin3d[n3d][6]={"CLOUD", "U", "T" };
  
  /* Units appropriate to my data */
  char units3d[n3d][6]={"%", "m s-1", "K"};
  
  /* Corresponding IPCC Table A1c entry (variable name)  */
  char entry3d[n3d][3]={"cl","ua","ta"};

  /* My variable names for IPCC Table A1a fields */
  char varin2d[n2d][9]={ "LATENT","TSURF","SOIL_WET","PSURF" };
  
  /* Units appropriate to my data */
  char units2d[n2d][7]={ "W m-2","K","kg m-2","Pa"};
  
  char positive2d[n2d][4]={"down"," ", " ", " "};
  
  /* Corresponding IPCC Table A1a entry (variable name)  */
  char entry2d[n2d][6]={"hfls", "tas","mrsos","ps"};

/*  uninitialized variables used in communicating with CMOR: */
/*  --------------------------------------------------------- */

  int error_flag;
  int znondim_id, zfactor_id;
  int var2d_ids[n2d];
  int var3d_ids[n3d];
  double data2d[lat*lon];
  double data3d[lev*lat*lon];
  double alats[lat];
  double alons[lon];
  int ilats[lat];
  int ilons[lon];
  double   plevs[lev];
  int   iplevs[lev];
  long   lplevs[lev];
  float   fplevs[lev];
  double Time[2];
  double  bnds_time[4];
  double bnds_lat[lat*2];
  double bnds_lon[lon*2];
  double zlevs[lev];
  double zlev_bnds[lev+1];

  double a_coeff[lev]={ 0.1, 0.2, 0.3, 0.22, 0.1 };
  double b_coeff[lev]={ 0.0, 0.1, 0.2, 0.5, 0.8 };
  float p0= 1.e5;
  double a_coeff_bnds[lev+1]={0.,.15, .25, .25, .16, 0.};
  double b_coeff_bnds[lev+1]={0.,.05, .15, .35, .65, 1.};
  int ilon, ilat, ipres, ilev, itim;
  double dtmp,dtmp2;

  /*  Other variables: */
  /*  --------------------- */
  
  int it, m, i,ierr , j;
  int myaxes[10];
  int myaxes2[10];
  int myvars[10];
  char id[CMOR_MAX_STRING];
  char units[CMOR_MAX_STRING];
  char interval[CMOR_MAX_STRING];
  char anames[25][CMOR_MAX_STRING];
  char type;
  char regions[5][23] = { "atlantic_arctic_ocean", "indian_pacific_ocean", "pacific_ocean", "global_ocean", "sf_bay"};
  double timestest[5];
  /* Externals funcs */
  int tables[5];
  char msg[555];
  double bt=0.;
  /* ================================ */
  /*  Execution begins here: */
  /* ================================ */
  
  /* Read coordinate information from model into arrays that will be passed  */
  /*   to CMOR. */
  /* Read latitude, longitude, and pressure coordinate values into  */
  /*   alats, alons, and plevs, respectively.  Also generate latitude and  */
  /*   longitude bounds, and store in bnds_lat and bnds_lon, respectively. */
  /*   Note that all variable names in this code can be freely chosen by */
  /*   the user. */
  
  /*   The user must write the subroutine that fills the coordinate arrays  */
  /*   and their bounds with actual data.  The following line is simply a */
  /*   a place-holder for the user's code, which should replace it. */
  
  /*  *** possible user-written call *** */
  

  
  m = CMOR_EXIT_ON_MAJOR;
  j = CMOR_REPLACE_4;
  i=1;
  it=0;
  printf("ok mode is:%i\n",m);
  ierr = cmor_setup(NULL,&j,NULL,&m,NULL,&i);//,"  ipcc_test.LOG  ");

  read_coords(&alats[0], &alons[0], &iplevs[0], &bnds_lat[0], &bnds_lon[0],lon,lat,lev);
  int tmpmo[12];
  printf("Test code: ok init cmor\n");
  char c1[CMOR_MAX_STRING];
  char c2[CMOR_MAX_STRING];
  strcpy(c1,"GICCM1(2002)\0");
  strcpy(c2,"Nat\0");


  printf("yep: %s, %s\n",c1,c2);
  ierr = cmor_dataset_json("Test/common_user_input.json");

  printf("Test code: ok load cmor table(s)\n");
  ierr = cmor_load_table("Tables/CMIP6_Omon.json",&tables[0]);
  ierr = cmor_load_table("Tables/CMIP6_Amon.json",&tables[1]);

  strcpy(id,"time");
  strcpy(units,"months since 1980");
  strcpy(interval,"1 month");

  read_time(0, &Time[0], &bnds_time[0]);
  read_time(1, &Time[1], &bnds_time[2]);
  ierr = cmor_axis(&myaxes[0],id,units,ntimes,&Time[0],'d',&bnds_time[0],2,interval);
  
  strcpy(id,"latitude");
  strcpy(units,"degrees_north");
  strcpy(interval,"");
  ierr = cmor_axis(&myaxes[1],id,units,lat,&alats,'d',&bnds_lat,2,interval);

  strcpy(id,"longitude");
  strcpy(units,"degrees_east");
  ierr = cmor_axis(&myaxes[2],id,units,lon,&alons,'d',&bnds_lon,2,interval);

  strcpy(id,"plev19");
  strcpy(units,"hPa");
  ierr = cmor_axis(&myaxes[3],id,units,lev,&iplevs,'i',NULL,0,interval);

  zlevs[0]=0.1;
  zlevs[1]= 0.3;
  zlevs[2]=0.5;
  zlevs[3]= 0.72;
  zlevs[4] =  0.9;

  zlev_bnds[0]=0.;
  zlev_bnds[1]=.2;
  zlev_bnds[2]=.42;
  zlev_bnds[3]=.62;
  zlev_bnds[4]=.8;
  zlev_bnds[5]=1.;
/*   p0 = 1.e5; */
/*   a_coeff = { 0.1, 0.2, 0.3, 0.22, 0.1 }; */
/*   b_coeff = { 0.0, 0.1, 0.2, 0.5, 0.8 }; */

/*   a_coeff_bnds={0.,.15, .25, .25, .16, 0.}; */
/*   b_coeff_bnds={0.,.05, .15, .35, .65, 1.}; */

  ierr = cmor_axis(  &myaxes[4],"standard_hybrid_sigma","1",5,&zlevs,'d',&zlev_bnds,1,interval);

  cmor_set_table(tables[0]);
  /* ok here we declare a "regions" axis */
  printf("Test code: defining axis region \n");
  ierr = cmor_axis(  &myaxes[5],"basin","",4,&regions[0],'c',NULL,23,interval);

  printf("Test code: Redefining time/lat from O table\n");

  strcpy(id,"time");
  strcpy(units,"months since 1980");
  strcpy(interval,"1 month");
  read_time(0, &Time[0], &bnds_time[0]);
  read_time(1, &Time[1], &bnds_time[2]);
  ierr = cmor_axis(&myaxes[7],id,units,ntimes,&Time[0],'d',&bnds_time[0],2,interval);

  strcpy(id,"latitude");
  strcpy(units,"degrees_north");
  strcpy(interval,"");
  ierr = cmor_axis(&myaxes[8],id,units,lat,&alats,'d',&bnds_lat,2,interval);

  cmor_set_table(tables[1]);

  dtmp = -999;
  dtmp2=1.e-4;
  myaxes2[0] = myaxes[0];
  myaxes2[1] = myaxes[3];
  myaxes2[2] = myaxes[1];
  myaxes2[3] = myaxes[2];

  printf("Test code: defining variables from table 1, %s\n",positive2d[0]);
  ierr = cmor_variable(&myvars[0],entry2d[0],units2d[0],3,myaxes,'d',&dtmp,&dtmp2,positive2d[0],varin2d[0],"no history","no future");
  ierr = cmor_variable(&myvars[1],entry3d[2],units3d[2],4,myaxes2,'d',NULL,&dtmp2,NULL,varin3d[2],"no history","no future");

  printf("Test code: definig tas\n");
  ierr = cmor_variable(&myvars[5],"tas","K",3,myaxes,'d',NULL,&dtmp2,NULL,"TS","no history","no future");

  myaxes2[1] = myaxes[4];
  ierr = cmor_variable(&myvars[2],entry3d[0],units3d[0],4,myaxes2,'d',NULL,&dtmp2,NULL,varin3d[0],"no history","no future");
  ierr = cmor_zfactor(&myvars[3],myaxes2[1],"p0","Pa",0,NULL,'f',&p0,NULL);
  ierr = cmor_zfactor(&myvars[3],myaxes2[1],"b","",1,&myaxes2[1],'d',&b_coeff,&b_coeff_bnds);
  ierr = cmor_zfactor(&myvars[3],myaxes2[1],"a","",1,&myaxes2[1],'d',&a_coeff,&a_coeff_bnds);
/*   printf("defining ap\n"); */
/*   for(i=0;i<5;i++) {a_coeff[i]*=1.e3;printf("sending acoef: %i, %lf\n",i,a_coeff[i]);} */
/*   for(i=0;i<6;i++) {a_coeff_bnds[i]*=1.e5;printf("sending acoef: %i, %lf\n",i,a_coeff_bnds[i]);} */
/*   ierr = cmor_zfactor(&myvars[3],myaxes2[1],"ap","hPa",1,&myaxes2[1],'d',&a_coeff,&a_coeff_bnds); */
  ierr = cmor_zfactor(&myvars[3],myaxes2[1],"ps","hPa",3,&myaxes[0],'d',NULL,NULL);

  /* ok here we decalre a variable for region axis testing */
  cmor_set_table(tables[0]);
  myaxes2[0] = myaxes[7]; /* time */
  myaxes2[1] = myaxes[5]; /* region */
  myaxes2[2] = myaxes[8]; /* latitudes */
  printf("Test code: ok we define hfogo positive: %s\n",positive2d[0]);
  ierr = cmor_variable(&myvars[4],"htovgyre","W",3,myaxes2,'d',NULL,&dtmp2,NULL,varin2d[0],"no history","no future");

  cmor_set_table(tables[1]);


  for (i=0;i<ntimes;i++) {
    printf("Test code: writing time: %i of %i\n",i+1,ntimes);
    
    printf("2d\n");
    read_2d_input_files(i, varin2d[0], &data2d,lat,lon);
    sprintf(id,"%i",i);
    ierr = cmor_write(myvars[0],&data2d,'d',1,NULL,NULL,NULL);

    printf("3d\n");
    read_3d_input_files(i, varin3d[2], &data3d,lev,lat,lon);
    ierr = cmor_write(myvars[1],&data3d,'d',1,NULL,NULL,NULL);
    printf("writing tas\n");
    read_2d_input_files(i, varin2d[1], &data2d,lat,lon);
    ierr = cmor_write(myvars[5],&data2d,'d',1,NULL,NULL,NULL);

    printf("3d zfactor\n");
    read_3d_input_files(i, varin3d[0], &data3d,5,lat,lon);
    ierr = cmor_write(myvars[2],&data3d,'d',1,NULL,NULL,NULL);

    printf("writing ps\n");
    read_2d_input_files(i, varin2d[3], &data2d,lat,lon);
    ierr = cmor_write(myvars[3],&data2d,'d',1,NULL,NULL,&myvars[2]);

    /* rereading hfls to fake hfogo */
    printf("2d region\n");
    read_2d_input_files(i, "htov", &data2d,lat,lon);
    ierr = cmor_write(myvars[4],&data2d,'d',1,NULL,NULL,NULL);
  }
  ierr = cmor_close_variable(myvars[0],NULL,NULL);
  ierr = cmor_close();
  return( 0 );
}

Tags: