Home > matlabmk > rm_regress.m

rm_regress

PURPOSE ^

rm_regress() - Performs repeated measures multiple regression analysis

SYNOPSIS ^

function regress_results=rm_regress(gui_infiles_or_tmplt,time_wind,varargin)

DESCRIPTION ^

 rm_regress() - Performs repeated measures multiple regression analysis
                using EEG as a response variable via the regression method
                described in Lorch & Meyers (1990).  The method works by
                performing a separate regression analysis for each
                participant.  Then the regression coefficients are
                averaged across participants and their significance
                determined by performing a t-test with a null hypothesis
                of a coefficient of 0.  The regression analysis can be
                performed across multiple electrodes.  When multiple
                electrodes are used, the function corrects for multiple
                comparisons by using the Bonferroni-Holms procedure.  Each
                electrode is considered a distinct test (i.e., the total
                number of electrodes equals the number of tests in the
                family of tests).

 Usage:
  >> regress_results=rm_regress(gui_infiles_or_tmplt,time_wind,varargin);

 Required Inputs:
  gui_infiles_or_tmplt - ['gui', a cell array of strings, or a string template]
                         If 'gui', a GUI is created that allows you to select
                         which set files to import (this is probably the
                         easiest way to import files).  If a cell array of
                         of strings, each element of the cell array should
                         contain the filename of an EEGLAB set file (e.g.,
                         {'visodbl01.set','visodbl02.set'}.  Otherwise, this
                         input should be a filename template (i.e., a string with
                         # where the subject number should be--'visodbl#.set').
                         If you provide a template, you must use the option
                         'sub_ids' (see below) to specify the ID numbers of
                         each subject. Include the files' path unless the files
                         are in the current working directory.
  time_wind            - [pair of integers] The time window (in milliseconds)
                         across which to average EEG amplitude for the response
                         variable (e.g., [300 500]).

 Optional Inputs:
  predictors    - [cell array of strings] A cell array that specifies the
                  non-intercept predictors you wish to include in the
                  regression analysis (an intercept predictor is automatically
                  added).  The predictors must be fields of the EEG.epoch
                  field of the EEG struct variable stored in each
                  set file. If not specified, the list of possible
                  predictors will be presented on the command line and the
                  user will be asked to select from that list. {default:
                  not specified}
  sub_ids       - [integer vector] A set of integers specifying the
                  subject ID numbers to include in the grand average.
                  Only necessary if a filename template is given as
                  the input to gui_infiles_or_tmplt. Leading 0's are not
                  necessary for ID numbers less than 10 (e.g., If 7 is a
                  sub_id and visodbl#.set the template, the function will
                  look for visodbl07.set AND visodbl7.set).
  alpha         - [value between 0 and 1] Family-wise alpha level (i.e.,
                  alpha level with adjustment for multiple comparisons)
                  {default: 0.05}
  use_bins      - [integer vector] The bin number or numbers to use in the
                  analysis (i.e., all trials that fall in those bins will
                  be included in the analysis). {default: all bins}
  bsln_wind     - [pair of integers] The time window (in units of
                  milliseconds) that will be used to baseline each trial
                  of EEG.  The mean voltage in the time window will be
                  removed from the entire EEG epoch. If the data have
                  already been baselined and ICA artifact correction was NOT
                  applied, you won't need to re-baseline the data. {default:
                  no additional baselining will be done}
  plot_topos    - [0 or 1] If 1, topographies of mean regression
                  coefficients and their corresponding t-scores will be
                  produced (if more than one channel was used in the analysis).
                  {default: 1}
  tail          - [1 | 0 | -1] If tail=1, the alternative hypothesis is
                  that mean regression coeffcients are greater than 0 (upper
                  tailed test).  If tail=0, the alternative hypothesis is
                  that the mean regression coefficients are different than
                  0 (two tailed test). If tail=-1, the alternative
                  hypothesis is that the mean regression coefficients
                  are less than 0 (lower tailed test). {default: 0}
  exclude_chans - A cell array of channel labels to exclude from the
                  analysis (e.g., {'A2','lle','rhe'}).  This option
                  sacrifices spatial resolution to increase test power by
                  reducing the number of comparisons. You cannot
                  use both this option and 'include_chans' (below).{default:
                  not used, all channels included in test}
  include_chans - A cell array of channel labels to use in the analysis
                  (e.g., {'A2','lle','rhe'}).  All other channels will
                  be ignored. This option sacrifices spatial resolution to
                  increase test power by reducing the number of comparisons.
                  You cannot use both this option and 'exclude_chans'
                  (above). {default: not used, all channels included in test}
  correction    - The method used to correct for multiple comparisons
                  (i.e., tests at multiple channels).  There are two options:
                   'perm'      -within subject permutation test {default}
                   'Bonf-Holm' -Bonferroni-Holm procedure (faster than but
                                probably not as powerful as permutation test
                                method when number of participants is 7 or more).
                   'FDR BH'    -Benjamini & Hochberg (1995) false
                                discovery rate control procedure.
                                Guaranteed to control FDR for independent
                                or positive regression dependent data.
                   'FDR BY'    -Benjamini & Yekutieli (2001) false
                                discovery rate control procedure.
                                Always guaranteed to control FDR.
                  If the regression analysis is being performed on a
                  single channel, no correction for multiple comparisons
                  is applied.
  n_perm        - Number of permutations to use for multiple comparison
                  correction.  Manly (1997) suggests using at least 1000
                  permutations for an alpha level of 0.05 and at least
                  5000 permutations for an alpha level of 0.01.  Has no
                  effect if a permutation test is NOT used to correct
                  for multiple comparisons. {default: 5000}
  output_file   - A string indicating the name of a tab delimited text
                  file to produce containing the results of the analysis.
  freq_filt     - [low_boundary high_boundary] a two element vector indicating the frequency
                  cut-offs for a 3rd order Butterworth filter that will be applied to each
                  trial of data.  If low_boundary=0, the filter is a low pass filter.  If
                  high_boundary=(sampling rate)/2, then the filter is a high pass filter.  If both
                  boundaries are between 0 and (sampling rate)/2, then the filter is a band-pass filter.
                  If both boundaries are between 0 and -(sampling rate)/2, then the filter is a band-
                  stop filter (with boundaries equal to the absolute values of the low_boundary and
                  high_boundary).  Note, using this option requires the signal processing toolbox
                  function butter.m and filtfilt.m.  If 'freq_filt' is not
                  specified, no fitering is done. {default: no filtering}
   n_pad        - [integer] number of time points to pad each epoch of
                  data before filtering.  For example, if n_pad is 512 and
                  you have 256 time points of data per epoch, each epoch of
                  data will be grown to 1280 time points (i.e., 512*2+256) by
                  adding 512 padding points before and after the 256 time points
                  of data.  The values of the padding points form a line from the
                  value of the first and last data point (i.e., if you wrapped
                  the padded waveform around a circle the pre-padding and
                  post-padding points would form a line).  This method of
                  padding is the way the Kutaslab function filter.c works.
                  If n_pad is not specified, butterfilt.m will follow the Kutaslab
                  convention of n_pad=2*(the number of time points per
                  epoch). If you wish to avoid zero padding, set n_pad to
                  0.  Note, 'n_pad' has no effect if the optional argument
                  'freq_filt' is not used.
  seed_state    - The seed for the MATLAB random number generator.  This
                  will be used to seed the permutation test (if you've
                  requested to use a permutation test to correct for
                  multiple comparisons).  This argument is useful for
                  reproducing previous test results.  If you pass
                  regress_results.perm_test_info.seed_state from a previous
                  run of rm_regress and keep all the other input parameters
                  the same, you should exactly reproduce the results of the previous run.

 Output:
   Here's a brief explanation as to what each field of regress_results contains:
    -sub_coefs:       The regression coefficient at each channel for each
                       predictor and subject (the matrix is channel x predictor x
                       subject)
    -mn_coefs:        The mean regression coefficient across subjects for each
                       channel and predictor
    -se_coefs:        The standard error of the mean regression coefficient across
                       subjects for each channel and predictor
    -hi_ci:           Upper bound of 95% confidence interval for the estimate of the
                       mean regression coefficient across subjects for each channel
                       and predictor.  Confidence intervals assume a t-distribution
                       and are NOT corrected for multiple comparisons.
    -low_ci:          Upper bound of 95% confidence interval for the estimate of the
                       mean regression coefficient across subjects for each channel
                       and predictor.
    -t_coefs:         t-scores of mean coefficients (i.e., the mean divided by the
                       standard error)
    -t_df:            degrees of freedom for the t-scores in t_coefs
    -d_coefs:         Cohen's d of the mean coefficients (i.e., the mean of the
                       coefficients divided by the standard deviation).  Cohen's
                       d is a standard measure of effect size.
    -tail:            The tail of the hypothesis tests
    -p_coefs_uncor:   Uncorrected p-values for the mean coefficients
    -crctn_method:    The method used to correct for multiple comparisons
                      (if more than one channel analyzed)
    -p_coefs_cor:     p-values after correction for multiple comparisons
    -h_coefs_cor:     Binary matrix (channel x predictor) indicating whether
                       or not the null hypothesis of a mean coefficient of 0
                       could be rejected. 1=the null hypothesis is rejected.
                       0=you failed to reject the null hypothesis.
    -predictors:      The names of the predictor variables
    -R_collinear:     Estimate of the degree of collinearity for each predictor
                       (see next section)
    -family_alpha:    Specified family-wise alpha level
    -chanlocs:        Channel labels and location information for the EEG
                       channels included in the analysis
    -bins:            The bins included in the analysis
    -time_wind:       The lower and upper bound of time window used for analysis
    -participant_filenames: Names of the EEGLAB set files used in the analysis.
    -perm_test_info:  Information about the permutation test used to correct for
                       multiple comparisons (if used at all).  This
                       includes the number of permutations (n_perm), the
                       critical t-score for signficance (tmx_ptile), the
                       seed state of the random number generator (useful
                       for reproducing the analysis), and the estimated
                       family-wise alpha level of the test.

 References:
 Lorch, R.F.,Jr, & Myers, J.L. 1990, Regression analyses of repeated measures
 data in cognitive research. Journal of Experimental Psychology: Learning,
 Memory, and Cognition, 16(1), 149-157.

 Manly, B.F.J. (1997) Randomization, bootstrap, and Monte Carlo methods in
 biology. 2nd ed. Chapmn and Hall, London.

 Notes:
 -To plot topographies of coefficients from the output of this function at
 a later time, use the function sig_topo_coefs.m.
 -If ICA has been applied to the data and some ICs have been labeled as
 artifacts, this function will remove them and re-baseline the data before
 performing the regression analysis. The function should report on the
 command line how many ICs have been removed.
 -If you get the message "Warning: Matrix is singular to working
 precision." something is wrong with your data or predictors.  One or both
 of them is exhibiting perfect collinearity and the regression
 coefficients are undetermined.
 -If you get a warning that some trials could not be used because one of
 predictors have NaN values for that trial, that means that when you
 loaded information about that predictor into the set file a predictor 
 value for that trial was not found.  "NaN" simply stands for "not a
 number" and indicates that that trial can not be used in the regression
 analysis.

 Author:
 David Groppe
 Kutaslab, 7/2010

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 % rm_regress() - Performs repeated measures multiple regression analysis
0002 %                using EEG as a response variable via the regression method
0003 %                described in Lorch & Meyers (1990).  The method works by
0004 %                performing a separate regression analysis for each
0005 %                participant.  Then the regression coefficients are
0006 %                averaged across participants and their significance
0007 %                determined by performing a t-test with a null hypothesis
0008 %                of a coefficient of 0.  The regression analysis can be
0009 %                performed across multiple electrodes.  When multiple
0010 %                electrodes are used, the function corrects for multiple
0011 %                comparisons by using the Bonferroni-Holms procedure.  Each
0012 %                electrode is considered a distinct test (i.e., the total
0013 %                number of electrodes equals the number of tests in the
0014 %                family of tests).
0015 %
0016 % Usage:
0017 %  >> regress_results=rm_regress(gui_infiles_or_tmplt,time_wind,varargin);
0018 %
0019 % Required Inputs:
0020 %  gui_infiles_or_tmplt - ['gui', a cell array of strings, or a string template]
0021 %                         If 'gui', a GUI is created that allows you to select
0022 %                         which set files to import (this is probably the
0023 %                         easiest way to import files).  If a cell array of
0024 %                         of strings, each element of the cell array should
0025 %                         contain the filename of an EEGLAB set file (e.g.,
0026 %                         {'visodbl01.set','visodbl02.set'}.  Otherwise, this
0027 %                         input should be a filename template (i.e., a string with
0028 %                         # where the subject number should be--'visodbl#.set').
0029 %                         If you provide a template, you must use the option
0030 %                         'sub_ids' (see below) to specify the ID numbers of
0031 %                         each subject. Include the files' path unless the files
0032 %                         are in the current working directory.
0033 %  time_wind            - [pair of integers] The time window (in milliseconds)
0034 %                         across which to average EEG amplitude for the response
0035 %                         variable (e.g., [300 500]).
0036 %
0037 % Optional Inputs:
0038 %  predictors    - [cell array of strings] A cell array that specifies the
0039 %                  non-intercept predictors you wish to include in the
0040 %                  regression analysis (an intercept predictor is automatically
0041 %                  added).  The predictors must be fields of the EEG.epoch
0042 %                  field of the EEG struct variable stored in each
0043 %                  set file. If not specified, the list of possible
0044 %                  predictors will be presented on the command line and the
0045 %                  user will be asked to select from that list. {default:
0046 %                  not specified}
0047 %  sub_ids       - [integer vector] A set of integers specifying the
0048 %                  subject ID numbers to include in the grand average.
0049 %                  Only necessary if a filename template is given as
0050 %                  the input to gui_infiles_or_tmplt. Leading 0's are not
0051 %                  necessary for ID numbers less than 10 (e.g., If 7 is a
0052 %                  sub_id and visodbl#.set the template, the function will
0053 %                  look for visodbl07.set AND visodbl7.set).
0054 %  alpha         - [value between 0 and 1] Family-wise alpha level (i.e.,
0055 %                  alpha level with adjustment for multiple comparisons)
0056 %                  {default: 0.05}
0057 %  use_bins      - [integer vector] The bin number or numbers to use in the
0058 %                  analysis (i.e., all trials that fall in those bins will
0059 %                  be included in the analysis). {default: all bins}
0060 %  bsln_wind     - [pair of integers] The time window (in units of
0061 %                  milliseconds) that will be used to baseline each trial
0062 %                  of EEG.  The mean voltage in the time window will be
0063 %                  removed from the entire EEG epoch. If the data have
0064 %                  already been baselined and ICA artifact correction was NOT
0065 %                  applied, you won't need to re-baseline the data. {default:
0066 %                  no additional baselining will be done}
0067 %  plot_topos    - [0 or 1] If 1, topographies of mean regression
0068 %                  coefficients and their corresponding t-scores will be
0069 %                  produced (if more than one channel was used in the analysis).
0070 %                  {default: 1}
0071 %  tail          - [1 | 0 | -1] If tail=1, the alternative hypothesis is
0072 %                  that mean regression coeffcients are greater than 0 (upper
0073 %                  tailed test).  If tail=0, the alternative hypothesis is
0074 %                  that the mean regression coefficients are different than
0075 %                  0 (two tailed test). If tail=-1, the alternative
0076 %                  hypothesis is that the mean regression coefficients
0077 %                  are less than 0 (lower tailed test). {default: 0}
0078 %  exclude_chans - A cell array of channel labels to exclude from the
0079 %                  analysis (e.g., {'A2','lle','rhe'}).  This option
0080 %                  sacrifices spatial resolution to increase test power by
0081 %                  reducing the number of comparisons. You cannot
0082 %                  use both this option and 'include_chans' (below).{default:
0083 %                  not used, all channels included in test}
0084 %  include_chans - A cell array of channel labels to use in the analysis
0085 %                  (e.g., {'A2','lle','rhe'}).  All other channels will
0086 %                  be ignored. This option sacrifices spatial resolution to
0087 %                  increase test power by reducing the number of comparisons.
0088 %                  You cannot use both this option and 'exclude_chans'
0089 %                  (above). {default: not used, all channels included in test}
0090 %  correction    - The method used to correct for multiple comparisons
0091 %                  (i.e., tests at multiple channels).  There are two options:
0092 %                   'perm'      -within subject permutation test {default}
0093 %                   'Bonf-Holm' -Bonferroni-Holm procedure (faster than but
0094 %                                probably not as powerful as permutation test
0095 %                                method when number of participants is 7 or more).
0096 %                   'FDR BH'    -Benjamini & Hochberg (1995) false
0097 %                                discovery rate control procedure.
0098 %                                Guaranteed to control FDR for independent
0099 %                                or positive regression dependent data.
0100 %                   'FDR BY'    -Benjamini & Yekutieli (2001) false
0101 %                                discovery rate control procedure.
0102 %                                Always guaranteed to control FDR.
0103 %                  If the regression analysis is being performed on a
0104 %                  single channel, no correction for multiple comparisons
0105 %                  is applied.
0106 %  n_perm        - Number of permutations to use for multiple comparison
0107 %                  correction.  Manly (1997) suggests using at least 1000
0108 %                  permutations for an alpha level of 0.05 and at least
0109 %                  5000 permutations for an alpha level of 0.01.  Has no
0110 %                  effect if a permutation test is NOT used to correct
0111 %                  for multiple comparisons. {default: 5000}
0112 %  output_file   - A string indicating the name of a tab delimited text
0113 %                  file to produce containing the results of the analysis.
0114 %  freq_filt     - [low_boundary high_boundary] a two element vector indicating the frequency
0115 %                  cut-offs for a 3rd order Butterworth filter that will be applied to each
0116 %                  trial of data.  If low_boundary=0, the filter is a low pass filter.  If
0117 %                  high_boundary=(sampling rate)/2, then the filter is a high pass filter.  If both
0118 %                  boundaries are between 0 and (sampling rate)/2, then the filter is a band-pass filter.
0119 %                  If both boundaries are between 0 and -(sampling rate)/2, then the filter is a band-
0120 %                  stop filter (with boundaries equal to the absolute values of the low_boundary and
0121 %                  high_boundary).  Note, using this option requires the signal processing toolbox
0122 %                  function butter.m and filtfilt.m.  If 'freq_filt' is not
0123 %                  specified, no fitering is done. {default: no filtering}
0124 %   n_pad        - [integer] number of time points to pad each epoch of
0125 %                  data before filtering.  For example, if n_pad is 512 and
0126 %                  you have 256 time points of data per epoch, each epoch of
0127 %                  data will be grown to 1280 time points (i.e., 512*2+256) by
0128 %                  adding 512 padding points before and after the 256 time points
0129 %                  of data.  The values of the padding points form a line from the
0130 %                  value of the first and last data point (i.e., if you wrapped
0131 %                  the padded waveform around a circle the pre-padding and
0132 %                  post-padding points would form a line).  This method of
0133 %                  padding is the way the Kutaslab function filter.c works.
0134 %                  If n_pad is not specified, butterfilt.m will follow the Kutaslab
0135 %                  convention of n_pad=2*(the number of time points per
0136 %                  epoch). If you wish to avoid zero padding, set n_pad to
0137 %                  0.  Note, 'n_pad' has no effect if the optional argument
0138 %                  'freq_filt' is not used.
0139 %  seed_state    - The seed for the MATLAB random number generator.  This
0140 %                  will be used to seed the permutation test (if you've
0141 %                  requested to use a permutation test to correct for
0142 %                  multiple comparisons).  This argument is useful for
0143 %                  reproducing previous test results.  If you pass
0144 %                  regress_results.perm_test_info.seed_state from a previous
0145 %                  run of rm_regress and keep all the other input parameters
0146 %                  the same, you should exactly reproduce the results of the previous run.
0147 %
0148 % Output:
0149 %   Here's a brief explanation as to what each field of regress_results contains:
0150 %    -sub_coefs:       The regression coefficient at each channel for each
0151 %                       predictor and subject (the matrix is channel x predictor x
0152 %                       subject)
0153 %    -mn_coefs:        The mean regression coefficient across subjects for each
0154 %                       channel and predictor
0155 %    -se_coefs:        The standard error of the mean regression coefficient across
0156 %                       subjects for each channel and predictor
0157 %    -hi_ci:           Upper bound of 95% confidence interval for the estimate of the
0158 %                       mean regression coefficient across subjects for each channel
0159 %                       and predictor.  Confidence intervals assume a t-distribution
0160 %                       and are NOT corrected for multiple comparisons.
0161 %    -low_ci:          Upper bound of 95% confidence interval for the estimate of the
0162 %                       mean regression coefficient across subjects for each channel
0163 %                       and predictor.
0164 %    -t_coefs:         t-scores of mean coefficients (i.e., the mean divided by the
0165 %                       standard error)
0166 %    -t_df:            degrees of freedom for the t-scores in t_coefs
0167 %    -d_coefs:         Cohen's d of the mean coefficients (i.e., the mean of the
0168 %                       coefficients divided by the standard deviation).  Cohen's
0169 %                       d is a standard measure of effect size.
0170 %    -tail:            The tail of the hypothesis tests
0171 %    -p_coefs_uncor:   Uncorrected p-values for the mean coefficients
0172 %    -crctn_method:    The method used to correct for multiple comparisons
0173 %                      (if more than one channel analyzed)
0174 %    -p_coefs_cor:     p-values after correction for multiple comparisons
0175 %    -h_coefs_cor:     Binary matrix (channel x predictor) indicating whether
0176 %                       or not the null hypothesis of a mean coefficient of 0
0177 %                       could be rejected. 1=the null hypothesis is rejected.
0178 %                       0=you failed to reject the null hypothesis.
0179 %    -predictors:      The names of the predictor variables
0180 %    -R_collinear:     Estimate of the degree of collinearity for each predictor
0181 %                       (see next section)
0182 %    -family_alpha:    Specified family-wise alpha level
0183 %    -chanlocs:        Channel labels and location information for the EEG
0184 %                       channels included in the analysis
0185 %    -bins:            The bins included in the analysis
0186 %    -time_wind:       The lower and upper bound of time window used for analysis
0187 %    -participant_filenames: Names of the EEGLAB set files used in the analysis.
0188 %    -perm_test_info:  Information about the permutation test used to correct for
0189 %                       multiple comparisons (if used at all).  This
0190 %                       includes the number of permutations (n_perm), the
0191 %                       critical t-score for signficance (tmx_ptile), the
0192 %                       seed state of the random number generator (useful
0193 %                       for reproducing the analysis), and the estimated
0194 %                       family-wise alpha level of the test.
0195 %
0196 % References:
0197 % Lorch, R.F.,Jr, & Myers, J.L. 1990, Regression analyses of repeated measures
0198 % data in cognitive research. Journal of Experimental Psychology: Learning,
0199 % Memory, and Cognition, 16(1), 149-157.
0200 %
0201 % Manly, B.F.J. (1997) Randomization, bootstrap, and Monte Carlo methods in
0202 % biology. 2nd ed. Chapmn and Hall, London.
0203 %
0204 % Notes:
0205 % -To plot topographies of coefficients from the output of this function at
0206 % a later time, use the function sig_topo_coefs.m.
0207 % -If ICA has been applied to the data and some ICs have been labeled as
0208 % artifacts, this function will remove them and re-baseline the data before
0209 % performing the regression analysis. The function should report on the
0210 % command line how many ICs have been removed.
0211 % -If you get the message "Warning: Matrix is singular to working
0212 % precision." something is wrong with your data or predictors.  One or both
0213 % of them is exhibiting perfect collinearity and the regression
0214 % coefficients are undetermined.
0215 % -If you get a warning that some trials could not be used because one of
0216 % predictors have NaN values for that trial, that means that when you
0217 % loaded information about that predictor into the set file a predictor
0218 % value for that trial was not found.  "NaN" simply stands for "not a
0219 % number" and indicates that that trial can not be used in the regression
0220 % analysis.
0221 %
0222 % Author:
0223 % David Groppe
0224 % Kutaslab, 7/2010
0225 %
0226 
0227 %%%%%%%%%%%%%%%% Future Work %%%%%%%%%%%%%%%%%
0228 % -diagnostics plots for each sub?
0229 % -add verblevel as input and make more use of it?
0230 % -could speed up function by baselining just used trials
0231 % -option: exclude garv flagged trials?
0232 % -reaction time as predictor should be checked
0233 % -store additional permutation test info in regress_results?
0234 
0235 %%%%%%%%%%%%%%%% REVISION LOG %%%%%%%%%%%%%%%%%
0236 % 7/19/2010 Added:
0237 % -check that there's more than one subject with a usable number of trials
0238 % -check that there aren't more predictors than trials
0239 %
0240 % 7/23/2010
0241 % -Added random generator seed state optional input argument
0242 % -Added additional information about test to regress_results and to command
0243 % line/output file output
0244 % -Moved report as to min/max predictor values so that it did not include
0245 % trials excluded from analysis
0246 %
0247 % 10/5/2010-freq_filt and n_pad options added
0248 %
0249 % 10/6/2010-'predictors' argument now works. p-value summary added to
0250 % command line output
0251 %
0252 % 12/9/2010-First trial in selected bins was being used even if predictors
0253 % had an NaN value for that trial.  That's been fixed.  Code now reports
0254 % how many trials could not be used because they have NaN values.  Code
0255 % also checks for empty EEG.epoch(x).eventfield values, warns if they're
0256 % found, and replaces them with NaN
0257 %
0258 % 2/1/2010-remove_art_ics.m replaced by remove_artifact_ics.m. Bugs in help
0259 % documentation fixed.
0260 %
0261 % 6/28/2011-Added FDR control as an option for correcting for multiple
0262 % comparisons
0263 
0264 function regress_results=rm_regress(gui_infiles_or_tmplt,time_wind,varargin)
0265 
0266 % One optional input arguments has no effect.
0267 % It just included so that items_regress.m and rm_regress.m accept the same optional input arguments
0268 % This allows minF_regress.m to call them with the same varagin.
0269 p=inputParser;
0270 p.addRequired('gui_infiles_or_tmplt',@(x) ischar(x) || iscell(x));
0271 p.addRequired('time_wind',@(x) isnumeric(x) && (length(x)==2) && isvector(x));
0272 p.addParamValue('predictors',[],@(x) ischar(x) || iscell(x));
0273 p.addParamValue('alpha',.05,@(x) isnumeric(x) && (length(x)==1) && isvector(x) && (x>0) && (x<1));
0274 p.addParamValue('sub_ids',[],@isnumeric);
0275 p.addParamValue('use_bins',[],@(x) isnumeric(x) && isvector(x));
0276 p.addParamValue('bsln_wind',[],@(x) isnumeric(x) && length(x)==2);
0277 p.addParamValue('freq_filt',[],@(x) isnumeric(x) && length(x)==2);
0278 p.addParamValue('n_pad',[],@(x) isnumeric(x) && length(x)==1);
0279 p.addParamValue('plot_topos',1,@isnumeric);
0280 p.addParamValue('exclude_chans',[],@(x) ischar(x) || iscell(x));
0281 p.addParamValue('include_chans',[],@(x) ischar(x) || iscell(x));
0282 p.addParamValue('output_file',[],@ischar);
0283 p.addParamValue('n_perm',5000,@(x) isscalar(x) && (x>0));
0284 p.addParamValue('tail',0,@(x) isscalar(x) && ((x==0) || (x==-1) || (x==1)));
0285 p.addParamValue('correction','perm',@(x) ischar(x) && (strcmpi(x,'Bonf-Holm') ...
0286     || strcmpi(x,'perm') || strcmpi(x,'FDR BH') || strcmpi(x,'FDR BY')));
0287 p.addParamValue('seed_state',[],@isnumeric);
0288 p.addParamValue('use_bins_and_evcode','no',@(x) ischar(x) && (strcmpi(x,'yes')) || (strcmpi(x,'no'))); %Has no effect.
0289 
0290 p.parse(gui_infiles_or_tmplt,time_wind,varargin{:});
0291 
0292 
0293 %Make sure exclude & include options were not both used.
0294 if ~isempty(p.Results.include_chans) && ~isempty(p.Results.exclude_chans)
0295     error('You cannot use BOTH ''include_chans'' and ''exclude_chans'' options.');
0296 end
0297 if ischar(p.Results.exclude_chans),
0298     exclude_chans{1}=p.Results.exclude_chans;
0299 elseif isempty(p.Results.exclude_chans)
0300     exclude_chans=[];
0301 else
0302     exclude_chans=p.Results.exclude_chans;
0303 end
0304 if ischar(p.Results.include_chans),
0305     include_chans{1}=p.Results.include_chans;
0306 elseif isempty(p.Results.include_chans)
0307     include_chans=[];
0308 else
0309     include_chans=p.Results.include_chans;
0310 end
0311 flt=p.Results.freq_filt;
0312 
0313 VERBLEVEL=2; % ?? This is currently barely used.
0314 global EEG; %necessary for remove_artifact_ics.m
0315 
0316 %% Get *.set fileames
0317 infiles=get_set_infiles(gui_infiles_or_tmplt,p.Results.sub_ids);
0318 
0319 %% Import Data
0320 n_sub=length(infiles);
0321 if n_sub==1,
0322     error('You need more than one participant for repeated measures regression.');
0323 end
0324 
0325 n_regress_trial=zeros(1,n_sub);
0326 for sub=1:n_sub,
0327     fprintf('Loading data for Participant %s\n',infiles{sub});
0328     EEG=pop_loadset(infiles{sub});
0329     %load(infiles{sub},'-MAT');
0330     
0331     % Get time points
0332     if time_wind(1)<EEG.times(1),
0333         error('Analysis time window (%d to %d ms) begins before earliest time point in file %s (%d ms).', ...
0334             time_wind(1),time_wind(2),infiles{sub},EEG.times(1));
0335     else
0336         start_tpt=find_tpt(time_wind(1),EEG.times);
0337     end
0338     if time_wind(2)>EEG.times(end),
0339         error('Analysis time window (%d to %d ms) extends beyond latest time point in file %s (%d ms).', ...
0340             time_wind(1),time_wind(2),infiles{sub},EEG.times(end));
0341     else
0342         end_tpt=find_tpt(time_wind(2),EEG.times);
0343     end
0344     time_ids=start_tpt:end_tpt;
0345     
0346     %Check for artifact ICs and remove them if there
0347     %[EEG, ICs_removed]=remove_art_ics(EEG,p.Results.bsln_wind,VERBLEVEL);?? old code
0348     ICs_removed=remove_artifact_ics(p.Results.bsln_wind,VERBLEVEL);
0349     
0350     %Filter the data if requested
0351     if ~isempty(flt)
0352         %first error check
0353         if ~isempty(flt),
0354             if max(flt)>(EEG.srate/2),
0355                 error('''filt'' parameters need to be less than or equal to (sampling rate)/2 (i.e., %f).',EEG.srate/2);
0356             elseif (flt(2)==(EEG.srate/2)) && (flt(1)==0),
0357                 error('If second element of ''filt'' parameter is EEG.srate/2, then the first element must be greater than 0.');
0358             elseif abs(flt(2))<=abs(flt(1)),
0359                 error('Second element of ''filt'' parameters must be greater than first in absolute value.');
0360             elseif (flt(1)<0) || (flt(2)<0),
0361                 if (flt(1)>=0) || (flt(2)>=0),
0362                     error('BOTH parameters of ''filt'' need to be greater than or equal to zero OR need to be negative.');
0363                 end
0364                 if min(flt)<=(-EEG.srate/2),
0365                     error('''filt'' parameters need to be greater than sampling rate/2 (i.e., -%f) when creating a stop band.',EEG.srate/2);
0366                 end
0367             end
0368             
0369         end
0370         EEG=butterfilt(EEG,flt,[],p.Results.n_pad);
0371     end
0372     
0373     %Baseline EEG (unless already baselined by remove_art_ics
0374     if ~isempty(p.Results.bsln_wind) && isempty(ICs_removed),
0375         EEG=baseline_EEG(EEG,p.Results.bsln_wind,VERBLEVEL);   
0376     end
0377     
0378     n_pos_chan=EEG.nbchan;
0379     chan_ids=zeros(1,n_pos_chan);
0380     
0381     if sub==1,
0382         %% Identify predictors
0383         if isempty(p.Results.predictors),
0384             %Print list of possible predictors on command line
0385             epoch_flds=fieldnames(EEG.epoch);
0386             n_epoch_flds=length(epoch_flds);
0387             poss_pred=cell(1,n_epoch_flds);
0388             poss_pred_fullname=cell(1,n_epoch_flds);
0389             
0390             fprintf('\n**** Choose Predictor(s) for Regression Analysis ****\n');
0391             ct=0;
0392             for fld_loop=1:n_epoch_flds,
0393                 if ~strcmpi('event',epoch_flds{fld_loop}) && ~strcmpi('eventtype',epoch_flds{fld_loop}),
0394                     ct=ct+1;
0395                     poss_pred_fullname{ct}=epoch_flds{fld_loop};
0396                     if strcmpi('event',epoch_flds{fld_loop}(1:5)),
0397                         poss_pred{ct}=epoch_flds{fld_loop}(6:end);
0398                     else
0399                         poss_pred{ct}=epoch_flds{fld_loop};
0400                     end
0401                     fprintf('%d) %s\n',ct,poss_pred{ct});
0402                 end
0403             end
0404             %Is reaction time a field?
0405             EEG_flds=fieldnames(EEG);
0406             if ismember('rtmsec',EEG_flds) && ismember('rtbins',EEG_flds),
0407                 ct=ct+1;
0408                 poss_pred{ct}='Reaction Time';
0409                 poss_pred_fullname{ct}='Reaction Time';
0410                 fprintf('%d) %s\n',ct,poss_pred{ct});
0411             end
0412             
0413             pred_ids=[];
0414             while isempty(pred_ids),
0415                 pred_ids=input('Enter the number(s) of desired predictor(s): ','s');
0416                 fprintf('\n');
0417                 pred_ids=str2num(pred_ids);
0418                 if max(pred_ids)>ct,
0419                     fprintf('ERROR: There are no predictor indices greater than %d.\n',ct);
0420                     pred_ids=[];
0421                 elseif min(pred_ids)<1,
0422                     fprintf('ERROR: All predictor indices must be greater than 0.\n');
0423                     pred_ids=[];
0424                 end
0425             end
0426             predictors=poss_pred_fullname(unique(pred_ids));
0427             predictor_names_neat=poss_pred(unique(pred_ids));
0428             if ismember('Reaction Time',predictors),
0429                 rt_selected=1;
0430             else
0431                 rt_selected=0;
0432             end
0433         else
0434             %get possible predictors
0435             epoch_flds=fieldnames(EEG.epoch);
0436             n_epoch_flds=length(epoch_flds);
0437             poss_pred=cell(1,n_epoch_flds);
0438             poss_pred_fullname=cell(1,n_epoch_flds);
0439             ct=0;
0440             for fld_loop=1:n_epoch_flds,
0441                 if ~strcmpi('event',epoch_flds{fld_loop}) && ~strcmpi('eventtype',epoch_flds{fld_loop}),
0442                     ct=ct+1;
0443                     poss_pred_fullname{ct}=epoch_flds{fld_loop};
0444                     if strcmpi('event',epoch_flds{fld_loop}(1:5)),
0445                         poss_pred{ct}=epoch_flds{fld_loop}(6:end);
0446                     else
0447                         poss_pred{ct}=epoch_flds{fld_loop};
0448                     end
0449                 end
0450             end
0451             %Is reaction time a field?
0452             EEG_flds=fieldnames(EEG);
0453             if ismember('rtmsec',EEG_flds) && ismember('rtbins',EEG_flds),
0454                 ct=ct+1;
0455                 poss_pred{ct}='Reaction Time';
0456                 poss_pred_fullname{ct}='Reaction Time';
0457             end
0458             
0459             %figure out which of the possible predictors have been
0460             %requested
0461             if ischar(p.Results.predictors)
0462                 requested_pred{1}=p.Results.predictors;
0463             else
0464                 requested_pred=p.Results.predictors;
0465             end
0466             pred_ids=zeros(1,length(requested_pred));
0467             ct=0;
0468             n_poss=length(poss_pred);
0469             for dloop=1:length(requested_pred),
0470                 found=0;
0471                 for eloop=1:n_poss,
0472                     if strcmpi(requested_pred{dloop},poss_pred{eloop}) || ...
0473                             strcmpi(requested_pred{dloop},poss_pred_fullname{eloop})
0474                         found=1;
0475                         ct=ct+1;
0476                         pred_ids(ct)=eloop;
0477                         break;
0478                     end
0479                 end
0480                 if ~found,
0481                     fprintf('*** ERROR!! ***\n');
0482                     fprintf('Requested predictor %s was not found in this EEG variable.\n', ...
0483                         requested_pred{dloop});
0484                     fprintf('Possible predictors are:\n');
0485                     for floop=1:n_poss,
0486                         if ~isempty(poss_pred{floop}),
0487                             fprintf('%d) %s\n',floop,poss_pred{floop});
0488                         end
0489                     end
0490                     error('Requested predictor not found.');
0491                 end
0492             end
0493             predictors=poss_pred_fullname(unique(pred_ids));
0494             predictor_names_neat=poss_pred(unique(pred_ids));
0495             if ismember('Reaction Time',predictors),
0496                 rt_selected=1;
0497             else
0498                 rt_selected=0;
0499             end
0500         end
0501         n_pred=length(predictors);
0502         
0503         %% Figure out which channels to ignore if any
0504         % exclude and include chan options
0505         use_chan_labels=cell(1,n_pos_chan); %preallocate mem
0506         ct=0;
0507         if ~isempty(exclude_chans),
0508             for x=1:n_pos_chan,
0509                 if ~ismember(EEG.chanlocs(x).labels,exclude_chans),
0510                     ct=ct+1;
0511                     chan_ids(ct)=x;
0512                     use_chan_labels{ct}=EEG.chanlocs(x).labels;
0513                 end
0514             end
0515         elseif ~isempty(include_chans),
0516             for x=1:n_pos_chan,
0517                 if ismember(EEG.chanlocs(x).labels,include_chans),
0518                     ct=ct+1;
0519                     chan_ids(ct)=x;
0520                     use_chan_labels{ct}=EEG.chanlocs(x).labels;
0521                 end
0522             end
0523         else
0524             for x=1:n_pos_chan,
0525                 use_chan_labels{x}=EEG.chanlocs(x).labels;
0526             end
0527             chan_ids=1:n_pos_chan;
0528             ct=n_pos_chan;
0529         end
0530         chan_ids=chan_ids(1:ct);
0531         use_chan_labels(ct+1:end)=[];
0532         n_chan=length(chan_ids);
0533         chanlocs=EEG.chanlocs(chan_ids);
0534         
0535         %Preallocate memory for regression coefficient estimates
0536         sub_coefs=zeros(n_chan,n_pred+1,n_sub); %add one for intercept
0537         R_collinear=zeros(n_pred+1,n_sub)*NaN; %add one for intercept
0538     else
0539         %Not the first subject, grab the same channels in the same order and throw error if missing used channel(s)
0540         ct=0;
0541         for a=1:n_chan,
0542             found=0;
0543             for b=1:n_pos_chan,
0544                 %a=channel index for analysis
0545                 %b=channel index for this particular subject
0546                 if strcmpi(EEG.chanlocs(b).labels,use_chan_labels{a}),
0547                     found=1;
0548                     ct=ct+1;
0549                     chan_ids(ct)=b;
0550                     break;
0551                 end
0552             end
0553             if ~found,
0554                 error('Missing channel %s for participant %s.',use_chan_labels{a}, ...
0555                     infiles{sub});
0556             end
0557         end
0558         chan_ids=chan_ids(1:ct);
0559     end
0560     
0561     poss_prdct=fieldnames(EEG.epoch);
0562     if rt_selected,
0563         EEG_flds=fieldnames(EEG);
0564         if ismember('rtmsec',EEG_flds) && ismember('rtbins',EEG_flds),
0565             poss_prdct{1+length(poss_prdct)}='Reaction Time';
0566         end
0567     end
0568     missing_prdct=setdiff(predictors,poss_prdct);
0569     if ~isempty(missing_prdct),
0570         fprintf('ERROR: File %s is missing the following predictor(s): \n', ...
0571             infiles{sub});
0572         for a=1:length(missing_prdct),
0573             fprintf('%s \n',missing_prdct{a});
0574         end
0575         error('Regression aborted.');
0576     end
0577     
0578     n_trial=length(EEG.epoch);
0579     use_trial=zeros(1,n_trial);
0580     pred_val=zeros(n_pred,n_trial);
0581     EEG_val=zeros(n_chan,n_trial);
0582     for trial=1:n_trial,
0583         n_type=length(EEG.epoch(trial).eventtype);
0584         
0585         if isempty(p.Results.use_bins),
0586             use_trial(trial)=1;
0587         else
0588             %Find out if current trial falls into desired bin
0589             for typ=1:n_type,
0590                 for bin=p.Results.use_bins,
0591                     if strcmpi(['bin' num2str(bin)],EEG.epoch(trial).eventtype{typ}),
0592                         use_trial(trial)=1;
0593                         break; %leave bin loop
0594                     end
0595                 end
0596                 if use_trial(trial),
0597                     break; %leave typ loop
0598                 end
0599             end
0600         end
0601         
0602         %Record predictor and response var values if trial is being used
0603         if use_trial(trial),
0604             for pred=1:n_pred,
0605                 if strcmpi(predictors{pred},'Reaction Time'),
0606                     n_rt_bin=length(EEG.rtbins{trial});
0607                     bin_rts=zeros(1,n_rt_bin);
0608                     bin_ct=0;
0609                     for b=1:n_rt_bin,
0610                         if ismember(EEG.rtbins{trial}(b),p.Results.use_bins),
0611                             bin_ct=bin_ct+1;
0612                             bin_rts(bin_ct)=EEG.rtmsec{trial}(b);
0613                         end
0614                     end
0615                     bin_rts=bin_rts(1:bin_ct);
0616                     uni_rt=unique(bin_rts);
0617                     if length(uni_rt)>1
0618                         error('Trial %d has more than one reaction time for the bins you''ve selected.',trial);
0619                     elseif isempty(uni_rt),
0620                         watchit(sprintf('Epoch %d has an empty value for reaction time.  Please use NaN for missing predictor values.\n', ...
0621                             trial));
0622                         pred_val(pred,trial)=NaN;
0623                     else
0624                         pred_val(pred,trial)=uni_rt;
0625                     end
0626                 else
0627                     cmnd=['emptyval=isempty(EEG.epoch(trial).' predictors{pred} ');'];
0628                     eval(cmnd); %for some reason calling isempty.m wasn't working in the function so I used this workaround
0629                     if emptyval,
0630                         watchit(sprintf('Epoch %d has an empty value for predictor %s.  Please use NaN for missing predictor values.\n', ...
0631                             trial,predictor_names_neat{pred}));
0632                         cmnd=['pred_val(pred,trial)=NaN;']; %?? Do RT too
0633                         eval(cmnd);
0634                     else
0635                         cmnd=['temp_pred=EEG.epoch(trial).' predictors{pred} ';'];
0636                         eval(cmnd);
0637                         if iscell(temp_pred),
0638                             if all_same_cell_elements(temp_pred),
0639                                 pred_val(pred,trial)=temp_pred{1};
0640                             else
0641                                 error('Epoch %d has multiple values for predictor %s.', ...
0642                                     trial,predictors{pred});
0643                             end
0644                         else
0645                             pred_val(pred,trial)=temp_pred;
0646                         end
0647                     end
0648                 end
0649             end
0650             for c=1:n_chan,
0651                 EEG_val(c,trial)=squeeze(mean(EEG.data(chan_ids(c),time_ids,trial),2));
0652             end
0653         end
0654     end
0655     
0656     %get rid of unused trials
0657     trial_ids=find(use_trial==1);
0658     if n_chan>1,
0659         EEG_val=EEG_val(:,trial_ids);
0660     else
0661         EEG_val=EEG_val(trial_ids);
0662     end
0663     if n_pred>1,
0664         pred_val=pred_val(:,trial_ids);
0665     else
0666         pred_val=pred_val(trial_ids);
0667     end
0668 
0669     %get rid of NaN trials (if any)
0670     if n_pred>1,
0671         has_NaN=sum(isnan(pred_val));
0672         non_NaN_ids=find(has_NaN==0);
0673         NaN_ids=find(has_NaN);
0674         pred_val=pred_val(:,non_NaN_ids);
0675     else
0676         non_NaN_ids=find(~isnan(pred_val));
0677         NaN_ids=find(isnan(pred_val));
0678         pred_val=pred_val(non_NaN_ids);
0679     end
0680     if n_chan>1,
0681         EEG_val=EEG_val(:,non_NaN_ids);
0682     else
0683         EEG_val=EEG_val(non_NaN_ids);
0684     end
0685     
0686     n_nonNaN_trials=length(non_NaN_ids);
0687     n_selected_trials=length(trial_ids);
0688     if n_selected_trials~=n_nonNaN_trials,
0689         watchit(sprintf('%d of the selected trials have NaN predictor values for at least one predictor variable.', ...
0690             n_selected_trials-n_nonNaN_trials));
0691         NaN_trial_ids=trial_ids(NaN_ids);
0692         if VERBLEVEL>2,
0693             disp(['The EEG.epoch indices of those trials are:' num2str(NaN_trial_ids)]);
0694         end
0695     end
0696     n_regress_trial(sub)=n_nonNaN_trials;
0697     fprintf('Number of usable trials: %d\n',n_nonNaN_trials);
0698     %Check if sufficient # of usable trials
0699     if ~n_nonNaN_trials,
0700         if isempty(p.Results.use_bins),
0701             error('Participant %s has no usable trials.  Regression aborted.', ...
0702                 infiles{sub});
0703         else
0704             error('Participant %s has no trials for Bin(s) %s.  Regression aborted.', ...
0705                 infiles{sub},num2str(p.Results.use_bins));
0706         end
0707     elseif n_nonNaN_trials<=n_pred,
0708         error('Participant %s has insufficient usable trials (i.e., %d) for the number of predictors in this analysis (i.e., %d plus an intercept term).', ...
0709             infiles{sub},n_nonNaN_trials,n_pred);
0710     end
0711     
0712     %Report min and max values for each predictor
0713     for pred_loop=1:n_pred,
0714         fprintf('%s (min/max): %f/%f\n',predictor_names_neat{pred_loop}, ...
0715             min(pred_val(pred_loop,:)),max(pred_val(pred_loop,:)));
0716     end
0717   
0718     %perform multiple regression at each channel
0719     for c=1:n_chan,
0720         [coeff, S_err, XTXI, R_sq, R_sq_adj, F_val, Coef_stats, y_hat, residuals]= ...
0721             mregress(EEG_val(c,:)',pred_val',1); %final argument "1" means that an intercept term is included in the model
0722         %Note that the first element of coeff and associated variables
0723         %correpsponds to the intercept term
0724         sub_coefs(c,1:n_pred+1,sub)=coeff;
0725     end
0726     if sum(isnan(coeff)),
0727         error('The data for participant %s exhibits perfect collinearity and the regression coefficients cannot be determined.',infiles{sub});
0728     end
0729     %Quantify degree of collinearity with other predictors
0730     if n_pred>1,
0731         for a=1:n_pred,
0732             [coeffCOL, S_errCOL, XTXIcol, R_sqCOL]=mregress(pred_val(a,:)', ...
0733                 pred_val(setdiff(1:n_pred,a),:)',1);
0734             R_collinear(a+1,sub)=R_sqCOL;
0735         end
0736     end
0737     fprintf('\n');
0738 end
0739 
0740 regress_results.sub_coefs=sub_coefs;
0741 regress_results.mn_coefs=mean(sub_coefs,3);
0742 regress_results.se_coefs=stderr(sub_coefs,3);
0743 t_df=n_sub-1;
0744 crit_t=tinv(.975,t_df); %for 95% confidence intervals
0745 regress_results.hi_ci=regress_results.mn_coefs+crit_t*regress_results.se_coefs;
0746 regress_results.low_ci=regress_results.mn_coefs-crit_t*regress_results.se_coefs;
0747 regress_results.t_coefs=regress_results.mn_coefs./regress_results.se_coefs;
0748 regress_results.t_df=t_df;
0749 regress_results.d_coefs=regress_results.mn_coefs./std(sub_coefs,0,3); %0 indicates that n-1 SD formula will be used
0750 regress_results.F_coefs=zeros(n_chan,n_pred)*NaN;
0751 regress_results.tail=p.Results.tail;
0752 regress_results.p_coefs_uncor=zeros(n_chan,n_pred)*NaN;
0753 if n_chan==1,
0754     regress_results.crctn_method='Not applicable';
0755 else
0756     regress_results.crctn_method=p.Results.correction;
0757 end
0758 regress_results.p_coefs_cor=regress_results.p_coefs_uncor;
0759 regress_results.h_coefs_cor=regress_results.p_coefs_uncor;
0760 regress_results.predictor_names=cell(1,n_pred+1);
0761 regress_results.predictor_names{1}='Intercept';
0762 %regress_results.predictor_names(2:n_pred+1)=predictors; <=These are
0763 %predictor names with event in front of it
0764 regress_results.predictor_names(2:n_pred+1)=predictor_names_neat;
0765 regress_results.R_collinear=R_collinear;
0766 regress_results.family_alpha=p.Results.alpha;
0767 regress_results.chanlocs=chanlocs;
0768 if isempty(p.Results.use_bins),
0769     regress_results.bins='All';
0770 else
0771     regress_results.bins=p.Results.use_bins;
0772 end
0773 regress_results.time_wind=time_wind;
0774 regress_results.participant_filenames=infiles;
0775 regress_results.perm_test_info.n_perm=NaN;
0776 regress_results.perm_test_info.tmx_ptile=NaN;
0777 regress_results.perm_test_info.seed_state=NaN;
0778 regress_results.perm_test_info.est_alpha=NaN;
0779 for pred=1:n_pred+1,
0780     fprintf('Computing significance of mean coefficient(s) for predictor %s.\n', ...
0781         regress_results.predictor_names{pred});
0782     if ~isempty(p.Results.seed_state) && strcmpi(p.Results.correction,'perm');
0783         fprintf('Seeding permutation test with specified seed_state.\n');
0784     end
0785     for c=1:n_chan,
0786         if ~p.Results.tail
0787             %two-tailed test
0788             regress_results.p_coefs_uncor(c,pred)=2*(1-tcdf(abs(regress_results.t_coefs(c,pred)),n_sub-1));
0789         elseif p.Results.tail==1,
0790             %upper-tailed test
0791             regress_results.p_coefs_uncor(c,pred)=(1-tcdf(regress_results.t_coefs(c,pred),n_sub-1));
0792         else
0793             %lower-tailed test
0794             regress_results.p_coefs_uncor(c,pred)=tcdf(regress_results.t_coefs(c,pred),n_sub-1);
0795         end
0796         regress_results.F_coefs(c,pred)=finv(1-regress_results.p_coefs_uncor(c,pred),1,regress_results.t_df);
0797     end
0798     if n_chan==1,
0799         regress_results.p_coefs_cor(:,pred)=regress_results.p_coefs_uncor(:,pred);
0800         regress_results.h_coefs_cor(:,pred)=(regress_results.p_coefs_cor(:,pred)<p.Results.alpha);
0801     else
0802         if strcmpi(p.Results.correction,'Bonf-Holm'),
0803             [regress_results.p_coefs_cor(:,pred), regress_results.h_coefs_cor(:,pred)]= ...
0804                 bonf_holm(regress_results.p_coefs_uncor(:,pred),p.Results.alpha);
0805         elseif strcmpi(p.Results.correction,'FDR BH'),
0806             [regress_results.h_coefs_cor(:,pred) dummy regress_results.p_coefs_cor(:,pred)]= ...
0807                 fdr_bh(regress_results.p_coefs_uncor(:,pred),p.Results.alpha,'pdep','yes');
0808         elseif strcmpi(p.Results.correction,'FDR BY'),
0809             [regress_results.h_coefs_cor(:,pred) dummy regress_results.p_coefs_cor(:,pred)]= ...
0810                 fdr_bh(regress_results.p_coefs_uncor(:,pred),p.Results.alpha,'dep','yes');
0811         else
0812             if pred>1 || isempty(p.Results.seed_state),
0813                 [pval, t_orig, tmx_ptile, seed_state, est_alpha]=mxt_perm1(sub_coefs(:,pred,:), ...
0814                     p.Results.n_perm,p.Results.alpha,p.Results.tail,VERBLEVEL);
0815             else
0816                 %Just seed the first permutation test if seed_state
0817                 %specified
0818                 [pval, t_orig, tmx_ptile, seed_state, est_alpha]=mxt_perm1(sub_coefs(:,pred,:), ...
0819                     p.Results.n_perm,p.Results.alpha,p.Results.tail,VERBLEVEL,p.Results.seed_state);
0820             end
0821             regress_results.p_coefs_cor(:,pred)=pval;
0822             regress_results.h_coefs_cor(:,pred)=pval<p.Results.alpha;
0823             regress_results.perm_test_info.n_perm=p.Results.n_perm;
0824             regress_results.perm_test_info.tmx_ptile=tmx_ptile;
0825             if pred==1,
0826                 regress_results.perm_test_info.seed_state=seed_state;
0827             end
0828             regress_results.perm_test_info.est_alpha=est_alpha;
0829         end
0830     end
0831 end
0832 
0833 %add error check if only one participant submitted? ??
0834 fprintf('\n\n');
0835 
0836 %% Report Results to Command Line
0837 fprintf('**ANALYSIS PARAMETERS**\n');
0838 fprintf('Number of participants: %d\n',n_sub);
0839 fprintf('Regression analysis t-score degrees of freedom: %d\n',t_df);
0840 if p.Results.tail>0,
0841     fprintf('Tail of tests: Upper\n');
0842 elseif p.Results.tail<0,
0843     fprintf('Tail of tests: Lower\n');
0844 else
0845     fprintf('Tail of tests: Two-Tailed\n');
0846 end
0847 if n_chan==1,
0848     fprintf('Multiple comparison correction method: Not Applicable\n');
0849 else
0850     if strcmpi(p.Results.correction,'perm'),
0851         fprintf('Multiple comparison correction method: Within-subjects permutation test\n');
0852     elseif strcmpi(p.Results.correction,'FDR BH'),
0853         fprintf('Benjamini & Hochberg FDR control procedure\n');
0854     elseif strcmpi(p.Results.correction,'FDR BY'),
0855         fprintf('Benjamini & Yekutieli FDR control procedure\n');
0856     else
0857         fprintf('Multiple comparison correction method: Bonferroni-Holm procedure\n');
0858     end
0859 end
0860 fprintf('Specified Family-Wise Alpha Level: %.3f\n',p.Results.alpha);
0861 if strcmpi(p.Results.correction,'perm'),
0862     fprintf('Estimated Perm Test Family-Wise Alpha Level: %.3f\n', ...
0863         regress_results.perm_test_info.est_alpha);
0864     fprintf('# of permutations used for permutation test: %d\n', ...
0865         regress_results.perm_test_info.n_perm);
0866 end
0867 fprintf('Number of channels analyzed: %d\n',n_chan);
0868 fprintf('Mean EEG amplitude measured from %d to %d ms.\n',time_wind(1), ...
0869     time_wind(2));
0870 fprintf('Mean (SD) # of trials per participant: %.1f (%.1f)\n',mean(n_regress_trial),std(n_regress_trial));
0871 fprintf('Minimum and maximum # of trials per participant: %.1f to %.1f\n',min(n_regress_trial),max(n_regress_trial));
0872 fprintf('**RESULTS (Summarized across all channels)**\n');
0873 if n_pred>1,
0874     fprintf('Predictor\t#_of_Sig_Channels\tMedian(IQR)_Collinearity\tp-values\n');
0875     for a=1:n_pred+1,
0876         mn_p=min(regress_results.p_coefs_cor(:,a));
0877         if mn_p>=p.Results.alpha,
0878             %no significant effects for this predictor
0879             if a==1,
0880                 %intercept term
0881                 fprintf('%s\t\t%d\t\t\tNA\t\t\tp>=%f\n',regress_results.predictor_names{a}, ...
0882                     sum(regress_results.h_coefs_cor(:,a)),mn_p); %intercept term has no collinearity measure
0883             else
0884                 fprintf('%s\t\t%d\t\t\t%.2f(%.2f)\t\tp>=%f\n',regress_results.predictor_names{a}, ...
0885                     sum(regress_results.h_coefs_cor(:,a)),median(R_collinear(a,:)), ...
0886                     iqr(R_collinear(a,:)),mn_p);
0887             end
0888         else
0889             %at least one significant effects for this predictor
0890             sig_p_id=find(regress_results.p_coefs_cor(:,a)<p.Results.alpha);
0891             mx_p=max(regress_results.p_coefs_cor(sig_p_id,a));
0892             if a==1,
0893                 %intercept term
0894                 fprintf('%s\t\t%d\t\t\tNA\t\t%f>=sig p>=%f\n',regress_results.predictor_names{a}, ...
0895                     sum(regress_results.h_coefs_cor(:,a)),mx_p,mn_p); %intercept term has no collinearity measure
0896             else
0897                 fprintf('%s\t\t%d\t\t\t%.2f(%.2f)\t%f>=sig p>=%f\n',regress_results.predictor_names{a}, ...
0898                     sum(regress_results.h_coefs_cor(:,a)),median(R_collinear(a,:)), ...
0899                     iqr(R_collinear(a,:)),mx_p,mn_p);
0900             end
0901         end
0902     end
0903 else
0904     fprintf('Predictor\t#_of_Sig_Channels\t\tp-values\n');
0905     for a=1:2,
0906         mn_p=min(regress_results.p_coefs_cor(:,a));
0907         if mn_p>=p.Results.alpha,
0908             %no significant effects for this predictor
0909             fprintf('%s\t\t%d\t\t\tp>=%f\n',regress_results.predictor_names{a}, ...
0910                 sum(regress_results.h_coefs_cor(:,a)),mn_p);
0911         else
0912             %at least one significant effect for this predictor
0913             sig_p_id=find(regress_results.p_coefs_cor(:,a)<p.Results.alpha);
0914             mx_p=max(regress_results.p_coefs_cor(sig_p_id,a));
0915             fprintf('%s\t\t%d\t\t%f>=sig p>=%f\n',regress_results.predictor_names{a}, ...
0916                 sum(regress_results.h_coefs_cor(:,a)),mx_p,mn_p);
0917         end
0918     end
0919 end
0920 
0921 %% Print Results to Output File
0922 if ~isempty(p.Results.output_file),
0923     [fid msg]=fopen(p.Results.output_file,'w');
0924     if fid==-1,
0925         error('Cannot create file %s for writing.  According to fopen.m: %s.', ...
0926             p.Results.file,msg);
0927     else
0928         % Header Information
0929         fprintf(fid,'**ANALYSIS_PARAMETERS**\n');
0930         fprintf(fid,'Number of participants: %d\n',n_sub);
0931         fprintf(fid,'Regression analysis t-score degrees of freedom: %d\n',n_sub-1);
0932         if p.Results.tail>0,
0933             fprintf(fid,'Tail of tests: Upper\n');
0934         elseif p.Results.tail<0,
0935             fprintf(fid,'Tail of tests: Lower\n');
0936         else
0937             fprintf(fid,'Tail of tests: Two-Tailed\n');
0938         end
0939         if n_chan==1,
0940             fprintf(fid,'Multiple comparison correction method: Not Applicable\n');
0941         else
0942             if strcmpi(p.Results.correction,'perm'),
0943                 fprintf(fid,'Multiple comparison correction method: Within-subjects permutation test\n');
0944             elseif strcmpi(p.Results.correction,'FDR BH'),
0945                 fprintf(fid,'Benjamini & Hochberg FDR control procedure\n');
0946             elseif strcmpi(p.Results.correction,'FDR BY'),
0947                 fprintf(fid,'Benjamini & Yekutieli FDR control procedure\n');
0948             else
0949                 fprintf(fid,'Multiple comparison correction method: Bonferroni-Holm procedure\n');
0950             end
0951         end
0952         fprintf(fid,'Family-Wise Alpha Level: %.3f\n',p.Results.alpha);
0953         if strcmpi(p.Results.correction,'perm'),
0954             fprintf(fid,'Estimated Perm Test Family-Wise Alpha Level: %.3f\n', ...
0955                 regress_results.perm_test_info.est_alpha);
0956             fprintf(fid,'# of permutations used for permutation test: %d\n', ...
0957                 regress_results.perm_test_info.n_perm);
0958         end
0959         fprintf(fid,'Number of channels analyzed: %d\n',n_chan);
0960         fprintf(fid,'Mean EEG amplitude measured from %d to %d ms.\n',time_wind(1), ...
0961             time_wind(2));
0962         fprintf(fid,'Mean (SD) # of trials per participant: %.1f (%.1f)\n',mean(n_regress_trial),std(n_regress_trial));
0963         fprintf(fid,'Minimum and maximum # of trials per participant: %.1f to %.1f\n',min(n_regress_trial),max(n_regress_trial));
0964         fprintf(fid,'*.set_files_used_in_analysis #_of_trials_from_setfile_used\n');
0965         for a=1:n_sub,
0966             fprintf(fid,'%s %d\n',infiles{a},n_regress_trial(a));
0967         end
0968         fprintf(fid,'**REGRESSION_RESULTS_SUMMARY**\n');
0969         if n_pred>1,
0970             fprintf(fid,'Predictor\t#_of_Sig_Channels\tMedian(IQR)_Collinearity\tp-values\n');
0971             for a=1:n_pred+1,
0972                 mn_p=min(regress_results.p_coefs_cor(:,a));
0973                 if mn_p>=p.Results.alpha,
0974                     %no significant effects for this predictor
0975                     if a==1,
0976                         %intercept term
0977                         fprintf(fid,'%s\t\t%d\t\t\tNA\t\t\tp>=%f\n',regress_results.predictor_names{a}, ...
0978                             sum(regress_results.h_coefs_cor(:,a)),mn_p); %intercept term has no collinearity measure
0979                     else
0980                         fprintf(fid,'%s\t\t%d\t\t\t%.2f(%.2f)\t\tp>=%f\n',regress_results.predictor_names{a}, ...
0981                             sum(regress_results.h_coefs_cor(:,a)),median(R_collinear(a,:)), ...
0982                             iqr(R_collinear(a,:)),mn_p);
0983                     end
0984                 else
0985                     %at least one significant effects for this predictor
0986                     sig_p_id=find(regress_results.p_coefs_cor(:,a)<p.Results.alpha);
0987                     mx_p=max(regress_results.p_coefs_cor(sig_p_id,a));
0988                     if a==1,
0989                         %intercept term
0990                         fprintf(fid,'%s\t\t%d\t\t\tNA\t\t%f>=sig p>=%f\n',regress_results.predictor_names{a}, ...
0991                             sum(regress_results.h_coefs_cor(:,a)),mx_p,mn_p); %intercept term has no collinearity measure
0992                     else
0993                         fprintf(fid,'%s\t\t%d\t\t\t%.2f(%.2f)\t%f>=sig p>=%f\n',regress_results.predictor_names{a}, ...
0994                             sum(regress_results.h_coefs_cor(:,a)),median(R_collinear(a,:)), ...
0995                             iqr(R_collinear(a,:)),mx_p,mn_p);
0996                     end
0997                 end
0998             end
0999         else
1000             fprintf(fid,'Predictor\t#_of_Sig_Channels\t\tp-values\n');
1001             for a=1:2,
1002                 mn_p=min(regress_results.p_coefs_cor(:,a));
1003                 if mn_p>=p.Results.alpha,
1004                     %no significant effects for this predictor
1005                     fprintf(fid,'%s\t\t%d\t\t\tp>=%f\n',regress_results.predictor_names{a}, ...
1006                         sum(regress_results.h_coefs_cor(:,a)),mn_p);
1007                 else
1008                     %at least one significant effect for this predictor
1009                     sig_p_id=find(regress_results.p_coefs_cor(:,a)<p.Results.alpha);
1010                     mx_p=max(regress_results.p_coefs_cor(sig_p_id,a));
1011                     fprintf(fid,'%s\t\t%d\t\t%f>=sig p>=%f\n',regress_results.predictor_names{a}, ...
1012                         sum(regress_results.h_coefs_cor(:,a)),mx_p,mn_p);
1013                 end
1014             end
1015         end
1016         
1017         fprintf(fid,'**REGRESSION_RESULTS_PER_CHANNEL**\n');
1018         for c=1:n_chan,
1019             fprintf(fid,'Results_for_Channel: %s \n',regress_results.chanlocs(c).labels);
1020             fprintf(fid,'Predictor\tMean_Coefficient\t95%c_CI_lower_bound\t95%c_CI_upper_bound\tt-score\tp-value(Uncorrected)\tSignificant(Corrected)\tCohen''s_d\n', ...
1021                 37,37);
1022             for pred=1:n_pred+1,
1023                 %mean coefficient
1024                 %95% CI
1025                 %t-score
1026                 %p-value
1027                 %Cohen's d
1028                 if pred==1,
1029                     pred_name='Intercept';
1030                 else
1031                     pred_name=predictors{pred-1};
1032                 end
1033                 fprintf(fid,'%s \t%f \t%f \t%f \t%.3f \t%.3f \t%d \t%.2f\n', ...
1034                     pred_name,regress_results.mn_coefs(c,pred), ...
1035                     regress_results.low_ci(c,pred),regress_results.hi_ci(c,pred), ...
1036                     regress_results.t_coefs(c,pred),regress_results.p_coefs_uncor(c,pred), ...
1037                     regress_results.h_coefs_cor(c,pred),regress_results.d_coefs(c,pred));
1038             end
1039         end
1040         fclose(fid);
1041     end
1042 end
1043 
1044 %% Plot Results
1045 if p.Results.plot_topos && n_chan>1,
1046     sig_topo_coefs(regress_results);
1047     sig_topo_coefs(regress_results,'statistic','t');
1048 end
1049 
1050 %%% End of Main Function %%%
1051 
1052 
1053 function all_same=all_same_cell_elements(cell_array)
1054 %function to ensure that all elements a 1D cell array are the same
1055 
1056 n=length(cell_array);
1057 all_same=1;
1058 for a=2:n,
1059     if ~(isnan(cell_array{1}) && isnan(cell_array{a}))
1060         if ~isequal(cell_array{1},cell_array{a}),
1061             all_same=0;
1062             break;
1063         end
1064     end
1065 end
1066 
1067

Generated on Tue 10-May-2016 16:37:45 by m2html © 2005