function [good,bad]=do_sta2ncml_tdsmeta_grid(server, prefix, text_name) %do_sta2ncml_tdsmeta- generates CF compliant NcML from WHSC Time Series Data % adds THREDDS geospatial and time metadata elements, converts to % cf-time and adds some elements required for CF compliance % requires three arguments:base path,experiment directory name, and the % name of the file containing the extra metadata % usage: do_sta2ncml_tdsmeta('http://stellwagen.er.usgs.gov/opendap/','ARGO_MERCHANT/','extra_meta.txt') % You MUST use the slash at the end of the input string!! % outputs: ARGO_MERCHANT.ncml % ** 12/09 upgrade to hyrax has the url path looking like this % http://stellwagen.er.usgs.gov/opendap/HUDSON_SVALLEY06/ instead of % http://stellwagen.er.usgs.gov/cgi-bin/nph_dods/DATAFILES/HUDSON_SVALLEY06 % code and doc modified to reflect this change % new Apr/2010 % good: list of "good" urls (urls that worked) % bad: list of "bad" urls. (urls that did not open with mDataset) % only the "good ones will be included in the ncml. The others have to % be fixed before they can be included % use the thredds server opendap, not the hyrax/opendap if ~exist('server','var') server='http://stellwagen.er.usgs.gov/thredds/dodsC/TSdata/'; end if ~exist('prefix','var') prefix=input('Enter a directory name containing data files on stellwagen') end if ~exist('text_name','var') [fname, pathname] = uigetfile('**', 'Pick a file containing exp, PI, title, summary'); text_name=[pathname fname]; end url_base=[server prefix]; % grab all the files in this directory... % depending on where you're getting the data, have to use different parsers % because the html generated by urlread of a hyrax/opendap page is different % than the html generated by urlread of a thredds/opendap page if isempty(strfind(server,'thredds')) files=get_files_from_url(url_base); else files=get_files_from_TDS(url_base); end %... or use specific files %files={'3392-a1h.nc','3412-a1h.nc','3482-a1h.nc'}; %make a root name % don't always need to pull out the slashes since prefix should be just one level sep=filesep; slsh=findstr(sep, prefix); if length(slsh)==1 rname=prefix(1:slsh(1)-1); elseif length(slsh) > 1 rname=prefix(slsh(1)+1:slsh(2)-1) else rname=prefix(1:end-1) end % find the info that won't be in all the files by reading the % experiment_info file. The format of the entries should have 4 comma delimited %fields that contain: directory name, PI,title, summary and look like this: %ARGO_MERCHANT,B. Butman,Argo Merchant Experiment,A moored array deployed after the ARGO MERCHANT ran aground on Nantucket Shoals designed to help understand the fate of the spilled oil. % no single quotes are used, just the commas [aa,bb,cc,dd]=textread(text_name,'%s%s%s%s','delimiter',','); loc_use=find(strcmp(prefix(1:end-1),aa)); fid=fopen([rname '.ncml'],'wt'); igood=0; ibad=0; for i=1:length(files) % process all files %for i=1:5 % process only the 1st file stafile=char(files(i)); %% %if ~isempty(strfind(lower(stafile),'a1h')); %process only a1h files stafile; if (~isempty(strfind(stafile,'bst')) | ~isempty(strfind(stafile,'b-cal')) | ~isempty(strfind(stafile,'q-cal'))) % this is for Wrightsville, that has burst data disp ('burst file, skipping') % the bursts generate java heap errors elseif (~isempty(strfind(stafile,'fan')) | ~isempty(strfind(stafile,'pen')) | ~isempty(strfind(stafile,'im'))) % this is for Wrightsville, that has burst data disp ('sonar file, skipping') % the sonar generate java heap errors elseif (~isempty(strfind(stafile,'p-cal')) | ~isempty(strfind(stafile,'wsp'))) % this is for Wrightsville, that has burst data disp ('wave file, skipping') % the sonar generate java heap errors elseif (~isempty(strfind(stafile,'abs'))) % this is for Wrightsville, that has burst data disp ('abss file, skipping') % the sonar generate java heap errors else url=[url_base stafile]; try % replaces get_whfc_meta 4/19/10 % get_whfc_time has correct cast to double required usind mDataset [mvals]=get_whfc_time(url); [mvals]=get_whfc_varmeta(url,mvals); %add variable info to struct if mvals.timebase_uniform % replace the Sci_PI, title and summary fields here mvals.scipi=bb{loc_use}; mvals.title=[stafile ' - ' cc{loc_use}]; mvals.summary=dd{loc_use}; %start=mvals.mjd_start; % matlab datenum %dt=mvals.dtms; % convert dt (seconds => days) site=['USGS/CMGP-' stafile(1:3)]; %adds the nice xml wrappings to content of mvals sta2ncml_tdsmeta_grid(fid,server,prefix,stafile,mvals,site); end igood=igood+1; good{igood}=url; catch ME ibad=ibad+1; bad.addr{ibad}=url; % when opendap error checker fails it's retrievable with lasterror prob=lasterror; msg_str=getfield(prob,'message'); if isempty(msg_str) msg_str='no message available'; end % now save the message c=textscan(msg_str,'%s','HeaderLines',1, 'EndOfLine','\n'); if (length(c{1})==0) bad.cause{ibad}='unknown'; elseif strmatch(char(c{1}(9)),'at') bad.cause{ibad}=msg_str(1:100); else bad.cause{ibad}=char(c{1}(9)); %it's usually the 9th line end end end %end %% end fclose(fid); % to output a sensible list of contents of bad, enter: if(ibad > 0) % only do if there's bad data rsons=char(bad.cause); addrs=char(bad.addr); qbad=strcat(addrs, '- => ', rsons) oname=[prefix(1:end-1) '_ng.txt'] % now save it for posterity fid=fopen(oname,'w') [p,q]=size(qbad); fmt=['%' num2str(q) 's\n']; for ik=1:p fprintf(fid,fmt,qbad(ik,:)) end fclose(fid) else bad=0; %must return something in bad end end