Machine Learning Tutorial #6: Scripting


Overview

In a previous chapter in this module, you edited a script that was generated through the SPM GUI. We will use that same script and impose a for-loop on it in order to analyze all of the subjects, one after another, without having to do anything in between. This makes it much easier and less tedious to analyze large numbers of subjects, especially when they are all formatted identically with the same number of runs and timing files - the only difference is the subject number, which will be changed on each iteration of the loop.

Editing the Preprocessing Script

We will first make a copy of the script Haxby_Script_job.m by saving it as Haxby_Script_allSubjs.m and saving it in the Haxby_Data folder. Then add this line of code near the top of the script:

subjects = [2 3 4 6];

for subject=subjects

and remember to add the string end to the very last line of the script to close the for-loop.

Note

Subject 5 has 11 runs instead of the usual 12 runs that all of the other subjects have, so we will save that for another script below.

To make this script work for any subject, we will need to replace any occurrences of sub-1 with the variable located in subject. Open the Find and Replace menu, and replace every instance of pwd '/sub-1/func/sub-1 with pwd '/sub-' subject '/func/sub-' subject '. Also change [ pwd '/SPM_Results_1' ] to [ pwd '/SPM_Results_' subject].

In the section that loads the onset times, you will need to change each condition from something like this:

load('sub-1/func/bottle.txt');

to this:

load(['sub-' subject '/func/bottle.txt']);

Repeat for all of the other conditions.

Lastly, near the beginning of the script, just after the for loop is defined, insert the following code:

subject = num2str(subject);
% Check whether the files have been unzipped. If not, unzip them using
% gunzip

if exist([ pwd filesep 'sub-' subject '/anat/sub-' subject '_T1w.nii' ]) == 0
    display('Anatomical image has not been unzipped; unzipping now')
    gunzip([ pwd filesep 'sub-' subject '/anat/sub-' subject '_T1w.nii.gz' ])
else
    display('Anatomical image is already unzipped; doing nothing')
end

runs = [ 01 02 03 04 05 06 07 08 09 10 11 12 ];

for run=runs

run = num2str(run, '%02d'); % Zero-pads each number so that the "run" variable is 2 characters long

if exist([ pwd filesep 'sub-' subject '/func/sub-' subject '_task-objectviewing_run-' run '_bold.nii']) == 0
    display([ 'Run ' run ' has not been unzipped; unzipping now'])
    gunzip([ pwd filesep 'sub-' subject '/func/sub-' subject '_task-objectviewing_run-' run '_bold.nii.gz' ])
else
    display(['Run ' run ' is already unzipped; doing nothing'])
end

end

This will check whether the files are zipped, and if so, it will unzip them. This is necessary for them to be loaded into the SPM batch structure.

Note

It might be easier to download a script that has already been edited, and compare it against the script you generated in the previous chapters. Click here and download the file “Haxby_Script_allSubjs.m”. If you place it in the directory Haxby_Data, you should be able to run it from the terminal by typing Haxby_Script_allSubjs and pressing Enter.

When the script has finished running for subjects 2, 3, 4, and 6, the only subject remaining is number 5. Change the subjects array from [2 3 4 6] to [5], and remove the number 12 from the runs array. Then comment out the line {[ pwd filesep 'sub-' subject '/func/sub-' subject '_task-objectviewing_run-12_bold.nii']}, the line around 64 that begins matlabbatch{2}.spm.spatial.realign.estwrite.data{12}(1) = cfg_dep('Named File Selector: Runs(12) - Files, and any line of code that begins with matlabbatch{4}.spm.stats.fmri_spec.sess(12). Run the script again, saving it as a separate file if you want to.

Editing the MVPA Scripts

The changes to the MVPA scripts are similar to the edits for the preprocessing. At the beginning of the Haxby_MVPA_ROI script we will declare our for-loop:

subjects = [1 2 3 4 5 6];

for subject=subjects

subject = num2str(subject);

And then change the code for setting the results and beta maps directories:

% Set the output directory where data will be saved, e.g. 'c:\exp\results\buttonpress'
cfg.results.dir = [pwd '/SPM_Results_' subject];

% Set the filepath where your SPM.mat and all related betas are, e.g. 'c:\exp\glm\model_button'
beta_loc = [pwd '/SPM_Results_' subject];

Also, add an end at the end of the file.

And run the script from the terminal. As an exercise, when it has finished modify the script again to do a searchlight analysis for all of the subjects, using the methods you learned in the last chapter. A template script can be downloaded here, under the file Haxby_MVPA_ROI_Scripted.

Next Steps

The ROI results may be all that you need for your analysis; with an accuracy value per condition for each subject, these can be used as values in a t-test. Keep in mind that they need to be compared to chance, as opposed to a baseline of zero. (This might be why one of the outputs you can select is accuracy minus chance; that removes the need for an additional step of subtracting chance.)

If you are instead interested in the searchlight whole-brain results, on the other hand, we will need to normalize them to MNI space. To see how to do that, click the Next button.