returns onset times for events FORMAT [sf,Cname,Pv,Pname,DSstr] = spm_get_ons(k,T,dt,STOC,Fstr,v,Cname,s) k - number of scans T - time bins per scan dt - time bin length (secs) STOC - flag to enable stochastic designs [0 or 1] Fstr - Prompt string (usually indicates session) v - number of conditions or trials : can be empty Cname - {1 x v} cell of names for each condition : can be empty s - session number (used by batch system) sf - {1 x n} cell of stick function matrices Cname - {1 x n} cell of names for each condition Pv - {1 x n} cell of parametric vectors Pname - {1 x n} cell of names for each parameter DSstr - Design string _______________________________________________________________________ spm_get_ons contructs a cell of sparse delta functions specifying the onset of events or epochs (or both). These are convolved with a basis set at a later stage to give regressors that enter into the design matrix. Interactions of evoked responses with some parameter (time or a specified variate Pv) enter at this stage as additional columns in sf with each delta function multiplied by the [expansion of the] trial-specific parameter. If parametric modulation is modeled, P contains the original variate and Pname is its name. Otherwise Pv{i} = [] and Pname{i} = ''; Notes on responding to questions: 'number of conditions or trials': The number of conditions, trials, events or epochs in the design. Generally the baseline condition (epoch-related) or null event (event-related) should not be included e.g. for a simple ABABAB.. design enter 1 STOCHASTIC DESIGNS 'stochastic design': If you want a random design select yes. The ensuing design matrix and onset times in Sess are then used in subsequent analysis of the data and stimulus design respectively. 'include a null event': for stochastic designs a null event should be included if you want to estimate responses common to all trial types 'SOA (scans)': Stimulus onset asynchrony for the sucessive occurrence of trials. This is the time (in scans) between the onset of sucessive stimuli or trials (usually a fraction of a scan) 'relative frequency [trial 1,..n null]': Enter a vector with a relative frequency of presentation for each trial type (and the null event if included). The null event is last. The most efficient designs are given when all the frequencies are equal. 'stationary|modulated': If the occurence probabilities are the same for all scans then choose 'stationary'. Modulated designs are more efficient but entail 'runs' of the same trial type. NON STOCHASTIC DESIGNS 'Fixed|Variable': If the event of epoch starts with a fixed SOA choose 'Fixed'. If the SOA changes within any trial type choose variable. 'vector of onsets (scans) for trial n': If the SOA are variable you have to enter a vector of onet times for each event or epoch. Time is specified in terms of scans, where the start of the session begins at 0. 'variable durations'. If you want to model trains of onsets then select 'yes'. You will then be prompted for a vector of durations for each onset. This is useful when modeling short epochs of variable duration. 'SOA (scans)' and 'first trial (scans)': If the SOA is fixed you only have to specify what it is and when the first condition ses in terms of an interaction with the specified variate. SLCIE TIMIING With longs TRs you may want to shift the regressors so that they are aligned to a particular slice. This is effected by resetting the values of fMRI_T and fMRI_T0 in som_defaults. fMRI_T is the number of time-bins per scan used when building regressors. Onsets are defined in temporal units of scans starting at 0. fMRI_T0 is the first time-bin at which the regressors are resampled to coincide with data acquisition. If fMRI_T0 = 1 then the regressors will be appropriate for the first slice. If you want to temporally realign the regressors so that they match responses in the middle slice then make fMRI_T0 = fMRI_T/2 (assuming there is a negligible gap between volume acquisitions. Default values are fMRI_T = 16 and fMRI_T0 = 1. _______________________________________________________________________ @(#)spm_get_ons.m 2.30 Karl Friston 01/03/22
0001 function [sf,Cname,Pv,Pname,DSstr] = pr_spm_get_ons(k,T,dt,STOC,Fstr,v,Cname,s) 0002 % returns onset times for events 0003 % FORMAT [sf,Cname,Pv,Pname,DSstr] = spm_get_ons(k,T,dt,STOC,Fstr,v,Cname,s) 0004 % 0005 % k - number of scans 0006 % T - time bins per scan 0007 % dt - time bin length (secs) 0008 % STOC - flag to enable stochastic designs [0 or 1] 0009 % Fstr - Prompt string (usually indicates session) 0010 % v - number of conditions or trials : can be empty 0011 % Cname - {1 x v} cell of names for each condition : can be empty 0012 % s - session number (used by batch system) 0013 % 0014 % sf - {1 x n} cell of stick function matrices 0015 % Cname - {1 x n} cell of names for each condition 0016 % Pv - {1 x n} cell of parametric vectors 0017 % Pname - {1 x n} cell of names for each parameter 0018 % DSstr - Design string 0019 %_______________________________________________________________________ 0020 % 0021 % spm_get_ons contructs a cell of sparse delta functions specifying the 0022 % onset of events or epochs (or both). These are convolved with a basis set 0023 % at a later stage to give regressors that enter into the design matrix. 0024 % Interactions of evoked responses with some parameter (time or a specified 0025 % variate Pv) enter at this stage as additional columns in sf with each delta 0026 % function multiplied by the [expansion of the] trial-specific parameter. 0027 % If parametric modulation is modeled, P contains the original variate and 0028 % Pname is its name. Otherwise Pv{i} = [] and Pname{i} = ''; 0029 % 0030 % Notes on responding to questions: 0031 % 0032 % 'number of conditions or trials': The number of conditions, trials, 0033 % events or epochs in the design. Generally the baseline condition 0034 % (epoch-related) or null event (event-related) should not be included 0035 % e.g. for a simple ABABAB.. design enter 1 0036 % 0037 % STOCHASTIC DESIGNS 0038 % 0039 % 'stochastic design': If you want a random design select yes. The ensuing 0040 % design matrix and onset times in Sess are then used in 0041 % subsequent analysis of the data and stimulus design respectively. 0042 % 0043 % 'include a null event': for stochastic designs a null event should 0044 % be included if you want to estimate responses common to 0045 % all trial types 0046 % 0047 % 'SOA (scans)': Stimulus onset asynchrony for the sucessive occurrence 0048 % of trials. This is the time (in scans) between the onset 0049 % of sucessive stimuli or trials (usually a fraction of a scan) 0050 % 0051 % 'relative frequency [trial 1,..n null]': Enter a vector with a 0052 % relative frequency of presentation for each trial type 0053 % (and the null event if included). The null event is last. 0054 % The most efficient designs are given when all the frequencies 0055 % are equal. 0056 % 0057 % 'stationary|modulated': If the occurence probabilities are 0058 % the same for all scans then choose 'stationary'. Modulated 0059 % designs are more efficient but entail 'runs' of the 0060 % same trial type. 0061 % 0062 % NON STOCHASTIC DESIGNS 0063 % 0064 % 'Fixed|Variable': If the event of epoch starts with a fixed 0065 % SOA choose 'Fixed'. If the SOA changes within any trial type 0066 % choose variable. 0067 % 0068 % 'vector of onsets (scans) for trial n': If the SOA are variable 0069 % you have to enter a vector of onet times for each event or 0070 % epoch. Time is specified in terms of scans, where the 0071 % start of the session begins at 0. 0072 % 0073 % 'variable durations'. If you want to model trains of 0074 % onsets then select 'yes'. You will then be prompted for 0075 % a vector of durations for each onset. This is useful when 0076 % modeling short epochs of variable duration. 0077 % 0078 % 'SOA (scans)' and 'first trial (scans)': If the SOA is fixed you 0079 % only have to specify what it is and when the first condition 0080 %ses in terms of an interaction with the specified 0081 % variate. 0082 % 0083 % SLCIE TIMIING 0084 % 0085 % With longs TRs you may want to shift the regressors so that they are 0086 % aligned to a particular slice. This is effected by resetting the 0087 % values of fMRI_T and fMRI_T0 in som_defaults. fMRI_T is the number of 0088 % time-bins per scan used when building regressors. Onsets are defined 0089 % in temporal units of scans starting at 0. fMRI_T0 is the first 0090 % time-bin at which the regressors are resampled to coincide with data 0091 % acquisition. If fMRI_T0 = 1 then the regressors will be appropriate 0092 % for the first slice. If you want to temporally realign the regressors 0093 % so that they match responses in the middle slice then make fMRI_T0 = 0094 % fMRI_T/2 (assuming there is a negligible gap between volume 0095 % acquisitions. Default values are fMRI_T = 16 and fMRI_T0 = 1. 0096 % 0097 % 0098 %_______________________________________________________________________ 0099 % @(#)spm_get_ons.m 2.30 Karl Friston 01/03/22 0100 0101 %-GUI setup 0102 %----------------------------------------------------------------------- 0103 spm_help('!ContextHelp',mfilename) 0104 0105 0106 %-Condition arguments 0107 %----------------------------------------------------------------------- 0108 if nargin < 5, Fstr = ''; end 0109 spm_input(Fstr,1,'d') 0110 0111 0112 % initialize variables 0113 %----------------------------------------------------------------------- 0114 sf = {}; 0115 Pv = {}; 0116 Pname = {}; 0117 DSstr = ''; 0118 %-------- 0119 sillyvar=0; 0120 0121 0122 % get stick functions {ons} and names 0123 %======================================================================= 0124 0125 0126 % get trials 0127 %----------------------------------------------------------------------- 0128 if isempty(v) 0129 v = spm_input('number of conditions or trials',2,'w1'); 0130 end 0131 if isempty(Cname) 0132 Cname = {}; 0133 for i = 1:v 0134 % get names 0135 %--------------------------------------------------------------- 0136 str = sprintf('name for condition/trial %d ?',i); 0137 Cname{i} = spm_input(str,3,'s',sprintf('trial %d',i)); 0138 end 0139 end 0140 0141 0142 0143 % event/epoch-related responses 0144 %----------------------------------------------------------------------- 0145 if v 0146 0147 0148 % stochastic designs 0149 %--------------------------------------------------------------- 0150 spm_input('Trial specification...',1,'d',Fstr) 0151 if STOC 0152 STOC = spm_input('stochastic design','+1','y/n',[1 0]); 0153 end 0154 if STOC 0155 0156 0157 % minimum SOA 0158 %------------------------------------------------------- 0159 ne = spm_input('include a null event','+1','y/n',[1 0]); 0160 soa = spm_input('SOA (scans)','+1','r',2)*T; 0161 on = fix(1:soa:(k*T)); 0162 ns = length(on); 0163 DSstr = [DSstr sprintf('Stochastic: %.2fsec SOA ',soa*dt)]; 0164 0165 0166 % occurence probabilities - stationary 0167 %------------------------------------------------------- 0168 if ne 0169 str = sprintf('relative frequency [trial 1,..%d null]',v); 0170 else 0171 str = sprintf('relative frequency [trial 1,..%d]',v); 0172 end 0173 P = ones(1,(v + ne)); 0174 P = spm_input(str,'+1','r',P,[1 (v + ne)]); 0175 str = 'occurence probability'; 0176 if spm_input(str,'+1','stationary|modulated',[1 0]) 0177 DSstr = [DSstr '(stationary) ']; 0178 P = P(:)*ones(1,ns); 0179 0180 % occurence probabilities - modulated (32 sec period) 0181 %------------------------------------------------------- 0182 else 0183 DSstr = [DSstr '(modulated) ']; 0184 p = ones((v + ne),ns); 0185 dc = 32/dt; 0186 for i = 1:(v + ne); 0187 q = sin(2*pi*(on/dc + (i - 1)/(v + ne))); 0188 p(i,:) = 1 + q; 0189 end 0190 P = diag(P)*p; 0191 end 0192 0193 0194 % assign trials 0195 %------------------------------------------------------- 0196 P = [zeros(1,ns); cumsum(P)]; 0197 P = P*diag(1./max(P)); 0198 q = zeros(size(on)); 0199 Q = rand(size(on)); 0200 for i = 1:(v + ne); 0201 j = find(Q >= P(i,:) & Q < P(i + 1,:)); 0202 q(j) = i; 0203 end 0204 0205 0206 % create stick functions 0207 %------------------------------------------------------- 0208 ons = sparse(on,q,1,k*T,v + ne); 0209 0210 0211 % stick function array (and delete null event) 0212 %------------------------------------------------------- 0213 for i = 1:v 0214 sf{i} = full(ons(:,i)); 0215 end 0216 0217 0218 % non-stochastic designs 0219 %--------------------------------------------------------------- 0220 else 0221 0222 0223 % get onsets 0224 %----------------------------------------------------------- 0225 Sstr = spm_input('SOA',2,'Fixed|Variable'); 0226 DSstr = [DSstr Sstr ' SOA ']; 0227 i = 1; 0228 while i <= v 0229 0230 0231 % get onsets 0232 %------------------------------------------------------- 0233 switch Sstr 0234 0235 0236 case 'Fixed' 0237 %- In batch mode, Sstr is always 'Variable' 0238 %----------------------------------------------- 0239 str = ['SOA (scans) for ' Cname{i}]; 0240 soa = spm_input(str,3,'r'); 0241 on = spm_input('time to 1st trial (scans)',4,'r',0); 0242 on = {on:soa:k}; 0243 dur = {zeros(size(on{1}))}; 0244 0245 0246 case 'Variable' 0247 %----------------------------------------------- 0248 str = ['vector of onsets (scans) - ' Cname{i}]; 0249 on = spm_input(str,3); 0250 if ~iscell(on), on = {on}; end 0251 0252 % get durationa 0253 %----------------------------------------------- 0254 dur = {}; 0255 for j = 1:length(on) 0256 dur{j} = zeros(size(on{j})); 0257 if length(on) == 1 0258 str = 'variable durations'; 0259 if spm_input(str,'+1','y/n',[1 0],2) 0260 dur{j} = spm_input('durations (scans)',... 0261 '+1','e',[],[1 length(on{j})]); 0262 dur{j} = round(dur{j}*T); 0263 end 0264 end 0265 end 0266 0267 0268 end 0269 0270 0271 % create stick functions 0272 %----------------------------------------------- 0273 for j = 1:length(on) 0274 ons = sparse(k*T,1); 0275 for p = 1:length(on{j}) 0276 q = round(on{j}(p)*T + 1); 0277 ons(q:(q + dur{j}(p))) = 1; 0278 end 0279 sf{i} = ons(1:(k*T)); 0280 i = i + 1; 0281 end 0282 0283 0284 end 0285 end 0286 0287 0288 0289 % get parameters, contruct interactions and append 0290 %================================================================ 0291 spm_input('Parametric specification...','+1','d',Fstr) 0292 0293 0294 % paramteric representation of causes - defaults for main effects 0295 %---------------------------------------------------------------- 0296 for i = 1:v 0297 Pv{i} = []; 0298 Pname{i} = ''; 0299 end 0300 0301 0302 % get parameter type 0303 %---------------------------------------------------------------- 0304 Ptype = {'none',... 0305 'time',... 0306 'other'}; 0307 Ptype = spm_input('parametric modulation','+1','b',Ptype); 0308 switch Ptype 0309 0310 0311 case 'none' 0312 %-------------------------------------------------------- 0313 return 0314 0315 0316 case 'other' 0317 %-------------------------------------------------------- 0318 Pstr = spm_input('name of parameter','+1','s'); 0319 0320 0321 case 'time' 0322 %-------------------------------------------------------- 0323 Pstr = Ptype; 0324 end 0325 0326 0327 % get parameters of expansion 0328 %---------------------------------------------------------------- 0329 Etype = {'linear',... 0330 'exponen',... 0331 'polynom'}; 0332 Etype = spm_input('expansion','+1','b',Etype); 0333 DSstr = [DSstr '[ x ' Pstr ' (' Etype ')] ']; 0334 switch Etype 0335 0336 0337 case 'exponen' 0338 %-------------------------------------------------------- 0339 if strcmp(Ptype,'time') 0340 h = round(k*T*dt/4); 0341 h = spm_input('time constant {secs}','+1','r',h); 0342 0343 0344 else 0345 h = spm_input('decay constant','+1','r'); 0346 end 0347 0348 0349 case 'polynom' 0350 %-------------------------------------------------------- 0351 str = 'order of polynomial expansion'; 0352 h = spm_input(str,'+1','r',2); 0353 0354 0355 end 0356 0357 0358 0359 % cycle over selected trial types 0360 %---------------------------------------------------------------- 0361 str = sprintf('which trial[s] 1 to %d',v); 0362 Ypos = spm_input('!NextPos'); 0363 0364 0365 for i = spm_input(str,'+1','e',1) 0366 %----------------- 0367 sillyvar=sillyvar+1; 0368 spm_input(Cname{i},Ypos,'d',Fstr); 0369 on = find(sf{i}(:,1)); 0370 ns = length(on); 0371 0372 0373 % get parameters 0374 %------------------------------------------------------- 0375 switch Ptype 0376 0377 0378 case 'other' 0379 %----------------------------------------------- 0380 str = ['parameters for ' Cname{i}]; 0381 p = spm_input(str,'+1','r',[],[ns,1]); 0382 0383 0384 case 'time' 0385 %----------------------------------------------- 0386 p = on*dt; 0387 0388 0389 end 0390 0391 0392 % expansion 0393 %-------------------------------------------------------- 0394 switch Etype 0395 0396 0397 0398 case 'polynom' 0399 %------------------------------------------------ 0400 u = spm_detrend(p(:)); 0401 v = zeros(size(u,1),h + 1); 0402 q = sparse(size(sf{i},1),h); 0403 for j = 0:h 0404 v(:,(j + 1)) = (u.^j) - v*(pinv(v)*(u.^j)); 0405 end 0406 for j = 1:h 0407 u = v(:,(j + 1)); 0408 q(:,j) = sparse(on,1,u,size(sf{i},1),1); 0409 end 0410 0411 0412 case 'exponen' 0413 %------------------------------------------------ 0414 q = exp(-p/h); 0415 q = spm_detrend(q(:)); 0416 q = sparse(on,1,q,size(sf{i},1),1); 0417 0418 0419 case 'linear' 0420 %------------------------------------------------ 0421 q = spm_detrend(p(:)); 0422 q = sparse(on,1,q,size(sf{i},1),1); 0423 0424 0425 0426 end 0427 0428 0429 % append as modulated stick functions 0430 %-------------------------------------------------------- 0431 sf{i} = [sf{i} q]; 0432 Pv{i} = p; 0433 Pname{i} = Pstr; 0434 0435 0436 end 0437 end