Back to the main page.

Bug 2793 - add mini version of spm12 to fieldtrip/external

Status CLOSED FIXED
Reported 2014-12-23 12:56:00 +0100
Modified 2019-08-10 12:41:14 +0200
Product: FieldTrip
Component: external
Version: unspecified
Hardware: PC
Operating System: Mac OS
Importance: P5 enhancement
Assigned to: Arjen Stolk
URL:
Tags:
Depends on:
Blocks: 32282837
See also:

Robert Oostenveld - 2014-12-23 12:56:12 +0100

this requires to find out which of the spm12 functions are called by fieldtrip, and only add those functions. Should use depfun or mydepfun


Arjen Stolk - 2015-11-19 01:13:55 +0100

It seems we should replace, in ft_volumerealign, the call to spm_normalise by spm_coreg. The latter can be called according to: VG = 'IR18_MR.nii'; % VG - handle for reference image (see spm_vol). VF = 'IR18_CT.nii'; % VF - handle for source (moved) image. flags = []; % use the defaults x = spm_coreg(VG,VF,flags); transform = spm_matrix(x(:)');


Arjen Stolk - 2015-11-19 01:53:16 +0100

Actually just build this in. For instance, if one has spm12 on the path, one can call: mri = ft_read_mri(mrfile); ct = ft_read_mri(ctfile); cfg = []; cfg.method = 'spm'; cfg.spmversion = 'spm12'; ct = ft_volumerealign(cfg, ct, mri); The build in support (ft_volumerealign): elseif strcmpi(cfg.spmversion, 'spm12') if ~isfield(cfg, 'spm'), cfg.spm = []; end tname1 = [tempname, '.nii']; tname2 = [tempname, '.nii']; VG = ft_write_mri(tname1, target.anatomy, 'transform', target.transform, 'spmversion', spm('ver'), 'dataformat', 'nifti_spm'); % reference image VF = ft_write_mri(tname2, mri.anatomy, 'transform', mri.transform, 'spmversion', spm('ver'), 'dataformat', 'nifti_spm'); % source (moved) image flags = cfg.spm; x = spm_coreg(VG,VF,flags); transform = spm_matrix(x(:)'); end Note that spm_coreg works fine without having two put the two volumes in the same coordsys (a big plus from my point of view). I've also add the spm12 options to the help section: % When cfg.spmversion = 'spm12', the following options apply: % cfg.spm.sep = optimisation sampling steps (mm), default: [4 2] % cfg.spm.params = starting estimates (6 elements), default: [0 0 0 0 0 0] % cfg.spm.cost_fun = cost function string: % 'mi' - Mutual Information (default) % 'nmi' - Normalised Mutual Information % 'ecc' - Entropy Correlation Coefficient % 'ncc' - Normalised Cross Correlation % cfg.spm.tol = tolerences for accuracy of each param, default: [0.02 0.02 0.02 0.001 0.001 0.001] % cfg.spm.fwhm = smoothing to apply to 256x256 joint histogram, default: [7 7]


Arjen Stolk - 2015-11-19 08:29:43 +0100

Turns out it is not as easy as transform = spm_matrix(x(:)'); According to the documentation of spm_coreg, mapping from voxels in 'target' to voxels in 'mri' is attained by: mri.transform\spm_matrix(x(:)')*target.transform At the end of ft_volumerealign, the realign struc is build according to: realign.transform = transform * mri.transform; meaning that the transform variable should equal: ( mri.transform\spm_matrix(x(:)')*target.transform )/mri.transform However, I cannot produce consistent results this way, switching between markers placed in either a ct or mri. Whereas the spm gui does produce a coregistered file that has markers with equal positions as within its target. As a sidenote, spm12 now has spm_coreg and spm_realign, for aligning between and within modalities, respectively. Spm_normalise no longer is included (it was in spm8).


Robert Oostenveld - 2015-11-19 08:37:08 +0100

we should change it such that it remains compatible with old versions of spm. The code of ft_read_mri contains an example on how to make it work for different spm versions.


Arjen Stolk - 2015-11-19 08:44:25 +0100

(In reply to Robert Oostenveld from comment #4) It (still) is: if strcmpi(cfg.spmversion, 'spm2') || strcmpi(cfg.spmversion, 'spm8') ... params = spm_normalise(V2,V1,[],[],[],flags); transform = (target.transform/params.Affine)/T/mri.transform; .... elseif strcmpi(cfg.spmversion, 'spm12') if ~isfield(cfg, 'spm'), cfg.spm = []; end tname1 = [tempname, '.nii']; tname2 = [tempname, '.nii']; VG = ft_write_mri(tname1, target.anatomy, 'transform', target.transform, 'spmversion', spm('ver'), 'dataformat', 'nifti_spm'); % reference image VF = ft_write_mri(tname2, mri.anatomy, 'transform', mri.transform, 'spmversion', spm('ver'), 'dataformat', 'nifti_spm'); % source (moved) image flags = cfg.spm; x = spm_coreg(VG,VF,flags); end


Arjen Stolk - 2015-11-19 19:33:11 +0100

(In reply to Arjen Stolk from comment #5) Transformation matrices are not my cup of tea, but this seems to produce identical results as when done with the spm gui: tname1 = [tempname, '.nii']; tname2 = [tempname, '.nii']; V1 = ft_write_mri(tname1, mri.anatomy, 'transform', mri.transform, 'spmversion', spm('ver'), 'dataformat', 'nifti_spm'); % source (moved) image V2 = ft_write_mri(tname2, target.anatomy, 'transform', target.transform, 'spmversion', spm('ver'), 'dataformat', 'nifti_spm'); % reference image flags = cfg.spm; x = spm_coreg(V2,V1,flags); % spm_realign does within modality rigid body movement parameter estimation % x - the parameters describing the rigid body rotation, such that a % mapping from voxels in G to voxels in F is attained by: % VF.mat\spm_matrix(x(:)')*VG.mat M = inv(spm_matrix(x(:)')); MM = spm_get_space(tname1); mri.transform = spm_get_space(tname1, M * MM); transform = eye(4); % such that realign.transform will be created below


Arjen Stolk - 2015-11-19 19:48:52 +0100

(In reply to Arjen Stolk from comment #6) simplified to: ... elseif strcmpi(cfg.spmversion, 'spm12') if ~isfield(cfg, 'spm'), cfg.spm = []; end tname1 = [tempname, '.nii']; tname2 = [tempname, '.nii']; V1 = ft_write_mri(tname1, mri.anatomy, 'transform', mri.transform, 'spmversion', spm('ver'), 'dataformat', 'nifti_spm'); % source (moved) image V2 = ft_write_mri(tname2, target.anatomy, 'transform', target.transform, 'spmversion', spm('ver'), 'dataformat', 'nifti_spm'); % reference image flags = cfg.spm; x = spm_coreg(V2,V1,flags); % spm_realign does within modality rigid body movement parameter estimation transform = inv(spm_matrix(x(:)')); % from V1 to V2, to be multiplied still with the original transform (mri.transform), see below end


Arjen Stolk - 2017-01-03 01:01:57 +0100

To make a start in terms of a mini SPM12 version, can we minimally add the following list of functions? They are needed to use SPM12's spm_coregister.m when calling ft_volumerealign as follows: cfg = []; cfg.method = 'spm'; cfg.spmversion = 'spm12'; % requires spm_coregister.m and a bunch of others cfg.coordsys = 'tal'; cfg.viewresult = 'yes'; ct_fused = ft_volumerealign(cfg, ct, mri);


Arjen Stolk - 2017-01-03 01:02:42 +0100

Created attachment 822 minimally required functions (zip)


Arjen Stolk - 2017-01-03 01:03:11 +0100

Created attachment 823 minimally required functions (screen capture)


Arjen Stolk - 2017-01-03 01:04:23 +0100

(In reply to Arjen Stolk from comment #9) Total size, unpacked, is 2.1 MB.


Jan-Mathijs Schoffelen - 2017-01-03 07:28:07 +0100

Other FT-functions that rely on spm functionality are (non exhaustively): ft_volumenormalise ft_volumesegment ft_warp_apply


Arjen Stolk - 2017-01-03 08:41:09 +0100

If those functions also support algorithms specific to spm12, those algorithms and their supporting functions ideally are also added. However, given not much progress has been made in the this bug's 2-year lifetime, shall we proceed with accommodating this instance and add that mini spm12 folder to external?


Jan-Mathijs Schoffelen - 2017-01-03 08:53:38 +0100

sure, but while we (=you) are/is at it, it would be good to resolve it once and for all :-). Grand-scheme-of-things, and that kind of stuff.


Arjen Stolk - 2017-01-23 20:40:33 +0100

% TEST test_spm12 % currently (Jan, 2017) SPM12 support for: % - ft_volumerealign % - ft_volumedownsample (incl smoothing) % - private/mni2tal % - private/tal2mni % - private/volumesmooth % - ft_read_mri (nifti_spm, default remains spm8) - based on function deps, not real data % - private/volumewrite_spm (default remains spm8) - based on function deps, not real data % - utilities/private/sn2individual (called by ft_warp_apply) - based on function deps, not real data % - utilities/private/individual2sn (called by ft_warp_apply) - forced use of spm8 since spm_invdef is missing in spm12 (in toolbox/OldSeg) % to do (function-specific intelligence required): % - ft_volumenormalise % - ft_volumesegment This is a major commit, and may require monitoring of spm-related functionalities starting to fail testing. ft_volumenormalise and ft_volumesegment did not support spm12 in the first place, and nothing has changed to them. Enforced use of spm8 in individual2sn since spm_invdef is missing in spm12 (it's in toolbox/OldSeg but not accessible on the fly)


Robert Oostenveld - 2017-01-24 14:35:00 +0100

(In reply to Arjen Stolk from comment #15) arjen submitted this https://github.com/fieldtrip/fieldtrip/pull/305 I have pulled it to a local branch and will look into it. Important is that existing code does not break, and that consistency is maintained (to avoid future headaches).


Bruno L. Giordano - 2017-01-24 15:23:38 +0100

Hi, please bear with me, this is the first time I work on bugzilla and I am sure I won't contribute in the right format. I hope this helps anyway. I have used SPM12 quite a bit in the ft pipelines I developed. In the last iteration I am using Dartel-based normalization of native-space contrasts computed in native grids. Here I am giving the procedures for doing MNI grids based on the new segmentation in SPM, and also the procedures for doing the Dartel-based analysis (big picture approach). The code below for calling SPM routines is based on the batch system (need to dig the actual functions, and quite a few must be common to SPM8). 1. AC-center the anatomical to improve the segmentation. M=eye(4); M(1:3,end)=-AC; %AC is AC location in mm, [3,1] vector batch.spm.util.reorient.transform.transM = M; %run the batch. 2. use the new segmentation to extract the TPMs. The grey-matter TPM will be used to create the volume conduction model. batch: batch.spm.spatial.preproc requires TPM.nii in spmdir/tpm 3. MNI grid approach: estimate normalization from AC-centered native-space anatomical to MNI: batch.spm.tools.oldnorm.est 4. MNI grid approach: MNI normalize subject-specific grey-matter TPMs batch.spm.tools.oldnorm.write 5. MNI grid approach: average MNI-normalized grey-matter TPMs, and eventually exclude regions based on MNI atlases (e.g., AAL, although lately I prefer the Neuromorphometrics atlas in spm12/tmp) cfg=[]; cfg.grid.resolution=resolution; cfg.mri=mri; %group-average MNI grey TPM with non-interesting regions set to 0 cfg.threshold=0.25;% cfg.smooth=0; groupgrid=ft_prepare_sourcemodel(cfg); 6. various alignment steps 7. MNI grid approach: prepare volume conduction and source models using the new segmentation clear seg seg.gray=Gray; %spm_read_vol('c1acs.nii'); %c1 from ac-centered anatomical seg.white=White; %spm_read_vol('c2acs.nii'); seg.csf=CSF; %spm_read_vol('c3acs.nii'); seg.dim=MRI_HeadShapes.dim; %MRI_HeadShapes is the AC anatomical aligned to %digitized headshape seg.transform=MRI_HeadShapes.transform; seg.coordsys=MRI_HeadShapes.coordsys; seg.unit=MRI_HeadShapes.unit; cfg=[]; cfg.output='brain'; %create brain mask from segmentation seg=ft_volumesegment(cfg,seg); %not sure why I do this and the following three seg.gray=Gray; seg.white=White; seg.csf=CSF; cfg=[]; cfg.method='singleshell'; vol=ft_prepare_headmodel(cfg,seg); cfg = []; cfg.grid.warpmni = 'yes'; cfg.grid.template = groupgrid; cfg.grid.nonlinear = 'yes'; cfg.mri = seg; grid = ft_prepare_sourcemodel(cfg); The Dartel-based approach is much more involved! 1. ac-center native-space anatomicals; 2. segment ac-centered anatomicals; 3. create Dartel template using the anatomical segmentations at 2. Note, the stereotaxic space is specific to the group of participants. Further steps are required to move to/from MNI: batch.spm.tools.dartel.warp 4. normalize something from native to MNI through Dartel to estimate the Dartel-to-MNI transformation (e.g., participant-specific grey-matter TPMs): batch.spm.tools.dartel.mni_norm 5. normalize the Dartel template to MNI for eventual visualization and sanity checks: !cp -fv Template_6.nii Template_6_MNI.nii %Template_6.nii is the Dartel template load Template_6_2mni.mat %contains mni structure with Dartel-to-MNI transforms M = mni.affine; P='Template_6_MNI.nii'; Nii = nifti(P); Nii.mat = M; Nii.mat_intent = 4; create(Nii); %note, this changes the header not the data, so voxels are equispaced in Dartel not MNI space 6. transform atlases to Dartel space (here example based on aal_for_spm12 http://www.gin.cnrs.fr/AAL) eval(['!cp -fv AAL.nii AAL_Dartel.nii']) infile='AAL_Dartel.nii'; M1=spm_vol(infile); M1=M1.mat; M2=spm_vol([darteldir,'Template_6.nii,1']); M2=M2.mat; load([darteldir,'Template_6_2mni.mat']) M3 = mni.affine; M=M2*(M3\M1); P=infile; Nii = nifti(P); Nii.mat = M; Nii.mat_intent = 4; create(Nii); %now AAL_Dartel header is squeezed to Dartel space The next step is to resize bounding box and voxel size of the Dartel-normalized atlas so that it corresponds to what in the Dartel template: vtarg=spm_vol([maskdir,'Template_6.nii,1']); resize_img_BLG_nearNeighb('AAL_Dartel.nii',... %will attach this function later nan(1,3), nan(2,3), 0,vtarg.mat,vtarg.dim) %resize atlas to dartel template 'rAAL_Dartel.nii' can now be used for label-based removal of uninteresting regions from the Dartel-space grey-matter TPM 7. transform the Dartel-space TPM with uninteresting regions set to 0 from Dartel to native space batch.spm.tools.dartel.crt_iwarped batch.spm.tools.dartel.crt_iwarped.interp = 7; and set to a binary mask. 8. prepare native-space grids with specific resolution maskforgridfn=fn_for_native-space_mask computed at 7. targetvoxdim=in_mm; BB=nan(2,3); %if nans it uses bounding box of original volume resize_img_BLG_nearNeighb(maskforgridfn, targetvoxdim, BB, 1); vm=spm_vol(['r',maskforgridfn]); [Mask,XYZ]=spm_read_vols(vm); Mask=Mask(:)==1; cfg=[]; cfg.grid.pos =XYZ'/10;% = N*3 matrix with position of each source cfg.grid.inside =Mask; cfg.grid.dim =vm.dim;% cfg.unit='cm'; grid=ft_prepare_sourcemodel(cfg); 9. the forward model is computed as above. Now we need to compute the leadfields for the native-space grid. Before doing so, we transform the positions so that they include the alignment of the native-space anatomical to the digitized headshape. vgridmask=spm_vol((['r',maskforgridfn]); %the native-space grid mask at 7. Mgridmask=vgridmask.mat; vanat=spm_vol(anatfn); %the ac-centered anatomical for this subject Manat=vanat.mat; Mheadshapes=MRI_HeadShapes.transformorig; %form MRI-to-headshape alignment M1=Mgridmask; M2=Mheadshapes; M3=Manat; dim=grid.dim; %native-space grid from 8. [X,Y,Z] = ndgrid(1:dim(1), 1:dim(2), 1:dim(3)); posvox=[X(:) Y(:) Z(:)]; M=M2*inv(M3)*M1; grid.pos = ft_warp_apply(M,posvox)/10; Now we can compute leadfields using grid 10. when done with our native-space analyses we can finally dartel-normalize the contrasts/encoding/whatever measures of interest from native to group space. Note, this also uses a smoothing of the dartel-normalized images, which boosts SNR further than what already done by the improved Dartel-based alignment of anatomies. We have two options here. 10.a. we Dartel-normalize native-space stuff then smooth batch.spm.tools.dartel.crt_warped %dartel normalize THEN batch.spm.spatial.smooth %smooth 10.b. directly normalize to MNI (includes a smoothing step): batch.spm.tools.dartel.mni_norm The SPM community prefers 10.a. Note that with this option the Dartel normalization is slower than with option 10.b. Also, 10.a. produces volumes with the same resolution of the Dartel template, which should be overkill for MEG. Ideally, one would resample the output of 10.a. to a target resolution and find out how 10.a. can be sped up.


Bruno L. Giordano - 2017-01-24 15:26:11 +0100

Created attachment 826 the resize function used in comment 17


Robert Oostenveld - 2017-01-24 17:07:13 +0100

I searched through the code, there were quite some inconsistencies which needed to be fixed. SPM2 turned out to be partially broken, and sometimes SPM8 was forced on the path (even if spm2 or spm12 were already on the path). I pimped the test_old_spm8 script, which I think should in principle be able to work with either spm version. Note that it does not work yet for spm12. I added the changes to my bug2793-spm12 branch on github. @Arjen can you review that branch and see whether it works for you? If it does, we should continue testing that it works for all other existing spm use cases. mac011> git commit -a [bug2793-spm12 4500931] FIX - various changes to improve the support for SPM12 and the mini version that is diccussed in http://bugzilla.fieldtriptoolbox.org/show_bug.cgi?id=2793 16 files changed, 149 insertions(+), 104 deletions(-) mac011> git push X11 forwarding request failed on channel 0 Counting objects: 40, done. Delta compression using up to 4 threads. Compressing objects: 100% (40/40), done. Writing objects: 100% (40/40), 5.33 KiB | 0 bytes/s, done. Total 40 (delta 36), reused 0 (delta 0) remote: Resolving deltas: 100% (36/36), completed with 28 local objects. To github.com:robertoostenveld/fieldtrip.git 5906965..4500931 bug2793-spm12 -> bug2793-spm12


Arjen Stolk - 2017-01-24 21:18:00 +0100

(In reply to Robert Oostenveld from comment #19) Hey Robert, there's a test_spm12 in my pull request, which is also based on test_spm8_old. It tests some of the new spm12 functionalities, in additional to older spm8 functionalities. There's no way for me to do more in-depth testing than simply using the minispm12 branch as I have been doing for a short amount of time. More thorough testing would require running the test suite on the donders cluster? Another option would be to compare external/spm8 and external/spm12 and see where the functions that are currently in spm8 and not in spm12 are used.


Arjen Stolk - 2017-01-24 23:09:32 +0100

(In reply to Arjen Stolk from comment #20) "Another option would be to compare external/spm8 and external/spm12 and see where the functions that are currently in spm8 and not in spm12 are used." > Although spm_coreg (spm12) used to be spm_normalize (spm2/8). And spm_invdef is no longer in the main folder (as it is in external/spm8). But at the least, in conjunction with the output of the ft's testsuite, it could help determine what functions need copying over still for full integration with spm12.


Arjen Stolk - 2017-01-25 06:56:14 +0100

Pulled your branch and ran the test, Robert (test_old_spm8). As expected ft_volumenormalize and ft_volumesegment do not yet support spm12: > ft_volumenormalize with spm12 Reference to non-existent field 'template'. Error in ft_volumenormalise (line 158) if isempty(cfg.template) Error in test_old_spm8 (line 37) n12 = ft_volumenormalise(cfg, mri); > ft_volumesegment with spm12: the input is volume data with dimensions [256 256 176] Error using ft_volumesegment (line 436) unsupported SPM version Everything else ran fine. Also tried coregistration using ft_volumerealign, which ran through for all 3 versions. spm_coreg (used with spm12), however, took just a couple of seconds whereas spm_normalise (used with spm2/8) took longer than 15 mins somehow. clear fun; cfg = []; cfg.method = 'spm'; cfg.coordsys = 'tal'; % arjsto test mri is in tal cfg.spmversion = 'spm2'; r2 = ft_volumerealign(cfg, mri, mri); rmpath(spm('dir')); clear fun; cfg.spmversion = 'spm8'; r8 = ft_volumerealign(cfg, mri, mri); rmpath(spm('dir')); clear fun; cfg.spmversion = 'spm12'; r12 = ft_volumerealign(cfg, mri, mri); rmpath(spm('dir'));


Arjen Stolk - 2017-01-25 07:03:13 +0100

arjens-MacBook-Pro:fieldtrip arjsto$ git add -A arjens-MacBook-Pro:fieldtrip arjsto$ git status On branch bug2793-spm12 Your branch is up-to-date with 'roboos/bug2793-spm12'. Changes to be committed: (use "git reset HEAD ..." to unstage) modified: test/test_old_spm8.m arjens-MacBook-Pro:fieldtrip arjsto$ git commit -m 'ONGOING DEV' [bug2793-spm12 b8a19a0] ONGOING DEV 1 file changed, 25 insertions(+), 5 deletions(-) arjens-MacBook-Pro:fieldtrip arjsto$ git push origin bug2793-spm12 Enter passphrase for key '/Users/arjsto/.ssh/id_rsa': Counting objects: 82, done. Delta compression using up to 4 threads. Compressing objects: 100% (82/82), done. Writing objects: 100% (82/82), 156.20 KiB | 0 bytes/s, done. Total 82 (delta 67), reused 0 (delta 0) remote: Resolving deltas: 100% (67/67), completed with 36 local objects. To git@github.com:StolkArjen/fieldtrip.git * [new branch] bug2793-spm12 -> bug2793-spm12 </p>

Arjen Stolk - 2017-01-25 07:13:56 +0100

ft_volumenormalise and ft_volumesegment need some adjustment work still. In case of the former it's just a matter of finding and adding the template (e.g. same as spm8's 'T1.nii'?) but the latter requiring function-specific intelligence, i.e. about tissue prob maps.


Robert Oostenveld - 2017-01-25 10:10:36 +0100

(In reply to Arjen Stolk from comment #24) sorry, I had missed test_spm12 and therefore started on test_old_spm8. I will rename that to test_spm8. I consider it desirable to not change the default SPM version from 8 to 12 anywhere yet. We first have to ensure that SPM12 works on request, and if so, we can consider making it the default. This applies both to the high-level and low-level code. I have pulled the changes from your branch, and continue from there: --- mac011> git commit [bug2793-spm12 329a121] ENH - renamed test_old_spm8 to test_spm8, removed the spm12 parts of that script (see test_spm12 for that). Made the top-level documentation of cfg.spmversion consistent for spm2/spm8/spm12, and made the call to ft_hastoolbox consistent. 7 files changed, 33 insertions(+), 68 deletions(-) rename test/{test_old_spm8.m => test_spm8.m} (71%) --- I am still concerned about SPM version conflicts. Hence I will change the path handling in the private functions into this ft_hastoolbox('spm8up', 3) || ft_hastoolbox('spm2', 1); This checks whether 8 or 12 is available. If so, it does nothing. If 8 or 12 are not available, it tries to add 8. If that fails (silently), it tries to add 2. If that fails, it throws an error. This is consistent with spm8 being the default in the top-level functions, but allows spm12 to be used consistently as well. --- mac011> git commit [bug2793-spm12 ea24956] ENH - ensure consistent path handling for spm, accept spm12 as correct version, add spm8 when no version is available yet. See http://bugzilla.fieldtriptoolbox.org/show_bug.cgi?id=2793 17 files changed, 34 insertions(+), 55 deletions(-) mac011> git commit -a [bug2793-spm12 84726dd] ENH - additional changes to make spm version handling consistent, see http://bugzilla.fieldtriptoolbox.org/show_bug.cgi?id=2793 3 files changed, 97 insertions(+), 103 deletions(-) rewrite fileio/private/volumewrite_spm.m (87%) ---


Robert Oostenveld - 2017-01-25 10:22:18 +0100

Since spm8 is still the default (now even better than before) and spm12 is purely optional (it is not forced on the path anywhere), it is safe to merge this into the release. This allows for easier testing and extending, e.g. based on the suggestions of Bruno (sorry for ignoring you so far...) I created this PR https://github.com/fieldtrip/fieldtrip/pull/308 and have merged. The development branches can (and should) be deleted to avoid confusion. What still needs to be done is to review the documentation on the wiki, and to test and further enhance support for spm12.


Bruno L. Giordano - 2017-01-25 10:40:20 +0100

No worries. SPM12 is anyway important mostly for the new segmentation approach, which is present also in spm8. The other changes are Dartel-related, and I am discussing them with Jan-Mathijs on another bug.


Arjen Stolk - 2017-01-25 18:47:48 +0100

Nice work, Robert. I agree with you spm8 should stay the default for now, and spm12 is gradually phased in while remaining functionalities are also implemented (i.e. ft_volumesegment and ft_volumenormalise). A brief test using spm12 followed by a call to a spm8-only functionality without specifying what version to use, was successful: cfg = []; cfg.method = 'spm'; cfg.spmversion = 'spm12'; cfg.spm.coostfun = 'nmi'; cfg.coordsys = 'tal'; r12 = ft_volumerealign(cfg, mri, mri2); cfg = []; cfg.nonlinear = 'no'; n8 = ft_volumenormalise(cfg, mri); % note spm8 is not specified by is switched to anyway And sorry indeed, Bruno. I guess now with this critical transformation finally out of the way, we can start adding new functionalities. I'm closing this bug for now, and suggest you start a new thread for the dartel application in order to keep things a bit organized (I violated this unwritten rule myself as you can see).


Arjen Stolk - 2017-01-25 18:52:45 +0100

Oh right, of course 'the captain' beat me to it: http://bugzilla.fieldtriptoolbox.org/show_bug.cgi?id=3228


Robert Oostenveld - 2019-08-10 12:35:03 +0200

This closes a whole series of bugs that have been resolved (either FIXED/WONTFIX/INVALID) for quite some time. If you disagree, please file a new issue on https://github.com/fieldtrip/fieldtrip/issues.


Robert Oostenveld - 2019-08-10 12:41:14 +0200

This closes a whole series of bugs that have been resolved (either FIXED/WONTFIX/INVALID) for quite some time. If you disagree, please file a new issue on https://github.com/fieldtrip/fieldtrip/issues.