[FieldTrip] Source fitting with template MRI/Headmodel
Tommy Wilson
tommy.wilson at med.einstein.yu.edu
Wed Jan 25 20:47:13 CET 2017
Oh! Whew. Well, at least there's that. (It's the small things, you know?)
But, doesn't that lead to another question? As you can see from the
topographies attached, the Attended topography is much higher in amplitude
than the unattended (they are on the same color scale). Perhaps this is a
moment when my intuition doesn't matter, but wouldn't you expect that the
source generating the Attended topography would have greater power than the
Unattended source? Or is there something I don't understand here?
Thanks again for taking the time to respond. I truly appreciate your help.
Best,
Tommy
On Wed, Jan 25, 2017 at 12:11 PM, Matt Craddock <m.p.craddock at leeds.ac.uk>
wrote:
> Sorry Tommy, I misread the sign of my results - they're the same as yours
> :) I get the NaNs plotting thing sometimes too, never totally sure why as
> it seems intermittent.
>
> Cheers,
> Matt
>
> On 25/01/2017 16:13, Tommy Wilson wrote:
>
>> Hi Matt,
>>
>> Thanks so much for your reply here!
>>
>> I believe I've correctly implemented your comments: I computed a common
>> filter by source analyzing the combined (read: averaged) data/covariance
>> matrix. In a second step, I used this filter to source localize each
>> condition separately. I subsequently contrasted the two conditions, but
>> I'm seeing that sourceU.avg.pow > sourceA.avg.pow at about 99% of the
>> voxels. I attached an image of the ft_sourceplot to this email. (I don't
>> know why the NaNs aren't masking appropriately, but I can figure that
>> out on my own time).
>>
>> I also attempted your quick and dirty solution to see if I could
>> reproduce that, and I'm seeing the same thing as above (sourceU.avg.pow
>>
>>> sourceA.avg.pow in 99% of voxels), which is exactly the opposite of
>>>
>> what you said you came up with. (The ft_sourceplot for this scenario
>> looks identical to the first, which is unsurprising--in both cases, we
>> used the average covariance matrix to construct the filters, so they
>> ought to be identical). I must be doing something wrong here, but alas,
>> I can't seem to put the pieces together.
>>
>> Any help/guidance you could provide would be deeply appreciated. I've
>> attached the updated script to this email (and printed it below for
>> posterity), and as before, the data can be found here
>> <https://www.dropbox.com/s/8w99ejwrzmwc5pt/Source_fitting_dump.mat?dl=0>.
>>
>>
>> Again, thank you for taking the time to respond.
>>
>> Best,
>>
>> Tommy
>>
>> --- CODE ---
>>
>> %% Source fitting protocol
>> % Fieldtrip path (to find template MRI)
>> ftdir = 'your\path\here\fieldtrip-20160309';
>>
>> % Average both conditions to generate common filter
>> M = ft_timelockgrandaverage(struct(),A,U);
>> M.cov = mean(cat(3,A.cov,U.cov),3);
>>
>> % Equate covariance matrices for now to rule out any differences in the
>> % source fit due to differences in covariances
>> % A.cov = U.cov;
>>
>> %%% Do the LCMV sourcefitting
>> cfg = [];
>> cfg.method = 'lcmv';
>> cfg.grid = leadfield;
>> cfg.vol = vol;
>> cfg.elec = elec;
>> cfg.lcmv.lambda = '15%';
>> cfg.lcmv.keepfilter = 'yes';
>> cfg.lcmv.fixedori = 'yes';
>> cfg.lcmv.projectnoise = 'yes';
>>
>> % Generate common filter
>> sourceM = ft_sourceanalysis(cfg,M);
>>
>> % Add the common filter to the cfg
>> cfg.grid.filter = sourceM.avg.filter;
>>
>> % Source fit the originals
>> sourceA = ft_sourceanalysis(cfg,A);
>> sourceU = ft_sourceanalysis(cfg,U);
>>
>> %%% Matt's quick and dirty version
>> % Replace A's cov matrix with an average of A.cov and U.cov
>> tmp = A.cov;
>> A.cov = mean(cat(3,tmp,U.cov),3);
>>
>> cfg = [];
>> cfg.method = 'lcmv';
>> cfg.grid = leadfield;
>> cfg.vol = vol;
>> cfg.elec = elec;
>> cfg.lcmv.lambda = '15%';
>> cfg.lcmv.keepfilter = 'yes';
>> cfg.lcmv.fixedori = 'yes';
>> cfg.lcmv.projectnoise = 'yes';
>>
>> % Generate common test filter
>> sourceA_common_test = ft_sourceanalysis(cfg,A);
>>
>> % Add common filter to configuration
>> cfg.grid.filter = sourceA_common_test.avg.filter;
>>
>> % Replace original covariance matrix
>> A.cov = tmp;
>>
>> % Now fit both A and U with the common test filter
>> sourceA_test = ft_sourceanalysis(cfg,A);
>> sourceU_test = ft_sourceanalysis(cfg,U);
>>
>>
>> %%% Attempt a contrast
>> % Create the contrasts
>> sourceContrast = sourceA;
>> sourceContrast.avg.pow = sourceA.avg.pow - sourceU.avg.pow;
>> sourceContrast_test = sourceA_test;
>> sourceContrast_test.avg.pow = sourceA_test.avg.pow - sourceU_test.avg.pow;
>>
>> % Gauge what percent of the contrast is negative (i.e. sourceU power >
>> % sourceA power)
>> perc_neg =
>> sum(sourceContrast.avg.pow(sourceContrast.inside(:))<0)./num
>> el(sourceContrast.avg.pow(sourceContrast.inside(:)));
>> perc_neg_test =
>> sum(sourceContrast_test.avg.pow(sourceContrast_test.inside(:
>> ))<0)./numel(sourceContrast_test.avg.pow(sourceContrast_test.inside(:)));
>>
>> %%% Visualize the output
>> % Load template MRI
>> mri = ft_read_mri([ftdir '\template\anatomy\single_subj_T1.nii']);
>>
>> % Interpolate source onto MRI
>> cfg = [];
>> cfg.parameter = 'avg.pow';
>> sourceContrast_interp = ft_sourceinterpolate(cfg, sourceContrast, mri);
>> sourceContrast_test_interp = ft_sourceinterpolate(cfg,
>> sourceContrast_test, mri);
>>
>> % Visualize with ft_sourceplot
>> cfg = [];
>> cfg.method = 'ortho';
>> cfg.funparameter = 'avg.pow';
>> cfg.funcolorlim = [-100 5];
>> cfg.maskparameter = cfg.funparameter;
>> ft_sourceplot(cfg, sourceContrast_interp);
>>
>> cfg = [];
>> cfg.method = 'ortho';
>> cfg.funparameter = 'avg.pow';
>> cfg.funcolorlim = [-100 5];
>> cfg.maskparameter = cfg.funparameter;
>> ft_sourceplot(cfg, sourceContrast_test_interp);
>>
>> On Tue, Jan 24, 2017 at 4:12 PM Matt Craddock <m.p.craddock at leeds.ac.uk
>> <mailto:m.p.craddock at leeds.ac.uk>> wrote:
>>
>> Hi Tommy,
>>
>> > % Equate covariance matrices for now to rule out any differences
>> in the
>> > % source fit due to differences in covariances
>> > U.cov = A.cov;
>> >
>>
>> This is the problem. ft_sourceanalysis is using the covariance matrix
>> and leadfield to construct a spatial filter for each grid point; if
>> the
>> covariance matrices are equivalent, the source solutions will be too.
>>
>> What you need to do is something like run the source analysis on data
>> averaged over both conditions first, then take the filter from the
>> combined analysis and run source analysis on each condition
>> seperately.
>>
>> so say sourceAll is the result of
>> ft_sourceanalysis(cfg,bothConditions)
>>
>> You'd do
>>
>> cfg.grid.filter = sourceAll.avg.filter
>>
>> then
>>
>> ft_sourceanalysis(cfg,A)
>> ft_sourceanalysis(cfg,U)
>>
>> As a quick and dirty version I just replaced the covariance matrix in
>> A
>> with the average of the two A.cov and U.cov, ran sourceanalysis on
>> that,
>> then put A.cov back to its original value and ran sourceanalysis on
>> each
>> condition seperately. Spoiler: the unattended condition has lower
>> activity everywhere :)
>>
>> There's some weirdness around the boundaries of the headmodel, not
>> sure
>> what's causing that exactly. Maybe try using a different source grid
>> instead of the standard one...
>>
>> Cheers,
>> Matt
>>
>> On 24/01/2017 16:36, Tommy Wilson wrote:
>> > Hi Julian,
>> >
>> > Thank you so much for your reply.
>> >
>> > I've pasted the commented code below (I apologize for the code
>> dump).
>> > I've also attached an m-file to this email if you'd prefer to
>> download
>> > it that way. If relevant, you can download the leadfield,
>> headmodel and
>> > electrode locations here
>> >
>> <https://www.dropbox.com/s/8w99ejwrzmwc5pt/Source_fitting_
>> dump.mat?dl=0
>> <https://www.dropbox.com/s/8w99ejwrzmwc5pt/Source_fitting_
>> dump.mat?dl=0>>
>> > (that file also includes the raw data stored in variables A and U
>> that I
>> > am attempting to source-fit).
>> >
>> > As per your questions: I do indeed have a contrast between
>> attended (A)
>> > and unattended (U) conditions. I've written the code below to
>> source-fit
>> > both conditions and create the contrast. However, despite that the
>> raw
>> > topographies (see attached images) are different, the source-fits
>> are
>> > the same (...?). As a consequence, the contrast has no non-zero
>> values.
>> > If instead, I normalize to noise (i.e. generate the Neural Activity
>> > Index
>> >
>> <http://www.fieldtriptoolbox.org/tutorial/beamformer#neural_
>> activity_index
>> <http://www.fieldtriptoolbox.org/tutorial/beamformer#neural_
>> activity_index>>)
>> > and look at a contrast there, we again see no non-zero values.
>> >
>> > Outside of the contrast, I've implemented your other suggestions.
>> I've
>> > rescaled the original ft_sourceplot such that you can see the
>> extent of
>> > it (see attached image). To my mind, it shouldn't look like this,
>> but
>> > having never done this before, I'm not quite sure what to expect.
>> I've
>> > also included an image of the ft_sourceplot for the Neural Activity
>> > Index of sourceA which also appears to me to be artefactual. More
>> to the
>> > point, I'd expect that since the topographies for A and U are
>> different,
>> > the NAIs should be different, which is not the case.
>> >
>> > I'm sort of at a loss about how to proceed here. So, thank you
>> very much
>> > for taking the time to look into this. If I can supply anything
>> else to
>> > help, please don't hesitate to let me know.
>> >
>> > Best,
>> >
>> > Tommy Wilson
>> >
>> > --- CODE ---
>> >
>> > %% Source fitting protocol
>> > % Fieldtrip path (to find template MRI)
>> > ftdir = 'your\path\here\';
>> >
>> > % Equate covariance matrices for now to rule out any differences
>> in the
>> > % source fit due to differences in covariances
>> > U.cov = A.cov;
>> >
>> > %%% Do the LCMV sourcefitting
>> > cfg = [];
>> > cfg.method = 'lcmv';
>> > cfg.grid = leadfield;
>> > cfg.vol = vol;
>> > cfg.elec = elec;
>> > cfg.lcmv.lambda = '15%';
>> > cfg.lcmv.keepfilter = 'yes';
>> > cfg.lcmv.fixedori = 'yes';
>> > cfg.lcmv.projectnoise = 'yes';
>> >
>> > sourceA = ft_sourceanalysis(cfg,A);
>> > sourceU = ft_sourceanalysis(cfg,U);
>> >
>> >
>> > %%% Attempt a contrast
>> > % Create the contrast
>> > sourceContrast = sourceA;
>> > sourceContrast.avg.pow = sourceA.avg.pow - sourceU.avg.pow;
>> >
>> > % Check to see if any non-zero values exist in the contrast
>> > if all(sourceContrast.avg.pow(sourceContrast.inside(:)) == 0)
>> > warning('No non-zero contast values exist. ft_sourceplot will
>> give
>> > an error. Do not plot.');
>> > end
>> >
>> >
>> > %%% Instead of a contrast, look at the Neural Activity Index (NAI)
>> > % See:
>> >
>> http://www.fieldtriptoolbox.org/tutorial/beamformer#neural_
>> activity_index
>> <http://www.fieldtriptoolbox.org/tutorial/beamformer#neural_
>> activity_index>
>> > sourceA_NAI = sourceA;
>> > sourceA_NAI.avg.pow = sourceA.avg.pow./sourceA.avg.noise;
>> > sourceU_NAI = sourceU;
>> > sourceU_NAI.avg.pow = sourceU.avg.pow./sourceU.avg.noise;
>> >
>> > if all(sourceA_NAI.avg.pow(sourceA_NAI.inside(:)) -
>> > sourceU_NAI.avg.pow(sourceU_NAI.inside(:))==0)
>> > warning('No non-zero contast values exist. ft_sourceplot will
>> give
>> > an error. Do not plot.')
>> > end
>> >
>> >
>> > %%% Visualize the output
>> > % Load template MRI
>> > mri = ft_read_mri([ftdir
>> > '\fieldtrip-20160309\template\anatomy\single_subj_T1.nii']);
>> >
>> > % Interpolate source onto MRI
>> > cfg = [];
>> > cfg.parameter = 'avg.pow';
>> > sourceA_interp = ft_sourceinterpolate(cfg, sourceA, mri);
>> > sourceA_NAI_interp = ft_sourceinterpolate(cfg, sourceA_NAI, mri);
>> >
>> > % Visualize with ft_sourceplot
>> > cfg = [];
>> > cfg.method = 'ortho';
>> > cfg.funparameter = 'avg.pow';
>> > cfg.funcolorlim = [0 3e3];
>> > cfg.maskparameter = cfg.funparameter;
>> > ft_sourceplot(cfg, sourceA_interp);
>> >
>> > cfg = [];
>> > cfg.method = 'ortho';
>> > cfg.funparameter = 'avg.pow';
>> > cfg.maskparameter = cfg.funparameter;
>> > ft_sourceplot(cfg, sourceA_NAI_interp);
>> >
>> > On Tue, Jan 24, 2017 at 3:42 AM Julian Keil <julian.keil at gmail.com
>> <mailto:julian.keil at gmail.com>
>> > <mailto:julian.keil at gmail.com <mailto:julian.keil at gmail.com>>>
>> wrote:
>> >
>> > Hi Tommy,
>> >
>> > did you do some sort of contrast (e.g. with the noise estimate
>> or a
>> > baseline) after your source analysis?
>> > Right now, it's not clear what you are looking at. Could you
>> paste
>> > your code not only of the sourceanalysis, but the rest after
>> which
>> > got you to the plot?
>> > It might also be the case that the automatic scaling in the
>> source
>> > plot throws you off - maybe try setting it by hand.
>> >
>> > Good luck,
>> >
>> > Julian
>> >
>> > Am 23.01.2017 um 22:00 schrieb Tommy Wilson:
>> >
>> > > Hi all,
>> > >
>> > > I'm working with EEG data and I'm trying to get some basic
>> source
>> > fitting up and running. Unfortunately, I don't have individual
>> > subject MRIs, so I'm using the templates provided by
>> fieldtrip. I've
>> > co-registered my 160 Biosemi electrodes to the standard_bem
>> template
>> > (see attached picture). For the sourcemodel, I'm using the
>> > standard_sourcemodel3d5mm grid (picture attached, overlaid on
>> > standard_bem). I can prepare the leadfield from there with
>> > ft_prepare_leadfield (cfg.normalize = 'yes'), as per the LCMV
>> tutorial.
>> > >
>> > > To test this configuration, I've selected a time window in
>> my data
>> > and averaged across it (the covariance matrix was also
>> calculated);
>> > the topography of this averaged data is attached. I then
>> attempted a
>> > source fit with the LCMV beamformer:
>> > >
>> > > cfg = [];
>> > > cfg.method = 'lcmv';
>> > > cfg.grid = leadfield;
>> > > cfg.vol = vol;
>> > > cfg.elec = elec;
>> > > cfg.lcmv.lambda = '15%';
>> > > cfg.lcmv.keepfilter = 'yes';
>> > > cfg.lcmv.fixedori = 'yes';
>> > > cfg.lcmv.projectnoise = 'yes';
>> > >
>> > > sourceA = ft_sourceanalysis(cfg,A);
>> > >
>> > > After interpolating to the single_subj_T1.nii provided with
>> > ft_sourceinterpolate and plotting with ft_sourceplot, I am
>> given a
>> > sourceplot that is highly focal in nature (see attached
>> picture).
>> > >
>> > > I'd find it very surprising if this topography were generated
>> > primarily by a source that isn't even inside the brain (as the
>> > sourceplot indicates). So, I'm not sure exactly where/how I'm
>> going
>> > wrong with this one, nor am I sure how to trouble shoot it. Any
>> > guidance you might provide would be greatly appreciated.
>> > >
>> > > Thanks so much,
>> > >
>> > > Tommy
>> > >
>> > > <Grid.PNG><Electrode
>> >
>> localization.PNG><Topo.PNG><Source.PNG>____________________
>> ___________________________
>> > > fieldtrip mailing list
>> > > fieldtrip at donders.ru.nl <mailto:fieldtrip at donders.ru.nl>
>> <mailto:fieldtrip at donders.ru.nl <mailto:fieldtrip at donders.ru.nl>>
>> > > https://mailman.science.ru.nl/mailman/listinfo/fieldtrip
>> <https://mailman.science.ru.nl/mailman/listinfo/fieldtrip>
>> >
>> > _______________________________________________
>> > fieldtrip mailing list
>> > fieldtrip at donders.ru.nl <mailto:fieldtrip at donders.ru.nl>
>> <mailto:fieldtrip at donders.ru.nl <mailto:fieldtrip at donders.ru.nl>>
>> > https://mailman.science.ru.nl/mailman/listinfo/fieldtrip
>> <https://mailman.science.ru.nl/mailman/listinfo/fieldtrip>
>> >
>> >
>> >
>> > _______________________________________________
>> > fieldtrip mailing list
>> > fieldtrip at donders.ru.nl <mailto:fieldtrip at donders.ru.nl>
>> > https://mailman.science.ru.nl/mailman/listinfo/fieldtrip
>> <https://mailman.science.ru.nl/mailman/listinfo/fieldtrip>
>> >
>> _______________________________________________
>> fieldtrip mailing list
>> fieldtrip at donders.ru.nl <mailto:fieldtrip at donders.ru.nl>
>> https://mailman.science.ru.nl/mailman/listinfo/fieldtrip
>> <https://mailman.science.ru.nl/mailman/listinfo/fieldtrip>
>>
>>
>>
>> _______________________________________________
>> fieldtrip mailing list
>> fieldtrip at donders.ru.nl
>> https://mailman.science.ru.nl/mailman/listinfo/fieldtrip
>>
>> _______________________________________________
> fieldtrip mailing list
> fieldtrip at donders.ru.nl
> https://mailman.science.ru.nl/mailman/listinfo/fieldtrip
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.science.ru.nl/pipermail/fieldtrip/attachments/20170125/07a19f29/attachment-0002.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Topo_Attended.PNG
Type: image/png
Size: 92946 bytes
Desc: not available
URL: <http://mailman.science.ru.nl/pipermail/fieldtrip/attachments/20170125/07a19f29/attachment-0004.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Topo_Unattended.PNG
Type: image/png
Size: 91677 bytes
Desc: not available
URL: <http://mailman.science.ru.nl/pipermail/fieldtrip/attachments/20170125/07a19f29/attachment-0005.png>
More information about the fieldtrip
mailing list