function [imagedata, headangle, prange] = showpencil(fname, datayear); % % function [imagedata, headangle, prange] = showpencil(fname, datayear); % % display Imagenex Pencil Beam Sonar images taken with Robin Singer's data logger % % fname = file name % datayear = the year the data was taken % imagedata = the image as [angle, point] % headangle = the head position in degrees % prange = profile range in cm % % Written by Marinna Martini 8/28/02 % for the U.S. Geological Survey, WOods Hole Field Center % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Use of this program is self described. % Program written in Matlab v7.1.0 SP3 % Program ran on PC with Windows XP Professional OS. % % "Although this program has been used by the USGS, no warranty, % expressed or implied, is made by the USGS or the United States % Government as to the accuracy and functioning of the program % and related program material nor shall the fact of distribution % constitute any such warranty, and no responsibility is assumed % by the USGS in connection therewith." %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % if exist('fname') ~= 1, [fname, fpath] = uigetfile('*.p*','Pencil beam data'); else fpath = []; end if 0, if exist('datayear') ~= 1, prompt = {'Enter the year the data was recorded:'}; windowtitle = 'Missing data'; lines= 1; def = {'2003'}; answer = inputdlg(prompt,windowtitle,lines,def); datayear = str2num(answer{1}); end end datayear = 2002; disp('assuming we are in the year 2002, if not, use the command line call') fid = fopen([fpath, fname],'r'); if fid == -1, disp(['error reading file ',fpath, fname]); return else disp(['Now reading file ', fpath, fname]); end % standard filename format is S1MMDDHH.PMM = S1082715.p30 gdate = [datayear str2num(fname(3:4)) str2num(fname(5:6)) str2num(fname(7:8)) str2num(fname(11:12)) 0]; jdate = julian(gdate); nheaderbytes = 13; % skip the 61 bytes of file header [fheader, numread] = fread(fid,61,'uchar'); % decipher the first 13 bytes of sonar header so we know what we are reading [sheader, numread] = fread(fid,nheaderbytes,'uchar'); disp('The header') sheader' % imagenex return data header will tell us the total number of return data bytes % conver the first three bytes into an ASCII string return_data_header = char(sheader(1:3,:))'; disp(sprintf('Return Data Header = %s',return_data_header)); head_ID = dec2hex(sheader(4)); disp(sprintf('Header ID = %s',head_ID)) % we can skip the serial status for now % head position headposhi = bitand(63,sheader(7)); headposlo = bitand(127,sheader(6)); headpos = headposhi*127+headposlo; stepdir = bitget(sheader(7),6); % translate from 0 to 2800 meaning -210 to 210 in 0.15 degree steps headangle = 0.15*(headpos-1400); disp(sprintf('Head angle = %f', headangle)) % sonar head range sonar_head_range = sheader(8); disp(sprintf('Sonar Head Range setting = %d m',sonar_head_range)); % profile range prangehi = bitand(127,sheader(10)); prangelo = bitand(127,sheader(9)); prange = prangehi*127+prangelo; disp(sprintf('First Digitized Range Value Above Threshold = %d cm', prange)) % Number of echo data bytes returned ndatabyteshi = bitand(127,sheader(12)); ndatabyteslo = bitand(127,sheader(11)); ndatabytes = ndatabyteshi*127+ndatabyteslo; disp(sprintf('Number of data bytes = %d', ndatabytes)) % given the header info, figure out how many data point we're dealing with % the number of data bits is hardwired to 8 in the logger source code (new_bits) ndatabits = 8; switch(return_data_header), case {'IMX'}, % switch data command for data points = 25 if ndatabits == 4, nreturnbytes = 141; end % 128 Data Byes, 256 Points if ndatabits == 8, nreturnbytes = 265; end % 252 Data Byes, 252 Points if ndatabits == 14, nreturnbytes = 513; end % 500 Data Byes, 250 Points case {'IGX'}, % switch data command for data points = 50 if ndatabits == 4, nreturnbytes = 265; % 252 Data Byes, 504 Points else nreturnbytes = 513; % 500 Data Byes, 500 Points % 500 Data Byes, 250 Points end case {'IQX'}, % there is no IQX for the pencil beam sonar case {'IPX'}, % Profile = ON nreturnbytes = 13; % 0 Data Byes, 0 Points end disp(sprintf('Number of return bytes per ping = %d',nreturnbytes)); npoints = nreturnbytes - nheaderbytes; % now figure out how many pings of data are in this file from the file size and header info. % 61 bytes of file header fseek(fid,0,'bof'); filebeg = ftell(fid); fseek(fid,0,'eof'); % go to the end of the file filebytes = ftell(fid)-filebeg-118; % byte from beginning of file npings = round(filebytes./nreturnbytes); disp(sprintf('Number of useable pings = %d (maybe)',npings)) frewind(fid); % skip the 61 bytes of file header [fheader, numread] = fread(fid,61,'uchar'); % guess at a dataholdersize imagedata = zeros(npings, nreturnbytes-nheaderbytes); headangle = zeros(npings, 1); prange = zeros(npings,1); pingidx = 0; while 1, pingstart = ftell(fid); if pingstart < 0, break; end pingidx = pingidx+1; % read header [sheader, numread] = fread(fid,nheaderbytes,'uchar'); if numread < nheaderbytes, break; end % grab the position % head position headposhi = bitand(63,sheader(7)); headposlo = bitand(127,sheader(6)); headpos = headposhi*127+headposlo; stepdir = bitget(sheader(7),6); % translate from 0 to 2800 meaning -210 to 210 in 0.15 degree steps headangle(pingidx) = 0.15*(headpos-1400); % profile range prangehi = bitand(127,sheader(10)); prangelo = bitand(127,sheader(9)); prange(pingidx) = prangehi*127+prangelo; % read image data [pingdata, numread] = fread(fid,nreturnbytes-nheaderbytes,'uint8'); if numread < nreturnbytes-nheaderbytes, break; end imagedata(pingidx,:) = pingdata'; end fclose(fid); [npings, npoints] = size(imagedata); headangle = headangle(1:npings); % trim it if there's an extra point prange = prange(1:npings); % plot linear figure clf; imagesc(headangle,0:(sonar_head_range/npoints):sonar_head_range,imagedata') colormap(jet); colorbar ylabel('Range, meters') xlabel('Head Position, degrees') title(['Fan beam image taken ',datestr(datenum(gdate))]) % plot headposition and prange figure [ax, h1, h2] = plotyy(1:npings,headangle,1:npings,prange); title(['Fan beam image taken ',datestr(datenum(gdate))]) xlabel('Head position and profile range by ping') ylabel('Deg')