function [ctd,varlabel,names,sensors]=ctd_rd(cnv_file,FMT);
% CTD_RD Reads the SeaBird ASCII .CNV file format
%
%  Usage:   CTD=ctd_rd(cnv_file);
%
%     Input:  cnv_file = name of .CNV file  (e.g. 'cast002.cnv')
%
%     Output: CTD - a data structure containing the CTD data and header info.
%
%  There are various formats possible for time/location information.
%  Some of these can be handled with an optional second input parameter:
%           CTD=ctd_rd(cnv_file,FORMAT)
%
%  where FORMAT = 'NMEA'  for SEASAVE output with GPS included through deckbox
%
%                          * System UpLoad Time = Oct 10 1999  18:20:32
%                          * NMEA Latitude = 48 36.69 N
%                          * NMEA Longitude = 123 13.07 W
%                          * NMEA UTC (Time) = Oct 10 1999  18:20:32
%
%                 'IR'    for an internally recording mode with a hand-typed
%                         header in this form:
%                         
%                          ** Latitude = 49 21.092 N
%                          ** Longitude = 121 49.028 W
%                          ** PST (Time) =Nov 23 2000 07:45
%
%                         will also work with SEASAVE output if no
%                         GPS NMEA string available.
%                         (default mode)
%
%                         If no '** Time' line gets it from System Upload Time
%
%                 'RP'    Ignore any header data but decode System Upload Time for
%                         the year, and the 'cast' line (DH command) for time -
%                         good for IR mode when to-yo-ing or otherwise too lazy
%                         to create proper headers.
%
%                 'LAB'   for a mode with no NMEA or header data (i.e. lab
%                         testing)
%
%  Add more lat,lon and date string handling if your .CNV files are different.
%

%  4-8-98  Rich Signell (rsignell@usgs.gov)  
%     incorporates ideas from code by Derek Fong & Peter Brickley
%  19-9-99 R. pawlowicz (ric@ocgy.ubc.ca)
%      - added a lot more decoding plus the idea of a data stucture for output
%  12-6-00 Changes variable names slightly.
%  19-2-02 dms as well as dmm.mm formats
%  20-5-11 modified by Rowan Fox (ro1@uvic.ca), adding in model #, temp
%  sensor SN # & cond sensor SN

%
% To be compatible with the older program, assumes the btl data structure
% looks like this:
%
% btl
%    station: 0
%       cast: 1
%        lat: 30.1833
%        lon: -80.1200
%      gtime: [2007 3 23 17 22 29]
%    sensors: [8x90 char]
%       tcor: 0
%       pcor: 0
%      names: {19x1 cell}
%       data: [24x19 double]
%
% and names and data are in a specific order and/or have specific names.
% For now I've made sure the .btl file has the variables in the correct
% order:  
%   'bottle_ros_position'
%    'date' (as a numeric datenum vector)
%    'pot_temp_pri'
%    'pot_temp_sec'
%    'sal_pri_pri'
%    'sal_sec_sec'
%    'sbedo2_mll_pri'
%    'sbedo2_mll_sec'
%    'scan'
%    'time_sec'
%    'depth_sw'
%    'pressure'
%    't90_pri'
%    't90_sec'
%    'con_pri'
%    'con_sec'
%    'sbeox_volt_pri'
%    'sbeox_volt_sec'
%    'altimeter'
%
% btl.data appears in this order.
%

if nargin==1,
 FMT='IR';
end;

ctd.name='ctd';
ctd.station='';

[pathstr,this_name,ext] = fileparts(cnv_file);
clear temp_sta;
temp_sta = str2num(this_name(findstr('_',this_name)+1:end));
if exist('temp_sta')
    ctd.station = temp_sta;
else
    ctd.station = 999.;
end
ctd.cast = 0;
ctd.pcor = 0;
ctd.tcor = 0;


% Open the .cnv file as read-only text

if isempty(findstr(lower(cnv_file),'.btl')),
  cnv_file=[cnv_file '.btl'];
end;
  
fid=fopen(cnv_file,'r');

fprintf(1,'Loading file %s\n', cnv_file)

% Read the header.
% Stop at line that starts with '*END*'

