Adding nuisance regressors to SPM model

Apologies in advance for the lengthy post

I’m trying to add regressors to my model, and have been following the recommendations in these two discussions:
https://neurostars.org/t/adding-additional-regressors-to-spm-modelgen-with-nipype/1089
https://neurostars.org/t/nuisance-regressors-in-fsl-level1design/641

The regressors aren’t confounds but conditions of no interest, which need to be convolved with HRF. So I ended up creating subject_info + running SpecifySPMModel + Level1Design only for the regressors, saving the results in a file and loading them to add to a new subject_info, which is then also fed to SpecifySPMModel + Level1Design. A bit roundabout, so any other solutions would be welcome.

However when concatenating runs that have regressors, SpecifySPMModel crashed. Here is an example of minimal code that replicates the error:

import sys import numpy as np from nipype.algorithms.modelgen import SpecifySPMModel from nipype.interfaces.base import Bunch

n_TRs = 509 # specific for the files I provided
reg1A = np.zeros((n_TRs,1))
reg1B = np.zeros((n_TRs,1))
reg1A[5] = 1
reg1B[200] = 1
subj_info1 = Bunch(conditions=[‘A’, ‘B’],
    onsets=[[5, 20], [45, 300]], durations=[[2], [2]],
     regressors=[reg1A.tolist(), reg1B.tolist()],
    regressor_names=[‘reg1’, ‘reg2’])

reg2A = np.zeros((n_TRs,1))
reg2B = np.zeros((n_TRs,1))
reg2A[100] = 1
reg2B[30] = 1
subj_info2 = Bunch(conditions=[‘A’, ‘B’],
    onsets=[[80, 300], [10]], durations=[[2], [2]],
     regressors=[reg2A.tolist(), reg2B.tolist()],
     regressor_names=[‘reg1’, ‘reg2’])

func_runs = [‘path_to_file1’, ‘path_to_file2’] # to run must be replaced with existing files
test_modelspec = SpecifySPMModel(concatenate_runs=True,
     input_units=‘secs’,
     output_units=‘secs’,
    time_repetition=2,
     high_pass_filter_cutoff=100)
test_modelspec.inputs.functional_runs = func_runs
test_modelspec.inputs.subject_info = [subj_info1, subj_info2]

test_modelspec.run()

I think the problem may be in the concatenation function of SpecifySPMModel, as it adds a regressor that distinguishes runs, but doesn’t add a name for it (the name is added elsewhere, but only if there are no named regressors). I created a local version of modelgen, and added this code to the _concatenate_info function:

infoout.regressor_names.insert(
     len(infoout.regressor_names),
     ‘UR%d’ % (len(infoout.regressor_names) + 1))

right after this:

infoout.regressors.insert(
    len(infoout.regressors),
    onelist.tolist()[0])

I know neurostars may not necessarily be the place to post this, but I am too new to Python/nipype etc. to be sure this is indeed something that should be corrected in the code, and I’m not just missing something.

I’d be very happy to hear thoughts from the experts here (as well as ideas on a more elegant way to add regressors that are simply conditions of no interest - excluded trials).

Thanks!

I just realised that while this works, it still doesn’t help with the original reason I needed this.
I have run1-exclude and run2-exclude and I prefer not to concatenate them. One solution is to have a regressor called run1-exclude with all zeros in run2 and vice-versa. But then if a specific participant has no exclude events, I have to make sure I remove that regressor from the subject_info of the other run. Doable, but it seems like there’s probably a simpler solution that I’m missing.

Thanks