Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
ENH: added afni NetCorr
Afni 3dNetCorr is added to nipype. For more details, please see: https://afni.nimh.nih.gov/pub/dist/doc/program_help/3dNetCorr.html
  • Loading branch information
aghayoor committed Mar 2, 2021
commit a8ee022d6c3d0217aae9837147d16fad110f18db
1 change: 1 addition & 0 deletions nipype/interfaces/afni/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
LFCD,
Maskave,
Means,
NetCorr,
OutlierCount,
QualityIndex,
ROIStats,
Expand Down
73 changes: 73 additions & 0 deletions nipype/interfaces/afni/preprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -2556,6 +2556,79 @@ def _format_arg(self, name, trait_spec, value):
return super(TCorrMap, self)._format_arg(name, trait_spec, value)


class NetCorrInputSpec(AFNICommandInputSpec):
in_file = File(exists=True, argstr="-inset %s", mandatory=True)
in_rois = File(exists=True, argstr="-in_rois %s", mandatory=True)
mask = File(exists=True, argstr="-mask %s")
weight_ts = File(exists=True, argstr="-weight_ts %s")
fish_z = traits.Bool(argstr="-fish_z")
part_corr = traits.Bool(argstr="-part_corr")
ts_out = traits.Bool(argstr="-ts_out")
ts_label = traits.Bool(argstr="-ts_label")
ts_indiv = traits.Bool(argstr="-ts_indiv")
ts_wb_corr = traits.Bool(argstr="-ts_wb_corr")
ts_wb_Z = traits.Bool(argstr="-ts_wb_Z")
ts_wb_strlabel = traits.Bool(argstr="-ts_wb_strlabel")
nifti = traits.Bool(argstr="-nifti")
output_mask_nonnull = traits.Bool(argstr="-output_mask_nonnull")
push_thru_many_zeros = traits.Bool(argstr="-push_thru_many_zeros")
ignore_LT = traits.Bool(argstr="-ignore_LT")
out_file = File(
name_template="%s_netcorr",
desc="output file name part",
argstr="-prefix %s",
position=1,
name_source="in_file",
)

class NetCorrOutputSpec(TraitedSpec):
out_matrix = File(desc="output text file for correlation stats")

class NetCorr(AFNICommand):
"""Calculate correlation matrix of a set of ROIs (using mean time series of
each). Several networks may be analyzed simultaneously, one per brick.

For complete details, see the `3dTcorrMap Documentation.
<https://afni.nimh.nih.gov/pub/dist/doc/program_help/3dNetCorr.html>`_

Examples
--------
>>> from nipype.interfaces import afni
>>> ncorr = afni.NetCorr()
>>> ncorr.inputs.in_file = 'functional.nii'
>>> ncorr.inputs.mask = 'mask.nii'
>>> ncorr.inputs.in_rois = 'rois.nii'
>>> ncorr.inputs.ts_wb_corr = True
>>> ncorr.inputs.ts_wb_Z = True
>>> ncorr.inputs.fish_z = True
>>> ncorr.inputs.prefix = 'sub0.tp1.ncorr'
>>> ncorr.cmdline # doctest: +SKIP
'3dNetCorr -prefix sub0.tp1.ncorr -inset functional.nii -mask mask.nii -in_rois rois.nii -ts_wb_corr -ts_wb_Z -fish_z'
>>> res = ncorr.run() # doctest: +SKIP

"""

_cmd = "3dNetCorr"
input_spec = NetCorrInputSpec
output_spec = NetCorrOutputSpec

def _list_outputs(self):
outputs = self.output_spec().get()

if not isdefined(self.inputs.out_file):
prefix = self._gen_fname(self.inputs.in_file, suffix="_netcorr")
else:
prefix = self.inputs.out_file

# All outputs should be in the same directory as the prefix
out_dir = os.path.dirname(os.path.abspath(prefix))

outputs["out_matrix"] = (
fname_presuffix(prefix, suffix="_000", use_ext=False, newpath=out_dir) + ".netcc"
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the output file called? I would expect, if I set netcorr.inputs.out_file, the output file is called exactly that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@effigies : the netcorr.inputs.out_file defines the prefix for the output.
Afni 3dNetCorr doesn't have actual output options, but it uses the prefix to write out the correlation matrix and correlation maps to the output directory.
This added function finds and returns the convention filename for the output correlation matrix.

I am also interested to return the correlation maps return to a subdirectory in the output directory. The number of these correlation maps depends on the number of regions in the input ROI label map. Do you have any idea how I can those to the output as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@effigies : Thanks for the approval.
also, do you have any idea on this?
Please let me know if my question needs more clarification

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, sorry, missed this. Assuming these files exist, you can use glob to get them. See an example here:

class FEAT(FSLCommand):
"""Uses FSL feat to calculate first level stats
"""
_cmd = "feat"
input_spec = FEATInputSpec
output_spec = FEATOutputSpec
def _list_outputs(self):
outputs = self._outputs().get()
is_ica = False
outputs["feat_dir"] = None
with open(self.inputs.fsf_file, "rt") as fp:
text = fp.read()
if "set fmri(inmelodic) 1" in text:
is_ica = True
for line in text.split("\n"):
if line.find("set fmri(outputdir)") > -1:
try:
outputdir_spec = line.split('"')[-2]
if os.path.exists(outputdir_spec):
outputs["feat_dir"] = outputdir_spec
except:
pass
if not outputs["feat_dir"]:
if is_ica:
outputs["feat_dir"] = glob(os.path.join(os.getcwd(), "*ica"))[0]
else:
outputs["feat_dir"] = glob(os.path.join(os.getcwd(), "*feat"))[0]
print("Outputs from FEATmodel:", outputs)
return outputs

Also, can you run make specs and commit the new file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! That was very helpful.

return outputs


class TCorrelateInputSpec(AFNICommandInputSpec):
xset = File(
desc="input xset",
Expand Down