Home > matlabmk > stats_tfrGND.m

stats_tfrGND

PURPOSE ^

stats_tfrGND() - Performs a paired-samples (i.e., repeated measures) t-

SYNOPSIS ^

function tfrGND=stats_tfrGND(tfrGND,binA,binB,varargin)

DESCRIPTION ^

 stats_tfrGND() - Performs a paired-samples (i.e., repeated measures) t-
                  test on the spectrogram in two bins of a MATLABmk tfrGND
                  variable with correction for multiple comparisons. The
                  analysis is done via the fieldtrip function
                  ft_freqstatistics.m.

 Usage:
  >> tfrGND=stats_tfrGND(tfrGND,binA,binB,varargin);

 Required Input:
   tfrGND  - A MATLABmk tfrGND variable. These are produced by the
             MATLABmk function tfrs2tfrGND.m. It contains spectrograms from 
             one or more participants, their grand averages, and
             associated information.
   binA    - One of the bins in the tfrGND variable. 
   binB    - One of the bins in the tfrGND variable. The analysis will be
             done by subtracting binB from binA.

 Optional Inputs:
   'freq_limits'   - [min max] Frequency limits (in Hz) of the frequency
                     band you wish to analyze. {default: lowest and highest
                     frequencies in the tfrGND variable}
   'time_limits'   - [min max] Time limits (in ms) of the window you wish
                     to analyze. {default: lowest and highest time 
                     points in the tfrGND variable}
   'tail'          - [1,0, or -1] An integer specifying the tail of the
                     hypothesis test.  "1" means upper-tailed (i.e., alternative 
                     hypothesis is that the spectrogram difference is greater 
                     than the mean of the null hypothesis).  "0" means two-
                     tailed (i.e., alternative hypothesis is that the 
                     spectrogram difference is not equal to the mean of the null
                     hypothesis). "-1" means lower-tailed (i.e., alternative 
                     hypothesis is that the spectrogram difference is less
                     than the mean of the null hypothesis). {default: 0}
   'alpha'         - A number between 0 and 1 specifying the family-wise
                     alpha level of the test. {default: 0.05}
   'correctm'      - [string] The method used to correct for multiple  
                     comparisons. Options are:
                       'max'     = tmax permutation based method that
                                   strongly controls the family-wise 
                                   error rate (FWER).
                       'cluster' = Cluster-based permutation test that
                                   weakly controls FWER. See Maris & 
                                   Oostenveld (2007) for details.
                                   {default}
                       'fdr_bh'  = Benjamini & Hochberg (1995) method for
                                   control of the false discovery rate.
                       'fdr_by'  = Benjamini & Yekutieli (1999) method for
                                   control of the false discovery rate.
                       'none'    = No correction for multiple comparisons. 
   'n_perm'        - The number of permutations to use in the test (if a 
                     permutation test is used).  As this value increases,
                     the test takes longer to compute and the results become 
                     more reliable.  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. 
                     {default: 1000}
   'clusteralpha'  - A number between 0 and 1 specifying the test-wise
                     alpha level threshold a variable needs to pass in order
                     to be included in a cluster.  Test-wise alpha levels 
                     are computed without correction for multiple comparisons. 
                     The smaller the value of 'cluteralpha' the more focal the 
                     clusters found by cluster-based test tend to be.  
                     'clusteralpha' should probably not have a value greater
                     than 5% since it could lead to declaring differences
                     as significant that would not have been declared 
                     significant if no correction for multiple comparisons
                     had been performed. This parameter only has an effect if
                     a cluster-based test is performed and does NOT affect
                     the family-wise error rate. {default: 0.05}
   'minnbchan'     - The minimum number of above threshold neighbors an
                     above threshold dependent variable has to have in order 
                     to be included in a cluseter. Having a non-zero value 
                     makes clusters more focal by preventing "bridges" 
                     between clusters.  A non-zero value will further bias the 
                     test against finding narrowly distributed clusters.
                     This only affects cluster-based tests. {default: 2}
   'neighbourdist' - All sensors within this distance are considered
                     neighbors for the purposes of the cluster-based test.
                     To get the approximate value of this parameter in cm, 
                     mulitply it by 8.9. {default: 0.61 which correspons 
                     approximately to 5.4 cm} 
   'clusterstatistic' - The statistic used for cluster based multiple
                        comparison correction.  This is the statistic that
                        is extracted from each random permutation of the
                        data. Options are:
                          'maxsum'  = The most extreme sum of the t-scores  
                                      across all clusters. {default}
                          'maxsize' = The size of the largest cluster.  
                          'max'     = The most extreme t-score across all
                                      the clusters.
   'units'         - ['dB' or 'raw'] If 'dB' spectrogram color scale will
                     be in units of decibels 10*log10(uV^2/Hz). If 'raw'
                     spectrogram color scale will be in units of uV^2/Hz.
                     {default: whatever the units were when the tfrGND
                     variable was first created}
   'bsln_type'     - The type of baseline used to normalize each
                     participant's data. Default is to use whatever baseline
                     type was used when the tfrGND variable was first 
                     created. Options are:
                       'relative' - Power at each time point is divided by 
                                    the mean power in the baseline window.
                       'absolute' - The mean power in the baseline window 
                                    is subtracted from the power at each 
                                    time point. 
   'bsln_wind'     - [min max] Time window (in ms) used to baseline the 
                     spectrograms {default: whatever baseline window was 
                     originally used with the tfrGND variable}
   'exclude_chans' - A cell array of channel labels (e.g., {'A2','lle'}) 
                     or a string channel label (e.g., 'A2') to exclude from the
                     analysis .  This option sacrifices spatial resolution
                     to increase test power by reducing the number of
                     comparisons. Use headinfo_spec.m to see the channel
                     labels stored in the tfrGND variable. 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 (e.g., {'RLOc','LLOc'})
                     or a string channel label (e.g., 'RLOc') to use in 
                     the analysis.  All other channels will be ignored. 
                     This option sacrifices spatial resolution to increase
                     test power by reducing the number of comparisons.
                     Use headinfo_spec.m to see the channel labels stored in the 
                     tfrGND variable. You cannot use both this option and 
                     'exclude_chans' (above). {default: not used, all channels 
                     included in test}
   'avgoverchan'   - ['yes' or 'no'] Perform the analysis on the mean of 
                     all included channels. Doing this sacrifices spatial 
                     resolution to increase test power by reducing the number of
                     comparisons. {default: 'no'}
   'avgovertime'   - ['yes' or 'no'] Perform the analysis on the mean of 
                     all included time windows. Doing this sacrifices temporal 
                     resolution to increase test power by reducing the number of
                     comparisons. {default: 'no'}
   'avgoverfreq'   - ['yes' or 'no'] Perform the analysis on the mean of 
                     all included frequencies. Doing this sacrifices temporal 
                     resolution to increase test power by reducing the number of
                     comparisons. {default: 'no'}

 Output:
   tfrGND    - MATLABmk tfrGND variable with fieldtrip formatted test 
               results stored in tfrGND.stats. Explanations of the various
               fields of tfrGND.stats are below. The fields vary somewhat
               depending on test parameters (e.g., two-tailed vs. one-tailed,
               permutation test vs. FDR control):
                 prob                - the p-value of each variable after being
                                       adjusted for multiple comparisons
                 posclusters         - the p-value and cluster statistic of each
                                       positive cluster. Note, the p-value is
                                       always the p-value for an UPPER TAILED test
                                       regardless of the actual tail of
                                       the test.
                 posclusterslabelmat - a matrix that specifies which positive cluster
                                       each variable belongs to (or 0 if the variable 
                                       does not belong to a positive cluster).
                 posdistribution     - the maximum cluster statistic for
                                       each random permutation of the data
                 negclusters         - the p-value and cluster statistic of each
                                       negative cluster. Note, the p-value is
                                       always the p-value for a LOWER TAILED test
                                       regardless of the actual tail of
                                       the test.
                 negclusterslabelmat - a matrix that specifies which negative cluster
                                       each variable belongs to (or 0 if the variable 
                                       does not belong to a negative cluster).
                 negdistribution:    - the minimum cluster statistic for
                                       each random permutation of the data                                   
                 mask                - a matrix with 1 for each variable with a 
                                       significant mult comp corrected p-value,
                                       0 otherwise. 
                 stat                - the t-score of each variable
                 df                  - the degrees of freedom for t-scores
                 critval             - the critical t-score(s) for significance
                 ref                 - the mean t-scores from all the
                                       random permutations
                 dimord              - What each dimension of matrices like 'prob,'
                                       'mask,' and 'stat' correspondes to (e.g.,
                                       which dimension corresponds to time, frequency, 
                                       and channel)
                 label               - Electrode names
                 freq                - Specific frequencies analyzed
                 time                - Center of moving time windows (in
                                       SECONDS)
                 cfg                 - The parameters used to call the
                                       fieldtrip function ft_freqstatistics.
                 correctm            - Which method was used for multiple 
                                       comparison correction.
                 bins                - The bins that were analyzed. A minus 
                                       sign will indicate which bin was 
                                       subtracted from which bin.

 Notes:
 -If you run out of memory trying to use this function, you can reduce
 memory load by:
   1) Using fewer permutations (if you're performing a permutation test)
   2) Analyzing a smaller frequency band
   3) Analyzing a shorter time window
   4) Computing spectrograms with fewer frequencies and using fewer time
   windows

 -Unlike a parametric test (e.g., an ANOVA), a discrete set of p-values
 are possible (at most the number of possible permutations).  Since the
 number of possible permutations grows rapdily with the number of
 participants, this is only issue for small sample sizes (e.g., 6
 participants).  When you have such a small sample size, the
 limited number of p-values may make the test less conservative (e.g., 
 you might be forced to use an alpha level of .0286 since it is the biggest
 possible alpha level less than .05).

 -When doing two-tailed test with cluster-based permutation test it is
 possible to get multiple comparison corrected p-values as big as 2.  When
 using FDR control, multiple comparisons corrected p-values (often called
 q-values for FDR control) can also be bigger than 1.

 

 References:
  Benjamini, Y. & Hochberg, Y. (1995) Controlling the false discovery
    rate: A practical and powerful approach to multiple testing. Journal
    of the Royal Statistical Society, Series B (Methodological). 57(1),
    289-300.

  Benjamini, Y. & Yekutieli, D. (2001) The control of the false discovery
    rate in multiple testing under dependency. The Annals of Statistics.
    29(4), 1165-1188.

  Manly, B.F.J. (1997) Randomization, Bootstrap, and Monte Carlo Methods in
    Biology. 2nd ed. Chapman and Hall, London.

  Maris, E., & Oostenveld, R. (2007). Nonparametric statistical testing of 
    EEG- and MEG-data. Journal of Neuroscience Methods, 164(1), 177-190. 


 Author:
 David Groppe
 Kutaslab, 1/2011

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 % stats_tfrGND() - Performs a paired-samples (i.e., repeated measures) t-
0002 %                  test on the spectrogram in two bins of a MATLABmk tfrGND
0003 %                  variable with correction for multiple comparisons. The
0004 %                  analysis is done via the fieldtrip function
0005 %                  ft_freqstatistics.m.
0006 %
0007 % Usage:
0008 %  >> tfrGND=stats_tfrGND(tfrGND,binA,binB,varargin);
0009 %
0010 % Required Input:
0011 %   tfrGND  - A MATLABmk tfrGND variable. These are produced by the
0012 %             MATLABmk function tfrs2tfrGND.m. It contains spectrograms from
0013 %             one or more participants, their grand averages, and
0014 %             associated information.
0015 %   binA    - One of the bins in the tfrGND variable.
0016 %   binB    - One of the bins in the tfrGND variable. The analysis will be
0017 %             done by subtracting binB from binA.
0018 %
0019 % Optional Inputs:
0020 %   'freq_limits'   - [min max] Frequency limits (in Hz) of the frequency
0021 %                     band you wish to analyze. {default: lowest and highest
0022 %                     frequencies in the tfrGND variable}
0023 %   'time_limits'   - [min max] Time limits (in ms) of the window you wish
0024 %                     to analyze. {default: lowest and highest time
0025 %                     points in the tfrGND variable}
0026 %   'tail'          - [1,0, or -1] An integer specifying the tail of the
0027 %                     hypothesis test.  "1" means upper-tailed (i.e., alternative
0028 %                     hypothesis is that the spectrogram difference is greater
0029 %                     than the mean of the null hypothesis).  "0" means two-
0030 %                     tailed (i.e., alternative hypothesis is that the
0031 %                     spectrogram difference is not equal to the mean of the null
0032 %                     hypothesis). "-1" means lower-tailed (i.e., alternative
0033 %                     hypothesis is that the spectrogram difference is less
0034 %                     than the mean of the null hypothesis). {default: 0}
0035 %   'alpha'         - A number between 0 and 1 specifying the family-wise
0036 %                     alpha level of the test. {default: 0.05}
0037 %   'correctm'      - [string] The method used to correct for multiple
0038 %                     comparisons. Options are:
0039 %                       'max'     = tmax permutation based method that
0040 %                                   strongly controls the family-wise
0041 %                                   error rate (FWER).
0042 %                       'cluster' = Cluster-based permutation test that
0043 %                                   weakly controls FWER. See Maris &
0044 %                                   Oostenveld (2007) for details.
0045 %                                   {default}
0046 %                       'fdr_bh'  = Benjamini & Hochberg (1995) method for
0047 %                                   control of the false discovery rate.
0048 %                       'fdr_by'  = Benjamini & Yekutieli (1999) method for
0049 %                                   control of the false discovery rate.
0050 %                       'none'    = No correction for multiple comparisons.
0051 %   'n_perm'        - The number of permutations to use in the test (if a
0052 %                     permutation test is used).  As this value increases,
0053 %                     the test takes longer to compute and the results become
0054 %                     more reliable.  Manly (1997) suggests using at least
0055 %                     1000 permutations for an alpha level of 0.05 and at
0056 %                     least 5000 permutations for an alpha level of 0.01.
0057 %                     {default: 1000}
0058 %   'clusteralpha'  - A number between 0 and 1 specifying the test-wise
0059 %                     alpha level threshold a variable needs to pass in order
0060 %                     to be included in a cluster.  Test-wise alpha levels
0061 %                     are computed without correction for multiple comparisons.
0062 %                     The smaller the value of 'cluteralpha' the more focal the
0063 %                     clusters found by cluster-based test tend to be.
0064 %                     'clusteralpha' should probably not have a value greater
0065 %                     than 5% since it could lead to declaring differences
0066 %                     as significant that would not have been declared
0067 %                     significant if no correction for multiple comparisons
0068 %                     had been performed. This parameter only has an effect if
0069 %                     a cluster-based test is performed and does NOT affect
0070 %                     the family-wise error rate. {default: 0.05}
0071 %   'minnbchan'     - The minimum number of above threshold neighbors an
0072 %                     above threshold dependent variable has to have in order
0073 %                     to be included in a cluseter. Having a non-zero value
0074 %                     makes clusters more focal by preventing "bridges"
0075 %                     between clusters.  A non-zero value will further bias the
0076 %                     test against finding narrowly distributed clusters.
0077 %                     This only affects cluster-based tests. {default: 2}
0078 %   'neighbourdist' - All sensors within this distance are considered
0079 %                     neighbors for the purposes of the cluster-based test.
0080 %                     To get the approximate value of this parameter in cm,
0081 %                     mulitply it by 8.9. {default: 0.61 which correspons
0082 %                     approximately to 5.4 cm}
0083 %   'clusterstatistic' - The statistic used for cluster based multiple
0084 %                        comparison correction.  This is the statistic that
0085 %                        is extracted from each random permutation of the
0086 %                        data. Options are:
0087 %                          'maxsum'  = The most extreme sum of the t-scores
0088 %                                      across all clusters. {default}
0089 %                          'maxsize' = The size of the largest cluster.
0090 %                          'max'     = The most extreme t-score across all
0091 %                                      the clusters.
0092 %   'units'         - ['dB' or 'raw'] If 'dB' spectrogram color scale will
0093 %                     be in units of decibels 10*log10(uV^2/Hz). If 'raw'
0094 %                     spectrogram color scale will be in units of uV^2/Hz.
0095 %                     {default: whatever the units were when the tfrGND
0096 %                     variable was first created}
0097 %   'bsln_type'     - The type of baseline used to normalize each
0098 %                     participant's data. Default is to use whatever baseline
0099 %                     type was used when the tfrGND variable was first
0100 %                     created. Options are:
0101 %                       'relative' - Power at each time point is divided by
0102 %                                    the mean power in the baseline window.
0103 %                       'absolute' - The mean power in the baseline window
0104 %                                    is subtracted from the power at each
0105 %                                    time point.
0106 %   'bsln_wind'     - [min max] Time window (in ms) used to baseline the
0107 %                     spectrograms {default: whatever baseline window was
0108 %                     originally used with the tfrGND variable}
0109 %   'exclude_chans' - A cell array of channel labels (e.g., {'A2','lle'})
0110 %                     or a string channel label (e.g., 'A2') to exclude from the
0111 %                     analysis .  This option sacrifices spatial resolution
0112 %                     to increase test power by reducing the number of
0113 %                     comparisons. Use headinfo_spec.m to see the channel
0114 %                     labels stored in the tfrGND variable. You cannot
0115 %                     use both this option and 'include_chans' (below).{default:
0116 %                     not used, all channels included in test}
0117 %   'include_chans' - A cell array of channel labels (e.g., {'RLOc','LLOc'})
0118 %                     or a string channel label (e.g., 'RLOc') to use in
0119 %                     the analysis.  All other channels will be ignored.
0120 %                     This option sacrifices spatial resolution to increase
0121 %                     test power by reducing the number of comparisons.
0122 %                     Use headinfo_spec.m to see the channel labels stored in the
0123 %                     tfrGND variable. You cannot use both this option and
0124 %                     'exclude_chans' (above). {default: not used, all channels
0125 %                     included in test}
0126 %   'avgoverchan'   - ['yes' or 'no'] Perform the analysis on the mean of
0127 %                     all included channels. Doing this sacrifices spatial
0128 %                     resolution to increase test power by reducing the number of
0129 %                     comparisons. {default: 'no'}
0130 %   'avgovertime'   - ['yes' or 'no'] Perform the analysis on the mean of
0131 %                     all included time windows. Doing this sacrifices temporal
0132 %                     resolution to increase test power by reducing the number of
0133 %                     comparisons. {default: 'no'}
0134 %   'avgoverfreq'   - ['yes' or 'no'] Perform the analysis on the mean of
0135 %                     all included frequencies. Doing this sacrifices temporal
0136 %                     resolution to increase test power by reducing the number of
0137 %                     comparisons. {default: 'no'}
0138 %
0139 % Output:
0140 %   tfrGND    - MATLABmk tfrGND variable with fieldtrip formatted test
0141 %               results stored in tfrGND.stats. Explanations of the various
0142 %               fields of tfrGND.stats are below. The fields vary somewhat
0143 %               depending on test parameters (e.g., two-tailed vs. one-tailed,
0144 %               permutation test vs. FDR control):
0145 %                 prob                - the p-value of each variable after being
0146 %                                       adjusted for multiple comparisons
0147 %                 posclusters         - the p-value and cluster statistic of each
0148 %                                       positive cluster. Note, the p-value is
0149 %                                       always the p-value for an UPPER TAILED test
0150 %                                       regardless of the actual tail of
0151 %                                       the test.
0152 %                 posclusterslabelmat - a matrix that specifies which positive cluster
0153 %                                       each variable belongs to (or 0 if the variable
0154 %                                       does not belong to a positive cluster).
0155 %                 posdistribution     - the maximum cluster statistic for
0156 %                                       each random permutation of the data
0157 %                 negclusters         - the p-value and cluster statistic of each
0158 %                                       negative cluster. Note, the p-value is
0159 %                                       always the p-value for a LOWER TAILED test
0160 %                                       regardless of the actual tail of
0161 %                                       the test.
0162 %                 negclusterslabelmat - a matrix that specifies which negative cluster
0163 %                                       each variable belongs to (or 0 if the variable
0164 %                                       does not belong to a negative cluster).
0165 %                 negdistribution:    - the minimum cluster statistic for
0166 %                                       each random permutation of the data
0167 %                 mask                - a matrix with 1 for each variable with a
0168 %                                       significant mult comp corrected p-value,
0169 %                                       0 otherwise.
0170 %                 stat                - the t-score of each variable
0171 %                 df                  - the degrees of freedom for t-scores
0172 %                 critval             - the critical t-score(s) for significance
0173 %                 ref                 - the mean t-scores from all the
0174 %                                       random permutations
0175 %                 dimord              - What each dimension of matrices like 'prob,'
0176 %                                       'mask,' and 'stat' correspondes to (e.g.,
0177 %                                       which dimension corresponds to time, frequency,
0178 %                                       and channel)
0179 %                 label               - Electrode names
0180 %                 freq                - Specific frequencies analyzed
0181 %                 time                - Center of moving time windows (in
0182 %                                       SECONDS)
0183 %                 cfg                 - The parameters used to call the
0184 %                                       fieldtrip function ft_freqstatistics.
0185 %                 correctm            - Which method was used for multiple
0186 %                                       comparison correction.
0187 %                 bins                - The bins that were analyzed. A minus
0188 %                                       sign will indicate which bin was
0189 %                                       subtracted from which bin.
0190 %
0191 % Notes:
0192 % -If you run out of memory trying to use this function, you can reduce
0193 % memory load by:
0194 %   1) Using fewer permutations (if you're performing a permutation test)
0195 %   2) Analyzing a smaller frequency band
0196 %   3) Analyzing a shorter time window
0197 %   4) Computing spectrograms with fewer frequencies and using fewer time
0198 %   windows
0199 %
0200 % -Unlike a parametric test (e.g., an ANOVA), a discrete set of p-values
0201 % are possible (at most the number of possible permutations).  Since the
0202 % number of possible permutations grows rapdily with the number of
0203 % participants, this is only issue for small sample sizes (e.g., 6
0204 % participants).  When you have such a small sample size, the
0205 % limited number of p-values may make the test less conservative (e.g.,
0206 % you might be forced to use an alpha level of .0286 since it is the biggest
0207 % possible alpha level less than .05).
0208 %
0209 % -When doing two-tailed test with cluster-based permutation test it is
0210 % possible to get multiple comparison corrected p-values as big as 2.  When
0211 % using FDR control, multiple comparisons corrected p-values (often called
0212 % q-values for FDR control) can also be bigger than 1.
0213 %
0214 %
0215 %
0216 % References:
0217 %  Benjamini, Y. & Hochberg, Y. (1995) Controlling the false discovery
0218 %    rate: A practical and powerful approach to multiple testing. Journal
0219 %    of the Royal Statistical Society, Series B (Methodological). 57(1),
0220 %    289-300.
0221 %
0222 %  Benjamini, Y. & Yekutieli, D. (2001) The control of the false discovery
0223 %    rate in multiple testing under dependency. The Annals of Statistics.
0224 %    29(4), 1165-1188.
0225 %
0226 %  Manly, B.F.J. (1997) Randomization, Bootstrap, and Monte Carlo Methods in
0227 %    Biology. 2nd ed. Chapman and Hall, London.
0228 %
0229 %  Maris, E., & Oostenveld, R. (2007). Nonparametric statistical testing of
0230 %    EEG- and MEG-data. Journal of Neuroscience Methods, 164(1), 177-190.
0231 %
0232 %
0233 % Author:
0234 % David Groppe
0235 % Kutaslab, 1/2011
0236 
0237 %%%%%%%%%%%%%%%% Revision History  %%%%%%%%%%%%%%%%%
0238 %
0239 
0240 %% Other Notes
0241 %-cfg.clusteralpha is the threshold for being included in a cluster.
0242 %Fieldtrip's code automatically figures out if a 1 or 2 sided test
0243 %should be computed when deriving the test-wise p-value for each test
0244 %
0245 %-Another possible value for the optional argument 'clusterstatistic' is
0246 %'wcm'.  I have no idea what it means. It's not commented on the fieldtrip
0247 %website nor is it explained in the code.  The function in which it is
0248 %actually used is clusterstat.m.
0249 %
0250 %-If you set cfg.method='montecarlo' you get test-wise p-values via a
0251 %permutation test and then (optionally) correct for multiple comparisons
0252 %with any of the following methods: 'no', 'max', cluster', 'bonferoni',
0253 %'holms', 'fdr' with the cfg parameter cfg.correctm.  Right now, stats_tfrGND.m
0254 %only supports 'cluster' and 'max'.  For doing FDR correction I think it's
0255 %better to use an analytic test because the repeated-measures t-test is
0256 %very robust to violations of normality and will perform better when sample
0257 %sizes (or the number of permutations) are small.
0258 %
0259 %-The tmax procedure is implemented using Fieldtrip's built in function,
0260 %which I don't think is as accurate as our MATLABmk code.  It should only
0261 %be a problem for small sample sizes or numbers of permutations.
0262 %
0263 %-Fieldtrip stats flow of control is:
0264 % 1) Call ft_freqstatistics
0265 % 2) Go to statistics_wrapper.m
0266 % 3) Go to statistics_montecarlo (for permutation based methods)
0267 % 4) Go to clusterstat.m for cluster-based tests
0268 %
0269 %-Note, at some point between January and March of 2011, the p-values in
0270 % tfrGND.stats{neo_test}.posclusters(a).prob were changed.  Originally, the
0271 % p-values were for one-tailed tests (regardless of the actual tail of the
0272 % test).  Now, they accurately reflect the tail of the test.  The change
0273 % was made by the FieldTrip people.
0274 %
0275 
0276 
0277 %%% Future Work:
0278 %
0279 
0280 function tfrGND=stats_tfrGND(tfrGND,binA,binB,varargin)
0281 
0282 p=inputParser;
0283 p.addRequired('tfrGND',@isstruct);
0284 p.addRequired('binA',@(x) isnumeric(x) && length(x)==1);
0285 p.addRequired('binB',@(x) isnumeric(x) && length(x)==1);
0286 p.addParamValue('freq_limits',[],@(x) isnumeric(x) && length(x)==2);
0287 p.addParamValue('time_limits',[],@(x) isnumeric(x) && length(x)==2);
0288 p.addParamValue('correctm','cluster',@ischar);
0289 p.addParamValue('clusterstatistic','maxsum',@(x) (strcmpi(x,'maxsum') || strcmpi(x,'maxsize') || strcmpi(x,'max')));
0290 p.addParamValue('alpha',.05,@(x) isnumeric(x) && (length(x)==1) && (x<=1) && (x>0));
0291 p.addParamValue('clusteralpha',.05,@(x) isnumeric(x) && (length(x)==1) && (x<=1) && (x>0));
0292 p.addParamValue('tail',0,@(x) isnumeric(x) && length(x)==1);
0293 p.addParamValue('neighbourdist',.61,@(x) isnumeric(x) && length(x)==1);
0294 p.addParamValue('minnbchan',2,@(x) isnumeric(x) && length(x)==1 && (x>=0));
0295 p.addParamValue('n_perm',1000,@(x) isnumeric(x) && length(x)==1 && (x>0));
0296 p.addParamValue('units',[],@(x) strcmpi(x,'dB') || strcmpi(x,'raw'));
0297 p.addParamValue('bsln_wind',[],@(x) isnumeric(x) && length(x)==2);
0298 p.addParamValue('bsln_type',[],@(x) strcmpi(x,'relative') || strcmpi(x,'absolute'));
0299 p.addParamValue('exclude_chans',[],@(x) ischar(x) || iscell(x));
0300 p.addParamValue('include_chans',[],@(x) ischar(x) || iscell(x));
0301 p.addParamValue('avgoverchan','no',@(x) strcmpi(x,'yes') || strcmpi(x,'no'));
0302 p.addParamValue('avgovertime','no',@(x) strcmpi(x,'yes') || strcmpi(x,'no'));
0303 p.addParamValue('avgoverfreq','no',@(x) strcmpi(x,'yes') || strcmpi(x,'no'));
0304 
0305 p.parse(tfrGND,binA,binB,varargin{:});
0306 
0307 %%%% I. Transform spectrograms to dB or re-baseline (if requested)
0308 if isempty(p.Results.bsln_wind),
0309     bsln_wind=tfrGND.bsln_wind; %note p.Results.bsln_wind should be in units of ms
0310 else
0311     bsln_wind=p.Results.bsln_wind;
0312 end
0313 if isempty(p.Results.bsln_type),
0314     bsln_type=tfrGND.bsln_type;
0315 else
0316     bsln_type=p.Results.bsln_type;
0317 end
0318 if isempty(p.Results.units),
0319     units=tfrGND.units;
0320 else
0321     units=p.Results.units;
0322 end
0323 if ~strcmpi(units,tfrGND.units) || ...
0324         ~isequal(bsln_wind,tfrGND.bsln_wind) || ...
0325         ~strcmpi(bsln_type,tfrGND.bsln_type)
0326     tfrGND=baseline_tfrGND(tfrGND,units,bsln_wind,bsln_type);
0327 end
0328 
0329 
0330 %%%% II. Generic testing paramters (common to all multiple comparison correction methods)
0331 cfg = [];
0332 
0333 %% Channel selection
0334 if ~isempty(p.Results.include_chans)
0335     if ~isempty(p.Results.exclude_chans),
0336         error('You cannot use BOTH include_chans and exclude_chans options.');
0337     end
0338     if ischar(p.Results.include_chans)
0339         cfg.channel{1}=p.Results.include_chans; %cfg.channel needs to be a cell array I believe
0340     else
0341         cfg.channel=p.Results.include_chans;
0342     end
0343 elseif ~isempty(p.Results.exclude_chans),
0344     if ischar(p.Results.exclude_chans)
0345         exclude{1}=p.Results.exclude_chans; %convert to cell array
0346     else
0347         exclude=p.Results.exclude_chans;
0348     end
0349     n_exclude=length(exclude);
0350     cfg.channel=cell(1,n_exclude+1);
0351     cfg.channel{1}='all';
0352     for a=1:n_exclude,
0353         cfg.channel{a+1}=['-' exclude{a}];
0354     end
0355 else
0356     %default
0357     cfg.channel          = {'all'};
0358 end
0359 
0360 %% Other paramaters
0361 cfg.tail             = p.Results.tail;
0362 if cfg.tail,
0363     cfg.alpha        = p.Results.alpha;
0364 else
0365     cfg.alpha        = p.Results.alpha/2; %for a two-tailed test FWER=cfg.alpha*2; presumably this just effects the mask
0366     %this appears to still be accurate despite the changes Fieldtrip made
0367     %to stats{#}.negclusters and stats{#}.posclusters
0368 end
0369 cfg.statistic        = 'depsamplesT';
0370 cfg.correctm         = p.Results.correctm;
0371 cfg.correcttail      = 'prob'; %this makes the p-values of ft_freqstatistics reflect the tail of the analysis
0372 % (i.e., the p-values in tfrGND.stats{neo_test}.prob).  Note that the
0373 % p-values in tfrGND.stats{neo_test}.negclusters and
0374 % tfrGND.stats{neo_test}.posclusters are one-tailed p-values
0375 
0376 cfg.avgoverchan=p.Results.avgoverchan;
0377 cfg.avgovertime=p.Results.avgovertime;
0378 cfg.avgoverfreq=p.Results.avgoverfreq;
0379 
0380 if isempty(p.Results.time_limits),
0381     cfg.latency=[tfrGND.ftrip.time(1) tfrGND.ftrip.time(end)];
0382 else
0383     cfg.latency=p.Results.time_limits/1000; %convert from ms to sec
0384     %error check
0385     if max(cfg.latency)>max(tfrGND.ftrip.time)
0386         error('Specified maximum time limit %g ms exceeds data (i.e., tfrGND) max time limit %g ms.', ...
0387             max(cfg.latency)*1000,max(tfrGND.ftrip.time)*1000);
0388     elseif min(cfg.latency)<min(tfrGND.ftrip.time)
0389         error('Specified minimum time limit %g ms exceeds data (i.e., tfrGND) min time limit %g ms.', ...
0390             min(cfg.latency)*1000,min(tfrGND.ftrip.time)*1000);
0391     end
0392 end
0393 if isempty(p.Results.freq_limits),
0394     cfg.frequency=[tfrGND.ftrip.freq(1) tfrGND.ftrip.freq(end)];
0395     %error check
0396     if max(cfg.frequency)>max(tfrGND.ftrip.freq)
0397         error('Specified maximum time limit %g Hz exceeds data (i.e., tfrGND) max time limit %g Hz.', ...
0398             max(cfg.frequency),max(tfrGND.ftrip.freq));
0399     elseif min(cfg.frequency)<min(tfrGND.ftrip.freq)
0400         error('Specified minimum time limit %g Hz exceeds data (i.e., tfrGND) min time limit %g Hz.', ...
0401             min(cfg.frequency),min(tfrGND.ftrip.freq));
0402     end
0403 else
0404     cfg.frequency=p.Results.freq_limits;
0405 end
0406 
0407 %% Parameters that vary depending on correction for multiple comparisons
0408 if strcmpi(cfg.correctm,'cluster'),
0409     cfg.method           = 'montecarlo';
0410     cfg.clusterstatistic = p.Results.clusterstatistic;
0411     cfg.clusteralpha     = p.Results.clusteralpha;
0412     cfg.minnbchan        = p.Results.minnbchan;
0413     cfg.numrandomization = p.Results.n_perm; %this massively eats up memory (I can get 500 to work though)
0414     cfg.neighbourdist=p.Results.neighbourdist; % This is approximately 5.4 cm (assuming a spherical head with 56 cm circumference)
0415                            % It seems to work well for 26 channel cap
0416     fprintf('Minimal number of above threshold neighbors required for cluster membership (i.e., minnbchan parameter of ft_freqstatistics): %d\n', ...
0417        cfg.minnbchan);          
0418 elseif strcmpi(cfg.correctm,'fdr_bh') || strcmpi(cfg.correctm,'fdr_by') || strcmpi(cfg.correctm,'none'),
0419     cfg.method          = 'analytic'; %this won't correct for multiple comparisons, but we can do that later
0420     
0421     %Alternatively, you could use the code below that uses a permutation
0422     %test to get test-wise p-values
0423     %cfg.method           = 'montecarlo';
0424     %cfg.correctm         = 'fdr';
0425     %cfg.numrandomization = p.Results.n_perm;
0426 elseif strcmpi(cfg.correctm,'max'),
0427     cfg.method           = 'montecarlo';
0428     cfg.numrandomization = p.Results.n_perm;
0429 else
0430     error('%s is not currently a supported method for multiple comparison correction.', ...
0431         p.Results.correctm);
0432 end
0433 
0434 %% Create design matrix
0435 n_subs=size(tfrGND.indiv{1},1);
0436 design = zeros(2,2*n_subs);
0437 for i = 1:n_subs
0438   design(1,i) = i;
0439 end
0440 for i = 1:n_subs
0441   design(1,n_subs+i) = i;
0442 end
0443 design(2,1:n_subs)        = 1;
0444 design(2,n_subs+1:2*n_subs) = 2;
0445 
0446 cfg.design   = design;
0447 cfg.uvar     = 1;
0448 cfg.ivar     = 2;
0449 
0450 
0451 %% Extract spectrograms from desired bins into dummy fieldtrip variables &
0452 % perform t-tests
0453 cond1=tfrGND.ftrip;
0454 cond1.dimord='subj_chan_freq_time';
0455 cond1.powspctrm=tfrGND.indiv{binA};
0456 
0457 cond2=tfrGND.ftrip;
0458 cond2.dimord='subj_chan_freq_time';
0459 cond2.powspctrm=tfrGND.indiv{binB};
0460 n_tests=length(tfrGND.stats);
0461 neo_test=n_tests+1;
0462 tfrGND.stats{neo_test}=ft_freqstatistics(cfg,cond1,cond2); %perform the test
0463 tfrGND.stats{neo_test}.correctm=p.Results.correctm;
0464 tfrGND.stats{neo_test}.family_alpha=p.Results.alpha;
0465 tfrGND.stats{neo_test}.bins=[num2str(binA) '-' num2str(binB)];
0466 
0467 
0468 %% Command line summary of results
0469 if strcmpi(cfg.correctm,'cluster'),
0470     if isfield(tfrGND.stats{neo_test},'posclusters')
0471         npc=length(tfrGND.stats{neo_test}.posclusters);
0472         sig_p=0;
0473         if npc,
0474             pc_pvals=ones(1,npc);
0475         end
0476         for a=1:npc,
0477             pc_pvals(a)=tfrGND.stats{neo_test}.posclusters(a).prob;
0478             sig_p=sig_p+(tfrGND.stats{neo_test}.posclusters(a).prob<=p.Results.alpha);
0479         end
0480         fprintf('Number of positive clusters found: %d\n',npc);
0481         fprintf('Number of *significant* positive clusters: %d\n',sig_p);
0482         if npc
0483             fprintf('Min/max positive cluster p-value: %g/%g\n',min(pc_pvals),max(pc_pvals));
0484         end
0485     end
0486     
0487     if isfield(tfrGND.stats{neo_test},'negclusters')
0488         nnc=length(tfrGND.stats{neo_test}.negclusters);
0489         sig_n=0;
0490         if nnc,
0491             nc_pvals=ones(1,nnc);
0492         end
0493         for a=1:nnc,
0494             sig_n=sig_n+(tfrGND.stats{neo_test}.negclusters(a).prob<=p.Results.alpha);
0495             nc_pvals(a)=tfrGND.stats{neo_test}.negclusters(a).prob;
0496         end
0497         fprintf('Number of negative clusters found: %d\n',nnc);
0498         fprintf('Number of *significant* negative clusters: %d\n',sig_n);
0499         if nnc
0500             fprintf('Min/max negative cluster p-value: %g/%g\n',min(nc_pvals),max(nc_pvals));
0501         end
0502     end
0503 elseif strcmpi(cfg.correctm,'fdr_bh'),
0504     %correct p-values using Benjamini-Hochberg method.  Note adjusted p-values may be
0505     %greater than 1.
0506     fprintf('NOW correcting for multiple comparisons with Benjamini & Hochberg FDR control algorithm.\n');
0507     [h, crit_p, tfrGND.stats{neo_test}.prob]=fdr_bh(tfrGND.stats{neo_test}.prob);
0508     tfrGND.stats{neo_test}.mask=tfrGND.stats{neo_test}.prob<=p.Results.alpha;
0509     clear h crit_p; %not needed
0510 elseif strcmpi(cfg.correctm,'fdr_by'),
0511     %correct p-values using Benjamini-Yekutieli method.  Note adjusted p-values may be
0512     %greater than 1.
0513      fprintf('NOW correcting for multiple comparisons with Benjamini & Yekutieli FDR control algorithm.\n');
0514     [h, crit_p, tfrGND.stats{neo_test}.prob]=fdr_bh(tfrGND.stats{neo_test}.prob,.05,'dep');
0515     tfrGND.stats{neo_test}.mask=tfrGND.stats{neo_test}.prob<=p.Results.alpha;
0516     clear h crit_p; %not needed
0517 end
0518 
0519 
0520 if ~strcmpi(cfg.correctm,'cluster'),
0521     if strcmpi(cfg.correctm(1:3),'fdr'),
0522         pORq='q';
0523     else
0524         pORq='p';
0525     end
0526     
0527     %summarize results
0528     mn_p=min(min(min(tfrGND.stats{neo_test}.prob)));
0529     mx_p=max(max(max(tfrGND.stats{neo_test}.prob)));
0530     fprintf('Min/Max %c-values: %g/%g\n',pORq,mn_p,mx_p);
0531     sig_ids=find(tfrGND.stats{neo_test}.prob<=p.Results.alpha);
0532     if isempty(sig_ids),
0533         fprintf('No comparisons are significant (%c<=%g)\n',pORq,p.Results.alpha);
0534     else
0535         mn_p=min(min(min(tfrGND.stats{neo_test}.prob(sig_ids))));
0536         mx_p=max(max(max(tfrGND.stats{neo_test}.prob(sig_ids))));
0537         fprintf('Min/max significant %c-values: %g/%g\n',pORq,mn_p,mx_p);
0538     end
0539 end
0540 
0541 %tag on baseline and unit information
0542 tfrGND.stats{neo_test}.units=units;
0543 tfrGND.stats{neo_test}.bsln_wind=bsln_wind;
0544 tfrGND.stats{neo_test}.bsln_type=bsln_type;
0545 
0546 %Indicate tfrGND variable hasn't been saved since last change
0547 tfrGND.saved='no';
0548

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