str='*START*';
str=fgetl(fid);
while (strncmp(str,'#',1) | strncmp(str,'*',1));
  
    
    switch FMT
        case 'NMEA'
            if (strncmp(str,'* NMEA Lat',10))
                lat=get_lat(str);
            elseif (strncmp(str,'* NMEA Lon',10))
                lon=get_lon(str);
            elseif (strncmp(str,'* NMEA UTC',10))
                gtime=get_timestamp(str);
                tzone='UTC';
            end;

        case 'IR',
            if any(findstr(str,'Latitude')) | any(findstr(str,'Lat'))
                lat=get_lat(str);
            elseif any(findstr(str,'Longitude')) | any(findstr(str,'Long'))
                lon=get_lon(str);
	    
            %    Read the  TIME string.  This may vary with CTD setup. Will need
            %      ** xxxxxxxxxxTimexxxx = 21 Dec 2005 hh:mm:ss
            %     where timezone may also be in there somewhere.
   
            elseif strncmp(str,'**',2) & any(findstr(str,'Time')),
                gtime=get_timestamp(str);
                tzone='unknown';
                if any(findstr(str,'PST')),
                    tzone='PST';
                elseif any(findstr(str,'PDT')),
                    tzone='PDT';
                elseif any(findstr(str,'UTC')),
                    tzone='UTC';
                elseif any(findstr(str,'EST')),
                    tzone='EST';
                elseif any(findstr(str,'EDT')),
                    tzone='EDT';
                end;  
            % The default - get a time from the 'upload' string (usually the other time
            % strings are later in the file so they will overwrite this, if they exist).	
            elseif (strncmp(str,'* System UpLoad',15)),
                tzone='unknown';
                gtime=get_timestamp(str);
            end;	
        
        case 'LAB',  	
       
            lat=0;lon=0;tzone='unknown';
  
            if (strncmp(str,'* System UpLoad',15)),
                tzone='unknown';
                gtime=get_timestamp(str);
            end;
	
        case 'RP',  
      	
            lat=0;lon=0;tzone='unknown';

            if (strncmp(str,'* System UpLoad',15))
                is=findstr(str,'=');
                % EXTRACT THE UPLOAD YEAR FOR CAST START TIME Roger 2003sep04
                upyearstr=str(is+9:is+12);
            end;

            %-------------------------------------------------------------------
            % READ CAST START TIME, SAMPLE RATE, COMPUTE mtime Roger 2003sep04
            % * cast 0  06/23  17:38:06   samples 0 to 1334 sample rate = 1 scan every 0.5 seconds
            if (strncmp(str,'* cast ',7))
                %Find slash
                indslash=find(str=='/');
                indcolon=find(str==':');

                if length(indslash)==1 & length(indcolon)>=2
                    datstr=[upyearstr ' '...
                      str(indslash-2:indslash-1) ' ' ...
                      str(indslash+1:indslash+2) ' ' ...
                      str(indcolon(1)-2:indcolon(1)-1) ' '...
                      str(indcolon(1)+1:indcolon(2)-1) ' '...
                      str(indcolon(2)+1:indcolon(2)+2)];
                    mtime=datenum(str2num(datstr));
                    gtime=datevec(mtime);
                    fprintf('Date from CAST START TIME in timezone of SBE clock\n');
                else
                    error('ERROR: CAST START TIME: str does not have expected form')
                end;

            end

            %
        otherwise,
            error('Unrecognized format specifier');
    end;
    
    %-----------------------------
    %
    % Read the ctd model from a comment line
    %
    if (strncmp(str,'* Sea-Bird',10)),
        ctd.model=str(findstr(str,'Sea-Bird SBE ')+13:findstr(str,' Data File')-1);
    %-----------------------------
    %
    % Read the ctd temperature sensor SN from a comment line
    %
    elseif (strncmp(str,'* Temperature SN = ',19)),
        ctd.tempsn=str(findstr(str,'* Temperature SN = ')+19:end);
    %-----------------------------
    %
    % Read the ctd conductivity sensor SN from a comment line
    %
    elseif (strncmp(str,'* Conductivity SN = ',20)),
        ctd.condsn=str(findstr(str,'* Conductivity SN = ')+20:end);
        
    %-----------------------------
    %
    % Read the depth from a comment line
    %
     
    elseif (strncmp(lower(str),'** depth',8)),
        idelim=findstr(str,':');
        ctd.depth=sscanf(str(idelim+1:end),'%f');
	if isempty(ctd.depth) 
        ctd.depth=NaN; 
    end;
	% Units?
	strrem=str(idelim+1:end);strrem(strrem>=48 & strrem<=57)=' ';
	if any(findstr(str(idelim+1:end),' m')),
	   % OK
	elseif any(findstr(str(idelim+1:end),' ft')) ,
	   ctd.depth=ctd.depth*0.3048;
	end;    

    %------------------------------
    %
    % Get sampling interval
    %
    elseif (strncmp(str,'# interval',10)),
       ctd.samp_interval=sscanf(str(findstr(str,':')+1:end),'%f');
	
    %------------------------------
    %
    %    Read the sensor names into a cell array
    %
    elseif (strncmp(str,'# sensor',8))  
        sens=sscanf(str(10:11),'%d',1);
        sensors{sens+1}=str;
    %------------------------------
    %
    %    Read the sensor ranges into a cell array
    %
    elseif (strncmp(str,'# span',6))  
        sens=sscanf(str(8:9),'%d',1);
        ctd.spans{sens+1}=sscanf(str(findstr(str,'=')+1:end),'%f,%f');
    %
    %  pick up bad flag value
    elseif (strncmp(str,'# bad_flag',10))  
        isub=13:length(str);
        bad_flag=sscanf(str(isub),'%g',1);
    %------------------------------
    %
    %    Read the sensor calibration coefficients into a cell array
    %
    elseif any(findstr(str,'Oxygen, SBE 43 -->'))
        str=fgetl(fid);
        str=fgetl(fid);
        % contains serial number between first ">" and second ">"        
        ox(1).serial = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%d');
        str=fgetl(fid); str=fgetl(fid); str=fgetl(fid); str=fgetl(fid);
        str=fgetl(fid); str=fgetl(fid); str=fgetl(fid); str=fgetl(fid);
        str=fgetl(fid); str=fgetl(fid); str=fgetl(fid); str=fgetl(fid);
        str=fgetl(fid); str=fgetl(fid);
        % contains SOC.  Following lines are coeffiecients for new Seabird
        ox(1).Soc = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(1).offset = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(1).A = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(1).B = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(1).C = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(1).D0 = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(1).D1 = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(1).D2 = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(1).E = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(1).Tau20 = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(1).H1 = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(1).H2 = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(1).H3 = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
    elseif any(findstr(str,'Oxygen, SBE 43, 2 -->'))
        str=fgetl(fid);
        str=fgetl(fid);
        % contains serial number between first ">" and second ">"        
        ox(2).serial = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%d');
        str=fgetl(fid); str=fgetl(fid); str=fgetl(fid); str=fgetl(fid);
        str=fgetl(fid); str=fgetl(fid); str=fgetl(fid); str=fgetl(fid);
        str=fgetl(fid); str=fgetl(fid); str=fgetl(fid); str=fgetl(fid);
        str=fgetl(fid); str=fgetl(fid);
        % contains SOC.  Following lines are coeffiecients for new Seabird
        ox(2).Soc = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(2).offset = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(2).A = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(2).B = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(2).C = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(2).D0 = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(2).D1 = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(2).D2 = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(2).E = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(2).Tau20 = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(2).H1 = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(2).H2 = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
        str=fgetl(fid);
        ox(2).H3 = sscanf(str(min(findstr(str,'>'))+1:max(findstr(str,'<'))-1),'%f');
    end
    
    % read ahead the next string
    str=fgetl(fid);
