function [mvals]=get_whfc_time(url); % GET_WHFC_TIME Reads time from an WHFC EPIC style time series file % and returns a structure with useful time info % etm 3/2010 modified to use mDataset from njtools instead of using a % DAP-enabled netcdf (requiring avery old mexnc_dap_r14) % nc=mDataset(url); % Determine if uniform time base by checking if % dt*(nt-1) = t(end)-t(1) % Why use dt=(t(3)-t(1))/2 instead of dt=t(2)-t(1)? % Good question. Because in the first dataset I tried % (MYRTLEBEACH/7201adc-a.nc), t(2) was off by 1 millisecond. % Do exact math in integers (milliseconds) % njTBX doesn't return dimension sizes, so need to get a variable length % and the cast to double is necessary for use with mDataset ntimes=length(nc{'time'}(:)); d1=double(nc{'time'}(1)); % having these as double is necessary d3=double(nc{'time'}(3)); % when netcdf-java is used. d99=double(nc{'time'}(end)); e1=double(nc{'time2'}(1)); e3=double(nc{'time2'}(3)); e99=double(nc{'time2'}(end)); % in this program, d?=the day part of the EPIC time, e? is the parts of the % day or "time" component (based on EPIC time2). % round time2 values to nearest second to cover for previous sins % in processing which have led to 1 millisecond errors t1=round(e1/1000)*1000; t3=(d3-d1)*3600*24*1000+round(e3/1000)*1000; tend=(d99-d1)*3600*24*1000+round(e99/1000)*1000; dt=(t3-t1)/2; % Calculate start/stop times in Matlab datenum with units=milliseconds % EPIC is "true Julian day", where day 2440000 begins at 0000 hours, May % 23, 1968, and datenum(1968,5,23,0,0,0) == 718941 so we need to use the % difference between these times % 2440000 - 718941 == 1721059, used below mvals.jd_start=(d1 - 1721059)+t1/3600/24/1000; mvals.jd_stop=(d1 - 1721059)+tend/3600/24/1000; mvals.mjd_start=(d1 - 1721059)*3600*24*1000 + t1; mvals.mjd_stop =(d1 - 1721059)*3600*24*1000 + tend; % fixed typo here tot1=dt*(ntimes-1); tot2=tend-t1; if tot1==tot2, mvals.timebase_uniform=1; mvals.dt=dt/1000; % dt in milliseconds mvals.dtms=dt; % dt in milliseconds else % check whether the mean(diff(juliandays)) is close to what's been computed, and call % and call it good if the numbers are close tt=double(nc{'time'}(:))+(double(nc{'time2'}(:))./86400000); dt_from_mean=mean(diff(tt))*86400000; %msec if (abs(dt-dt_from_mean) > dt*.001) mvals.timebase_uniform=0; else mvals.timebase_uniform=1; mvals.dt=dt/1000; % dt in milliseconds mvals.dtms=dt; end end % for the geospatial bounds we need to get the positions, not all of which % may be there- use the variable first, and if it's not there use the % attribute if isempty(nc{'lon'}(1)) mvals.lon=nc.longitude(:); else mvals.lon=nc{'lon'}(1); end if isempty(nc{'lat'}(1)) mvals.latmeta=nc.latitude(:); else mvals.lat=nc{'lat'}(1); end close(nc);