Nipype: Trait types required for first-level contrasts

Hi everyone,
I’d appreciate your help reconciling the error I’m getting when setting up the contrasts for a first-level analysis in nipype. TL; DR A tuple seemingly following the desired convention is not making it through the Trait check.

Briefly, I read in a csv with columns for the contrast title, contrast_type (‘T’ or ‘F’), conditions, and design matrix. After some formatting checks, I create a list of tuples for each contrast in the file using:

contrast_list = [x for x in df.itertuples(index=False, name=None)]

This list is passed to the Node.

info_lvl1 = Node(util.IdentityInterface(fields=['subj_id',
                                                 'task', 'timept',
                                                 'contrasts'], contrasts=contrast_list), name='info_lvl1')

And connected in its place as:

       ... (info_lvl1, contrastestimate,[('contrasts','contrasts')]) ...

However, the execution fails, producing the following error.

Traceback (most recent call last):

  File "custom_pypeline", in <module>    l1pipeline.run()

  File "/usr/local/misc/anaconda3/lib/python3.7/site-packages/nipype/pipeline/engine/workflows.py", line 589, in run
    execgraph = generate_expanded_graph(deepcopy(flatgraph))

  File "/usr/local/misc/anaconda3/lib/python3.7/site-packages/nipype/pipeline/engine/utils.py", line 1001, in generate_expanded_graph
    graph_in = _remove_nonjoin_identity_nodes(graph_in, keep_iterables=True)

  File "/usr/local/misc/anaconda3/lib/python3.7/site-packages/nipype/pipeline/engine/utils.py", line 879, in _remove_nonjoin_identity_nodes
    _remove_identity_node(graph, node)

  File "/usr/local/misc/anaconda3/lib/python3.7/site-packages/nipype/pipeline/engine/utils.py", line 907, in _remove_identity_node
    _propagate_root_output(graph, node, field, connections)

  File "/usr/local/misc/anaconda3/lib/python3.7/site-packages/nipype/pipeline/engine/utils.py", line 946, in _propagate_root_output
    destnode.set_input(inport, value)

  File "/usr/local/misc/anaconda3/lib/python3.7/site-packages/nipype/pipeline/engine/nodes.py", line 278, in set_input
    setattr(self.inputs, parameter, deepcopy(val))

  File "/usr/local/misc/anaconda3/lib/python3.7/site-packages/traits/trait_types.py", line 2573, in validate
    return TraitListObject(self, object, name, value)

  File "/usr/local/misc/anaconda3/lib/python3.7/site-packages/traits/trait_handlers.py", line 2474, in __init__
    raise excp

  File "/usr/local/misc/anaconda3/lib/python3.7/site-packages/traits/trait_handlers.py", line 2466, in __init__
    value = [validate(object, name, val) for val in value]

  File "/usr/local/misc/anaconda3/lib/python3.7/site-packages/traits/trait_handlers.py", line 2466, in <listcomp>
    value = [validate(object, name, val) for val in value]

  File "/usr/local/misc/anaconda3/lib/python3.7/site-packages/traits/trait_handlers.py", line 2151, in validate
    return self.slow_validate(object, name, value)

  File "/usr/local/misc/anaconda3/lib/python3.7/site-packages/traits/trait_handlers.py", line 2159, in slow_validate
    self.error(object, name, value)

  File "/usr/local/misc/anaconda3/lib/python3.7/site-packages/traits/trait_handlers.py", line 236, in error
    object, name, self.full_info(object, name, value), value

TraitError: Each element of the 'contrasts' trait of an EstimateContrastInputSpec instance must be a tuple of the form: (a unicode string, 'T', a list of items which are a unicode string, a list of items which are a float) or a tuple of the form: (a unicode string, 'T', a list of items which are a unicode string, a list of items which are a float, a list of items which are a float) or a tuple of the form: (a unicode string, 'F', a list of items which are a tuple of the form: (a unicode string, 'T', a list of items which are a unicode string, a list of items which are a float) or a tuple of the form: (a unicode string, 'T', a list of items which are a unicode string, a list of items which are a float, a list of items which are a float)), but a value of ('conditions minus baseline', 'F', ['high', 'low', 'nonfood', 'baseline'], [0.3, 0.3, 0.3, -1.0]) <class 'tuple'> was specified.

The error seems to indicate that I provided a tuple, when a tuple is required… and that’s problematic. I’ve tried adapting the contrast_list to [list(x) for x in df.itertuples(index=False, name=None)], in line with the output of Michael’s contrast_list variable in the tutorial (https://miykael.github.io/nipype_tutorial/notebooks/example_1stlevel.html). A similar, but predictable, error occurs, stating that <class ‘list’> was specified, when a tuple is required.

Nipype version: 1.2.0
Python version: 3.7.3
Any thoughts? Thank you!
Brianne

For future neurocoders:

One incompletely defined F-test in my list of 10 contrast tuples caused the above error to occur.

The error states that the F-test must be “a tuple of the form: (a unicode string, ‘F’, a list of items which are a tuple of the form: (a unicode string, ‘T’, a list of items which are a unicode string, a list of items which are a float) or a tuple of the form: (a unicode string, ‘T’, a list of items which are a unicode string, a list of items which are a float, a list of items which are a float))”. I didn’t realize, until closer inspection, that the F-test tuple was building a matrix of contrasts, just like you would see if setting up the test in the SPM GUI (e.g., [1 0 0; 0 1 0; 0 0 1]).

Hope this helps someone else solve their issue more quickly!

1 Like