├── Example_SPM_Pipeline.pptx ├── README.md ├── batch_files ├── README.md ├── contrast_manager_spm12.mat ├── coregister_est_spm12.mat ├── dicom_spm12.mat ├── estimate_bayesian_spm12.mat ├── estimate_spm12.mat ├── first_level_spm12.mat ├── imcalc_brainstrip_spm12.mat ├── normalise_write_111_spm12.mat ├── normalise_write_333_spm12.mat ├── realign_unwarp_spm12.mat ├── results_report_spm12.mat ├── second_level_factorial_analysis_spm12.mat ├── second_level_onesampleT_spm12.mat ├── second_level_pairedT_spm12.mat ├── segment_biascorrected_spm12.mat ├── slice_timing_spm12.mat └── smooth_spm12.mat ├── behavioural_data_onset_duration.m ├── firstlevel_analysis.m ├── multisubject_analysis.m ├── preprocess.m └── secondlevel_analysis.m /Example_SPM_Pipeline.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildean/SPM_fMRI_Example_Pipeline/2be7356bcdc7d50d9fbaf5dded1fe19c3a809412/Example_SPM_Pipeline.pptx -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SPM fMRI Example Pipeline 2 | Example pipeline for preprocessing, reading in behavioural files, first level and second level analysis 3 | 4 | This folder contains: 5 | 6 | Powerpoint summary of pipeline used (Example_SPM_Pipeline) 7 | Matlab Scripts 8 | SPM Batch Files 9 | 10 | The scripts are organised such that everything runs from the "_multisubject_analysis_" script 11 | 12 | This script calls all the other scripts, running through subjects and folders to do this. 13 | 14 | In order: 15 | 16 | First do the preprocessing ("_preprocess_" script) 17 | After this is completed, you can run first level analysis ("_firstlevel_analysis_") 18 | This uses the script "_behavioural_data_onset_duration_" to load in onsets and durations of stimuli 19 | After this second level analysis ("_secondlevel_analysis_") can be done. 20 | 21 | The scripts will not run "off the shelf" perfectly, and will need some modification for your data pathways and design (e.g. change file paths). This will definitely be the case for the script to read behavioural data ("_behavioural_data_onset_duration_"), but will also be likely for the first and second level analyses. 22 | 23 | It is also only an example pipeline (although based on a simplification of one used in published analyses). Therefore, there may be a better design or paradigm that fits your specific data. However, it is hopefully a good place to start when learning SPM analysis, to run preliminary analysis on data, and to adapt to fit your data as you become comfortable with it. 24 | 25 | There are comments within the scripts to help understand the script and what it is doing, and where to modify it. And where possible, the modifiable variables are usually at the top of the script. 26 | 27 | You may also notice that the script basically opens up an SPM batch file (kept in the "_batch_files_" folder) and fills it in with the data and variables for the study, then runs it. This can be hard coded in SPM (ie no need for batch files, just directly run the analysis), but filling in batch files from script gives a balance between coding and direct interface input that might be more intuitive when learning SPM analysis. 28 | 29 | You can load the batch files and see what they look like in SPM interface, then load them in the script and see what variables are contained within to have an idea of what the program is doing. 30 | 31 | 32 | -------------------------------------------------------------------------------- /batch_files/README.md: -------------------------------------------------------------------------------- 1 | ## Batch Files 2 | 3 | This folder contains the batch files used in the matlab scripts 4 | -------------------------------------------------------------------------------- /batch_files/contrast_manager_spm12.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildean/SPM_fMRI_Example_Pipeline/2be7356bcdc7d50d9fbaf5dded1fe19c3a809412/batch_files/contrast_manager_spm12.mat -------------------------------------------------------------------------------- /batch_files/coregister_est_spm12.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildean/SPM_fMRI_Example_Pipeline/2be7356bcdc7d50d9fbaf5dded1fe19c3a809412/batch_files/coregister_est_spm12.mat -------------------------------------------------------------------------------- /batch_files/dicom_spm12.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildean/SPM_fMRI_Example_Pipeline/2be7356bcdc7d50d9fbaf5dded1fe19c3a809412/batch_files/dicom_spm12.mat -------------------------------------------------------------------------------- /batch_files/estimate_bayesian_spm12.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildean/SPM_fMRI_Example_Pipeline/2be7356bcdc7d50d9fbaf5dded1fe19c3a809412/batch_files/estimate_bayesian_spm12.mat -------------------------------------------------------------------------------- /batch_files/estimate_spm12.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildean/SPM_fMRI_Example_Pipeline/2be7356bcdc7d50d9fbaf5dded1fe19c3a809412/batch_files/estimate_spm12.mat -------------------------------------------------------------------------------- /batch_files/first_level_spm12.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildean/SPM_fMRI_Example_Pipeline/2be7356bcdc7d50d9fbaf5dded1fe19c3a809412/batch_files/first_level_spm12.mat -------------------------------------------------------------------------------- /batch_files/imcalc_brainstrip_spm12.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildean/SPM_fMRI_Example_Pipeline/2be7356bcdc7d50d9fbaf5dded1fe19c3a809412/batch_files/imcalc_brainstrip_spm12.mat -------------------------------------------------------------------------------- /batch_files/normalise_write_111_spm12.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildean/SPM_fMRI_Example_Pipeline/2be7356bcdc7d50d9fbaf5dded1fe19c3a809412/batch_files/normalise_write_111_spm12.mat -------------------------------------------------------------------------------- /batch_files/normalise_write_333_spm12.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildean/SPM_fMRI_Example_Pipeline/2be7356bcdc7d50d9fbaf5dded1fe19c3a809412/batch_files/normalise_write_333_spm12.mat -------------------------------------------------------------------------------- /batch_files/realign_unwarp_spm12.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildean/SPM_fMRI_Example_Pipeline/2be7356bcdc7d50d9fbaf5dded1fe19c3a809412/batch_files/realign_unwarp_spm12.mat -------------------------------------------------------------------------------- /batch_files/results_report_spm12.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildean/SPM_fMRI_Example_Pipeline/2be7356bcdc7d50d9fbaf5dded1fe19c3a809412/batch_files/results_report_spm12.mat -------------------------------------------------------------------------------- /batch_files/second_level_factorial_analysis_spm12.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildean/SPM_fMRI_Example_Pipeline/2be7356bcdc7d50d9fbaf5dded1fe19c3a809412/batch_files/second_level_factorial_analysis_spm12.mat -------------------------------------------------------------------------------- /batch_files/second_level_onesampleT_spm12.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildean/SPM_fMRI_Example_Pipeline/2be7356bcdc7d50d9fbaf5dded1fe19c3a809412/batch_files/second_level_onesampleT_spm12.mat -------------------------------------------------------------------------------- /batch_files/second_level_pairedT_spm12.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildean/SPM_fMRI_Example_Pipeline/2be7356bcdc7d50d9fbaf5dded1fe19c3a809412/batch_files/second_level_pairedT_spm12.mat -------------------------------------------------------------------------------- /batch_files/segment_biascorrected_spm12.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildean/SPM_fMRI_Example_Pipeline/2be7356bcdc7d50d9fbaf5dded1fe19c3a809412/batch_files/segment_biascorrected_spm12.mat -------------------------------------------------------------------------------- /batch_files/slice_timing_spm12.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildean/SPM_fMRI_Example_Pipeline/2be7356bcdc7d50d9fbaf5dded1fe19c3a809412/batch_files/slice_timing_spm12.mat -------------------------------------------------------------------------------- /batch_files/smooth_spm12.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildean/SPM_fMRI_Example_Pipeline/2be7356bcdc7d50d9fbaf5dded1fe19c3a809412/batch_files/smooth_spm12.mat -------------------------------------------------------------------------------- /behavioural_data_onset_duration.m: -------------------------------------------------------------------------------- 1 | function [ev] = behavioural_data_onset_duration(filename,response_button) 2 | % Updated Dec 2018 3 | % Based on script by Adam McNamara, edited by Philip Dean 4 | 5 | % READS BEHAVIOURAL FILE TO GET TIMING OF BLOCKS 6 | % (NB: This is for block design fMRI study. Event related needs this for 7 | % each individual stimuli) 8 | 9 | 10 | % First level analysis needs block start and block duration (or event start/duration) relative to start of fMRI scan. 11 | 12 | % Also find timing of other factors, especially rest screen (and intro 13 | % screen, feedback, stimuli and response) 14 | 15 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 | %% Define variables to be used in script 17 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 18 | 19 | ev = {}; % This is the ev variable that is reported out by the script 20 | 21 | %%%% These subvariable arrays are made when going through the logfile below 22 | ev.blockstartend = []; % This is a sub-variable in ev which notes start and end of block: [Block, Block_Type, StartEnd, Time] 23 | ev.stimulus = []; % Stimuli in Block: [Block, Block_Type, Actual_Number, Is_Target, Time] 24 | ev.stimulus_other = []; % Other Stimuli (outside block): [Block, Block_Type, Stimuli_Type, Time] 25 | ev.response = []; % Response in Block: [Block, Exp_Block, Block_Type, Response_Code, Is_Target, Time] 26 | ev.response_other = []; % Response outside block: [Block, Block_Type, Response_Code, Time] 27 | ev.pulse_timing = []; % Timing of MRI Pulse: [Block, Block_Type, Time] 28 | 29 | %%%% These are variables used in making the arrays above 30 | Block = 0; % Counts up number of blocks 31 | Exp_Block = 0; % Counts up number of task (non-rest) blocks. 32 | BlockType = 0; % 1=Rest; 2=0-Back; 3=2-Back; 4=4-Back; 0=Beginning of experiment 33 | startend = 2; % 0=In Block; 1=End of Block & Between Block; 2=Beginning of Experiment 34 | first_time_only = 0; % Make sure that only counts first MRI pulse as start of session 35 | stim_other_type = 0; % 1=nBack Intro Screen, 2=Rest Intro Screen, 3=Intro Rest, 4=Intro 0-Back, 5=Intro 2-Back, 6=Intro 4-Back 36 | 37 | response_on = 0; % Determines whether to record response and prevents a double response to one stimuli 0=record response; 1=don't record response (response outside Block, and prevents a double response to one stimuli) 38 | is_target = 0; % Whether stimuli is "target" or not: 0=non-target; 1=target 39 | 40 | %%%% These subvariable arrays created from above arrays after going through logfile 41 | ev.blockstartduration = []; % This is in the format onset/duration as needed by 1st level analysis [Block, Block_Type, StartEnd, Time, Duration] 42 | ev.blockstartduration_rest = []; % [Block, Block_Type, StartEnd, Time, Duration] 43 | ev.blockstartduration_task = []; % [Block, Block_Type, StartEnd, Time, Duration] 44 | ev.blockstartduration_task_adjusted = [];% Adjusted for start of block (time_adjust_2 below) 45 | 46 | ev.percent_correct = []; % USED IN FIRST LEVEL PARAMETRIC ANALYSIS [Block, Block_Type, Total % Correct, Target % Correct, Non-Target % Correct] 47 | singleblock = []; % used in percent correct calculation 48 | 49 | %%%% These are variables used in making the arrays above 50 | num_correct_T = 0; % Number Correct: Target 51 | num_correct_N = 0; % Number Correct: Non-Target 52 | num_correct = 0; % Total Number Correct 53 | 54 | %%%% Constants for your experiment type. used in percent correct calculation 55 | trial_per_block = 15; 56 | target_stimuli_block = 5; 57 | nontarget_stimuli_block = 10; 58 | 59 | time_adjust_1 = 60000; % seconds between intro screen and start of block in first experiment 60 | time_adjust_2 = 21500; % seconds between Pulse MR screen and start of block in main experiment 61 | 62 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 63 | %% Main Script 64 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 65 | 66 | fid = fopen(filename); % opens the logfile 67 | 68 | begin = 0; %identifies first trial and switches to collecting data 69 | 70 | %%%%%%%%%%%% Code works out if at end of logfile by finding 20 consecutive "gaps" 71 | %%%%%%%%%%%% in logfile 72 | keeplooking = 0; % ignores the occasional gap in the file but notices the end of the file 73 | while keeplooking < 20; % i.e more than 20 empty returns signals end of file 74 | a = fscanf(fid,'%s',1); %this just looks for the next bit of info and reads as string. 75 | if strcmp(a,''); keeplooking = keeplooking+1; else keeplooking = 0; end; %counts number of times there is nothing returned 76 | %%%%%%%%%%%% 77 | 78 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 79 | %% Code for responses and stimuli in logfile 80 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 81 | 82 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 83 | %% Pulses (MRI Pulse, for EEG-MRI only) 84 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 85 | 86 | if strcmp(a,'Pulse') 87 | Code = fscanf(fid,'%s',1); % Next column with entry is the "code" column (100 for Pulse) 88 | Time = fscanf(fid,'%s',1); % Next column with entry is "Time" column 89 | CodePulse = str2num(Code); 90 | if first_time_only == 0; 91 | if CodePulse == 100; 92 | sess_start=str2num(Time); % Works out when session started from first MRI Pulse 93 | first_time_only = 1; % Makes sure only 94 | end 95 | else 96 | if CodePulse == 100; 97 | ev.pulse_timing = [ev.pulse_timing;[Block BlockType [str2num(Time)-sess_start]]]; 98 | end 99 | end 100 | end 101 | 102 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 103 | %% Responses 104 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 105 | 106 | if strcmp(a,'Response') 107 | Code = fscanf(fid,'%s',1); 108 | Time = fscanf(fid,'%s',1); 109 | CodeNum = str2num(Code); 110 | % if CodeNum == 5; % This is the mouse button press that usually starts the experiment 111 | % sess_start=str2num(Time); % Works out when session started from first press of mouse button (CodeNum 5) 112 | % sess= sess + 1; 113 | % end 114 | if exist('sess_start'); 115 | if startend == 0; % Responses during blocks 116 | if response_on == 0; % Response only recorded if response_on = 0 (prevents recording double hit of button) 117 | ev.response = [ev.response;[Block Exp_Block BlockType CodeNum is_target [str2num(Time)-sess_start]]]; 118 | response_on = 1; % means next response will not be counted unless response_on reset to 0 (prevents recording double hit of button) 119 | elseif response_on == 1; 120 | end 121 | else % startend=2 (beginning of block); startend=1 (responses between blocks) 122 | if response_on == 0; 123 | ev.response_other = [ev.response_other;[Block BlockType CodeNum [str2num(Time)-sess_start]]]; 124 | response_on = 1; 125 | elseif response_on == 1; 126 | end 127 | end 128 | end 129 | end; 130 | 131 | 132 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 133 | %% Stimuli 134 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 135 | 136 | if strcmp(a,'Picture') 137 | Code = fscanf(fid,'%s',1); 138 | Code2 = fscanf(fid,'%s',1); 139 | 140 | switch Code2 % used to look at each instance of what is in this position in the logfile in turn 141 | 142 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 143 | %% Start Block Screens %%%%%%%%%%%%%%%%%% 144 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 145 | 146 | case 'Block' %%%% Rest Block 147 | TrialCode = fscanf(fid,'%s',1); 148 | TrialCode2 = fscanf(fid,'%s',1); 149 | 150 | Time = fscanf(fid,'%s',1); 151 | 152 | Block = Block + 1; 153 | BlockType = 1; 154 | startend = 0; % Start of Block = 0 155 | response_on = 1; % to prevent first button press being registered in % correct 156 | 157 | ev.blockstartend = [ev.blockstartend;[Block BlockType startend [str2num(Time)-sess_start]]]; 158 | 159 | 160 | case 'MR' %%%% Post MR Pulse 0-Back; Post MR Pulse 2-Back; Post MR Pulse 4-Back; 161 | Code3 = fscanf(fid,'%s',1); 162 | Code4 = fscanf(fid,'%s',1); 163 | TrialCode = fscanf(fid,'%s',1); 164 | TrialCode2 = fscanf(fid,'%s',1); 165 | TrialCode3 = fscanf(fid,'%s',1); 166 | TrialCode4 = fscanf(fid,'%s',1); 167 | 168 | Time = fscanf(fid,'%s',1); 169 | %Time_Adjust = Time + 21660; % Adjust as the info screen lasts 2.15s (2.166 in logfile) 170 | 171 | if strcmp(Code4,'0-Back') == 1 %%%% Post MR Pulse 0-Back 172 | Block = Block + 1; 173 | Exp_Block = Exp_Block + 1; 174 | BlockType = 2; 175 | startend = 0; % Start of Block = 0 176 | response_on = 1; % to prevent first button press being registered in % correct 177 | 178 | ev.blockstartend = [ev.blockstartend;[Block BlockType startend [str2num(Time)-sess_start]]]; 179 | 180 | elseif strcmp(Code4,'2-Back') == 1 %%%% Post MR Pulse 2-Back 181 | Block = Block + 1; 182 | Exp_Block = Exp_Block + 1; 183 | BlockType = 3; 184 | startend = 0; % Start of Block = 0 185 | response_on = 1; % to prevent first button press being registered in % correct 186 | 187 | ev.blockstartend = [ev.blockstartend;[Block BlockType startend [str2num(Time)-sess_start]]]; 188 | 189 | elseif strcmp(Code4,'4-Back') == 1 %%%% Post MR Pulse 0-Back THIS NEVER OCCURS IN LOGFILE! 190 | Block = Block + 1; 191 | Exp_Block = Exp_Block + 1; 192 | BlockType = 4; 193 | startend = 0; % Start of Block = 0 194 | response_on = 1; % to prevent first button press being registered in % correct 195 | 196 | ev.blockstartend = [ev.blockstartend;[Block BlockType startend [str2num(Time)-sess_start]]]; 197 | 198 | end 199 | 200 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 201 | %% End Block Screens %%%%%%%%%%%%%%%%%% 202 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 203 | 204 | case 'Rest' %%%% Intro Rest; EndBl Rest 205 | TrialCode = fscanf(fid,'%s',1); 206 | TrialCode2 = fscanf(fid,'%s',1); 207 | 208 | Time = fscanf(fid,'%s',1); 209 | 210 | if strcmp(TrialCode,'EndBl') == 1 %%%% EndBl Rest 211 | startend = 1; % End of Block = 1 212 | response_on = 0; 213 | 214 | ev.blockstartend = [ev.blockstartend;[Block BlockType startend [str2num(Time)-sess_start]]]; 215 | 216 | elseif strcmp(TrialCode,'Intro') == 1 217 | stim_other_type = 3; 218 | response_on = 1; % means next response is not recorded 219 | ev.stimulus_other = [ev.stimulus_other;[Block BlockType stim_other_type [str2num(Time)-sess_start]]]; 220 | 221 | end 222 | 223 | case '0-Back' %%%% EndBl 0-Back 224 | TrialCode = fscanf(fid,'%s',1); 225 | TrialCode2 = fscanf(fid,'%s',1); 226 | 227 | Time = fscanf(fid,'%s',1); 228 | 229 | startend = 1; % End of Block = 1 230 | response_on = 0; 231 | 232 | ev.blockstartend = [ev.blockstartend;[Block BlockType startend [str2num(Time)-sess_start]]]; 233 | 234 | 235 | case '2-Back' %%%% EndBl 2-Back 236 | TrialCode = fscanf(fid,'%s',1); 237 | TrialCode2 = fscanf(fid,'%s',1); 238 | 239 | Time = fscanf(fid,'%s',1); 240 | 241 | startend = 1; % End of Block = 1 242 | response_on = 0; 243 | 244 | ev.blockstartend = [ev.blockstartend;[Block BlockType startend [str2num(Time)-sess_start]]]; 245 | 246 | 247 | case '4-Back' %%%% EndBl 4-Back 248 | TrialCode = fscanf(fid,'%s',1); 249 | TrialCode2 = fscanf(fid,'%s',1); 250 | 251 | Time = fscanf(fid,'%s',1); 252 | 253 | startend = 1; % End of Block = 1 254 | response_on = 0; 255 | 256 | ev.blockstartend = [ev.blockstartend;[Block BlockType startend [str2num(Time)-sess_start]]]; 257 | 258 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 259 | %% Before Experiment Stimuli (and before block for n-Back) %%%%%%% 260 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 261 | 262 | case 'Intro' %%%% nBack Intro Screen; Rest Intro Screen 263 | Code3 = fscanf(fid,'%s',1); 264 | TrialCode = fscanf(fid,'%s',1); %%%% nBack or Rest 265 | TrialCode2 = fscanf(fid,'%s',1); %%%% Intro 266 | TrialCode3 = fscanf(fid,'%s',1); %%%% Screen 267 | 268 | if strcmp(TrialCode,'nBack') == 1 269 | Time = fscanf(fid,'%s',1); 270 | stim_other_type = 1; 271 | response_on = 1; % means next response is not recorded 272 | ev.stimulus_other = [ev.stimulus_other;[Block BlockType stim_other_type [str2num(Time)-sess_start]]]; 273 | elseif strcmp(TrialCode,'Rest') == 1 274 | Time = fscanf(fid,'%s',1); 275 | stim_other_type = 2; 276 | response_on = 1; % means next response is not recorded 277 | ev.stimulus_other = [ev.stimulus_other;[Block BlockType stim_other_type [str2num(Time)-sess_start]]]; 278 | end 279 | 280 | case '0' %%%% Intro 0 n-Back 281 | Code3 = fscanf(fid,'%s',1); 282 | TrialCode = fscanf(fid,'%s',1); 283 | TrialCode2 = fscanf(fid,'%s',1); 284 | TrialCode3 = fscanf(fid,'%s',1); 285 | 286 | Time = fscanf(fid,'%s',1); 287 | 288 | stim_other_type = 4; 289 | response_on = 1; % means next response is not recorded 290 | ev.stimulus_other = [ev.stimulus_other;[Block BlockType stim_other_type [str2num(Time)-sess_start]]]; 291 | 292 | %%%%%%% Code used for those logfiles without "Post MR Pulse n-Back" 293 | %Block = Block + 1; 294 | %BlockType = 2; 295 | %startend = 0; % Start of Block = 0 296 | %ev.blockstartend = [ev.blockstartend;[Block BlockType startend [str2num(Time)-sess_start]]]; 297 | 298 | case '2' %%%% Intro 2 n-Back 299 | Code3 = fscanf(fid,'%s',1); 300 | TrialCode = fscanf(fid,'%s',1); 301 | TrialCode2 = fscanf(fid,'%s',1); 302 | TrialCode3 = fscanf(fid,'%s',1); 303 | 304 | Time = fscanf(fid,'%s',1); 305 | 306 | stim_other_type = 5; 307 | response_on = 1; % means next response is not recorded 308 | ev.stimulus_other = [ev.stimulus_other;[Block BlockType stim_other_type [str2num(Time)-sess_start]]]; 309 | 310 | %%%%%%% Code used for those logfiles without "Post MR Pulse n-Back" 311 | %Block = Block + 1; 312 | %BlockType = 3; 313 | %startend = 0; % Start of Block = 0 314 | %ev.blockstartend = [ev.blockstartend;[Block BlockType startend [str2num(Time)-sess_start]]]; 315 | 316 | case '4' %%%% Intro 4 n-Back 317 | Code3 = fscanf(fid,'%s',1); 318 | TrialCode = fscanf(fid,'%s',1); 319 | TrialCode2 = fscanf(fid,'%s',1); 320 | TrialCode3 = fscanf(fid,'%s',1); 321 | 322 | Time = fscanf(fid,'%s',1); 323 | 324 | stim_other_type = 6; 325 | response_on = 1; % means next response is not recorded 326 | ev.stimulus_other = [ev.stimulus_other;[Block BlockType stim_other_type [str2num(Time)-sess_start]]]; 327 | 328 | %%%%%%% Code used for those logfiles without "Post MR Pulse n-Back" 329 | %Block = Block + 1; 330 | %BlockType = 4; 331 | %startend = 0; % Start of Block = 0 332 | %ev.blockstartend = [ev.blockstartend;[Block BlockType startend [str2num(Time)-sess_start]]]; 333 | 334 | %%%%%%%%%% All Stimuli in the block (all the numbers 1-9) 335 | 336 | otherwise %%%% All Stimuli in the Block 337 | 338 | TrialCode = fscanf(fid,'%s',1); 339 | TrialCode2 = fscanf(fid,'%s',1); 340 | Number = fscanf(fid,'%s',1); 341 | Target = fscanf(fid,'%s',1); 342 | Time = fscanf(fid,'%s',1); 343 | NumberNum = str2num(Number); 344 | 345 | switch Target 346 | 347 | case 'Yes' %%%% Number is a Target 348 | is_target = 1; 349 | response_on = 0; % Next response counted 350 | 351 | ev.stimulus = [ev.stimulus;[Block BlockType NumberNum is_target [str2num(Time)-sess_start]]]; 352 | 353 | 354 | case 'No' %%%% Number is Non-Target 355 | is_target = 0; 356 | response_on = 0; % Next response counted 357 | 358 | ev.stimulus = [ev.stimulus;[Block BlockType NumberNum is_target [str2num(Time)-sess_start]]]; 359 | 360 | otherwise %%%% Is Not a Yes (Target) or No (Non-Target) Stimuli - Ignores it. 361 | 362 | end; 363 | end; 364 | 365 | end; % END Looking for Event Type "Picture" 366 | 367 | end; % END "while keep looking<20", i.e. end looking at logfile 368 | 369 | 370 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 371 | %%%% End of Looking through Logfile 372 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 373 | 374 | %%%%%% AND NOW 375 | 376 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 377 | %% Modification of existing arrays 378 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 379 | 380 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 381 | %% Create Block Start Duration array %%%%%%%%%%%%%%%%%%%% 382 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 383 | 384 | ev.blockstartduration=ev.blockstartend(find(ev.blockstartend(:,3) == 0),:); % find start of each block 385 | ev.blockstartduration=[ev.blockstartduration ev.blockstartend(find(ev.blockstartend(:,3) == 1),end)-ev.blockstartduration(:,end)]; % add duration at end of array 386 | %%%% [Block, Block_Type, StartEnd, Time, Duration] 387 | 388 | ev.blockstartduration(4,2) = 4; % Change "block_type" to 4 (from 3) for 4-Back 389 | ev.blockstartduration(6,2) = 4; 390 | ev.blockstartduration(12,2) = 4; 391 | ev.blockstartduration(13,2) = 4; 392 | ev.blockstartduration(19,2) = 4; 393 | ev.blockstartduration(22,2) = 4; 394 | ev.blockstartduration(29,2) = 4; 395 | ev.blockstartduration(33,2) = 4; 396 | ev.blockstartduration(34,2) = 4; 397 | ev.blockstartduration(38,2) = 4; 398 | 399 | ev.blockstartduration_rest = ev.blockstartduration(find(ev.blockstartduration(:,2) == 1),:); 400 | ev.blockstartduration_task = ev.blockstartduration(find(ev.blockstartduration(:,2) == 2 | ev.blockstartduration(:,2) == 3 | ev.blockstartduration(:,2) == 4),:); 401 | 402 | ev.blockstartduration_task_adjusted = ev.blockstartduration_task; 403 | ev.blockstartduration_task_adjusted(:,4) = (ev.blockstartduration_task_adjusted(:,4)+ time_adjust_2); 404 | ev.blockstartduration_task_adjusted(:,5) = (ev.blockstartduration_task_adjusted(:,5)- time_adjust_2); 405 | 406 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 407 | %% Create Percent Correct Array %%%%%%%%%%%%%%%%%%%%%%% 408 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 409 | 410 | if response_button == 1; 411 | if isempty(ev.response) == 1; %if no responses at all 412 | 413 | else 414 | for ii = 1:size(ev.blockstartduration_task_adjusted, 1) 415 | ev.singleblock = ev.response((find(ev.response(:,2) == ii)), :); % find only block ii (block 1-Block) 416 | num_correct_T = size(find(ev.singleblock(:,4) == 1 & ev.singleblock(:,5) == 1)); % Num correct target: response = 2 and is_target = 1 417 | num_correct_N = size(find(ev.singleblock(:,4) == 2 & ev.singleblock(:,5) == 0)); % Num correct non-target: response = 1 and is_target = 0 418 | num_correct = num_correct_T(1,1) + num_correct_N(1,1); % add these two together 419 | 420 | ev.percent_correct = [ev.percent_correct;[ii ev.singleblock(1,3) ((num_correct/trial_per_block)*100) ((num_correct_T(1,1)/target_stimuli_block)*100) ((num_correct_N(1,1)/nontarget_stimuli_block)*100)]]; 421 | %%%% [ExpBlock, Block_Type, Total % Correct, Target % Correct, Non-Target % Correct] 422 | end; 423 | end 424 | 425 | elseif response_button == 2; 426 | if isempty(ev.response) == 1; %if no responses at all 427 | 428 | else 429 | for ii = 1:size(ev.blockstartduration_task_adjusted, 1) % For each of the Blocks 430 | ev.singleblock = ev.response((find(ev.response(:,2) == ii)), :); % find only block ii (block 1-Block) 431 | num_correct_T = size(find(ev.singleblock(:,4) == 2 & ev.singleblock(:,5) == 1)); % Num correct target: response = 2 and is_target = 1 432 | num_correct_N = size(find(ev.singleblock(:,4) == 1 & ev.singleblock(:,5) == 0)); % Num correct non-target: response = 1 and is_target = 0 433 | num_correct = num_correct_T(1,1) + num_correct_N(1,1); % add these two together 434 | 435 | ev.percent_correct = [ev.percent_correct;[ii ev.singleblock(1,3) ((num_correct/trial_per_block)*100) ((num_correct_T(1,1)/target_stimuli_block)*100) ((num_correct_N(1,1)/nontarget_stimuli_block)*100)]]; 436 | %%%% [ExpBlock, Block_Type, Total % Correct, Target % Correct, Non-Target % Correct] 437 | end; 438 | end 439 | end 440 | 441 | ev.percent_correct(3,2) = 4; % Change "block_type" to 4 (from 3) for 4-Back 442 | ev.percent_correct(5,2) = 4; 443 | ev.percent_correct(10,2) = 4; 444 | ev.percent_correct(11,2) = 4; 445 | ev.percent_correct(15,2) = 4; 446 | ev.percent_correct(18,2) = 4; 447 | ev.percent_correct(22,2) = 4; 448 | ev.percent_correct(26,2) = 4; 449 | ev.percent_correct(27,2) = 4; 450 | ev.percent_correct(29,2) = 4; -------------------------------------------------------------------------------- /firstlevel_analysis.m: -------------------------------------------------------------------------------- 1 | function firstlevel_analysis(todo,D, sh, subj) 2 | % Dec 2018 redone for spm12 3 | % Based on script by Adam McNamara, edited by Philip Dean 4 | 5 | % MAKE AND ESTIMATE MODEL 6 | % Make model using experimental logfiles/timings 7 | % Estimate model to create SPM file for first level analysis 8 | % Create contrasts 9 | % Results manager 10 | 11 | % INPUT ARGUMENTS: 12 | 13 | % 'todo' 14 | % m = make model (Basic GLM) 15 | % p = make model (Parametric) 16 | % b = make model (Bayesian) 17 | % e = estimate model NB: Need to change this dependent on what model made (see above) 18 | % c = contrasts manager NB: Need to change this dependent on what model made (see above) 19 | % r = results report NB: Need to change this dependent on what model made (see above) 20 | 21 | % if todo not given defaults todo = 'me' 22 | 23 | % 'D' 24 | % This is the Directory, e.g. 'E:\MRI\BECi_Study\Data\Subject_01' 25 | 26 | % So could call script as: 27 | % firstlevel_analysis('me','E:\MRI\BECi_Study\Data\Subject_01') 28 | % or, if just want to do model: 29 | % firstlevel_analysis('m','E:\MRI\BECi_Study\Data\Subject_01') 30 | 31 | % 'sh', 'subj' 32 | % These are inputs from the "multisubject_analysis.m" script 33 | % sh constains: sh.studypath; sh.imagepath; sh.behavpath 34 | % subj contains: subj.path; subj.task; subj.log_sess1; subj.log_sess2; subj.log_sess3; subj.response_button 35 | 36 | % Global Variables 37 | spm('Defaults', 'FMRI'); % Reset SPM defaults for fMRI (not sure necessary - safety catch?) 38 | global defaults; % Reset Global defaults (not sure why needed?) 39 | 40 | if ~exist('todo','var'); todo='me'; end; % if nothing entered in "todo" bracket, then this is the default action 41 | 42 | way='E:\MRI\BECi_Study\scripts\batch_files'; % Path to the "jobs"/batch files needed 43 | 44 | TR = 3; % Bunched acqusition (2s acquire, 1s gap for EEG) 45 | nslices_fMRI = 25; % Number of slices 46 | M = [0 0 0 0 0 0]; % Movement Parameter in-fill for contrasts 47 | numsess = 1; % Number of sessions 48 | 49 | % Contrasts to be used. Design is: 50 | % M is movement regressors, C is the constant for each session 51 | % [Rest_sess1 0Back_sess1 2Back_sess1 4-Back_sess1 M Rest_sess2 etc then Rest_sess3 etc then C C C] 52 | % F Contrasts 53 | % T Contrasts 54 | 55 | 56 | tic % start clock timing how long analysis takes 57 | 58 | 59 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 60 | %% Make model: Basic GLM 61 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 62 | if strfind(todo,'m') 63 | 64 | % if folder for stats doesnt exist, create the folder 65 | if ~exist(fullfile(D,'Stats\GLM'),'dir'); cd(D); mkdir('Stats\GLM'); end; 66 | stats_directory=fullfile(D,'Stats\GLM'); 67 | 68 | load(fullfile(way,'first_level_spm12.mat')); 69 | 70 | %%%%%% Global setup for model 71 | matlabbatch{1}.spm.stats.fmri_spec.dir = {stats_directory}; %Output Directory 72 | %matlabbatch{1}.spm.stats.fmri_spec.timing.units = secs; %TIMING secs/scans 73 | %matlabbatch{1}.spm.stats.fmri_spec.timing.RT = 3; %TR 74 | %matlabbatch{1}.spm.stats.fmri_spec.timing.fmri_t = 16; %Microtime resolution 75 | %matlabbatch{1}.spm.stats.fmri_spec.timing.fmri_t0 = 8; %Microtime Onset 76 | 77 | 78 | %%%%%% Filling in scans and conditions for each session 79 | for ss=1:numsess; %number of sessions 80 | directory=fullfile(D,['sess' num2str(ss)]); 81 | 82 | % Loading up pre-processed scans 83 | P=cellstr(spm_select('FPList', directory,'^swuf.*\.nii$')); 84 | 85 | for ii=1:size(P, 1); 86 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).scans{ii} = P{ii}; 87 | end 88 | 89 | clear P; 90 | 91 | 92 | %%%%%% Loading up onset/duration from behavioural logfile using script "behavioural_data_onset_duration" 93 | global ev; 94 | ev = {}; 95 | 96 | %if ss == 1; 97 | ev = behavioural_data_onset_duration((fullfile(sh.behavpath, subj.path, ['sess' num2str(ss)], subj.log_sess1)), subj.response_button); %finding the behavioural file for participant 98 | %elseif ss == 2; 99 | % ev = behavioural_data_onset_duration((fullfile(sh.behavpath, subj.path, ['sess' num2str(ss)], subj.log_sess2)), subj.response_button); 100 | %else 101 | % ev = behavioural_data_onset_duration((fullfile(sh.behavpath, subj.path, ['sess' num2str(ss)], subj.log_sess3)), subj.response_button); 102 | %end 103 | 104 | % Onsets/Duration 105 | n0=ev.blockstartduration_task_adjusted(find(ev.blockstartduration_task_adjusted(:,2) == 2),:); 106 | n2=ev.blockstartduration_task_adjusted(find(ev.blockstartduration_task_adjusted(:,2) == 3),:); 107 | n4=ev.blockstartduration_task_adjusted(find(ev.blockstartduration_task_adjusted(:,2) == 4),:); 108 | 109 | %%%%%% Filling in onsets and durations for each condition 110 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(1).name = 'Rest'; 111 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(1).onset =(ev.blockstartduration_rest(:,end-1)./10000); 112 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(1).duration =(ev.blockstartduration_rest(:,end)./10000); 113 | 114 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(2).name = '0-Back'; 115 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(2).onset = (n0(:,end-1)./10000); 116 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(2).duration = (n0(:,end)./10000); 117 | 118 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(3).name = '2-Back'; 119 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(3).onset = (n2(:,end-1)./10000); 120 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(3).duration = (n2(:,end)./10000); 121 | 122 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(4).name = '4-Back'; 123 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(4).onset = (n4(:,end-1)./10000); 124 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(4).duration = (n4(:,end)./10000); 125 | 126 | %%%%%% Loading in movement parameters as multiple regressor 127 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).multi_reg = cellstr(spm_select('FPList', directory,'^rp_f.*\.txt$')); 128 | 129 | %%%%%% Other possible inputs to Session: 130 | %matlabbatch{1}.spm.stats.fmri_spec.sess(1).cond(1).tmod = 0; % Time Modulation 131 | %matlabbatch{1}.spm.stats.fmri_spec.sess(1).cond(1).pmod; % Parametric Modulation 132 | %matlabbatch{1}.spm.stats.fmri_spec.sess(1).cond(1).orth = 1; % Orthogonalise Modulations (1=Yes) 133 | 134 | %matlabbatch{1}.spm.stats.fmri_spec.sess(1).multi = {''}; % For Multiple Conditions (.mat file) 135 | %matlabbatch{1}.spm.stats.fmri_spec.sess(1).regress = []; % Regressors to be regressed out of data 136 | %matlabbatch{1}.spm.stats.fmri_spec.sess(1).hpf = 128; % High Pass filter (for filtering out scanner drift/noise) 137 | 138 | end; 139 | 140 | %%%%%% Other Possible inputs 141 | %matlabbatch{1}.spm.stats.fmri_spec.fact = []; % Factorial Design 142 | %matlabbatch{1}.spm.stats.fmri_spec.bases.hrf.derivs = [0 0]; % Basis Function & Derivatives 143 | %matlabbatch{1}.spm.stats.fmri_spec.volt = 1; % Model Interactions(Volterra) 144 | %matlabbatch{1}.spm.stats.fmri_spec.global = 'None'; % Global Normalisation 145 | %matlabbatch{1}.spm.stats.fmri_spec.mthresh = 0.8; % Masking Threshold 146 | %matlabbatch{1}.spm.stats.fmri_spec.mask = {''}; % Explicit Mask 147 | %matlabbatch{1}.spm.stats.fmri_spec.cvi = 'AR(1)'; % Serial Correlations 148 | 149 | % keyboard %Used in bug-testing script 150 | spm_jobman('run',matlabbatch); 151 | 152 | end 153 | 154 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 155 | %% Make model: Parametric 156 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 157 | if strfind(todo,'p') 158 | 159 | % if folder for stats doesnt exist, create the folder 160 | if ~exist(fullfile(D,'Stats\Parametric'),'dir'); cd(D); mkdir('Stats\Parametric'); end; 161 | stats_directory=fullfile(D,'Stats\Parametric'); 162 | 163 | load(fullfile(way,'first_level_spm12.mat')); 164 | 165 | %%%%%% Global setup for model 166 | matlabbatch{1}.spm.stats.fmri_spec.dir = {stats_directory}; %Output Directory 167 | %matlabbatch{1}.spm.stats.fmri_spec.timing.units = secs; %TIMING secs/scans 168 | %matlabbatch{1}.spm.stats.fmri_spec.timing.RT = 3; %TR 169 | %matlabbatch{1}.spm.stats.fmri_spec.timing.fmri_t = 16; %Microtime resolution 170 | %matlabbatch{1}.spm.stats.fmri_spec.timing.fmri_t0 = 8; %Microtime Onset 171 | 172 | 173 | %%%%%% Filling in scans and conditions for each session 174 | for ss=1:numsess; %number of sessions 175 | directory=fullfile(D,['sess' num2str(ss)]); 176 | 177 | % Loading up pre-processed scans 178 | P=cellstr(spm_select('FPList', directory,'^swuf.*\.nii$')); 179 | 180 | for ii=1:size(P, 1); 181 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).scans{ii} = P{ii}; 182 | end 183 | 184 | clear P; 185 | 186 | 187 | %%%%%% Loading up onset/duration and precent correct (PARAMETRIC) from behavioural logfile using script "behavioural_data_onset_duration" 188 | global ev; 189 | ev = {}; 190 | 191 | %if ss == 1; 192 | ev = behavioural_data_onset_duration((fullfile(sh.behavpath, subj.path, ['sess' num2str(ss)], subj.log_sess1)), subj.response_button); %finding the behavioural file for participant 193 | %elseif ss == 2; 194 | % ev = behavioural_data_onset_duration((fullfile(sh.behavpath, subj.path, ['sess' num2str(ss)], subj.log_sess2)), subj.response_button); 195 | %else 196 | % ev = behavioural_data_onset_duration((fullfile(sh.behavpath, subj.path, ['sess' num2str(ss)], subj.log_sess3)), subj.response_button); 197 | %end 198 | 199 | % Onsets/Duration 200 | n0=ev.blockstartduration_task_adjusted(find(ev.blockstartduration_task_adjusted(:,2) == 2),:); 201 | n2=ev.blockstartduration_task_adjusted(find(ev.blockstartduration_task_adjusted(:,2) == 3),:); 202 | n4=ev.blockstartduration_task_adjusted(find(ev.blockstartduration_task_adjusted(:,2) == 4),:); 203 | % Percent Correct 204 | p0=ev.percent_correct(find(ev.percent_correct(:,2) == 2),:); 205 | p2=ev.percent_correct(find(ev.percent_correct(:,2) == 3),:); 206 | p4=ev.percent_correct(find(ev.percent_correct(:,2) == 4),:); 207 | 208 | %%%%%% Filling in onsets and durations for each condition 209 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(1).name = 'Rest'; 210 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(1).onset =(ev.blockstartduration_rest(:,end-1)./10000); 211 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(1).duration =(ev.blockstartduration_rest(:,end)./10000); 212 | 213 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(2).name = '0-Back'; 214 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(2).onset = (n0(:,end-1)./10000); 215 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(2).duration = (n0(:,end)./10000); 216 | 217 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(3).name = '2-Back'; 218 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(3).onset = (n2(:,end-1)./10000); 219 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(3).duration = (n2(:,end)./10000); 220 | 221 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(4).name = '4-Back'; 222 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(4).onset = (n4(:,end-1)./10000); 223 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(4).duration = (n4(:,end)./10000); 224 | 225 | %%%%%% Filling in percent correct for each task block (PARAMETRIC, Total % Correct) 226 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(2).pmod.name = '0-Back Correct'; % Parametric Modulation 227 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(2).pmod.poly = 1; 228 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(2).pmod.param = p0(:,end-2); 229 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(3).pmod.name = '2-Back Correct'; 230 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(3).pmod.poly = 1; 231 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(3).pmod.param = p2(:,end-2); 232 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(4).pmod.name = '4-Back Correct'; 233 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(4).pmod.poly = 1; 234 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(4).pmod.param = p4(:,end-2); 235 | 236 | %%%%%% Loading in movement parameters as multiple regressor 237 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).multi_reg = cellstr(spm_select('FPList', directory,'^rp_f.*\.txt$')); 238 | 239 | %%%%%% Other possible inputs to Session: 240 | %matlabbatch{1}.spm.stats.fmri_spec.sess(1).cond(1).tmod = 0; % Time Modulation 241 | %matlabbatch{1}.spm.stats.fmri_spec.sess(1).cond(1).orth = 1; % Orthogonalise Modulations (1=Yes) 242 | 243 | %matlabbatch{1}.spm.stats.fmri_spec.sess(1).multi = {''}; % For Multiple Conditions (.mat file) 244 | %matlabbatch{1}.spm.stats.fmri_spec.sess(1).regress = []; % Regressors to be regressed out of data 245 | %matlabbatch{1}.spm.stats.fmri_spec.sess(1).hpf = 128; % High Pass filter (for filtering out scanner drift/noise) 246 | 247 | end; 248 | 249 | %%%%%% Other Possible inputs 250 | %matlabbatch{1}.spm.stats.fmri_spec.fact = []; % Factorial Design 251 | %matlabbatch{1}.spm.stats.fmri_spec.bases.hrf.derivs = [0 0]; % Basis Function & Derivatives 252 | %matlabbatch{1}.spm.stats.fmri_spec.volt = 1; % Model Interactions(Volterra) 253 | %matlabbatch{1}.spm.stats.fmri_spec.global = 'None'; % Global Normalisation 254 | %matlabbatch{1}.spm.stats.fmri_spec.mthresh = 0.8; % Masking Threshold 255 | %matlabbatch{1}.spm.stats.fmri_spec.mask = {''}; % Explicit Mask 256 | %matlabbatch{1}.spm.stats.fmri_spec.cvi = 'AR(1)'; % Serial Correlations 257 | 258 | % keyboard %Used in bug-testing script 259 | spm_jobman('run',matlabbatch); 260 | 261 | end 262 | 263 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 264 | %% Make model: Bayesian 265 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 266 | if strfind(todo,'b') 267 | 268 | % if folder for stats doesnt exist, create the folder 269 | if ~exist(fullfile(D,'Stats\Bayesian'),'dir'); cd(D); mkdir('Stats\Bayesian'); end; 270 | stats_directory=fullfile(D,'Stats\Bayesian'); 271 | 272 | load(fullfile(way,'first_level_spm12.mat')); 273 | 274 | %%%%%% Global setup for model 275 | matlabbatch{1}.spm.stats.fmri_spec.dir = {stats_directory}; %Output Directory 276 | %matlabbatch{1}.spm.stats.fmri_spec.timing.units = secs; %TIMING secs/scans 277 | %matlabbatch{1}.spm.stats.fmri_spec.timing.RT = 3; %TR 278 | %matlabbatch{1}.spm.stats.fmri_spec.timing.fmri_t = 16; %Microtime resolution 279 | %matlabbatch{1}.spm.stats.fmri_spec.timing.fmri_t0 = 8; %Microtime Onset 280 | 281 | 282 | %%%%%% Filling in scans and conditions for each session 283 | for ss=1:numsess; %number of sessions 284 | directory=fullfile(D,['sess' num2str(ss)]); 285 | 286 | % Loading up pre-processed scans 287 | P=cellstr(spm_select('FPList', directory,'^wuf.*\.nii$')); % NON-SMOOTHED DATA USED 288 | 289 | for ii=1:size(P, 1); 290 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).scans{ii} = P{ii}; 291 | end 292 | 293 | clear P; 294 | 295 | 296 | %%%%%% Loading up onset/duration and precent correct (PARAMETRIC) from behavioural logfile using script "behavioural_data_onset_duration" 297 | global ev; 298 | ev = {}; 299 | 300 | %if ss == 1; 301 | ev = behavioural_data_onset_duration((fullfile(sh.behavpath, subj.path, ['sess' num2str(ss)], subj.log_sess1)), subj.response_button); %finding the behavioural file for participant 302 | %elseif ss == 2; 303 | % ev = behavioural_data_onset_duration((fullfile(sh.behavpath, subj.path, ['sess' num2str(ss)], subj.log_sess2)), subj.response_button); 304 | %else 305 | % ev = behavioural_data_onset_duration((fullfile(sh.behavpath, subj.path, ['sess' num2str(ss)], subj.log_sess3)), subj.response_button); 306 | %end 307 | 308 | % Onsets/Duration 309 | n0=ev.blockstartduration_task_adjusted(find(ev.blockstartduration_task_adjusted(:,2) == 2),:); 310 | n2=ev.blockstartduration_task_adjusted(find(ev.blockstartduration_task_adjusted(:,2) == 3),:); 311 | n4=ev.blockstartduration_task_adjusted(find(ev.blockstartduration_task_adjusted(:,2) == 4),:); 312 | 313 | %%%%%% Filling in onsets and durations for each condition 314 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(1).name = 'Rest'; 315 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(1).onset =(ev.blockstartduration_rest(:,end-1)./10000); 316 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(1).duration =(ev.blockstartduration_rest(:,end)./10000); 317 | 318 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(2).name = '0-Back'; 319 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(2).onset = (n0(:,end-1)./10000); 320 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(2).duration = (n0(:,end)./10000); 321 | 322 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(3).name = '2-Back'; 323 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(3).onset = (n2(:,end-1)./10000); 324 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(3).duration = (n2(:,end)./10000); 325 | 326 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(4).name = '4-Back'; 327 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(4).onset = (n4(:,end-1)./10000); 328 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).cond(4).duration = (n4(:,end)./10000); 329 | 330 | %%%%%% Loading in movement parameters as multiple regressor 331 | matlabbatch{1}.spm.stats.fmri_spec.sess(ss).multi_reg = cellstr(spm_select('FPList', directory,'^rp_f.*\.txt$')); 332 | 333 | %%%%%% Other possible inputs to Session: 334 | %matlabbatch{1}.spm.stats.fmri_spec.sess(1).cond(1).tmod = 0; % Time Modulation 335 | %matlabbatch{1}.spm.stats.fmri_spec.sess(1).cond(1).pmod; % Parametric Modulation 336 | %matlabbatch{1}.spm.stats.fmri_spec.sess(1).cond(1).orth = 1; % Orthogonalise Modulations (1=Yes) 337 | 338 | %matlabbatch{1}.spm.stats.fmri_spec.sess(1).multi = {''}; % For Multiple Conditions (.mat file) 339 | %matlabbatch{1}.spm.stats.fmri_spec.sess(1).regress = []; % Regressors to be regressed out of data 340 | %matlabbatch{1}.spm.stats.fmri_spec.sess(1).hpf = 128; % High Pass filter (for filtering out scanner drift/noise) 341 | 342 | end; 343 | 344 | %%%%%% Other Possible inputs 345 | %matlabbatch{1}.spm.stats.fmri_spec.fact = []; % Factorial Design 346 | %matlabbatch{1}.spm.stats.fmri_spec.bases.hrf.derivs = [0 0]; % Basis Function & Derivatives 347 | %matlabbatch{1}.spm.stats.fmri_spec.volt = 1; % Model Interactions(Volterra) 348 | %matlabbatch{1}.spm.stats.fmri_spec.global = 'None'; % Global Normalisation 349 | %matlabbatch{1}.spm.stats.fmri_spec.mthresh = 0.8; % Masking Threshold 350 | %matlabbatch{1}.spm.stats.fmri_spec.mask = {''}; % Explicit Mask 351 | %matlabbatch{1}.spm.stats.fmri_spec.cvi = 'AR(1)'; % Serial Correlations 352 | 353 | 354 | % keyboard %Used in bug-testing script 355 | spm_jobman('run',matlabbatch); 356 | 357 | end 358 | 359 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 360 | %% Estimate model 361 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 362 | if strfind(todo,'e') 363 | 364 | stats_directory=fullfile(D,'Stats\GLM'); 365 | %stats_directory=fullfile(D,'Stats\Parametric'); % change these dependent on what analysis you have done 366 | %stats_directory=fullfile(D,'Stats\Bayesian'); % NEEDS BAYESIAN ESTIMATION 367 | 368 | statsfile=fullfile(stats_directory,'SPM.mat'); 369 | 370 | load(fullfile(way,'estimate_spm12.mat')); 371 | %load(fullfile(way,'estimate_bayesian_spm12.mat')); % BAYESIAN ESTIMATION 372 | 373 | %What SPM.mat file to open and estimate 374 | matlabbatch{1}.spm.stats.fmri_est.spmmat={statsfile}; 375 | 376 | %%%%% Other Options 377 | %matlabbatch{1}.spm.stats.fmri_est.write_residuals=0; % Write Residuals: 0=No 378 | %matlabbatch{1}.spm.stats.fmri_est.method.Classical=1; % Method = classical (opposed to Bayesian) 379 | 380 | %%%%% Bayesian Options 381 | %matlabbatch{1}.spm.stats.fmri_est.method.Bayesian.space.volume.block_type = 'Slices'; 382 | %matlabbatch{1}.spm.stats.fmri_est.method.Bayesian.signal = 'UGL'; 383 | %matlabbatch{1}.spm.stats.fmri_est.method.Bayesian.ARP = 3; 384 | %matlabbatch{1}.spm.stats.fmri_est.method.Bayesian.noise.UGL = 1; 385 | %matlabbatch{1}.spm.stats.fmri_est.method.Bayesian.LogEv = 'No'; 386 | %matlabbatch{1}.spm.stats.fmri_est.method.Bayesian.anova.first = 'No'; 387 | %matlabbatch{1}.spm.stats.fmri_est.method.Bayesian.anova.second = 'Yes'; 388 | %matlabbatch{1}.spm.stats.fmri_est.method.Bayesian.gcon = ; Simple contrasts. name & convec 389 | 390 | % keyboard Used in bug-testing script 391 | spm_jobman('run',matlabbatch); 392 | end 393 | 394 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 395 | %% Contrast Manager 396 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 397 | if strfind(todo,'c') 398 | 399 | stats_directory=fullfile(D,'Stats\GLM'); 400 | statsfile=fullfile(stats_directory,'SPM.mat'); 401 | 402 | load(fullfile(way,'contrast_manager_spm12.mat')); 403 | 404 | %What SPM.mat file to open 405 | matlabbatch{1}.spm.stats.con.spmmat={statsfile}; 406 | 407 | % What contrasts to put in 408 | matlabbatch{1}.spm.stats.con.consess{1}.tcon.name = 'ME_Rest'; % t Contrast (f contrast = fcon) 409 | matlabbatch{1}.spm.stats.con.consess{1}.tcon.weights = [1 0 0 0]; 410 | matlabbatch{1}.spm.stats.con.consess{1}.tcon.sessrep = 'sess'; 411 | %Reproduce across sessions: 'none' dont replicate; 'sess' create per session; 'repl' replicate; 'both' replicate and create 412 | 413 | matlabbatch{1}.spm.stats.con.consess{2}.tcon.name = 'ME_0Back'; % t Contrast 414 | matlabbatch{1}.spm.stats.con.consess{2}.tcon.weights = [0 1 0 0]; 415 | matlabbatch{1}.spm.stats.con.consess{2}.tcon.sessrep = 'sess'; 416 | 417 | matlabbatch{1}.spm.stats.con.consess{3}.tcon.name = 'ME_2Back'; % t Contrast 418 | matlabbatch{1}.spm.stats.con.consess{3}.tcon.weights = [0 0 1 0]; 419 | matlabbatch{1}.spm.stats.con.consess{3}.tcon.sessrep = 'sess'; 420 | 421 | matlabbatch{1}.spm.stats.con.consess{4}.tcon.name = 'ME_4Back'; % t Contrast 422 | matlabbatch{1}.spm.stats.con.consess{4}.tcon.weights = [0 0 0 1]; 423 | matlabbatch{1}.spm.stats.con.consess{4}.tcon.sessrep = 'sess'; 424 | 425 | matlabbatch{1}.spm.stats.con.consess{5}.tcon.name = '0Back_gt_R'; % t Contrast 426 | matlabbatch{1}.spm.stats.con.consess{5}.tcon.weights = [-1 1 0 0]; 427 | matlabbatch{1}.spm.stats.con.consess{5}.tcon.sessrep = 'sess'; 428 | 429 | matlabbatch{1}.spm.stats.con.consess{6}.tcon.name = '2Back_gt_R'; % t Contrast 430 | matlabbatch{1}.spm.stats.con.consess{6}.tcon.weights = [-1 0 1 0]; 431 | matlabbatch{1}.spm.stats.con.consess{6}.tcon.sessrep = 'sess'; 432 | 433 | matlabbatch{1}.spm.stats.con.consess{7}.tcon.name = '4Back_gt_R'; % t Contrast 434 | matlabbatch{1}.spm.stats.con.consess{7}.tcon.weights = [-1 0 0 1]; 435 | matlabbatch{1}.spm.stats.con.consess{7}.tcon.sessrep = 'sess'; 436 | 437 | matlabbatch{1}.spm.stats.con.consess{8}.tcon.name = '2Back_gt_0Back'; % t Contrast 438 | matlabbatch{1}.spm.stats.con.consess{8}.tcon.weights = [0 -1 1 0]; 439 | matlabbatch{1}.spm.stats.con.consess{8}.tcon.sessrep = 'sess'; 440 | 441 | matlabbatch{1}.spm.stats.con.consess{9}.tcon.name = '4Back_gt_0Back'; % t Contrast 442 | matlabbatch{1}.spm.stats.con.consess{9}.tcon.weights = [0 -1 0 1]; 443 | matlabbatch{1}.spm.stats.con.consess{9}.tcon.sessrep = 'sess'; 444 | 445 | matlabbatch{1}.spm.stats.con.consess{10}.tcon.name = '0Back_gt_2Back'; % t Contrast 446 | matlabbatch{1}.spm.stats.con.consess{10}.tcon.weights = [0 1 -1 0]; 447 | matlabbatch{1}.spm.stats.con.consess{10}.tcon.sessrep = 'sess'; 448 | 449 | matlabbatch{1}.spm.stats.con.consess{11}.tcon.name = '0Back_gt_4Back'; % t Contrast 450 | matlabbatch{1}.spm.stats.con.consess{11}.tcon.weights = [0 1 0 -1]; 451 | matlabbatch{1}.spm.stats.con.consess{11}.tcon.sessrep = 'sess'; 452 | 453 | matlabbatch{1}.spm.stats.con.delete = 1; % delete existing contrasts (0=No, 1=Yes) 454 | 455 | % Contrast in terms of condition or regressor instead of columns in 456 | % design matrix. Allows creation of contrast automatically even if some 457 | % columns not always present (e.g. parametric modulations) 458 | %matlabbatch{1}.spm.stats.con.consess{3}.tconsess.name - ''; % T Contrast (cond/sess based) 459 | %matlabbatch{1}.spm.stats.con.consess{3}.tconsess.sessions = [1 2 3]; % Which sessions this contrast should be over 460 | %matlabbatch{1}.spm.stats.con.consess{3}.tconsess.coltype.colconds.conweight = []; 461 | %matlabbatch{1}.spm.stats.con.consess{3}.tconsess.coltype.colconds.colcond = []; 462 | %matlabbatch{1}.spm.stats.con.consess{3}.tconsess.coltype.colconds.colbf = []; 463 | %matlabbatch{1}.spm.stats.con.consess{3}.tconsess.coltype.colconds.colmod = []; 464 | %matlabbatch{1}.spm.stats.con.consess{3}.tconsess.coltype.colconds.colmodord = []; 465 | 466 | % keyboard Used in bug-testing script 467 | spm_jobman('run',matlabbatch); 468 | end 469 | 470 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 471 | %% Results Report 472 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 473 | if strfind(todo,'r') 474 | 475 | stats_directory=fullfile(D,'Stats\GLM'); 476 | statsfile=fullfile(stats_directory,'SPM.mat'); 477 | 478 | threshtype = 'FWE'; % Test type 479 | p_value = 0.0500; % P Value 480 | vox_extent = 0; % Number of voxels per cluster 481 | 482 | load(fullfile(way,'results_report_spm12.mat')); 483 | 484 | %What SPM.mat file to open 485 | matlabbatch{1}.spm.stats.results.spmmat={statsfile}; 486 | 487 | % Which contrast files to report 488 | matlabbatch{1}.spm.stats.results.conspec(1).titlestr = 'Session 1 0Back gt Rest'; 489 | matlabbatch{1}.spm.stats.results.conspec(1).contrasts = 13; 490 | matlabbatch{1}.spm.stats.results.conspec(1).threshdesc = threshtype; % Test type 491 | matlabbatch{1}.spm.stats.results.conspec(1).thresh = p_value; % P Value 492 | matlabbatch{1}.spm.stats.results.conspec(1).extent = vox_extent; % Number of voxels per cluster 493 | %matlabbatch{1}.spm.stats.results.conspec(1).conjunction = 1; 494 | %matlabbatch{1}.spm.stats.results.conspec(1).mask.none = 1; % No masking 495 | 496 | %matlabbatch{1}.spm.stats.results.units = 1; % 1=Volumetric 2D/3D; 497 | %matlabbatch{1}.spm.stats.results.export{1}.ps = 1; % Export results as postscript 498 | %Can also be exported as: Thresholded SPM, All Clusters (binary/n-ary), 499 | %eps, pdf, jpeg, png, tiff, Matlab figure, CSV file, Excel spreadsheet, 500 | %NIDM 501 | 502 | %keyboard % Used in bug-testing script 503 | spm_jobman('run',matlabbatch); 504 | 505 | matlabbatch{1}.spm.stats.results.conspec(1).titlestr = 'Session 2 0Back gt Rest'; 506 | matlabbatch{1}.spm.stats.results.conspec(1).contrasts = 14; 507 | matlabbatch{1}.spm.stats.results.conspec(1).threshdesc = threshtype; 508 | matlabbatch{1}.spm.stats.results.conspec(1).thresh = p_value; 509 | matlabbatch{1}.spm.stats.results.conspec(1).extent = vox_extent; 510 | 511 | spm_jobman('run',matlabbatch); 512 | 513 | matlabbatch{1}.spm.stats.results.conspec(1).titlestr = 'Session 3 0Back gt Rest'; 514 | matlabbatch{1}.spm.stats.results.conspec(1).contrasts = 15; 515 | matlabbatch{1}.spm.stats.results.conspec(1).threshdesc = threshtype; 516 | matlabbatch{1}.spm.stats.results.conspec(1).thresh = p_value; 517 | matlabbatch{1}.spm.stats.results.conspec(1).extent = vox_extent; 518 | 519 | spm_jobman('run',matlabbatch); 520 | 521 | matlabbatch{1}.spm.stats.results.conspec(1).titlestr = 'Session 1 2Back gt Rest'; 522 | matlabbatch{1}.spm.stats.results.conspec(1).contrasts = 16; 523 | matlabbatch{1}.spm.stats.results.conspec(1).threshdesc = threshtype; 524 | matlabbatch{1}.spm.stats.results.conspec(1).thresh = p_value; 525 | matlabbatch{1}.spm.stats.results.conspec(1).extent = vox_extent; 526 | 527 | spm_jobman('run',matlabbatch); 528 | 529 | matlabbatch{1}.spm.stats.results.conspec(1).titlestr = 'Session 2 2Back gt Rest'; 530 | matlabbatch{1}.spm.stats.results.conspec(1).contrasts = 17; 531 | matlabbatch{1}.spm.stats.results.conspec(1).threshdesc = threshtype; 532 | matlabbatch{1}.spm.stats.results.conspec(1).thresh = p_value; 533 | matlabbatch{1}.spm.stats.results.conspec(1).extent = vox_extent; 534 | 535 | spm_jobman('run',matlabbatch); 536 | 537 | matlabbatch{1}.spm.stats.results.conspec(1).titlestr = 'Session 3 2Back gt Rest'; 538 | matlabbatch{1}.spm.stats.results.conspec(1).contrasts = 18; 539 | matlabbatch{1}.spm.stats.results.conspec(1).threshdesc = threshtype; 540 | matlabbatch{1}.spm.stats.results.conspec(1).thresh = p_value; 541 | matlabbatch{1}.spm.stats.results.conspec(1).extent = vox_extent; 542 | 543 | spm_jobman('run',matlabbatch); 544 | 545 | matlabbatch{1}.spm.stats.results.conspec(1).titlestr = 'Session 1 4Back gt Rest'; 546 | matlabbatch{1}.spm.stats.results.conspec(1).contrasts = 19; 547 | matlabbatch{1}.spm.stats.results.conspec(1).threshdesc = threshtype; 548 | matlabbatch{1}.spm.stats.results.conspec(1).thresh = p_value; 549 | matlabbatch{1}.spm.stats.results.conspec(1).extent = vox_extent; 550 | 551 | spm_jobman('run',matlabbatch); 552 | 553 | matlabbatch{1}.spm.stats.results.conspec(1).titlestr = 'Session 2 4Back gt Rest'; 554 | matlabbatch{1}.spm.stats.results.conspec(1).contrasts = 20; 555 | matlabbatch{1}.spm.stats.results.conspec(1).threshdesc = threshtype; 556 | matlabbatch{1}.spm.stats.results.conspec(1).thresh = p_value; 557 | matlabbatch{1}.spm.stats.results.conspec(1).extent = vox_extent; 558 | 559 | spm_jobman('run',matlabbatch); 560 | 561 | matlabbatch{1}.spm.stats.results.conspec(1).titlestr = 'Session 3 4Back gt Rest'; 562 | matlabbatch{1}.spm.stats.results.conspec(1).contrasts = 21; 563 | matlabbatch{1}.spm.stats.results.conspec(1).threshdesc = threshtype; 564 | matlabbatch{1}.spm.stats.results.conspec(1).thresh = p_value; 565 | matlabbatch{1}.spm.stats.results.conspec(1).extent = vox_extent; 566 | 567 | spm_jobman('run',matlabbatch); 568 | 569 | matlabbatch{1}.spm.stats.results.conspec(1).titlestr = 'Session 1 2Back gt 0Back'; 570 | matlabbatch{1}.spm.stats.results.conspec(1).contrasts = 22; 571 | matlabbatch{1}.spm.stats.results.conspec(1).threshdesc = threshtype; 572 | matlabbatch{1}.spm.stats.results.conspec(1).thresh = p_value; 573 | matlabbatch{1}.spm.stats.results.conspec(1).extent = vox_extent; 574 | 575 | spm_jobman('run',matlabbatch); 576 | 577 | matlabbatch{1}.spm.stats.results.conspec(1).titlestr = 'Session 2 2Back gt 0Back'; 578 | matlabbatch{1}.spm.stats.results.conspec(1).contrasts = 23; 579 | matlabbatch{1}.spm.stats.results.conspec(1).threshdesc = threshtype; 580 | matlabbatch{1}.spm.stats.results.conspec(1).thresh = p_value; 581 | matlabbatch{1}.spm.stats.results.conspec(1).extent = vox_extent; 582 | 583 | spm_jobman('run',matlabbatch); 584 | 585 | matlabbatch{1}.spm.stats.results.conspec(1).titlestr = 'Session 3 2Back gt 0Back'; 586 | matlabbatch{1}.spm.stats.results.conspec(1).contrasts = 24; 587 | matlabbatch{1}.spm.stats.results.conspec(1).threshdesc = threshtype; 588 | matlabbatch{1}.spm.stats.results.conspec(1).thresh = p_value; 589 | matlabbatch{1}.spm.stats.results.conspec(1).extent = vox_extent; 590 | 591 | spm_jobman('run',matlabbatch); 592 | 593 | matlabbatch{1}.spm.stats.results.conspec(1).titlestr = 'Session 1 4Back gt 0Back'; 594 | matlabbatch{1}.spm.stats.results.conspec(1).contrasts = 25; 595 | matlabbatch{1}.spm.stats.results.conspec(1).threshdesc = threshtype; 596 | matlabbatch{1}.spm.stats.results.conspec(1).thresh = p_value; 597 | matlabbatch{1}.spm.stats.results.conspec(1).extent = vox_extent; 598 | 599 | spm_jobman('run',matlabbatch); 600 | 601 | matlabbatch{1}.spm.stats.results.conspec(1).titlestr = 'Session 2 4Back gt 0Back'; 602 | matlabbatch{1}.spm.stats.results.conspec(1).contrasts = 26; 603 | matlabbatch{1}.spm.stats.results.conspec(1).threshdesc = threshtype; 604 | matlabbatch{1}.spm.stats.results.conspec(1).thresh = p_value; 605 | matlabbatch{1}.spm.stats.results.conspec(1).extent = vox_extent; 606 | 607 | spm_jobman('run',matlabbatch); 608 | 609 | matlabbatch{1}.spm.stats.results.conspec(1).titlestr = 'Session 3 4Back gt 0Back'; 610 | matlabbatch{1}.spm.stats.results.conspec(1).contrasts = 27; 611 | matlabbatch{1}.spm.stats.results.conspec(1).threshdesc = threshtype; 612 | matlabbatch{1}.spm.stats.results.conspec(1).thresh = p_value; 613 | matlabbatch{1}.spm.stats.results.conspec(1).extent = vox_extent; 614 | 615 | spm_jobman('run',matlabbatch); 616 | 617 | 618 | end 619 | 620 | toc % stop clock timing how long analysis takes 621 | return 622 | 623 | -------------------------------------------------------------------------------- /multisubject_analysis.m: -------------------------------------------------------------------------------- 1 | function [mem] = multisubject_analysis(shift) 2 | % Updated Dec 2018 3 | % Based on script by Adam McNamara, edited by Philip Dean 4 | 5 | % ALL ANALYSIS SCRIPTS RUN FROM HERE 6 | % Runs all the specific programs for each subject in turn: 7 | % preprocess 8 | % firstlevel_analysis 9 | % including behavioural_data_onset_duration 10 | % secondlevel_analysis 11 | % 12 | % Can add any other analysis into here if wanted. 13 | 14 | % subject independent information such as study paths 15 | % the scripts assume this setup for your data. 16 | sh.studypath = 'E:\MRI\BECi_Study\Data'; 17 | sh.imagepath = 'E:\MRI\BECi_Study\Raw_Data'; 18 | sh.behavpath = 'E:\MRI\BECi_Study\Behavioural_Data'; 19 | % subj.path is the folder name for your participant 20 | % subj.log_sess1 is the file name for your behavioural logfile 21 | % subj.response_button is the response button used for the experiment (if counterbalanced) 22 | 23 | mypwd = pwd; 24 | addpath(mypwd); 25 | global ev 26 | ev = {}; 27 | 28 | %% subject-specific information such as logfile names and response buttons 29 | 30 | %for jj = 1:11; subj(jj).path = ['Subject_' num2str(jj)]; end; % this is one way of specifying subject path or could do the below for more specific/random subject names 31 | 32 | subj(1).path = 'Subject_1'; subj(1).log_sess1='P01_S1_Targ1_BECi_nBack_SCE.log'; subj(1).response_button = 1; % subj(1).log_sess2='P01_S2_Targ1_BECi_nBack_SCE_REDONE.log'; subj(1).log_sess3='PO1_S3_Targ1_BECi_nBack_SCE.log'; 33 | subj(2).path = 'Subject_2'; subj(2).log_sess1='P02_S1_Targ2_BECi_nBack_SCE.log'; subj(2).response_button = 2; % subj(2).log_sess2='P02_S2_Targ2_BECi_nBack_SCE_REDONE.log'; subj(2).log_sess3='PO2_S3_Targ2_BECi_nBack_SCE.log'; 34 | subj(3).path = 'Subject_3'; subj(3).log_sess1='P03_S1_Targ2_BECi_nBack_SCE.log'; subj(3).response_button = 2; % subj(3).log_sess2='P03_S2_Targ2_BECi_nBack_SCE.log'; subj(3).log_sess3='P03_S3_Targ2_BECi_nBack_SCE.log'; 35 | subj(4).path = 'Subject_4'; subj(4).log_sess1='P04_S1_Targ1_BECi_nBack_SCE.log'; subj(4).response_button = 1; % subj(4).log_sess2='P04_S2_Targ1_BECi_nBack_SCE.log'; subj(4).log_sess3='P04_S3_Targ1_BECi_nBack_SCE.log'; 36 | subj(5).path = 'Subject_5'; subj(5).log_sess1='P05_S1_Targ1_BECi_nBack_SCE.log'; subj(5).response_button = 1; % subj(5).log_sess2='P05_S2_Targ1_BECi_nBack_SCE.log'; subj(5).log_sess3='P05_S3_Targ1_BECi_nBack_SCE.log'; 37 | subj(6).path = 'Subject_6'; subj(6).log_sess1='P06_S1_Targ2_BECi_nBack_SCE.log'; subj(6).response_button = 2; % subj(6).log_sess2='P06_S2_Targ2_BECi_nBack_SCE.log'; subj(6).log_sess3='P06_S3_Targ2_BECi_nBack_SCE.log'; 38 | subj(7).path = 'Subject_7'; subj(7).log_sess1='P07_S1_Targ2_BECi_nBack_SCE.log'; subj(7).response_button = 2; % subj(7).log_sess2='P07_S2_Targ2_BECi_nBack_SCE.log'; subj(7).log_sess3='P07_S3_Targ2_BECi_nBack_SCE.log'; 39 | subj(8).path = 'Subject_8'; subj(8).log_sess1='P08_S1_Targ1_BECi_nBack_SCE.log'; subj(8).response_button = 1; % subj(8).log_sess2='P08_S2_Targ1_BECi_nBack_SCE.log'; subj(8).log_sess3='P08_S3_Targ1_BECi_nBack_SCE.log'; 40 | subj(9).path = 'Subject_9'; subj(9).log_sess1='P09_S1_Targ2_BECi_nBack_SCE.log'; subj(9).response_button = 2; % subj(9).log_sess2='P09_S2_Targ2_BECi_nBack_SCE.log'; subj(9).log_sess3='P09_S3_Targ2_BECi_nBack_SCE.log'; 41 | subj(10).path = 'Subject_10'; subj(10).log_sess1='P10_S1_Targ1_BECi_nBack_SCE.log'; subj(10).response_button = 1; % subj(10).log_sess2='P10_S2_Targ1_BECi_nBack_SCE.log'; subj(10).log_sess3='P10_S3_Targ1_BECi_nBack_SCE.log'; 42 | subj(11).path = 'Subject_11'; subj(11).log_sess1='P11_S1_Targ1_BECi_nBack_SCE.log'; subj(11).response_button = 1; % subj(11).log_sess2='P11_S2_Targ1_BECi_nBack_SCE.log'; subj(11).log_sess3='P11_S3_Targ1_BECi_nBack_SCE.log'; 43 | 44 | 45 | for i = 1:length(subj) 46 | 47 | spm('Defaults', 'FMRI'); % Reset SPM defaults for fMRI (not sure necessary - safety catch?) 48 | 49 | %first define directory name 50 | fprintf(subj(i).path); 51 | fprintf('\n'); 52 | 53 | %% Stage 1: do preprocessing ('drsbcnog') 54 | fprintf(' --- Preprocessing fMRI --- \n'); 55 | preprocess('drsbcnog', fullfile(sh.studypath,subj(i).path)); 56 | 57 | %% Stage 2: do first level analysis ('me') 58 | %fprintf(' --- First level analysis: GLM --- \n'); 59 | %firstlevel_analysis('mec', fullfile(sh.studypath,subj(i).path), sh, subj(i)); 60 | end; 61 | 62 | %% Stage 3: do second level analysis 63 | %fprintf(' --- Second level analysis: Paired-Test GLM & Parametric --- \n'); 64 | %secondlevel_analysis('o',sh.studypath); -------------------------------------------------------------------------------- /preprocess.m: -------------------------------------------------------------------------------- 1 | function preprocess(todo,D) 2 | % Dec 2018 Redone for spm12 3 | % Based on script by Adam McNamara, edited by Philip Dean 4 | 5 | % INITIAL PREPROCESSING: 6 | % Dicom transfer to get structural image (d: f*.nii & s*.nii) 7 | % [Slice timing if necessary (a: af*.nii)] 8 | % Realign and unwarp functional data (r: uf*.nii) 9 | % Segment structural data (s: c1*.nii; c2*.nii; c3*.nii; ms*.nii; y_s*.nii) 10 | % [Optional Skull-strip bias-corrected structural (ms*.nii) using imcalc] 11 | % Coregister invididual structural data to mean functional and apply to all functional data (c: headers changed) 12 | % Normalise functional data using deformation field (y_s*nii) (n: wuf*.nii) 13 | % Smooth normalised functional data (g: swuf*.nii) 14 | 15 | % INPUT ARGUMENTS: 16 | 17 | %%%%% 'todo' 18 | % if todo not given, then it defaults to 'drsbcnog' 19 | % d = dicom transfer 20 | % a = slice timing (af*.nii) 21 | % r = realignment 22 | % s = segment 23 | % b = Skull strip bias-corrected Brain using Imcalc 24 | % c = coregistration to structural 25 | % n = Normalise (functional) 26 | % o = Normalise Structural 27 | % g = Smoothing with Gaussian kernal 28 | 29 | % OTHER POSSIBLY USEFUL COMMANDS: 30 | % x = Delete uf*.img and wuf*.img to save disk space (only do if performed CheckReg to see if preprocessing OK) 31 | % p = print movement parameters to pdf 32 | % (NB these are already saved as .ps postscript files in format e.g. spm_2017Jan25.ps along with other preprocessing figures) 33 | 34 | %%%%% 'D' 35 | % This is the Directory, e.g. 'E:\MRI\BECi_Study\Data\Subject_01' 36 | 37 | % So could call script as: 38 | % preprocess('drsbcnog','E:\MRI\BECi_Study\Data\Subject_01') 39 | % or, if just want to do dicom transfer: 40 | % preprocess('d','E:\MRI\BECi_Study\Data\Subject_01') 41 | 42 | % Global Variables 43 | spm('Defaults', 'FMRI'); % Reset SPM defaults for fMRI (not sure necessary - safety catch?) 44 | global defaults; % Reset Global defaults (not sure why needed?) 45 | 46 | if ~exist('todo','var'); todo='drsbcnog'; end; % if nothing entered in "todo" bracket, then this is the default action 47 | 48 | way='E:\MRI\BECi_Study\scripts\batch_files'; % Path to the "jobs"/batch files needed 49 | 50 | TR = 3; % Bunched acquisition (2s acquire, 1s gap for EEG) 51 | nslices_fMRI = 25; % Number of slices 52 | sliceorder = []; % Left blank here, but can be used to specify slice order for slice time correction 53 | vxl_fmri = [3 3 3]; % fMRI resolution 3x3x3 with 1mm gap (3x3x4) 54 | vxl_str = [1 1 1]; % Structural resolution 55 | 56 | tic % start clock timing how long analysis takes 57 | 58 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 59 | %% Dicom transfer 60 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 61 | if strfind(todo,'d') 62 | % if folders for each import dont exist, create these folders 63 | if ~exist(fullfile(D,'sess1'),'dir'); cd(D); mkdir('sess1'); end; 64 | % if ~exist(fullfile(D,'sess2'),'dir'); cd(D); mkdir('sess2'); end; % add these if more than one session 65 | % if ~exist(fullfile(D,'sess3'),'dir'); cd(D); mkdir('sess3'); end; 66 | if ~exist(fullfile(D,'structural'),'dir'); cd(D); mkdir('structural'); end; 67 | 68 | % use num_scans to get data to import (see nums_scans function below) 69 | [T]=num_scans(D); 70 | 71 | % import fMRI and structural 72 | for tt=1:length(T) 73 | load(fullfile(way,'dicom_spm12.mat')); 74 | if length(T(tt).files) > 123; 75 | [cr,ap]=fileparts(D); 76 | for ii=1:size(T(tt).files,2); 77 | matlabbatch{1}.spm.util.import.dicom.data{ii}=fullfile(fileparts(fileparts(D)),'Raw_Data',ap, T(tt).files{ii});%put the scans in 78 | end; 79 | fprintf('\n Number of Volumes = %d\n',size(matlabbatch{1}.spm.util.import.dicom.data,1)); 80 | matlabbatch{1}.spm.util.import.dicom.outdir{1}=fullfile(D,T(tt).scantype); 81 | % keyboard Used in bug-testing script 82 | spm_jobman('run',matlabbatch); 83 | end; 84 | end; 85 | 86 | end; 87 | 88 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 89 | %% Slice-timing correction NOT USED IN THIS ANALYSIS 90 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 91 | if strfind(todo,'a') 92 | 93 | load(fullfile(way,'slice_timing_spm12.mat')); 94 | 95 | matlabbatch{1}.spm.temporal.st.nslices = nslices_fMRI; 96 | matlabbatch{1}.spm.temporal.st.tr = TR; 97 | matlabbatch{1}.spm.temporal.st.ta = TR - (TR/nslices_fMRI); 98 | matlabbatch{1}.spm.temporal.st.so = [1:2:n_slices_fMRI 2:2:nslices_fMRI]; % interleaved bottom up 99 | matlabbatch{1}.spm.temporal.st.refslice = 1; %Reference slice is first slice 100 | 101 | P=cellstr(spm_select('FPList', directory,'^f.*\.nii$')); 102 | 103 | for ii=1:size(P, 1); 104 | matlabbatch{1}.spm.temporal.st.scans{ii}=P{ii};%put the scans in 105 | end; 106 | 107 | fprintf('\nTR = %d',matlabbatch{1}.spm.temporal.st.tr); 108 | fprintf('\nnslices = %d',matlabbatch{1}.spm.temporal.st.nslices); 109 | 110 | % keyboard %Used in bug-testing script 111 | spm_jobman('run',matlabbatch); 112 | 113 | end; 114 | 115 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 116 | %% Realignment: Realign & Unwarp 117 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 118 | if strfind(todo,'r') 119 | 120 | load(fullfile(way,'realign_unwarp_spm12.mat')); % change this to e.g. "realign_unwarp_2sess_spm12.mat" if more than one session 121 | 122 | for ss=1:3; %number of sessions 123 | directory=fullfile(D,['sess' num2str(ss)]); 124 | 125 | P=cellstr(spm_select('FPList', directory,'^f.*\.nii$')); 126 | 127 | for ii=1:size(P, 1); 128 | matlabbatch{1}.spm.spatial.realignunwarp.data(ss).scans{ii} = P{ii}; 129 | end 130 | 131 | clear P; 132 | end; 133 | % keyboard %Used in bug-testing script 134 | spm_jobman('run',matlabbatch); 135 | 136 | end; 137 | 138 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 139 | %% Segment 140 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 141 | if strfind(todo,'s') 142 | 143 | load(fullfile(way,'segment_biascorrected_spm12.mat')); 144 | struct_directory=fullfile(D,'structural'); 145 | 146 | matlabbatch{1}.spm.spatial.preproc.channel.vols = cellstr(spm_select('FPList', struct_directory,'^s.*\.nii$')); 147 | 148 | % matlabbatch{1}.spm.spatial.preproc.channel.write = [0 1]; Save Bias Corrected Image 149 | % matlabbatch{1}.spm.spatial.preproc.warp.write = [0 1]; Forward Deformation 150 | % keyboard %Used in bug-testing script 151 | spm_jobman('run',matlabbatch); 152 | 153 | end; 154 | 155 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 156 | %% Skull Strip ImCalc 157 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 158 | if strfind(todo,'b') 159 | 160 | load(fullfile(way,'imcalc_brainstrip_spm12.mat')); 161 | struct_directory=fullfile(D,'structural'); 162 | 163 | matlabbatch{1}.spm.util.imcalc.input(1) = cellstr(spm_select('FPList', struct_directory,'^c1s.*\.nii$')); % i1: GM Segment 164 | matlabbatch{1}.spm.util.imcalc.input(2) = cellstr(spm_select('FPList', struct_directory,'^c2s.*\.nii$')); % i2: WM Segment 165 | matlabbatch{1}.spm.util.imcalc.input(3) = cellstr(spm_select('FPList', struct_directory,'^c3s.*\.nii$')); % i3: CSF Segment 166 | matlabbatch{1}.spm.util.imcalc.input(4) = cellstr(spm_select('FPList', struct_directory,'^ms.*\.nii$')); % i4: Bias Corrected Image 167 | 168 | matlabbatch{1}.spm.util.imcalc.outdir = {struct_directory}; % Output directory 169 | % keyboard %Used in bug-testing script 170 | spm_jobman('run',matlabbatch); 171 | 172 | end; 173 | 174 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 175 | %% Coregistration: Estimate 176 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 177 | if strfind(todo,'c') 178 | 179 | load(fullfile(way,'coregister_est_spm12.mat')); 180 | 181 | struct_directory=fullfile(D,'structural'); 182 | matlabbatch{1}.spm.spatial.coreg.estimate.ref = cellstr(spm_select('FPList', struct_directory,'^Brain.*\.nii$')); 183 | 184 | directory=fullfile(D,'sess1'); 185 | matlabbatch{1}.spm.spatial.coreg.estimate.source = cellstr(spm_select('FPList', directory,'^meanuf.*\.nii$')); 186 | 187 | P=cellstr(spm_select('FPList', directory,'^uf.*\.nii$')); % input session 1 scans 188 | 189 | % directory=fullfile(D,'sess2'); % add these if more than one session 190 | % P=[P;[cellstr(spm_select('FPList', directory,'^uf.*\.nii$'))]]; % add session 2 scans 191 | % directory=fullfile(D,'sess3'); 192 | % P=[P;[cellstr(spm_select('FPList', directory,'^uf.*\.nii$'))]]; % add session 3 scans 193 | 194 | for ii=1:size(P, 1); 195 | matlabbatch{1}.spm.spatial.coreg.estimate.other{ii} = P{ii}; 196 | end 197 | 198 | clear P; 199 | % keyboard %Used in bug-testing script 200 | spm_jobman('run',matlabbatch); 201 | 202 | end; 203 | 204 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 205 | %% Normalization: Write 206 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 207 | if strfind(todo,'n') 208 | 209 | load(fullfile(way,'normalise_write_333_spm12.mat')); % Change batch file if resolution not 3x3x3 or change in script below 210 | 211 | % matlabbatch{1}.spm.spatial.normalise.write.woptions.vox = [3 3 3] Change to [1 1 1] for structural 212 | 213 | struct_directory=fullfile(D,'structural'); 214 | matlabbatch{1}.spm.spatial.normalise.write.subj.def = cellstr(spm_select('FPList', struct_directory,'^y_s.*\.nii$')); 215 | 216 | directory=fullfile(D,'sess1'); 217 | P=cellstr(spm_select('FPList', directory,'^uf.*\.nii$')); % input session 1 scans 218 | 219 | % directory=fullfile(D,'sess2'); % add these if more than one session 220 | % P=[P;[cellstr(spm_select('FPList', directory,'^uf.*\.nii$'))]]; % add session 2 scans 221 | % directory=fullfile(D,'sess3'); 222 | % P=[P;[cellstr(spm_select('FPList', directory,'^uf.*\.nii$'))]]; % add session 3 scans 223 | 224 | 225 | for ii=1:size(P, 1); 226 | matlabbatch{1}.spm.spatial.normalise.write.subj.resample{ii} = P{ii}; 227 | end 228 | 229 | clear P; 230 | % keyboard %Used in bug-testing script 231 | spm_jobman('run',matlabbatch); 232 | 233 | end; 234 | 235 | 236 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 237 | %% Normalization (structural): Write 238 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 239 | if strfind(todo,'o') 240 | 241 | load(fullfile(way,'normalise_write_111_spm12.mat')); % Change batch file if resolution not 3x3x3 or change in script below 242 | 243 | % matlabbatch{1}.spm.spatial.normalise.write.woptions.vox = [1 1 1] Change to [3 3 3] for functional 244 | 245 | struct_directory=fullfile(D,'structural'); 246 | matlabbatch{1}.spm.spatial.normalise.write.subj.def = cellstr(spm_select('FPList', struct_directory,'^y_s.*\.nii$')); 247 | matlabbatch{1}.spm.spatial.normalise.write.subj.resample = cellstr(spm_select('FPList', struct_directory,'^Brain.*\.nii$')); 248 | % keyboard Used in bug-testing script 249 | spm_jobman('run',matlabbatch); 250 | 251 | end; 252 | 253 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 254 | %% Smoothing 255 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 256 | if strfind(todo,'g') 257 | 258 | load(fullfile(way,'smooth_spm12.mat')); 259 | 260 | % Other possible things to change: 261 | % matlabbatch{1}.spm.spatial.smooth.fhwm = [8 8 8] % Smoothing level 262 | % matlabbatch{1}.spm.spatial.smooth.im = 0 % Implicit mask (0 = no, 1 = yes) 263 | 264 | 265 | directory=fullfile(D,'sess1'); % add these if more than one session 266 | P=cellstr(spm_select('FPList', directory,'^wuf.*\.nii$')); % input session 1 scans 267 | 268 | % directory=fullfile(D,'sess2'); 269 | % P=[P;[cellstr(spm_select('FPList', directory,'^wuf.*\.nii$'))]]; % add session 2 scans 270 | % directory=fullfile(D,'sess3'); 271 | % P=[P;[cellstr(spm_select('FPList', directory,'^wuf.*\.nii$'))]]; % add session 3 scans 272 | 273 | 274 | for ii=1:size(P, 1); 275 | matlabbatch{1}.spm.spatial.smooth.data{ii} = P{ii}; 276 | end 277 | 278 | clear P; 279 | % keyboard %Used in bug-testing script 280 | spm_jobman('run',matlabbatch); 281 | 282 | end; 283 | 284 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 285 | %% Delete uf*.im and wuf*.img files to save space 286 | % WARNING: DELETES FILES PERMANENTLY - TAKE CARE! 287 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 288 | if strfind(todo,'x') 289 | 290 | % Preprocessing files: 291 | % f*.nii KEEP 292 | % uf*.nii 293 | % rp_f*.txt KEEP 294 | % meanuf*.nii KEEP 295 | % wuf*.nii 296 | % swuf*.nii KEEP 297 | 298 | here = pwd; %remember where I am before I start to work 299 | 300 | directory_sess1=fullfile(D,'sess1'); 301 | %directory_sess2=fullfile(D,'sess2'); 302 | %directory_sess3=fullfile(D,'sess3'); 303 | 304 | % keyboard %Used in bug-testing script 305 | 306 | cd(directory_sess1); 307 | delete ('uf*.*') % to save diskspace (take care!) 308 | delete ('wuf*.*') % to save diskspace (take care!) 309 | 310 | % cd(directory_sess2); 311 | % delete ('uf*.*') % to save diskspace (take care!) 312 | % delete ('wuf*.*') % to save diskspace (take care!) 313 | % cd(directory_sess3); 314 | % delete ('uf*.*') % to save diskspace (take care!) 315 | % delete ('wuf*.*') % to save diskspace (take care!) 316 | 317 | cd (here); % go back to where I was 318 | 319 | end; 320 | 321 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 322 | %% Graph and Print Movement Regressors to PDF file 323 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 324 | if strfind(todo,'p') 325 | 326 | here = pwd; %remember where I am before I start to work 327 | 328 | directory_sess1=fullfile(D,'sess1'); 329 | %directory_sess2=fullfile(D,'sess2'); 330 | %directory_sess3=fullfile(D,'sess3'); 331 | 332 | [path,sj] = fileparts(D); 333 | 334 | movesess1=dlmread(spm_select('FPList', directory_sess1, '^rp_f.*\.txt$')); 335 | % movesess2=dlmread(spm_select('FPList', directory_sess2, '^rp_f.*\.txt$')); 336 | % movesess3=dlmread(spm_select('FPList', directory_sess3, '^rp_f.*\.txt$')); 337 | 338 | scrsz = get(groot,'ScreenSize'); 339 | figure('OuterPosition',[1 1 scrsz(3)/2 scrsz(4)]); 340 | 341 | trans1 = subplot(2,1,1); 342 | plot(movesess1(:,1), 'b'); 343 | hold on; 344 | plot(movesess1(:,2), 'g'); 345 | plot(movesess1(:,3), 'r'); 346 | title([sj ' Translation']); 347 | xlabel ('image sess1'); 348 | ylabel ('mm'); 349 | legend ('x', 'y', 'z', 'Location', 'northeastoutside'); 350 | 351 | % trans2 = subplot(3,2,3); 352 | % plot(movesess2(:,1), 'b'); 353 | % hold on; 354 | % plot(movesess2(:,2), 'g'); 355 | % plot(movesess2(:,3), 'r'); 356 | % title([sj ' Translation']); 357 | % xlabel ('image sess2'); 358 | % ylabel ('mm'); 359 | % legend ('x', 'y', 'z', 'Location', 'northeastoutside'); 360 | % trans3 = subplot(3,2,5); 361 | % plot(movesess3(:,1), 'b'); 362 | % hold on; 363 | % plot(movesess3(:,2), 'g'); 364 | % plot(movesess3(:,3), 'r'); 365 | % title([sj ' Translation']); 366 | % xlabel ('image sess3'); 367 | % ylabel ('mm'); 368 | % legend ('x', 'y', 'z', 'Location', 'northeastoutside'); 369 | 370 | rot1 = subplot(2,1,2); 371 | plot(movesess1(:,4), 'b'); 372 | hold on; 373 | plot(movesess1(:,5), 'g'); 374 | plot(movesess1(:,6), 'r'); 375 | title([sj ' Rotation']); 376 | xlabel ('image sess1'); 377 | ylabel ('degrees'); 378 | legend ('pitch', 'roll', 'yaw', 'Location', 'northeastoutside'); 379 | 380 | % rot2 = subplot(3,2,4); 381 | % plot(movesess2(:,4), 'b'); 382 | % hold on; 383 | % plot(movesess2(:,5), 'g'); 384 | % plot(movesess2(:,6), 'r'); 385 | % title([sj ' Rotation']); 386 | % xlabel ('image sess2'); 387 | % ylabel ('degrees'); 388 | % legend ('pitch', 'roll', 'yaw', 'Location', 'northeastoutside'); 389 | % rot3 = subplot(3,2,6); 390 | % plot(movesess3(:,4), 'b'); 391 | % hold on; 392 | % plot(movesess3(:,5), 'g'); 393 | % plot(movesess3(:,6), 'r'); 394 | % title([sj ' Rotation']); 395 | % xlabel ('image sess3'); 396 | % ylabel ('degrees'); 397 | % legend ('pitch', 'roll', 'yaw', 'Location', 'northeastoutside'); 398 | 399 | % maxmin_mm_values = [max(movesess1(:,1)), min(movesess1(:,1)), max(movesess1(:,2)), min(movesess1(:,2)), max(movesess1(:,3)), min(movesess1(:,3)); 400 | % max(movesess2(:,1)), min(movesess2(:,1)), max(movesess2(:,2)), min(movesess2(:,2)), max(movesess2(:,3)), min(movesess2(:,3)); 401 | % max(movesess3(:,1)), min(movesess3(:,1)), max(movesess3(:,2)), min(movesess3(:,2)), max(movesess3(:,3)), min(movesess3(:,3))]; 402 | 403 | maxmin_mm_values = [max(movesess1(:,1)), min(movesess1(:,1)), max(movesess1(:,2)), min(movesess1(:,2)), max(movesess1(:,3)), min(movesess1(:,3))]; 404 | 405 | 406 | cd (D); 407 | 408 | print([sj '_Head_Movement'],'-dpdf','-fillpage'); 409 | csvwrite([sj '_Head_Movement_MaxMin.csv'], maxmin_mm_values); 410 | 411 | cd (here); % go back to where I was 412 | 413 | end; 414 | 415 | toc % stop clock timing how long analysis takes 416 | return 417 | 418 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 419 | %% OTHER FUNCTIONS USED BY SCRIPT ABOVE 420 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 421 | 422 | %%%%%%%%%%%%%%%%%%%%%%%%%% 423 | function [T]=num_scans(D) 424 | % For DICOM Import 425 | % Returns most likely sorting procedure for your sessions 426 | % Looks into Raw Data, and classifies what data you have dependent on the number of scans in it 427 | % Looks in more than one folder if necessary (multi-session, 1 folder only protocol below) 428 | 429 | % In this case: 430 | % Scan Number: 3 = Localiser 431 | % Scan Number: 176 = structural 432 | % Scan Number: >176 = fMRI Data (sess1) 433 | 434 | % These labels also used to create folder in Dicom Import as needed 435 | % Change dependent on your setup 436 | 437 | cd(D); 438 | [cr,ap]=fileparts(pwd); 439 | 440 | %%%%%% Look for Raw Data 441 | d=dir(fullfile('..\..\Raw_Data',ap)); %This assumes you have a setup as described in the "multisubject_analysis" file 442 | 443 | scan_mem_d=0; 444 | c_d=0; 445 | 446 | for jj=1:20;T(jj).files={};end; 447 | 448 | for ss = 3:length(d); 449 | if strcmp(d(ss).name(end-3:end),'.IMA'); 450 | f=find(double(d(ss).name) == 46); 451 | scan_d=str2num(d(ss).name(f(3)+1:f(4)-1)); 452 | if scan_mem_d ~= scan_d; c_d=1; scan_mem_d=scan_d; else; c_d= c_d+1; end; 453 | T(scan_d).files{c_d}=d(ss).name; 454 | end 455 | end; 456 | 457 | c_d=1; 458 | for jj=1:length(T); 459 | if ~isempty(T(jj).files); 460 | t(c_d)=T(jj); c_d=c_d+1; 461 | end; 462 | end; 463 | 464 | T=t; 465 | c_d=1; 466 | for jj=1:length(T); 467 | if length(T(jj).files) == 3; T(jj).scantype='localizer'; end; 468 | if length(T(jj).files) == 176; T(jj).scantype='structural'; end; 469 | if length(T(jj).files) > 176; T(jj).scantype=['sess' num2str(c_d)]; c_d=c_d+1; end; 470 | end -------------------------------------------------------------------------------- /secondlevel_analysis.m: -------------------------------------------------------------------------------- 1 | function secondlevel_analysis(todo,D) 2 | % Dec 2018 redone for spm12 3 | % Based on script by Adam McNamara, edited by Philip Dean 4 | 5 | % MAKE AND ESTIMATE SECOND LEVEL MODEL 6 | % Make model using first-level contrast images 7 | % Estimate model to create SPM file for second level analysis 8 | % Create second level contrasts 9 | 10 | % INPUT ARGUMENTS: 11 | 12 | % 'todo' 13 | % o = make one-sample t-test 14 | % t = make two-sample t-test %not done yet 15 | % p = make paired sample t-test 16 | % f = make Factorial model 17 | 18 | % 'D' 19 | % This is the Directory, e.g. 'E:\MRI\BECi_Study\Data' 20 | 21 | % So could call script as: 22 | % secondlevel_analysis('o','E:\MRI\BECi_Study\Data') 23 | 24 | 25 | %% Global Variables 26 | spm('Defaults', 'FMRI'); % Reset SPM defaults for fMRI (not sure necessary - safety catch?) 27 | global defaults; % Reset Global defaults (not sure why needed?) 28 | 29 | % Groups to be analysed 30 | group(1).subj=[1 2 3 4 5 6 7 8 9 10 11];group(1).name='All_11SJ'; 31 | %group(2).subj=[1 2 3 4 5 7 8 9 10 11];group(2).name='10SJ_No6'; 32 | 33 | 34 | % Analysis to be looked at 35 | analysis_type={'GLM' 'Parametric' 'Bayesian'}; 36 | 37 | way='E:\MRI\BECi_Study\scripts\batch_files'; % Path to the "jobs"/batch files needed 38 | 39 | % Contrast and Subject "precursors" 40 | contrast_begin = 'con_00'; %this is added to with 01; 02.....10; 11 in script 41 | subj_begin = 'Subject_'; % this is the folder name for your subjects and is added to with 01;..10 etc in script 42 | 43 | % if folder for 2nd level within groups stats doesnt exist, create the folder 44 | if ~exist(fullfile(D,'Second_Level_Stats\Within_Groups'),'dir'); mkdir(fullfile(D,'Second_Level_Stats\Within_Groups')); end; 45 | withingroups_stats_directory = fullfile(D,'Second_Level_Stats\Within_Groups'); 46 | 47 | % if folder for 2nd level between groups stats doesnt exist, create the folder 48 | %if ~exist(fullfile(D,'Second_Level_Stats\Between_Groups'),'dir'); mkdir(fullfile(D,'Second_Level_Stats\Between_Groups')); end; 49 | %betweengroups_stats_directory = fullfile(D,'Second_Level_Stats\Between_Groups'); 50 | 51 | tic 52 | 53 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 54 | %% Make model: 2nd level One-sample t-test 55 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 56 | if strfind(todo,'o') 57 | 58 | if ~exist(fullfile(withingroups_stats_directory,'OneSampleTTest'),'dir'); mkdir(fullfile(withingroups_stats_directory,'OneSampleTTest')); end; 59 | onesampleTtest_directory = fullfile(withingroups_stats_directory,'OneSampleTTest'); 60 | 61 | for aa = 1%:length(analysis_type) %change it if want just GLM, just Parametric, Just Bayesian etc 62 | 63 | template_SPM = load(fullfile(D,'Subject_01\Stats', analysis_type{aa}, 'SPM.mat')); 64 | contrast_num = length(template_SPM.SPM.xCon); 65 | for nn = 1:length(template_SPM.SPM.xCon) 66 | contrast_name{nn} = template_SPM.SPM.xCon(nn).name; 67 | contrast_name{nn}(contrast_name{nn}==' ') = '_'; 68 | contrast_name{nn}(contrast_name{nn}=='-') = ''; 69 | end; 70 | 71 | if ~exist(fullfile(onesampleTtest_directory,analysis_type{aa}),'dir'); 72 | mkdir(fullfile(onesampleTtest_directory,analysis_type{aa})); %Make GLM/Parametric etc directory within onesamplettest 73 | end 74 | 75 | for gg=1:length(group) 76 | 77 | if ~exist(fullfile(onesampleTtest_directory,analysis_type{aa}, group(gg).name),'dir'); 78 | mkdir(fullfile(onesampleTtest_directory,analysis_type{aa}, group(gg).name)); %Make directory for each set of subjects (e.g. 'All_11SJ') 79 | end; 80 | 81 | for cc=1:contrast_num 82 | 83 | if ~exist(fullfile(onesampleTtest_directory,analysis_type{aa}, group(gg).name, contrast_name{cc}),'dir'); 84 | mkdir(fullfile(onesampleTtest_directory,analysis_type{aa}, group(gg).name, contrast_name{cc})); 85 | end; 86 | 87 | load(fullfile(way,'second_level_onesampleT_spm12.mat')); 88 | 89 | output_directory = fullfile(onesampleTtest_directory,analysis_type{aa}, group(gg).name, contrast_name{cc}); 90 | 91 | matlabbatch{1}.spm.stats.factorial_design.dir = {output_directory}; 92 | 93 | for ss=1:length(group(gg).subj) 94 | 95 | contrast_end=['0' num2str(cc)]; if cc > 9; contrast_end=contrast_end(2:end); end; 96 | subj_end = ['0' num2str(group(gg).subj(ss))]; if length(subj_end) > 2; subj_end=subj_end(2:end); end; 97 | 98 | insert_contrast = [contrast_begin contrast_end '.nii']; 99 | insert_subj = [subj_begin subj_end]; 100 | 101 | subject_directory = fullfile(D, insert_subj, 'Stats', analysis_type{aa}); 102 | 103 | P=cellstr(spm_select('FPList', subject_directory, insert_contrast)); 104 | 105 | matlabbatch{1}.spm.stats.factorial_design.des.t1.scans{ss} = P{1}; 106 | 107 | clear P; 108 | 109 | end; %ss (inputting each subjects contrast) 110 | 111 | %Other Possible Inputs 112 | %matlabbatch{1}.spm.stats.factorial_design.cov.c; %Covariate vector 113 | %matlabbatch{1}.spm.stats.factorial_design.cov.cname; %Covariate name 114 | %matlabbatch{1}.spm.stats.factorial_design.cov.iCFi; %Covariate interactions (default = none) 115 | %matlabbatch{1}.spm.stats.factorial_design.cov.iCC; %Covariate centering (default = overall mean) 116 | %matlabbatch{1}.spm.stats.factorial_design.multi_cov.files; %Multiple covariate files 117 | %matlabbatch{1}.spm.stats.factorial_design.multi_cov.iCFI; %Multiple covariate interactions 118 | %matlabbatch{1}.spm.stats.factorial_design.multi_cov.iCC; %Multiple covariate centering 119 | 120 | %matlabbatch{1}.spm.stats.factorial_design.masking.tm.tm_none = 1; %Threshold masking (default = none) 121 | %matlabbatch{1}.spm.stats.factorial_design.masking.im = 1; %Implicit mask (default = yes [1]) 122 | %matlabbatch{1}.spm.stats.factorial_design.masking.em = {}; %Explicit mask 123 | 124 | %matlabbatch{1}.spm.stats.factorial_design.globalc.g_omit = 1; %Global calculation (default = omit; used for PET) 125 | %matlabbatch{1}.spm.stats.factorial_design.globalm.gmsca.gmsca_no = 1; %Global normalisation (default = no grand mean scaling; used for PET) 126 | %matlabbatch{1}.spm.stats.factorial_design.globalm.glonorm = 1; %Global normalisation (default = none; used for PET) 127 | 128 | 129 | %keyboard %Used in bug-testing script 130 | 131 | spm_jobman('run',matlabbatch); 132 | 133 | clear matlabbatch; 134 | 135 | load(fullfile(way,'estimate_spm12.mat')); 136 | stats_directory=fullfile(onesampleTtest_directory, analysis_type{aa}, group(gg).name, contrast_name{cc}); 137 | statsfile=fullfile(stats_directory,'SPM.mat'); 138 | matlabbatch{1}.spm.stats.fmri_est.spmmat={statsfile}; 139 | 140 | spm_jobman('run',matlabbatch); 141 | 142 | clear matlabbatch; 143 | 144 | load(fullfile(way,'contrast_manager_spm12.mat')); 145 | 146 | stats_directory=fullfile(onesampleTtest_directory, analysis_type{aa}, group(gg).name, contrast_name{cc}); 147 | statsfile=fullfile(stats_directory,'SPM.mat'); 148 | matlabbatch{1}.spm.stats.con.spmmat={statsfile}; 149 | 150 | matlabbatch{1}.spm.stats.con.consess{1}.tcon.name = 'Main_Effect'; % t Contrast (f contrast = fcon) 151 | matlabbatch{1}.spm.stats.con.consess{1}.tcon.weights = [1]; 152 | 153 | matlabbatch{1}.spm.stats.con.consess{2}.tcon.name = 'Main_Effect_Minus'; % t Contrast (f contrast = fcon) 154 | matlabbatch{1}.spm.stats.con.consess{2}.tcon.weights = [-1]; 155 | 156 | spm_jobman('run',matlabbatch); 157 | 158 | end; %cc (inputting each contrast (e.g. con_0001.img)) 159 | 160 | end; %gg (inputting each group type (e.g. ALL_11SJ)) 161 | 162 | end; %aa (inputting each analysis type (e.g. GLM)) 163 | 164 | end; %end 'o' one sample t-test 165 | 166 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 167 | %% Make model: 2nd level paired-sample t-test 168 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 169 | if strfind(todo,'p') 170 | 171 | if ~exist(fullfile(withingroups_stats_directory,'PairedTTest'),'dir'); mkdir(fullfile(withingroups_stats_directory,'PairedTTest')); end; 172 | pairsampleTtest_directory = fullfile(withingroups_stats_directory,'PairedTTest'); 173 | 174 | for aa = 1%:length(analysis_type) %change it if want just GLM, just Parametric, Just Bayesian etc 175 | 176 | template_SPM = load(fullfile(D,'Subject_01\Stats', analysis_type{aa}, 'SPM.mat')); 177 | contrast_num = length(template_SPM.SPM.xCon); 178 | for nn = 1:length(template_SPM.SPM.xCon) 179 | contrast_name{nn} = template_SPM.SPM.xCon(nn).name; 180 | contrast_name{nn}(contrast_name{nn}==' ') = '_'; 181 | contrast_name{nn}(contrast_name{nn}=='-') = ''; 182 | end; 183 | 184 | if ~exist(fullfile(pairsampleTtest_directory,analysis_type{aa}),'dir'); 185 | mkdir(fullfile(pairsampleTtest_directory,analysis_type{aa})); %Make GLM/Parametric etc directory within twosamplettest 186 | end 187 | 188 | if contrast_num > 6 189 | pairs_array = [1 3; 2 4; 7 9; 8 10]; 190 | pairs_name = {'PreVsPost_TaskgtRest' 'PreVsPost_RestgtTask' 'PreVsPost_ME_Left' 'PreVsPost_ME_Right'}; 191 | else 192 | pairs_array = [1 3; 2 4]; 193 | pairs_name = {'PreVsPost_TaskgtRest' 'PreVsPost_RestgtTask'}; 194 | end 195 | 196 | 197 | for gg=1%:length(group) 198 | 199 | if ~exist(fullfile(pairsampleTtest_directory,analysis_type{aa}, group(gg).name),'dir'); 200 | mkdir(fullfile(pairsampleTtest_directory,analysis_type{aa}, group(gg).name)); %Make directory for each set of subjects (e.g. 'Control') 201 | end; 202 | 203 | for cc=4:size(pairs_array,1) 204 | if ~exist(fullfile(pairsampleTtest_directory,analysis_type{aa}, group(gg).name, pairs_name{cc}),'dir'); 205 | mkdir(fullfile(pairsampleTtest_directory,analysis_type{aa}, group(gg).name, pairs_name{cc})); %Make directory for each paired t-test (e.g. Pre vs post task gt rest_ 206 | end; 207 | 208 | load(fullfile(way,'second_level_pairedT_spm12')); 209 | 210 | output_directory = fullfile(pairsampleTtest_directory,analysis_type{aa}, group(gg).name, pairs_name{cc}); 211 | 212 | matlabbatch{1}.spm.stats.factorial_design.dir = {output_directory}; 213 | 214 | first_contrast_pair = ['0' num2str(pairs_array(cc,1))]; if pairs_array(cc,1) > 9; first_contrast_pair = first_contrast_pair(2:end); end; 215 | second_contrast_pair = ['0' num2str(pairs_array(cc,2))]; if pairs_array(cc,2) > 9; second_contrast_pair = second_contrast_pair(2:end); end; 216 | 217 | for ss=1:length(group(gg).subj) 218 | 219 | insert_contrast1 = [contrast_begin first_contrast_pair '.nii']; 220 | insert_contrast2 = [contrast_begin second_contrast_pair '.nii']; 221 | 222 | insert_subj = [subj(group(gg).subj(ss)).path]; 223 | 224 | subject_directory = fullfile(D, insert_subj, 'Stats', analysis_type{aa}); 225 | 226 | P=cellstr(spm_select('FPList', subject_directory, insert_contrast1)); 227 | matlabbatch{1}.spm.stats.factorial_design.des.pt.pair(ss).scans{1,:} = P{1}; % new paired one 228 | clear P; 229 | 230 | P=cellstr(spm_select('FPList', subject_directory, insert_contrast2)); 231 | matlabbatch{1}.spm.stats.factorial_design.des.pt.pair(ss).scans{2,:} = P{1}; % new paired one 232 | clear P; 233 | 234 | end; %ss (inputting each subjects contrast) 235 | 236 | %Other Possible Inputs 237 | %matlabbatch{1}.spm.stats.factorial_design.cov.c; %Covariate vector 238 | %matlabbatch{1}.spm.stats.factorial_design.cov.cname; %Covariate name 239 | %matlabbatch{1}.spm.stats.factorial_design.cov.iCFi; %Covariate interactions (default = none) 240 | %matlabbatch{1}.spm.stats.factorial_design.cov.iCC; %Covariate centering (default = overall mean) 241 | %matlabbatch{1}.spm.stats.factorial_design.multi_cov.files; %Multiple covariate files 242 | %matlabbatch{1}.spm.stats.factorial_design.multi_cov.iCFI; %Multiple covariate interactions 243 | %matlabbatch{1}.spm.stats.factorial_design.multi_cov.iCC; %Multiple covariate centering 244 | 245 | %matlabbatch{1}.spm.stats.factorial_design.masking.tm.tm_none = 1; %Threshold masking (default = none) 246 | %matlabbatch{1}.spm.stats.factorial_design.masking.im = 1; %Implicit mask (default = yes [1]) 247 | %matlabbatch{1}.spm.stats.factorial_design.masking.em = {}; %Explicit mask 248 | 249 | %matlabbatch{1}.spm.stats.factorial_design.globalc.g_omit = 1; %Global calculation (default = omit; used for PET) 250 | %matlabbatch{1}.spm.stats.factorial_design.globalm.gmsca.gmsca_no = 1; %Global normalisation (default = no grand mean scaling; used for PET) 251 | %matlabbatch{1}.spm.stats.factorial_design.globalm.glonorm = 1; %Global normalisation (default = none; used for PET) 252 | 253 | 254 | %keyboard %Used in bug-testing script 255 | 256 | spm_jobman('run',matlabbatch); 257 | 258 | clear matlabbatch; 259 | 260 | load(fullfile(way,'estimate_spm12.mat')); 261 | stats_directory=fullfile(pairsampleTtest_directory, analysis_type{aa}, group(gg).name, pairs_name{cc}); 262 | statsfile=fullfile(stats_directory,'SPM.mat'); 263 | matlabbatch{1}.spm.stats.fmri_est.spmmat={statsfile}; 264 | 265 | spm_jobman('run',matlabbatch); 266 | 267 | clear matlabbatch; 268 | 269 | load(fullfile(way,'contrast_manager_spm12.mat')); 270 | 271 | stats_directory=fullfile(pairsampleTtest_directory, analysis_type{aa}, group(gg).name, pairs_name{cc}); 272 | statsfile=fullfile(stats_directory,'SPM.mat'); 273 | matlabbatch{1}.spm.stats.con.spmmat={statsfile}; 274 | 275 | matlabbatch{1}.spm.stats.con.consess{1}.tcon.name = 'Pre_gt_Post'; % t Contrast (f contrast = fcon) 276 | matlabbatch{1}.spm.stats.con.consess{1}.tcon.weights = [1 -1]; 277 | 278 | matlabbatch{1}.spm.stats.con.consess{2}.tcon.name = 'Post_gt_Pre'; % t Contrast (f contrast = fcon) 279 | matlabbatch{1}.spm.stats.con.consess{2}.tcon.weights = [-1 1]; 280 | 281 | spm_jobman('run',matlabbatch); 282 | 283 | end; %cc (inputting each contrast (e.g. con_0001.img)) 284 | 285 | end; %gg (inputting each group type (e.g. ALL_11SJ)) 286 | 287 | end; %aa (inputting each analysis type (e.g. GLM)) 288 | 289 | end; %end 'p' pair sample t-test 290 | 291 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 292 | %% Make model: 2nd level Factorial 293 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 294 | if strfind(todo,'f') 295 | 296 | if ~exist(fullfile(withingroups_stats_directory,'Factorial'),'dir'); mkdir(fullfile(withingroups_stats_directory,'FlexibleFactorial')); end; 297 | factorial_directory = fullfile(withingroups_stats_directory,'Factorial'); 298 | 299 | factor_1_name = 'Condition'; 300 | factor_1_level = 4; 301 | factor_2_name = 'Session'; 302 | factor_2_level = 3; 303 | contrast_num = factor_1_level*factor_2_level; 304 | level_array = [1 1 1 2 2 2 3 3 3 4 4 4; 1 2 3 1 2 3 1 2 3 1 2 3]; 305 | 306 | for aa = 1%:length(analysis_type) %change it if want just GLM, just Parametric, Just Bayesian etc 307 | 308 | if ~exist(fullfile(factorial_directory,analysis_type{aa}),'dir'); 309 | mkdir(fullfile(factorial_directory,analysis_type{aa})); %Make GLM/Parametric etc directory within onesamplettest 310 | end 311 | 312 | for gg=1:length(group) 313 | 314 | if ~exist(fullfile(factorial_directory,analysis_type{aa}, group(gg).name),'dir'); 315 | mkdir(fullfile(factorial_directory,analysis_type{aa}, group(gg).name)); %Make directory for each set of subjects (e.g. 'All_11SJ') 316 | end; 317 | 318 | 319 | load(fullfile(way,'second_level_factorial_analysis_spm12.mat')); 320 | 321 | output_directory = fullfile(factorial_directory,analysis_type{aa},group(gg).name); 322 | matlabbatch{1}.spm.stats.factorial_design.dir = {output_directory}; 323 | 324 | matlabbatch{1}.spm.stats.factorial_design.des.fd.fact(1).name = factor_1_name; 325 | matlabbatch{1}.spm.stats.factorial_design.des.fd.fact(1).levels = factor_1_level; 326 | %matlabbatch{1}.spm.stats.factorial_design.des.fd.fact(1).dept = 1; %Independence 327 | %matlabbatch{1}.spm.stats.factorial_design.des.fd.fact(1).variance = 0; %Variance Equal/Unequal 328 | %matlabbatch{1}.spm.stats.factorial_design.des.fd.fact(1).gmsca = 0; %Grand Mean Scaling (for PET/VBM) 329 | %matlabbatch{1}.spm.stats.factorial_design.des.fd.fact(1).ancova = 0; %ANCOVA (for PET/VBM) 330 | 331 | matlabbatch{1}.spm.stats.factorial_design.des.fd.fact(2).name = factor_2_name; 332 | matlabbatch{1}.spm.stats.factorial_design.des.fd.fact(2).levels = factor_2_level; 333 | 334 | %matlabbatch{1}.spm.stats.factorial_design.des.fd.contrasts = 1; %Generate contrasts: 1 = yes 335 | 336 | for cc = 1:contrast_num 337 | 338 | matlabbatch{1}.spm.stats.factorial_design.des.fd.icell(cc).levels = level_array(:,cc); 339 | 340 | for ss=1:length(group(gg).subj) 341 | 342 | contrast_end=['0' num2str(cc)]; if cc > 9; contrast_end=contrast_end(2:end); end; 343 | subj_end = ['0' num2str(group(gg).subj(ss))]; if length(subj_end) > 2; subj_end=subj_end(2:end); end; 344 | 345 | insert_contrast = [contrast_begin contrast_end '.nii']; 346 | insert_subj = [subj_begin subj_end]; 347 | 348 | subject_directory = fullfile(D, insert_subj, 'Stats', analysis_type{aa}); 349 | 350 | P=cellstr(spm_select('FPList', subject_directory, insert_contrast)); 351 | 352 | matlabbatch{1}.spm.stats.factorial_design.des.fd.icell{ss} = P{1}; 353 | 354 | clear P; 355 | 356 | end; %ss (inputting each subjects contrast) 357 | 358 | end; %cc (inputting particular contrast into cell) 359 | 360 | %Other Possible Inputs 361 | %matlabbatch{1}.spm.stats.factorial_design.cov.c; %Covariate factor 362 | %matlabbatch{1}.spm.stats.factorial_design.cov.cname; %Covariate name 363 | %matlabbatch{1}.spm.stats.factorial_design.cov.iCFi; %Covariate interactions (default = none) 364 | %matlabbatch{1}.spm.stats.factorial_design.cov.iCC; %Covariate centering (default = overall mean) 365 | %matlabbatch{1}.spm.stats.factorial_design.multi_cov.files; %Multiple covariate files 366 | %matlabbatch{1}.spm.stats.factorial_design.multi_cov.iCFI; %Multiple covariate interactions 367 | %matlabbatch{1}.spm.stats.factorial_design.multi_cov.iCC; %Multiple covariate centering 368 | 369 | %matlabbatch{1}.spm.stats.factorial_design.masking.tm.tm_none = 1; %Threshold masking (default = none) 370 | %matlabbatch{1}.spm.stats.factorial_design.masking.im = 1; %Implicit mask (default = yes [1]) 371 | %matlabbatch{1}.spm.stats.factorial_design.masking.em = {}; %Explicit mask 372 | 373 | %matlabbatch{1}.spm.stats.factorial_design.globalc.g_omit = 1; %Global calculation (default = omit; used for PET) 374 | %matlabbatch{1}.spm.stats.factorial_design.globalm.gmsca.gmsca_no = 1; %Global normalisation (default = no grand mean scaling; used for PET) 375 | %matlabbatch{1}.spm.stats.factorial_design.globalm.glonorm = 1; %Global normalisation (default = none; used for PET) 376 | 377 | 378 | %keyboard %Used in bug-testing script 379 | 380 | spm_jobman('run',matlabbatch); 381 | 382 | clear matlabbatch; 383 | 384 | load(fullfile(way,'estimate_spm12.mat')); 385 | stats_directory=fullfile(factorial_directory, analysis_type{aa}, group(gg).name); 386 | statsfile=fullfile(stats_directory,'SPM.mat'); 387 | matlabbatch{1}.spm.stats.fmri_est.spmmat={statsfile}; 388 | 389 | spm_jobman('run',matlabbatch); 390 | 391 | clear matlabbatch; 392 | 393 | 394 | end; %gg (inputting each group type (e.g. ALL_11SJ)) 395 | 396 | end; %aa (inputting each analysis type (e.g. GLM)) 397 | 398 | end; %end 'f' flexible factorial 399 | 400 | return --------------------------------------------------------------------------------