Home > src > sosttest.m

# sosttest

## PURPOSE

- object for creating t-tests

## SYNOPSIS

This is a script file.

## DESCRIPTION

     - object for creating t-tests

     copyright 2009-2012 Blair Armstrong, Christine Watson, David Plaut

        This file is part of SOS

        SOS is free software: you can redistribute it and/or modify
        it for academic and non-commercial purposes
        under the terms of the GNU General Public License as published by
        the Free Software Foundation, either version 3 of the License, or
        (at your option) any later version.  For commercial or for-profit
        uses, please contact the authors (sos@cnbc.cmu.edu).

        SOS is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

## CROSS-REFERENCE INFORMATION

This function calls:

- genericStatTest - parent class for statistical test objects
- sosttest - object for creating t-tests
- verbosePrint - master print function that regulates cmd line output based on verbosity flags

This function is called by:

- genericStatTest - parent class for statistical test objects
- sosttest - object for creating t-tests

## SUBFUNCTIONS

- function obj = sosttest(varargin)
- function [userHypothesis, prob, label] = runTest(obj,varargin)
- function [userHypothesis, prob, label] =
- function [userHypothesis, prob, label] =
- function [userHypothesis, prob, label] =
- function constructIndependentSamplettest(obj,sosObj,varargin)
- function constructPairedSamplettest(obj,sosObj,varargin)
- function constructSingleSamplettest(obj,sosObj,varargin)
- function userHypothesis = returnNaN(~,~)
- function flag = validTestType(str)

