netcdf converting_to_netcdf_supplement { // CONVERTING DATA TO THE "NETWORK COMMON DATA FORM" (netCDF): // A SUPPLEMENT // // NOAA PMEL Thermal Modeling and Analysis Project (TMAP) // Dan Trueman, Steve Hankin // last revised: 1 Dec 1993: slat80_82 and slon10_140 coordinates included // // I. INTRODUCTION // // This supplement to "Converting Data to the Network Common Data Form: // an Introduction" describes: // // 1. How to set up a cdl file capable of handling data // on staggered grids. // 2. How to define coordinate systems such that the data // in the netCDF file may be regarded as hyperslabs of // larger coordinate spaces. // 3. How to define variables of 1, 2, or 3 dimensions. // 4. How to define boundaries between unevenly spaced axis // coordinates (used in numerical integrations). // 5. How to set up climatological "modulo" time axes. // 6. How to convert time word data into numerical data // appropriate for netCDF. // // In this sample data set, we will consider wind, salt, and // velocity calculated using a staggered-grid, finite-difference // technique. The wind data is naturally limited to the surface // layer of the ocean (i.e. normal to the depth axis). We will // also consider the salt data to be limited to a narrow slab from // 139E to 90W (I=10 to 140), 32.5N to 34.9N (J=80 to 82), and for // all depth and time values. // // II. STAGGERED GRIDS // // Dealing with staggered grids is fairly straightforward. Dimensions // for each grid axis must be defined, the axes themselves must be // defined (in Variables), and the coordinate values for each axis must // be initialized (in Data). In this case, there are two grids, a // wind grid, and a velocity grid, so tlon, tlat and tdepth are // defined for the wind grid, and ulon, ulat, and udepth for the velocity // grid. The variables are then given arguments to place them in their // proper grids (i.e. wind(time, sdepth, slat, slon)). // // III. HYPERSLABS // // There are a number of steps required to set up a netCDF data set that // represents a hyperslab of data from a larger grid definition. // // 1. Define a dimension named "grid_definition". This dimension // should be set equal to 1. // 2. Define parent grids in Variables with the argument // "grid_definition". // // char wind_grid(grid_definition) ; // char salt_grid(grid_definition) ; // // 3. Define the 4 axes of the parent grids using the "axes" attribute. // // wind_grid: axes = "slon slat normal time" ; // salt_grid: axes = "slon slat sdepth time" ; // // Note that the order of arguments is opposite that in the // variable declaration. The argument "normal" indicates that // wind_grid is normal to the depth axis. // // 4. Define the variables which are hyperslabs of these grids with // the proper dimensions. // // float wind(time, slat, slon) ; // float salt(time, sdepth, slat80_82, slon10_140) ; // // where slat80_82 = 3 and slon10_140 = 131. The axis names are /// arbitrary - chosen for readability. These axes (child axes) // must be defined with the attribute "child_axis" as follows: // // float slat80_82(slat80_82) ; // slat80_82: child_axis = " " ; // // These "child axes" need not be initialized in Data, nor do their // edges need be defined; FERRET retrieves this information from // the parent axes. // // 5. Use the "parent_grid" variable attribute to point to the // parent grid. // // wind: parent_grid = "wind_grid" // // 6. Also as a variable attribute, define the index range of interest // within the parent grid. // // wind: slab_min_index = 1s, 1s, 1s, 0s ; // wind: slab_max_index = 160s, 100s, 1s, 0s ; // salt: slab_min_index = 10s, 80s, 1s, 0s ; // salt: slab_max_index = 140s, 82s, 27s, 0s ; // // The "s" after each integer indicates a "short" 16-bit integer // rather than the default "long" 32-bit integer. If an axis // dimension is designated as "unlimited" then the index bounds // for this axis must be designated as "0s". // // These commands will effectively locate the wind and salt data within // the full grid. // // IV. VARIABLES OF 1, 2, or 3 DIMENSIONS // // One, two, or three dimensional variables may be set up in one of // two ways - either using the parent_grid and child_axis attributes // as illustrated in the 3-dimensional variable "wind" from the hyperslab // example, above, or by selecting axis names and units that provide // FERRET with adequate hints to map this variable onto 4-dimensional // space and time. The following hints are recognized by FERRET: // // Units of days, hours, minutes, etc. or an axis name of "TIME", "DATE" // implies a time axis. // Units of "degrees xxxx" where "xxxx" contains "lat" or "lon" implies // a latitude or longitude axis, respectively. // Units of "degrees" together with an axis name containing "LAT" or // "Y" implies a latitude axis else longitude is assumed. // Units of millibars, "layer" or "level" or an axis name containing // "Z" or "ELEV" implies a vertical axis. // // V. UNEVENLY SPACED COORDINATE BOUNDARIES // // For coordinate axes with uneven spacing, the boundaries between each // coordinate can be indicated by pointing to an additional axis that // contains the locations of the boundaries. The dimension of this "edge" // axis will necessarily be one larger than the coordinate axis concerned. // If edges are not defined for an unevenly spaced axis, the midpoint // between coordinates will be assumed by default. // // 1. Define a dimension one larger than the coordinate axis. For // the sdepth axis, with 27 coordinates, define: // // sdepth_edges = 28 ; // // 2. Define an axis called sdepth_edges. // 3. Initialize this axis appropriately (in Data). // 4. As a sdepth axis attribute, point to sdepth_edges: // // sdepth: edges = "sdepth_edges" ; // // If the coordinate axes are evenly spaced, the attribute "point spacing" // should be used: // // slat: point_spacing = "even" ; // // When used, this attribute will improve memory use efficiency in FERRET. // // VI. CLIMATOLOGICAL "MODULO" AXES // // The "modulo" axis attribute indicates that the axis wraps around, // the first point immediately following the last. The most common // uses of modulo axes are: // // 1. As longitude axes for globe-encircling data. // 2. As time axes for climatological data. // // time: modulo = " " ; // any arbitrary string is allowed // // If the climatological data occurs in the years 0000 or 0001 then FERRET // will omit the year from the output formatting. // // VII. CONVERTING TIME WORD DATA TO NUMERICAL DATA // // If the time data being converted to netCDF format exists in string format // (i.e. 1972 - JANUARY 15 12:15:00), rather than numerical format (i.e. 55123 // seconds) a number of TMAP routines are available to aid in the conversion // process. The steps required for conversion are as follows: // // 1. Break the time string into its 6 pieces. If the data is of the // form dd-mmm-yyyy:hh:mm:dd, the TMAP routine "tm_break_date.f" can // be used. // 2. Choose a time_origin before the beginning of the time data to // assure that all time values are positive. i.e. if the data begins // at 15-JAN-1982:05:30:00, choose a time origin of // 15-JAN-1981:00:00:00. This time_origin should then be an attribute // of the time axis variable in the CDL file. // 3. Produce numerical time data by using "tm_sec_from_bc.f", which // calculates the number of seconds between 01-01-0000:00:00:00 and // the date specified. Continuing the example from (2), the time value // for the first time step with respect to the time_origin could be // calculated as follows: // // time(1) = tm_sec_from_bc(1982, 1, 15, 5, 30, 0) - // tm_sec_from_bc(1981, 1, 15, 0, 0, 0) // // or more generally // // time(n) = tm_sec_from_bc(nyear,nmonth,nday,nhour,nminute,nsecond) - // tm-sec_from_bc(oyear,omonth,oday,ohour,ominute,osecond) // // where nyear is the year for the nth time step and oyear is the year // of time_origin. // // VII. EXAMPLE CDL FILE dimensions: // staggered grid dimension definitions: slon = 160 ; // wind/salt longitude dimension ulon = 160 ; // velocity longitude dimension slat = 100 ; // wind/salt latitude dimension ulat = 100 ; // velocity latitude dimension sdepth = 27 ; // salt depth dimension wdepth = 27 ; // velocity depth dimension slon10_140 = 131 ; // for salt hyperslab slat80_82 = 3 ; // for salt hyperslab time = unlimited ; // grid_definition is the dimension name to be used for all grid definitions grid_definition = 1 ; // edge dimension definitions: sdepth_edges = 28 ; wdepth_edges = 28 ; variables: // variable definitions: float wind(time, slat, slon) ; // 3-dimensional variable wind: parent_grid = "wind_grid" ; wind: slab_min_index = 1s, 1s, 1s, 0s ; wind: slab_max_index = 160s, 100s, 1s, 0s ; wind: long_name = "WIND" ; wind: units = "deg. C" ; wind: _FillValue = 1E34f ; float salt(time, sdepth, slat80_82, slon10_140) ; // 4-dim. variable salt: parent_grid = "salt_grid" ; salt: slab_min_index = 10s, 80s, 1s, 0s ; salt: slab_max_index = 140s, 82s, 27s, 0s ; salt: long_name = "(SALINITY(ppt) - 35) /1000" ; salt: units = "frac. by wt. less .035" ; salt: _FillValue = -999.f ; float u(time, sdepth, ulat, ulon) ; u: long_name = "ZONAL VELOCITY" ; u: units = "cm/sec" ; u: _FillValue = 1E34f ; float v(time, sdepth, ulat, ulon) ; v: long_name = "MERIDIONAL VELOCITY" ; v: units = "cm/sec" ; v: _FillValue = 1E34f ; float w(time, wdepth, slat, slon) ; w: long_name = "VERTICAL VELOCITY" ; w: units = "cm/sec" ; w: _FillValue = 1E34f ; // axis definitions: float slon(slon) ; slon: units = "degrees" ; slon: point_spacing = "even" ; float ulon(ulon) ; ulon: units = "degrees" ; ulon: point_spacing = "even" ; float slat(slat) ; slat: units = "degrees" ; slat: point_spacing = "even" ; float ulat(ulat) ; ulat: units = "degrees" ; ulat: point_spacing = "even" ; float sdepth(sdepth) ; sdepth: units = "meters" ; sdepth: positive = "down" ; sdepth: edges = "sdepth_edges" ; float wdepth(wdepth) ; wdepth: units = "meters" ; wdepth: positive = "down" ; wdepth: edges = "wdepth_edges" ; float time(time) ; time: modulo = " " ; time: time_origin = "15-JAN-1981:00:00:00" ; time: units = "seconds" ; // child grid definitions: float slon10_140(slon10_140) ; slon10_140: child_axis = " " ; slon10_140: units = "degrees" ; float slat80_82(slat80_82) ; slat80_82: child_axis = " " ; slat80_82: units = "degrees" ; // edge axis definitions: float sdepth_edges(sdepth_edges) ; float wdepth_edges(wdepth_edges) ; // parent grid definition: char wind_grid(grid_definition) ; wind_grid: axes = "slon slat normal time" ; char salt_grid(grid_definition) ; salt_grid: axes = "slon slat sdepth time" ; // global attributes: :title = "netCDF Title" ; data: // // ignore this block // // This next data entry, for time, should be ignored. Time is initialized here // only so that FERRET can read test.cdf (the file created by this cdl file) // with no additional data inserted into it. time=1000; // // end of ignored block // slat= -28.8360729218,-26.5299491882,-24.2880744934,-22.1501560211,-20.1513576508, -18.3207626343,-16.6801033020,-15.2428140640,-14.0134353638,-12.9874248505, -12.1513509750,-11.4834814072,-10.9547319412,-10.5299386978,-10.1693935394, -9.8333206177,-9.4999876022,-9.1666536331,-8.8333196640,-8.4999856949, -8.1666526794,-7.8333187103,-7.4999847412,-7.1666512489,-6.8333182335, -6.4999852180,-6.1666517258,-5.8333182335,-5.4999852180,-5.1666517258, -4.8333187103,-4.4999852180,-4.1666517258,-3.8333187103,-3.4999852180, -3.1666517258,-2.8333184719,-2.4999852180,-2.1666519642,-1.8333185911, -1.4999852180,-1.1666518450,-0.8333183527,-0.4999849498,-0.1666515470, 0.1666818559,0.5000152588,0.8333486915,1.1666821241,1.5000154972, 1.8333489895,2.1666824818,2.5000159740,2.8333494663,3.1666829586, 3.5000162125,3.8333497047,4.1666831970,4.5000162125,4.8333497047, 5.1666831970,5.5000162125,5.8333497047,6.1666827202,6.5000162125, 6.8333497047,7.1666827202,7.5000166893,7.8333501816,8.1666841507, 8.5000181198,8.8333511353,9.1666851044,9.5000190735,9.8333530426, 10.1679363251,10.5137376785,10.8892869949,11.3138961792,11.8060989380, 12.3833675385,13.0618314743,13.8560228348,14.7786512375,15.8403968811, 17.0497493744,18.4128704071,19.9334945679,21.6128730774,23.4497566223, 25.4404067993,27.5786647797,29.8560409546,32.2618522644,34.7833900452, 37.4061241150,40.1139259338,42.8893203735,45.7137718201,48.5679702759; ulat= -27.6721439362,-25.3877544403,-23.1883945465,-21.1119174957,-19.1907978058, -17.4507274628,-15.9094810486,-14.5761461258,-13.4507236481,-12.5241250992, -11.7785758972,-11.1883859634,-10.7210769653,-10.3387994766,-9.9999876022, -9.6666545868,-9.3333206177,-8.9999866486,-8.6666526794,-8.3333196640, -7.9999856949,-7.6666517258,-7.3333182335,-6.9999847412,-6.6666512489, -6.3333182335,-5.9999847412,-5.6666517258,-5.3333182335,-4.9999847412, -4.6666517258,-4.3333182335,-3.9999849796,-3.6666517258,-3.3333184719, -2.9999852180,-2.6666519642,-2.3333184719,-1.9999853373,-1.6666518450, -1.3333184719,-0.9999850392,-0.6666516662,-0.3333182633,0.0000151545, 0.3333485723,0.6666819453,1.0000153780,1.3333487511,1.6666821241, 2.0000154972,2.3333489895,2.6666827202,3.0000162125,3.3333497047, 3.6666829586,4.0000162125,4.3333497047,4.6666827202,5.0000162125, 5.3333492279,5.6666827202,6.0000162125,6.3333492279,6.6666827202, 7.0000157356,7.3333497047,7.6666831970,8.0000171661,8.3333511353, 8.6666841507,9.0000181198,9.3333520889,9.6666860580,10.0000190735, 10.3358526230,10.6916217804,11.0869522095,11.5408391953,12.0713586807, 12.6953773499,13.4282865524,14.2837600708,15.2735414505,16.4072513580, 17.6922454834,19.1334934235,20.7334957123,22.4922523499,24.4072608948, 26.4735546112,28.6837768555,31.0283031464,33.4953994751,36.0713844299, 38.7408676147,41.4869842529,44.2916526794,47.1358833313,50.0000534058; slon= 130.5,131.5,132.5,133.5,134.5,135.5,136.5,137.5,138.5,139.5,140.5,141.5, 142.5,143.5,144.5,145.5,146.5,147.5,148.5,149.5,150.5,151.5,152.5,153.5, 154.5,155.5,156.5,157.5,158.5,159.5,160.5,161.5,162.5,163.5,164.5,165.5, 166.5,167.5,168.5,169.5,170.5,171.5,172.5,173.5,174.5,175.5,176.5,177.5, 178.5,179.5,180.5,181.5,182.5,183.5,184.5,185.5,186.5,187.5,188.5,189.5, 190.5,191.5,192.5,193.5,194.5,195.5,196.5,197.5,198.5,199.5,200.5,201.5, 202.5,203.5,204.5,205.5,206.5,207.5,208.5,209.5,210.5,211.5,212.5,213.5, 214.5,215.5,216.5,217.5,218.5,219.5,220.5,221.5,222.5,223.5,224.5,225.5, 226.5,227.5,228.5,229.5,230.5,231.5,232.5,233.5,234.5,235.5,236.5,237.5, 238.5,239.5,240.5,241.5,242.5,243.5,244.5,245.5,246.5,247.5,248.5,249.5, 250.5,251.5,252.5,253.5,254.5,255.5,256.5,257.5,258.5,259.5,260.5,261.5, 262.5,263.5,264.5,265.5,266.5,267.5,268.5,269.5,270.5,271.5,272.5,273.5, 274.5,275.5,276.5,277.5,278.5,279.5,280.5,281.5,282.5,283.5,284.5,285.5, 286.5,287.5,288.5,289.5; ulon= 131.0,132.0,133.0,134.0,135.0,136.0,137.0,138.0,139.0,140.0,141.0,142.0, 143.0,144.0,145.0,146.0,147.0,148.0,149.0,150.0,151.0,152.0,153.0,154.0, 155.0,156.0,157.0,158.0,159.0,160.0,161.0,162.0,163.0,164.0,165.0,166.0, 167.0,168.0,169.0,170.0,171.0,172.0,173.0,174.0,175.0,176.0,177.0,178.0, 179.0,180.0,181.0,182.0,183.0,184.0,185.0,186.0,187.0,188.0,189.0,190.0, 191.0,192.0,193.0,194.0,195.0,196.0,197.0,198.0,199.0,200.0,201.0,202.0, 203.0,204.0,205.0,206.0,207.0,208.0,209.0,210.0,211.0,212.0,213.0,214.0, 215.0,216.0,217.0,218.0,219.0,220.0,221.0,222.0,223.0,224.0,225.0,226.0, 227.0,228.0,229.0,230.0,231.0,232.0,233.0,234.0,235.0,236.0,237.0,238.0, 239.0,240.0,241.0,242.0,243.0,244.0,245.0,246.0,247.0,248.0,249.0,250.0, 251.0,252.0,253.0,254.0,255.0,256.0,257.0,258.0,259.0,260.0,261.0,262.0, 263.0,264.0,265.0,266.0,267.0,268.0,269.0,270.0,271.0,272.0,273.0,274.0, 275.0,276.0,277.0,278.0,279.0,280.0,281.0,282.0,283.0,284.0,285.0,286.0, 287.0,288.0,289.0,290.0; sdepth= 5.0,15.0,25.0,35.0,45.0,55.0,65.0,75.0,85.0,95.0,106.25,120.0,136.25,155.0, 177.5,205.0,240.0,288.5,362.5,483.5,680.0,979.5,1395.5,1916.0,2524.0,3174.0, 3824.0; sdepth_edges= 0.0,10.0,20.0,30.0,40.0,50.0,60.0,70.0,80.0,90.0,100.0,112.5,127.5, 145.0,165.0,190.0,220.0,260.0,317.0,408.0,559.0,801.0,1158.0,1633.0,2199.0, 2849.0,3499.0,4149.0; wdepth= 10.0,20.0,30.0,40.0,50.0,60.0,70.0,80.0,90.0,100.0,112.5,127.5,145.0,165.0, 190.0,220.0,260.0,317.0,408.0,559.0,801.0,1158.0,1633.0,2199.0,2849.0,3499.0, 4149.0; wdepth_edges= 5.0,15.0,25.0,35.0,45.0,55.0,65.0,75.0,85.0,94.375,105.625,119.375,135.625, 153.75,176.25,202.5,235.75,280.0,347.5,460.75,651.25,950.0,1372.75,1895.0, 2524.0,3174.0,3986.5,4311.0; slon10_140= 139.5, 140.5, 141.5, 142.5, 143.5, 144.5, 145.5, 146.5, 147.5, 148.5, 149.5, 150.5, 151.5, 152.5, 153.5, 154.5, 155.5, 156.5, 157.5, 158.5, 159.5, 160.5, 161.5, 162.5, 163.5, 164.5, 165.5, 166.5, 167.5, 168.5, 169.5, 170.5, 171.5, 172.5, 173.5, 174.5, 175.5, 176.5, 177.5, 178.5, 179.5, 180.5, 181.5, 182.5, 183.5, 184.5, 185.5, 186.5, 187.5, 188.5, 189.5, 190.5, 191.5, 192.5, 193.5, 194.5, 195.5, 196.5, 197.5, 198.5, 199.5, 200.5, 201.5, 202.5, 203.5, 204.5, 205.5, 206.5, 207.5, 208.5, 209.5, 210.5, 211.5, 212.5, 213.5, 214.5, 215.5, 216.5, 217.5, 218.5, 219.5, 220.5, 221.5, 222.5, 223.5, 224.5, 225.5, 226.5, 227.5, 228.5, 229.5, 230.5, 231.5, 232.5, 233.5, 234.5, 235.5, 236.5, 237.5, 238.5, 239.5, 240.5, 241.5, 242.5, 243.5, 244.5, 245.5, 246.5, 247.5, 248.5, 249.5, 250.5, 251.5, 252.5, 253.5, 254.5, 255.5, 256.5, 257.5, 258.5, 259.5, 260.5, 261.5, 262.5, 263.5, 264.5, 265.5, 266.5, 267.5, 268.5, 269.5 ; slat80_82= 11.8060989379883, 12.3833675384522, 13.0618314743042 ; }