// -*-C++-*-
// Purpose: CDL file to generate netCDF4 test file for groups
// Created: 20110801 based on in.cdl

// Usage:
// NB: ncgen arguments depend on version:
// "-k netCDF-4" for netCDF >= 3.6.3, "-k hdf5" for netCDF < 3.6.3
// "-k netCDF-4 classic model" for netCDF >= 3.6.3, "-k hdf5-nc3" for netCDF < 3.6.3
// ncgen -k netCDF-4 -b -o ~/nco/data/in_grp.nc ~/nco/data/in_grp.cdl
// scp ~/nco/data/in_grp.cdl givre.ess.uci.edu:nco/data
// scp ~/nco/data/in_grp.nc dust.ess.uci.edu:/var/www/html/nco
// scp dust.ess.uci.edu:/var/www/html/nco/in_grp.nc ~/nco/data

// URL: 
// http://dust.ess.uci.edu/nco/in_grp.nc
// http://thredds-test.ucar.edu/thredds/dodsC/testdods/in_grp.nc

// CDL Data constants:
// byte: 'a'
// char: "a"
// short: 1s
// int: 1 (no decimal point)
// float: 1.f (decimal point is required, f is required to distinguish from double)
// double: 1.0, 1.d, 1.0e-20 (decimal point is required, d is not required)
// CDL complex types:
// man ncgen describes all
// roulee:/data/zender/tmp/netcdf-4.2.1/nc_test/ref_tst_diskless2.cdl

// NCL usage:
// id_in=addfile("/home/zender/nco/data/in_grp.nc","r")
// print(id_in)
// list_filevars(id_in)
// ncks --get_file_info  ~/nco/data/in_grp.nc

// NB: Must be tested with 
// ncks --lbr
// Linked to netCDF library version 4.1.1, compiled Nov  7 2011 11:35:16

