Skip to content

Commit

Permalink
Merge branch 'master' of github.com:fieldtrip/fieldtrip
Browse files Browse the repository at this point in the history
  • Loading branch information
robertoostenveld committed Sep 20, 2016
2 parents 40a3b1a + be73163 commit 29e8a0c
Show file tree
Hide file tree
Showing 20 changed files with 1,047 additions and 816 deletions.
2 changes: 1 addition & 1 deletion contrib/nutmegtrip/nmt_animate.m
Expand Up @@ -15,7 +15,7 @@ function nmt_animate(cfg)

Fs = 1/(st.nmt.time(2)-st.nmt.time(1));

cfg.stepsize = ft_getopt(cfg, 'stepsize', round(10e-3 * Fs)); % default is 10ms step
cfg.stepsize = ft_getopt(cfg, 'stepsize', round(5e-3 * Fs)); % default is 5ms step
cfg.winsize = ft_getopt(cfg,'winsize',1);

cfg.winsize = cfg.winsize - 1; % simplifies index tracking
Expand Down
1,214 changes: 619 additions & 595 deletions contrib/nutmegtrip/nmt_sourceplot.m

Large diffs are not rendered by default.

183 changes: 17 additions & 166 deletions contrib/nutmegtrip/nmt_spm_plot.m
@@ -1,18 +1,23 @@
function nmt_spm_plot(cfg)
function nmt_spm_plot(cfg,axsel)
% nmt_spm_plot(cfg)
% plots desired activation on SPM8 viewer
% designed for use via nmt_sourceplot, but possibly usable independently

global st

if(~exist('cfg','var'))
if(~exist('cfg','var') || isempty(cfg))
cfg = st.nmt.cfg;
end

if(~isfield('cfg','axsel'))
cfg.axsel = 1;
if(~exist('axsel','var'))
axsel = 1;
end

if(~isfield(cfg,'colormap'))
cfg.colormap = jet(64);
end


% if there is no time dimension, set cfg.time_idx to index first and only column
if(~isfield(cfg,'time_idx'))
cfg.time_idx = [1 1];
Expand All @@ -25,22 +30,22 @@ function nmt_spm_plot(cfg)


if(cfg.time_idx(1) == cfg.time_idx(2) && cfg.freq_idx(1) == cfg.freq_idx(2)) % single time point selected
fun = st.nmt.fun{cfg.axsel}(:,cfg.time_idx(1),cfg.freq_idx(1));
fun = st.nmt.fun{axsel}(:,cfg.time_idx(1),cfg.freq_idx(1));
% set colorscale: anatomical (first 64) + functional (second 64)
% grayscale for MRI; jet for painted activation
set(st.fig,'Colormap',[gray(64);jet(64)]);
set(st.fig,'Colormap',[gray(64);cfg.colormap]);

scalemax = max(abs(st.nmt.fun{cfg.axsel}(:)));
scalemin = -max(abs(st.nmt.fun{cfg.axsel}(:)));
scalemax = max(abs(st.nmt.fun{axsel}(:)));
scalemin = -max(abs(st.nmt.fun{axsel}(:)));
else % time interval selected
switch(cfg.plottype)
case 'tf'
fun = nmt_ts_intervalpower(st.nmt.fun{cfg.axsel}(:,cfg.time_idx(1):cfg.time_idx(2),cfg.freq_idx(1):cfg.freq_idx(2)),'mean');
fun = nmt_ts_intervalpower(st.nmt.fun{axsel}(:,cfg.time_idx(1):cfg.time_idx(2),cfg.freq_idx(1):cfg.freq_idx(2)),'mean');
% set colorscale: anatomical (first 64) + functional (second 64)
% grayscale for MRI; jet for painted activation
set(st.fig,'Colormap',[gray(64);jet(64)]);
set(st.fig,'Colormap',[gray(64);cfg.colormap]);
otherwise
fun = nmt_ts_intervalpower(st.nmt.fun{cfg.axsel}(:,cfg.time_idx(1):cfg.time_idx(2),cfg.freq_idx(1):cfg.freq_idx(2)),'rms');
fun = nmt_ts_intervalpower(st.nmt.fun{axsel}(:,cfg.time_idx(1):cfg.time_idx(2),cfg.freq_idx(1):cfg.freq_idx(2)),'rms');
% set colorscale: anatomical (first 64) + functional (second 64)
% grayscale for MRI; jet for painted activation
set(st.fig,'Colormap',[gray(64);hot(64)]);
Expand Down Expand Up @@ -108,160 +113,6 @@ function nmt_spm_plot(cfg)
set(st.nmt.gui.beamin,'String',sprintf('%+g',funval));


