// -*-C++-*-
// Purpose: CDL file to generate netCDF4 test file for known netCDF problems
// Isolating non-working and backwards incompatible CDL usage allows in_grp.cdl
// to parse bug-free with most modern netCDF libraries (i.e., v. 4.1.1+).
// Examples here break on netCDF versions indicated in comments
// Contents of this file should be migrated back to in_grp.cdl eventually

// Created: 20130429 based on in_grp.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/buggy.nc ~/nco/data/buggy.cdl
// scp ~/nco/data/buggy.cdl givre.ess.uci.edu:nco/data
// scp ~/nco/data/buggy.nc dust.ess.uci.edu:/var/www/html/nco
// scp dust.ess.uci.edu:/var/www/html/nco/buggy.nc ~/nco/data

netcdf buggy {

 dimensions:
  lat=2;
  lon=4;
  tm2=unlimited;
  tm3=unlimited;
  time=unlimited;

 variables:
  float att_var;
 att_var:byte_att = '\000','\001','\002','\177','\200','\201','\376','\377';
 att_var:char_att = "Sentence one.\nSentence two.\n";
 att_var:short_att = 37s;
 att_var:int_att = 73;
 att_var:float_att = 73.0f,72.0f,71.0f,70.010f,69.0010f,68.010000f,67.01000100f;
 att_var:double_att = 73.0,72.0,71.0,70.010,69.0010,68.010000,67.01000100;
 att_var:ubyte_att = 0ub, 1ub, 2ub, 127ub, 128ub, 254ub, 255ub, 0ub; // 20130712: ncgen 4.3.0 translates this to byte
 att_var:ubyte2_att = '\000','\001','\002','\177','\200','\201','\376','\377'; // 20130712: ncgen 4.3.0 translates this to byte
 att_var:ushort_att = 37us;
 att_var:uint_att = 73u; // 20170322: ncgen 4.4.1 converts u-suffixed numbers to uint64 type instead of uint32. Counter-intuitive. Regular uint=uint32 must be obtained by ul suffix. 
 att_var:uint_att2 = 73ul;
 att_var:int64_att = 9223372036854775807ll; // 20130712: ncgen 4.3.0 chokes on ll, LL suffix for int64 attributes, and translates l-suffixed numbers to NC_UINT64. Bug reported (netCDF #HEX-795132) and fixed in snapshot 20131117
 att_var:uint64_att = 18446744073709551615ull; // 20130712: ncgen 4.3.0 chokes on ull, ULL suffix for uint64 attributes, 20131120: XML treats unsigned as signed types, so toolsui produces errors when reading maximum uint64 values (though not when reading maximum ubyte, ushort, and uint values), 20170322: ncgen 4.4.1 works fine with ull
 att_var:string_att1 = "20130723: ncgen -k netCDF-4 version 4.0.x converts quoted string to NC_STRING not NC_CHAR. Incompatible with classic behavior.";
 att_var:string_att2 = "20130712: ncgen -k netCDF-4 version 4.2.x+ converts quoted string to NC_CHAR not NC_STRING. Backwards compatible with classic behavior.";
  string att_var:string_att3 = "20130723: Prefixing full attribute name with \"string\" causes CDL to produce NC_STRING.";
  string att_var:string_att4 = "20130723: Arrays of NC_STRING are simply separated by commas.","If there are commas within a string, well, then, be careful. Did we \"jump the shark\"?","This array comprises three sentences.";

 string string_var2;
 string_var2:long_name = "string-type variable with default XML separator";

 float nan_arr(lat);
 nan_arr:long_name = "Intended for array representation of IEEE NaN";
 nan_arr:note = "20120308 Apparently netCDF ncgen chokes on variable names of nan and NaN";
 nan_arr:note2 = "20120330 netCDF ncgen on AIX/bluefire chokes on variable/attribute values of nan";
 nan_arr:note3 = "20120625 netCDF ncgen on netCDF 4.1.1 on apparently chokes on variable/attribute values of nan";
 nan_arr:note4 = "If your NCO build fails because your version of netCDF does not support nan, then cd to the directory that contains the file nco/data/in.cdl and run the command in note5 first and then try to build again";
 nan_arr:note5 = "sed -e 's/nan;/1.0f;/' in.cdl > foo.cdl;ncgen -b -o in.nc foo.cdl";
 nan_arr:note6 = "It is too troublesome to distribute in.cdl with references to NaNs because users always build with old netCDF versions that do not support it. So just comment out nan's for now.";
 nan_arr:_FillValue = nanf;

 float nan_scl;
 nan_scl:long_name = "Intended for scalar representation of IEEE NaN";
 nan_scl:note = "20120308 Apparently netCDF ncgen chokes on variable names of nan and NaN";
 nan_scl:note2 = "20120330 netCDF ncgen on AIX/bluefire chokes on variable/attribute values of nan";
 nan_scl:note3 = "20120625 netCDF ncgen on netCDF 4.1.1 on apparently chokes on variable/attribute values of nan";
 nan_scl:note6 = "It is too troublesome to distribute in.cdl with references to NaNs because users always build with old netCDF versions that do not support it. So just comment out nan's for now.";
 nan_scl:_FillValue = nanf;

 float nan_val;
 nan_val:long_name = "Intended for scalar representation of IEEE NaN without missing values";
 nan_val:note = "20120308 Apparently netCDF ncgen chokes on variable names of nan and NaN";
 nan_val:note2 = "20120330 netCDF ncgen on AIX/bluefire chokes on variable/attribute values of nan";
 nan_val:note3 = "20120625 netCDF ncgen on netCDF 4.1.1 on apparently chokes on variable/attribute values of nan";
 nan_val:note6 = "It is too troublesome to distribute in.cdl with references to NaNs because users always build with old netCDF versions that do not support it. So just comment out nan's for now.";
 nan_val:note7 = "20170505 For testing without missing values"; 

 double nan_val_dbl;
 nan_val_dbl:long_name = "Intended for scalar representation of IEEE NaN without missing values";
 nan_val_dbl:note = "20120308 Apparently netCDF ncgen chokes on variable names of nan and NaN";
 nan_val_dbl:note2 = "20120330 netCDF ncgen on AIX/bluefire chokes on variable/attribute values of nan";
 nan_val_dbl:note3 = "20120625 netCDF ncgen on netCDF 4.1.1 on apparently chokes on variable/attribute values of nan";
 nan_val_dbl:note6 = "It is too troublesome to distribute in.cdl with references to NaNs because users always build with old netCDF versions that do not support it. So just comment out nan's for now.";
 nan_val_dbl:note7 = "20170505 For testing without missing values"; 

 int tm3_lat_flt(tm3,lat);
 tm3_lat_flt:purpose = "record variable compressed with netCDF 4.6.0 _Filter attribute"; 
 tm3_lat_flt:bug = "ncgen until 4.6.0 20180125 fails to parse this. Furthermore, ncgen will only parse this correctly if the bzip2 filter is installed as per instructions below. Variables compressed with _Filters must be chunked, so we make this a record variable. More instructions at https://www.unidata.ucar.edu/software/netcdf/docs/md__Users_wfisher_Desktop_gitprojects_netcdf-c_docs_filters.html";
 tm3_lat_flt:usage="export HDF5_PLUGIN_PATH=/usr/local/lib";
 tm3_lat_flt:_Filter = "307,9";
 tm3_lat_flt:_Storage = "chunked";
 tm3_lat_flt:_ChunkSizes = 3,2;
 
 int lat_time(lat,time);
 lat_time:purpose = "record variable where record dimension is not first dimension"; 
 lat_time:bug = "ncgen until 4.3.3-rc2 20140922 fails to parse this because of Jira NCF-315. Some variables with non-leading record dimensions (like lat_tm2, lat_tm3) did work before today in \"standalone\" files like buggy.cdl, but lat_time did not.";
  
  float lat_tm2(lat,tm2);
  float lat_tm3(lat,tm3);
  float tm2_lat(tm2,lat);
  float tm3_lat(tm3,lat);

  float tm2_tm3(tm2,tm3);
  tm2_tm3:purpose = "a variable containing mutiple record dimensions";
  tm2_tm3:note = "ncdump prior to snapshot 20121116 and/or release netCDF 4.3 fails to print braces required to dis-ambiguate data sizes of mutiple record dimensions";
  tm2_tm3:note2 = "ncgen from netCDF after ~201207 fails when ambiguous syntax (without braces) is used. Catch 22. Therefore remove tm2_tm3 from test file for now.";

  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";
    
  uint64 uint64_var;
 uint64_var:long_name = "uint64-type variable";
 uint64_var:purpose="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)";

 data:
  att_var=10.0;

  // 20130127: Braces are required to disambiguate correct record dimension sizes, but brace syntax was not supported by ncgen until netCDF snapshots ~201211, i.e., post netCDF 4.2.1.1. Uggh.
  lat_tm2={1,2},{3,4}; // NB: Unlimited dimensions (other than the first) must be enclosed in braces
  lat_tm3={1,2,3},{4,5,6}; // NB: Unlimited dimensions (other than the first) must be enclosed in braces
  tm2_lat=1,2,3,4; // NB: Braces forbidden when unlimited dimension is first. sizeof(tm2)=sizeof(whole)/$lat
  tm3_lat=1,2,3,4,5,6; // NB: Braces forbidden when unlimited dimension is first. sizeof(tm2)=sizeof(whole)/$lat

  tm3_lat_flt=1,2,3,4,5,6;

  tm2_tm3={1.,2.,3.},{4.,5.,6.};

  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.";

  lat_time={1,2,3,4,5,6,7,8,9,10},{11,12,13,14,15,16,17,18,19,20};

  nan_arr=0,nanf;
  nan_scl=nanf;
  nan_val=nanf;
  nan_val_dbl=nan;

   // 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

   uint64_var=18446744073709551615; // 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)

 group: \1g { 
    // Non-bug netCDF #TLO-836022 reported 20131118: ncgen fails on group names that begin with numeric characters. Response:
    // "An identifier with a leading digit is allowed, but the leading digit must be escaped. So in your example change 1g -> \1g"
 :att=1;
 } // 1g

 group: g1 {
  dimensions:
    lat=2;
    lon=4;
  variables:
    double lat(lat);
    double lon(lon);
  data:
    lat=-45,45;
    lon=0,90,180,270;
  } // /g1

 group: g2 {
  dimensions:
    lat=3;
    lon=3;
  variables:
    double lat(lat);
    double lon(lon);
  data:
    lat=-60,0,60;
    lon=0,120,240;
  } // /g2

 group: g3 {
    dimensions:
    lat=1;
    lon=1;
  variables:
    float latlon(lat,lon);
    // 20131120: Test whether out-of-scope dimensions can be referenced by full paths
    // Result: They cannot
    // float lat2lon4(/g1/lat,/g1/lon);
    //    float lat3lon3(/g2/lat,/g2/lon);
    //    float lat2lon3(/g1/lat,/g2/lon);
  data:
    latlon=1;
    // lat2lon4=1,2,3,4,5,6,7,8;
    // lat3lon3=1,2,3,4,5,6,7,8,9;
    //    lat2lon3=1,2,3,4,5,6;
  } // /g3

 group: g4 {
   variables:
     float one;
   data:
     one=1;
   } // /g4

 group: g5 { // Level 1
    // Purpose: Test hidden attributes
    // NB: Hidden attributes not supported by ncgen at least through netCDF 4.1.1 (201111)
    // Having this group in in_grp.cdl breaks building of in_grp.nc with netCDF 4.1.1- (201111)
    // This breaks many NCO regression tests
    // ncks -C -v var_cmp.? -m ~/nco/data/in_grp.nc
  variables:

    int one(lat);
  one:_DeflateLevel=1;
  one:_Shuffle=1;
  one:_Fletcher32=1;
  one:_NOFILL=1;

    int two(lat);

    int three(lat);
  three:_ChunkSizes=1;
  three:_Endianness="big";

    int four(lat);
  four:_ChunkSizes=2;

    int var_cmp(lat);
  var_cmp:purpose="Variable with compression. Original _DeflateLevel = 1";
  var_cmp:_DeflateLevel = 1;

    int var_cmp_0(lat);
  var_cmp_0:purpose="Variable with compression. Original _DeflateLevel = 0";
  var_cmp_0:_DeflateLevel = 0;
    
    int var_cmp_1(lat);
  var_cmp_1:purpose="Variable with compression. Original _DeflateLevel = 1";
  var_cmp_1:_DeflateLevel = 1;

    int var_cmp_9(lat);
  var_cmp_9:purpose="Variable with compression. Original _DeflateLevel = 9";
  var_cmp_9:_DeflateLevel = 9;

  data:
    one=1,1;
    two=2,2;
    three=3,3;
    four=4,4;
    var_cmp=1,1;
    var_cmp_0=1,1;
    var_cmp_1=1,1;
    var_cmp_9=1,1;
  } // end g5

 group: g12 {
    // Purpose: Test netCDF4 vlen type
    // 20130208: ncgen from netCDF 4.2.1- broken for vlen types
    // Probably broken on all snapshots until ~201211 because brace-handling broken
  types:
    int(*) vlen_t;
  variables:
    vlen_t vlen_var;
  data:
    vlen_var={17,18,19};
  } // end g12

 group: g13 { // Level 1
    // Purpose: Test netCDF4 opaque type
  types:
    opaque(11) opaque_t;
  } // end g13

 group: g14 { // Level 1
    // Purpose: Test netCDF4 enum type
  types:
    ubyte enum enum_t {Clear=0,Cumulonimbus=1,Stratus=2};
  variables:
    // 20130429: ncgen or ncdump from netCDF 4.1.1- broken for enum types
    // This causes regression tests to fail with Ubuntu 12.04-
    // 20220101: Recent ncgen and ncdump from netCDF 4.8.1 work with enum types
    enum_t cloud_flg(lon);
  data:
    cloud_flg=Stratus,Stratus,Cumulonimbus;
  } // end g14

 group: g15 { // Level 1
    // Purpose: Test netCDF4 compound type
   types:
     ubyte enum enum2_t {Clear=0,Cumulonimbus=1,Stratus=2};
     //compound cmpd_t {vlen_t f1;enum2_t f2;};
   variables:
     //cmpd_t compound_var;
     //data:
     //compound_var={{3,4,5},Stratus};
  } // end g15

  //g17 
  //ncks -O -v ts -d time,0,1 -d Latitude,40.0 -d Longitude,-105.0 http://hydro1.sci.gsfc.nasa.gov/opendap/hyrax/ncml/LPRM_AMSRE_D_SOILM3_timeSeries.ncml ~/amsre.nc
  group: g17 { 
    dimensions:
    time3 = 2; 
    maxStrlen64 = 64 ;    
    variables:
    char time3(time3, maxStrlen64) ;
     time3:_CoordinateAxisType = "Time" ;
    data:   
    time3 = "2002-06-19T00:00:00Z","2002-06-20T00:00:00Z" ;
 } // end  g17

} // end root group