netcdf in_grp {

 dimensions:
  lat=2;
  lev=3;
  lon=4;
  time=unlimited; 
  vrt_nbr=2;
  gds_crd=8;
  
 variables:
  double time(time);
  
  float lat(lat);
  lat:units = "degrees_north";
  
  float lon(lon);
  lon:units = "degrees_east";
  
  float lev(lev);
  lev:units = "hybrid_sigma_pressure";
  lev:bounds = "ilev";
   
  float ilev(lev,vrt_nbr);
  ilev:purpose = "Cell boundaries for lev coordinate"; 
  
  float area(lat);
  area:units = "meter2";

  float one;
  
  float scl;
  
  integer unique;
  unique:purpose = "the only variable of this name in this file, to test smallest possible access requests"; 
  
  float lat_lon(lat,lon);
  
  //global attributes
  :Conventions = "CF-1.0";
  :history = "History global attribute.\n";
  :julian_day = 200000.04;
  :RCS_Header = "$Header: /cvsroot/nco/nco/data/in_grp.cdl,v 1.120 2014/02/20 16:43:22 zender Exp $";
  
 data:
  area=10.,10.;
  lat=-90,90;
  lat_lon=1.,2.,3.,4.,5.,6.,7.,8;
  ilev=0,300,300,750,750,1013.25;
  lev=100,500,1000;
  lon=0,90,180,270;
  one=1.;
  scl=1.0;
  time=1.,2.,3.,4.,5.,6.,7.,8.,9.,10.;
  unique=73;
  //
  //g1
  //
 group: g1 { 
  :history = "History group attribute.\n";
  variables:
  
    //coordinate variable (/lon)
    float lon(lon);
    lon:units = "degrees_east";
    float scl;
    int g1v1;
    int v1;
  data:
    lon=0,90,180,270;
    scl=1.1;
    g1v1=1;
    v1=1;  
  group: g1g1 { 
    variables:
      float scl;
      int v1;
    data:
      scl=1.11;
      v1=11;
    } // end g1g1
  group: g1\:g2 {
      :purpose = "group name with semi-special character, a colon (makes CDL-parsing hard)";
      :csznote = "As of 20131006, ncks skips groups whose names contain special characters. ncdump handles them fine. e.g.,\nncgen -k netCDF-4 -b -o ~/nco/data/in_grp.nc ~/nco/data/in_grp.cdl\nncks --cdl -m -g g1 ~/nco/data/in_grp.nc | m\nncdump -h -g g1 ~/nco/data/in_grp.nc | m\n";
    } // end g1:g2
  } // end g1
  
  //
  //g2
  //
 group: g2 { 
  variables:
    //coordinate variable (dimension at root)
    double time(time);
    float lon(lon);
    float scl;
  data:
    time=1.,2.,3.,4.,5.,6.,7.,8.,9.,10.;
    lon=0,90,180,270;
    scl=1.2;
  } // end g2
  
  //
  //g4
  //
 group: g4 { 
  variables:
    int one_dmn_rec_var(time);
	one_dmn_rec_var:long_name = "one dimensional record variable";
	one_dmn_rec_var:units = "kelvin";
  data:
    one_dmn_rec_var=1,2,3,4,5,6,7,8,9,10;  
  } // end g4
  
 //
 //g5
 //
 group: g5 { 
  dimensions:
  time51=unlimited;  //test --rec_apn with more than 1 record in group (NB: make first record, time51, differ from variable size (time52) ) 
  time52=unlimited;
  variables:
    int one_dmn_rec_var(time52);
	one_dmn_rec_var:long_name = "one dimensional record variable";
	one_dmn_rec_var:units = "kelvin";
	double time51(time51);
	double time52(time52);
  data:
    one_dmn_rec_var=1,2,3,4,5,6,7,8,9,10; 
	time51=1.,2.;
    time52=1.,2.,3.,4.,5.,6.,7.,8.,9.,10.;	
  } // end g5
  
  //
  //g6
  //
 group: g6 { // Level 1
  variables:
    float area(lat);
    float area1(lat);
  data:
    area=20.,30.;
    area1=21.,31.;
  group: g6g1 { // Level 2
    variables:
      float area(lat);
    data:
      area=40.,50.;
    } //end g6g1
  } // end g6
  
  //
  //g7
  //
 group: g7 { 
  variables:
  
    //coordinate variable (/g7/gds_crd)
    float gds_crd(gds_crd);
    gds_crd:long_name = "Geodesic coordinate";
    gds_crd:units = "degree";
    gds_crd:purpose = "enumerated coordinate like those that might define points in a geodesic grid";
    gds_crd:coordinates = "lat_gds lon_gds";
  
    double lat_gds(gds_crd);
    lat_gds:units="degree";
    lat_gds:long_name = "Latitude";  
    lat_gds:standard_name = "latitude";
    lat_gds:units="degree";
    lat_gds:purpose = "1-D latitude coordinate referred to by geodesic grid variables";
    
    double lon_gds(gds_crd);
    lon_gds:long_name = "Longitude";
    lon_gds:standard_name = "longitude";
    lon_gds:units="degree";
    lon_gds:purpose = "1-D longitude coordinate referred to by geodesic grid variables";
    
  data:
    gds_crd=0,1,2,3,4,5,6,7;
    lat_gds=-90, -30,  -30,    0,   0, 30,  30,  90;
    lon_gds=  0,   0,  180,    0, 180,  0, 180,   0;
    
     group: g7g1 { // Level 2  
     variables:       
     float gds_var(gds_crd);
     gds_var:units = "meter";
     gds_var:coordinates = "lat_gds lon_gds";
     data:
     gds_var=273.1,273.2,273.3,273.4,273.5,273.6,273.7,273.8;  
      } //g7g1
  } // end g7
 
  //
  //g8
  //
 group: g8 { // Level 1
  group: g8g1 { // Level 2
    group: g8g1g1 { // Level 3
      group: g8g1g1g1 { // Level 4
	  :mtd_grp = "Group metadata from g8g1g1g1, a leaf-group with no variables, to test whether metadata-only leaf groups are copied and/or printed";
	  :answer = "Twerking";
	} // end g8g1g1g1
      } // end g8g1g1
    } // end g8g1
  } // end g8

  //
  //g9
  //
 group: g9 { // Level 1
  group: g9g1 { // Level 2
    variables:
      int v6;
    data:
      v6=63;
    group: g9g1g1 { // Level 3
      group: g9g1g1g1 { // Level 4
	  :mtd_grp = "Group metadata from g9g1g1g1, a group with no variables, to test whether group metadata are copied to ancestor groups of extracted variables";
	group: g9g1g1g1g1 { // Level 5
	  group: g9g1g1g1g1g1 { // Level 6
	    group: g9g1g1g1g1g1g1 { // Level 7
	      variables:
		int v7;
	      data:
		v7=73;
	      } // end g9g1g1g1g1g1g1
	    } // end g9g1g1g1g1g1
	  } // end g9g1g1g1g1
	} // end g9g1g1g1
      } // end g9g1g1
    } // end g9g1
  } // end g9

 group: g10 { // Level 1
  variables:
    float two_dmn_rec_var(time,lev);
    float three_dmn_rec_var(time,lat,lon);
	three_dmn_rec_var:units = "watt meter-2";
  data:
    two_dmn_rec_var=1.,2.0,3.,
      1.,2.1,3.,
      1.,2.2,3.,
      1.,2.3,3.,
      1.,2.4,3.,
      1.,2.5,3.,
      1.,2.6,3.,
      1.,2.7,3.,
      1.,2.8,3.,
      1.,2.9,3.;
    three_dmn_rec_var= 	 1, 2, 3, 4, 5, 6, 7, 8,
      9,10,11,12,13,14,15,16,
      17,18,19,20,21,22,23,24,
      25,26,27,28,29,30,31,32,
      33,34,35,36,37,38,39,40,
      41,42,43,44,45,46,47,48,
      49,50,51,52,53,54,55,56,
      57,58,59,60,61,62,63,64,
      65,66,67,68,69,70,71,72,
      73,74,75,76,77,78,79,80;
  } // end g10

 group: g11 { // Level 1
    // Purpose: Test all netCDF3 and netCDF4 atomic types
  variables:
    // netCDF3 atomic types
    byte byte_var;
  byte_var:long_name = "byte-type variable";
    
    char char_var;
  char_var:long_name = "char-type variable";
    
    char char_var_arr(time);
  char_var_arr:long_name = "char-type variable array";
    
    int int_var;
  int_var:long_name = "int-type variable";
    
    short short_var;
  short_var:long_name = "short-type variable";

    long long_var;
  long_var:long_name = "long-type variable";
  long_var:purpose = "Variable of CDL type=long, which is deprecated for int. Included to test back-compatibility";

    double double_var;
  double_var:long_name = "double-type variable";

    float float_var;
  float_var:long_name = "float-type variable";

    // netCDF4-only atomic types
    int64 int64_var;
  int64_var:long_name = "int64-type variable";
    
    string string_var;
  string_var:long_name = "string-type variable";
    
    // string string_var2;
    // string_var2:long_name = "string-type variable with default XML separator";

    string string_arr(lat);
  string_arr:long_name = "string-type array variable";

    string string_rec_arr(time);
  string_rec_arr:long_name = "string-type record array variable";

    ubyte ubyte_var;
  ubyte_var:long_name = "ubyte-type variable";
    
    uint uint_var;
  uint_var:long_name = "uint-type variable";
  uint_var:_FillValue = 73u;
  uint_var:purpose = "_FillValue attribute tests whether NcML parser inadvertently creates two _FillValues for unsigned types";
    
    uint uint_arr(lat);
  uint_arr:long_name = "uint-type array variable";
    
    uint64 uint64_var;
  uint64_var:long_name = "uint64-type variable";
    
    ushort ushort_var;
  ushort_var:long_name = "ushort-type variable";
  data:
    // netCDF3 atomic types
    byte_var='z';
    char_var="z";
    char_var_arr="two words";
    double_var=10.;
    float_var=10.;
    short_var=10;
    int_var=10;
    long_var=10;
    // netCDF4-only atomic types
    int64_var=9223372036854775807; // LLONG_MAX = 9223372036854775807, NC_FILL_INT64 is -9223372036854775806LL
    string_var="If you prick us, do we not bleed? If you tickle us, do we not laugh? If you poison us, do we not die? And if you wrong us, shall we not revenge?";
    //  string_var2="20131121: This NC_STRING contains NCO's default XML string separator, *. And it contains multiple sequential copies of that separator, ***. Be sure ncks automatically switches to a different separator, aka the backup separator, the string obtained by removing the two spaces from this:\"* | *\". As of 20131121, ncks handles this correctly, yet toolsui breaks when trying to input the ncks-generated NcML. Appears to be a toolsui bug.";
    string_arr="Stanza 1","Stanza 2";
    string_rec_arr="One little ","two little ","three little indians, ","four little ","five little ","six little indians, ","seven little ","eight little ","nine little indians, ","ten little indian boys.";
    ubyte_var='z'; // UCHAR_MAX = 255, NC_FILL_UBYTE = 255
    // 20130208: netCDF 4.2.1.1- fail as nc_get_var1_uint() returns -60 = NetCDF: Numeric conversion not representable on (valid) input values exceeding INT_MAX=2147483647. This was bug netCDF #PUX-602809 fixed in daily snapshot 20130210.
    // uint_var=4294967295; // UINT_MAX = 4294967295, NC_FILL_UINT is 4294967295U
    uint_var=0; // UINT_MAX = 4294967295, NC_FILL_UINT is 4294967295U
    uint_arr=4294967295,4294967295; // UINT_MAX = 4294967295, NC_FILL_UINT is 4294967295U
    //    uint64_var=18446744073709551615; // ULLONG_MAX = 18446744073709551615, NC_FILL_UINT is 18446744073709551614ULL, 20131120: XML treats unsigned as signed types, so toolsui produces errors when reading maximum uint64 values (though not when reading maxium ubyte, ushort, and uint values)
    uint64_var = 0ul; // 20130712: ncgen 4.3.0 chokes on ull, ULL suffix for uint64 attributes, 
    ushort_var=65535; // USHRT_MAX = 65535, NC_FILL_USHORT = 65535
 } // end g11
   
 group: g12 { // Level 1
    // Purpose: Test special characters in names
    // Most special characters need backslash protection
  : comma_in_name\, = "foo";
  : lt_in_name\< = "foo";
  : gt_in_name\> = "foo";
  : hash_in_name\# = "foo";
  : xclaim_in_name\! = "foo";
  : dollar_in_name\$ = "foo";
  : ampersand_in_name\& = "foo";
  : equals_in_name\= = "foo";
  : semicolon_in_name\; = "foo";
  : colon_in_name\: = "foo";
  : lbrace_in_name\{ = "foo";
  : rbrace_in_name\} = "foo";
  : lparen_in_name\( = "foo";
  : rparen_in_name\) = "foo";
  : lbracket_in_name\[ = "foo";
  : rbracket_in_name\] = "foo";
  : plus_in_name+ = "foo";
    //  : period_in_name. = "foo"; // Likely to cause DAP server error
  : hyphen_in_name- = "foo";
  : at_in_name@ = "foo";
 } // end g12

} // end root group