%nmt_update_panel(axsel)

%% update time series, if applicable
if(isfield(st.nmt,'time')) %& ~isfield(st.nmt,'freq'))
set(st.nmt.gui.timeguih,'Visible','On'); % ensure plot is visible
switch(st.nmt.cfg.plottype)
case 'tf'
set(st.nmt.gui.freqguih,'Visible','On'); % ensure plot is visible
if(all(st.nmt.freq(1,:) == [0 0])) % if the first row contains evoked data
nmt_tfplot(st.nmt.gui.ax_ts(cfg.axsel),st.nmt.time,st.nmt.freq(2:end,:),squeeze(st.nmt.fun{cfg.axsel}(st.nmt.cfg.vox_idx,:,2:end)),@nmt_repos_start);
else
nmt_tfplot(st.nmt.gui.ax_ts(cfg.axsel),st.nmt.time,st.nmt.freq,squeeze(st.nmt.fun{cfg.axsel}(st.nmt.cfg.vox_idx,:,:)),@nmt_repos_start);
end
case 'ts'
if(isfinite(st.nmt.cfg.vox_idx))
plot(st.nmt.gui.ax_ts(cfg.axsel),st.nmt.time,squeeze(st.nmt.fun{cfg.axsel}(st.nmt.cfg.vox_idx,:,:)));
grid(st.nmt.gui.ax_ts(cfg.axsel),'on');
else
plot(st.nmt.gui.ax_ts(cfg.axsel),st.nmt.time,nan(length(st.nmt.time),1));
end

% set y-axis range based on whole volume range (single time point), or
% selected timeslice range
if(st.nmt.cfg.time_idx(1)==st.nmt.cfg.time_idx(2))
ymin = min(st.nmt.fun{cfg.axsel}(:));
ymax = max(st.nmt.fun{cfg.axsel}(:));
else
ymin = min(min(st.nmt.fun{cfg.axsel}(:,st.nmt.cfg.time_idx(1):st.nmt.cfg.time_idx(2))));
ymax = max(max(st.nmt.fun{cfg.axsel}(:,st.nmt.cfg.time_idx(1):st.nmt.cfg.time_idx(2))));
end
set(st.nmt.gui.ax_ts(cfg.axsel),'YLim',[ymin ymax]);

end
set(st.nmt.gui.ax_ts(cfg.axsel),'XLim',st.nmt.time([1 end]));
xlabel(st.nmt.gui.ax_ts(cfg.axsel),['Time (s)']);


%% plot vertical line indicating selected time point
switch(st.nmt.cfg.plottype)
case 'ts'
ylim=get(st.nmt.gui.ax_ts(cfg.axsel),'YLim');
case 'tf'
ylim = [st.nmt.freq(st.nmt.cfg.freq_idx(1),1) st.nmt.freq(st.nmt.cfg.freq_idx(2),2)];
end
axes(st.nmt.gui.ax_ts(cfg.axsel));
zlim = get(st.nmt.gui.ax_ts(cfg.axsel),'ZLim'); % selection patch needs to have a Z higher than the TF range so that it's not hidden by the TF plot
h=patch([st.nmt.time(st.nmt.cfg.time_idx(1)) st.nmt.time(st.nmt.cfg.time_idx(2)) st.nmt.time(st.nmt.cfg.time_idx(2)) st.nmt.time(st.nmt.cfg.time_idx(1))]',[ylim(1) ylim(1) ylim(2) ylim(2)]',[zlim(2) zlim(2) zlim(2) zlim(2)],[1 0.4 0.4],'EdgeColor','red');

set(st.nmt.gui.ax_ts(cfg.axsel),'ButtonDownFcn',@nmt_repos_start);


switch('disabled') % TODO: hook for overlaying time series on TF plot;
% perhaps better solution is independent nmt_spm_plot call for each funparameter
case 'tf'
if(st.nmt.cfg.evokedoverlay)
% trick to overlay time series taken from plotyy.m
ylim=get(st.nmt.gui.ax_ts(cfg.axsel,2),'YLim');
ts=squeeze(st.nmt.fun{cfg.axsel}(st.nmt.cfg.vox_idx,:,1));

axes(st.nmt.gui.ax_ts(cfg.axsel,2));
plot(st.nmt.gui.ax_ts(cfg.axsel,2),st.nmt.time,ts);
set(st.nmt.gui.ax_ts(cfg.axsel,2),'YAxisLocation','right','Color','none', ...
'XGrid','off','YGrid','off','Box','off', ...
'HitTest','off','Visible','on');
end
end

