[FieldTrip] Issue with source grand averaging
Mohd Faizal Mohd Zulkifly
mfzl_mzly at yahoo.com
Wed Apr 29 13:14:48 CEST 2020
Dear all,
I am doing source analysis based on subject-specific MRI andcurrently having an issue to do source grandaveraging. I tried to use differentversion of fieldtrips (i.e. Fieldtrip-20181122, Fieldtrip-20191127 andFieltrip-20200109), and it still ended up with the same error: “Error usingft_sourcegrandaverage (line 116) the input sources vary in the field inside”. Ialso aware that this issue was discussed previously https://mailman.science.ru.nl/pipermail/fieldtrip/2015-October/022580.html.Unfortunately, I still facing the same error after specifying source.pos =template_grid.pos. It would be grateful if some of you can help and let me knowmy mistakes in the scripts below. It is a long script and I was thinking itmight be helpful to provide a full script for others to help. Hope to hear fromyou guys soon. Thank you.
***********************************Forwardmodel************************************************************
subject_data= {'A’, ‘B’};
subj={'A’, ‘B’};
nsubj = numel(subject_data);
% MRI Segmentation
% if do_mri_seg
% read the *mgz files from FreeSurfer
fprintf(['starting forward model for: ', subj{s},'\n '])
mri = ft_read_mri([subject_mri, subj{s},'/','mri/','T1.mgz']);
mri.coordsys = 'ctf';
% interactively set fiducials to align MRI space to EEGspace
cfg = [];
cfg.method = 'interactive';
mri = ft_volumerealign(cfg, mri);
cfg = [];
cfg.output = {'brain','skull','scalp'};
segmentedmri = ft_volumesegment(cfg, mri);
% save segmentedmri
%%
% Head mesh
%if do_head_mesh
addpath 'XXXXXX/fieldtrip-20181122/external/spm12'
segmentedmri.dim = segmentedmri.dim;
segmentedmri.coordsys = segmentedmri.coordsys;
segmentedmri.unit = segmentedmri.unit;
cfg = [];
cfg.tissue = {'brain','skull','scalp'};
cfg.method = 'projectmesh';
cfg.numvertices = [3000 2000 1000];
mri_bnd = [];
mri_bnd.transform = segmentedmri.transform;
mri_bnd.brain = segmentedmri.brain;
braindil = imdilate(segmentedmri.brain, strel_bol(6));
mri_bnd.skull = braindil > 0.5;
mri_bnd.scalp = segmentedmri.scalp;
mri_bnd.dim = segmentedmri.dim;
mri_bnd.coordsys = segmentedmri.coordsys;
mri_bnd.unit = segmentedmri.unit;
src = ft_prepare_mesh(cfg, mri_bnd);
% save src
%%
% COMPONENT 1: Headmodel
addpath 'XXX/fieldtrip-20181122/external/dipoli'
cfg = [];
cfg.method = 'dipoli';
hdm = ft_prepare_headmodel(cfg, src);
% save hdm
disp(hdm)
%%
% COMPONENT 2: Sensoradjustment %getting electrodes in the right position
%if do_sensor_alignment
sens = ft_read_sens([XXX, subj{s}, '.sfp']); %GEOSCAN
sens = ft_convert_units(sens, 'mm');
nas = mri.cfg.fiducial.nas;
lpa = mri.cfg.fiducial.lpa;
rpa = mri.cfg.fiducial.rpa;
% warp NAS LPA and RPA
nas = ft_warp_apply(mri.transform, nas, 'homogenous');
lpa = ft_warp_apply(mri.transform, lpa, 'homogenous');
rpa = ft_warp_apply(mri.transform, rpa, 'homogenous');
fid = [];
fid.elecpos = [nas; lpa;rpa]; % ctf-coordinates of fiducials
fid.chanpos = [nas; lpa;rpa]; % ctf-coordinates of fiducials
fid.label = {char(sens.label(1)); ...
char(sens.label(2)); ...
char(sens.label(3))}; % samelabels as in elec
% alignment
cfg = [];
cfg.method ='fiducial';
cfg.target =fid; % see above
cfg.elec = sens;
cfg.fiducial ={char(sens.label(1)); ...
char(sens.label(2)); ...
char(sens.label(3))}; % labels of fiducials in fid and inelec
elec_aligned =ft_electroderealign(cfg);
cfg = [];
cfg.method = 'project';
cfg.elec = elec_aligned;
cfg.headshape = src(3);
elec_aligned = ft_electroderealign(cfg);
% save elec_aligned
%%
%COMPONENT 3: Sourcemodel
% % load a template grid
% NOTE: the path to the template file is user-specific
pathin ='XXX/matlab/toolbox/';
load(fullfile(pathin,'fieldtrip-20200109/template/sourcemodel/standard_sourcemodel3d5mm'));
template = sourcemodel;
clear sourcemodel;
% create the subject specific grid, using the template gridthat has just been created
% inverse-warp the template grid to subject specificcoordinates
cfg = [];
cfg.warpmni = 'yes';
cfg.template = template;
cfg.nonlinear = 'yes';
cfg.mri = mri; %mri - not working properly/ showingscalp
cfg.unit = 'mm';
grid =ft_prepare_sourcemodel(cfg);
%save grid
%%
% COMPONENT 4: Leadfield
fname_preproc_data = fullfile(XXX,subject_data{s}]);
preproc_data = load(fname_preproc_data);
EEG_name = cell2mat(fieldnames(preproc_data));
%
cfg = [];
cfg.elec = elec_aligned;
cfg.channel =preproc_data.conv_data_rpost.label; % ensure that rejected electrodes are not present
cfg.headmodel = hdm;
cfg.grid.pos = sourcemodel.pos;
cfg.normalize ='no'; %normalize 'yes' it when don't have a contrast to avaoid activity at thecenter (NAI tutorial)
cfg.normalizeparam = 0.5;
cfg.grid.unit = 'mm';
leadfield = ft_prepare_leadfield(cfg);
%save leadfield
% the data consists of fewer channels than theprecomputed
% leadfields, the following chunk of codetakes care of this
[a,b] = match_str(preproc_data.conv_data_rpost.label,leadfield.label);
for k = 1:numel(leadfield.leadfield)
if ~isempty(leadfield.leadfield{k})
tmp =leadfield.leadfield{k};
tmp = tmp(b,:);
tmp =tmp-repmat(mean(tmp,1),[size(tmp,1) 1]); % average re-ref
leadfield.leadfield{k} = tmp;
end
end
leadfield.label = leadfield.label(b);
%save leadfield
*****************************************************source_analysis**************************************
subject_rpost_data= {‘A’, ‘B’};
subj={‘A’, ‘B’ };
nsubj = numel(subj);
% Loop over subjects
for s=1:nsubj
fprintf(['starting source analysis for:', subj{s},'\n '])
load(fname_preproc_data);
load(fname_sourcemodel);
load(fname_leadfield);
load(fname_headmodel);
load(fname_elec);
mri =ft_read_mri(fname_seg_mri);
mri.coordsys = 'ctf';
load(fname_smri )
% transform original mri tosegemented mri transformation info
trns = segmentedmri.transform /mri.transform;
clear segmentedmri
% reslice mri
mri.coordsys = 'ctf';
mri = ft_volumereslice([], mri);
% transform mri to coordinates ofleadfield
mri = ft_transform_geometry(trns,mri);
% Bring data as in time domain
% Cut Trial data in baseline and evokedtime segments
cfg = [];
cfg.latency = [-1.0 0]; %baseline % choose baseline as i didwith sensor analysis (100ms)
datbasl = ft_selectdata(cfg,preproc_data.(EEG_name));
cfg = [];
cfg.latency = [0 3]; % evoked activity
datact = ft_selectdata(cfg,preproc_data.(EEG_name));
cfg = [];
cfg.latency = [-1 3];
datall =ft_selectdata(cfg,preproc_data.(EEG_name));
%%
% Compute covariance matrix
cfg = [];
cfg.covariance = 'yes';
cfg.keeptrials = 'no'; % 'no' createsaveraged trial
cfg.removemean = 'yes';
cfg.channel = {'all', '-E257'};
datbasl_avg =ft_timelockanalysis(cfg, datbasl); %Baseline data (in time domain)
datact_avg =ft_timelockanalysis(cfg, datact); %Activity data
datall_avg =ft_timelockanalysis(cfg, datall); %Data with baseline and activity
%% Source analysis
%
% adapt leadfield channels to channel ofcurrent eeg data (199 instead
% of 256)
[~,b] = match_str(datbasl_avg.label,leadfield.label);
for k = 1:numel(leadfield.leadfield)
if~isempty(leadfield.leadfield{k})
tmp = leadfield.leadfield{k};
tmp = tmp(b,:);
tmp = tmp-repmat(mean(tmp,1),[size(tmp,1) 1]); % average re-ref
leadfield.leadfield{k} = tmp;
end
end
leadfield.label = leadfield.label(b);
% Compute common spatialfilter
cfg = [];
cfg.channel =datall_avg.label;
cfg.elec = elec_aligned.elec_aligned;
cfg.method ='lcmv';
% cfg.grid =leadfield;
cfg.headmodel = headmodel.hdm;
cfg.sourcemodel.grid.pos =leadfield.pos; % bei FT wird hier der output von ft_leadfield angegeben
cfg.grid.resolution = 5;
cfg.lcmv.keepfilter = 'yes';
cfg.lcmv.fixedori = 'yes';
cfg.lcmv.projectnoise = 'yes';
cfg.lcmv.weightnorm = 'nai';
cfg.lcmv.lambda = '5%';
eegsrc_all = ft_sourceanalysis(cfg,datall_avg); %source data in all time window
% apply common filters to pre andpost stimulus data
cfg.grid.filter = eegsrc_all.avg.filter;
% Compute source for baseline andactivty time window
eegsrc_basl = ft_sourceanalysis(cfg,datbasl_avg); %source data for baseline time window
eegsrc_act = ft_sourceanalysis(cfg,datact_avg); %source data for activity time window
% contrast post stimulus onsetactivity with respect to baseline
eegsrc_act_basnrm = eegsrc_act;
eegsrc_act_basnrm.avg.pow =(eegsrc_act.avg.pow - eegsrc_basl.avg.pow)./ eegsrc_basl.avg.pow;
%% Choose time of interest
% average across time the dipole momentswithin the N1 latency range
ind =find(eegsrc_act_basnrm.time>=0.1 & eegsrc_act_basnrm.time<=0.5); %at18ms-24ms
timecourse =eegsrc_act_basnrm.avg.mom(eegsrc_act_basnrm.inside);
tc_toi =zeros(size(eegsrc_act_basnrm.avg.pow(eegsrc_act_basnrm.inside)));
for ii = 1:length(timecourse)
tc_toi(ii) =mean(abs(timecourse{ii}(ind)));
end
source = eegsrc_act_basnrm;
source.avg.pow(eegsrc_act_basnrm.inside)= tc_toi;
% source.cfg = rmfield(source.cfg,{'headmodel' 'callinfo'}); % this is removed because it takes up a lot ofmemory
% Save source
% interpolate and normalize toindividual mri
%first, interpolate
cfg = [];
cfg.parameter = 'pow';
eeg_source_interp =ft_sourceinterpolate(cfg, source, mri);
% second, normalise
cfg = [];
cfg.nonlinear ='no';
eeg_source_interp_norm =ft_volumenormalise(cfg, eeg_source_interp);
% save the interpolate andnormalised data
%%
% load sourcereconstructed data
% keep subjects path_data nsubjpath_ft
allsource_rpost = cell(1,nsubj);
for s = 1:nsubj
datapath =strcat(fname_eeg_source_interp_norm);
% datafile =fullfile(datapath, [subj{s}, '_source.mat']); % take _sourcedata?
datafile =fullfile(datapath, [subj{s}, '_eeg_source_interp_norm.mat']);
load(datafile)
allsource_rpost{s} = eeg_source_interp_norm;
% allsource_rpost{s} = source;
end
% grand average
cfg =[];
cfg.parameter = 'pow';
% cfg.keepindividual='yes';
gasource_rpost =ft_sourcegrandaverage(cfg, allsource_rpost{:});
%save gasource_rpost
With best wishes,
Faizal Zulkifly
--------------------------------------------------------
Mohd Faizal Mohd Zulkifly
University Medical Center Göttingen
University of Göttingen
Clinic for Clinical Neurophysiology
Robert-Koch-Straße40
37075 Göttingen
Germany
Tel: +49 55139-8457
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.science.ru.nl/pipermail/fieldtrip/attachments/20200429/55638b10/attachment.htm>
More information about the fieldtrip
mailing list