[FieldTrip] Help with parcellation of data to atlas
Monika
monik2407993 at gmail.com
Thu Jul 18 15:51:54 CEST 2024
Hello All Fieldtrippers!
First i will tell you what my data is: I have epoched EEG data, where in
each epoch participants task was to imagine the situations presented on
screen. Each epoch is 5 seconds long, containing fixation cross and tag for
imagination.
What i want: I want to perform source analysis on my preprocessed epoched
data, then i want to parcellate sources to atlas, then i want to create a
matrix where i will have reconstructed source data for each ROI from atlas.
I need my data to be epoched (time locked, but not ERP), and not power,
since i want to do multiple operations on this matrix. So the matrix will
look like
ROI 1 signal value for 1st time point | signal value for 2nd time point
.....
ROI 2 signal value for 1st time point | signal value for 2nd time point
.....
ROI 3 signal value for 1st time point | signa value for 2nd time point .....
...
What i did: I've done preprocessing in eeglab, computed headmodel (im using
template MRI from Fieldtrip repsitory), sourcemodel, leadfield and
sourcemodel (i will paste code below), then i wanted to compute
sourceinterpolate and sourceparcellate (i've used some tutorials from Your
page), and then i wanted to create a matrix.
What is my problem: I faced first trouble after running sourceanalysis.
I've check 'source.avg.filter' and 'source.avg.mom' field and is looks like
this:
{0×0 double}
{0×0 double}
{0×0 double}
{0×0 double}
{0×0 double}
{0×0 double}
{0×0 double}
{0×0 double}
{3×19 double}
{3×19 double}
{3×19 double}
{0×0 double}
{0×0 double}
{0×0 double}
{0×0 double}
{0×0 double}
{0×0 double}
{0×0 double}
Next, i've tried running sourceinterpolate on my source data and atlas, it
worked without errors. I passed cfg.parameter = 'trial'; since i thought it
would interpolate data as time locked epochs (trials).
Unfortunately, next function i wanted to use - sourceparcellate can not
parcellate data like that, as i've seen it works only with 'pow' parameter,
and i dont want power, since its like average power for ROI.
It only works like that:
cfg = [];
cfg.interpmethod = 'nearest';
cfg.parameter = 'all'; %'avg.pow'
cfg.atlas = atlas;
cfg.keeptrials = 'yes';
cfg.mri = mri_resliced;
source_int = ft_sourceinterpolate(cfg, source, atlas);
cfg = [];
cfg.parameter = 'all';
cfg.method = 'mean';
cfg.atlas = atlas;
source_parcel = ft_sourceparcellate(cfg, source_int,atlas);
but when i tried to create matrix on source_parcel data, i got a lot of
NaNs:
1.3660 1.3660 1.3660 1.3660 1.3660 1.3660 1.3660
1.3660
0.4568 0.4568 0.4568 0.4568 0.4568 0.4568 0.4568
0.4568
0.8530 0.8530 0.8530 0.8530 0.8530 0.8530 0.8530
0.8530
NaN NaN NaN NaN NaN NaN NaN
NaN
NaN NaN NaN NaN NaN NaN NaN
NaN
NaN NaN NaN NaN NaN NaN NaN
NaN
0.4486 0.4486 0.4486 0.4486 0.4486 0.4486 0.4486
0.4486
NaN NaN NaN NaN NaN NaN NaN
NaN
NaN NaN NaN NaN NaN NaN NaN
NaN
So, in summary, i need some help with usage of sourceinterpolate and
sourceparcellate on epoched data, so i will be able to create matrix
containing signal, not one power value per ROI. I haven't seen anyone do
this on the data structure that i'm working with, so i feel a little bit
lost by now.
If you spot any mistakes prior to sourceinterpolate please let me know, i'm
doing pipeline like that first time in my life so i know it can contain
mistakes.
I would appreciate any help.
Thanks in advance and have a good day!
Monika
%%%%code
fid = fopen(electrode_file_path, 'r');
if fid == -1
error('Failed to open file: %s', electrode_file_path);
end
file_content = textscan(fid, '%s %s %f %f %f %f %f %f %f %f', 'HeaderLines',
1);
fclose(fid);
labels = file_content{2};
X = file_content{5};
Y = file_content{6};
Z = file_content{7};
elec = struct();
elec.label = labels;
elec.pnt = [X, Y, Z];
n_elec = length(labels);
elec.chantype = repmat({'eeg'}, n_elec, 1);
elec.chanunit = repmat({'V'}, n_elec, 1);
elec.unit = 'mm';
cfg = [];
cfg.method = 'fiducial';
cfg.coordsys = 'ctf';
mri_realigned = ft_volumerealign(cfg, mri);
cfg = [];
cfg.method = 'flip';
cfg.coordsys = 'ctf';
mri_resliced = ft_volumereslice(cfg, mri_realigned);
cfg = [];
cfg.output = {'brain', 'skull', 'scalp'};
cfg.coordsys = 'ctf';
segmentedmri = ft_volumesegment(cfg, mri_resliced);
cfg = [];
cfg.method = 'hexahedral';
cfg.coordsys = 'ctf';
mesh = ft_prepare_mesh(cfg, segmentedmri);
cfg = [];
cfg.method = 'simbio'; %method used in artcile
cfg.conductivity = [0.33, 0.0125, 0.33]; % brain skull scalp
headmodel = ft_prepare_headmodel(cfg, mesh);
cfg = [];
cfg.headmodel = headmodel;
cfg.headmodel.type='simbio';
cfg.xgrid = 'auto';
cfg.ygrid = 'auto';
cfg.zgrid = 'auto';
cfg.unit = 'mm';
cfg.tight = 'yes';
cfg.inwardshift = -1.5;
cfg.resolution = 6;
sourcemodel = ft_prepare_sourcemodel(cfg);
atlas = ft_read_atlas(fullfile(ftpath, 'template\atlas\aal\ROI_MNI_V4.nii'))
atlas = ft_convert_units(atlas,'mm');
sourcemodel = ft_convert_units(sourcemodel,'mm');
file_list = dir(fullfile(PATH, '*.mat'));
for idx = 1:length(file_list)
data_load = load(fullfile(PATH, file_list(idx).name));
EEG = data_load.EEG2;
data = struct();
data.label = {EEG.chanlocs.labels}';
num_trials = EEG.trials;
num_points = EEG.pnts;
srate = EEG.srate;
time = linspace(EEG.xmin, EEG.xmax, num_points);
data.time = repmat({time}, 1, num_trials);
data.trial = squeeze(num2cell(EEG.data, [1, 2]));
data.trial = data.trial';
sample_info_start = repmat((0:num_trials-1)' * num_points, 1, 1);
sample_info_end = sample_info_start + num_points - 1;
data.sampleinfo = [sample_info_start, sample_info_end];
data.trialinfo = [EEG.epoch.eventtype]';
data.hdr = EEG;
data.elec = elec;
data.cfg = [];
cfg = [];
cfg.method = 'project';
cfg.headshape = mesh;
cfg.mri=mri_resliced;
elec_aligned = ft_electroderealign(cfg,elec);
elec_good = ft_prepare_vol_sens(headmodel, elec_aligned)
data.elec = elec_good;
cfg = [];
cfg.trials = 'all';
cfg.keeptrials = 'yes';
cfg.covariance = 'yes';
data.elec=data.elec.elec;
timlock = ft_timelockanalysis(cfg,data);
cfg = [];
cfg.elec = timlock.elec;
cfg.channel = data.label;
cfg.headmodel = headmodel;
cfg.sourcemodel.pos = sourcemodel.pos;
cfg.grid = sourcemodel;
cfg.channel = {'EEG'};
leadfield = ft_prepare_leadfield(cfg);
cfg = [];
cfg.interpmethod = 'nearest';
cfg.parameter = 'all';
cfg.atlas=atlas;
cfg.mri=mri_resliced;
atlas_int = ft_sourceinterpolate(cfg, sourcemodel, atlas);
cfg = [];
cfg.method = 'lcmv';
cfg.elec = timlock.elec; ;
cfg.sourcemodel = sourcemodel;
cfg.grid = sourcemodel;
cfg.sourcemodel.leadfield = leadfield;
cfg.headmodel = headmodel;
cfg.projectnoise = 'yes';
cfg.keepmom = 'yes';
cfg.keepfilter = 'yes';
cfg.keeptrials = 'yes';
source = ft_sourceanalysis(cfg, timlock);
cfg=[];
cfg.keeptrials = 'yes';
source = ft_sourcedescriptives(cfg, source);
if ~isfield(source, 'filter')
source.filter = cell(size(source.pos, 1), 1);
for i = 1:length(source.filter)
if source.inside(i)
source.filter{i} = leadfield.leadfield{i} * source.avg.mom{i};
else
source.filter{i} = [];
end
end
end
cfg = [];
cfg.interpmethod = 'nearest';
cfg.parameter = 'trial'; %'avg.pow'
cfg.atlas = atlas;
cfg.keeptrials = 'yes';
cfg.mri = mri_resliced;
source_int = ft_sourceinterpolate(cfg, source, atlas);
cfg = [];
cfg.parameter = 'all';
cfg.method = 'mean';
cfg.atlas = atlas;
source_parcel = ft_sourceparcellate(cfg, source_int,atlas);
%%big matrix creation works only for 'pow' parameter
num_regions = length(source_parcel.label);
num_epochs = size(EEG.data, 3);
big_matrix = zeros(num_regions, num_epochs);
for region_idx = 1:num_regions
for epoch_idx = 1:num_epochs
big_matrix(region_idx, epoch_idx) = source_parcel.pow(region_idx);
end
end
end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.science.ru.nl/pipermail/fieldtrip/attachments/20240718/136d065a/attachment.htm>
More information about the fieldtrip
mailing list