Fieldtrip [1] includes a template headmodel based on the “Colin27” anatomical MRI. While this model is fine the way it is, there are some reasons why i do not like to use it.

Colin27 is not symetric and also only based on a single individual. This can cause problems when you visualize your sources on the MRI. Second, it is not a common template  and this causes problems when you want to use a specific atlas, maybe more in tune with your research question. For example, FSL comes with a larg set of atlases, but they are all geared towards the ICBM152! It would make life easier if one could use a template headmodel which can easily use these atlases. So i made one, and i want to share it with you.

I used the „MNI152_T1_0.5mm.nii“  template included in FSL. Using Fieldtrips functions, i performed a segmentation, estimated a boundary triangle mesh and finally used the dipoli-method to construct a headmodel [2]. You can find the code below. If you want to understand the process better, consider taking a look at fieldtrips tutorial on headmodel construction.

Put Short:Take a look, and feel free to download the symetric_headmodel.
Code for Construction
I used the following code for construction the headmodel.


[mri]               = ft_read_mri('MNI152_T1_0.5mm.nii');

mri.coordsys        ='MNI'
cfg                 = [];
cfg.brainthreshold  = 0.5;
cfg.scalpthreshold  = 0.15;
cfg.downsample      = 1; %no downsampling
cfg.units           = 'cm';
cfg.output          = {'brain' 'scalp' 'skull'};
seg                 = ft_volumesegment(cfg, mri);

cfg                 = [];
cfg.tissue          = {'scalp', 'skull', 'brain'};
cfg.numvertices     = [1000 1000 1000];
bnd                 = ft_prepare_mesh(cfg, seg);

% i enlarged / reduced the boundary mesh a little bit, because they were causing errors, probably due to overlapping
bnd(1).pnt          = bnd(1).pnt.*1.001
bnd(2).pnt          = bnd(2).pnt.*1
bnd(3).pnt          = bnd(3).pnt.*0.999

cfg                 = [];
cfg.method          = 'dipoli';
headmodel           = ft_prepare_headmodel(cfg, bnd);
headmodel           = ft_convert_units(headmodel,'cm');


alpha 0.1

Visual Inspection

In the comments, the topic of adapting the code for indivual MRIs was discussed. Important for a sucessful implementation is finding an error in one of the steps. If you want to inspect your steps, you can try the following code.


%variante #1 segmentation inspection
seg.anatomy         = mri.anatomy;
cfg                 = [];
cfg.funparameter    = 'brain';
cfg.funparameter    = 'scalp';
cfg.funparameter    = 'skull';

%variante #2 segmentation inspection
seg.anatomy         = mri.anatomy;
seg.trishells       = seg.scalp+2*seg.skull+3*seg.brain
cfg                 = [];
cfg.funparameter    = 'trishells';
cfg.funcolormap     = [1 0 0;0 1 0;0 0 1]

% mesh inspection
hold on
alpha 0.1

%headmodel inspection
ft_plot_vol(headmodel, 'edgecolor', 'none')
alpha 0.1
[1] Oostenveld R, Fries P, Maris E, Schoffelen J-M. FieldTrip: Open Source Software for Advanced Analysis of MEG, EEG, and Invasive Electrophysiological Data. Computational Intelligence and Neuroscience 2011;2011:1–9. doi:10.1155/2011/156869.
[2] Oostendorp TF, van Oosterom A. Source parameter estimation in inhomogeneous volume conductors of arbitrary shape. IEEE Trans Biomed Eng 1989;36:382–91. doi:10.1109/10.19859.
Robert Bauer

Written by Robert Bauer

Agricolab | Descendant of Latin 'agricola', farmer; Lab (colloquial) A laboratory



Hi Robert, I used your set up except changed the .nii file to a subject’s file I have and changed the method to ‚bemcp‘. When I do this the vertices on the skull do not end up working, a lot of holes appear. What would you recommend for the ‚bemcp‘ method?

Robert Bauer

Individual MRIs offer many challenges compared the smooth and averaged ICBM152.

MRI quality is important. For example, is the head completeley measured with a gap to the borders of the image? Are the boundaries of the head noisy? Smoothing, shifting or padding the image might be necessary to make it usable for segmentation. If you are certain its MNI, adding the field is a quick fix. Alternatively you might use ft_determine_coordsys or ft_volume_realign.

Possible is also that your segmentation (seg) or the mesh (bnd) is not good. you can check that visually; use either fieldtrip functions or imagesc and trimesh. Usually playing with the segmentation thresholds (ft_volume_segment) and the number of vertices or the method (ft_prepare_mesh) provides a fix.

