[FieldTrip] ft_sourcemovie - producing 'contemporary art' instead of a brain

Emilie Caspar ecaspar at ulb.ac.be
Tue Apr 14 13:44:26 CEST 2020


Dear Jan-Mathijs,

Thank you for those pointers because indeed now I have obtained a nice brain instead of my contemporary piece of art (see Figure attached!) (I write below the full code, if others would find it relevant as well).

I am however struggled to find out how to extract the coordinates of the source reconstruction in order to use them as a ROI on MRI data. If I use the ft_sourcemovie, I can obtain the indications of the coordinates when I click on a specific location. But I guess it’s not the most proper method?

I have used the ft_sourceplot function based on an atlas that I uploaded in the templates. However, it does not plot the data, only a template brain with unknown as X Y and Z coordinates. 

atlas = ft_read_atlas('ROI_MNI_V4.nii');            
statint.coordsys = 'mni';
cfg               = [];
cfg.method        = 'ortho';
cfg.funparameter  = 'stat';
cfg.maskparameter = 'mask';
cfg.locationcoordinates = 'head';
cfg.atlas         = atlas;
cfg.location = 'max';
cfg.funcolorlim   = [-5 5];
cfg.funcolormap = 'jet';
ft_sourceplot(cfg,sdDIFFC);
 
I also used the ft_volumelookup function as follow

cfg = [];
cfg.atlas = atlas;
cfg.inputcoord = 'mni';
cfg.maskparameter = 'inside';
labels = ft_volumelookup(cfg,sdDIFFC);


But it fails to recognize the atlas

Do you want to change the anatomical labels for the axes [Y, n]? Y
What is the anatomical label for the positive X-axis [r, l, a, p, s, i]? r
What is the anatomical label for the positive Y-axis [r, l, a, p, s, i]? a
What is the anatomical label for the positive Z-axis [r, l, a, p, s, i]? s
Is the origin of the coordinate system at the a(nterior commissure), i(nterauricular), n(ot a landmark)? n
Warning: The field cfg.inputcoord is forbidden, it will be removed from your configuration
 
 In ft_checkconfig at line 224
 In ft_volumelookup at line 119

Error using atlas_lookup (line 89)
the mismatch between the coordinate system in the atlas and the coordinate system in the data cannot be
resolved

Therefore, I was wondering what the most reliable option is to exact coordinates from the EEG source reconstruction than I can later implement as ROI in MRI data. Any suggestions is welcome!

Thanks a lot for the help, 

Emilie



—— Code used:

load Subject01_sourcemodel_15684;
headmodel = ft_read_headmodel('headmodel/standard_bem.mat');
electr_pos=ft_read_sens('Biosemi-Cap64.sfp');

load('GA_C_Shock.mat')
load('GA_C_NOShock.mat')

cfg = [];
cfg.method = 'interactive';
cfg.elec = electr_pos;
cfg.headshape = headmodel.bnd(1); %1 = skin
elec = ft_electroderealign(cfg, electr_pos);

cfg         = [];
cfg.elec = elec;   % sensor information
cfg.channel = elec.label;%;  % the used channels
cfg.sourcemodel    = sourcemodel;   % source points
cfg.headmodel = headmodel;   % volume conduction model
cfg.singleshell.batchsize = 5000; % speeds up the computation
leadfield   = ft_prepare_leadfield(cfg);

cfg               = [];
cfg.method        = 'mne';
cfg.elec = elec;
cfg.grid          = leadfield;
cfg.headmodel     = headmodel;
cfg.mne.prewhiten = 'yes';
cfg.mne.lambda    = 3;
cfg.mne.scalesourcecov = 'yes';
source_C_Shock = ft_sourceanalysis(cfg, GA_C_Shock);
source_C_Noshock = ft_sourceanalysis(cfg, GA_C_NOshock);

cfg = [];
cfg.projectmom = 'yes';
sd_C_SHOCK  = ft_sourcedescriptives(cfg,source_C_Shock);
 
cfg = [];
cfg.projectmom = 'yes';
sd_C_NOshock = ft_sourcedescriptives(cfg, source_C_Noshock);
 

 
sdDIFFC         = sd_C_SHOCK;
sdDIFFC.avg.pow = sd_C_SHOCK.avg.pow - sd_C_NOshock.avg.pow;
 