%% update GUI textboxes
set(st.nmt.gui.t1,'String',num2str(st.nmt.time(st.nmt.cfg.time_idx(1))));
set(st.nmt.gui.t2,'String',num2str(st.nmt.time(st.nmt.cfg.time_idx(2))));

if(1)
set(st.nmt.gui.f1,'Value',st.nmt.cfg.freq_idx(1));
set(st.nmt.gui.f2,'Value',st.nmt.cfg.freq_idx(2));
else
set(st.nmt.gui.f1,'String',num2str(st.nmt.freq(st.nmt.cfg.freq_idx(1),1)));
set(st.nmt.gui.f2,'String',num2str(st.nmt.freq(st.nmt.cfg.freq_idx(2),2)));
end

%% optionally add topoplot
switch(st.nmt.cfg.topoplot)
case 'timelock'
cfgplot.xlim = st.nmt.time(st.nmt.cfg.time_idx);
cfgplot.zlim = 'maxabs';
nmt_addtopo(cfgplot,st.nmt.timelock);
case {'spatialfilter','leadfield','leadfieldX','leadfieldY','leadfieldZ','leadfieldori'}
% FIXME: this isn't so elegant :-)
% currently steals some information from timelock structure
topo.label = st.nmt.timelock.label;
topo.grad = st.nmt.timelock.grad;
topo.dimord = 'chan_time';
topo.time = [0 1 2 3]; % not really time, but selection of magnitude or x/y/z components
switch(cfg.topoplot)
case 'spatialfilter'
topo.time = 0; % fake time (take vector norm)
cfgplot.xlim = [topo.time topo.time];
cfgplot.zlim = 'maxabs';
topo.avg = st.nmt.spatialfilter{st.nmt.cfg.vox_idx}';
case {'leadfield','leadfieldX','leadfieldY','leadfieldZ'}
switch(cfg.topoplot)
case 'leadfield'
topo.time = 0; % fake time (take vector norm)
topo.avg = nut_rownorm(st.nmt.grid.leadfield{st.nmt.cfg.vox_idx}); % TODO: remove dependency on nut_rownorm (from NUTMEG)
case 'leadfieldX'
topo.time = 1;
topo.avg = st.nmt.grid.leadfield{st.nmt.cfg.vox_idx};
case 'leadfieldY'
topo.time = 2;
topo.avg = st.nmt.grid.leadfield{st.nmt.cfg.vox_idx};
case 'leadfieldZ'
topo.time = 3;
topo.avg = st.nmt.grid.leadfield{st.nmt.cfg.vox_idx};
end
cfgplot.xlim = [topo.time topo.time];
cfgplot.zlim = 'maxabs';
% case 'leadfieldX'
% topo.time = 1; % fake time (corresponds to x-orientation)
% cfgplot.xlim = [topo.time topo.time];
% cfgplot.zlim = 'maxabs';
% topo.avg = st.nmt.grid.leadfield{st.nmt.cfg.vox_idx};
% case 'leadfieldY'
% topo.time = 2; % fake time (corresponds to y-orientation)
% cfgplot.xlim = [topo.time topo.time];
% cfgplot.zlim = 'maxabs';
% topo.avg = st.nmt.grid.leadfield{st.nmt.cfg.vox_idx};
% case 'leadfieldZ'
% topo.time = 3; % fake time (corresponds to z-orientation)
% cfgplot.xlim = [topo.time topo.time];
% cfgplot.zlim = 'maxabs';
% topo.avg = nut_rownorm(st.nmt.grid.leadfield{st.nmt.cfg.vox_idx});
% case 'leadfieldori'
% error('TODO: not yet implemented');
end

nmt_addtopo(cfgplot,topo);
case {'no',''}
% do nothing
otherwise
error('requested cfg.topoplot parameter is not supported.');
end
end




function nmt_repos_start(varargin)
global st
set(gcbf,'windowbuttonmotionfcn',@nmt_repos_move, 'windowbuttonupfcn',@nmt_repos_end);
nmt_timeselect('ts');
%_______________________________________________________________________
%_______________________________________________________________________
function nmt_repos_move(varargin)
nmt_timeselect('ts');
%_______________________________________________________________________
%_______________________________________________________________________
function nmt_repos_end(varargin)
set(gcbf,'windowbuttonmotionfcn','', 'windowbuttonupfcn','');

