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

Schoffelen, J.M. (Jan Mathijs) jan.schoffelen at donders.ru.nl
Fri Apr 3 19:02:26 CEST 2020


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://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://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/20200403/15fdec57/attachment.htm>


More information about the fieldtrip mailing list