Back to the main page.
Bug 3125 - ft_electroderealign with method='fiducial' does not work properly for me
Status | CLOSED FIXED |
Reported | 2016-05-11 17:17:00 +0200 |
Modified | 2016-06-14 16:14:51 +0200 |
Product: | FieldTrip |
Component: | core |
Version: | unspecified |
Hardware: | PC |
Operating System: | Windows |
Importance: | P5 normal |
Assigned to: | Robert Oostenveld |
URL: | |
Tags: | |
Depends on: | |
Blocks: | |
See also: |
Daniel Miklody - 2016-05-11 17:17:21 +0200
I encounter the following problem: I want to align electrodes (standard10_05.elc) autmoatically based on fiducials to an individual head but what ft_electroderealign does is bring it further away (it says so in it's own output (line 467 fprintf('mean distance between fiducials prior to realignment %f, after realignment %f\n', dpre, dpost);) I have made the warps manually and figured out that line 452 (norm.m = elec2common / templ2common;) is the problem in my case. If I use ft_warp_apply sequentially first with elec2common and then with inv(templ2common) it works well and the results are correct. But this way the electrodes are tilted into the wrong direction.
Robert Oostenveld - 2016-05-11 17:44:18 +0200
can you share some data that allows us to reproduce the situation you encounter? That will help us in figuring out whether the issue is with the configuration, the data, or with the FT code.
Jan-Mathijs Schoffelen - 2016-05-12 08:48:31 +0200
to add: are you sure that the fiducials are expressed in the same coordinate system as the electrodes?
Daniel Miklody - 2016-05-12 09:48:05 +0200
Created attachment 791 Boundary file, fiducials and template electrode set in a ZIP Good morning. Here are the files. Yes, if I plot the fiducials or the headshape ( new_bnd(1) ) together with the template electrodes set, they are not far from each other. Anyway I guess it shouldn't matter because they are first transformed to a common coordinate system and than to the target one. The code I use that produces the error is as follows: load('bnd4_1922_corrected_fiducials.mat') load('bnd4_1922_corrected.mat') elec10_05=ft_read_sens('standard_1005.elc'); cfg=[]; cfg.method='fiducial'; cfg.target.elecpos(1,:)=NAS; cfg.target.elecpos(2,:)=LPA; cfg.target.elecpos(3,:)=RPA; cfg.target.chanpos=cfg.target.elecpos; cfg.target.label={'NZ','LPA','RPA'}; cfg.target.unit='m'; cfg.elec=elec10_05; elec=ft_convert_units(ft_electroderealign(cfg),'m'); figure ft_plot_mesh(new_bnd(1)) ft_plot_sens(elec) If I use the cfg as specified in the help: If you want to realign the EEG electrodes using anatomical fiducials, the template has to contain the three fiducials, e.g. cfg.target.pos(1,:) = [110 0 0] % location of the nose cfg.target.pos(2,:) = [0 90 0] % location of the left ear cfg.target.pos(3,:) = [0 -90 0] % location of the right ear cfg.target.label = {'NAS', 'LPA', 'RPA'} I got the following error: Undefined function or variable "lab". Error in channelposition (line 314) n = size(lab,2); Error in ft_datatype_sens (line 328) [chanpos, chanori, lab] = channelposition(sens); Error in ft_electroderealign (line 242) tmp(i) = ft_convert_units(ft_datatype_sens(target(i)), elec.unit); The code that works is as follows: templ2common = ft_headcoordinates(NAS, LPA, RPA); elec2common = ft_headcoordinates(elec10_05.chanpos(3,:)/1000, elec10_05.chanpos(1,:)/1000, elec10_05.chanpos(2,:)/1000); elec10_05_warp=ft_convert_units(elec10_05,'m'); elec10_05_warp.elecpos=ft_warp_apply(elec2common,elec10_05_warp.elecpos); elec10_05_warp.elecpos=ft_warp_apply(inv(templ2common ),elec10_05_warp.elecpos); elec10_05_warp.chanpos=elec10_05_warp.elecpos; figure ft_plot_mesh(new_bnd(1)) ft_plot_sens(elec10_05_warp) which is using 2 consequent transofrmation with first templ2common and then elec2common instead of one transformation with elec2common / templ2common.
Daniel Miklody - 2016-05-12 10:09:30 +0200
Hey I think I just realized what the problem is! You are using the transpose of the transformation matrix in ft_warp_apply. You would have to do norm.m=templ2common\elec2common; in line 452 of ft_electrodrealign instead of norm.m = elec2common / templ2common; to make it work. If you transpose a matrixmultiplication, the order changes : (AB)' = B'A'.
Robert Oostenveld - 2016-05-12 21:47:20 +0200
(In reply to Daniel Miklody from comment #4) thanks for the test data, I can reproduce the problem. The input specification is fine. And furthermore thanks for locating the problem and fixing it. The forward and back slash as matrix operations are always tricky. I just made a number of commits that solve the issue. While at it, I also reorganised some internal code. Furthermore, I added the 'project' method (which was planned anyway). Since your electrodes are very loose around the head after realigning, you should give method=project a try. See fieldtrip/test/inspect_bug3125 as example, which is based on your data (I keep it for reference and future testing).
Robert Oostenveld - 2016-05-12 21:47:29 +0200
mbp> git push upstream master Counting objects: 5, done. Delta compression using up to 2 threads. Compressing objects: 100% (5/5), done. Writing objects: 100% (5/5), 916 bytes | 0 bytes/s, done. Total 5 (delta 3), reused 0 (delta 0) To git@github.com:fieldtrip/fieldtrip.git 8e8c53e..d9688be master -> master
Daniel Miklody - 2016-05-17 09:00:03 +0200
Alrighty! Good to be helpful ;) Thanks also for adding the project method, I was already using it but good to have it in a standard interafece fashion!! Thaanks