[FieldTrip] Source fitting with template MRI/Headmodel

Matt Craddock m.p.craddock at leeds.ac.uk
Wed Jan 25 18:11:41 CET 2017


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)./numel(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
>



More information about the fieldtrip mailing list