AOML_MASTER_BOTTLE_FILE - Create a master bottle file from the .bot files in a given directory. USAGE: [bottle_struct] = aoml_master_bottle_file(prefix); [bottle_struct] = aoml_master_bottle_file(prefix,inputDirectory); [bottle_struct] = aoml_master_bottle_file(prefix,inputDirectory,excludeStations); [bottle_struct] = aoml_master_bottle_file(prefix,inputDirectory,excludeStations,outDir); INPUT: in_vars: prefix = is a string representing the file naming convention. It is assumed that all files to be processed are similarly named according to the convention, prefix####.btl or .BTL. There can be any number of #s representing the station number. inputDir = string containing the path to the directory in which the .btl and .bot files reside. excludeStations = vector contining the station numbers to exclude outputDir = string containing the path to the directory in which the output file will be written. OUTPUT: out_vars: bottle_struct = Structure containing all the bottle information in the .btl and .bot files in the input directory. Fieldnames will correspond to the sensor types written on the first noncomment line in the .btl files. BUGS: 1. The prefix is case sensitive but the suffix (.btl or .BTL) is not. NOTE: TO BE DONE: VERSION: 0.1 AUTHOR: Derrick Snowden Derrick.Snowden@noaa.gov NOAA/AOML/PhOD Based on the program read_sbecnv.m from the www.mathtools.net Geographics and Oceanographics page. which was written by Rich Signell. rsignell@usgs.gov CALLER: User DEPENDENCIES:
0001 function [bottle_struct] = aoml_master_bottle_file(varargin) 0002 % AOML_MASTER_BOTTLE_FILE - Create a master bottle file from the .bot files in a given directory. 0003 % 0004 % USAGE: 0005 % [bottle_struct] = aoml_master_bottle_file(prefix); 0006 % [bottle_struct] = aoml_master_bottle_file(prefix,inputDirectory); 0007 % [bottle_struct] = aoml_master_bottle_file(prefix,inputDirectory,excludeStations); 0008 % [bottle_struct] = aoml_master_bottle_file(prefix,inputDirectory,excludeStations,outDir); 0009 % 0010 % INPUT: 0011 % in_vars: 0012 % prefix = is a string representing the file naming convention. 0013 % It is assumed that all files to be processed are 0014 % similarly named according to the convention, 0015 % prefix####.btl or .BTL. There can be any number of #s representing the station number. 0016 % inputDir = string containing the path to the directory in which the .btl and .bot files reside. 0017 % excludeStations = vector contining the station numbers to exclude 0018 % outputDir = string containing the path to the directory in which the output file will be written. 0019 % 0020 % OUTPUT: 0021 % out_vars: bottle_struct = Structure containing all the bottle information in the .btl and 0022 % .bot files in the input directory. Fieldnames will correspond to the 0023 % sensor types written on the first noncomment line in the .btl files. 0024 % 0025 % 0026 % 0027 % BUGS: 0028 % 1. The prefix is case sensitive but the suffix (.btl or .BTL) is not. 0029 % NOTE: 0030 % 0031 % TO BE DONE: 0032 % 0033 % 0034 % VERSION: 0.1 0035 % 0036 % AUTHOR: Derrick Snowden 0037 % Derrick.Snowden@noaa.gov 0038 % NOAA/AOML/PhOD 0039 % Based on the program read_sbecnv.m from the 0040 % www.mathtools.net Geographics and Oceanographics page. 0041 % which was written by Rich Signell. rsignell@usgs.gov 0042 % CALLER: User 0043 % 0044 % DEPENDENCIES: 0045 0046 0047 0048 % Check the input arguments 0049 if (nargin == 0) 0050 print_error('Must include a prefix for the input btl file naming convention'); 0051 0052 elseif (nargin == 1) 0053 if (ischar(varargin{1})) 0054 prefix = varargin{1}; 0055 inputDir = './'; 0056 excludeStations = []; 0057 outputDir = inputDir; 0058 else 0059 print_error('Input prefix not a character variable'); 0060 end 0061 elseif (nargin == 2) 0062 if (ischar(varargin{1})) & (ischar(varargin{2})) 0063 prefix = varargin{1}; 0064 inputDir = varargin{2}; 0065 excludeStations = []; 0066 outputDir = inputDir; 0067 else 0068 print_error('Input prefix or directory is not a character variable.'); 0069 end 0070 elseif (nargin == 3) 0071 if (ischar(varargin{1})) & (ischar(varargin{2})) & (isnumeric(varargin{3})) 0072 prefix = varargin{1}; 0073 inputDir = varargin{2}; 0074 excludeStations = varargin{3}; 0075 outputDir = inputDir; 0076 else 0077 print_error('Input prefix or directory is not a character variable or excludeStations not a numeric vector'); 0078 end 0079 elseif (nargin == 4) 0080 if (ischar(varargin{1})) & (ischar(varargin{2})) & (isnumeric(varargin{3})) & (ischar(varargin{4})) 0081 prefix = varargin{1}; 0082 inputDir = varargin{2}; 0083 excludeStations = varargin{3}; 0084 outputDir = varargin{4}; 0085 else 0086 print_error('Input prefix or i/o directorys are not character variables or excludeStations not a numeric vector'); 0087 end 0088 else 0089 disp([mfilename,' error: Incorrect number of inputs.']); 0090 help aoml_master_bottle_file 0091 return 0092 end 0093 0094 0095 0096 % See how many .btl files are in the given directory. 0097 % Try to assemble a list of unique filenames regardless of case (btl or BTL) 0098 if (inputDir(end) ~= '/' | inputDir(end) ~= '\' | prefix(1) ~= '/' | prefix(1) ~= '\') 0099 inputDir 0100 lowercase = dir([inputDir,'/',prefix,'*.btl']); 0101 uppercase = dir([inputDir,'/',prefix,'*.BTL']); 0102 else 0103 lowercase = dir([inputDir,prefix,'*.btl']); 0104 uppercase = dir([inputDir,prefix,'*.BTL']); 0105 end 0106 identical = []; 0107 btlFileNames = {}; 0108 % Make sure the capitalized suffixes actually represent different files 0109 if length(lowercase) == 0 & length(uppercase) == 0 0110 print_error([' No .btl or .BTL files found in ',inputDir]); 0111 end 0112 if length(lowercase) == 0 & length(uppercase) ~= 0 0113 btlFileNames = cellstr(strcat(inputDir,strvcat(uppercase.name))); 0114 elseif length(lowercase) ~= 0 & length(uppercase) == 0 0115 btlFileNames = cellstr(strcat(inputDir,strvcat(lowercase.name))); 0116 else % don't make any assumptions. Check every name for duplicates 0117 % A duplicate name will be any name that is identical except for case. 0118 % If there is even one character different between two similar names then 0119 % the names will be considered distinct. 0120 for i = 1:length(lowercase) 0121 for j = 1: length(uppercase) 0122 rootIndex = findstr(lowercase(i).name,'.'); 0123 rootLC = lowercase(i).name(1:rootIndex-1); 0124 rootIndex = findstr(uppercase(i).name,'.'); 0125 rootUC = uppercase(j).name(1:rootIndex-1); 0126 if strcmpi(rootLC,rootUC) %1 => identical except for case 0127 if (lowercase(i).size == uppercase(j).size) 0128 % Names are identical except for case and sizes are identical 0129 % so they are the same file. Ignore one of them 0130 identical = [identical ; j]; 0131 end 0132 end 0133 end 0134 end 0135 if (length(identical) ~= length(uppercase)) 0136 if (length(identical) ~= 0) 0137 % Those files in uppercse not flagged as identical 0138 uniqueIndex = setdiff([1:length(uppercase)],identical); 0139 else 0140 uniqueIndex = [1:length(uppercase)]; 0141 end 0142 btlFileNames = cellstr(strvcat(strcat(inputDir,strvcat(lowercase.name)),... 0143 strcat(inputDir,strvcat(uppercase(uniqueIndex).name)))); 0144 else 0145 btlFileNames = cellstr(strcat(inputDir,strvcat(lowercase.name))); 0146 end 0147 btlFileNames = {inputDir,btlFileNames}; 0148 end 0149 0150 % Step through the input files and open them in turn. 0151 btlFileNames = sort(btlFileNames); %Hopefully this sorts by station number if 0152 % everything else works correctly. 0153 for i = 1:length(btlFileNames) 0154 0155 % Open the .btl files as read-only text 0156 % 0157 fid=fopen(btlFileNames{i},'rt'); 0158 if fid == -1 0159 print_error(['Error opening ',btlFileNames{i}]); 0160 end 0161 % 0162 % Read the header. 0163 % Start reading header lines of .CNV file, 0164 % Stop at line that starts with '*END*' 0165 % 0166 % Pull out NMEA lat & lon along the way and look 0167 % at the '# name' fields to see how many variables we have. 0168 % 0169 str='*START*'; 0170 while (~strncmp(str,' Bottle',10)); 0171 str=fgetl(fid); 0172 %----------------------------------- 0173 % 0174 % Read latitude string. This may vary with CTD setup. 0175 % 0176 if (strncmp(str,'** Latitude',11)) 0177 is=findstr(str,':'); 0178 isub=is+1:length(str); %Index of susbstring 0179 dm=sscanf(str(isub),'%f',2); 0180 if(findstr(str(isub),'N')); 0181 lat=dm(1)+dm(2)/60; 0182 else 0183 lat=-(dm(1)+dm(2)/60); 0184 end 0185 0186 %------------------------------- 0187 % 0188 % Read the longitude string. This may vary with CTD setup. 0189 % 0190 elseif (strncmp(str,'** Longitude',12)) 0191 is=findstr(str,':'); 0192 isub=is+1:length(str); 0193 dm=sscanf(str(isub),'%f',2); 0194 if(findstr(str(isub),'E')); 0195 lon=dm(1)+dm(2)/60; 0196 else 0197 lon=-(dm(1)+dm(2)/60); 0198 end 0199 0200 0201 %------------------------ 0202 % 0203 % Read the 'System upload time' to get the date. 0204 % This may vary with CTD setup. 0205 % 0206 % I'm reading this in to get the date, since the NMEA time string 0207 % does not contain date. Unfortunately, the system upload time is 0208 % in local time (here, EST), so I need to convert to UTC by adding 0209 % 5 hours (5/24 days). 0210 % 0211 elseif (strncmp(str,'* System UpLoad',15)) 0212 is=findstr(str,'='); 0213 % pick apart date string and reassemble in DATEFORM type 0 form 0214 datstr=[str(is+6:is+7) '-' str(is+2:is+4) '-' str(is+9:is+12)]; 0215 datstr=[datstr ' ' str(is+14:is+21)]; 0216 % convert datstr to Julian time, add 5 hours to convert from EST to GMT 0217 n=datenum(datstr)+5/24; 0218 gtime=datevec(n); 0219 % %---------------------------- 0220 % % 0221 % % Read the NMEA TIME string. This may vary with CTD setup. 0222 % % 0223 % % replace the System upload time with the NMEA time 0224 % elseif (strncmp(str,'* NMEA UTC',10)) 0225 % is=findstr(str,':'); 0226 % isub=is(1)-2:length(str); 0227 % gtime([4:6])=sscanf(str(isub),'%2d:%2d:%2d'); 0228 %------------------------------ 0229 % 0230 % Read the variable names & units into a cell array 0231 % 0232 % elseif (strncmp(str,'# name',6)) 0233 % var=sscanf(str(7:10),'%d',1); 0234 % var=var+1; % .CNV file counts from 0, Matlab counts from 1 0235 % % stuff variable names into cell array 0236 % names{var}=str; 0237 %------------------------------ 0238 % 0239 % Read the sensor names into a cell array 0240 % 0241 elseif (strncmp(str,'# sensor',8)) 0242 sens=sscanf(str(10:11),'%d',1); 0243 sens=sens+1; % .CNV file counts from 0, Matlab counts from 1 0244 % stuff sensor names into cell array 0245 sensors{sens}=str; 0246 % 0247 % pick up bad flag value 0248 % elseif (strncmp(str,'# bad_flag',10)) 0249 % isub=13:length(str); 0250 % bad_flag=sscanf(str(isub),'%g',1); 0251 end 0252 end 0253 %============================================== 0254 % 0255 % Done reading header. Now read the data! 0256 % 0257 nvars=var; %number of variables 0258 0259 % Read the data into one big matrix 0260 % 0261 data=fscanf(fid,'%f',[nvars inf]); 0262 0263 fclose(fid); 0264 0265 % 0266 % Flag bad values with nan 0267 % 0268 ind=find(data==bad_flag); 0269 data(ind)=data(ind)*nan; 0270 0271 % 0272 % Flip data around so that each variable is a column 0273 data=data.'; 0274 0275 % Convert cell arrays of names to character matrices 0276 names=char(names); 0277 sensors=char(sensors); 0278 0279 end %End looping through the input files btlFileNames 0280 return 0281 0282 0283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0284 % Subfunctions 0285 function [] = print_error(error_message); 0286 disp('aoml_master_bottle_file error error:') 0287 error(error_message); 0288 return 0289 0290