20 changes: 10 additions & 10 deletions contrib/nutmegtrip/nmt_spmfig_setup.m
Expand Up @@ -235,24 +235,24 @@ function nmt_spmfig_setup(cfg)
if(1) % popup menu for frequency selection
st.nmt.gui.f1 = uicontrol('Style','popupmenu','String',num2str(1),'BackgroundColor',nmt_textboxcolor,'Parent',st.fig);
% set(st.nmt.gui.f1,'Position',[offx+s*Dims(1)+4*skx+100 offy+s*Dims(2)-100 80 25],...
set(st.nmt.gui.f1,'Position',[offx+s*Dims(1)+4*skx+35 sz(2) 40 25],...
set(st.nmt.gui.f1,'Position',[offx+s*Dims(1)+4*skx+35 sz(2) 50 25],...
'HorizontalAlignment','right','Visible','off','Callback','nmt_timeselect(''textbox'')');
st.nmt.gui.freqguih(2) = st.nmt.gui.f1;

st.nmt.gui.freqguih(3) = uicontrol(fg,'Style','Text','String','to','BackgroundColor',[1 1 1],'HorizontalAlignment','left','Parent',st.fig,...
'Position',[offx+s*Dims(1)+4*skx+80 sz(2)-5 50 25],'Visible','off');
'Position',[offx+s*Dims(1)+4*skx+90 sz(2)-5 50 25],'Visible','off');
% 'Position',[offx+s*Dims(1)+4*skx+185 offy+s*Dims(2)-105 50 25],'Visible','off');


st.nmt.gui.f2 = uicontrol('Style','popupmenu','String',num2str(1),'BackgroundColor',nmt_textboxcolor,'Parent',st.fig,...
'Position',[offx+s*Dims(1)+4*skx+95 sz(2) 40 25],...
'Position',[offx+s*Dims(1)+4*skx+105 sz(2) 50 25],...
'HorizontalAlignment','right','Visible','off','Callback','nmt_timeselect(''textbox'')');
% 'Position',[offx+s*Dims(1)+4*skx+205 offy+s*Dims(2)-100 80 25],...
% 'HorizontalAlignment','right','Visible','off','Callback','nmt_timeselect(''textbox'')');
st.nmt.gui.freqguih(4) = st.nmt.gui.f2;

st.nmt.gui.freqguih(5) = uicontrol(fg,'Style','Text','String','Hz','BackgroundColor',[1 1 1],'HorizontalAlignment','left','Parent',st.fig,...
'Position',[offx+s*Dims(1)+4*skx+140 sz(2)-5 50 25],'Visible','off');
'Position',[offx+s*Dims(1)+4*skx+160 sz(2)-5 50 25],'Visible','off');
else % individual text boxes for frequency selection
st.nmt.gui.f1 = uicontrol('Style','edit','String',num2str(1),'BackgroundColor',nmt_textboxcolor,'Parent',st.fig);
set(st.nmt.gui.f1,'Position',[offx+s*Dims(1)+4*skx+100 offy+s*Dims(2)-100 80 25],...
Expand Down Expand Up @@ -280,19 +280,19 @@ function nmt_spmfig_setup(cfg)
'Position',[offx+s*Dims(1)+4*skx 20 50 25],...
'Callback','nmt_peaksearch_helper;');
st.nmt.gui.peakdomain = uicontrol(fg,'Style','PopupMenu','String',{'spatiotemporal','spatial','temporal'},'BackgroundColor',nmt_textboxcolor,'HorizontalAlignment','right','Parent',st.fig,...
'Position',[offx+s*Dims(1)+4*skx+50 20 100 25]);
'Position',[offx+s*Dims(1)+4*skx+50 20 150 25]);
st.nmt.gui.peaktype = uicontrol(fg,'Style','PopupMenu','String',{'mag','max','min'},'BackgroundColor',nmt_textboxcolor,'HorizontalAlignment','right','Parent',st.fig,...
'Position',[offx+s*Dims(1)+4*skx+150 20 45 25]);
'Position',[offx+s*Dims(1)+4*skx+195 20 55 25]);
st.nmt.gui.searchradius1 = uicontrol('Style','edit','String',num2str(0),'BackgroundColor',nmt_textboxcolor,'Parent',st.fig,...
'Position',[offx+s*Dims(1)+4*skx+205 20 30 25],...
'Position',[offx+s*Dims(1)+4*skx+260 20 30 25],...
'HorizontalAlignment','right','Visible','on');
uicontrol(fg,'Style','Text','String','to','BackgroundColor',[1 1 1],'HorizontalAlignment','left','Parent',st.fig,...
'Position',[offx+s*Dims(1)+4*skx+240 15 30 25]);
'Position',[offx+s*Dims(1)+4*skx+295 15 30 25]);
st.nmt.gui.searchradius2 = uicontrol('Style','edit','String',num2str(200),'BackgroundColor',nmt_textboxcolor,'Parent',st.fig,...
'Position',[offx+s*Dims(1)+4*skx+255 20 30 25],...
'Position',[offx+s*Dims(1)+4*skx+310 20 30 25],...
'HorizontalAlignment','right','Visible','on');
uicontrol(fg,'Style','Text','String','mm from cursor','BackgroundColor',[1 1 1],'HorizontalAlignment','left','Parent',st.fig,...
'Position',[offx+s*Dims(1)+4*skx+295 15 100 25]);
'Position',[offx+s*Dims(1)+4*skx+350 15 150 25]);



