% function cal = get_float_cals(MBARI_ID_str, dirs)
% PURPOSE:
%   This function tries to parse all the calibration data for the
%   biogoechemical sensors on a given float from a *FloatConfig.txt file
%   and from a *cal nitrate file if it exists. If a sensor is detected in
%   the config or cal text files a stucture field with calibration data
%   will be created.
%   FUNCTION ASSUMES ONLY ONE SENSOR TYPE PER FLOAT (no good for 3xO2 floats)
%
% USAGE:
%	data = get_float_cals(MBARI_ID_str, dirs)
%
% INPUTS:
%   MBARI_ID_str  = MBARI Float ID as a string
%   dirs       = Either an empty variable or a structure with directory
%                strings where files are located. It must contain these
%                fields at a minimum or be empty. If dirs is empty default
%                paths will be used.
%
%   dirs.cal       = path to *.cal (nitrate) and cal####.mat (working float cal) files
%   dirs.temp      = path to temporary working dir
%
% OUTPUTS:
%       cal =   a structure of calibration info. Structure fields change
%               depending on the sensors detectd in the cal file and float
%               type (APEX or NAVIS).
%
%       cal.O       Oxygen calibration coefficients
%                   (Aanderaa 3830&4330, SBE63)
%       cal.CHL     biooptics calibration coefficients (FLBBAP2 or MCOMS
%       cal.BB      biooptics calibration coefficients (FLBBAP2 or MCOMS
%       cal.CDOM    biooptics calibration coefficients (FLBBAP2 or MCOMS
%       cal.pH   	Durafet pH calibration coefficients
%       cal.N   	ISUS or SUNA calibration coefficients
%
%       cal.info    float information (WMO ID#, UW/MBARI ID#,
%                                      FILE CREATION DATE, ETC)
%
% REQUIRES: MBARI_float_list.m
%
% EXAMPLES:
%   jp = get_float_cals('ua8501S', dirs)
%   jp = get_float_cals('ua8501S', [])
%


% ************************************************************************
% FOR TESTING
dirs =[];
dirs='/Users/Mau/Documents/MBARIprojects/w_ctd/cpf/Test_files/CPF003/TankTests/2021-8-11T20-6-55';
MBARI_ID_str = 'CPF003';

% ************************************************************************
% SET DIRECTORY AND VARIABLES
% ************************************************************************
%INST_ID_str  = regexp(MBARI_ID_str,'^\d+','once','match');
config_file  = [MBARI_ID_str,'_FloatConfig.txt'];
NO3_calfile  = [MBARI_ID_str, '.cal'];
%master_list  = 'new_MBARI_float_list.mat';
master_list  = 'MBARI_float_list.mat';

% **** DEFAULT STRUCTURE FOR DIRECTORY PATHS ****
if isempty(dirs)
    user_dir = getenv('USERPROFILE'); %returns user path,i.e. 'C:\Users\jplant'
    user_dir = [user_dir, '\Documents\MATLAB\ARGO_PROCESSING\DATA\'];
    dirs.cal        = [user_dir,'CAL\']; % save created lists here
    dirs.MasterDir  = [dirs.cal,'FLOAT_CONFIG\']; % MBARI master list source
    dirs.msg        = '\\seaecho.shore.mbari.org\floats\';
    dirs.bfile      = [getenv('USERPROFILE'),'\Documents\MATLAB\ARGO_MBARI2AOML\'];
    dirs.temp      = 'C:\temp\';
elseif ~isstruct(dirs)
    disp('Check "dirs" input. Must be an empty variable or a structure')
    return
end

info.WMO_ID     = '';
info.file_date  = datestr(now,'mm/dd/yyyy HH:MM');
info.float_type = '';

disp(['Building calibration file for ',MBARI_ID_str]);

% ************************************************************************
% PARSE CONFIG FILE TO GET OXYGEN CALIBRATION COEFFICIENTS
% Examples of OptodeSn output:
% 'OptodeSn = 737'                   (Aanderaa 3830 older)
% 'OptodeSn = 4330 1168'             (Aanderaa 4330 newer)
% 'OptodeSn = SBE63 rev J S/N 0455'  (Seabird 63)
% ************************************************************************
info.O2_flag    = 0;
tline = ' ';% initialize some variables
fid   = fopen([dirs.cal,'FLOAT_CONFIG\', config_file]);
if fid == -1
    disp(['Could not open *.txt config file for ',MBARI_ID_str])
    cal = [];
    return
end

while ischar(tline)
    if regexp(tline,'OptodeSn =','once') % APEX
        optode_info = regexp(tline, '\d+', 'match'); % parse any numbers from SN line
        break
    elseif regexp(tline,'^O2 sensor','once') % NAVIS SBE63 or SBE83
        optode_info = regexp(tline,'(?<=\()\w+|\w+(?=\))','match');
        break
    end
    tline = fgetl(fid);
    
end

if ~ischar(tline) % -1 (end of file reached - no O2)
    disp(['NO oxygen sensor detected for float ',MBARI_ID_str])
    
    % NEWER STYLE AANDERAA OXYGEN CALIBRATION FORMAT (4330)    p02 = f(Phase)
elseif length(optode_info) == 2 && strcmp(optode_info{1},'4330')
    info.O2_flag = 1;
    O.type       = optode_info{1};
    O.SN         = optode_info{2};
    disp(['Aanderaa oxygen optode detected (', ...
        O.type,' SN: ',O.SN,')'])
    while tline ~= -1 % EXTRACT COEFFICIENTS
        % comments at end stop searching
        if ~isempty(regexp(tline,'^COMMENTS:', 'once'))
            break
        end
        
        if ~isempty(regexp(tline,'PhaseCoef','once'))
            ind = regexp(tline,'PhaseCoef\s+\d+\s+\d+\s+','once','end');
            O.PCoef = sscanf(tline(ind:end),'%f',4);
        end
        
        if ~isempty(regexp(tline,'FoilCoefA','once'))
            ind = regexp(tline,'FoilCoefA\s+\d+\s+\d+\s+','once','end');
            FCoefA = sscanf(tline(ind:end),'%f',14);
        end
        
        if ~isempty(regexp(tline,'FoilCoefB','once'))
            ind = regexp(tline,'FoilCoefB\s+\d+\s+\d+\s+','once','end');
            FCoefB = sscanf(tline(ind:end),'%f',14);
        end
        
        if ~isempty(regexp(tline,'FoilPolyDegT','once'))
            ind = regexp(tline,'FoilPolyDegT\s+\d+\s+\d+\s+','once','end');
            O.PolyDegT = sscanf(tline(ind:end),'%f',28);
        end
        
        if ~isempty(regexp(tline,'FoilPolyDegO','once'))
            ind = regexp(tline,'FoilPolyDegO\s+\d+\s+\d+\s+','once','end');
            O.PolyDegO = sscanf(tline(ind:end),'%f',28);
        end
        
        if ~isempty(regexp(tline,'SVUFoilCoef','once'))
            ind = regexp(tline,'SVUFoilCoef\s+\d+\s+\d+\s+','once','end');
            SVU = sscanf(tline(ind:end),'%f',7);
            if sum(SVU(:)) ~= 0
                O.SVUFoilCoef = SVU;
            end
        end
        
        if ~isempty(regexp(tline,'ConcCoef','once'))
            ind = regexp(tline,'ConcCoef\s+\d+\s+\d+\s+','once','end');
            O.ConcCoef = sscanf(tline(ind:end),'%f',2);
        end
        
        tline = fgetl(fid);
    end
    O.FCoef =[FCoefA;FCoefB];
    t1 = O.FCoef == 0; % Look for zero & remove to shorten calc, 0 * x = 0
    O.FCoef(t1)    = [];
    O.PolyDegT(t1) = [];
    O.PolyDegO(t1) = [];
    
    clear FCoefA FCoefB opt_info ind t1
    
    % ************************************************************************
    % NAVIS SBE63 / SBE83 OXYGEN CALIBRATION FORMAT
elseif length(optode_info) == 2 && strncmp(optode_info{1},'SBE63',3)
    info.O2_flag = 1;
    O.type       = optode_info{1};
    O.SN         = optode_info{2};
    disp(['SBE oxygen optode detected (', O.type,' SN: ',O.SN,')'])
    
    while ischar(tline)
        if regexp(tline,'^O2 sensor.+Temp coefficents', 'once')
            TC = regexp(tline,',','split');
            O.TempCoef = str2double(TC(2:end)); % TA0-3
        elseif regexp(tline,'^O2 sensor.+Phase coefficents', 'once')
            PC = regexp(tline,',','split');
            O.PhaseCoef = str2double(PC(2:end)); % TA0-3
        end
        tline =fgetl(fid);
    end
    clear TC PC
    % ************************************************************************
    % OLD STYLE AANDERAA OXYGEN CALIBRATION FORMAT (3830)    02 = f(Phase)
elseif length(optode_info) == 1 % NO senser type just S/N
    info.O2_flag = 1;
    
    info.O2_flag = 1;
    O.type       = '3830';
    O.SN         = optode_info{1};
    disp(['Aanderaa oxygen optode detected (', O.type,' SN: ',O.SN,')'])
    coef = textscan(fid,'%s %*s %f'); %{1}= ID, {2}= value
    %BUILD COEFF ARRAYS for POLYVAL
    coef_srch = {'C0', 'C1', 'C2', 'C3', 'C4', 'P'};
    
    for i = 1:length(coef_srch) % build coeff arrays with eval
        % Aanderaa = ascending powers
        ind1 = find(strncmp(coef_srch{i},coef{1},length(coef_srch{i})));
        ind1 = sort(ind1,'descend')'; % Matlab needs descending powers
        O.(['p',coef_srch{i}]) = coef{1,2}(ind1);
    end
    
    clear coef_format coef_path coef_srch calfile ind1 i opt_info
    
end

if info.O2_flag == 1
    cal.O = O;
else
    disp(['Can not determine oxygen optode type for ', MBARI_ID_str])
end