## SOURCE CODE

    0001 % - object for creating t-tests
    0002 %
    0003 % copyright 2009-2012 Blair Armstrong, Christine Watson, David Plaut
    0004 %
    0005 %    This file is part of SOS
    0006 %
    0007 %    SOS is free software: you can redistribute it and/or modify
    0008 %    it for academic and non-commercial purposes
    0009 %    under the terms of the GNU General Public License as published by
    0010 %    the Free Software Foundation, either version 3 of the License, or
    0011 %    (at your option) any later version.  For commercial or for-profit
    0012 %    uses, please contact the authors (sos@cnbc.cmu.edu).
    0013 %
    0014 %    SOS is distributed in the hope that it will be useful,
    0015 %    but WITHOUT ANY WARRANTY; without even the implied warranty of
    0016 %    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    0017 %    GNU General Public License for more details.
    0018
    0019 %    You should have received a copy of the GNU General Public License
    0020 %    along with SOS (see COPYING.txt).
    0021 %    If not, see <http://www.gnu.org/licenses/>.
    0022
    0023 classdef sosttest < genericStatTest
    0024     % runs user-specified t-tests and tests user hypotheses on their outcomes
    0025     %
    0026     %PROPERTIES
    0027     %     sosObj % sos object the test is associated with
    0028     %     name % string label to associate with the test
    0029     %     s1 % sample1
    0030     %     s2 % sample2
    0031     %     s1ColName % column name of data in sample1
    0032     %     s2ColName % column name of data in sample2
    0033     %     s1Col   % column index in sample1
    0034     %     s2Col   % column index in sample2
    0035     %     type    % type of ttest (paired,independent,
    0036     %     runSpecificTest % handle to specific test method
    0037     %     desiredpvalCondition % indicates the desired outcome of the test, either NaN, <= or >=
    0038     %     desiredpvalConditionHandle  % handle to the function that will evaluate whether the desiredpValCondition was met
    0039     %     desiredpval % desired p-val to test against
    0040     %     targValue % target value for single-sample ttest
    0041     %     tail % tail of test.  left -> t-vals < 0, right = t-vals > 0; both = pos. and neg. t will reject the null
    0042     %     lastp % last p-value that was calcualted
    0043     %     thresh % threshold between two means being compared that, if below, causes the test to pass regardless of the p-value
    0044     %
    0045     %METHODS:
    0046     %   sosttest(sosObj,varargin)  %constructs an sosttest object of the specified type.
    0047     %   constructIndependentSamplettest(obj,sosObj,varargin)  %initialize an independent samples t-test object.
    0048     %   constructPairedSamplettest(obj,sosObj,varargin)  %initialize a paired samples t-test object
    0049     %   constructSingleSamplettest(obj,sosObj,varargin) %initialize a single sample t-test object
    0050     %   [userHypothesis, prob, label] = runTest(obj,varargin) %runs the ttest
    0051     %   [userHypothesis, prob, label] =  runIndependentSamplettest(obj,varargin) %runs an independent sample ttest.  Assumes equal variance
    0052     %   [userHypothesis, prob, label] = runPairedSamplettest(obj,varargin)  %runs a paired sample ttest
    0053     %   [userHypothesis, prob, label] =  runSingleSamplettest(obj,varargin)  %runs a single sample ttest
    0054     %
    0055     %METHODS (Static)
    0056     %    userHypothesis = returnNaN(~,~)  % returns NaN
    0057     %   flag = validTestType(str) % returns 1 if the name of type of test is 'single', 'paired',  or 'independent'; error otherwise.
    0058
    0059
    0060     %% PROPERTIES
    0061     properties
    0062         sosObj % sos object the test is associated with
    0063         name % string label to associate with the test
    0064         s1 % sample1
    0065         s2 % sample2
    0066         s1ColName % column name of data in sample1
    0067         s2ColName % column name of data in sample2
    0068         s1Col   % column index in sample1
    0069         s2Col   % column index in sample2
    0070         type    % type of ttest (paired,independent,
    0071         runSpecificTest % handle to specific test method
    0072         desiredpvalCondition % indicates the desired outcome of the test, either NaN, <= or >=
    0073         desiredpvalConditionHandle  % handle to the function that will evaluate whether the desiredpValCondition was met
    0074         desiredpval % desired p-val to test against
    0075         targValue % target value for single-sample ttest
    0076         tail % tail of test.  left -> t-vals < 0, right = t-vals > 0; both = pos. and neg. t will reject the null
    0077         lastp % last p-value that was calcualted
    0078         label % label denoting what is being tested
    0079         thresh % threshold between two means being compared that, if below, causes the test to pass regardless of the p-value
    0080     end % properties
    0081
    0082     methods
    0083
    0084         %% sosttest CONSTRUCTOR
    0085         function obj = sosttest(varargin)
    0086             %constructs an sosttest object of the specified type.
    0087             %
    0088             %PARAMETERS:
    0089             % sosObj - sosObject test will be associated with
    0090             % 'type'/string, type of ttest - either 'paired', 'independent', or 'single'
    0091             % 'sample1'/sample - a sample associated with sosObj.
    0092             % 'thresh'/numeric - % threshold between two means being
    0093             % compared that, if below, causes the test to pass regardless of the p-value
    0094             %
    0095             % ... Other parameters as required by the constructor for the
    0096             % specific type of t-test requested.  See those constructors
    0097             % for additional info.
    0098             %
    0099             % Returns an sosttest object.
    0100
    0101           %  varargin = varargin{1};
    0102
    0103             % perform basic checks for universally required components of
    0104             % the t-test
    0105             p = inputParser;
    0106             p.addParamValue('sosObj', 'null',...
    0107                 @(sosObj)strcmp(class(sosObj),'sos'));
    0108             p.addParamValue('type','null', ...
    0109                 @(type)sosttest.validTestType(type));
    0110             p.addParamValue('sample1','null', ...
    0111                             @(sample1)strcmp(class(sample1),'sample'));
    0112             p.addParamValue('name','noname',@(name)ischar(name));
    0113
    0114
    0115             %keep all of the parameters for specific t-tests
    0116             p.KeepUnmatched = true;
    0117             p.parse(varargin{:});
    0118
    0119
    0120
    0121             %basic checks are passed, construct the specific type of t-test
    0122             %that has been requested
    0123
    0124             sosObj = p.Results.sosObj; %#ok<PROP>
    0125
    0126             if(strcmp(p.Results.type,'independent'))
    0127                 obj.constructIndependentSamplettest(sosObj,varargin{:}) %#ok<PROP>
    0128             elseif(strcmp(p.Results.type,'paired'))
    0129                 obj.constructPairedSamplettest(sosObj,varargin{:}); %#ok<PROP>
    0130             elseif strcmp(p.Results.type,'single')
    0131                 obj.constructSingleSamplettest(sosObj,varargin{:}); %#ok<PROP>
    0132             else
    0133                error(['Specified <type>: ',p.Results.type, ...
    0134                         ' is not supported']);
    0135             end
    0136
    0137             obj.lastp = NaN;
    0138             obj.sosObj = p.Results.sosObj;
    0139
    0140
    0141             % add the test's name.
    0142             if any(strcmp(p.UsingDefaults,'name'))
    0143
    0144                  numTests = length(obj.sosObj.sosstattests);
    0145
    0146
    0147              obj.name = ['ttest_',num2str(numTests+1)];
    0148              else
    0149                  obj.name = p.Results.name;
    0150              end
    0151
    0152         end % Constructor
    0153
    0154
    0155         %% [userHypothesis, prob, label] = runTest(obj,varargin) METHOD
    0156         function [userHypothesis, prob, label] = runTest(obj,varargin)
    0157             %runs the ttest
    0158             %
    0159             % PARAMETERS:
    0160             % 'reportStyle'/'short'|'full'/'none' - style of report to be
    0161             %           printed.  Either none, short or full
    0162             %
    0163             % RETURNS:
    0164             %   userHypothesis - whether the user's hypothesis has been met or not. NaN if no user hypothesis for the test.
    0165             %   prob - p-value from the ttest
    0166             %   label - string label denoting what was tested.
    0167
    0168             [userHypothesis, prob, label] = obj.runSpecificTest(varargin);
    0169
    0170             obj.lastp = prob;
    0171         end
    0172
    0173         %% [userHypothesis, prob, label] =  runIndependentSamplettest(varargin) METHOD
    0174         function [userHypothesis, prob, label] = ...
    0175                 runIndependentSamplettest(obj,varargin)
    0176             %runs an independent sample ttest.  Assumes equal variance
    0177             %
    0178             % PARAMETERS:
    0179             % 'reportStyle'/'short'|'full' - style of report to be printed.  Either short or long
    0180             %
    0181             % RETURNS:
    0182             %   userHypothesis - whether the user's hypothesis has been met or not. NaN if no user hypothesis for the test.
    0183             %   prob - p-value from the ttest
    0184             %   label - string label denoting what was tested.
    0185
    0186
    0187             varargin = varargin{1};
    0188
    0189             p = inputParser;
    0190
    0191             p.addParamValue('reportStyle','short', ...
    0192                     @(reportStyle)any([strcmp(reportStyle,'short') ...
    0193                                     strcmp(reportStyle,'full') ...
    0194                                     strcmp(reportStyle,'none')]));
    0195             p.parse(varargin{:});
    0196
    0197
    0198             reportStyle = p.Results.reportStyle;
    0199
    0200
    0201             % Make sure that the samples have been filled before running
    0202             % the actual test, otherwise generate an error
    0203             if isempty(obj.s1.data) || length(obj.s1.data{obj.s1Col}) ~= obj.s1.n
    0204                 error('sample 1 has not been filled.  Aborting stat test.');
    0205             end
    0206             if isempty(obj.s2.data) || length(obj.s2.data{obj.s1Col}) ~= obj.s2.n
    0207                 error('sample 2 has not been filled.  Aborting stat test.');
    0208             end
    0209
    0210             [h,prob,ci,stats] = ttest2(obj.s1.data{obj.s1Col},...
    0211                                    obj.s2.data{obj.s2Col},...
    0212                                 0.05,obj.tail,'equal');       %#ok<ASGLU>
    0213
    0214             % if prob was NaN, it's because the denominator in the t-test
    0215             % was 0.  So just check the means manually to determine
    0216             % prob
    0217             if isnan(prob)
    0218              m1 = mean(obj.s1.data{obj.s1Col});
    0219              m2 = mean(obj.s2.data{obj.s2Col});
    0220
    0221              if m1==m2
    0222                  prob = 1;
    0223              else
    0224                  prob = 0;
    0225              end
    0226
    0227             end
    0228
    0229             userHypothesis = obj.desiredpvalConditionHandle(...
    0230                                   prob,obj.desiredpval);
    0231
    0232
    0233              m1 = mean(obj.s1.data{obj.s1Col});
    0234              m2 = mean(obj.s2.data{obj.s2Col});
    0235
    0236              stderr1 = std(obj.s1.data{obj.s1Col})/ ...
    0237                         sqrt(length(obj.s1.data{obj.s1Col}));
    0238              stderr2 = std(obj.s2.data{obj.s2Col})/ ...
    0239                         sqrt(length(obj.s2.data{obj.s2Col}));
    0240
    0241              label = [obj.s1.name, '{',obj.s1ColName, '}-', ...
    0242                     obj.s2.name, '{',obj.s2ColName, '}'];
    0243
    0244              if (isnan(userHypothesis))
    0245                  printHyp = 'N/A';
    0246              elseif userHypothesis == 1
    0247                  printHyp = 'PASS';
    0248              elseif userHypothesis == 0
    0249                  printHyp = 'FAIL';
    0250
    0251                  if abs(m2 - m1) < obj.thresh && isnan(obj.thresh) == 0
    0252                     userHypothesis = 1;
    0253                     printHyp ='PTHR';
    0254
    0255                  end
    0256
    0257              end
    0258
    0259
    0260              if (strcmp(reportStyle,'short'))
    0261                 verbosePrint([' UserHyp: ', printHyp, '; ', label, ': ', ...
    0262                      't[',obj.type,'](',num2str(stats.df,3),') = ', ...
    0263                      num2str(stats.tstat), ', p = ', num2str(prob), ...
    0264                      ' p-des: ',num2str(obj.desiredpval)], ...
    0265                      'sosttest_ruIndependentSamplettest');
    0266              elseif (strcmp(reportStyle,'full'))
    0267                  verbosePrint([' UserHyp: ', printHyp , ...
    0268                      '; ', label, ': ', ...
    0269                      't[',obj.type,'](',num2str(stats.df,3),') = ', ...
    0270                      num2str(stats.tstat), ', p = ', num2str(prob), ...
    0271                      ' p-des: ',num2str(obj.desiredpval), ...
    0272                      ' m(1) = ', num2str(m1),' (se=',num2str(stderr1,4), ...
    0273                      '); m(2) = ', num2str(m2),' (se=',num2str(stderr2,4), ...
    0274                      ')', ...
    0275                      ' thresh = ', num2str(obj.thresh), ...
    0276                      ], 'sosttest_ruIndependentSamplettest');
    0277              end
    0278         end %independentSamplesTtest
    0279
    0280
    0281         %% [userHypothesis, prob, label] =  runPairedSamplettest(varargin) METHOD
    0282         function [userHypothesis, prob, label] = ...
    0283                 runPairedSamplettest(obj,varargin)
    0284             %runs a paired sample ttest
    0285             %
    0286             % PARAMETERS:
    0287             % 'reportStyle'/'short'|'full' - style of report to be printed.  Either short or long
    0288             %
    0289             % RETURNS:
    0290             %   userHypothesis - whether the user's hypothesis has been met or not. NaN if no user hypothesis for the test.
    0291             %   prob - p-value from the ttest
    0292             %   label - string label denoting what was tested.
    0293
    0294             varargin = varargin{1};
    0295
    0296             p = inputParser;
    0297             p.addParamValue('reportStyle','short', ...
    0298                     @(reportStyle)any([strcmp(reportStyle,'short') ...
    0299                                     strcmp(reportStyle,'full') ...
    0300                                     strcmp(reportStyle,'none')]));
    0301             p.parse(varargin{:});
    0302
    0303             reportStyle = p.Results.reportStyle;
    0304
    0305             [h,prob,ci,stats] = ttest(obj.s1.data{obj.s1Col},...
    0306                                    obj.s2.data{obj.s2Col},...
    0307                                 0.05,obj.tail);       %#ok<ASGLU>
    0308
    0309             if isnan(prob)
    0310                  m = mean(obj.s1.data{obj.s1Col}-obj.s2.data{obj.s2Col});
    0311
    0312                  if m == 0
    0313                      prob = 1;
    0314                  else
    0315                      prob = 0;
    0316                  end
    0317              end
    0318
    0319              userHypothesis = obj.desiredpvalConditionHandle(...
    0320                                                     prob,obj.desiredpval);
    0321
    0322
    0323              m1 = mean(obj.s1.data{obj.s1Col});
    0324              m2 = mean(obj.s2.data{obj.s2Col});
    0325
    0326             dat1 =  obj.s1.data{obj.s1Col};
    0327             dat2 = obj.s2.data{obj.s2Col};
    0328
    0329             meanDiff = mean(dat2-dat1);
    0330
    0331
    0332
    0333
    0334              stderr = stats.sd/length(obj.s1.data{obj.s1Col});
    0335
    0336              label = [obj.s1.name, '{',obj.s1ColName, '}-', ...
    0337                     obj.s2.name, '{',obj.s2ColName, '}'];
    0338
    0339              if (isnan(userHypothesis))
    0340                  printHyp = 'N/A';
    0341              elseif userHypothesis == 1
    0342                  printHyp = 'PASS';
    0343              elseif userHypothesis == 0
    0344                  printHyp = 'FAIL';
    0345
    0346                 if abs(meanDiff) < obj.thresh && isnan(obj.thresh) == 0
    0347                     userHypothesis = 1;
    0348                     printHyp = 'PTHR';
    0349                 end
    0350
    0351              end
    0352
    0353              if (strcmp(reportStyle,'short'))
    0354                 verbosePrint([' UserHyp: ', printHyp, ...
    0355                      '; ', label, ': ', ...
    0356                      't[',obj.type,'](',num2str(stats.df,3),') = ', ...
    0357                      num2str(stats.tstat), ', p = ', num2str(prob), ...
    0358                      ' p-des: ',num2str(obj.desiredpval)], ...
    0359                      'sosttest_runPairedSamplettest');
    0360             elseif (strcmp(reportStyle,'full'))
    0361                  verbosePrint([' UserHyp: ', printHyp, ...
    0362                      '; ', label, ': ', ...
    0363                      't[',obj.type,'](',num2str(stats.df,3),') = ', ...
    0364                      num2str(stats.tstat), ', p = ', num2str(prob), ...
    0365                      ' p-des: ',num2str(obj.desiredpval), ...
    0366                      ' m(1) = ', num2str(m1), '; m(2) = ', num2str(m2), ...
    0367                      ' (se=',num2str(stderr), ')' ...
    0368                      ' thresh = ', num2str(obj.thresh), ...
    0369                      ], 'sosttest_runPairedSamplettest');
    0370              end
    0371         end %pairedSamplettest
    0372
    0373
    0374         %% [userHypothesis, prob, label] = runSingleSamplettest(varargin) METHOD
    0375         function [userHypothesis, prob, label] = ...
    0376                 runSingleSamplettest(obj,varargin)
    0377             %runs a single sample ttest
    0378             %
    0379             % PARAMETERS:
    0380             % 'reportStyle'/'short'|'full' - style of report to be printed.  Either short or long
    0381             %
    0382             % RETURNS:
    0383             %   userHypothesis - whether the user's hypothesis has been met or not. NaN if no user hypothesis for the test.
    0384             %   prob - p-value from the ttest
    0385             %   label - string label denoting what was tested.
    0386
    0387             varargin = varargin{1};
    0388
    0389             p = inputParser;
    0390             p.addParamValue('reportStyle','short', ...
    0391                     @(reportStyle)any([strcmp(reportStyle,'short') ...
    0392                                     strcmp(reportStyle,'full') ...
    0393                                     strcmp(reportStyle,'none')]));
    0394             p.parse(varargin{:});
    0395
    0396             reportStyle = p.Results.reportStyle;
    0397
    0398             [h,prob,ci,stats] = ttest(obj.s1.data{obj.s1Col},...
    0399                                    obj.targValue,...
    0400                                     0.05,obj.tail);       %#ok<ASGLU>
    0401
    0402             if isnan(prob)
    0403                  m = mean(obj.s1.data{obj.s1Col});
    0404
    0405                  if m == 0
    0406                      prob = 1;
    0407                  else
    0408                      prob = 0;
    0409                  end
    0410             end
    0411
    0412              userHypothesis = obj.desiredpvalConditionHandle(...
    0413                                                     prob,obj.desiredpval);
    0414
    0415
    0416
    0417              m1 = mean(obj.s1.data{obj.s1Col});
    0418              stderr = stats.sd/length(obj.s1.data{obj.s1Col});
    0419
    0420
    0421
    0422
    0423              label = [obj.s1.name, '{',obj.s1ColName, '}-', ...
    0424                     num2str(obj.targValue)'];
    0425
    0426              if (isnan(userHypothesis))
    0427                  printHyp = 'N/A';
    0428              elseif userHypothesis == 1
    0429                  printHyp = 'PASS';
    0430              elseif userHypothesis == 0
    0431                  printHyp = 'FAIL';
    0432
    0433                  if abs(m1-obj.targValue) < obj.thresh && isnan(obj.thresh) == 0
    0434                     userHypothesis = 1;
    0435                     printHyp = 'PTHR';
    0436                  end
    0437              end
    0438
    0439              if (strcmp(reportStyle,'short'))
    0440                 verbosePrint([' UserHyp: ', printHyp, ...
    0441                     '; ', label, ': ', ...
    0442                      't[',obj.type,'](',num2str(stats.df,3),') = ', ...
    0443                      num2str(stats.tstat), ', p = ', num2str(prob), ...
    0444                      ' p-des: ',num2str(obj.desiredpval)], ...
    0445                      'sosttest_runSingleSamplettest');
    0446              elseif (strcmp(reportStyle,'full'))
    0447                  verbosePrint([' UserHyp: ', printHyp, ...
    0448                      '; ', label, ': ', ...
    0449                      't[',obj.type,'](',num2str(stats.df,3),') = ', ...
    0450                      num2str(stats.tstat), ', p = ', num2str(prob), ...
    0451                      ' p-des: ',num2str(obj.desiredpval), ...
    0452                      ' m = ', num2str(m1), ...
    0453                      ' (se=',num2str(stderr), ...
    0454                      ')', ...
    0455                     ' thresh = ', num2str(obj.thresh), ...
    0456                     ], 'sosttest_runSingleSamplettest');
    0457              end
    0458         end %singleSamplettest
    0459
    0460
    0461         %% constructIndependentSamplettest(sosObj,varargin) METHOD
    0462         function constructIndependentSamplettest(obj,sosObj,varargin)
    0463             %initialize an independent samples t-test object.
    0464             % Assumes equal variance.
    0465             %
    0466             % PARAMETERS:
    0467             % Required:
    0468             %   sosObj - sos Object test is to be associated with
    0469             %   sample1 - a sample object
    0470             %   sample2 - a sample object
    0471             %   s1ColName - name of data column in sample1
    0472             %   s2ColName - name of data column in sample2
    0473             %
    0474             % Optional:
    0475             %   desiredpvalCondition/string - desired condition for the ttest
    0476             %       pval. Either it should exceed (=>) some value, be less
    0477             %       than '<=' some condition, or be 'N/A' if there is no
    0478             %       desired condition.  Default is N/A.  Note that the
    0479             %       ordering of '=' and '<' is important, so though '<=' is
    0480             %       valid, '=<' is not.
    0481             %   desiredpval - desired p-value to evaluate the condition
    0482             %       against.  Defaults to 0.05
    0483             %   tail - tail of test - left/right/both
    0484             %
    0485             % RETURNS:
    0486             %   Configured sosttest object.
    0487
    0488
    0489             p = inputParser;
    0490
    0491             p.addRequired('sosObj', ...
    0492                 @(sosObj)strcmp(class(sosObj),'sos'));
    0493             p.addParamValue('type','null', ...
    0494                 @(type)sosttest.validTestType(type));
    0495             p.addParamValue('sample1','null', ...
    0496                         @(sample1)strcmp(class(sample1),'sample'));
    0497             p.addParamValue('sample2','null', ...
    0498                         @(sample2)strcmp(class(sample2),'sample'));
    0499             %NaN will fail by default
    0500             p.addParamValue('s1ColName',NaN, ...
    0501                 @(s1ColName)ischar(s1ColName));
    0502             p.addParamValue('s2ColName',NaN, ...
    0503                 @(s2ColName)ischar(s2ColName));
    0504             p.addParamValue('desiredpvalCondition','N/A', ...
    0505                 @(desiredpvalCondition)any([strcmp(desiredpvalCondition,'<='), ...
    0506                             strcmp(desiredpvalCondition,'=>'), ...
    0507                             strcmp(desiredpvalCondition,'N/A')]));
    0508             p.addParamValue('desiredpval', 0.05, ...
    0509                 @(desiredpval)validateattributes(desiredpval, ...
    0510                     {'numeric'}, ...
    0511                     {'scalar', 'positive', '>=', 0, '<=', 1}));
    0512             p.addParamValue('tail','both', ...
    0513                 @(tail)any([strcmp(tail,'both'), strcmp(tail,'left'),strcmp(tail,'right')]));
    0514             p.addParamValue('name','noname',@(name)ischar(name)); % dealt with in the main constructor
    0515             p.addParamValue('thresh',NaN,@(thres)validateattributes(thres, ...
    0516                     {'numeric'}, {'scalar'}));
    0517
    0518             p.parse(sosObj,varargin{:});
    0519
    0520
    0521             sample1 = p.Results.sample1;
    0522             sample2 = p.Results.sample2;
    0523             s1ColName = p.Results.s1ColName; %#ok<PROP>
    0524             s2ColName = p.Results.s2ColName; %#ok<PROP>
    0525             obj.desiredpvalCondition = p.Results.desiredpvalCondition;
    0526             obj.thresh = p.Results.thresh;
    0527
    0528             if strcmp(obj.desiredpvalCondition,'N/A')
    0529                 obj.desiredpvalConditionHandle = @sosttest.returnNaN;
    0530             elseif strcmp(obj.desiredpvalCondition,'<=')
    0531                 obj.desiredpvalConditionHandle = @le;
    0532             elseif strcmp(obj.desiredpvalCondition,'=>')
    0533                 obj.desiredpvalConditionHandle = @ge;
    0534             end
    0535
    0536             % can't have a desiredpval without a desiredpvalcondition
    0537             if strcmp(obj.desiredpvalCondition,'N/A')
    0538                 obj.desiredpval = NaN;
    0539             else
    0540                 obj.desiredpval = p.Results.desiredpval;
    0541             end
    0542
    0543
    0544             % perform additional checks on the objects
    0545
    0546             present1 = sosObj.containsSample(sample1);
    0547             if (present1 == 0 )
    0548                 error('sos sosObject does not contain sample1');
    0549             end
    0550
    0551             present2 = sosObj.containsSample(sample2);
    0552             if (present2 == 0 )
    0553                 error('sos sosObject does not contain sample2');
    0554             end
    0555
    0556             col1 = sample1.colName2colNum(s1ColName); %#ok<PROP>
    0557             if(col1 == -1)
    0558                 error('<s1ColName> not a column of data in <sample1>');
    0559             end
    0560
    0561             col2 = sample1.colName2colNum(s2ColName); %#ok<PROP>
    0562             if(col2 == -1)
    0563                 error('<s2ColName> not a column of data in <sample2>');
    0564             end
    0565
    0566             if isempty(sample1.data)
    0567                 error('sample 1 does not contain items - did you fill it yet?');
    0568             end
    0569
    0570             if isempty(sample2.data)
    0571                 error('sample 2 does not contain items - did you fill it yet?');
    0572             end
    0573             %all variables check out, create the stats test
    0574
    0575             obj.s1 = sample1;
    0576             obj.s2 = sample2;
    0577             obj.s1ColName = s1ColName; %#ok<PROP>
    0578             obj.s2ColName = s2ColName; %#ok<PROP>
    0579             obj.s1Col = col1;
    0580             obj.s2Col = col2;
    0581             obj.type = p.Results.type;
    0582             obj.tail = p.Results.tail;
    0583
    0584             obj.runSpecificTest = @obj.runIndependentSamplettest;
    0585
    0586             obj.label = [obj.s1.name, '{',obj.s1ColName, '}-', ...
    0587                     obj.s2.name, '{',obj.s2ColName, '}', ...
    0588                     ':t[',obj.type,']'];
    0589
    0590
    0591         end
    0592
    0593         %% constructPairedSamplettest(sosObj,varargin) METHOD
    0594         function constructPairedSamplettest(obj,sosObj,varargin)
    0595             %initialize a paired samples t-test object
    0596             %
    0597             % PARAMETERS:
    0598             % Required:
    0599             %   sosObj - sos Object test is to be associated with
    0600             %   sample1 - a sample object
    0601             %   sample2 - a sample object
    0602             %   s1ColName - name of data column in sample1
    0603             %   s2ColName - name of data column in sample2
    0604             %
    0605             % Optional:
    0606             %   desiredpvalCondition/string - desired condition for the ttest
    0607             %       pval. Either it should exceed (=>) some value, be less
    0608             %       than '<=' some condition, or be 'N/A' if there is no
    0609             %       desired condition.  Default is N/A.  Note that the
    0610             %       ordering of '=' and '<' is important, so though '<=' is
    0611             %       valid, '=<' is not.
    0612             %   desiredpval - desired p-value to evaluate the condition
    0613             %       against.  Defaults to 0.05
    0614             %   tail - tail of test - left/right/both
    0615             %
    0616             % RETURNS:
    0617             %   Configured sosttest object.
    0618
    0619             p = inputParser;
    0620
    0621             p.addRequired('sosObj', ...
    0622                 @(sosObj)strcmp(class(sosObj),'sos'));
    0623             p.addParamValue('type','null', ...
    0624                 @(type)sosttest.validTestType(type));
    0625             p.addParamValue('sample1','null', ...
    0626                         @(sample1)strcmp(class(sample1),'sample'));
    0627             p.addParamValue('sample2','null', ...
    0628                         @(sample2)strcmp(class(sample2),'sample'));
    0629             %NaN will fail by default
    0630             p.addParamValue('s1ColName',NaN, ...
    0631                 @(s1ColName)ischar(s1ColName));
    0632             p.addParamValue('s2ColName',NaN, ...
    0633                 @(s2ColName)ischar(s2ColName));
    0634             p.addParamValue('desiredpvalCondition','N/A', ...
    0635                 @(desiredpvalCondition)any([strcmp(desiredpvalCondition,'<='), ...
    0636                             strcmp(desiredpvalCondition,'=>'), ...
    0637                             strcmp(desiredpvalCondition,'N/A')]));
    0638             p.addParamValue('desiredpval', 0.05, ...
    0639                 @(desiredpval)validateattributes(desiredpval, ...
    0640                     {'numeric'}, ...
    0641                     {'scalar', 'positive', '>=', 0, '<=', 1}));
    0642             p.addParamValue('tail','both', ...
    0643                 @(tail)any([strcmp(tail,'both'), strcmp(tail,'left'),strcmp(tail,'right')]));
    0644             p.addParamValue('name','noname',@(name)ischar(name)); % dealt with in the main constructor
    0645             p.addParamValue('thresh',NaN,@(thres)validateattributes(thres, ...
    0646                     {'numeric'}, {'scalar'}));
    0647
    0648
    0649             p.parse(sosObj,varargin{:});
    0650
    0651
    0652             sample1 = p.Results.sample1;
    0653             sample2 = p.Results.sample2;
    0654             s1ColName = p.Results.s1ColName; %#ok<PROP>
    0655             s2ColName = p.Results.s2ColName; %#ok<PROP>
    0656             obj.desiredpvalCondition = p.Results.desiredpvalCondition;
    0657             obj.thresh = p.Results.thresh;
    0658
    0659             if strcmp(obj.desiredpvalCondition,'N/A')
    0660                 obj.desiredpvalConditionHandle = @sosttest.returnNaN;
    0661             elseif strcmp(obj.desiredpvalCondition,'<=')
    0662                 obj.desiredpvalConditionHandle = @le;
    0663             elseif strcmp(obj.desiredpvalCondition,'=>')
    0664                 obj.desiredpvalConditionHandle = @ge;
    0665             end
    0666
    0667             % can't have a desiredpval without a desiredpvalcondition
    0668             if strcmp(obj.desiredpvalCondition,'N/A')
    0669                 obj.desiredpval = NaN;
    0670             else
    0671                 obj.desiredpval = p.Results.desiredpval;
    0672             end
    0673
    0674
    0675             % perform additional checks on the objects
    0676
    0677             present1 = sosObj.containsSample(sample1);
    0678             if (present1 == 0 )
    0679                 error('sos sosObject does not contain sample1');
    0680             end
    0681
    0682             present2 = sosObj.containsSample(sample2);
    0683             if (present2 == 0 )
    0684                 error('sos sosObject does not contain sample2');
    0685             end
    0686
    0687             col1 = sample1.colName2colNum(s1ColName); %#ok<PROP>
    0688             if(col1 == -1)
    0689                 error('<s1ColName> not a column of data in <sample1>');
    0690             end
    0691
    0692             col2 = sample1.colName2colNum(s2ColName); %#ok<PROP>
    0693             if(col2 == -1)
    0694                 error('<s2ColName> not a column of data in <sample2>');
    0695             end
    0696
    0697             %check that both columns of data have the same number of
    0698             %observations
    0699
    0700             if isempty(sample1.data)
    0701                 error('sample 1 does not contain items - did you fill it yet?');
    0702             end
    0703
    0704             if isempty(sample2.data)
    0705                 error('sample 2 does not contain items - did you fill it yet?');
    0706             end
    0707
    0708             if (length(sample1.data{col1}) ~= length(sample2.data{col2}))
    0709                 error('Sample 1 and Sample 2 must have the same number of observations for a paired comparison');
    0710             end
    0711
    0712             %all variables check out, create the stats test
    0713
    0714             obj.s1 = sample1;
    0715             obj.s2 = sample2;
    0716             obj.s1ColName = s1ColName; %#ok<PROP>
    0717             obj.s2ColName = s2ColName; %#ok<PROP>
    0718             obj.s1Col = col1;
    0719             obj.s2Col = col2;
    0720             obj.type = p.Results.type;
    0721             obj.tail = p.Results.tail;
    0722
    0723             obj.runSpecificTest = @obj.runPairedSamplettest;
    0724
    0725             obj.label = [obj.s1.name, '{',obj.s1ColName, '}-', ...
    0726                     obj.s2.name, '{',obj.s2ColName, '}', ...
    0727                     ':t[',obj.type,']'];
    0728
    0729
    0730         end
    0731
    0732         %%  constructSingleSamplettest(sosObj,varargin) METHOD
    0733         function constructSingleSamplettest(obj,sosObj,varargin)
    0734             %initialize a single sample t-test object
    0735             %
    0736             % PARAMETERS:
    0737             % Required:
    0738             %   sosObj - sos Object test is to be associated with
    0739             %   sample1 - a sample object
    0740             %   s1ColName - name of data column in sample1
    0741             %   ** See also 'optional' but recommended 'targValue'
    0742             %
    0743             % Optional:
    0744             %   targValue/numeric - target value to test for equality with
    0745             %   desiredpvalCondition/string - desired condition for the ttest
    0746             %       pval. Either it should exceed (=>) some value, be less
    0747             %       than '<=' some condition, or be 'N/A' if there is no
    0748             %       desired condition.  Default is N/A.  Note that the
    0749             %       ordering of '=' and '<' is important, so though '<=' is
    0750             %       valid, '=<' is not.
    0751             %   desiredpval - desired p-value to evaluate the condition
    0752             %       against.  Defaults to 0.05
    0753             %   tail - tail of test - left/right/both
    0754             %
    0755             % RETURNS:
    0756             %   Configured sosttest object.
    0757
    0758             p = inputParser;
    0759
    0760             p.addRequired('sosObj', ...
    0761                 @(sosObj)strcmp(class(sosObj),'sos'));
    0762             p.addParamValue('type','null', ...
    0763                 @(type)sosttest.validTestType(type));
    0764             p.addParamValue('sample1','null', ...
    0765                         @(sample1)strcmp(class(sample1),'sample'));
    0766             %NaN will fail by default
    0767             p.addParamValue('s1ColName',NaN, ...
    0768                 @(s1ColName)ischar(s1ColName));
    0769             p.addParamValue('targValue', 0.0, ...
    0770                 @(targValue)validateattributes(targValue, ...
    0771                     {'numeric'}, {'scalar'}));
    0772             p.addParamValue('desiredpvalCondition','N/A', ...
    0773                 @(desiredpvalCondition)any([strcmp(desiredpvalCondition,'<='), ...
    0774                             strcmp(desiredpvalCondition,'=>'), ...
    0775                             strcmp(desiredpvalCondition,'N/A')]));
    0776             p.addParamValue('desiredpval', 0.05, ...
    0777                 @(desiredpval)validateattributes(desiredpval, ...
    0778                     {'numeric'}, ...
    0779                     {'scalar', 'positive', '>=', 0, '<=', 1}));
    0780             p.addParamValue('tail','both', ...
    0781                 @(tail)any([strcmp(tail,'both'), strcmp(tail,'left'),strcmp(tail,'right')]));
    0782             p.addParamValue('name','noname',@(name)ischar(name)); % dealt with in the main constructor
    0783             p.addParamValue('thresh',NaN,@(thres)validateattributes(thres, ...
    0784                     {'numeric'}, {'scalar'}));
    0785
    0786             p.parse(sosObj,varargin{:});
    0787
    0788
    0789             sample1 = p.Results.sample1;
    0790             s1ColName = p.Results.s1ColName; %#ok<PROP>
    0791             obj.desiredpvalCondition = p.Results.desiredpvalCondition;
    0792             obj.targValue = p.Results.targValue;
    0793             obj.thresh = p.Results.thresh;
    0794
    0795             if strcmp(obj.desiredpvalCondition,'N/A')
    0796                 obj.desiredpvalConditionHandle = @sosttest.returnNaN;
    0797             elseif strcmp(obj.desiredpvalCondition,'<=')
    0798                 obj.desiredpvalConditionHandle = @le;
    0799             elseif strcmp(obj.desiredpvalCondition,'=>')
    0800                 obj.desiredpvalConditionHandle = @ge;
    0801             end
    0802
    0803             % can't have a desiredpval without a desiredpvalcondition
    0804             if strcmp(obj.desiredpvalCondition,'N/A')
    0805                 obj.desiredpval = NaN;
    0806             else
    0807                 obj.desiredpval = p.Results.desiredpval;
    0808             end
    0809
    0810
    0811             % perform additional checks on the objects
    0812
    0813             present1 = sosObj.containsSample(sample1);
    0814             if (present1 == 0 )
    0815                 error('sos sosObject does not contain sample1');
    0816             end
    0817
    0818             col1 = sample1.colName2colNum(s1ColName); %#ok<PROP>
    0819             if(col1 == -1)
    0820                 error('<s1ColName> not a column of data in <sample1>');
    0821             end
    0822
    0823
    0824             if isempty(sample1.data)
    0825                 error('sample 1 does not contain items - did you fill it yet?');
    0826             end
    0827
    0828
    0829             %all variables check out, create the stats test
    0830
    0831             obj.s1 = sample1;
    0832             obj.s1ColName = s1ColName; %#ok<PROP>
    0833             obj.s1Col = col1;
    0834             obj.type = p.Results.type;
    0835             obj.tail = p.Results.tail;
    0836
    0837             obj.runSpecificTest = @obj.runSingleSamplettest;
    0838
    0839
    0840             obj.label = [obj.s1.name, '{',obj.s1ColName, '}-', ...
    0841                     num2str(obj.targValue),':t[',obj.type,']'];
    0842
    0843         end % constructSingleSamplettest
    0844     end
    0845
    0846
    0847     methods (Static)
    0848
    0849         %% userHypothesis = returnNaN(~,~) STATIC FUNCTION
    0850         function userHypothesis = returnNaN(~,~)
    0851             % returns NaN
    0852             userHypothesis = NaN;
    0853         end
    0854
    0855         %%  flag = validTestType(str) STATIC FUNCTION
    0856         function flag = validTestType(str)
    0857             % returns 1 if the name of type of test is 'single', 'paired',  or 'independent'; error otherwise.
    0858
    0859             flag = 0; %#ok<NASGU>
    0860
    0861             if(ischar(str) == false)
    0862                 error('<Type> must be either "single","paired", or "independent"');
    0863             end
    0864
    0865             if (strcmp(str,'single') || strcmp(str,'paired') || ...
    0866                         strcmp(str,'independent'))
    0867                 flag = 1;
    0868             else
    0869                 error('<Type> must be either "single","paired", or "independent"');
    0870             end
    0871
    0872         end
    0873     end
    0874
    0875 end
    0876