Home > matlabmk > tfdrGRP.m

tfdrGRP

PURPOSE ^

tfdrGRP() - Tests the null hypothesis that the grand average voltage

SYNOPSIS ^

function [GRP, p_values, data_t, crit_t, adj_p]=tfdrGRP(GRP_or_fname,bin,varargin)

DESCRIPTION ^

 tfdrGRP() - Tests the null hypothesis that the grand average voltage
             of a between-subject difference wave or ERP averaged across two
             groups is mu (usually 0) using t-tests with false discovery
             rate (FDR) control to correct for multiple comparisons.  This
             function requires individual subject ERPs to be stored in a 
             "GRP" structure and outputs the test results in a 
             number of graphical and text formats. For analogous within-
             subject comparisons use the function tfdrGND.m.
               Note, when applied to a bin that is the mean ERP across two
             groups (i.e., NOT a difference wave), a one-sample test is
             executed.
             
 Usage:
  >> [GRP, p_values, data_t, crit_t]=tfdrGRP(GRP_or_fname,bin,varargin)

 Required Inputs:
   GRP_or_fname - A GRP structure variable or the filename of a 
                  GRP structure that has been saved to disk.  To 
                  create a GRP variable from Kutaslab ERP files (e.g.,
                  *.mas files) use GNDs2GRP.m.  See Mass Univariate ERP
                  Toolbox documentation for detailed information about the
                  format of a GRP variable. If you specifiy a filename be 
                  sure to include the file's path, unless the file is in
                  the current working directory.
   bin          - [integer] The bin to contrast against the mean of the
                  null hypothesis. Use the function headinfo.m to see what 
                  bins are stored in a GRP variable.  Use the function 
                  bin_opGRP.m to create a difference wave between two bins 
                  whose significance you can test with this function.

 Optional Inputs:
   tail          - [1 | 0 | -1] An integer specifying the tail of the
                   hypothesis test.  "1" means upper-tailed (i.e., alternative 
                   hypothesis is that the ERP/difference wave is greater 
                   than mu).  "0" means two-tailed (i.e., alternative hypothesis
                   is that the ERP/difference wave is not equal to mu).  
                   "-1" means lower-tailed (i.e., alternative hypothesis
                   is that the ERP/difference wave is less than mu).
                   {default: 0}
   q             - A number between 0 and 1 specifying the family-wise
                   q level of the test. q is the upper bound on the 
                   expected proportion of rejected null hypotheses that are
                   false rejections (i.e., the FDR). {default: 0.05}
   method        - ['bh', 'by', or 'bky'] The procedure used to control
                   the FDR. 'bh' is the classic Benjamini & Hochberg (1995)
                   procedure, which is guaranteed to control FDR when the 
                   tests are independent or positively dependent (e.g., 
                   positively correlated Gaussians). 'by' is a much more
                   conservative version of 'bh' that always controls FDR
                   (regardless of the dependency structure of the tests--
                   Benjamini & Yekutieli, 2001). 'bky' is a "two-stage"
                   version of 'bh' that is more powerful than 'bh' when a 
                   lot of the null hypotheses are false (Benjamini, Krieger, &
                   Yekutieli, 2006).  'bky' is guaranteed to control FDR when the
                   tests are independent and tends to be slightly less
                   powerful than 'bh' when few or no null hypothese are
                   false.
   time_wind     - 2D matrix of pairs of time values specifying the beginning 
                   and end of one or more time windows in ms (e.g., 
                   [160 180; 350 550]).  Every single time point in 
                   the time window will be individually tested (i.e.,
                   maximal temporal resolution) if mean_wind option is
                   NOT used. Note, boundaries of time window(s) may not 
                   exactly correspond to desired time window boundaries 
                   because of temporal digitization (i.e., you only have
                   samples every so many ms). {default: 0 ms to the end of
                   the epoch}
   time_block_dur- [integers] A number or numbers (in milliseconds) 
                   specifying a duration of time blocks in which the time 
                   windows specified by time_wind will be divided.  For
                   example, if time_wind=[300 600] and time_block_dur=100,
                   the 300 to 600 ms time window will be sub-divided into
                   100 ms windows (i.e., time_wind will equal [300 396;
                   400 496; 500 596]).  This is an easy way to break up
                   larger time windows of interest into smaller windows
                   for mean window analysis (if mean_wind option is set to
                   'yes').  If you specify multiple time windows with
                   time_wind, you can break them up using durations of
                   different lengths.  For example, if time_wind=[150 250;
                   400 900] and time_block_dur=[25 100], the first time
                   window (150 to 250 ms) will be broken up into 25 ms
                   windows and the second window (400 to 900 ms) will be
                   broken up into 100 ms windows. {default: not used}
   mean_wind     - ['yes' or 'no'] If 'yes', the t-tests will be performed
                   on the mean amplitude within each time window specified 
                   by time_wind.  This sacrifices temporal resolution 
                   to increase test power by reducing the number of 
                   comparisons.  If 'no', every single time point within
                   time_wind's time windows will be tested individually.
                   {default: 'no'}
   null_mean     - [number] The mean of the null hypothesis (i.e., mu) in 
                   units of microvolts). {default: 0}
   exclude_chans - A cell array of channel labels to exclude from the
                   t-tests (e.g., {'A2','lle','rhe'}).  This option 
                   sacrifices spatial resolution to increase test power by 
                   reducing the number of comparisons. Use headinfo.m to see
                   the channel labels stored in the GRP 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 to use in the t-tests
                   (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.
                   Use headinfo.m to see the channel labels stored in the GRP
                   variable. You cannot use both this option and 
                   'exclude_chans' (above). {default: not used, all channels 
                   included in test}
   verblevel     - An integer specifiying the amount of information you want
                   this function to provide about what it is doing during runtime.
                    Options are:
                      0 - quiet, only show errors, warnings, and EEGLAB reports
                      1 - stuff anyone should probably know
                      2 - stuff you should know the first time you start working
                          with a data set {default value}
                      3 - stuff that might help you debug (show all
                          reports)
   plot_gui      - ['yes' or 'no'] If 'yes', a GUI is created for
                   visualizing the results of the t-tests using the 
                   function gui_erp.m. The GUI vizualizes the grand average 
                   ERPs in each bin via various stats (uV, t-scores), shows 
                   topographies at individual time points, and illustrates 
                   which electrodes significantly differ from the null 
                   hypothesis.  This option does not work if mean_wind 
                   option is set to 'yes.' This GUI can be reproduced using
                   the function gui_erp.m. {default: 'yes'}
   plot_raster   - ['yes' or 'no'] If 'yes', a two-dimensional (time x channel)
                   binary "raster" diagram is created to illustrate the
                   results of the t-tests.  Significant negative and
                   positive deviations from the null hypothesis are shown
                   as black and white rectangles respectively. Non-
                   significant comparisons are shown as gray rectangles. 
                   Clicking on the rectangles will show you the 
                   corresponding time and channel label for that
                   rectangle. This figure can be reproduced with the 
                   function sig_raster.m. {default: 'yes'}
   plot_mn_topo  - ['yes' or 'no'] If 'yes', the topographies of the mean
                   voltages/effects in each time window is produced.  More
                   specifically, two figures are produced: one showing the
                   topographies in uV the other in t-scores. Significant/
                   nonsignificant comparisons are shown as white/black 
                   electrodes. Clicking on electrodes will show the
                   electrode's name.  This figure can be reproduced with
                   the function sig_topo.m.  This option has NO effect if
                   mean_wind option is set to 'no'. {default: 'yes'}
   output_file   - A string indicating the name of a space delimited text
                   file to produce containing the p-values of all comparisons 
                   and the details of the test (e.g., FDR method used, 
                   family-wise q level, etc...). If mean_wind option is
                   set to 'yes,' t-scores of each comparison are also 
                   included since you cannot derive them from the t-scores
                   at each time point/electrode in a simple way. When 
                   importing this file into a spreadsheet be sure NOT to 
                   count consecutive spaces as multiple delimiters. If bh
                   or bh FDR control procedures are used, FDR adjusted 
                   p-values (also called "q-values") will be output to the 
                   text file.  If method bky is used, unadjusted p-values 
                   will be output since it is not clear how to compute FDR
                   adjusted p-values for this method. {default: none}
   save_GRP      - ['yes' or 'no'] If 'yes', the GRP variable will be
                   saved to disk after the t-tests have been completed 
                   and added to it. User will first be prompted to verify 
                   file name and path. {default: 'yes'}

 Outputs:
   GRP           - GRP structure variable.  This is the same as
                   the input GRP variable with one addition: the 
                   field GRP.t_tests will contain the results of the 
                   t-tests and the test parameters. 
   p_values      - A two-dimensional matrix (channel x time) of the
                   p-values of each comparison (no correction for multiple
                   comparisons).
   data_t        - A two-dimensional matrix (channel x time) of the
                   t-scores of each comparison.
   crit_t        - The critical t-score(s) for the test.  Any t-scores
                   that are more extreme than the critical t-score(s) 
                   significantly deviate from 0.
   adj_p         - FDR corrected p-values (also called q-values). Note, 
                   FDR corrected p-values can be greater than 1. For bky 
                   procedure adj_p is NaN since it is not clear how to
                   compute adjusted p-values for this procedure.

   Note also that a great deal of information about the test is displayed 
   in the MATLAB command window.  You can easiy record of all this
   information to a text file using the MATLAB command "diary."

 Global Variables:
   VERBLEVEL - Mass Univariate ERP Toolbox level of verbosity (i.e., tells
               functions how much to report about what they're doing during
               runtime) set by the optional function argument 'verblevel'

 Notes:
 -To add a difference wave to a GRP variable, use the function "bin_opGRP".

 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., Krieger, A. M., & Yekutieli, D. (2006). Adaptive linear 
 step-up procedures that control the false discovery rate. Biometrika, 
 93(3), 491-507. 

   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. 

 Author:
 David Groppe
 Kutaslab, 5/2010

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 % tfdrGRP() - Tests the null hypothesis that the grand average voltage
0002 %             of a between-subject difference wave or ERP averaged across two
0003 %             groups is mu (usually 0) using t-tests with false discovery
0004 %             rate (FDR) control to correct for multiple comparisons.  This
0005 %             function requires individual subject ERPs to be stored in a
0006 %             "GRP" structure and outputs the test results in a
0007 %             number of graphical and text formats. For analogous within-
0008 %             subject comparisons use the function tfdrGND.m.
0009 %               Note, when applied to a bin that is the mean ERP across two
0010 %             groups (i.e., NOT a difference wave), a one-sample test is
0011 %             executed.
0012 %
0013 % Usage:
0014 %  >> [GRP, p_values, data_t, crit_t]=tfdrGRP(GRP_or_fname,bin,varargin)
0015 %
0016 % Required Inputs:
0017 %   GRP_or_fname - A GRP structure variable or the filename of a
0018 %                  GRP structure that has been saved to disk.  To
0019 %                  create a GRP variable from Kutaslab ERP files (e.g.,
0020 %                  *.mas files) use GNDs2GRP.m.  See Mass Univariate ERP
0021 %                  Toolbox documentation for detailed information about the
0022 %                  format of a GRP variable. If you specifiy a filename be
0023 %                  sure to include the file's path, unless the file is in
0024 %                  the current working directory.
0025 %   bin          - [integer] The bin to contrast against the mean of the
0026 %                  null hypothesis. Use the function headinfo.m to see what
0027 %                  bins are stored in a GRP variable.  Use the function
0028 %                  bin_opGRP.m to create a difference wave between two bins
0029 %                  whose significance you can test with this function.
0030 %
0031 % Optional Inputs:
0032 %   tail          - [1 | 0 | -1] An integer specifying the tail of the
0033 %                   hypothesis test.  "1" means upper-tailed (i.e., alternative
0034 %                   hypothesis is that the ERP/difference wave is greater
0035 %                   than mu).  "0" means two-tailed (i.e., alternative hypothesis
0036 %                   is that the ERP/difference wave is not equal to mu).
0037 %                   "-1" means lower-tailed (i.e., alternative hypothesis
0038 %                   is that the ERP/difference wave is less than mu).
0039 %                   {default: 0}
0040 %   q             - A number between 0 and 1 specifying the family-wise
0041 %                   q level of the test. q is the upper bound on the
0042 %                   expected proportion of rejected null hypotheses that are
0043 %                   false rejections (i.e., the FDR). {default: 0.05}
0044 %   method        - ['bh', 'by', or 'bky'] The procedure used to control
0045 %                   the FDR. 'bh' is the classic Benjamini & Hochberg (1995)
0046 %                   procedure, which is guaranteed to control FDR when the
0047 %                   tests are independent or positively dependent (e.g.,
0048 %                   positively correlated Gaussians). 'by' is a much more
0049 %                   conservative version of 'bh' that always controls FDR
0050 %                   (regardless of the dependency structure of the tests--
0051 %                   Benjamini & Yekutieli, 2001). 'bky' is a "two-stage"
0052 %                   version of 'bh' that is more powerful than 'bh' when a
0053 %                   lot of the null hypotheses are false (Benjamini, Krieger, &
0054 %                   Yekutieli, 2006).  'bky' is guaranteed to control FDR when the
0055 %                   tests are independent and tends to be slightly less
0056 %                   powerful than 'bh' when few or no null hypothese are
0057 %                   false.
0058 %   time_wind     - 2D matrix of pairs of time values specifying the beginning
0059 %                   and end of one or more time windows in ms (e.g.,
0060 %                   [160 180; 350 550]).  Every single time point in
0061 %                   the time window will be individually tested (i.e.,
0062 %                   maximal temporal resolution) if mean_wind option is
0063 %                   NOT used. Note, boundaries of time window(s) may not
0064 %                   exactly correspond to desired time window boundaries
0065 %                   because of temporal digitization (i.e., you only have
0066 %                   samples every so many ms). {default: 0 ms to the end of
0067 %                   the epoch}
0068 %   time_block_dur- [integers] A number or numbers (in milliseconds)
0069 %                   specifying a duration of time blocks in which the time
0070 %                   windows specified by time_wind will be divided.  For
0071 %                   example, if time_wind=[300 600] and time_block_dur=100,
0072 %                   the 300 to 600 ms time window will be sub-divided into
0073 %                   100 ms windows (i.e., time_wind will equal [300 396;
0074 %                   400 496; 500 596]).  This is an easy way to break up
0075 %                   larger time windows of interest into smaller windows
0076 %                   for mean window analysis (if mean_wind option is set to
0077 %                   'yes').  If you specify multiple time windows with
0078 %                   time_wind, you can break them up using durations of
0079 %                   different lengths.  For example, if time_wind=[150 250;
0080 %                   400 900] and time_block_dur=[25 100], the first time
0081 %                   window (150 to 250 ms) will be broken up into 25 ms
0082 %                   windows and the second window (400 to 900 ms) will be
0083 %                   broken up into 100 ms windows. {default: not used}
0084 %   mean_wind     - ['yes' or 'no'] If 'yes', the t-tests will be performed
0085 %                   on the mean amplitude within each time window specified
0086 %                   by time_wind.  This sacrifices temporal resolution
0087 %                   to increase test power by reducing the number of
0088 %                   comparisons.  If 'no', every single time point within
0089 %                   time_wind's time windows will be tested individually.
0090 %                   {default: 'no'}
0091 %   null_mean     - [number] The mean of the null hypothesis (i.e., mu) in
0092 %                   units of microvolts). {default: 0}
0093 %   exclude_chans - A cell array of channel labels to exclude from the
0094 %                   t-tests (e.g., {'A2','lle','rhe'}).  This option
0095 %                   sacrifices spatial resolution to increase test power by
0096 %                   reducing the number of comparisons. Use headinfo.m to see
0097 %                   the channel labels stored in the GRP variable. You cannot
0098 %                   use both this option and 'include_chans' (below).{default:
0099 %                   not used, all channels included in test}
0100 %   include_chans - A cell array of channel labels to use in the t-tests
0101 %                   (e.g., {'A2','lle','rhe'}).  All other channels will
0102 %                   be ignored. This option sacrifices spatial resolution to
0103 %                   increase test power by reducing the number of comparisons.
0104 %                   Use headinfo.m to see the channel labels stored in the GRP
0105 %                   variable. You cannot use both this option and
0106 %                   'exclude_chans' (above). {default: not used, all channels
0107 %                   included in test}
0108 %   verblevel     - An integer specifiying the amount of information you want
0109 %                   this function to provide about what it is doing during runtime.
0110 %                    Options are:
0111 %                      0 - quiet, only show errors, warnings, and EEGLAB reports
0112 %                      1 - stuff anyone should probably know
0113 %                      2 - stuff you should know the first time you start working
0114 %                          with a data set {default value}
0115 %                      3 - stuff that might help you debug (show all
0116 %                          reports)
0117 %   plot_gui      - ['yes' or 'no'] If 'yes', a GUI is created for
0118 %                   visualizing the results of the t-tests using the
0119 %                   function gui_erp.m. The GUI vizualizes the grand average
0120 %                   ERPs in each bin via various stats (uV, t-scores), shows
0121 %                   topographies at individual time points, and illustrates
0122 %                   which electrodes significantly differ from the null
0123 %                   hypothesis.  This option does not work if mean_wind
0124 %                   option is set to 'yes.' This GUI can be reproduced using
0125 %                   the function gui_erp.m. {default: 'yes'}
0126 %   plot_raster   - ['yes' or 'no'] If 'yes', a two-dimensional (time x channel)
0127 %                   binary "raster" diagram is created to illustrate the
0128 %                   results of the t-tests.  Significant negative and
0129 %                   positive deviations from the null hypothesis are shown
0130 %                   as black and white rectangles respectively. Non-
0131 %                   significant comparisons are shown as gray rectangles.
0132 %                   Clicking on the rectangles will show you the
0133 %                   corresponding time and channel label for that
0134 %                   rectangle. This figure can be reproduced with the
0135 %                   function sig_raster.m. {default: 'yes'}
0136 %   plot_mn_topo  - ['yes' or 'no'] If 'yes', the topographies of the mean
0137 %                   voltages/effects in each time window is produced.  More
0138 %                   specifically, two figures are produced: one showing the
0139 %                   topographies in uV the other in t-scores. Significant/
0140 %                   nonsignificant comparisons are shown as white/black
0141 %                   electrodes. Clicking on electrodes will show the
0142 %                   electrode's name.  This figure can be reproduced with
0143 %                   the function sig_topo.m.  This option has NO effect if
0144 %                   mean_wind option is set to 'no'. {default: 'yes'}
0145 %   output_file   - A string indicating the name of a space delimited text
0146 %                   file to produce containing the p-values of all comparisons
0147 %                   and the details of the test (e.g., FDR method used,
0148 %                   family-wise q level, etc...). If mean_wind option is
0149 %                   set to 'yes,' t-scores of each comparison are also
0150 %                   included since you cannot derive them from the t-scores
0151 %                   at each time point/electrode in a simple way. When
0152 %                   importing this file into a spreadsheet be sure NOT to
0153 %                   count consecutive spaces as multiple delimiters. If bh
0154 %                   or bh FDR control procedures are used, FDR adjusted
0155 %                   p-values (also called "q-values") will be output to the
0156 %                   text file.  If method bky is used, unadjusted p-values
0157 %                   will be output since it is not clear how to compute FDR
0158 %                   adjusted p-values for this method. {default: none}
0159 %   save_GRP      - ['yes' or 'no'] If 'yes', the GRP variable will be
0160 %                   saved to disk after the t-tests have been completed
0161 %                   and added to it. User will first be prompted to verify
0162 %                   file name and path. {default: 'yes'}
0163 %
0164 % Outputs:
0165 %   GRP           - GRP structure variable.  This is the same as
0166 %                   the input GRP variable with one addition: the
0167 %                   field GRP.t_tests will contain the results of the
0168 %                   t-tests and the test parameters.
0169 %   p_values      - A two-dimensional matrix (channel x time) of the
0170 %                   p-values of each comparison (no correction for multiple
0171 %                   comparisons).
0172 %   data_t        - A two-dimensional matrix (channel x time) of the
0173 %                   t-scores of each comparison.
0174 %   crit_t        - The critical t-score(s) for the test.  Any t-scores
0175 %                   that are more extreme than the critical t-score(s)
0176 %                   significantly deviate from 0.
0177 %   adj_p         - FDR corrected p-values (also called q-values). Note,
0178 %                   FDR corrected p-values can be greater than 1. For bky
0179 %                   procedure adj_p is NaN since it is not clear how to
0180 %                   compute adjusted p-values for this procedure.
0181 %
0182 %   Note also that a great deal of information about the test is displayed
0183 %   in the MATLAB command window.  You can easiy record of all this
0184 %   information to a text file using the MATLAB command "diary."
0185 %
0186 % Global Variables:
0187 %   VERBLEVEL - Mass Univariate ERP Toolbox level of verbosity (i.e., tells
0188 %               functions how much to report about what they're doing during
0189 %               runtime) set by the optional function argument 'verblevel'
0190 %
0191 % Notes:
0192 % -To add a difference wave to a GRP variable, use the function "bin_opGRP".
0193 %
0194 % References:
0195 %   Benjamini, Y., & Hochberg, Y. (1995). Controlling the false discovery
0196 % rate: A practical and powerful approach to multiple testing. Journal of
0197 % the Royal Statistical Society. Series B (Methodological), 57(1), 289-300.
0198 %
0199 %   Benjamini, Y., Krieger, A. M., & Yekutieli, D. (2006). Adaptive linear
0200 % step-up procedures that control the false discovery rate. Biometrika,
0201 % 93(3), 491-507.
0202 %
0203 %   Benjamini, Y., & Yekutieli, D. (2001). The control of the false
0204 % discovery rate in multiple testing under dependency. The Annals of
0205 % Statistics, 29(4), 1165-1188.
0206 %
0207 % Author:
0208 % David Groppe
0209 % Kutaslab, 5/2010
0210 
0211 
0212 %%%%%%%%%%%%%%%% FUTURE WORK %%%%%%%%%%%%%%%%%
0213 %
0214 
0215 %%%%%%%%%%%%%%%% REVISION LOG %%%%%%%%%%%%%%%%%
0216 % 4/14/2011-FDR corrected p-values added for by and bh procedures. I don't
0217 % know if there's a way to compute them for bky procedure.
0218 %
0219 % 1/24/2015-Changed line 583 from
0220 % "sig_elec=find(p_values(:,t)<p.Results.q);" to
0221 % "sig_elec=find(adj_p(:,t)<p.Results.q);"
0222 % This bug meant that the command window output was incorrect (It was using
0223 % the un-adjusted p-values to assess significance). However, the figures
0224 % and GRP.t_test results were correct.
0225 
0226 function [GRP, p_values, data_t, crit_t, adj_p]=tfdrGRP(GRP_or_fname,bin,varargin)
0227 
0228 global VERBLEVEL;
0229 
0230 p=inputParser;
0231 p.addRequired('GRP_or_fname',@(x) ischar(x) || isstruct(x));
0232 p.addRequired('bin',@(x) isnumeric(x) && (length(x)==1) && (x>0));
0233 p.addParamValue('tail',0,@(x) isnumeric(x) && (length(x)==1));
0234 p.addParamValue('q',0.05,@(x) isnumeric(x) && (x>0) && (x<1));
0235 p.addParamValue('method','bh',@(x) strcmpi(x,'bh') || strcmpi(x,'by') || strcmpi(x,'bky'));
0236 p.addParamValue('time_wind',[],@(x) isnumeric(x) && (size(x,2)==2));
0237 p.addParamValue('time_block_dur',[],@isnumeric);
0238 p.addParamValue('mean_wind','no',@(x) ischar(x) && (strcmpi(x,'yes') || strcmpi(x,'no')));
0239 p.addParamValue('null_mean',0,@(x) isnumeric(x) && (length(x)==1));
0240 p.addParamValue('exclude_chans',[],@(x) ischar(x) || iscell(x));
0241 p.addParamValue('include_chans',[],@(x) ischar(x) || iscell(x));
0242 p.addParamValue('verblevel',[],@(x) isnumeric(x) && (length(x)==1));
0243 p.addParamValue('plot_gui','yes',@(x) ischar(x) && (strcmpi(x,'yes') || strcmpi(x,'no')));
0244 p.addParamValue('plot_raster','yes',@(x) ischar(x) && (strcmpi(x,'yes') || strcmpi(x,'no')));
0245 p.addParamValue('plot_mn_topo',[],@(x) ischar(x) && (strcmpi(x,'yes') || strcmpi(x,'no')));
0246 p.addParamValue('output_file',[],@ischar);
0247 p.addParamValue('save_GRP','yes',@(x) ischar(x) && (strcmpi(x,'yes') || strcmpi(x,'no')));
0248 
0249 p.parse(GRP_or_fname,bin,varargin{:});
0250 
0251 
0252 if isempty(p.Results.verblevel),
0253     if isempty(VERBLEVEL),
0254         VERBLEVEL=2;
0255     end
0256 else
0257    VERBLEVEL=p.Results.verblevel; 
0258 end
0259     
0260 mean_wind=str2bool(p.Results.mean_wind);
0261 
0262 %Load GRP struct
0263 if ischar(GRP_or_fname),
0264     fprintf('Loading GRP struct from file %s.\n',GRP_or_fname);
0265     load(GRP_or_fname,'-MAT');
0266 else
0267     GRP=GRP_or_fname;
0268     clear GRP_or_fname;
0269 end
0270 [n_chan, n_pt, n_bin]=size(GRP.grands);
0271 VerbReport(sprintf('Experiment: %s',GRP.exp_desc),2,VERBLEVEL);
0272 
0273 if (bin>n_bin),
0274     error('There is no Bin %d in this GRP variable.',bin); 
0275 end
0276 grpA=GRP.bin_info(bin).groupA;
0277 grpB=GRP.bin_info(bin).groupB;
0278 
0279 
0280 %% Figure out which channels to ignore if any
0281 %But first make sure exclude & include options were not both used.
0282 if ~isempty(p.Results.include_chans) && ~isempty(p.Results.exclude_chans)
0283     error('You cannot use BOTH ''include_chans'' and ''exclude_chans'' options.');
0284 end
0285 if ischar(p.Results.exclude_chans),
0286     exclude_chans{1}=p.Results.exclude_chans;
0287 elseif isempty(p.Results.exclude_chans)
0288     exclude_chans=[];
0289 else
0290     exclude_chans=p.Results.exclude_chans;
0291 end
0292 if ischar(p.Results.include_chans),
0293     include_chans{1}=p.Results.include_chans;
0294 elseif isempty(p.Results.include_chans)
0295     include_chans=[];
0296 else
0297     include_chans=p.Results.include_chans;
0298 end
0299 
0300 % exclude and include chan options
0301 if ~isempty(exclude_chans),
0302     ignore_chans=zeros(1,length(exclude_chans)); %preallocate mem
0303     ct=0;
0304     for x=1:length(exclude_chans),
0305         found=0;
0306         for c=1:n_chan,
0307             if strcmpi(exclude_chans{x},GRP.chanlocs(c).labels),
0308                 found=1;
0309                 ct=ct+1;
0310                 ignore_chans(ct)=c;
0311             end
0312         end
0313         if ~found,
0314             watchit(sprintf('I attempted to exclude %s.  However no such electrode was found in GRP variable.', ...
0315                 exclude_chans{x}));
0316         end
0317     end
0318     ignore_chans=ignore_chans(1:ct);
0319     use_chans=setdiff(1:n_chan,ignore_chans);
0320 elseif ~isempty(include_chans),
0321     use_chans=zeros(1,length(include_chans)); %preallocate mem
0322     ct=0;
0323     for x=1:length(include_chans),
0324         found=0;
0325         for c=1:n_chan,
0326             if strcmpi(include_chans{x},GRP.chanlocs(c).labels),
0327                 found=1;
0328                 ct=ct+1;
0329                 use_chans(ct)=c;
0330             end
0331         end
0332         if ~found,
0333             watchit(sprintf('I attempted to include %s.  However no such electrode was found in GRP variable.', ...
0334                 include_chans{x}));
0335         end
0336     end
0337     use_chans=use_chans(1:ct);
0338 else
0339     use_chans=1:n_chan;
0340 end
0341 
0342 
0343 %% Find time points
0344 if isempty(p.Results.time_wind),
0345     time_wind=[0 GRP.time_pts(end)]; %default time window
0346 else
0347     time_wind=p.Results.time_wind;
0348 end
0349 time_wind=sort(time_wind,2); %first make sure earlier of each pair of time points is first
0350 time_wind=sort(time_wind,1); %next sort time windows from earliest to latest onset
0351 n_wind=size(time_wind,1);
0352 if ~isempty(p.Results.time_block_dur),
0353     tbd=p.Results.time_block_dur;
0354     n_block=length(tbd);
0355     if (n_block>1) && (n_block~=n_wind),
0356        error('If you specify more than one time block duration you need to provide exactly one duration for every time window (in this case %d).',n_wind); 
0357     elseif (n_block==1) && (n_wind>1),
0358         tbd=repmat(tbd,1,n_wind);
0359     end
0360         
0361     t_winds=[];
0362     one_step=1000/GRP.srate;
0363     for a=1:n_wind,
0364         wind_strt=time_wind(a,1);
0365         wind_stop=time_wind(a,2);
0366         new_winds=[wind_strt:tbd(a):wind_stop];
0367         for b=1:(length(new_winds)-1),
0368             t_winds=[t_winds; new_winds(b) new_winds(b+1)-one_step];
0369         end
0370     end
0371     time_wind=t_winds;
0372     clear t_winds;
0373     n_wind=size(time_wind,1);
0374 end
0375 
0376 if mean_wind,
0377     use_tpts=cell(1,n_wind);
0378 else
0379     use_tpts=[];
0380 end
0381 for a=1:n_wind,
0382     VerbReport(sprintf('Time Window #%d:',a),1,VERBLEVEL);
0383     VerbReport(sprintf('Attempting to use time boundaries of %d to %d ms for hypothesis test.',time_wind(a,1),time_wind(a,2)), ...
0384         1,VERBLEVEL);
0385     start_tpt=find_tpt(time_wind(a,1),GRP.time_pts);
0386     end_tpt=find_tpt(time_wind(a,2),GRP.time_pts);
0387     if mean_wind,
0388         use_tpts{a}=[start_tpt:end_tpt];
0389     else
0390         use_tpts=[use_tpts [start_tpt:end_tpt]];
0391     end
0392     %replace desired time points with closest matches
0393     time_wind(a,1)=GRP.time_pts(start_tpt);
0394     time_wind(a,2)=GRP.time_pts(end_tpt);
0395     VerbReport(sprintf('Exact window boundaries are %d to %d ms (that''s from time point %d to %d).', ...
0396         time_wind(a,1),time_wind(a,2),start_tpt,end_tpt),1,VERBLEVEL);
0397 end
0398 if ~mean_wind,
0399     use_tpts=unique(use_tpts); %sorts time points and gets rid of any redundant time points
0400 end
0401 
0402 
0403 %% Compile data from two groups of participants
0404 %pre-allocate memory
0405 grp_ct=0;
0406 for grp=[grpA grpB],
0407     grp_ct=grp_ct+1;
0408     if grp_ct==1,
0409         %Group A's bin
0410         ur_bin=GRP.bin_info(bin).source_binA;
0411     else
0412         %Group B's bin
0413         ur_bin=GRP.bin_info(bin).source_binB;
0414     end
0415     
0416     %Load GND variable for this group
0417     load(GRP.GND_fnames{grp},'-MAT');
0418     VerbReport(sprintf('Loading individual participant ERPs from Bin %d (%s) of GND variable from %s.', ...
0419         ur_bin,GND.bin_info(ur_bin).bindesc,GRP.GND_fnames{grp}),2,VERBLEVEL);
0420     
0421     %Check to make sure time points are still compatible across GND and GRP
0422     %variables
0423     if ~isequal(GND.time_pts,GRP.time_pts)
0424         error('The time points in the GND variable from file %s are NOT the same as those in your GRP variable.', ...
0425             GRP.GND_fnames{grp});
0426     end
0427     
0428     %Derive channel indexes for this GND variable in case GND.chanlocs differs from
0429     %GRP.chanlocs (in order or in identity of channels)
0430     n_chanGND=length(GND.chanlocs);
0431     use_chansGND=[];
0432     for a=use_chans,
0433         found=0;
0434         for b=1:n_chanGND,
0435             if strcmpi(GRP.chanlocs(a).labels,GND.chanlocs(b).labels),
0436                 found=1;
0437                 use_chansGND=[use_chansGND b];
0438                 break;
0439             end
0440         end
0441         if ~found,
0442             error('GND variable in file %s is missing channel %s.',GRP.GND_fnames{grp},GRP.chanlocs(a).labels);
0443         end
0444     end
0445     
0446     %Use only subs with data in relevant bin(s)
0447     use_subs=find(GND.indiv_bin_ct(:,ur_bin));
0448     n_sub=length(use_subs);
0449     
0450     if mean_wind,
0451         %Take mean amplitude in time blocks and then test
0452         if grp_ct==1,
0453             %Group A's ERPs
0454             n_subA=n_sub;
0455             use_subsA=use_subs;
0456             erpsA=zeros(length(use_chans),n_wind,n_sub);
0457             for a=1:n_wind,
0458                 for sub=1:n_sub,
0459                     erpsA(:,a,sub)=mean(GND.indiv_erps(use_chansGND,use_tpts{a},ur_bin,use_subs(sub)),2);
0460                 end
0461             end
0462         else
0463             %Group B's ERPs
0464             n_subB=n_sub;
0465             use_subsB=use_subs;
0466             erpsB=zeros(length(use_chans),n_wind,n_sub);
0467             for a=1:n_wind,
0468                 for sub=1:n_sub,
0469                     erpsB(:,a,sub)=mean(GND.indiv_erps(use_chansGND,use_tpts{a},ur_bin,use_subs(sub)),2);
0470                 end
0471             end
0472         end
0473     else
0474         %Use every single time point in time window(s)
0475         if grp_ct==1,
0476             %Group A's ERPs
0477             n_subA=n_sub;
0478             use_subsA=use_subs;
0479             n_use_tpts=length(use_tpts);
0480             erpsA=zeros(length(use_chans),n_use_tpts,n_sub);
0481             for sub=1:n_sub,
0482                 erpsA(:,:,sub)=GND.indiv_erps(use_chansGND,use_tpts,ur_bin,use_subs(sub));
0483             end
0484         else
0485             %Group B's ERPs
0486             n_subB=n_sub;
0487             use_subsB=use_subs;
0488             n_use_tpts=length(use_tpts);
0489             erpsB=zeros(length(use_chans),n_use_tpts,n_sub);
0490             for sub=1:n_sub,
0491                 erpsB(:,:,sub)=GND.indiv_erps(use_chansGND,use_tpts,ur_bin,use_subs(sub));
0492             end
0493         end
0494     end
0495 end
0496 df=n_subA+n_subB-2;
0497 
0498 %% Report tail of test & alpha levels
0499 VerbReport(sprintf('Testing null hypothesis that the grand average ERPs in GRP variable''s Bin %d (%s) have a mean of %f microvolts.',bin, ...
0500     GRP.bin_info(bin).bindesc,p.Results.null_mean),1,VERBLEVEL);
0501 if p.Results.tail==0
0502     VerbReport(sprintf('Alternative hypothesis is that the ERPs differ from %f (i.e., two-tailed test).',p.Results.null_mean), ...
0503         1,VERBLEVEL);
0504 elseif p.Results.tail<0,
0505     VerbReport(sprintf('Alternative hypothesis is that the ERPs are less than %f (i.e., lower-tailed test).',p.Results.null_mean), ...
0506         1,VERBLEVEL);
0507 else
0508     VerbReport(sprintf('Alternative hypothesis is that the ERPs are greater than %f (i.e., upper-tailed test).',p.Results.null_mean), ...
0509         1,VERBLEVEL);
0510 end
0511 
0512 
0513 
0514 %Compute the t-tests
0515 if strcmpi(GRP.bin_info(bin).op,'(A+B)/n'),
0516     %one sample t-test
0517     VerbReport('Performing one sample/repeated measures t-tests.',1,VERBLEVEL);
0518     erpsAB=zeros(length(use_chans),size(erpsA,2),n_subA+n_subB);
0519     erpsAB(:,:,1:n_subA)=erpsA-p.Results.null_mean;
0520     erpsAB(:,:,(n_subA+1):(n_subA+n_subB))=erpsB-p.Results.null_mean;
0521     [p_values, data_t]=fast_t1(erpsAB,p.Results.tail,VERBLEVEL);
0522 else
0523     %independent samples t-test
0524     VerbReport('Performing independent samples t-tests.',1,VERBLEVEL);
0525     [p_values, data_t]=fast_t2(erpsA-p.Results.null_mean,erpsB,p.Results.tail,VERBLEVEL);
0526 end
0527 %Perform FDR control
0528 switch lower(p.Results.method)
0529     case 'bh'
0530         VerbReport('FDR control procedure: Benjamini & Hochberg (independent or positive dependency)',1,VERBLEVEL);
0531         [h_rej, crit_p, adj_p]=fdr_bh(p_values,p.Results.q,'pdep','no');
0532     case 'by'
0533         VerbReport('FDR control procedure: Benjamini & Yekutieli (arbitrary dependency)',1,VERBLEVEL);
0534         [h_rej, crit_p, adj_p]=fdr_bh(p_values,p.Results.q,'dep','no');
0535     case 'bky'
0536         VerbReport('FDR control procedure: Benjamini, Krieger, & Yekutieli (two-stage)',1,VERBLEVEL);
0537         [h_rej, crit_p]=fdr_bky(p_values,p.Results.q,'no');
0538         adj_p=NaN;
0539 end
0540 
0541 sig_tpts=find(sum(h_rej));
0542 if isempty(sig_tpts),
0543     if p.Results.tail==0,
0544         crit_t=[NaN NaN];
0545     else
0546         crit_t=NaN;
0547     end
0548     fprintf('ERPs are NOT significantly different from zero (q=%f) at any time point/window analyzed.\n', ...
0549         p.Results.q);
0550     if ~strcmpi(p.Results.method,'bky'),
0551         %don't have adjusted p-values for bky method
0552         fprintf('All FDR adjusted p-values>=%f\n',min(min(adj_p)));
0553     end
0554 else
0555     crit_t=min(abs(data_t(crit_p==p_values)));
0556     if p.Results.tail<0,
0557         crit_t=-crit_t;
0558     elseif p.Results.tail==0,
0559         crit_t=[-crit_t crit_t];
0560     end
0561     
0562     %Command line summary of results
0563     VerbReport(['Critical t-score(s):' num2str(crit_t)],1,VERBLEVEL);
0564     if p.Results.tail
0565         %one-tailed test
0566         tw_alpha=1-cdf('t',max(abs(crit_t)),df);
0567     else
0568         %two-tailed test
0569         tw_alpha=2-cdf('t',max(crit_t),df)-cdf('t',-min(crit_t),df);
0570     end
0571     VerbReport(sprintf('That corresponds to a test-wise alpha level of %f.',tw_alpha),1,VERBLEVEL);
0572     VerbReport(sprintf('Bonferroni test-wise alpha would be %f.',p.Results.q/(size(p_values,1)* ...
0573         size(p_values,2))),1,VERBLEVEL);
0574   
0575     fprintf('Significant differences from zero (in order of earliest to latest):\n');
0576     if ~strcmpi(p.Results.method,'bky'),
0577         %don't have adjusted p-values for bky method
0578         max_sig_p=0;
0579         min_sig_p=max(max(adj_p));
0580     end
0581     for t=sig_tpts,
0582         if mean_wind
0583             %time windows instead of time points
0584             fprintf('%d to %d ms, electrode(s): ',GRP.time_pts(use_tpts{t}(1)), ...
0585                 GRP.time_pts(use_tpts{t}(end)));
0586         else
0587             fprintf('%d ms, electrode(s): ',GRP.time_pts(use_tpts(t)));
0588         end
0589         sig_elec=find(adj_p(:,t)<p.Results.q);
0590         ct=0;
0591         for c=sig_elec',
0592             ct=ct+1;
0593             if ~strcmpi(p.Results.method,'bky'),
0594                 %don't have adjusted p-values for bky method
0595                 if adj_p(c,t)>max_sig_p,
0596                     max_sig_p=adj_p(c,t);
0597                 end
0598                 if adj_p(c,t)<min_sig_p,
0599                     min_sig_p=adj_p(c,t);
0600                 end
0601             end
0602             if ct==length(sig_elec),
0603                 fprintf('%s.\n',GRP.chanlocs(use_chans(c)).labels);
0604             else
0605                 fprintf('%s, ',GRP.chanlocs(use_chans(c)).labels);
0606             end
0607         end
0608     end
0609     if ~strcmpi(p.Results.method,'bky'),
0610         fprintf('All significant corrected p-values are between %f and %f\n',max_sig_p,min_sig_p);
0611     end
0612 end
0613 
0614 
0615 %Add t-test results to GRP struct
0616 n_t_tests=length(GRP.t_tests);
0617 neo_test=n_t_tests+1;
0618 GRP.t_tests(neo_test).bin=bin;
0619 GRP.t_tests(neo_test).time_wind=time_wind;
0620 GRP.t_tests(neo_test).used_tpt_ids=use_tpts;
0621 n_use_chans=length(use_chans);
0622 include_chans=cell(1,n_use_chans);
0623 for a=1:n_use_chans,
0624    include_chans{a}=GRP.chanlocs(use_chans(a)).labels; 
0625 end
0626 GRP.t_tests(neo_test).include_chans=include_chans;
0627 GRP.t_tests(neo_test).used_chan_ids=use_chans;
0628 GRP.t_tests(neo_test).mult_comp_method=p.Results.method;
0629 GRP.t_tests(neo_test).n_perm=NaN;
0630 GRP.t_tests(neo_test).desired_alphaORq=p.Results.q;
0631 GRP.t_tests(neo_test).estimated_alpha=NaN;
0632 GRP.t_tests(neo_test).null_mean=p.Results.null_mean;
0633 if mean_wind,
0634     GRP.t_tests(neo_test).data_t=data_t;
0635     GRP.t_tests(neo_test).mean_wind='yes';
0636 else
0637     GRP.t_tests(neo_test).data_t='See GRP.grands_t';
0638     GRP.t_tests(neo_test).mean_wind='no';
0639 end
0640 GRP.t_tests(neo_test).crit_t=crit_t;
0641 GRP.t_tests(neo_test).df=df;
0642 GRP.t_tests(neo_test).adj_pval=adj_p;
0643 GRP.t_tests(neo_test).fdr_rej=h_rej;
0644 GRP.t_tests(neo_test).seed_state=NaN;
0645 GRP.t_tests(neo_test).clust_info=NaN;
0646 GRP.t_tests(neo_test).chan_hood=NaN;
0647 
0648 
0649 if strcmpi(p.Results.plot_raster,'yes'),
0650     sig_raster(GRP,neo_test,'verblevel',0,'use_color','rgb');
0651 end
0652 
0653 if mean_wind,
0654     if strcmpi(p.Results.plot_mn_topo,'yes') || isempty(p.Results.plot_mn_topo),
0655         sig_topo(GRP,neo_test,'units','t','verblevel',0); %t-score topographies
0656         sig_topo(GRP,neo_test,'units','uV','verblevel',0); %microvolt topographies
0657     end
0658 else
0659     %plot_pvals(GRP,p.Results.q,use_chans,use_tpts,p_values,bin);
0660     %%improve plot_pvals and make it an option ??
0661     if strcmpi(p.Results.plot_gui,'yes'),
0662         gui_erp('initialize','GNDorGRP',GRP,'t_test',neo_test,'stat','t','verblevel',1);
0663     end
0664 end
0665 
0666 if ~isempty(p.Results.output_file)
0667     [fid msg]=fopen(p.Results.output_file,'w');
0668     if fid==-1,
0669         error('Cannot create file %s for writing.  According to fopen.m: %s.', ...
0670             p.Results.file,msg);
0671     else
0672         %Write header column of times
0673         % Leave first column blank for channel labels
0674         if mean_wind,
0675             for t=1:n_wind
0676                 fprintf(fid,' %d-%d',GRP.time_pts(use_tpts{t}(1)), ...
0677                     GRP.time_pts(use_tpts{t}(end)));
0678             end
0679             
0680             %write a couple spaces and then write header for t-scores
0681             fprintf(fid,'  ');
0682             for t=1:n_wind
0683                 fprintf(fid,' %d-%d',GRP.time_pts(use_tpts{t}(1)), ...
0684                     GRP.time_pts(use_tpts{t}(end)));
0685             end
0686         else
0687             for t=use_tpts,
0688                 fprintf(fid,' %d',GRP.time_pts(t));
0689             end
0690         end
0691         fprintf(fid,' Milliseconds\n');
0692         
0693         % Write channel labels and p-values
0694         chan_ct=0;
0695         for c=use_chans,
0696             chan_ct=chan_ct+1;
0697             fprintf(fid,'%s',GRP.chanlocs(c).labels);
0698             if strcmpi(p.Results.method,'bky'),
0699                 %print uncorrected p-values for bky method since I don't
0700                 %think there's a way to compute them
0701                 for t=1:length(use_tpts),
0702                     fprintf(fid,' %f',p_values(chan_ct,t));
0703                 end
0704                 fprintf(fid,' p-value(uncorrected)');
0705             else
0706                 for t=1:length(use_tpts),
0707                     fprintf(fid,' %f',adj_p(chan_ct,t));
0708                 end
0709                 fprintf(fid,' p-value(FDR_corrected)');
0710             end
0711             
0712             if mean_wind,
0713                 %write a couple spaces and then write t-scores if mean amp
0714                 %in time windows used
0715                 fprintf(fid,' ');
0716                 for t=1:n_wind
0717                     fprintf(fid,' %f',data_t(chan_ct,t));
0718                 end
0719                 fprintf(fid,' t-score \n');
0720             else
0721                 fprintf(fid,'\n');
0722             end
0723         end
0724         
0725         % Write t-test details
0726         fprintf(fid,'Experiment: %s\n',GRP.exp_desc);
0727         fprintf(fid,'Test_of_null_hypothesis_that_Bin_%d_equals: %d\n',bin,p.Results.null_mean);
0728         fprintf(fid,'#_of_time_windows: %d\n',n_wind);
0729         fprintf(fid,'FDR_method: %s\n',p.Results.method);
0730         fprintf(fid,'Tail_of_test: ');
0731         if ~p.Results.tail,
0732             fprintf(fid,'Two_tailed\n');
0733             fprintf(fid,'Critical_t_scores: %f %f\n',crit_t(1),crit_t(2));
0734         elseif p.Results.tail>0
0735             fprintf(fid,'Upper_tailed\n');
0736             fprintf(fid,'Critical_t_score: %f\n',crit_t(1));
0737         else
0738             fprintf(fid,'Lower_tailed\n');
0739             fprintf(fid,'Critical_t_score: %f\n',crit_t(1));
0740         end
0741         fprintf(fid,'Critical_p-value: %f\n',crit_p);
0742         fprintf(fid,'Total_#_of_significant_differences: %d\n',sum(sum(h_rej)));
0743         fprintf(fid,'Estimated_upper_bound_on_expected_#_of_false_discoveries: %.1f\n',sum(sum(h_rej))*p.Results.q);
0744         fprintf(fid,'Degrees_of_freedom: %d\n',df);
0745         fprintf(fid,'q_level: %f\n',p.Results.q);
0746         for grp=[grpA grpB],
0747             % # of participants and filenames
0748             if grp==grpA,
0749                 use_subs=use_subsA;
0750                 fprintf(fid,'GND_fname_GroupA: %s\n',GRP.GND_fnames{grp});
0751                 fprintf(fid,'#_of_participants_GroupA: %d\n',n_subA);
0752                 fprintf(fid,'Participant_names_GroupA: \n');
0753             else
0754                 use_subs=use_subsB;
0755                 fprintf(fid,'GND_fname_GroupB: %s\n',GRP.GND_fnames{grp});
0756                 fprintf(fid,'#_of_participants_GroupB: %d\n',n_subB);
0757                 fprintf(fid,'Participant_names_GroupB: \n');
0758             end
0759             for s=1:length(use_subs),
0760                 fprintf(fid,'%s\n',GRP.indiv_subnames{grp}{use_subs(s)});
0761             end
0762         end
0763     end
0764     fclose(fid);
0765 end
0766 
0767 if ~strcmpi(p.Results.save_GRP,'no'),
0768     GRP=save_erps(GRP);
0769 end
0770 
0771 %
0772 %% %%%%%%%%%%%%%%%%%%%%% function str2bool() %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0773 %
0774 function bool=str2bool(str)
0775 %function bool=str2bool(str)
0776 
0777 if ischar(str),
0778     if strcmpi(str,'yes') || strcmpi(str,'y')
0779         bool=1;
0780     else
0781         bool=0;
0782     end
0783 else
0784    bool=str; 
0785 end
0786

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