Output names for mapnode

I am having issues using mapnode for gunzip which creates the same names for all the files for my different functional runs.

tsnr = MapNode(TSNR(regress_poly=2), name=‘tsnr’, iterfield=[‘in_file’])
gunzip = MapNode(Gunzip(), name=“gunzip”, iterfield=[‘in_file’])
smooth = Node(Smooth(), name=“smooth”)
smooth.iterables = (“fwhm”, [4, 6, 8])

Creating the below connection between gunzip and smooth creates output with same names

( tsnr, gunzip, [ ( ‘detrended_file’ , ‘in_file’ ) ] ),
(gunzip, smooth, [(‘out_file’, ‘in_files’)])

For my 4 functional runs, I get the output file names as sdetrend.nii, sdetrend_c0000.nii and so on, thus losing the functional run information in the names. Is there a better way to do this ?

I think you should try to use iterables instead of MapNode

Could you give me an example how i can use it ? As you can see, I am using iterables for the smooth node.

I meant that you can use iterables in tsnr, but actually two MapNodes should also work, so I probably didn’t understand your problem.

Can you please tell me which function/node doesn’t produce the output files you expect? You should have directories like tsnr/mapflow/_tsnr0 and tsnr/mapflow/_tsnr1 (and similar for gunzip) for different elements from in_file list.

Or do you mean that you do have a separate directories but you don’t like the output names given by TSNR interface?

I do have the folders you stated for tsnr and gunzip. The issue is that the outputs after smooth node are sdetrend.nii, sdetrend_c0000.nii, sdetrend_c0001.nii and sdetrend_c0002.nii.

The reason for that is due to gunzip operating on detrend.nii file for all four runs due to MapNode. I want the names after smooth node to be sdetrend1.nii, sdetrend2.nii … sdetrend4.nii. Is there a way to obtain that ?

Thanks for your consideration.

So the reason why you have the same name at the end is that the TSNR produces output files with the same names, i.e. detrend.nii.gz for detrended_file. You can change it by providing an optional input for TSNR that is also called detrended_file.

So you can have your tsnr node written like this:

tsnr = MapNode(TSNR(regress_poly=2), name="tsnr", iterfield=["in_file", "detrended_file"])
tsnr.inputs.in_file = ["orig_file_1.nii", "orig_file_2.nii"]
tsnr.inputs.detrended_file = ["detrend_1.nii.gz", "detrend_2.nii.gz"]

I think it should solve your problem.

Nipype also offers DataSink interface with substitutions that can be used for output names manipulations. You can read more in doc or in tutorial, but I believe you don’t need it here, just for the future reference.

Based on your suggestions, I tried the following code where my tsnr node is connected to realign node:

tsnr = MapNode(TSNR(regress_poly=2), name=‘tsnr’, iterfield=[‘in_file’,‘detrended_file’])
tsnr.inputs.in_file = [“rarun1_despike.nii”, “rarun2_despike.nii”, “rarun3_despike.nii”, “rarun4_despike.nii” ]
tsnr.inputs.detrended_file = [“detrend_1.nii.gz”, “detrend_2.nii.gz”, “detrend_3.nii.gz”, “detrend_4.nii.gz”]

The problem is the validation that nipype does before creating the workflow. It gives me an error that the paths to the inputs of tsnr node do not exist - “traits.trait_errors.TraitError: The trait ‘in_file’ of a DynamicTraitedSpec instance is an existing file name, but the path ‘rarun1_despike.nii’ does not exist

I do not know how to fix the paths since they will be dynamically generated for every processed subject. Is there something that I am doing incorrectly ?

So how does your original workflow look like?

Based on your post I thought that you’re starting from TSNR and you’re simply providing names of in_file. If you have another node before TSNR, than you have to keep the connection instead of providing tsnr.inputs.in_file

It is exactly like the preprocessing workflow described at http://miykael.github.io/nipype-beginner-s-guide/firstLevel.html in the preproc variable
This used to work for me some time before but with changes to tsnr node in new versions of nipype, I am getting these errors now. I have just changed the workflow to save my outputs after the preprocessing step.

Thanks for your help.

Can you please try to modify your original workflow so tsnr has an additional input detrended_file, i.e.:

tsnr = MapNode(TSNR(regress_poly=2), name="tsnr", iterfield=["in_file", "detrended_file"])
tsnr.inputs.detrended_file = ["detrend_1.nii.gz", "detrend_2.nii.gz"]

If you take in_file variable from ralign node output, you should just keep it (so don’t include the second line from my previous post).

1 Like

It works !

Thanks for the help. Appreciate it.