end

if exist('ox','var')
    ctd.ox = ox;
end
%==============================================
%  Done reading header.  Now read the first line of the data!
%------------------------------
%
%    Read the variable names & units into a cell array
%
% BTL header looks like:
%    Bottle        Date Potemp090C Potemp190C      Sal00      Sal11 Sbeox0ML/L Sbeox1ML/L       Scan       PrDM      T090C      T190C    Sbeox0V    Sbeox1V    C0mS/cm    C1mS/cm      Sal00      Sal11      TimeY
var=textscan(str,'%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s','ReturnOnError');
% get rid of empty variable names
nvars = 0;
for II = 1 : length(var)
    if ~isempty(var{II})
        nvars = nvars + 1;
        ctd.names{nvars} = strrep(char(var{II}), '/', '');      
    end
end
str=fgetl(fid); % gets junk header on next line.
ctd.names = ctd.names(:);

%
% Get rid of junk characters is variable labels
%

    
% Read the data into one big matrix
% Reads bottle data two lines at a time
num_bottles = 0;
while 1
    str = fgetl(fid);
    if ~ischar(str), break, end
    num_bottles = num_bottles + 1;
    bottle_num(num_bottles) = sscanf(str,'%f');
    bottle_data(num_bottles,:) = sscanf(str(23:end),'%f',nvars-2);
    next_str = fgetl(fid);
    bottle_date(num_bottles) = datenum([str(12:22) ' ' next_str(15:22)]);
