SPM: Computing first level contrasts across sessions with different number of conditions

Hello everyone!

I would like to calculate first level contrasts for a an experiment with six runs of a encoding/retrieval task. Due to the nature of the task, not all runs have the same number of conditions. For example: Trials could be “remembered negative”, some “remembered neutral”. However, some participants do not always remember everything, so they might lack the “remembered neutral” category entirely.

How should I specify the contrasts correctly for such a design?

In the contrast batch manager I have tow plausible options: T contrast and T contrast (sess/cond based). The first option seems to be only useful if I have the same number of regressors in each run, which I don’t. So it seems what I want is the second option. But here I seem to run into a similar problem.

the matlabbatch looks like this:

matlabbatch{1}.spm.stats.con.consess{1}.tconsess.name = 'remembered_neutral'; 
   -- does this name have to be the one I specified in the onset file?
matlabbatch{1}.spm.stats.con.consess{1}.tconsess.coltype.colconds.conweight = '<UNDEFINED>';
   -- I guess here just goes a 1 as it wants me to enter a 1 by 1 array.
matlabbatch{1}.spm.stats.con.consess{1}.tconsess.coltype.colconds.colcond = '<UNDEFINED>';
   -- what goes here? "Select which condition function set is to be contrasted." I find that very unclear.
   -- does that mean I put in the number of the condition in the onset file? But that varies from session to session...
matlabbatch{1}.spm.stats.con.consess{1}.tconsess.coltype.colconds.colbf = '<UNDEFINED>';
   -- do I just enter 1 here?
matlabbatch{1}.spm.stats.con.consess{1}.tconsess.coltype.colconds.colmod = '<UNDEFINED>';
   -- I guess I enter 1?
matlabbatch{1}.spm.stats.con.consess{1}.tconsess.coltype.colconds.colmodord = '<UNDEFINED>';
   -- I guess I enter 0?
matlabbatch{1}.spm.stats.con.consess{1}.tconsess.sessions = '<UNDEFINED>';
   -- would I enter an array like [1:6] to indicate the numer of runs this applies to? But again this wouldn't work if my runs vary in the number of conditions.
...(repeat for the other conditions)...

Thank you for your help!

Note quite. You can totally use that option but you need to do a bit more scripting to generate the vector contrast to enter. This is the option I usually chose by going and looking up into the SPM.mat which sessions have the condition I am interested in.

Adding some info going by what the I can see in the SPM doc:

matlabbatch{1}.spm.stats.con.consess{1}.tconsess.name = 'remembered_neutral'; 
% does this name have to be the one I specified in the onset file?

up to you: this will be the name that appears in the SPM GUI when selecting a contrast.

so maybe remembered_neutral_gt_baseline

matlabbatch{1}.spm.stats.con.consess{1}.tconsess.coltype.colconds.conweight = '<UNDEFINED>';
% I guess here just goes a 1 as it wants me to enter a 1 by 1 array.

In most cases that would seem reasonable.

matlabbatch{1}.spm.stats.con.consess{1}.tconsess.coltype.colconds.colcond = '<UNDEFINED>';
% what goes here? "Select which condition function set is to be contrasted." I find that very unclear.
% does that mean I put in the number of the condition in the onset file? 

I would suspect so

% But that varies from session to session...

then to make your life easier, it may be better to generate onset file where conditions are always in the same order (if you can)

matlabbatch{1}.spm.stats.con.consess{1}.tconsess.coltype.colconds.colbf = '<UNDEFINED>';
% do I just enter 1 here?

YES: in most cases (assuming you are using canonical HRF and maybe its derivatives) you want the basis function for the canonical HRF so → 1

matlabbatch{1}.spm.stats.con.consess{1}.tconsess.coltype.colconds.colmod = '<UNDEFINED>';
% I guess I enter 1?

YES

matlabbatch{1}.spm.stats.con.consess{1}.tconsess.coltype.colconds.colmodord = '<UNDEFINED>';
% I guess I enter 0?

YES

matlabbatch{1}.spm.stats.con.consess{1}.tconsess.sessions = '<UNDEFINED>';
% would I enter an array like [1:6] to indicate the number of runs this applies to? But again this wouldn't work if my runs vary in the number of conditions.

I suspect you would then enter the runs for which this condition is present.

Honestly I would recommend using the former method and use the function I linked to help you build get the index of the conditions you want.

Ok cool thank you very much!
Ok so once I get the output from the function you shared, I would write the output in here as such:

matlabbatch{1}.spm.stats.con.con

sess{1}.tcon.name    = name;  
-- output of your function
matlabbatch{1}.spm.stats.con.consess{1}.tcon.weights = weightvector; 
-- output of your function
matlabbatch{1}.spm.stats.con.consess{1}.tcon.sessrep = 'none'; 
-- and this would be "none" right? because I extract all regressors from the whole session across all possible runs.

Yup the last part would be none.
Once again the name is up to you.
And the function linked to can help you construct the weight vector you need by giving you the indices of the regressors corresponding to your condition it but won’t directly create the weight vector
.