If regardless of the mesh quality, bemcp is giving bad results, dipoli might, but it only runs in a linux environment.


Hi Robert, Thanks for your reply, I was able to check that indeed it is in MNI. What fieldtrip functions help you check the seg or mesh visually? Even when I am able to plot the mesh, I am not sure how to pick out the exact vertices in the mesh that are skewed and fix them.
I also wanted to ask you about eeg channels, do you recommend using the electrode map from the template? How do you extract the fiducial landmarks from the MRI for this? I’m sorry for all of the questions but I found your code and explanations to be much clearer than the tutorials. Thanks!

Robert Bauer

Dear Hassan,

I updated the post to include code for visual inspection of your segmentation, mesh and the final headmodel. For me, it was never necessary to correct the mesh by hand. I do believe such functions are not included in Fieldtrip, but Mathworks should have something for automatic mesh-correction. Usually, smoothing of the segmentation (you can change the parameter for ft_volume_segment) and changing the number of vertices or method (e.g. isosurface) for mesh creation was sufficient.

EEG channels depend on your setup. If you localized all electrodes individually, you should have relative coordinates. If you did use a 10/5 EEG cap, you can use the template coordinates (from fieldtrip\template\electrode\standard_1005.elc). If you used fiducials, you can use ft_electroderealign. Whatever you decide to use, ft_electroderealign always gives you the option for manual alignment with the headmodel. Additionally, you can use ft_plot_sens(elec,’style‘,’sk‘) to plot them together with the headmodel for visual inspection.

I hope my answers can help you. Good luck with the source reconstruction!

hassan aleem

Hi Robert,

Thanks very much for your answers they have been extremely helpful! The fieldtrip site should just link to this page :). May I ask how has your experience been with source reconstruction? I am about to embark on it now that I have the headmodel. If you have any tips I would greatly appreciate it!


related to my previous comment on reading .nii file. when I read in the subject with ft_read_mri, if I display ‚mri‘, it doesn’t give me a field for cordsys automatically, do I have to apply that on my own like you did?

hassan aleem

Hi Robert,

I had a question regarding ft_sourceplot, no matter when I try to use it (including exactly as you posted) I always get the error

Error using textscan
First input can not be empty. Expected a non-empty string or a valid file-id.

Error in issubfield (line 44)
t = textscan(f,’%s‘,’delimiter‘,‘.‘);

Error in ft_sourceplot (line 456)
hasmsk = issubfield(functional, cfg.maskparameter);

Could you please advise?


Robert Bauer

Hm. Apparently the function does not find your functional data. did you intitialize the cfg, i.e cfg = []; ? Also, did you specify the fieldname of the functional data as a string? That might solve your issue. If not, it’s rather hard to diagnose from afar – but might be your sourcedata (check the fields) or a bug in your fieldtrip version (download the most recent). Did you interpolate your sourcedata to the mri before trying to plot?

hassan aleem

Hi Robert.

I understand, allow me to provide you some more information. Yes I did initialize with cfg=[]; I am not sure what you mean by specifying it as a string, and yes I did interpolate before plotting. (perhaps the error is in the interpolation) let me paste the relevant part of the code below. Also a link with the script and variables is I really appreciate all of your help so far, I would be stuck so far behind. This is the topic of my lab rotation and you have been extremely helpful.

%have already read in the symmetric headmodel, aligned electrodes and done timelockanalysis
% running lcmv beamformer
cfg = [];
cfg.method = ‚lcmv‘;
cfg.grid = sourcemodel.cfg.grid; %template grid from fieldtrip’s sourcemodel
cfg.headmodel = headmodel;
cfg.lcmv.keepfilter = ‚yes‘;
cfg.lcmv.fixedori = ‚yes‘;

% source interpolation
cfg = [];
cfg.interpmethod = ’nearest‘; % I am not sure if this is the best parameter
cfg.parameter = ‚pow‘; % I don’t understand what this defines?
cfg.grid=sourcemodel.cfg.grid; %using the template grid provided by fieldtrip in template sourcemodel
sourceinterp_m0 = ft_sourceinterpolate( cfg, source_m0, seg);

cfg = [];
cfg.method = ‚ortho‘;
cfg.funcolorlim = ‚maxabs‘;
ft_sourceplot(cfg, sourceinterp_m0);
%when I do the above, it gives me the (line 456) error as I described before.

I am using the latest version of fieldtrip -20160309. And matlab R2015b. Thanks for your help.


Hey Robert, Just wanted to let you know that I was able to figure it out. Apparently the ‚issubfield‘ function was the problem, I changed it from that to the MatLab version ‚isfield‘ and everything worked.


Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.