end
data = [bottle_num(:) bottle_date(:) bottle_data];
ctd.data = data;

if exist('sensors'), ctd.sensors=char(sensors); end;

ctd.lat=lat;
ctd.lon=lon;
ctd.gtime=gtime;
ctd.time=bottle_date;
ctd.mtime=datenum(gtime(1),gtime(2),gtime(3),gtime(4),gtime(5),gtime(6));
ctd.tzone=tzone;

eval(['ctd.' ctd.names{1} '= ctd.data(:,1);']);
for k = 3 : length(ctd.names)
    eval(['ctd.' ctd.names{k} '= ctd.data(:,k);']);
end;
 
return

%---------------------------------------------------
function lon=get_lon(str);
% decodes latitude from input string

% Get delimiter - '=' or ':'
is=findstr(str,'=');
if isempty(is), is=findstr(str,':'); end;


isub=is+1:length(str);
dm=sscanf(str(isub),'%f');

% E or W
if(findstr(str(isub),'E')); sigl=1; else sigl=-1; end;

% dd.ddd or dd mm.mmm or dd mm ss formats
switch (length(dm)),
case 1,
   lon=sigl*dm;
case 2,   	
   lon=sigl*(dm(1)+dm(2)/60);
case 3,  
   lon=sigl*(dm(1)+dm(2)/60+dm(3)/3600);
otherwise,
   lon=NaN;
   disp(['Can''t scan string ->' str '<- for longitude']);    
end
 
return;

%---------------------------------------------------
function lat=get_lat(str);
% decodes latitude from input string

% Get delimiter - '=' or ':'
is=findstr(str,'=');
if isempty(is), is=findstr(str,':'); end;


isub=is+1:length(str);
dm=sscanf(str(isub),'%f');

% N or S
if(findstr(str(isub),'N')); sigl=1; else sigl=-1; end;

% dd.ddd or dd mm.mmm or dd mm ss formats
switch (length(dm)),
case 1,
   lat=sigl*dm;
case 2,   	
   lat=sigl*(dm(1)+dm(2)/60);
case 3,  
   lat=sigl*(dm(1)+dm(2)/60+dm(3)/3600);
otherwise,
   lat=NaN;
   disp(['Can''t scan string ->' str '<- for longitude']);    
end
 
return;
%--------------------------------------------------
function gtime=get_timestamp(str);
% Decodes time string

% Time to right of '='
idelim=findstr(str,'=');
if any(idelim),
   str=str(idelim+1:end);
else   % try a colon delimiter
 idelim=findstr(str,':');
 if any(idelim),
    str=str(idelim(1)+1:end);
 end;
end;
     
% is there hh:mm:ss in there?
is=findstr(str,':');
if any(is),
  isub=is(1)-2:length(str);
  
  % Date in   Dec 21 2005 format
  nbl=find(str(1:is(1)-3)~=' ');
  datstr=str(min(nbl):max(nbl));
  ibl=findstr(datstr,' ');
  if length(ibl)==2,
    % Write into 21-Dec-2001 format which matlab can decode
    datstr=[datstr(ibl(1)+1:ibl(2)-1) '-' datstr(1:ibl(1)-1) '-' datstr(ibl(2)+1:end)];
    if ibl(2)-ibl(1)==2,
      datstr=['0' datstr];
    end; 
    gtime=datevec(datstr);
    % Add hh:mm:ss
    if length(is)==1,
      gtime([4:5])=sscanf(str(isub),'%d:%2d');
    elseif length(is)==2,
      gtime([4:6])=sscanf(str(isub),'%d:%2d:%2d');
    else
      disp(['Can''t scan string ->' str '<- for time of day']);    
      gtime=[0 0 0 0 0 0];
    end; 
  else
    disp(['Can''t scan string ->' str '<- for day of year']);    
   gtime=[0 0 0 0 0 0];
  end; 
else
    disp(['Can''t scan string ->' str '<- for time of day']);    
   gtime=[0 0 0 0 0 0];
end; 




