findThermalLagParams

PURPOSE ^

FINDTHERMALLAGPARAMS Thermal lag parameter estimation for profiles.

SYNOPSIS ^

function [params, exitflag, residual] = findThermalLagParams(varargin)

DESCRIPTION ^

FINDTHERMALLAGPARAMS  Thermal lag parameter estimation for profiles.

  Syntax:
    PARAMS = FINDTHERMALLAGPARAMS(TIME1, COND1, TEMP1, PRES1, TIME2, COND2, TEMP2, PRES2)
    PARAMS = FINDTHERMALLAGPARAMS(TIME1, COND1, TEMP1, PRES1, FLOW1, TIME2, COND2, TEMP2, PRES2, FLOW2)
    PARAMS = FINDTHERMALLAGPARAMS(..., OPTIONS)
    PARAMS = FINDTHERMALLAGPARAMS(..., OPT1, VAL1, ...)
    [PARAMS, EXITFLAG, RESIDUAL] = FINDTHERMALLAGPARAMS(...)

    PARAMS = FINDTHERMALLAGPARAMS(TIME1, COND1, TEMP1, PRES1, TIME2, COND2, TEMP2, PRES2)
    finds the thermal lag parameters for two CTD profiles with constant flow
    speed (pumped CTD) given by sequences of time (s), conductivity (S/m), 
    temperature (deg C) and pressure (dbar) in respective vectors TIME1, COND1, 
    TEMP1 and PRES1, and TIME2, COND2, TEMP2 and PRES2. The profiles are 
    supposed to measure the same column of water in opposite directions.
    The computed parameters are returned in a two element vector PARAMS,
    with the error magnitude (alpha), and the error time constant (tau).
    A detailed description of these parameters may be found in the references
    listed below (Lueck 1990).

    Under the assumption that both profiles should be as similar as possible,
    the function solves the minimization problem of finding the thermal lag 
    parameters such that the area between profiles of temperature and salinity 
    is minimal; where salinity is derived from temperature, conductivity and 
    pressure sequences using SW_SALT with the corrected temperature sequence
    returned by CORRECTTHERMALLAG. This problem is solved by function FMINCON,
    using default values for the initial guess and the parameter bounds.
    See OPTIONS description below.

    PARAMS = FINDTHERMALLAGPARAMS(TIME1, COND1, TEMP1, PRES1, FLOW1, TIME2, DEPTH2, TEMP2, PRES2, FLOW2, ...)
    performs the same estimation but for a pair of CTD profiles with variable 
    flow speed (unpumped CTD), given by respective vectors FLOW1 and FLOW2.
    The estimated parameters are returned in a four element vector PARAMS,
    with the offset and the slope of the error magnitude (alpha_o and alpha_s)
    and the offset and the slope of the error time (tau_o and tau_s). Details
    on these parameters may be found in references below (Morison 1994).

    PARAMS = FINDTHERMALLAGPARAMS(..., OPTIONS) and 
    PARAMS = FINDTHERMALLAGPARAMS(..., OPT1, VAL1, ...) allow passing extra 
    options given in key-value pairs OPT1, VAL1... or in a struct OPTIONS with 
    field names as option keys and field values as option values.
    Recognized options are:
      GRAPHICS: whether graphic output should be produced.
        A boolean. If true a nice figure showing the minimization process will
        be displayed. It includes the parameter values, the objective function 
        value, a temperature-salinity diagram, a pressure-salinity diagram, 
        a temperature-time plot, and a conductivity-time plot.
        Default value: false.
      GUESS: initial guess for minimization function FMINCON.
        A two or four element vector with the initial guess for each parameter.
        Default value:
          For constant flow speed: [0.0677 11.1431] (see note below)
          For variable flow speed: [0.0135 0.0264 7.1499 2.7858] (Morison 1994)
      LOWER: lower bounds of parameters for minimization function FMINCON.
        A two or four element vector with the lower bound for each parameter.
        Default value:
          For constant flow speed: [0 0] (no correction)
          For variable flow speed: [0 0 0 0] (no correction)
      UPPER: upper bounds of parameters for minimization function FMINCON.
        A two or four element vector with the upper bound for each parameter.
        Default value:
          For constant flow speed: [4 2.5*RANGE(TIME1)]
          For variable flow speed: [2 1 RANGE(TIME1) RANGE(TIME1)/2]
      OPTIMOPTS: extra options for the minimization function FMINCON.
        An option struct as needed by the function FMINCON.
        Default value: default options for FMINCON, except for:
          'Algorithm': 'interior-point'
          'FinDiffType': 'central'
          'TolFun': 1e-4
          'TolCon': 1e-5
          'TolX': 1e-5
          'Display': 'off'

    [PARAMS, EXITFLAG, RESIDUAL] = FINDTHERMALLAGPARAMS(...) also returns the 
    exit code of the minimization function FMINCON in EXITFLAG, and the 
    residual area in RESIDUAL. EXITFLAG is positive when minimization succeeds.

  Notes:
    This function is an improved version of a previous function by Tomeu Garau,
    called ADJUSTTHERMALLAGPARAMS. He is the true glider man. Main changes are:
      - Support for CTD profiles with constant flow speed (pumped CTD).
      - Different minimization algorithm (interior-point instead of active-set).
      - Support for custom minimization options.
      - Optional predefined graphical output.

    It remains to be assessed that the parameters found minimize the area 
    between the corrected profiles globally, because the solver might look for
    local minimizers only.

    Parameters' initial guess values and bounds are taken from original 
    implementation. Since it did not handle constant flow speed profiles, 
    the values for this case has been set according to the same reference, 
    aproximating the constant CTD flow speed by v = 0.4867 m/s:
      alpha = 0.0135 + 0.0264 / 0.4867        =  0.0677
        tau = 7.1499 + 2.7858 / sqrt(11.1431) = 11.1431 
    The flow speed value is estimated from reported Seabird Glider Payload CTD 
    (GPCTD) specifications as:
      V = Q / U * L = 0.010 / 0.003 * 0.146 = 0.4867 m/s
    where:
      Q = 0.010 l/s is the flow rate.
      U = 0.003 l   is the cell volume.
      L = 0.146 m   is the cell length.

  References:
    Garau, B.; Ruiz, S.; G. Zhang, W.; Pascual, A.; Heslop, E.;
    Kerfoot, J.; and Tintoré, J.; 2011:
    Thermal Lag Correction on Slocum CTD Glider Data.
    Journal of Atmospheric and Oceanic Technology, vol. 28, pages 1065-1071.

    Morison, J.; Andersen, R.; Larson, N.; D'Asaro, E.; and Boyd, T.; 1994:
    The Correction for Thermal-Lag Effects in Sea-Bird CTD Data.
    Journal of Atmospheric and Oceanic Technology, vol. 11, pages 1151-1164.

    Lueck, R. G.; and Picklo, J. J.; 1990:
    Thermal Inertia of Conductivity Cells: Observations with a Sea-Bird cell.
    Journal of Atmospheric and Oceanic Technology, vol. 7, pages 756–768.

    Lueck, R. G.; 1990:
    Thermal Inertia of Conductivity Cells: Theory.
    Journal of Atmospheric and Oceanic Technology, vol. 7, pages 741–755.

  Examples:
    % Constant flow speed profiles (pumped CTD):
    data = load('private/test/ctd_pumped.dat');
    profile = data(:, 10);
    time1 = data(profile==1, 1);
    cond1 = data(profile==1, 2);
    temp1 = data(profile==1, 3);
    pres1 = data(profile==1, 4);
    time2 = data(profile==2, 1);
    cond2 = data(profile==2, 2);
    temp2 = data(profile==2, 3);
    pres2 = data(profile==2, 4);
    params = findThermalLagParams(time1, cond1, temp1, pres1, ...
                                  time2, cond2, temp2, pres2)

    % Variable flow speed profiles (unpumped CTD):
    data = load('private/test/ctd_unpumped.dat');
    profile = data(:, 10);
    time1 = data(profile==1, 1);
    cond1 = data(profile==1, 2);
    temp1 = data(profile==1, 3);
    pres1 = data(profile==1, 4);
    ptch1 = data(profile==1, 5);
    lati1 = data(profile==1, 8);
    dpth1 = sw_dpth(pres1, lati1);
    flow1 = computeCTDFlowSpeed(time1, dpth1, ptch1, 'minpitch', deg2rad(11));
    time2 = data(profile==2, 1);
    cond2 = data(profile==2, 2);
    temp2 = data(profile==2, 3);
    pres2 = data(profile==2, 4);
    ptch2 = data(profile==2, 5);
    lati2 = data(profile==2, 8);
    dpth2 = sw_dpth(pres2, lati2);
    flow2 = computeCTDFlowSpeed(time2, dpth2, ptch2, 'minpitch', deg2rad(11));
    params = findThermalLagParams(time1, cond1, temp1, pres1, flow1, ...
                                  time2, cond2, temp2, pres2, flow2)

    % Variable flow speed profiles with exit code, residual and extra options.
    [params, exitflag, residual] = ...
      findThermalLagParams(time1, cond1, temp1, pres1, flow1, ...
                           time2, cond2, temp2, pres2, flow2, ...
                           'graphics', 'true')

  See also:
    FMINCON
    OPTIMSET
    CORRECTTHERMALLAG
    SW_SALT
    SW_DENS
    COMPUTECTDFLOWSPEED

  Authors:
    Joan Pau Beltran  <joanpau.beltran@socib.cat>

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

