function sta2ncml_tdsmeta_grid(fid,server,prefix,stafile,mvals,site); % sta2ncml_tdsmeta: Write NcML to make time series file CF-compliant % Usage: sta2ncml(fid,server,prefix,stafile,start,dt); % Inputs: % fid = file id of text file *already opened for writing* % server = first part of URL. For example: % 'http://stellwagen.er.usgs.gov/thredds/dodsC/TSdata/' % thredds OPeNDAP style % 'http://stellwagen.er.usgs.gov/opendap/' % Hyrax OPeNDAP style % 'http://stellwagen.er.usgs.gov/' % HTTP style % prefix = The time series directory (next part of URL). % 'MBAY_LT/'; % 'MYRTLEBEACH/'; % stafile = name of NetCDF file: '7201adc-a.nc'; % mvals = a structure containing start stop times, lat, lon and timestep % mvals may be obtained by calling get_whfc_time() % site = a string containing the site ID (made up of mooring ID) % % Rich Signell (rsignell@usgs.gov) % Notes on making our Time Series Data CF-compliant: % Time: Our time series data use non CF-compliant time convention, % with "time" variable containing Julian days and "time2" containing % milliseconds since midnight. To make these CF-compliant, we use % NcML to construct a double precision time vector in Modified Julian Day, % one of the few internationally recognized time conventions that starts % at midnight. (See http://tycho.usno.navy.mil/mjd.html for more info.) % % We specify %.16f precision, which will give us accuracy of: % - better than 3.0e-5 milliseconds until August 31, 2132 and % - better than 3.0e-4 milliseconds until October 12, 4596! % % Lon,Lat and Depth: We give "lon" and "lat" CF-Compatible units of % "degrees_east" and "degrees_north" and give "depth" the attribute of % "positive=down" so that it recognized as a vertical coordinate. start=(mvals.mjd_start-3600*24*1000*datenum(1858,11,17,0,0,0)); % convert datenum to MJD location=[server prefix stafile]; stub=[prefix stafile]; fprintf(fid,'\n',stafile,stub,stub); % this line isn't needed if the experiment has this inherited fprintf(fid,'manyservices\n'); % this inserts the THREDDS metadata fprintf(fid,'\n'); fprintf(fid,'\n'); fprintf(fid,'\n'); fprintf(fid,' %f \n',mvals.lat); fprintf(fid,'0\n'); fprintf(fid,'degrees_north\n'); fprintf(fid,'\n'); fprintf(fid,'\n'); fprintf(fid,' %f \n',mvals.lon); fprintf(fid,'0\n'); fprintf(fid,'degrees_west\n'); fprintf(fid,'\n'); fprintf(fid,'\n'); fprintf(fid,'\n'); % in the TDS metadata, these must NOT be inside quotes fprintf(fid,'%s \n',datestr(mvals.jd_start,31)); fprintf(fid,' %s \n',datestr(mvals.jd_stop,31)); fprintf(fid,'\n'); fprintf(fid,'\n'); for ik=1:length(mvals.varnames) % this inserts the cf_name obtained in lookup_cf if available % if units are missing, it's a ' ' (space), so this patches most cases % with current GI-cat usage both should probably be cf_name % old way looks like: % sea_water_salinity % for it to find "sea_water_salinity", that string has to be the last element % based on the THREDDS metadata documentation, "sea_water_salinity" should % really be in the vocabulary name, so probably it should go in both fields % % this is the "broken" way that used to work in gi-cat % try % if isspace(mvals.units{ik}) % fprintf(fid,'%s\n',... % mvals.varnames{ik},deblank(mvals.long_name{ik}),'unknown',deblank(mvals.cf_name{ik})); % % else % fprintf(fid,'%s\n',... % mvals.varnames{ik},deblank(mvals.long_name{ik}),mvals.units{ik},deblank(mvals.cf_name{ik})); % end % % this is the swapped way try if isspace(mvals.units{ik}) fprintf(fid,'%s\n',... mvals.varnames{ik},deblank(mvals.cf_name{ik}),'unknown',deblank(mvals.long_name{ik})); else fprintf(fid,'%s\n',... mvals.varnames{ik},deblank(mvals.cf_name{ik}),mvals.units{ik},deblank(mvals.long_name{ik})); end catch ME disp ('we are here because it did not like the long_name') keyboard end end fprintf(fid,''); fprintf(fid,'\n'); % the netcdf line *MUST* follow the metadata fprintf(fid,'\n',location); % this part adds the cf-time fprintf(fid,'\n'); fprintf(fid,' \n'); fprintf(fid,' \n'); fprintf(fid,' \n',start,mvals.dtms); fprintf(fid,'\n'); % get rid of old time2 fprintf(fid,'\n'); fprintf(fid,'\n'); fprintf(fid,' \n'); fprintf(fid,' \n'); % standard_name of station_altitude is needed for point obs- don't use yet fprintf(fid,'\n'); % lon lat (and depth for single depth instruments) should be shape "" fprintf(fid,'\n'); fprintf(fid,' \n'); fprintf(fid,' \n'); fprintf(fid,'\n'); fprintf(fid,'\n'); fprintf(fid,' \n'); fprintf(fid,' \n'); fprintf(fid,'\n'); % now add the site id to allow it to by "station" fprintf(fid,'\n'); fprintf(fid,'\n'); fprintf(fid,' "%s"\n', site); fprintf(fid,' \n'); % for each of the non-coordinate variables, add the standard_name if % available cf_sub is 1 when there was a CF name equivalant- do nothing % when cf_sub is 0 for ik=1:length(mvals.varnames) if mvals.cf_sub{ik}==1 eval(['fprintf(fid,''\n'');']) eval(['fprintf(fid,''\n'');']) fprintf(fid,'\n'); end end % add these necessary items for identification fprintf(fid,'\n'); % put the next two back in if needed as appropriate for "grid" %fprintf(fid,'\n'); %fprintf(fid,'\n'); % %here's more from the unidata dataset discovery attributes that are already %in the thredds dataset, but that aren't already inherited eval(['fprintf(fid,''\n'');']) fprintf(fid,'\n'); fprintf(fid,'\n'); fprintf(fid,'\n'); fprintf(fid,'\n'); fprintf(fid,'\n'); fprintf(fid,'\n'); fprintf(fid,'\n'); eval(['fprintf(fid,''\n'');']) fprintf(fid,'\n'); eval(['fprintf(fid,''\n'');']) eval(['fprintf(fid,''\n'');']) fprintf(fid,'\n'); fprintf(fid,'\n'); eval(['fprintf(fid,''\n'');']) % re-write start_time and stop time attributes in ISO 8601 format fprintf(fid,'\n',datestr(mvals.jd_start,31)); fprintf(fid,'\n',datestr(mvals.jd_stop,31)); fprintf(fid,'\n'); fprintf(fid,'\n');