figure
m=sdDIFFC.avg.pow(:,500); % plotting the result at the 450th time-point that is
                         % 500 ms after the zero time-point       
ft_plot_mesh(source_FR_Shock, 'vertexcolor', m);
view([180 0]); 
h = light; 
set(h, 'position', [0 1 0.2]); 
lighting gouraud; 
material dull







---------------------------------------------
Emilie Caspar, Ph.D
 
CO3, Centre de Recherche Cognition et Neurosciences (CRCN), ULB 
Voice : +32 2 650 32 95 
mail : ecaspar at ulb.ac.be
office: DB10-138 

Social Brain Lab, Netherlands Institute for Neuroscience (NIN), KNAW
mail : e.caspar at nin.knaw.nl

> Le 3 avr. 2020 à 19:02, Schoffelen, J.M. (Jan Mathijs) <jan.schoffelen at donders.ru.nl> a écrit :
> 
> Hi Emilie,
> 
> Hmmm, a few pointers:
> 
> Yes, it seems that you are expecting something from ft_sourceinterpolate that the function cannot deliver. In the pasted code you specify that you want to interpolate the parameter ‘elec.chanpos’. This is incorrect. If anything, you can only meaningfully interpolate parameters that are defined with a scalar per source dipole position, and in addition only using fields in a structure that are available in the input data structure. since source_C_Shock by construction should not contain an elec field, this is never going to work. In addition, the elec.chanpos field does not map onto the source dipole positions, so this is the second reason why this is never going to work.
> Also, if I am not mistaken ft_sourceinterpoalte cannot deal with data that are vectors (e.g. source activity time courses) for each source position, so even if you would specify cfg.parameter to be ‘pow’, or ‘avg.pow’ this will probably not work.
> 
> Once again, indeed the tutorial mentions the ’tri’ field as a prerequisite to be able to visualize data in ft_sourcemovie. Since you created your sourcemodel to be a 3D grid, which is volumetric in nature, and not the expected surface description (that is based on a combination of vertex positions (in fieldtrip speak: pos) and faces (in fieldtrip speak: tri)) the visualization you wish for does not work. Hence Eelke’s suggestion to use ft_sourceinterpolate first, which I question as per my comment above.
> 
> Besides, in general I would recommend against using a 3D grid as a sourcemodel when using a distributed inverse modelling approach. The reason for this is that activity is going to be ‘mapped’ onto locations that does not make sense a priori (white matter). 
> 
> Finally, your current results containing a lot of NaNs is perfectly fine, since this corresponds to source dipole locations that lie outside the volume of interest, i.e. outside the head.
> 
> Best wishes,
> Jan-Mathijs
> 
> 
>> On 2 Apr 2020, at 17:33, Emilie Caspar <ecaspar at ulb.ac.be <mailto:ecaspar at ulb.ac.be>> wrote:
>> 
>> Dear Elke and Jan-Mathijs,
>> 
>> Thank you for your answers. So indeed I now understand the problem, but I still have issues to solve that problem. It’s probably something simple to solve but I do not find it. Basically, I have now tried to use the ft_sourceinterpolate, as suggested. As far as I understand, this has to be done after the ft_sourceanalysis. However, I constantly have an issue with cfg_parameters, which should be the positions of the electrodes. I run the following code (full code below):
>> 
>> cfg = [];
>> cfg.parameter = 'elec.chanpos';
>> cfg.interpmethod  = 'nearest';
>> interp = ft_sourceinterpolate(cfg, source_C_Shock, sourcemodel)
>>  
>> I get the following error message: "Reference to non-existent field 'elec’. », which I do not get since I do have my ‘elec’ file which is indeed opened, with a .chanpos that contains the positions of the electrodes. 
>> 
>> Perhaps I am doing something wrong with ft_sourceinterpolate. But in fact I am also worried about the fact that the file which results from the ft_sourceanalysis has lots of NaN (see screenshot in attachement) and I am not sure it should be the case or if I should have obtained full data in each case. From the tutorials, the source model have a .tri but I don’t have one in the source model I have created. Perhaps it may also be the source of the issue?
>> 
>> Thank you in advance for your time!
>> 
>> Emilie
>> 
>> <NaN.png>
>> 
>> 
>> load biosemi64.mat
>> q=angles;
>>  
>> ph = cell2mat(q(:,2));
>> th = cell2mat(q(:,3));
>> x = sin(ph*pi/180) .* cos(th*pi/180);
>> y = sin(ph*pi/180) .* sin(th*pi/180);
>> z = cos(ph*pi/180);
>>  
>> plot3(x, y, z, '.');
>> elec.label = q(:,1);
>> elec.pnt = [x y z];
>>  
>> cfg.sourcemodel.pos = elec.pnt;
>> sourcemodel = ft_prepare_sourcemodel(cfg);
>>  
>> headmodel = ft_read_headmodel('headmodel/standard_bem.mat');
>> %electr_pos=ft_read_sens('Biosemi-Cap64.sfp');
>>  
>> %% realign electrodes to headmodel
>> cfg = [];
>> cfg.method = 'interactive';
>> cfg.elec = elec;
>> cfg.headshape = headmodel.bnd(1); %1 = skin
>> elec = ft_electroderealign(cfg);
>>  
>> %save new electrodes
>> save elec64.mat elec
>>  
>> %ERPsAll.elec = ft_read_sens('Biosemi-Cap64.sfp');
>>  
>> % Prepare leadfield
>> cfg                 = [];
>> cfg.elec            = elec;
>> cfg.headmodel             = headmodel;
>> cfg.reducerank      = 3;
>> cfg.resolution = 1;   % use a 3-D grid with a 1 cm resolution
>> cfg.sourcemodel.unit       = 'cm';
>> cfg.channel ={'all'};
>> leadfield = ft_prepare_leadfield(cfg);
>>  
>> %% mne
>> cfg              = [];
>> cfg.method       = 'mne'; %pcc: partial cannonical correlation/coherence
>> cfg.elec         = elec; %grid.cfg.elec;%
>> cfg.headmodel          = headmodel;
>> cfg.grid = leadfield;
>> %cfg.sourcemodel = sourcemodel;
>> % cfg.channel ={'all'};%, '-spmnas', '-spmlpa', '-spmrpa'};
>> cfg.mne.prewhiten = 'yes';
>> cfg.mne.lambda    = 3;
>> cfg.mne.scalesourcecov = 'yes';
>> %cfg.reducerank          = 2;
>>  
>> source_C_Shock = ft_sourceanalysis(cfg, GA_C_Shock);
>> source_C_Noshock = ft_sourceanalysis(cfg, GA_C_NOshock);
>> 
>> cfg = [];
>> cfg.parameter = 'elec.chanpos';
>> cfg.interpmethod  = 'nearest';
>> interp = ft_sourceinterpolate(cfg, source_C_Shock, sourcemodel)
>>  
>> 
>> cfg = [];
>> cfg.projectmom = 'yes';
>> sdShock  = ft_sourcedescriptives(cfg,source_C_Shock);
>> sdNoShock = ft_sourcedescriptives(cfg,source_C_Noshock);
>>  
>> sdDIFF         = sdNoShock;
>> sdDIFF.avg.pow = sdNoShock.avg.pow - sdShock.avg.pow;
>>  
>> save sd sdDIFF;
>>  
>> cfg = [];
>> cfg.funparameter = 'pow';
>> ft_sourcemovie(cfg,sdDIFF);
>> 
>> 
>> 
>> ---------------------------------------------
>> Emilie Caspar, Ph.D
>>  
>> CO3, Centre de Recherche Cognition et Neurosciences (CRCN), ULB 
>> Voice : +32 2 650 32 95 
>> mail : ecaspar at ulb.ac.be <mailto:ecaspar at ulb.ac.be>
>> office: DB10-138 
>> 
>> Social Brain Lab, Netherlands Institute for Neuroscience (NIN), KNAW
>> mail : e.caspar at nin.knaw.nl <mailto:e.caspar at nin.knaw.nl>
>> 
>>> Le 31 mars 2020 à 12:02, Eelke Spaak <e.spaak at donders.ru.nl <mailto:e.spaak at donders.ru.nl>> a écrit :
>>> 
>>> Hi Emilie,
>>> 
>>> To add to Jan-Mathijs' explanation of why this does not work: you can
>>> use ft_sourceinterpolate to interpolate your volumetric source data
>>> onto a surface, which you can then plot using ft_sourcemovie (or the
>>> newer, though still somewhat experimental, ft_sourceplot_interactive).
>>> 
>>> Best,
>>> Eelke
>>> 
>>> On Tue, 31 Mar 2020 at 11:07, Schoffelen, J.M. (Jan Mathijs)
>>> <jan.schoffelen at donders.ru.nl <mailto:jan.schoffelen at donders.ru.nl>> wrote:
>>>> 
>>>> Hi Emilie,
>>>> 
>>>> ft_sourcemovie has been designed to operate on source level data that is defined on a cortical surface based source model.
>>>> The code you pasted in suggests that you used a 3-dimensional grid as a sourcemodel. So this is never going to work.
>>>> Apparently, you managed to fool the function by post-hoc including a so-called ’tri’ field, which is the hallmark that fieldtrip uses to determine whether the sourcemodel geometry was a mesh or not.
>>>> However, there is no relation whatsoever between the specified triangulation (which you took from the headmodel) and the dipole positions at which your source activity has been estimated.
>>>> 
>>>> Best wishes,
>>>> Jan-Mathijs
>>>> 
>>>> 
>>>> On 31 Mar 2020, at 10:42, Emilie Caspar <ecaspar at ulb.ac.be <mailto:ecaspar at ulb.ac.be>> wrote:
>>>> 
>>>> Dear all,
>>>> 
>>>> I am trying to compute a source reconstruction of different ERPs between two experimental conditions. Well, good news is that the script ‘works’, but the issue is that I am producing contemporary art instead of a brain with ft_sourcemovie (see figure in attachement). The headmodel I used is the standard one available for download. The leadfield I built seems to look like a brain with a correct positions of the electrodes (see also figure in attachement).
>>>> 
>>>> I really have no cue about how I produced such output with ft_sourcemovie and what could possibly be the issue (code is below). If someone can help transforming this to a brain? ;-)
>>>> The only thing that differs (I think) from the tutorial is that I don’t have a headmodel.tri but rather a headmodel.bnd.tri. Don’t know if it makes any difference. Perhaps the sourcespace defined in the tutorial is something different?
>>>> 
>>>> Thank you,
>>>> 
>>>> Emilie
>>>> 
>>>> <ft_sourcemovie.png><leadfield.png><ft_plot_mesh.png>
>>>> 
>>>> CODE
>>>> 
>>>> q=biosim64;
>>>> ph = cell2mat(q(:,2));
>>>> th = cell2mat(q(:,3));
>>>> x = sin(ph*pi/180) .* cos(th*pi/180);
>>>> y = sin(ph*pi/180) .* sin(th*pi/180);
>>>> z = cos(ph*pi/180);
>>>> 
>>>> plot3(x, y, z, '.');
>>>> elec.label = q(:,1);
>>>> elec.pnt = [x y z];
>>>> 
>>>> cfg.sourcemodel.pos = elec.pnt;
>>>> sourcemodel = ft_prepare_sourcemodel(cfg);
>>>> 
>>>> headmodel = ft_read_headmodel('headmodel/standard_bem.mat');
>>>> 
>>>> % realign electrodes to headmodel
>>>> cfg = [];
>>>> cfg.method = 'interactive';
>>>> cfg.elec = elec;
>>>> cfg.headshape = headmodel.bnd(1); %1 = skin
>>>> elec = ft_electroderealign(cfg);
>>>> 
>>>> %save new electrodes
>>>> save elec64.mat elec
>>>> 
>>>> ERPsAll.elec = ft_read_sens('elec64.mat’);
>>>> 
>>>> % Prepare leadfield
>>>> cfg                 = [];
>>>> cfg.elec            = ERPsAll.elec;
>>>> cfg.vol             = headmodel;
>>>> cfg.reducerank      = 3;
>>>> cfg.grid.resolution = 1;   % use a 3-D grid with a 1 cm resolution
>>>> cfg.grid.unit       = 'cm';
>>>> cfg.channel ={'all'};
>>>> leadfield = ft_prepare_leadfield(cfg);
>>>> 
>>>> 
>>>> 
>>>> %%mne
>>>> cfg              = [];
>>>> cfg.method       = 'mne'; %pcc: partial cannonical correlation/coherence
>>>> cfg.elec         = ERPsAll.elec; %grid.cfg.elec;%
>>>> cfg.headmodel          = headmodel;
>>>> cfg.grid = leadfield;
>>>> %cfg.sourcemodel = sourcemodel;
>>>> % cfg.channel ={'all'};%, '-spmnas', '-spmlpa', '-spmrpa'};
>>>> cfg.mne.prewhiten = 'yes';
>>>> cfg.mne.lambda    = 3;
>>>> cfg.mne.scalesourcecov = 'yes';
>>>> %cfg.reducerank          = 2;
>>>> 
>>>> source_C_Shock = ft_sourceanalysis(cfg, GA_C_Shock);
>>>> source_C_Noshock = ft_sourceanalysis(cfg, GA_C_NOshock);
>>>> 
>>>> save source_C_Shock.mat source_C_Shock
>>>> save source_C_Noshock.mat source_C_Noshock
>>>> 
>>>> bnd.pos = headmodel.bnd.pos;
>>>> bnd.tri = headmodel.bnd.tri;
>>>> 
>>>> m=source_C_Shock.avg.pow(:,450);
>>>> %timeN1 = [1232:1301];timeP3 = [1722:1927];timeeLPP = [1928:2356];timelLPP = [2357:2868];
>>>> ft_plot_mesh(bnd, 'vertexcolor', m);
>>>> view([180 0]); h = light; set(h, 'position', [0 1 0.2]); lighting gouraud; material dull
>>>> 
>>>> cfg = [];
>>>> cfg.projectmom = 'yes';
>>>> sdShock  = ft_sourcedescriptives(cfg,source_C_Shock);
>>>> sdNoShock = ft_sourcedescriptives(cfg,source_C_Noshock);
>>>> 
>>>> sdDIFF         = sdNoShock;
>>>> sdDIFF.avg.pow = sdNoShock.avg.pow - sdShock.avg.pow;
>>>> sdDIFF.tri = headmodel.bnd.tri;
>>>> 
>>>> save sd sdDIFF;
>>>> 
>>>> cfg = [];
>>>> cfg.funparameter = 'pow';
>>>> %cfg.method       = 'surface';
>>>> ft_sourcemovie(cfg,sdDIFF);
>>>> 
>>>> 
>>>> ---------------------------------------------
>>>> Emilie Caspar, Ph.D
>>>> 
>>>> CO3, Centre de Recherche Cognition et Neurosciences (CRCN), ULB
>>>> Voice : +32 2 650 32 95
>>>> mail : ecaspar at ulb.ac.be <mailto:ecaspar at ulb.ac.be>
>>>> office: DB10-138
>>>> 
>>>> Social Brain Lab, Netherlands Institute for Neuroscience (NIN), KNAW
>>>> mail : e.caspar at nin.knaw.nl <mailto:e.caspar at nin.knaw.nl>
>>>> 
>>>> _______________________________________________
>>>> fieldtrip mailing list
>>>> https://mailman.science.ru.nl/mailman/listinfo/fieldtrip <https://mailman.science.ru.nl/mailman/listinfo/fieldtrip>
>>>> https://doi.org/10.1371/journal.pcbi.1002202 <https://doi.org/10.1371/journal.pcbi.1002202>
>>>> 
>>>> 
>>>> _______________________________________________
>>>> fieldtrip mailing list
>>>> https://mailman.science.ru.nl/mailman/listinfo/fieldtrip
>>>> https://doi.org/10.1371/journal.pcbi.1002202
>>> 
>>> _______________________________________________
>>> fieldtrip mailing list
>>> https://mailman.science.ru.nl/mailman/listinfo/fieldtrip <https://mailman.science.ru.nl/mailman/listinfo/fieldtrip>
>>> https://doi.org/10.1371/journal.pcbi.1002202 <https://doi.org/10.1371/journal.pcbi.1002202>
>> 
>> _______________________________________________
>> fieldtrip mailing list
>> https://mailman.science.ru.nl/mailman/listinfo/fieldtrip <https://mailman.science.ru.nl/mailman/listinfo/fieldtrip>
>> https://doi.org/10.1371/journal.pcbi.1002202
> 
> _______________________________________________
> fieldtrip mailing list
> https://mailman.science.ru.nl/mailman/listinfo/fieldtrip
> https://doi.org/10.1371/journal.pcbi.1002202

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.science.ru.nl/pipermail/fieldtrip/attachments/20200414/472f1ee8/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: SourceLoc.jpg
Type: image/jpeg
Size: 98533 bytes
Desc: not available
URL: <http://mailman.science.ru.nl/pipermail/fieldtrip/attachments/20200414/472f1ee8/attachment.jpg>


More information about the fieldtrip mailing list