function ncp = do_fan_rots(settings, fname, img_nums) % do_fan_rots - Processes Imagenex fan sonar data from the raw netCDF file. % this program applies a constant rotation to the fan sonar data to % orient it relative to North. Will process one or more samples % % usage: ncp = do_fan_rots(settings, '8369fan331_raw.cdf', [1:10]) % where: settings is the structure containing metafields % fname is the netcdf file containing the raw data. The % rootname will be used to create the name of the % processed file % img_nums is the array of image indices to process % can use [1 10 25] or [132:181], % default is to process all % ** nb: if you choose discontinuous elements, they will be % put into sequential elements in the output file, so % the timebase is likely to be irregular. % ncp is the processed output netcdf object % % USGS Woods Hole Field Center % emontgomery@usgs.gov % % Dependencies: % USGS NetCDF Toolbox (C. Denham) % -dap enabled mexnc doesn't work! ==> mexnc_win_2006a\mexnc.mexw32 works % procfan.m (E. Montgomery) % definefanprocnc.m (E. Montgomery) % % 3/25/08 at CRS request, splitting procsonar into two parts: 1) make the % raw.cdf file and 2) apply rotations and what-have-you % close all more off % get the current SVN version- the value is automatically obtained in svn % is the file's svn.keywords is set to "Revision" rev_info= 'SVN $Revision$'; % Check that the metadata contains required fields. reqFields = {'SonartoAnimate','fanadcp_off','adcp3val'}; for f = 1:length(reqFields) if ~isfield(settings,reqFields{f}) disp(['The field ''',reqFields{f},''' is not specified in settings']) missingFields(f) = 1; else missingFields(f) = 0; end end %If a required field is missing, ask the user for it. if any(missingFields) disp('Required fields missing from the metadata'); % Default settings for Eurostrat first deployment 2002-2003 settings.SonartoAnimate = 'fan'; settings.fanadcp_off = 0; settings.adcp3val = 0; settings.sweeps = 1; settings.dxy = 0.02; % Key setting...determines image resolution at cost of % speed (reasonable range 0.02 to 0.005) end clear reqFields missingFields clear FanTime Fanidx = 1; save settings settings; % open existing cdf file of raw fan data if exist(fname, 'file') ~= 2 || isempty(fname) disp('The raw cdf file name entered does not exist, please choose another.') [fname,PathName,FilterIndex] = uigetfile('*'); fname=[PathName fname]; end ncr=netcdf(fname); % set up output file name if isfield(settings,'onameRoot') ofproc=[settings.onameRoot '_proc.cdf']; else uidx=strfind(fname,'_'); outFileRoot=fname(1:uidx-1); ofproc=[outFileRoot '_proc.cdf']; end % decide how big the resulting matrices need to be if isfield(settings,'dxy') x=[-ncr.Range(:):settings.dxy(:):ncr.Range(:)]; else x=[-ncr.Range(:):ncr.dxy(:):ncr.Range(:)]; end dim_nc.x=length(x); dim_nc.y=length(x); % let a settings.sweeps superceede what's in the raw file, or compensate if % there isn't one in the raw file. if (isfield(settings,'sweeps')) dim_nc.sweep=settings.sweeps; else dim_nc.sweep=ncr.sweeps(:); settings.sweeps=ncr.sweeps(:); end if isempty(dim_nc.sweep) tmpsw= input('how many sweeps were made per sample? '); dim_nc.sweep=tmpsw; settings.sweeps=dim_nc.sweep; end % instantiate the output ncfile ncp = definefanprocnc(ofproc, settings, dim_nc); % if we ended up with sweep and sweeps attributes delete sweep tmp=att(ncp,'sweep'); if ~isempty(tmp) ncp.sweep=[]; end clear tmp % copy attributes from raw file rawAtts=ncnames(att(ncr)); for ik=1:length(rawAtts) eval(['ncp.' char(rawAtts(ik)) '= ncr.' char(rawAtts(ik)) '(:);']) end % if there's information in settings, replace the ncp attributes % with the values in settings nn=fieldnames(settings); for ik = 1:length(nn) eval(['ncp.' nn{ik} '(:)=settings.' nn{ik} ';']) end % since StepSize is wrong in header, add degreesPerStep here ncp.DegPerStep=ncr.StepSize(:); ncp.DegPerStep(:)= ncr{'headangle'}(5)-ncr{'headangle'}(4); %reset creation date to now ncp.CREATION_DATE = ncchar(datestr(now)); % set up how many images to process if nargin == 3 nimg_nums=img_nums; else nimg_nums=[1:1:length(ncr{'time'})]; end % do the right number of time elements ncp{'time'}(1:length(nimg_nums))=ncr{'time'}(nimg_nums); ncp{'time2'}(1:length(nimg_nums))=ncr{'time2'}(nimg_nums); % put the outputs into processed netcdf file for kj=1:settings.sweeps ncp{'sweep'}(kj)=kj; end for jj=(nimg_nums(1):nimg_nums(end)) % process the images and put into output netcdf file [Xplot,Yplot, thi, ri, Zs, rot]=procfan(ncr,jj,'polar', settings); % and put what's returned in the output file and object if Fanidx==1 ncp{'x'}(1:length(Xplot))=Xplot; ncp{'y'}(1:length(Yplot))=Yplot; end % Zs is float- needs to be multiplied by 10000 to store as short for kk=1:settings.sweeps tmp1=floor(Zs(kk,:,:)*10000); %have to force it to uint16 since sonar_image is nc_short tmp1=uint16(tmp1); ncp{'sonar_image'}(Fanidx,kk,1:length(Xplot),1:length(Yplot))=squeeze(tmp1); clear tmp1 end Fanidx=Fanidx+1; end ncp{'sonar_image'}.scale_factor(:)=10000; % this is the last we need ncr... close(ncr); % add to history & make some notes to the netcdf file hist = ncp.history(:); hist_new = ['Sonar processed with ' ,mfilename, ', ', rev_info, ', using Matlab ' ,... version, '; ',hist]; ncp.history = hist_new; ncp.NOTE =['radial data interpolated onto x-y grid to make image;',... 'image rotated so that +y (up) is N']; ncp.NOTE1 = ['To view images in Matlab type the following at the command ',... 'prompt: nc=netdcf(''sonarxxx.nc'');',... 'imagesc(nc{''x''}(:),nc{''y''}(:),squeeze(nc{''sonar_image''}(n,p,:,:)));',... 'set(gca,''ydir'',''normal''); **where n & p are the time and sweep indexes']; % the rotation of the image is comprised of fanadcp_off, adcp3val and % magnetic_variation, but that angle isn't captured in the attributes ncp.image_rotation_degrees=rot; % this is where the data is saved % writing to netCDF doesn't work, but you get a .mat file for each fan and % Pencil run if strcmpi(settings.SonartoAnimate,'fan'), t_all= ncp{'time'}(:)+ncp{'time2'}(:)./86400000; ncp.start_time = datestr(gregorian(t_all(1))); ncp.stop_time = datestr(gregorian(t_all(end))); % if time data is evenly spaced if length(t_all) > 1 & isempty(find(diff(diff(t_all))) ~= 0) ncp.DELTA_T = [num2str(gmean(diff(t_all))*24*60),' sec']; % time and time2 are EVEN by default else ncp{'time'}.type(:)='UNEVEN'; ncp{'time2'}.type(:)='UNEVEN'; ncp.DELTA_T = ['? sec']; end % close the writeable version close(ncp); ncclose; % re-open it read-only to return to matlab eval(['ncp=netcdf(''' ofproc ''');']) end % ---------------- Subfunction: readSonarMeta.m ------------------------- % function userMeta = readSonarMeta(metaFile); [atts, defs] = textread(metaFile,'%s %63c','commentstyle','shell'); defs = cellstr(defs); for i = 1:length(atts) theAtt = atts{i}(:)'; theDef = defs{i}(:)'; % deblank removes trailing whitespace theAtt = deblank(theAtt); theDef = deblank(theDef); % check for and replace spaces in % the attributes with underscores f1 = find(isspace(theAtt)); f2 = strfind(theAtt,'-'); f = union(f1,f2); if ~isempty(f) theAtt(f) = '_'; end % attribute definitions read in as characters; convert to % numbers where appropriate theDefNum = str2double(theDef); if ~isnan(theDefNum) theDef = theDefNum; end eval(['userMeta.',theAtt,'= theDef;']) end