Hi Felix,
On Sun, Mar 1, 2009 at 1:51 PM, Felix Blankenburg
<[log in to unmask]> wrote:
> I am trying to convert EEG time-frequency maps to nifti-images. The option
> of averaging over frequencies works. Unfortunately, if I am averaging over
> channels (for example: electrodes[s] [33 34 35 35] and region number 2), I
> get the following error message (see below).
I fixed the problem. Use the attached version.
> It's also not clear to me what
> the meaning of the 'region number' is.
>
As far as I can see from the code it's only the number that is
pre-pended to directory name. It's not used for anything else. In
general the code for all the sensor-level and TF analysis hasn't
changed much since SPM5. I'm planning to do a deep re-write of it but
I won't have time for it in the near future.
> My plan is to write an EEG time-frequency map for every single channel as a
> 2D or ideally as a 3D nifti images i.e. time, frequency and channels. Is
> there a simple way in SPM8 for EEG to do this?
Since representing channels requires 2 dimensions - time, frequency
and channels would be 4 dimensions and this is not supported. You can
either have channels and frequencies or channels and time or time
frequency for a single (or averaged) channel, but not everything
together.
>
> PS: Is there something noteworthiness that only up-going flanks are
> supported for Biosemi in SPM for EEG.
No. I think it's just a property of Biosemi that there are no
down-going flanks and SPM always asks for both directions so there is
a warning. As long as you can find the triggers you are interested in,
this is not something to worry about.
Best,
Vladimir
>
> Warning: Divide by zero.
>> In mean at 29
> In spm_cond_units at 19
> In spm_eeg_convert2images at 135
> In spm at 879
> Warning: Divide by zero.
>> In mean at 29
> In spm_cond_units at 19
> In spm_eeg_convert2images at 135
> In spm at 879
> ??? Error using ==> nifti.subsasgn>assigndat at 382
> "raw" must be of class "file_array"
>
> Error in ==> nifti.subsasgn>fun at 76
> obj = assigndat(obj,val);
>
> Error in ==> nifti.subsasgn at 20
> obji = fun(obji,subs,val);
>
> Error in ==> spm_eeg_convert2images at 135
> N.dat = spm_cond_units(dat);
>
> Error in ==> spm at 879
> evalin('base',CBs{v-1})
>
> ??? Error while evaluating uicontrol Callback
>
>
>
>
function [D, S] = spm_eeg_convert2images(S)
% User interface for conversion of M/EEG-files to SPM image file format
% FORMAT D = spm_eeg_convert2images(S)
%
% struct S is optional and has the following (optional) fields:
% D - matrix of EEG mat-files
% images.fmt - string that determines type of input file. Currently, this
% string can be 'electrodes' or 'frequency'
% images.elecs - electrodes of interest (as vector of indices)
% images.freqs - frequency window of interest (2-vector) [Hz]
% n - dimension of output images in voxels (scalar because
% output will be square image)
% interpolate_bad - flag (0/1) that indicates whether values for
% bad channels should be interpolated (1) or left
% out (0).
% output:
% S - can be used to construct script (as in the history-function)
%_______________________________________________________________________
%
% spm_eeg_convert2images is a user interface to convert M/EEG-files in SPM
% format to SPM's image format, using an interpolation on a 2D-plane.
% This function assembles some necessary information before
% branching to the format-specific conversion routines.
%
%
% Output: The converted data are written to files. The header
% structs, but not the data, are returned in D as a cell vector of structs,
% and the struct S is returned to allow for saving the history of function
% calls.
%_______________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging
% James Kilner, Stefan Kiebel
% $Id: spm_eeg_convert2images.m 2803 2009-03-02 10:47:41Z vladimir $
[Finter,Fgraph,CmdLine] = spm('FnUIsetup','TF',0);
try
D = S.D;
catch
D = spm_select(1, '\.mat$', 'Select EEG mat file');
S.D = D;
end
P = spm_str_manip(D, 'H');
try
D = spm_eeg_load(D);
catch
error(sprintf('Trouble reading file %s', D));
end
if strcmp(D.type, 'continuous')
error('Data are continuous. Try epoched data.');
end
if strcmp(D.transformtype, 'TF');
try
images.fmt = S.images.fmt;
catch
spm_input('average over ...', 1, 'd')
Ctype = {
'channels',...
'frequency'};
str = 'Average over which dimension';
Sel = spm_input(str, 2, 'm', Ctype);
images.fmt = Ctype{Sel};
end
switch images.fmt
case {'channels'}
try
images.electrodes_of_interest = S.images.elecs;
catch
str = 'electrodes[s]';
Ypos = -1;
while 1
if Ypos == -1
[images.electrodes_of_interest, Ypos] = spm_input(str, '+1', 'r', [], [1 Inf]);
else
images.electrodes_of_interest = spm_input(str, Ypos, 'r', [], [1 Inf]);
end
if any(ismember(images.electrodes_of_interest, [1:D.nchannels]))
break
end
end
S.images.elecs = images.electrodes_of_interest;
end
try
images.Nregion = S.images.region_no;
catch
str = 'region number';
Ypos = -1;
while 1
if Ypos == -1
[images.Nregion, Ypos] = spm_input(str, '+1', 'r', [], [1 Inf]);
else
images.Nregion = spm_input(str, Ypos, 'r', [], [1 Inf]);
end
if ~isempty(images.Nregion) break, end
str = 'No data';
end
S.images.region_no = images.Nregion;
end
cl = D.condlist;
for i = 1 : D.nconditions
Itrials = pickconditions(D, cl{i}, 1)';
cd(D.path)
dname = sprintf('%dROI_TF_trialtype_%s', images.Nregion, cl{i});
[m, sta] = mkdir(dname);
cd(dname);
for l = Itrials(:)'
% if single trial data make new directory for single trials,
% otherwise just write images to trialtype directory
if strcmp(D.type, 'single')
% single trial data
fname = sprintf('trial%04d.img', l);
else
fname = 'average.img';
end
dat = file_array(fname, [D.nfrequencies D.nsamples], 'FLOAT64');
dat(:, :) = spm_cond_units(squeeze(mean(D(images.electrodes_of_interest, :, :, l), 1)));
N = nifti;
N.dat = dat;
N.mat = [1 0 0 min(D.frequencies);
0 1000/D.fsample 0 time(D, 1, 'ms');
0 0 1 0;
0 0 0 1];
N.mat_intent = 'Aligned';
create(N);
end
end
case {'frequency'}
try
images.Frequency_window = S.images.freqs;
Ypos = -1;
while 1
if Ypos == -1
Ypos = '+1';
end
inds = find(D.frequencies >= Frequency_window(1) & D.frequencies <= Frequency_window(2));
if ~isempty(inds) break, end
str = 'No data in range';
end
catch
str = 'Frequency window';
Ypos = -1;
while 1
if Ypos == -1
Ypos = '+1';
end
[images.Frequency_window, Ypos] = spm_input(str, Ypos, 'r', [], 2);
inds = find(D.frequencies >= images.Frequency_window(1) & D.frequencies <= images.Frequency_window(2));
if ~isempty(inds) break, end
str = 'No data in range';
end
end
% generate new meeg object with new filenames
fnamedat = ['F' num2str(images.Frequency_window(1)) '_' num2str(images.Frequency_window(2)) '_' D.fnamedat];
Dnew = clone(D, fnamedat, [D.nchannels D.nsamples D.ntrials]);
Dnew(1:Dnew.nchannels, 1:Dnew.nsamples, 1:Dnew.ntrials) = ...
squeeze(mean(D(:, inds, :, :), 2));
% fake time-series data
Dnew = transformtype(Dnew, 'time');
save(Dnew);
S.Fname = fullfile(Dnew.path, Dnew.fname);
try
n = S.n;
catch
S.n = spm_input('Output image dimension', '+1', 'n', '32', 1);
n = S.n;
end
if length(n) > 1
error('n must be scalar');
end
try
interpolate_bad = S.interpolate_bad;
catch
S.interpolate_bad = spm_input('Interpolate bad channels or mask out?',...
'+1', 'b', 'Interpolate|Mask out', [1,0]);
end
spm_eeg_convertmat2nifti3D(S);
end
else
clear S;
S.Fname = fullfile(D.path, D.fname);
spm_eeg_convertmat2nifti3D(S);
end
|