Expand Down
9 changes: 5 additions & 4 deletions contrib/nutmegtrip/nmt_timeselect.m
Expand Up @@ -5,8 +5,8 @@ function nmt_timeselect(op)
op = '';
end

% TODO: how do we determine which axis was clicked? compare with gca??
axsel = st.nmt.gui.ax_ts(1);
%axsel = st.nmt.gui.ax_ts(1);
axsel = gca; % for multi panel support

switch(op)
case 'ts'
Expand Down Expand Up @@ -59,6 +59,7 @@ function nmt_timeselect(op)
st.nmt.cfg.time_idx = st.nmt.cfg.time_idx([2 1]);
end


nmt_spm_plot

for funidx=1:length(st.nmt.fun);
nmt_update_panel(funidx)
end
4 changes: 3 additions & 1 deletion contrib/nutmegtrip/private/getdimord.m
Expand Up @@ -341,7 +341,7 @@
dimord = 'rpt_pos_freq';
end

case {'mom'}
case {'mom','itc','aa','stat','pval','statitc','pitc'}
if isequal(datsiz, [npos nori nrpt])
dimord = 'pos_ori_rpt';
elseif isequal(datsiz, [npos nori ntime])
Expand Down Expand Up @@ -378,6 +378,8 @@
dimord = 'pos_rpt_ori_time';
elseif isequalwithoutnans(datsiz, [npos nrpt 1 ntime])
dimord = 'pos_rpt_ori_time';
elseif isequal(datsiz, [npos nfreq ntime])
dimord = 'pos_freq_time';
end

case {'filter'}
Expand Down
15 changes: 8 additions & 7 deletions contrib/nutmegtrip/private/nmt_tfplot.m
@@ -1,4 +1,4 @@
function nmt_tfplot(axh,twin,fwin,tf,ButtonDownFcn)
function h_tf = nmt_tfplot(axh,twin,fwin,tf,zlim,ButtonDownFcn)
% nutmegtrip uses this helper function to plot time-frequency data

% reformat beam.bands and corresponding tf info to include gaps
Expand All @@ -25,11 +25,11 @@ function nmt_tfplot(axh,twin,fwin,tf,ButtonDownFcn)

global st

st.nmt.gui.h_tf = mesh(axh,t,ffin,z);
h_tf = mesh(axh,t,ffin,z);
view(axh,2); % '2-D view' of spectrogram
%set(st.nmt.gui.h_tf,'LineStyle','none'); % useful if plot made with 'surf'
set(st.nmt.gui.h_tf,'ButtonDownFcn',ButtonDownFcn); % click on TF plot triggers CallbackFcn
set(st.nmt.gui.h_tf,'LineWidth',2); % seems to prevent faint lines around each TF datapoint
%set(h_tf,'LineStyle','none'); % useful if plot made with 'surf'
set(h_tf,'ButtonDownFcn',ButtonDownFcn); % click on TF plot triggers CallbackFcn
set(h_tf,'LineWidth',2.5); % seems to prevent faint lines around each TF datapoint

% limit labels to defined frequencies
ytick = unique(f);
Expand All @@ -46,8 +46,9 @@ function nmt_tfplot(axh,twin,fwin,tf,ButtonDownFcn)
end
end

caxis(axh,[st.vols{1}.blobs{1}.min st.vols{1}.blobs{1}.max*33/32]);
colormap(axh,[jet(128); 1 1 1]);
%caxis(axh,[st.vols{1}.blobs{1}.min st.vols{1}.blobs{1}.max*17/16]);
caxis(axh,[zlim(1) zlim(2)*17/16]);
colormap(axh,[st.nmt.cfg.colormap; 1 1 1]);
set(axh,'Color','none'); % make blank bits transparent

% xlabel(axh,'Time');
Expand Down

0 comments on commit 29e8a0c

Please sign in to comment.