Dear all,
Still trying to reproduce old results obtained with SPM8 version 3042. We have identified another secondary cause for the discrepancy between the results of that version vs. newer versions of SPM8. File spm_defaults.m seems to have been changed from:
% Results report batch defaults
%=======================================================================
defaults.stats.results.threshtype = 'FWE'; % Threshold type
defaults.stats.results.thresh = 0.05; % Threshold value
defaults.stats.results.extent = 0; % Spatial extent
defaults.stats.results.maskthresh = 0.05; % (Uncorrected) Threshold for masking
defaults.stats.results.print = true; % Print report to file
% Mask defaults
%=======================================================================
defaults.mask.thresh = 0.05;
to:
% Mask defaults
%=======================================================================
defaults.mask.thresh = 0.8;
As you can variable "stats.results.maskthresh" has been merged with variable "mask.thresh" and the default value has been changed from 0.05 to 0.8.
At least this change is consistent with the following snippet from file spm_fmri_spm_ui.m that resets to a default value of 0.8 in case of error:
try
TH = g.*gSF*spm_get_defaults('mask.thresh');
catch
TH = g.*gSF*0.8;
end
Although the use of "magic numbers" or "magic constants" in code is bad practice (which by the way has been fixed in this specific case in SPM12) at least the "magic constants" for mask thresholds are now consistent.
In short, the above piece of code has been made more consistent in SPM8 version 5236 and I would have much more confidence in its results than the results obtained with SPM8 version 3042.
What bothers me is that (as far as I can understand) Nipype attempts at some point to simulate the old behaviour of SPM8:
https://github.com/nipy/nipype/blob/master/nipype/interfaces/spm/model.py
https://github.com/nipy/nipype/commit/fe9d0e07a288afefb34e99f488ef194a443d6089
The relevant code snippet is:
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 = ones(size(SPM.xM.TH))*(%s);\n" % self.inputs.mask_threshold
postscript += "SPM.xM.xs = struct('Masking', 'explicit masking only');\n"
postscript += "save SPM SPM;\n"
Could you please comment on the SPM8 change and the Nipype code? I realize the last part of the question might be better answered on a Nipype mailing list, but I thought I'd start with the SPM mailing list for a good understanding of what's behind the SPM change.
Best,
Dimitri
|