// -*-C++-*-
// Purpose: CDL file to generate netCDF4 test file for groups

// 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_3.nc ~/nco/data/in_grp_3.cdl

// 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_3.nc","r")
// print(id_in)
// list_filevars(id_in)
// ncks --get_file_info  ~/nco/data/in_grp_3.nc

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

netcdf in_grp_3 {

  :Conventions = "CF-1.0";

  //
  //g3
  //
  // Test case generates duplicated dimension IDs in netCDF file
  // rlev dimension from g3 must be commented when using netCDF earlier than 4.3.0
  //
  //      ncks -O  -v two_dmn_rec_var in_grp.nc out.nc
  //
  //      nco_cpy_var_dfn() defines new dimesions for the file, as
  //
  //      ncks: INFO nco_cpy_var_dfn() defining dimensions
  //      ID=0 index [0]:</time> 
  //      ID=1 index [1]:</lev> 
  //      ID=2 index [0]:</g8/lev> 
  //      ID=3 index [1]:</g8/vrt_nbr> 
  //      ID=4 index [1]:</vrt_nbr> 
  //
  //
 group: g3 {
  dimensions:
    rlev=3;
  variables:
    :g3_group_attribute = "g3_group_attribute";
    
    //coordinate variable (/g3/rlev)
    float rlev(rlev);
    rlev:purpose = "Monotonically decreasing coordinate pressure";

    float rz(rlev);  
    float scl;
  data:
    rz=0,5000,17000;
    scl=1.3;
    rlev=1000.,500.,100.;
    
  group: g3g1 {
    variables:
      float prs(rlev);
      prs:long_name="reverse pressure";
    data:
      prs=1.0,10.0,100.0;
    } // end g3g1
  } // end g3
  
  //
  //g5
  //
 group: g5 { // Level 1
  dimensions:
    rlev=3;
  variables:
  
    //coordinate variable (/g5/rlev)
    float rlev(rlev);
  data:
    rlev=10.,5.,1.;
  group: g5g1 { // Level 2
    variables:
      float rz(rlev);
    data:
      rz=1,2,3;
    } //end g5g1 
  } // end g5  
  
  
  //
  //g8 test ncwa in groups 
  //
 group: g8 { 
  dimensions:
    lon=2,lev=3,vrt_nbr=2;
  variables:
  
    //coordinate variable (/g8/lon)
    float lon(lon);
    
    //coordinate variable (/g8/lev)
    float lev(lev); 
    lev:bounds = "lev_bnd";
    
    //coordinate variable (/g8/vrt_nbr)
    float vrt_nbr(vrt_nbr);
    
    float lev_bnd(lev,vrt_nbr);
	float lev_wgt(lev);
  data:
    lon=-180,0; 
    lev=100,500,1000;
    lev_bnd=0,300,300,750,750,1013.25;
    vrt_nbr=1,2;
    lev_wgt=9,2,1;
  } // end g8
  
 
  //
  //g16 
  //
  // Test variables and dimensions in and out of scope
  // Use case of variable in scope of dimension:
  // dimension /lon 
  // variable /g1/lon(lon)
  // Use case of variable NOT in scope of dimension:
  // variable /lon
  // dimension /g1/lon
  //
  // Test dimensions with no associated coordinate variable
  //
  group: g16 { 
    dimensions:
    lat=2;
    lon1=4;  //dimension that has a coordinate variable down in scope at /g16/g16g1/lon1(lon1)
    lon2=4;  //dimension that does NOT have a coordinate variable anywhere 
    lon3=4;  //dimension that has a coordinate "out of scope" (with group depth greater than the variable that uses the coordinate, g16g3g3)
    lon4=2;  //dimension that has several intermediate "in scope" coordinates
    variables:
    float lat1(lat);
    float lon2_var(lon2); //variable with no associated coordinate variable
    data:
    lat1=0.,1.;
    lon2_var=0.,1.,2.,3.; 
    
    group: g16g1 { 
     dimensions:
     lat1=2; //dimension that has a variable /lat1 down in *illegal* scope 
     variables:
     // MSA test -v lon1_var -d lon1,3.0, result is 3.
     float lon1(lon1);  //coordinate variable /g16/g16g1/lon1 that has dimension (/g16/lon1) in scope
     float lon1_var(lon1); // variable /g16/g16g1/lon1_var that has dimension (/g16/lon1) in scope *and* coordinate (/g16/g16g1/lon1) in scope
     data:
     lon1=0.,1.,2.,3.;
     lon1_var=0.,1.,2.,3.;  
      } // end g16g1 

    group: g16g2 { 
     dimensions:
     variables:
     //coordinate variable (/g16/lon1)
     float lon1(lon1); // MSA test -v lon1_var -d lon1,3.0, result is 0.,1.,2.,3.
     float lon1_var(lon1); //
     data:
     lon1=3.,4.,5.,6.;
     lon1_var=0.,1.,2.,3.;  
    } // end g16g2 
    
    group: g16g3 { 
     variables:
     float lon3_var(lon3); 
     data:
     lon3_var=0.,1.,2.,3.;  
        group: g16g3g1 { 
           variables:
            //coordinate "out of scope" (with group depth greater than the variable that uses the coordinate, in g16g3)
            float lon3(lon3);
            data:
            lon3=7.,8.,9.,10.;
        } // end g16g3g1
    } // end g16g3
    
    group: g16g4 { 
     variables:
     //intermediate "in scope " coordinate
     float lon4(lon4);
     data:
     lon4=1.,2.;     
     
      group: g16g4g1 { 
      variables:
      //intermediate "in scope " coordinate
      float lon4(lon4);
      data:
      lon4=3.,4.; 
      
        group: g16g4g1g1 { 
        variables:
        //variable that uses one of the intermediate "in scope " coordinate
        float lon4_var(lon4);
        data:
        lon4_var=0.,1.; 
       } // end g16g4g1g1
     } // end g16g4g1
    } // end g16g4
    
  } // end g16
  
  //
  //g18
  //
  group: g18 { 
  
    :Conventions = "CF-1.0";
  
    dimensions:
    time=unlimited; // NB: no coordinate for this dimension  
    gds_crd=8;
	
    variables:
    double lat_gds_1(gds_crd);
    lat_gds_1:long_name = "Latitude";  
    lat_gds_1:standard_name = "latitude";
    lat_gds_1:units="degree";
    lat_gds_1:purpose = "1-D latitude coordinate referred to by geodesic grid variables";

    double lon_gds_1(gds_crd);
    lon_gds_1:long_name = "Longitude";
    lon_gds_1:standard_name = "longitude";
    lon_gds_1:units="degree";
    lon_gds_1:purpose = "1-D longitude coordinate referred to by geodesic grid variables";
    
    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_1 lon_gds_1";
    
    float gds_3dvar(time,gds_crd);
    gds_3dvar:long_name = "Geodesic variable";
    gds_3dvar:units = "meter";
    gds_3dvar:coordinates = "lat_gds_1 lon_gds_1";
    gds_3dvar:purpose = "Test auxiliary coordinates like those that define geodesic grids";
    
    data:
    gds_crd=0,1,2,3,4,5,6,7;
	gds_3dvar=273.1,273.2,273.3,273.4,273.5,273.6,273.7,273.8,
	          274.1,274.2,274.3,274.4,274.5,274.6,274.7,274.8,
	          275.1,275.2,275.3,275.4,275.5,274.5,275.7,275.8,
	          276.1,276.2,276.3,276.4,276.5,276.5,276.7,276.8,
	          277.1,277.2,277.3,277.4,277.5,277.5,277.7,277.8,
	          278.1,278.2,278.3,278.4,278.5,278.6,278.7,278.8,
	          279.1,279.2,279.3,279.4,279.5,279.9,279.7,279.8,
	          280.1,280.2,280.3,280.4,280.5,280.9,280.7,280.8,
	          281.1,281.2,281.3,281.4,281.5,281.9,281.7,281.8,
	          282.1,282.2,282.3,282.4,282.5,282.9,282.7,282.8;
    lat_gds_1=-90, -30,  -30,    0,   0, 30,  30,  90;
    lon_gds_1=  0,   0,  180,    0, 180,  0, 180,   0;
	
		 group: g18g1 {  //test -X with "lat_gds lon_gds" in scope
		 
			:Conventions = "CF-1.0";
			
			variables:
			float gds_3dvar(time,gds_crd);
			gds_3dvar:long_name = "Geodesic variable";
			gds_3dvar:units = "meter";
			gds_3dvar:coordinates = "lat_gds_1 lon_gds_1";
			gds_3dvar:purpose = "Test auxiliary coordinates like those that define geodesic grids";
    
			data:
			gds_3dvar=273.1,273.2,273.3,273.4,273.5,273.6,273.7,273.8,
	          274.1,274.2,274.3,274.4,274.5,274.6,274.7,274.8,
	          275.1,275.2,275.3,275.4,275.5,274.5,275.7,275.8,
	          276.1,276.2,276.3,276.4,276.5,276.5,276.7,276.8,
	          277.1,277.2,277.3,277.4,277.5,277.5,277.7,277.8,
	          278.1,278.2,278.3,278.4,278.5,278.6,278.7,278.8,
	          279.1,279.2,279.3,279.4,279.5,279.9,279.7,279.8,
	          280.1,280.2,280.3,280.4,280.5,280.9,280.7,280.8,
	          281.1,281.2,281.3,281.4,281.5,281.9,281.7,281.8,
	          282.1,282.2,282.3,282.4,282.5,282.9,282.7,282.8;
			  
			group: g18g2 {  	  
				variables:
				double lat_gds_2(gds_crd);
				lat_gds_2:long_name = "Latitude";  
				lat_gds_2:standard_name = "latitude";
				lat_gds_2:units="degree";
				lat_gds_2:purpose = "1-D latitude coordinate referred to by geodesic grid variables";

				double lon_gds_2(gds_crd);
				lon_gds_2:long_name = "Longitude";
				lon_gds_2:standard_name = "longitude";
				lon_gds_2:units="degree";
				lon_gds_2:purpose = "1-D longitude coordinate referred to by geodesic grid variables";
    
                data:
				lat_gds_2=-90, -30,  -30,    0,   0, 30,  30,  90;
				lon_gds_2=  0,   0,  180,    0, 180,  0, 180,   0;				
			  } // end g18g2
		 } // end g18g1 
    } // end g18
     
  //
  //g19 test cases for ncpdq; same variables as ncpdq netCDF3 tests
  //
  
  group: g19 { 
  
   dimensions:
   lat=2;
   lev=3;
   lon=4;
   time=unlimited; 

   variables:
   float lat(lat);
   float lon(lon); 
   float lev(lev);
   float lev_wgt(lev);
   double time(time);

   data:
   lat=-90,90;
   lon=0,90,180,270;
   lev=100,500,1000;
   lev_wgt=10,2,1;
   time=1.,2.,3.,4.,5.,6.,7.,8.,9.,10.;
  
    group: g19g1 { 
     variables:
     float two_dmn_var(lat,lev);
	   two_dmn_var:long_name = "two dimensional variable";
	   two_dmn_var:units = "fraction";
    
     data:
     two_dmn_var=1.5,5.5,9.5,13.5,17.5,21.5;
	 
	 
    } // end g19g1 

    group: g19g2 {
    variables:
    float two_dmn_rec_var(time,lev);
	  two_dmn_rec_var:long_name = "two dimensional record variable";
	  two_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.;
      
 
      } // end g19g2   
 
 
     group: g19g3 { 
     variables:
	 double three_dmn_var_dbl(time,lat,lon);
	 three_dmn_var_dbl:long_name = "three dimensional record variable of type double";
	 three_dmn_var_dbl:units = "watt meter-2";
	 three_dmn_var_dbl:_FillValue = -99.;


     data:
     three_dmn_var_dbl= 	 1, 2, 3, 4, 5, 6, 7, 8,
				 9,10,11,12,13,14,15,16,
				17,18,19,20,21,22,23,24,
				-99,-99,-99,-99,-99,-99,-99,-99,
				33,34,35,36,37,38,39,40,
				41,42,43,44,45,46,47,48,
				49,50,51,52,53,54,55,56,
				-99,58,59,60,61,62,63,64,
				65,66,67,68,69,70,71,72,
				-99,74,75,76,77,78,79,-99;
    
 
      } // end g19g3  
      
      
      group: g19g4 { 
      variables:
      short rec_var_dbl_mss_val_dbl_pck(time);
	    rec_var_dbl_mss_val_dbl_pck:long_name = "record variable, double, packed as short, with double missing values";
	    rec_var_dbl_mss_val_dbl_pck:purpose = "Packed version of rec_var_dbl_mss_val_dbl_upk";
	    rec_var_dbl_mss_val_dbl_pck:_FillValue = -999s;
	    rec_var_dbl_mss_val_dbl_pck:missing_value = -999.;
        rec_var_dbl_mss_val_dbl_pck:scale_factor = -9.15541313801785e-05;
        rec_var_dbl_mss_val_dbl_pck:add_offset = 5.;
      double upk;
    	upk:long_name = "Unpacked scalar variable";
	    upk:note = "Unpacked value is 3.0d0, upk=unpack(pck)= 2.0d0*1s + 1.0d0 = 3.0d0. Packing this variable should create an NC_SHORT scalar = 0s with packing attribute add_offset=3.0d and either no scale_factor (ncap) or scale_factor = 0.0d (ncpdq).";
      data:
      upk=3.;
      rec_var_dbl_mss_val_dbl_pck=-999,32767,21845,10922,0,-10922,-21845,-32767,-999,-999;
      } // end g19g4 
          
  } // end g19


  //
  //g20 test cases for ncwa; same variables as ncwa netCDF3 tests
  //
  group: g20 {
  dimensions:
   lat=2;
   variables:
   float lat(lat);
   float lat_wgt(lat);
   data:
   lat=-90,90;
   lat_wgt=1.,2.;
   
    group: g20g1 { 
     variables:
     float lat_cpy(lat);
     float lat_wgt(lat);
     data:
     lat_cpy=-90,90;
     lat_wgt=1.,0.;
    } // end g20g1 

  } //g20
  
  //
  // prototype problem from ACCESS 
  //
  group: g21 { 
  dimensions:
    lat=2;
    lon=4;
  variables:
  float lat(lat);
  lat:units = "degrees_north";
  float lon(lon);
  lon:units = "degrees_east";
  float snc(lat,lon);
  snc:long_name = "Snow Cover";
  data:
  lat=-45,45;
  lon=0,90,180,270;
  snc=1,2,3,4,5,6,7,8;
  } // end g21
  
  //
  // prototype problem from ACCESS 
  //
  group: g22 { 
  dimensions:
    lat=3;
    lon=3;
  variables:
  float lat(lat);
  lat:units = "degrees_north";
  float lon(lon);
  lon:units = "degrees_east";
  float snc(lat,lon);
  snc:long_name = "Snow Cover";
  data:
  lat=-60,0,60;
  lon=0,120,240;
  snc=1,2,3,4,5,6,7,8,9;
  } // end g22
  
  group: g90 {
  dimensions:
  dim90=2;
  variables:
  int g9(dim90);
  data:
  g9=1,2; 
  } // end g90
  
  //
  // ncra test case
  //
  group: g23 { 
   dimensions:
    lat=2;
    lon=3;
    time=unlimited;
    variables:
    float lat(lat);
    lat:units = "degrees_north";
    float lon(lon);
    lon:units = "degrees_east";
    double time(time);
    float snd(time,lat,lon);
    snd:long_name = "Snow Depth timeseries";
    data:
    lat=-60,0;
    lon=0,120,240;
    time=1,2;
    snd=1,2,3,4,5,6,7,8,9,10,11,12;
  } // end g23
  
  //
  // ncra test case
  //
  group: g24 { 
   dimensions:
    lat=2;
    lon=3;
    time=unlimited;
    variables:
    float lat(lat);
    lat:units = "degrees_north";
    float lon(lon);
    lon:units = "degrees_east";
    double time(time);
    float snd(time,lat,lon);
    snd:long_name = "Snow Depth timeseries";
    data:
    lat=-60,0;
    lon=0,120,240;
    time=4;
    snd=1,2,3,4,5,6;
  } // end g24
  
  //
  // ncra test cases
  //
  group: g25 { 
  
    //g25g1, g25g2: same data
  
    group: g25g1 {
      dimensions:
	  time=unlimited;	
	  variables:
	  double time(time);
      int one_dmn_rec_var(time);
      data:
	  time=1.,2.,3.,4.,5.,6.,7.,8.,9.,10.;
      one_dmn_rec_var=1,2,3,4,5,6,7,8,9,10;    
    } // end g25g1 
	
	group: g25g2 { 
      dimensions:
	  time=unlimited;	
	  variables:
	  double time(time);
      int one_dmn_rec_var(time);
      data:
	  time=1.,2.,3.,4.,5.,6.,7.,8.,9.,10.;
      one_dmn_rec_var=1,2,3,4,5,6,7,8,9,10;     
    } // end g25g2 
	
	//g25g3: record (time) is not coordinate variable
	
	group: g25g3 {
	  dimensions:
	  time=unlimited;	
	  variables:
      int one_dmn_rec_var(time);
      data:
      one_dmn_rec_var=1,2,3,4,5,6,7,8,9,10;      
    } // end g25g3
	
  } // end g25
  
  //ncwa: test weight and hyperslab
  
  group: g26 {
	dimensions:
	lat = 3 ;
	lon = 3 ;
	variables:
	float a(lat, lon) ;
	a:_FillValue = -999.f ;
	float gw_lat(lat) ;
	float gw_lon(lon) ;
	data:
	 a =
	  45.123, 2.21029, 67.219,
	  87.19, 12.8974, 3.98,
	  20, 22.234, _ ;
	 gw_lat = 0.1, 0.9, 0.9 ;
	 gw_lon = 1, 1, 1 ;
	} // end g26
	
group: g27 { //test flatenning with paralell variables: ncks -3 -G : -g /g27g1/
	group: g27g1 {
	dimensions:
	delta_time_start=2;
	variables:
	float delta_time_start(delta_time_start);
	data:
	delta_time_start=1,2;
	}
		
	group: g27g2 {
	dimensions:
	delta_time_start=1;
	variables:
	float delta_time_start(delta_time_start);
	data:
	delta_time_start=1;	
	}	
} // end g27
	
	
group: g28 { //test CF extraction ( "delta_time_stop" has a CF attribute to "delta_time_start")
	dimensions:
	delta_time_start=1;
	variables:
	float delta_time_start(delta_time_start);
	float delta_time_stop(delta_time_start);
	delta_time_stop:coordinates = "delta_time_start";
	data:
	delta_time_start=1;	
	delta_time_stop=1;
} // end g28

group: g29 { //test standard_name = "longitude"
	dimensions:
	time29=unlimited;
	lat29=2;
	lon29=2;

	variables:
	int time29(time29);
	int lat29(lat29);
	lat29:standard_name = "latitude";
	lat29:units="degree";
	int lon29(lon29);
	lon29:standard_name = "longitude";
	lon29:units="degree";
	int var3d(time29,lat29,lon29);
	
	data:
	time29=1;	
	lat29=1,2;
	lon29=1,2;
	var3d=1,2,3,4;
} // end g29

group: g30 { //test cell_methods attribute
 group: g30g1 { 
	dimensions:
	time301=unlimited;
	variables:
	float time301(time301);
	time301:long_name = "time301";
	data:
	time301=1,2;
   }// end g30g1
  group: g30g2 { 
	dimensions:
	time302=unlimited;
	variables:
	float time302(time302);
	time302:long_name = "time302";
	time302:cell_methods = "time302: mean";
	data:
	time302=1,2;
   }// end g30g2

} // end g30
	
} // end root group
