Home > matlabmk > decimateGND.m

decimateGND

PURPOSE ^

decimateGND() - Downsamples a set of ERPs to a lower sampling rate.

SYNOPSIS ^

function GND=decimateGND(GND,decfactor,method,bsln_wind,save_GND,verblevel)

DESCRIPTION ^

 decimateGND() - Downsamples a set of ERPs to a lower sampling rate.
                 Useful for reducing the number of dependent variables and 
                 conserving memory.
 Usage:
  >> GND=decimateGND(GND,decfactor,method,bsln_wind,verblevel);

 Required Inputs:
   GND       - A GND structure variable.  To create a GND variable from
               Kutaslab ERP files (e.g., *.mas files) use avgs2GND.m.  To 
               do the same from EEGLAB *.set files use sets2GND.m.  See Mass
               Univariate ERP Toolbox documentation for detailed information  
               about the format of a GND variable. 
   decfactor - [positive integer] The factor by which to reduce the data
               set.  For example, if decfactor is 2, the data will have 
               approximately half as many time points.

 Optional Inputs:
   method     - ['boxcar' or 'fir'] If 'boxcar,' data are decimated with a
                boxcar moving average (this is the algorithm used by 
                Kutaslab's UNIX program "avg").  If 'fir,' data are decimated
                using the MATLAB function decimate.m and a 30th order FIR
                filter. See comments in this file (decimateGND.m) for more 
                information on how exactly decimation is done.  Note, you
                MUST HAVE THE MATLAB SIGNAL PROCESSING TOOLBOX to use the 
                'fir' option.  The 'boxcar' option does NOT require the 
                signal processing toolbox {default: 'boxcar'}
   bsln_wind  - [vector] Two element vector specifying the beginning and
                end (in ms) of the baseline time window (e.g., [-100 -4]).
                The mean amplitude across all time points within and 
                including those times will be removed from each ERP.  Data
                should be re-baselined after decimation, because baseline
                mean amplitude may no longer be zero after decimation.
                {default: all time points before 0}
   save_GND   - ['yes' or 'no'] If 'yes', the GND variable will be
                saved to disk after the permutation test is completed 
                and added to it. User will first be prompted to verify 
                file name and path. {default: 'yes'}
   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)

 Example:
 To convert a GND variable from 250 Hz to 125 Hz using a boxcar window:
 >>GND=decimateGND(GND,2);

 To convert a GND variable from 250 Hz to 125 Hz using a FIR anti-aliasing 
 filter and then re-baselining the data:
 >>GND=decimateGND(GND,2,'fir',[-100 0]);


 Author:
 David Groppe ('boxcar' algorithm from Paul Krewski)
 Kutaslab, 3/2010

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 % decimateGND() - Downsamples a set of ERPs to a lower sampling rate.
0002 %                 Useful for reducing the number of dependent variables and
0003 %                 conserving memory.
0004 % Usage:
0005 %  >> GND=decimateGND(GND,decfactor,method,bsln_wind,verblevel);
0006 %
0007 % Required Inputs:
0008 %   GND       - A GND structure variable.  To create a GND variable from
0009 %               Kutaslab ERP files (e.g., *.mas files) use avgs2GND.m.  To
0010 %               do the same from EEGLAB *.set files use sets2GND.m.  See Mass
0011 %               Univariate ERP Toolbox documentation for detailed information
0012 %               about the format of a GND variable.
0013 %   decfactor - [positive integer] The factor by which to reduce the data
0014 %               set.  For example, if decfactor is 2, the data will have
0015 %               approximately half as many time points.
0016 %
0017 % Optional Inputs:
0018 %   method     - ['boxcar' or 'fir'] If 'boxcar,' data are decimated with a
0019 %                boxcar moving average (this is the algorithm used by
0020 %                Kutaslab's UNIX program "avg").  If 'fir,' data are decimated
0021 %                using the MATLAB function decimate.m and a 30th order FIR
0022 %                filter. See comments in this file (decimateGND.m) for more
0023 %                information on how exactly decimation is done.  Note, you
0024 %                MUST HAVE THE MATLAB SIGNAL PROCESSING TOOLBOX to use the
0025 %                'fir' option.  The 'boxcar' option does NOT require the
0026 %                signal processing toolbox {default: 'boxcar'}
0027 %   bsln_wind  - [vector] Two element vector specifying the beginning and
0028 %                end (in ms) of the baseline time window (e.g., [-100 -4]).
0029 %                The mean amplitude across all time points within and
0030 %                including those times will be removed from each ERP.  Data
0031 %                should be re-baselined after decimation, because baseline
0032 %                mean amplitude may no longer be zero after decimation.
0033 %                {default: all time points before 0}
0034 %   save_GND   - ['yes' or 'no'] If 'yes', the GND variable will be
0035 %                saved to disk after the permutation test is completed
0036 %                and added to it. User will first be prompted to verify
0037 %                file name and path. {default: 'yes'}
0038 %   verblevel  - An integer specifiying the amount of information you want
0039 %                this function to provide about what it is doing during runtime.
0040 %                  Options are:
0041 %                    0 - quiet, only show errors, warnings, and EEGLAB reports
0042 %                    1 - stuff anyone should probably know
0043 %                    2 - stuff you should know the first time you start working
0044 %                        with a data set {default value}
0045 %                    3 - stuff that might help you debug (show all
0046 %                        reports)
0047 %
0048 % Example:
0049 % To convert a GND variable from 250 Hz to 125 Hz using a boxcar window:
0050 % >>GND=decimateGND(GND,2);
0051 %
0052 % To convert a GND variable from 250 Hz to 125 Hz using a FIR anti-aliasing
0053 % filter and then re-baselining the data:
0054 % >>GND=decimateGND(GND,2,'fir',[-100 0]);
0055 %
0056 %
0057 % Author:
0058 % David Groppe ('boxcar' algorithm from Paul Krewski)
0059 % Kutaslab, 3/2010
0060 
0061 function GND=decimateGND(GND,decfactor,method,bsln_wind,save_GND,verblevel)
0062 
0063 %%%%%%%%%%%%%%%% REVISION LOG %%%%%%%%%%%%%%%%%
0064 % 3/16/2011-Function now works when GND.cals field is empty.  This field is
0065 % unique to Kutaslab data and is empty for data obtained from other labs.
0066 % Thanks to Andrew Hill for finding this bug.
0067 %
0068 % 3/23/2011-save_GND option added.
0069 %
0070 % 3/12/2013-'fir' option now works when GND.cals field is empty (bug fix on
0071 % 3/16/2011 was accidentally incomplete).  Thanks to Aaron Newman for
0072 % reporting this.
0073 
0074 %Notes about decimation:
0075 % -When using the 'boxcar' method, the size of the boxcar moving window is
0076 % decfactor+1.  For example, if decfactor=2, each time point is replaced by
0077 % the mean of it and the immediately preceding and following time point.
0078 % Time points at the edge of the ERPs are discarded since they lack
0079 % sufficient preceding or following time points.  Every other time point is
0080 % discarded.  This method has the advantage that the latency of any effect
0081 % won't be distorted (i.e., data at a pre-decimated time point only effects
0082 % the data at a single post-decimated time point).  The DISADVANTAGE of this
0083 % method is that moving average windows have ripply stop bands.  Thus it
0084 % won't do a great job of suppressing high frequency activity (e.g., 60 Hz
0085 % and will surely result in some aliasing.  Unless you have a lot of
0086 % 60 Hz or EMG in your data this might not be a significant problem since
0087 % ERPs typically have little power at those high frequencies.
0088 %   I suspect that the 'fir' option could potentially shift effects a bit
0089 % in time, but I haven't verified this yet.  When I tried running the
0090 % filter on an impulse (a waveform with a single non-zero value), it showed
0091 % no evidence of this.  In contrast, the Chebyshev filter (decimate.m's
0092 % default filter) does spread an impulse forward and backward in time and
0093 % could distort the latency of effects.
0094 %
0095 
0096 if nargin<3,
0097     method='boxcar';
0098 else
0099    if ~(strcmpi(method,'boxcar') || strcmpi(method,'fir')),
0100        error('Arugment ''method'' needs to be ''boxcar'' or ''fir''');
0101    end
0102 end
0103 
0104 if nargin<4
0105     bsln_wind=[];
0106 elseif ~isempty(bsln_wind),
0107    if length(bsln_wind)~=2,
0108        error('Argument bsln_wind needs to be a two element vector.');
0109    end
0110 end
0111 
0112 if nargin<5
0113     save_GND='yes';
0114 elseif ~(strcmpi(save_GND,'yes') || strcmpi(save_GND,'no'))
0115     error('Argument save_GND needs to be ''yes'' or ''no''.');
0116 end
0117 
0118 global VERBLEVEL;
0119 if nargin<6
0120     if isempty(VERBLEVEL),
0121         VERBLEVEL=2;
0122     end
0123 else
0124     VERBLEVEL=verblevel;
0125 end
0126 
0127 
0128 %Erase any t-test results as they won't be valid anymore
0129 if ~isempty(GND.t_tests),
0130     %but ask first
0131     if VERBLEVEL>1,
0132         resp=[];
0133         while ~strcmpi(resp,'y') && ~strcmpi(resp,'n') && ~strcmpi(resp,'yes') ...
0134                 && ~strcmpi(resp,'no'),
0135             fprintf('These data have t-test results stored with them that won''t be accurate after the data have been decimated.\nFor this reason, they will be erased.\n');
0136             resp=input(sprintf('Continue with decimation (t-tests will be erased)? [y or n] '),'s');
0137         end
0138         if strcmpi('n',resp) || strcmpi('no',resp),
0139            return
0140         end
0141         fprintf('Erasing t-test results stored with these data.\n');
0142     end
0143     GND.t_tests=[];
0144 end
0145 
0146 [n_chan, n_tpt, n_bin, n_sub]=size(GND.indiv_erps);
0147 if strcmpi(method,'boxcar')
0148     if VERBLEVEL>1,
0149        fprintf('Downsampling data by a factor of %d after low-pass filtering with a boxcar moving average.\n', ...
0150            decfactor);
0151     end
0152     
0153     %decimate with moving boxcar window of length decfactor*2-1
0154     neo_n_tpt=length(decfactor:decfactor:(n_tpt-decfactor+1));
0155     
0156     %Recompute time points
0157     neo_times=zeros(1,neo_n_tpt);
0158     ct=0;
0159     for t=decfactor:decfactor:(n_tpt-decfactor+1),
0160         ct=ct+1;
0161         if ~rem(ct,10),
0162             fprintf('Now computing time point %d of %d.\n',ct,neo_n_tpt);
0163         end
0164         tstart=t-decfactor+1;
0165         tend=t+decfactor-1;
0166         neo_times(ct)=mean(GND.time_pts(tstart:tend));
0167         for s=1:n_sub,
0168             for c=1:n_chan,
0169                 for b=1:n_bin,
0170                     GND.indiv_erps(c,ct,b,s)=mean(GND.indiv_erps(c,tstart:tend,b,s));
0171                 end
0172                 %Cal pulses
0173                 if ~isempty(GND.cals),
0174                     GND.cals.indiv_cals(c,ct,s)=mean(GND.cals.indiv_cals(c,tstart:tend,s));
0175                 end
0176             end            
0177         end
0178     end
0179     GND.indiv_erps=GND.indiv_erps(:,1:neo_n_tpt,:,:);
0180     if ~isempty(GND.cals),
0181         GND.cals.indiv_cals= GND.cals.indiv_cals(:,1:neo_n_tpt,:);
0182     end
0183     GND.time_pts=neo_times;
0184 else
0185     if VERBLEVEL>1,
0186        fprintf('Downsampling data by a factor of %d after low-pass filtering with a MATLAB derived FIR filter.\n', ...
0187            decfactor);
0188     end
0189     
0190     %Recompute time points
0191     GND.time_pts=round(decimate(GND.time_pts,decfactor,'fir'));
0192     neo_n_tpt=length(GND.time_pts);
0193     
0194     
0195     %Decimate individual participant ERPs
0196     for c=1:n_chan,
0197         fprintf('Now downsampling Channel %d (%s).\n',c,GND.chanlocs(c).labels);
0198         for b=1:n_bin,
0199             for s=1:n_sub,
0200                 GND.indiv_erps(c,1:neo_n_tpt,b,s)=decimate(GND.indiv_erps(c,:,b,s),decfactor,'FIR');
0201             end
0202         end
0203     end
0204     GND.indiv_erps=GND.indiv_erps(:,1:neo_n_tpt,:,:);
0205         
0206     if ~isempty(GND.cals),
0207         %Decimate cal pulse ERPs
0208         fprintf('Now downsampling cal pulses.\n');
0209         for s=1:n_sub,
0210             for c=1:n_chan,
0211                 GND.cals.indiv_cals(c,1:neo_n_tpt,s)=decimate(GND.cals.indiv_cals(c,:,s),decfactor,'FIR');
0212             end
0213         end
0214         GND.cals.indiv_cals=GND.cals.indiv_cals(:,1:neo_n_tpt,:);
0215     end
0216 end
0217 
0218 %Shrink grand fields for overwriting
0219 GND.grands=GND.grands(:,1:neo_n_tpt,:);
0220 GND.grands_stder=GND.grands_stder(:,1:neo_n_tpt,:);
0221 GND.grands_t=GND.grands_t(:,1:neo_n_tpt,:);
0222 
0223 %Rebaseline individual ERPs/cal pulses and recompute grands
0224 GND=baselineGND(GND,bsln_wind);
0225 
0226 %Recompute sampling rate
0227 GND.srate=GND.srate/decfactor;
0228 
0229 %add comand to history
0230 n_hist=length(GND.history);
0231 if isempty(bsln_wind),
0232     GND.history{n_hist+1}=sprintf('GND=decimate(GND,%d,''%s'',[],%d);', ...
0233         decfactor,method,VERBLEVEL);
0234 else
0235     GND.history{n_hist+1}=sprintf('GND=decimate(GND,%d,''%s'',[%d %d],%d);', ...
0236         decfactor,method,bsln_wind(1),bsln_wind(2), ...
0237         VERBLEVEL);
0238 end
0239 
0240 
0241 GND.saved='no';
0242 if strcmpi(save_GND,'yes'),
0243     GND=save_matmk(GND,'gui');
0244 end

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