Hi,
I'm working on a modification of the SPM, DARTEL example and generally it's working well. This is an experiment that has multiple runs per subject and I'm trying to make the script fairly general-purpose. I need to run a 3-level model (i.e, a regular level 1 analysis, a fixed effects analysis at level 2 to combine runs for each subject, and random effects at level 3 across subjects). First off, if someone has a good suggestion for running this type of analysis besides the solution I'm using I'm happy to hear it.
In order to use the subjectinfo function to pull the appropriate information for each run, I need to provide "run" as an iterable for InfoSource. When running the workflow, in the working directory I get a separate subfolder for each run and subject ("_run_r2_subject_id_0000133"). Things appear to run smoothly, but when it comes to the DataSink, I have 2 options: if I set parameterization to True, then it separates everything by the run, but also creates lots of unnecessary subfolders for each contrast. When parameterization is False, then it stores everything in 1 subfolder for each subject, but only 1 set of results-- instead of a set of contrasts for each run.
I'm wondering if there's a way to specify the Datasink so the files are outputted like this:
subject_id/run/[all contrast images]
so, in the example below, each subject would have 2 subfolders, each containing all contrast images for that run.
I can attach my full workflow, but here's the snippet that's relevant:
runs = ['r2','r3']
struct_name = 'anat_full'
file_template = {'struct': '%s/'+struct_name+'.nii*',
'func': '%s/%s.nii'}
file_args = {'struct': [['subject_id']],
'func': [['subject_id', 'run']]}
subject_list = ['0000133', '0000322']
infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id','run']), name="infosource")
infosource.iterables = [('subject_id', subject_list),('run',runs)]
datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id','run'],
outfields=['func', 'struct']),
name = 'datasource')
datasource.inputs.base_directory = data_dir
datasource.inputs.template = '*'
datasource.inputs.field_template = file_template
datasource.inputs.template_args = file_args
datasource.inputs.sort_filelist = True
datasink = pe.Node(interface=nio.DataSink(), name="datasink")
datasink.inputs.base_directory = os.path.abspath(data_output_dir)
datasink.inputs.parameterization = False #added by Jason, so we don't need getstripdir
report = pe.Node(interface=nio.DataSink(infields=['subject_id','run']), name='report')
report.inputs.base_directory = os.path.abspath(report_dir)
report.inputs.parameterization = False
# store relevant outputs from various stages of the 1st level analysis
level1.connect([(infosource, datasink,[('subject_id','container')]),
(l1pipeline, datasink,[('analysis.contrastestimate.con_images','contrasts.@con'),
('analysis.contrastestimate.spmT_images','contrasts.@T')]),
(infosource, report,[('subject_id', 'container')]),
(l1pipeline, report,[('analysis.slicestats.out_file', '@report')]),
])
I realize that the original script was capable of processing multiple runs, but I couldn't see how to get the correct timing info for each run without a "run" field from InfoSource. Also, it looks like the example script simply concatenates the runs together, which isn't exactly what I want.
Any help you could offer would be great.
Thanks!
Jason