DOWNLOAD ^

findThermalLagParams.m

SOURCE CODE ^

0001 function [params, exitflag, residual] = findThermalLagParams(varargin)
0002 %FINDTHERMALLAGPARAMS  Thermal lag parameter estimation for profiles.
0003 %
0004 %  Syntax:
0005 %    PARAMS = FINDTHERMALLAGPARAMS(TIME1, COND1, TEMP1, PRES1, TIME2, COND2, TEMP2, PRES2)
0006 %    PARAMS = FINDTHERMALLAGPARAMS(TIME1, COND1, TEMP1, PRES1, FLOW1, TIME2, COND2, TEMP2, PRES2, FLOW2)
0007 %    PARAMS = FINDTHERMALLAGPARAMS(..., OPTIONS)
0008 %    PARAMS = FINDTHERMALLAGPARAMS(..., OPT1, VAL1, ...)
0009 %    [PARAMS, EXITFLAG, RESIDUAL] = FINDTHERMALLAGPARAMS(...)
0010 %
0011 %    PARAMS = FINDTHERMALLAGPARAMS(TIME1, COND1, TEMP1, PRES1, TIME2, COND2, TEMP2, PRES2)
0012 %    finds the thermal lag parameters for two CTD profiles with constant flow
0013 %    speed (pumped CTD) given by sequences of time (s), conductivity (S/m),
0014 %    temperature (deg C) and pressure (dbar) in respective vectors TIME1, COND1,
0015 %    TEMP1 and PRES1, and TIME2, COND2, TEMP2 and PRES2. The profiles are
0016 %    supposed to measure the same column of water in opposite directions.
0017 %    The computed parameters are returned in a two element vector PARAMS,
0018 %    with the error magnitude (alpha), and the error time constant (tau).
0019 %    A detailed description of these parameters may be found in the references
0020 %    listed below (Lueck 1990).
0021 %
0022 %    Under the assumption that both profiles should be as similar as possible,
0023 %    the function solves the minimization problem of finding the thermal lag
0024 %    parameters such that the area between profiles of temperature and salinity
0025 %    is minimal; where salinity is derived from temperature, conductivity and
0026 %    pressure sequences using SW_SALT with the corrected temperature sequence
0027 %    returned by CORRECTTHERMALLAG. This problem is solved by function FMINCON,
0028 %    using default values for the initial guess and the parameter bounds.
0029 %    See OPTIONS description below.
0030 %
0031 %    PARAMS = FINDTHERMALLAGPARAMS(TIME1, COND1, TEMP1, PRES1, FLOW1, TIME2, DEPTH2, TEMP2, PRES2, FLOW2, ...)
0032 %    performs the same estimation but for a pair of CTD profiles with variable
0033 %    flow speed (unpumped CTD), given by respective vectors FLOW1 and FLOW2.
0034 %    The estimated parameters are returned in a four element vector PARAMS,
0035 %    with the offset and the slope of the error magnitude (alpha_o and alpha_s)
0036 %    and the offset and the slope of the error time (tau_o and tau_s). Details
0037 %    on these parameters may be found in references below (Morison 1994).
0038 %
0039 %    PARAMS = FINDTHERMALLAGPARAMS(..., OPTIONS) and
0040 %    PARAMS = FINDTHERMALLAGPARAMS(..., OPT1, VAL1, ...) allow passing extra
0041 %    options given in key-value pairs OPT1, VAL1... or in a struct OPTIONS with
0042 %    field names as option keys and field values as option values.
0043 %    Recognized options are:
0044 %      GRAPHICS: whether graphic output should be produced.
0045 %        A boolean. If true a nice figure showing the minimization process will
0046 %        be displayed. It includes the parameter values, the objective function
0047 %        value, a temperature-salinity diagram, a pressure-salinity diagram,
0048 %        a temperature-time plot, and a conductivity-time plot.
0049 %        Default value: false.
0050 %      GUESS: initial guess for minimization function FMINCON.
0051 %        A two or four element vector with the initial guess for each parameter.
0052 %        Default value:
0053 %          For constant flow speed: [0.0677 11.1431] (see note below)
0054 %          For variable flow speed: [0.0135 0.0264 7.1499 2.7858] (Morison 1994)
0055 %      LOWER: lower bounds of parameters for minimization function FMINCON.
0056 %        A two or four element vector with the lower bound for each parameter.
0057 %        Default value:
0058 %          For constant flow speed: [0 0] (no correction)
0059 %          For variable flow speed: [0 0 0 0] (no correction)
0060 %      UPPER: upper bounds of parameters for minimization function FMINCON.
0061 %        A two or four element vector with the upper bound for each parameter.
0062 %        Default value:
0063 %          For constant flow speed: [4 2.5*RANGE(TIME1)]
0064 %          For variable flow speed: [2 1 RANGE(TIME1) RANGE(TIME1)/2]
0065 %      OPTIMOPTS: extra options for the minimization function FMINCON.
0066 %        An option struct as needed by the function FMINCON.
0067 %        Default value: default options for FMINCON, except for:
0068 %          'Algorithm': 'interior-point'
0069 %          'FinDiffType': 'central'
0070 %          'TolFun': 1e-4
0071 %          'TolCon': 1e-5
0072 %          'TolX': 1e-5
0073 %          'Display': 'off'
0074 %
0075 %    [PARAMS, EXITFLAG, RESIDUAL] = FINDTHERMALLAGPARAMS(...) also returns the
0076 %    exit code of the minimization function FMINCON in EXITFLAG, and the
0077 %    residual area in RESIDUAL. EXITFLAG is positive when minimization succeeds.
0078 %
0079 %  Notes:
0080 %    This function is an improved version of a previous function by Tomeu Garau,
0081 %    called ADJUSTTHERMALLAGPARAMS. He is the true glider man. Main changes are:
0082 %      - Support for CTD profiles with constant flow speed (pumped CTD).
0083 %      - Different minimization algorithm (interior-point instead of active-set).
0084 %      - Support for custom minimization options.
0085 %      - Optional predefined graphical output.
0086 %
0087 %    It remains to be assessed that the parameters found minimize the area
0088 %    between the corrected profiles globally, because the solver might look for
0089 %    local minimizers only.
0090 %
0091 %    Parameters' initial guess values and bounds are taken from original
0092 %    implementation. Since it did not handle constant flow speed profiles,
0093 %    the values for this case has been set according to the same reference,
0094 %    aproximating the constant CTD flow speed by v = 0.4867 m/s:
0095 %      alpha = 0.0135 + 0.0264 / 0.4867        =  0.0677
0096 %        tau = 7.1499 + 2.7858 / sqrt(11.1431) = 11.1431
0097 %    The flow speed value is estimated from reported Seabird Glider Payload CTD
0098 %    (GPCTD) specifications as:
0099 %      V = Q / U * L = 0.010 / 0.003 * 0.146 = 0.4867 m/s
0100 %    where:
0101 %      Q = 0.010 l/s is the flow rate.
0102 %      U = 0.003 l   is the cell volume.
0103 %      L = 0.146 m   is the cell length.
0104 %
0105 %  References:
0106 %    Garau, B.; Ruiz, S.; G. Zhang, W.; Pascual, A.; Heslop, E.;
0107 %    Kerfoot, J.; and Tintoré, J.; 2011:
0108 %    Thermal Lag Correction on Slocum CTD Glider Data.
0109 %    Journal of Atmospheric and Oceanic Technology, vol. 28, pages 1065-1071.
0110 %
0111 %    Morison, J.; Andersen, R.; Larson, N.; D'Asaro, E.; and Boyd, T.; 1994:
0112 %    The Correction for Thermal-Lag Effects in Sea-Bird CTD Data.
0113 %    Journal of Atmospheric and Oceanic Technology, vol. 11, pages 1151-1164.
0114 %
0115 %    Lueck, R. G.; and Picklo, J. J.; 1990:
0116 %    Thermal Inertia of Conductivity Cells: Observations with a Sea-Bird cell.
0117 %    Journal of Atmospheric and Oceanic Technology, vol. 7, pages 756–768.
0118 %
0119 %    Lueck, R. G.; 1990:
0120 %    Thermal Inertia of Conductivity Cells: Theory.
0121 %    Journal of Atmospheric and Oceanic Technology, vol. 7, pages 741–755.
0122 %
0123 %  Examples:
0124 %    % Constant flow speed profiles (pumped CTD):
0125 %    data = load('private/test/ctd_pumped.dat');
0126 %    profile = data(:, 10);
0127 %    time1 = data(profile==1, 1);
0128 %    cond1 = data(profile==1, 2);
0129 %    temp1 = data(profile==1, 3);
0130 %    pres1 = data(profile==1, 4);
0131 %    time2 = data(profile==2, 1);
0132 %    cond2 = data(profile==2, 2);
0133 %    temp2 = data(profile==2, 3);
0134 %    pres2 = data(profile==2, 4);
0135 %    params = findThermalLagParams(time1, cond1, temp1, pres1, ...
0136 %                                  time2, cond2, temp2, pres2)
0137 %
0138 %    % Variable flow speed profiles (unpumped CTD):
0139 %    data = load('private/test/ctd_unpumped.dat');
0140 %    profile = data(:, 10);
0141 %    time1 = data(profile==1, 1);
0142 %    cond1 = data(profile==1, 2);
0143 %    temp1 = data(profile==1, 3);
0144 %    pres1 = data(profile==1, 4);
0145 %    ptch1 = data(profile==1, 5);
0146 %    lati1 = data(profile==1, 8);
0147 %    dpth1 = sw_dpth(pres1, lati1);
0148 %    flow1 = computeCTDFlowSpeed(time1, dpth1, ptch1, 'minpitch', deg2rad(11));
0149 %    time2 = data(profile==2, 1);
0150 %    cond2 = data(profile==2, 2);
0151 %    temp2 = data(profile==2, 3);
0152 %    pres2 = data(profile==2, 4);
0153 %    ptch2 = data(profile==2, 5);
0154 %    lati2 = data(profile==2, 8);
0155 %    dpth2 = sw_dpth(pres2, lati2);
0156 %    flow2 = computeCTDFlowSpeed(time2, dpth2, ptch2, 'minpitch', deg2rad(11));
0157 %    params = findThermalLagParams(time1, cond1, temp1, pres1, flow1, ...
0158 %                                  time2, cond2, temp2, pres2, flow2)
0159 %
0160 %    % Variable flow speed profiles with exit code, residual and extra options.
0161 %    [params, exitflag, residual] = ...
0162 %      findThermalLagParams(time1, cond1, temp1, pres1, flow1, ...
0163 %                           time2, cond2, temp2, pres2, flow2, ...
0164 %                           'graphics', 'true')
0165 %
0166 %  See also:
0167 %    FMINCON
0168 %    OPTIMSET
0169 %    CORRECTTHERMALLAG
0170 %    SW_SALT
0171 %    SW_DENS
0172 %    COMPUTECTDFLOWSPEED
0173 %
0174 %  Authors:
0175 %    Joan Pau Beltran  <joanpau.beltran@socib.cat>
0176 
0177 %  Copyright (C) 2013-2016
0178 %  ICTS SOCIB - Servei d'observacio i prediccio costaner de les Illes Balears
0179 %  <http://www.socib.es>
0180 %
0181 %  This program is free software: you can redistribute it and/or modify
0182 %  it under the terms of the GNU General Public License as published by
0183 %  the Free Software Foundation, either version 3 of the License, or
0184 %  (at your option) any later version.
0185 %
0186 %  This program is distributed in the hope that it will be useful,
0187 %  but WITHOUT ANY WARRANTY; without even the implied warranty of
0188 %  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0189 %  GNU General Public License for more details.
0190 %
0191 %  You should have received a copy of the GNU General Public License
0192 %  along with this program.  If not, see <http://www.gnu.org/licenses/>.
0193 
0194   error(nargchk(8, 20, nargin, 'struct'));
0195   
0196   
0197   %% Parse basic input arguments.
0198   % Get numeric (non-option) arguments.
0199   nargnum = find(~cellfun(@isnumeric, varargin), 1, 'first') - 1;
0200   if isempty(nargnum)
0201     nargnum = nargin;
0202   end
0203   switch(nargnum)
0204     case 8
0205       % Constant flow speed (pumped CTD).
0206       [time1, cond1, temp1, pres1] = varargin{1:4};
0207       [time2, cond2, temp2, pres2] = varargin{5:8};
0208       constant_flow = true;
0209     case 10
0210       % Variable flow speed (unpumped CTD).
0211       [time1, cond1, temp1, pres1, flow1] = varargin{1:5};
0212       [time2, cond2, temp2, pres2, flow2] = varargin{6:10};
0213       constant_flow = false;
0214   end
0215   
0216   
0217   %% Configure default options.
0218   % For the case of variable flow speed (unpumped CTD)
0219   % this is equivalent to the original version by Tomeu Garau,
0220   % except for the method (it was active-set).
0221   time_range = min(max(time1) - min(time1), max(time2) - min(time2));
0222   options.graphics = false;
0223   if constant_flow
0224     options.guess = [0.0677 11.1431]; % above parameters applied to GPCTD flow speed.
0225     options.lower = [0 0]; % no correction.
0226     options.upper = [4 2.5*time_range]; % above parameters applied to GPCTD flow speed.
0227   else
0228     options.guess = [0.0135 0.0264 7.1499 2.7858]; % from Morrison (1994).
0229     options.lower = [0 0 0 0]; % no correction.
0230     options.upper = [2 1 time_range time_range/2]; % from old version.
0231   end
0232   options.optimopts = optimset(optimset('fmincon'), ...
0233                                'Algorithm', 'interior-point', ...
0234                                'TolFun', 1e-4, 'TolCon', 1e-5, 'TolX', 1e-5, ...
0235                                'FinDiffType', 'central', ...
0236                                'Display', 'off');
0237   
0238   
0239   %% Parse option arguments.
0240   % Get option key-value pairs in any accepted call signature.
0241   argopts = varargin(nargnum+1:end);
0242   if isscalar(argopts) && isstruct(argopts{1})
0243     % Options passed as a single option struct argument:
0244     % field names are option keys and field values are option values.
0245     opt_key_list = fieldnames(argopts{1});
0246     opt_val_list = struct2cell(argopts{1});
0247   elseif mod(numel(argopts), 2) == 0
0248     % Options passed as key-value argument pairs.
0249     opt_key_list = argopts(1:2:end);
0250     opt_val_list = argopts(2:2:end);
0251   else
0252     error('glider_toolbox:findThermalLagParams:InvalidOptions', ...
0253           'Invalid optional arguments (neither key-value pairs nor struct).');
0254   end
0255   % Overwrite default options with values given in extra arguments.
0256   for opt_idx = 1:numel(opt_key_list)
0257     opt = lower(opt_key_list{opt_idx});
0258     val = opt_val_list{opt_idx};
0259     if isfield(options, opt)
0260       options.(opt) = val;
0261     else
0262       error('glider_toolbox:findThermalLagParams:InvalidOption', ...
0263             'Invalid option: %s.', opt);
0264     end
0265   end
0266   
0267   
0268   %% Enable graphical output, if needed.
0269   % The functions are defined below.
0270   if options.graphics
0271     if constant_flow
0272       [temp_cor1, cond_cor1] = ...
0273         correctThermalLag(time1, cond1, temp1, options.guess);
0274       [temp_cor2, cond_cor2] = ...
0275         correctThermalLag(time2, cond2, temp2, options.guess);
0276     else
0277       [temp_cor1, cond_cor1] = ...
0278         correctThermalLag(time1, cond1, temp1, flow1, options.guess);
0279       [temp_cor2, cond_cor2] = ...
0280         correctThermalLag(time2, cond2, temp2, flow2, options.guess);
0281     end
0282     salt_cor1 = sw_salt(cond1 * (10 / sw_c3515()), temp_cor1, pres1);
0283     salt_cor2 = sw_salt(cond2 * (10 / sw_c3515()), temp_cor2, pres2);
0284     salt1 = sw_salt(cond1 * (10 / sw_c3515()), temp1, pres1);
0285     salt2 = sw_salt(cond2 * (10 / sw_c3515()), temp2, pres2);
0286     options.optimopts.OutputFcn = @optimoutUpdateCorrectedData;
0287     options.optimopts.PlotFcns = ...
0288       {@optimplotx @optimplotfval ...
0289        @optimplotTempSalt @optimplotPresSalt ...
0290        @optimplotTempTime @optimplotCondTime};
0291   end
0292   
0293   
0294   %% Perform estimation through minimization.
0295   % Definition of minimization objective function.
0296   objective_function = @optimobjTSArea;
0297 
0298   % Run minimization procedure.
0299   [params, residual, exitflag] = ...
0300     fmincon(objective_function, options.guess, ...
0301             [], [], [], [], options.lower, options.upper, [], ...
0302             options.optimopts);
0303   
0304   
0305   %% Definition of auxiliary objective and plotting functions.
0306   % They should be nested to access cast data.
0307   function area = optimobjTSArea(params)
0308   %OPTIMOBJTSAREA Compute area enclosed by profiles in TS diagram.
0309     if constant_flow
0310       temp_cor1 = correctThermalLag(time1, cond1, temp1, params);
0311       temp_cor2 = correctThermalLag(time2, cond2, temp2, params);
0312     else
0313       temp_cor1 = correctThermalLag(time1, cond1, temp1, flow1, params);
0314       temp_cor2 = correctThermalLag(time2, cond2, temp2, flow2, params);
0315     end
0316     salt_cor1 = sw_salt(cond1 * (10 / sw_c3515()), temp_cor1, pres1);
0317     salt_cor2 = sw_salt(cond2 * (10 / sw_c3515()), temp_cor2, pres2);
0318     dens_cor1 = sw_dens(salt_cor1, temp1, pres1);
0319     dens_cor2 = sw_dens(salt_cor2, temp2, pres2);
0320     dens_min = max(min(dens_cor1), min(dens_cor2));
0321     dens_max = min(max(dens_cor1), max(dens_cor2));
0322     dens_mask1 = (dens_min <= dens_cor1) & (dens_cor1 <= dens_max);
0323     dens_mask2 = (dens_min <= dens_cor2) & (dens_cor2 <= dens_max);
0324     min_idx1 = find(dens_mask1, 1, 'first');
0325     min_idx2 = find(dens_mask2, 1, 'first');
0326     max_idx1 = find(dens_mask1, 1, 'last');
0327     max_idx2 = find(dens_mask2, 1, 'last');
0328     area = ...
0329       profileArea(salt_cor1(min_idx1:max_idx1), temp1(min_idx1:max_idx1), ...
0330                   salt_cor2(min_idx2:max_idx2), temp2(min_idx2:max_idx2));
0331   end
0332   
0333   function stop = optimoutUpdateCorrectedData(params, ~, state)
0334   %OPTIMOUTUPDATEPLOTDATA  Update corrected data sequences.
0335     switch state
0336       case 'init'
0337       case 'iter'
0338         if constant_flow
0339           [temp_cor1, cond_cor1] = ...
0340             correctThermalLag(time1, cond1, temp1, params);
0341           [temp_cor2, cond_cor2] = ...
0342             correctThermalLag(time2, cond2, temp2, params);
0343         else
0344           [temp_cor1, cond_cor1] = ...
0345             correctThermalLag(time1, cond1, temp1, flow1, params);
0346           [temp_cor2, cond_cor2] = ...
0347             correctThermalLag(time2, cond2, temp2, flow2, params);
0348         end
0349         salt_cor1 = sw_salt(cond1 * (10 / sw_c3515()), temp_cor1, pres1);
0350         salt_cor2 = sw_salt(cond2 * (10 / sw_c3515()), temp_cor2, pres2);
0351       case 'interrupt'
0352       case 'done'
0353     end
0354     stop = false;
0355   end
0356   
0357   % Temperature-salinity diagram.
0358   function stop = optimplotTempSalt(~, ~, state)
0359   %OPTIMPLOTTEMPSALT  Temperature-salinity diagram for pair of casts.
0360     switch state
0361       case 'init'
0362       case 'iter'
0363         valid_cor1 = ~(isnan(salt_cor1) | isnan(temp1));
0364         valid_cor2 = ~(isnan(salt_cor2) | isnan(temp2));
0365         valid1 = ~(isnan(salt1) | isnan(temp1));
0366         valid2 = ~(isnan(salt2) | isnan(temp2));
0367         plot(salt1(valid1), temp1(valid1), ':r', ...
0368              salt2(valid2), temp2(valid2), ':b', ...
0369              salt_cor1(valid_cor1), temp1(valid_cor1), '-r', ...
0370              salt_cor2(valid_cor2), temp2(valid_cor2), '-b');
0371         title('Temperature-Salinity diagram');
0372         xlabel('Salinity');
0373         ylabel('Temperature');
0374       case 'interrupt'
0375       case 'done'
0376     end
0377     stop = false;
0378   end
0379   
0380   % Pressure-salinity diagram.
0381   function stop = optimplotPresSalt(~, ~, state)
0382   %OPTIMPLOTPRESSALT  Pressure-salinity diagram for pair of casts.
0383     switch state
0384       case 'init'
0385       case 'iter'
0386         valid_cor1 = ~(isnan(salt_cor1) | isnan(pres1));
0387         valid_cor2 = ~(isnan(salt_cor2) | isnan(pres2));
0388         valid1 = ~(isnan(salt1) | isnan(pres1));
0389         valid2 = ~(isnan(salt2) | isnan(pres2));
0390         plot(salt1(valid1), pres1(valid1), ':r', ...
0391              salt2(valid2), pres2(valid2), ':b', ...
0392              salt_cor1(valid_cor1), pres1(valid_cor1), '-r', ...
0393              salt_cor2(valid_cor2), pres2(valid_cor2), '-b');
0394         title('Pressure-Salinity diagram');
0395         xlabel('Salinity');
0396         ylabel('Pressure');
0397         set(gca, 'YDir', 'reverse')
0398       case 'interrupt'
0399       case 'done'
0400     end
0401     stop = false;
0402   end
0403   
0404   % Temperature-time diagram.
0405   function stop = optimplotTempTime(~, ~, state)
0406   %OPTIMPLOTTEMPTIME  Temperature-time diagram for pair of casts.
0407     switch state
0408       case 'init'
0409       case 'iter'
0410         valid_cor1 = (time1 > 0) & ~isnan(temp_cor1);
0411         valid_cor2 = (time2 > 0) & ~isnan(temp_cor2);
0412         valid1 = (time1 > 0) & ~isnan(temp1);
0413         valid2 = (time2 > 0) & ~isnan(temp2);
0414         time_offset = min(min(time1(valid1)), min(time2(valid2)));
0415         plot(time1(valid1) - time_offset, temp1(valid1), ':r', ...
0416              time2(valid2) - time_offset, temp2(valid2), ':b', ...
0417              time1(valid_cor1) - time_offset, temp_cor1(valid_cor1), '-r', ...
0418              time2(valid_cor2) - time_offset, temp_cor2(valid_cor2), '-b');
0419         title('Temperature-Time diagram');
0420         xlabel('Time');
0421         ylabel('Temperature');
0422       case 'interrupt'
0423       case 'done'
0424     end
0425     stop = false;
0426   end
0427   
0428   % Conductivity-time diagram.
0429   function stop = optimplotCondTime(~, ~, state)
0430   %OPTIMPLOTCONDTIME  Conductivity-time diagram for pair of casts.
0431     switch state
0432       case 'init'
0433       case 'iter'
0434         valid_cor1 = (time1 > 0) & ~isnan(cond_cor1);
0435         valid_cor2 = (time2 > 0) & ~isnan(cond_cor2);
0436         valid1 = (time1 > 0) & ~isnan(cond1);
0437         valid2 = (time2 > 0) & ~isnan(cond2);
0438         time_offset = min(min(time1(valid1)), min(time2(valid2)));
0439         plot(time1(valid1) - time_offset, cond1(valid1), ':r', ...
0440              time2(valid2) - time_offset, cond2(valid2), ':b', ...
0441              time1(valid_cor1) - time_offset, cond_cor1(valid_cor1), '-r', ...
0442              time2(valid_cor2) - time_offset, cond_cor2(valid_cor2), '-b');     
0443         title('Conductivity-Time diagram');
0444         xlabel('Time');
0445         ylabel('Conductivity');
0446       case 'interrupt'
0447       case 'done'
0448     end
0449     stop = false;
0450   end
0451   
0452 end

Generated on Fri 06-Oct-2017 10:47:42 by m2html © 2005