[Neuroimaging] [nipype] updated external mask handling in SPM
Satrajit Ghosh
satra at mit.edu
Wed Dec 9 07:43:22 EST 2015
hi dimitri,
a change that allows both versions would be fine. please submit a PR and we
can iterate on how to convey the differences through the option names and
description.
cheers,
satra
On Wed, Dec 9, 2015 at 6:43 AM, Dimitri Papadopoulos Orfanos <
dimitri.papadopoulos at cea.fr> wrote:
> Dear all,
>
> I looked into masking in SPM and with some help I came up with the
> following findings:
>
>
> * The SPM user interface only sets "analysis threshold masking", see
> file spm_fmri_spm_ui.m around line 375:
>
> %-Masking
> %==========================================================================
>
> %-Masking threshold, as proportion of globals
> %--------------------------------------------------------------------------
> try
> gMT = SPM.xM.gMT;
> catch
> gMT = spm_get_defaults('mask.thresh');
> end
> TH = g.*gSF*gMT;
>
> %-Place masking structure in xM
> %--------------------------------------------------------------------------
> SPM.xM = struct(...
> 'T', ones(q,1),...
> 'TH', TH,...
> 'gMT', gMT,...
> 'I', 0,...
> 'VM', {[]},...
> 'xs', struct('Masking','analysis threshold'));
>
>
> * When specifying the model in batch jobs, SPM itself sets "explicit
> masking" in the following way in file /spm_run_fmri_spec.m around line 385:
>
> %-Explicit mask
> %--------------------------------------------------------------------------
> if ~design_only
> if ~isempty(job.mask{1})
> SPM.xM.VM = spm_data_hdr_read(job.mask{1});
> SPM.xM.xs.Masking = [SPM.xM.xs.Masking, '+explicit mask'];
> end
> end
>
>
> * The intent of SPM seems to be that the "explicit mask" is a superset
> of the final mask, *not* that it will be the exact mask used during
> estimation. From spm_spm.m around line 50:
>
> % xM.VM - struct array of explicit mask image handles
> % - (empty if no explicit masks)
> % - Explicit mask images are >0 for valid voxels to assess.
> % - Mask images can have any orientation, voxel size or data
> % type. They are interpolated using nearest neighbour
> % interpolation to the voxel locations of the data Y.
> % - Note that voxels with constant data (i.e. the same value across
> % scans) are also automatically masked out.
>
>
>
> * We find different results with Nipype than when running vanilla SPM
> batch jobs.
>
>
> I would therefore suggest removing this Nipype hack by default:
>
> https://github.com/nipy/nipype/commit/fe9d0e07a288afefb34e99f488ef194a443d6089
> It could be added as an option, for different "explicit masking" than
> initially.
> I intend to propose a patch to remove the current hack. Does anyone have
> more insight on this Nipype hack that modifies default SPM behavior and
> would be against the patch?
>
> Best,
> Dimitri
>
> Le 04/12/2015 16:20, Dimitri Papadopoulos Orfanos a écrit :
> > Hi Satra,
> >
> > I understand the whole purpose of this piece of code is to get SPM to
> > use an explicit mask. This is done by manipulating the masking structure
> > "SPM.xM".
> >
> > I'm not yet entirely convinced this still needs to be done "behind the
> > back of SPM" by modifying SPM.mat outside of the SPM code, but here is
> > one of "John's Gems" that recommends this Nipype hack (it refers to SPM2
> > though):
> > http://blogs.warwick.ac.uk/nichols/entry/spm2_gem_12/
> >
> > With fMRI data/models, SPM2 is fully capable of doing explicit
> > masking, but the user interface for fMRI doesn't ask for it.
> > One way to do this type of masking anyway is to change the
> > SPM.mat file *after* you specify your model, but *before*
> > clicking 'Estimate'.
> > Specifically:
> > 1. Load the SPM.mat file,
> > load SPM
> > set the SPM.xM.TH values all to -Inf,
> > SPM.xM.TH = -Inf*SPM.xM.TH;
> > and, in case that you have an image format not allowing
> > NaNs, set SPM.xM.I to 0
> > SPM.xM.I = 0;
> > 2. If using a mask image, set SPM.xM.VM to a vector of
> > structures, where each structure element is the output
> > of spm_vol. For instance:
> > SPM.xM.VM = spm_vol('Maskimage');
> > 3. Finally, save by
> > save SPM SPM
> >
> >
> > Most importantly, I am puzzled by the fact that we don't find the same
> > results when running SPM8 via Nipype than when running SPM8 back in
> > 2010-2012 using batches created from the SPM user interface. At this
> > point I am not sure if this is an issue with Nipype, an issue with our
> > own scripts created in 2009-2010, or perhaps related to changes in SPM8.
> > I would like to the bottom of it - time permitting... I don't feel
> > comfortable with the idea that the default SPM workflow could have been
> > modified and I'd like to understand the cause of the discrepancy in the
> > results.
> >
> > Best,
> > Dimitri
> >
> > Le 02/12/2015 23:17, Satrajit Ghosh a écrit :
> >> hi dimitri,
> >>
> >> it's been a long while since those lines were written. but i believe
> >> this was written as noted in the comments to support the case where the
> >> user simply wanted spm to use the explicit mask. the other reason for it
> >> was that there were several places that could control spm options (e.g.,
> >> config file). we did not want to rely on the config file.
> >>
> >> i believe it was more of a perspective on what an explicit mask meant. i
> >> can't remember if this was discussed on the spm list or came from best
> >> practices in our lab at that time.
> >>
> >> cheers,
> >>
> >> satra
> >>
> >> On Wed, Dec 2, 2015 at 9:45 AM, Dimitri Papadopoulos Orfanos
> >> <dimitri.papadopoulos at cea.fr <mailto:dimitri.papadopoulos at cea.fr>>
> wrote:
> >>
> >> Hi,
> >>
> >> I have a question on the following commit:
> >>
> https://github.com/nipy/nipype/commit/fe9d0e07a288afefb34e99f488ef194a443d6089
> >>
> >> Could someone explain the rationale behind the addition of this
> piece of
> >> code in nipype/interfaces/spm/model.py? We came across this code
> while
> >> trying to reproduce the results obtained with an old version of
> SPM8 run
> >> manually vs. the latest version of SPM8 run from Nipype.
> >>
> >> if isdefined(self.inputs.mask_image):
> >> # SPM doesn't handle explicit masking properly,
> especially
> >> # when you want to use the entire mask image
> >> postscript = "load SPM;\n"
> >> postscript += "SPM.xM.VM = spm_vol('%s');\n" %
> >> list_to_filename(self.inputs.mask_image)
> >> postscript += "SPM.xM.I = 0;\n"
> >> postscript += "SPM.xM.T = [];\n"
> >> postscript += "SPM.xM.TH <http://SPM.xM.TH> =
> >> ones(size(SPM.xM.TH <http://SPM.xM.TH>))*(%s);\n" %
> >> self.inputs.mask_threshold
> >> postscript += "SPM.xM.xs = struct('Masking', 'explicit
> >> masking only');\n"
> >> postscript += "save SPM SPM;\n"
> >>
> >> We have understood almost all causes for differences in results. The
> >> only cause that remains to be explained is this Nipype hack. Has
> perhaps
> >> this issue been discussed on the SPM mailing list?
> >>
> >> Best,
> >> --
> >> Dimitri Papadopoulos
> >> CEA/Saclay
> >> I2BM, NeuroSpin
> >> F-91191 Gif-sur-Yvette cedex, France
> >> _______________________________________________
> >> Neuroimaging mailing list
> >> Neuroimaging at python.org <mailto:Neuroimaging at python.org>
> >> https://mail.python.org/mailman/listinfo/neuroimaging
> >>
> >>
> >>
> >>
> >> _______________________________________________
> >> Neuroimaging mailing list
> >> Neuroimaging at python.org
> >> https://mail.python.org/mailman/listinfo/neuroimaging
> _______________________________________________
> Neuroimaging mailing list
> Neuroimaging at python.org
> https://mail.python.org/mailman/listinfo/neuroimaging
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/neuroimaging/attachments/20151209/32f11e82/attachment.html>
More information about the Neuroimaging
mailing list