function vis_trajgui(trajStruct,arg)

% VIS_TRAJGUI subfuntion for SOM_TRAJECTORY
%
% This function is the actual GUI called by SOM_TRAJECTORY
% function.
%
% See also SOM_TRAJECTORY.

% Contributed code to SOM Toolbox 2.0, February 11th, 2000 by Juha Parhankangas
% Copyright (c) by Juha Parhankangas.
% http://www.cis.hut.fi/projects/somtoolbox/

% Version 2.0beta juha 180699

if nargin == 1

  sM_h=trajStruct.figure;

  if size(trajStruct.bmus,1) ~= 1 && size(trajStruct.bmus,2) ~= 1
    fuzzy_traj(trajStruct,[]);
    return;
  end

  if size(trajStruct.bmus,1) == 1 || size(trajStruct.bmus,2) == 1

    udata.bmus = trajStruct.bmus;
    udata.a_h=[findobj(get(sM_h,'Children'),'Tag','Uplane');...
	       findobj(get(sM_h,'Children'),'Tag','Cplane')];
    udata.sM_h=trajStruct.figure;
    udata.traj=[];
    data1 = trajStruct.primary_data;
    if ~isempty(trajStruct.primary_names)
      names=trajStruct.primary_names;
    else
      for i=1:size(data1,2)
	names{i,1}=sprintf('Var%d',i);
      end
    end

    udata.lattice=trajStruct.lattice;
    form = 0.7*vis_patch(udata.lattice);
    udata.msize = trajStruct.msize;

    %%%%%%%%%%%%%%%%%%%%%%%%
    %
    % forming a patch object, which is placed above every component plane
    %

    l = size(form,1);

    nx = repmat(form(:,1),1,prod(udata.msize));
    ny = repmat(form(:,2),1,prod(udata.msize));

    x=reshape(repmat(1:udata.msize(2),l*udata.msize(1),1),l,prod(udata.msize));
    y=repmat(repmat(1:udata.msize(1),l,1),1,udata.msize(2));

    if strcmp(udata.lattice,'hexa')
      t = find(~rem(y(1,:),2));
      x(:,t)=x(:,t)+.5;
    end
    x=x+nx;
    y=y+ny;

    colors=reshape(ones(prod(udata.msize),1)*[NaN NaN NaN],...
		   [1 prod(udata.msize) 3]);

    set(0,'CurrentFigure',udata.sM_h);

    %%%%%%%%%%%%%%%%%%%%%%
    %
    % drawing patch
    %
    % caxis -commands keep the colormap of the original patch unchanged.
    %

    for i=1:length(udata.a_h)
      udata.real_patch(i)=get(udata.a_h(i),'Children');
      set(udata.real_patch(i),'ButtonDownFcn',...
			'vis_trajgui([],''click'')');
      subplot(udata.a_h(i));
      v=caxis;
      udata.tmp_patch(i)=patch(x,y,colors,'EdgeColor','none',...
			       'ButtonDownFcn',...
			       'vis_trajgui([],''click'')',...
			       'Tag','TmpPatch');
      caxis(v);
    end

    %%%%%%%%%%%%%%%%%%%%

    udata.length_of_traj=length(trajStruct.size);
    udata.size=trajStruct.size;
    udata.color=trajStruct.color;
    udata.poly.x=[];
    udata.poly.y=[];
    udata.poly.h=[];
    udata.new_marks=[];
    udata.all_marks=[];
    udata.d_mark2=[];
    udata.fig1 = figure;
    set(udata.fig1,'KeyPressFcn','vis_trajgui([],''key'')',...
		   'Name','Primary Data');

    %%%%%%%%%%%%%%%%%%%%
    %
    % making the 'Tools' -menu
    %

    udata.m_i=uimenu(udata.fig1,'Label','Trajectoy T&ools');
    udata.m_i(2)=uimenu(udata.m_i,'Label','&Remove Trajectory',...
			'Callback',...
			'vis_trajgui([],''remove_traj'')');
    udata.m_i(3)=uimenu(udata.m_i(1),'Label','&Dye Nodes',...
			'Callback',...
			'vis_trajgui([],''dye_gui'')');
    udata.m_i(4)=uimenu(udata.m_i(1),'Label','&Clear Markers',...
			'Callback',...
			'vis_trajgui([],''clear'')');
    udata.m_i(5)=uimenu(udata.m_i(1),'Label','&Save',...
			'Callback',...
			'vis_trajgui([],''save'')');
    udata.m_i(6)=uimenu(udata.m_i(1),'Label','&Load',...
			'Callback',...
			'vis_trajgui([],''load'')');

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %
    % drawing data components to the figure ....
    %
    %

    if nargin < 5 || isempty(comps) || (ischar(comps) && strcmp(comps,'all'))
      comps = 1:size(data1,2);
    end

    x=1:size(data1,1);

    for i=1:length(comps)
      subplot(length(comps),1,i);
      udata.h(i)=gca;
      udata.d_mark(i).h=[];

      udata.d(i)=plot(x,data1(:,comps(i)),...
		      'ButtonDownFcn',...
		      'vis_trajgui([],''line_down'')');
      set(gca,'XLim',[1 size(data1,1)],...
	      'XTick',[],...
	      'ButtonDownFcn','vis_trajgui([],''line_down'')'); %,...
	      %'YLim',[min(data1(:,comps(i))) max(data1(:,comps(i)))]);

      ylabel(names{comps(i)});
      hold on;
      ymin=get(udata.h(i),'YLim');
      pos=mean(get(udata.h(i),'XLim'));
      udata.l(i) = line([pos pos],[ymin(1) ymin(2)],...
			'Color','red',...
			'ButtonDownFcn',...
			'vis_trajgui([],''down'')');
    end
    udata.text1=[];

    udata.fig2=[];
    udata.h2=[];
    udata.l2=[];
    udata.text2=[];

    %%%%%%%%%%%%%%%%%%%%%%%%%%%
    %
    % ... and to the figure 2.
    %

    if ~isempty(trajStruct.secondary_data)
      data2=trajStruct.secondary_data;
      if isempty(trajStruct.secondary_names)
	for i=1:size(data1,2)
	  names2{i,1}=sprintf('Var%d',i);
	end
      else
	names2=trajStruct.secondary_names;
      end

      udata.fig2 = figure;
      set(udata.fig2,'Name','Secondary Data');
      set(udata.fig2,'KeyPressFcn',...
		     'vis_trajgui([],''key'')');
      for i=1:size(data2,2)
	subplot(size(data2,2),1,i);
	udata.h2(i) = gca;
	udata.d_mark2(i).h=[];
	udata.d2(i) = plot(x,data2(:,i),...
			   'ButtonDownFcn',...
			   'vis_trajgui([],''line_down'')');
	set(gca,'XLim',[1 size(data1,1)],'XTick',[],'ButtonDownFcn',...
		'vis_trajgui([],[],[],[],[],[],''line_down'')');
	ylabel(names2{i});
	hold on;
	ymin = get(udata.h2(i),'YLim');
	pos = mean(get(udata.h2(i),'XLim'));
	udata.l2(i) = line([pos pos],ymin,'Color','red',...
			   'ButtonDownFcn','vis_trajgui([],''down'')');
      end
    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%

    set(udata.fig1,'UserData',udata);
    if ~isempty(udata.fig2);
      tmp.fig1=udata.fig1;
      set(udata.fig2,'UserData',tmp);
    end
    tmp=get(udata.sM_h,'UserData');
    tmp.fig1=udata.fig1;
    set(udata.sM_h,'UserData',tmp);
    set_numbers(round(pos));
    return;
  end

end

%%%%%%%%%%%%%%%%%
%
% if figures have been drawn, the only function calls that may exist
% are the ones that change the state of the application.
%
udata=get(gcf,'UserData');
udata=get(udata.fig1,'UserData');

switch arg
 case 'fuzzy'
  fuzzy_traj(tS,[]);
  return;
 case 'move_fuzzy'
  fuzzy_traj([],'move');
  return;
 case 'remove_traj'
  remove_traj;
  return;
 case 'line_down'
  line_bdf('down');
  return;
 case 'line_drag'
  line_bdf('drag');
  return;
 case 'line_up'
  line_bdf('up');
  return;
 case 'dye_gui';
  color_gui(udata.fig1);
  return;
 case {'dye','cyan','magenta','yellow','red','green','blue','white','grey'}
  dye_nodes(arg);
  return;
 case 'clear'
  clear_markers;
  return;
 case 'key'
  key_bdf;
  return;
 case 'click'
  click;
  return;
 case 'save'
  save_data;
  return;
 case 'load'
  load_data;
  return;
end

%%%%%%%%%%
%
% lines in the data figure(s) are dragged ...
%

udata=get(gcf,'UserData');
udata=get(udata.fig1,'UserData');

lims=get(gca,'XLim');
x = getfield(get(gca,'CurrentPoint'),{1});  % the location of the line

if x < lims(1)
  x=lims(1);
elseif x > lims(2)
  x=lims(2);
end

old = gcf;

switch arg
 case 'down',...

  % mouse button is pressed down above the line

  set(gcf,'WindowButtonMotionFcn','vis_trajgui([],''drag'')');
  set(gcf,'WindowButtonUpFcn','vis_trajgui([],''up'')');
  set(udata.l,'EraseMode','xor');
  delete(udata.text1);
  if ~isempty(udata.l2);
    set(udata.l2,'EraseMode','xor');
    delete(udata.text2);
  end
  set(gcf,'Pointer','crosshair');

 case 'drag'
  % change the location of the lines

  set(0,'CurrentFigure',udata.fig1);
  set(udata.l,'XData',[x x]);
  if ~isempty(udata.fig2)
    set(0,'CurrentFigure',udata.fig2);
    set(udata.l2,'XData',[x x]);
  end
  draw_traj(round(x));
  set(0,'CurrentFigure',old);
 case 'up'

  % draw trajectory and set figure to the normal state.

  set(udata.l,'EraseMode','normal');
  set(gcf,'Pointer','arrow','WindowButtonMotionFcn','',...
	  'WindowButtonUpFcn','');
  draw_traj(round(x));
  set_numbers(round(x));
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function draw_traj(point)

udata=get(gcf,'UserData');
udata=get(udata.fig1,'UserData');
color=udata.color;
eMode='normal';
if ischar(udata.color) && strcmp(udata.color,'xor')
  eMode='xor';
  color='black';
end
ind=udata.bmus(point);
[i j] = ind2sub(udata.msize,ind);
if ~mod(i,2)
  j=j+0.5;
end
old = gcf;
set(0,'CurrentFigure',udata.sM_h);
hold on;
if isempty(udata.traj) || length(udata.traj.h) ~= length(udata.a_h)

  % trajectory does not exist

  for i=1:length(udata.a_h)
    subplot(udata.a_h(i));
    hold on;
    new.h = plot(j,i,'Color',color,'EraseMode',eMode,'LineStyle','none');
    udata.traj.h(i)=new;
    udata.traj.j=j;
    udata.traj.i=i;
  end
else
  if length(udata.traj.j) == udata.length_of_traj
    % if the length of trajectory == ...,
    udata.traj.j(1) = [];         % the first (the oldest) coordinate pair
    udata.traj.i(1) = [];         % is removed.
  end
  udata.traj.j=[udata.traj.j;j]; % the new point is added to the
  udata.traj.i=[udata.traj.i;i]; % end of coordinate vectors (i and j)
  for i=1:length(udata.a_h)
    subplot(udata.a_h(i));            % remove the existing trajectory
    delete(udata.traj.h(i).h);          % and plot the new one.
    for j=1:length(udata.traj.j)
      udata.traj.h(i).h(j)=plot(udata.traj.j(j),udata.traj.i(j),...
				'Color',color,...
				'EraseMode',eMode,'Marker','o','LineWidth',2,...
				'MarkerSize',udata.size(udata.length_of_traj-j+1),...
				'LineStyle','none');
    end
  end
end
set(0,'CurrentFigure',udata.fig1);
set(udata.fig1,'UserData',udata);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function set_numbers(x)

% This function writes the numbers beside of the pointer lines

udata=get(gcf,'UserData');
udata=get(udata.fig1,'UserData');

xlim = get(gca,'XLim');
ylim = get(gca,'YLim');
p = ylim(1) + 0.9*(ylim(2)-ylim(1));

old = gcf;
set(0,'CurrentFigure',udata.fig1);

for i=1:length(udata.h)
  subplot(udata.h(i));

  % check if the text is placed to the left side of the line...

  if abs(x-xlim(1)) > (abs(x-xlim(2)))
    udata.text1(i)=text(x-1,p,sprintf('%d ->',x),...
                        'VerticalAlignment','top',...
                        'HorizontalAlignment','right',...
                        'FontWeight','demi');
  else

    %  or to the right side.

    udata.text1(i)=text(x+1,p,sprintf('<- %d',x),...
			'VerticalAlignment','top',...
			'FontWeight','demi');
  end
end

if ~isempty(udata.fig2)
  set(0,'CurrentFigure',udata.fig2);

  for i=1:length(udata.h2)
    subplot(udata.h2(i));

    if abs(x-xlim(1)) > (abs(x-xlim(2)))
      udata.text2(i)=text(x-1,p,sprintf('%d ->',x),...
			  'VerticalAlignment','top',...
			  'HorizontalAlignment','right',...
			  'FontWeight','demi');
    else
      udata.text2(i)=text(x+1,p,sprintf('<- %d',x),...
			  'VerticalAlignment','top',...
			  'FontWeight','demi');
    end
  end
end

set(0,'CurrentFigure',old);
set(udata.fig1,'UserData',udata);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function remove_traj()

% delete trajectory -object from every component plane.

udata=get(gcf,'UserData');
udata=get(udata.fig1,'UserData');

if isempty(udata.traj)
  return;
end

for i=1:length(udata.traj.h)
  delete(udata.traj.h(i).h);
end

udata.traj=[];
set(udata.fig1,'UserData',udata);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function line_bdf(arg)

% this function takes care of action when region is selected in the
% data figure.

udata=get(gcf,'UserData');
udata=get(udata.fig1,'UserData');
xlim=get(gca,'XLim');

if ~(any(strcmp('THIS',fieldnames(udata))))
  p = getfield(get(gca,'CurrentPoint'),{1});
else
  p = getfield(get(udata.THIS,'CurrentPoint'),{1});
end

if p < xlim(1)
  p = xlim(1);
elseif p > xlim(2)
  p = xlim(2);
end

switch arg
 case 'down'

  % the mouse button is pressed down, the pointer lines are drawn.
  % and the state of the figure is changed.

  udata.THIS=gca;
  set(gcf,'WindowButtonMotionFcn',...
	  'vis_trajgui([],''line_drag'')',...
	  'WindowButtonUpFcn','vis_trajgui([],''line_up'')');
  udata.start_p=p;

  old = gcf;
  set(0,'CurrentFigure',udata.fig1);

  for i=1:length(udata.h)
    subplot(udata.h(i));
    udata.t_line.h(i)=line([p p],get(gca,'YLim'),'Color','red');
    udata.t_line.h2(i)=line([p p],get(gca,'YLim'),'Color','red',...
			    'EraseMode','xor');
  end
  if ~isempty(udata.h2)
    set(0,'CurrentFigure',udata.fig2);
    for i=1:length(udata.h2)
      subplot(udata.h2(i));
      udata.t_line2.h(i)=line([p p],get(gca,'YLim'),'Color','red');
      udata.t_line2.h2(i)=line([p p],get(gca,'YLim'),'Color','red',...
			       'EraseMode','xor');
    end
  end

 case 'drag'

  % change the position of the pointer lines

  old = gcf;
  set(0,'CurrentFigure',udata.fig1);
  set(udata.t_line.h2,'XData',[p p]);
  if ~isempty(udata.fig2)
    set(0,'CurrentFigure',udata.fig2);
    set(udata.t_line2.h2,'XData',[p p]);
  end
  set(0,'CurrentFigure',old);
 case 'up'

  % sort the 'points' -vector and draw the markers to the data and nodes

  points=sort([round(udata.start_p) round(p)]);
  draw_markers(points(1):points(2));
  udata=get(udata.fig1,'UserData');
  udata.new_marks=unique([udata.new_marks ;(points(1):points(2))']);
  delete([udata.t_line.h2 udata.t_line.h]);
  if ~isempty(udata.fig2)
    delete([udata.t_line2.h2 udata.t_line2.h]);
  end
  set(get(udata.THIS,'Parent'),'WindowButtonMotionFcn','',...
		    'WindowButtonUpFcn','');
  udata=rmfield(udata,'THIS');
end

set(udata.fig1,'UserData',udata);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function draw_markers(x)

plot2data(x);
plot2plane(x);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function plot2data(x)

% plot black markers to the data figure(s)

udata=get(gcf,'UserData');
udata=get(udata.fig1,'UserData');

old = gcf;

set(0,'CurrentFigure',udata.fig1);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% if there already exist points in the positions that are members
% of the set x, then the old points are removed from data figures...

for i=1:length(udata.d_mark(1).h)
  tmp1 = get(udata.d_mark(1).h(i),'XData');
  tmp2 = setdiff(tmp1,x);
  if length(tmp1) ~= length(tmp2)
    inds=[];
    for j=1:length(tmp2);
      inds=[inds find(tmp2(j)==tmp1)];
    end
    for j=1:length(udata.d_mark)
      ydata=getfield(get(udata.d_mark(j).h(i),'YData'),{inds});
      set(udata.d_mark(j).h(i),'XData',tmp2,'YData',ydata);
    end
    if ~isempty(udata.fig2)
      for j=1:length(udata.d_mark2)
        ydata=getfield(get(udata.d_mark2(j).h(i),'YData'),{inds});
        set(udata.d_mark2(j).h(i),'XData',tmp2,'YData',ydata);
      end
    end
  end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% ... and the new ones are plotted.

for i=1:length(udata.h)
  subplot(udata.h(i));
  h=plot(x,getfield(get(udata.d(i),'YData'),{x}),'oblack',...
	 'ButtonDownFcn',...
	 'vis_trajgui([],''line_down'')');
  udata.d_mark(i).h=[udata.d_mark(i).h;h];
end

if ~isempty(udata.h2)
  set(0,'CurrentFigure',udata.fig2);

  for i=1:length(udata.h2)
    subplot(udata.h2(i));
    h=plot(x,getfield(get(udata.d2(i),'YData'),{x}),'oblack',...
	   'ButtonDownFcn',...
	   'vis_trajgui([],''line_down'')');
    udata.d_mark2(i).h=[udata.d_mark2(i).h;h];
  end
end

set(0,'CurrentFigure',old);
set(udata.fig1,'UserData',udata);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function plot2plane(x)

% sets markers to the component planes.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% actually new markers are never plotted, but the color of the patch
% lying above the original component plane patch is changed black in
% the right positions.

udata=get(gcf,'UserData');
udata=get(udata.fig1,'UserData');

udata.new_marks=unique([udata.new_marks ;x']);

for i=1:length(udata.a_h)
  col=get(udata.tmp_patch(i),'FaceVertexCData');
  if length(size(col)) == 3
    col = reshape(col,[size(col,1) 3]);
  end
  for j=1:length(udata.new_marks)
    col(udata.bmus(udata.new_marks(j)),:)=[0 0 0];
  end
  set(udata.tmp_patch(i),'FaceVertexCData',col);
end

set(udata.fig1,'UserData',udata);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function color_gui(fig1)

% construct the graphical user interface for changing the color of the
% black (marked) nodes.

udata=get(fig1,'UserData');

a = figure('Color',[0.8 0.8 0.8], ...
	   'Name','Colors', ...
	   'PaperType','a4letter', ...
	   'Position',[518 456 120 311], ...
	   'Tag','Fig1');

udata.c_struct.fig=a;

b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'BackgroundColor',[0.701961 0.701961 0.701961], ...
	      'Position',[0.0700415 0.28956 0.830492 0.594566], ...
	      'Style','frame', ...
	      'Tag','Frame1');
b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'BackgroundColor',[0.8 0.8 0.8], ...
	      'Position',[0.100059 0.301143 0.770456 0.571399], ...
	      'Style','frame', ...
	      'Tag','Frame2');

b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'Callback','vis_trajgui([],''cyan'')', ...
	      'Position',[0.130077 0.795326 0.170101 0.0617729], ...
	      'Style','radiobutton', ...
	      'Tag','cyan', ...
	      'Value',1);

b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'Callback','vis_trajgui([],''magenta'')', ...
	      'Position',[0.130077 0.733553 0.170101 0.057912], ...
	      'Style','radiobutton', ...
	      'Tag','magenta');

b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'Callback','vis_trajgui([],''yellow'')', ...
	      'Position',[0.130077 0.664059 0.170101 0.0617729], ...
	      'Style','radiobutton', ...
	      'Tag','yellow');

b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'Callback','vis_trajgui([],''red'')', ...
	      'Position',[0.130077 0.590703 0.170101 0.0617729], ...
	      'Style','radiobutton', ...
	      'Tag','red');

b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'Callback','vis_trajgui([],''green'')', ...
	      'Position',[0.130077 0.525068 0.170101 0.057912], ...
	      'Style','radiobutton', ...
	      'Tag','green');

b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'Callback','vis_trajgui([],''blue'')', ...
	      'Position',[0.130077 0.455575 0.170101 0.0617729], ...
	      'Style','radiobutton', ...
	      'Tag','blue');

b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'Callback','vis_trajgui([],''white'')', ...
	      'Position',[0.130077 0.38608 0.170101 0.0617729], ...
	      'Style','radiobutton', ...
	      'Tag','white');

b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'Callback','vis_trajgui([],''grey'')', ...
	      'Position',[0.130077 0.320447 0.170101 0.057912], ...
	      'Style','radiobutton', ...
	      'Tag','grey');

b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'BackgroundColor',[0.8 0.8 0.8], ...
	      'FontWeight','demi', ...
	      'HorizontalAlignment','left', ...
	      'Position',[0.32019 0.795326 0.470278 0.0501905], ...
	      'String','Cyan', ...
	      'Style','text', ...
	      'Tag','StaticText1');
b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'BackgroundColor',[0.8 0.8 0.8], ...
	      'FontWeight','demi', ...
	      'HorizontalAlignment','left', ...
	      'Position',[0.32019 0.733553 0.520308 0.0463296], ...
	      'String','Magenta', ...
	      'Style','text', ...
	      'Tag','StaticText2');
b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'BackgroundColor',[0.8 0.8 0.8], ...
	      'FontWeight','demi', ...
	      'HorizontalAlignment','left', ...
	      'Position',[0.32019 0.664059 0.470278 0.0501905], ...
	      'String','Yellow', ...
	      'Style','text', ...
	      'Tag','StaticText3');
b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'BackgroundColor',[0.8 0.8 0.8], ...
	      'FontWeight','demi', ...
	      'HorizontalAlignment','left', ...
	      'Position',[0.32019 0.590703 0.470278 0.0501905], ...
	      'String','Red', ...
	      'Style','text', ...
	      'Tag','StaticText4');
b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'BackgroundColor',[0.8 0.8 0.8], ...
	      'FontWeight','demi', ...
	      'HorizontalAlignment','left', ...
	      'Position',[0.32019 0.525068 0.470278 0.0463296], ...
	      'String','Green', ...
	      'Style','text', ...
	      'Tag','StaticText5');
b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'BackgroundColor',[0.8 0.8 0.8], ...
	      'FontWeight','demi', ...
	      'HorizontalAlignment','left', ...
	      'Position',[0.32019 0.455575 0.470278 0.0463296], ...
	      'String','Blue', ...
	      'Style','text', ...
	      'Tag','StaticText6');
b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'BackgroundColor',[0.8 0.8 0.8], ...
	      'FontWeight','demi', ...
	      'HorizontalAlignment','left', ...
	      'Position',[0.32019 0.38608 0.470278 0.0501905], ...
	      'String','White', ...
	      'Style','text', ...
	      'Tag','StaticText7');
b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'BackgroundColor',[0.8 0.8 0.8], ...
	      'FontWeight','demi', ...
	      'HorizontalAlignment','left', ...
	      'Position',[0.32019 0.320447 0.470278 0.0463296], ...
	      'String','Grey', ...
	      'Style','text', ...
	      'Tag','StaticText8');
b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'Position',[0.0700415 0.146711 0.830492 0.135128], ...
	      'Style','frame', ...
	      'Tag','Frame3');
b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'BackgroundColor',[0.8 0.8 0.8], ...
	      'Position',[0.100059 0.158293 0.770456 0.111963], ...
	      'Style','frame', ...
	      'Tag','Frame4');
b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'BackgroundColor',[0.8 0.8 0.8], ...
	      'FontWeight','demi', ...
	      'HorizontalAlignment','left', ...
	      'Position',[0.130077 0.177597 0.270833 0.0617729], ...
	      'String','RGB', ...
	      'Style','text', ...
	      'Tag','StaticText9');
b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'BackgroundColor',[1 1 1], ...
	      'Position',[0.410243 0.173736 0.420249 0.0810768], ...
	      'Style','edit', ...
	      'Tag','EditText1');

udata.c_struct.RGB=b;

b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'Callback','vis_trajgui([],''dye'')', ...
	      'FontWeight','demi', ...
	      'Position',[0.0700415 0.0270256 0.360214 0.0772162], ...
	      'String','OK', ...
	      'Tag','Pushbutton1');
b = uicontrol('Parent',a, ...
	      'Units','normalized', ...
	      'Callback','close gcf', ...
	      'FontWeight','demi', ...
	      'Position',[0.54032 0.0270256 0.360214 0.0772162], ...
	      'String','Close', ...
	      'Tag','Pushbutton2');

udata.c_struct.color=[0 1 1];

tmp.fig1=fig1;
set(a,'UserData',tmp);
set(udata.fig1,'UserData',udata);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function dye_nodes(arg)

% takes care of the action, when radiobuttons are pressed
% (or the RGB value is set) in the color_gui -figure.
% It also handles the starting of dying nodes and plots.

udata=get(gcf,'UserData');
udata=get(udata.fig1,'UserData');

switch arg
 case {'cyan','magenta','yellow','red','green','blue','white','grey'}
  h=findobj(get(gcf,'Children'),'Style','radiobutton');
  set(h,'Value',0);
  set(gcbo,'Value',1);
end

switch arg
 case 'cyan'
  RGB = [0 1 1];
 case 'magenta'
  RGB = [1 0 1];
 case 'yellow'
  RGB = [1 1 0];
 case 'red'
  RGB = [1 0 0];
 case 'green'
  RGB = [0 1 0];
 case 'blue'
  RGB = [0 0 1];
 case 'white'
  RGB = [1 1 1];
 case 'grey'
  RGB = [0.4 0.4 0.4];
 case 'dye'

  RGB = get(udata.c_struct.RGB,'String');
  if isempty(RGB)
    dye;
    return;
  else
    str1='The value of RGB must be vector containing three scalars';
    str2='between 0 and 1.';
    color = str2num(RGB);
    set(udata.c_struct.RGB,'String','');
    if isempty(color)
      close gcf;
      udata=rmfield(udata,'c_struct');
      set(udata.fig1,'UserData',udata);
      errordlg([{str1};{str2}]);
      return;
    end
    if ~all([1 3] == size(color)) && ~all([3 1] == size(color))
      close gcf;
      errordlg([{str1};{str2}]);
      udata=rmfield(udata,'c_struct',udata);
      set(udata.fig1,'UserData',udata);
      return;
    end
    if ~isempty(cat(2,find(color>1),find(color<0)))
      close gcf
      errordlg([{str1};{str2}]);
      udata=rmfield(udata,'c_struct',udata);
      set(udata.fig1,'UserData',udata);
      return;
    end
    udata.c_struct.color=color;
    set(udata.fig1,'UserData',udata);
    dye;
    return;
  end
end

udata.c_struct.color=RGB;
set(udata.fig1,'UserData',udata);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function dye()

% dyes black markers in the component planes and in the data figures

udata=get(gcf,'UserData');
udata=get(udata.fig1,'UserData');

inds=unique([udata.all_marks ; udata.new_marks]);

for i=1:length(udata.d_mark);
  for j=1:length(udata.d_mark(i).h)
    if all(get(udata.d_mark(i).h(j),'Color') == [0 0 0])
      set(udata.d_mark(i).h(j),'Color',udata.c_struct.color);
    end
  end
end

if ~isempty(udata.fig2);
  for i=1:length(udata.d_mark2)
    for j=1:length(udata.d_mark2(i).h)
      if all(get(udata.d_mark2(i).h(j),'Color') == [0 0 0])
        set(udata.d_mark2(i).h(j),'Color',udata.c_struct.color);
      end
    end
  end
end

for i=1:length(udata.a_h)
  col=get(udata.tmp_patch(i),'FaceVertexCData');
  for j=1:length(udata.new_marks)
    col(udata.bmus(udata.new_marks(j)),:)=udata.c_struct.color;
  end
  set(udata.tmp_patch(i),'FaceVertexCData',col);
end

udata.all_marks=unique([udata.all_marks;udata.new_marks]);
udata.new_marks=[];
close gcf;
udata=rmfield(udata,'c_struct');
set(udata.fig1,'UserData',udata);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function clear_markers()

% removes markers from the componentplanes and the data figure(s).

udata=get(gcf,'UserData');
udata=get(udata.fig1,'UserData');

for i=1:length(udata.d_mark)
  delete(udata.d_mark(i).h);
  udata.d_mark(i).h=[];
end

for i=1:length(udata.d_mark2)
  delete(udata.d_mark2(i).h);
  udata.d_mark2(i).h=[];
end

col=NaN*get(udata.tmp_patch(1),'FaceVertexCData');
col=reshape(col,[size(col,1) 3]);

for i=1:length(udata.tmp_patch)
  set(udata.tmp_patch(i),'FaceVertexCData',col);
end

udata.new_marks=[];
udata.all_marks=[];

if any(strcmp('c_struct',fieldnames(udata)))
  udata=rmfield(udata,'c_struct');
end

set(udata.fig1,'UserData',udata);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function key_bdf

% moves trajectory and pointer lines, when either of
% the keys '>' or '<' is pressed.

udata=get(gcf,'UserData');
udata=get(udata.fig1,'UserData');

key=get(gcbo,'CurrentCharacter');

% The easiest way to get a new coordinates is to get them from the texts...
% The texts are either '<- x' or 'x ->'

x=get(udata.text1(1),'String');
x=str2num(x(4:length(x)));

if isempty(x)
  x=get(udata.text1(1),'String');
  x=str2num(x(1:length(x)-3));
end

switch(key)
 case '<'
  if x ~= 1
    x= x-1;
  end
 case '>'
  if x ~= getfield(get(get(udata.text1(1),'Parent'),'XLim'),{2})
    x = x+1;
  end
 otherwise
  return;
end

set(udata.l,'XData',[x x]);
if ~isempty(udata.fig2)
  set(udata.l2,'XData',[x x]);
end

delete(udata.text1);
delete(udata.text2);

set_numbers(x);
draw_traj(x);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function click()

switch get(gcf,'SelectionType')
 case 'open'
  return;
 case {'normal','alt'}
  draw_poly;
 case 'extend'
  click_node;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function click_node()

% takes care of the action, when the middle mouse button is
% pressed (mouse pointer is above some component plane).

udata=get(gcf,'UserData');
udata=get(udata.fig1,'UserData');
new_marks=[];

old=gcf;

NEW=0;
AGAIN = 0;

coords=get(gca,'CurrentPoint');
row=round(coords(1,2));

if strcmp(udata.lattice,'hexa') && ~mod(row,2)
  col = round(coords(1,1) - 0.5);
else
  col = round(coords(1,1));
end

ind = sub2ind(udata.msize,row,col);
new_marks=find(udata.bmus==ind);

if strcmp(get(gcbo,'Tag'),'TmpPatch');

  % if the callback is made via temporary patch object, node is marked
  % (node is black) => the mark is to be removed

  node_color = getfield(get(gcbo,'FaceVertexCData'),{ind,[1:3]});
  AGAIN = 1;
end

for i=1:length(udata.tmp_patch)
  color = get(udata.tmp_patch(i),'FaceVertexCData');
  if length(size(color)) ~= 2
    color = reshape(color,[size(color,1) 3]);
  end
  if all(isnan(color(ind,:)))
    NEW=1;
    color(ind,:)=[0 0 0];
  else
    color(ind,:)=[NaN NaN NaN];
  end
  set(udata.tmp_patch(i),'FaceVertexCData',color);
end

set(0,'CurrentFigure',udata.fig1);

for j=1:length(udata.h)
  subplot(udata.h(j));
  if NEW
    y=getfield(get(udata.d(j),'YData'),{new_marks});
    udata.d_mark(j).h=[udata.d_mark(j).h;plot(new_marks,y,'Color',[0 0 0],...
                                              'LineStyle','none',...
                                              'Marker','o')];
  end
end

if ~isempty(udata.fig2)
  set(0,'CurrentFigure',udata.fig2);
  for j=1:length(udata.h2);
    subplot(udata.h2(j));
    if NEW
      y=getfield(get(udata.d2(j),'YData'),{new_marks});
      udata.d_mark2(j).h=[udata.d_mark2(j).h;plot(new_marks,y,...
						  'LineStyle','none',...
						  'Color','black',...
						  'Marker','o')];
    end
  end
end

if NEW
  udata.new_marks=[udata.new_marks; new_marks];
end

if AGAIN

  % find marks from the data that map to the clicked node. if the color
  % of the mark(s) is the same as the node's color, remove mark(s), else
  % let mark be unchanged.

  for i=1:length(udata.d_mark(1).h)
    if all(node_color==get(udata.d_mark(1).h(i),'Color'))
      tmp1 = get(udata.d_mark(1).h(i),'XData');
      tmp2 = setdiff(tmp1,new_marks);
      if length(tmp1) ~= length(tmp2)
        inds=[];
        for j=1:length(tmp2);
          inds=[inds find(tmp2(j)==tmp1)];
        end
        for j=1:length(udata.d_mark)
          ydata=getfield(get(udata.d_mark(j).h(i),'YData'),{inds});
          set(udata.d_mark(j).h(i),'XData',tmp2,'YData',ydata);
        end
        if ~isempty(udata.fig2)
          for j=1:length(udata.d_mark2)
            ydata=getfield(get(udata.d_mark2(j).h(i),'YData'),{inds});
            set(udata.d_mark2(j).h(i),'XData',tmp2,'YData',ydata);
          end
        end
      end
    end
  end
  udata.new_marks=setdiff(udata.new_marks, new_marks);
  udata.all_marks=setdiff(udata.all_marks,new_marks);
end

set(udata.fig1,'UserData',udata);
set(0,'CurrentFigure',old);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function draw_poly()

udata=get(gcf,'UserData');
udata=get(udata.fig1,'UserData');

if isempty(udata.poly.x)
  if strcmp(get(gcf,'SelectionType'),'alt')
    return;
  end
  udata.poly.THIS = gca;
end

% 'THIS' indicates what was the axes where the polygon was meant to
% drawn. It is not possible to add points, that lie in another axes, to the
% polygon.

if gca ~= udata.poly.THIS
  return;
end

coords(1,1) = getfield(get(gca,'CurrentPoint'),{3});
coords(1,2) = getfield(get(gca,'CurrentPoint'),{1});

udata.poly.x=cat(1,udata.poly.x,coords(2));
udata.poly.y=cat(1,udata.poly.y,coords(1));

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% remove old 'polygon' from axis

delete(udata.poly.h);

switch get(gcf,'SelectionType')
 case 'normal'

  % add point to the 'polygon' and draw it

  for i=1:length(udata.a_h)
    subplot(udata.a_h(i));
    hold on;
    udata.poly.h(i) = plot(udata.poly.x,udata.poly.y,'black',...
			   'EraseMode','xor',...
			   'ButtonDownFcn',...
			   'vis_trajgui([],''click'')',...
			   'LineWidth',2);
  end
 case 'alt'

  % The polygon is ready.

  udata.poly.x=cat(1,udata.poly.x,udata.poly.x(1));
  udata.poly.y=cat(1,udata.poly.y,udata.poly.y(1));

  for i=1:length(udata.a_h)
    subplot(udata.a_h(i));
    udata.poly.h(i) = plot(udata.poly.x,udata.poly.y,'black',...
			   'EraseMode','xor',...
			   'ButtonDownFcn',...
			   'vis_trajgui([],''click'')',...
			   'LineWidth',2);
  end

  tmp=sort(repmat((1:udata.msize(1))',udata.msize(2),1));
  tmp(:,2)=repmat((1:udata.msize(2))',udata.msize(1),1);
  tmp2=tmp;
  if strcmp(udata.lattice,'hexa');
    t=find(~rem(tmp(:,1),2));
    tmp(t,2)=tmp(t,2)+0.5;
  end

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % find the nodes that lie inside polygon and change coordinates to
  % linear indices.

  in = find(inpolygon(tmp(:,2),tmp(:,1),udata.poly.x,udata.poly.y));
  in = sub2ind(udata.msize,tmp2(in,1),tmp2(in,2));

  colors=get(udata.tmp_patch(1),'FaceVertexCData');
  colors=reshape(colors,[size(colors,1) 3]);
  tmp=ones(length(in),1);

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % set the color of the nodes just selected, black.

  colors(in,:)=tmp*[0 0 0];
  set(udata.tmp_patch,'FaceVertexCData',colors);

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % find the points mapping to the nodes from data

  inds = [];
  for i=1:length(in)
    inds=[inds;find(in(i) == udata.bmus)];
  end

  %%%%%%%%%%%%%%%%%%%
  % plot marks to data

  set(udata.fig1,'UserData',udata);
  plot2data(inds);
  udata=get(udata.fig1,'UserData');
  udata.new_marks=union(udata.new_marks,inds);
  delete(udata.poly.h);
  udata.poly.h=[];
  udata.poly.x=[];
  udata.poly.y=[];
  udata.poly.THIS=[];
end

set(udata.fig1,'UserData',udata);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function save_data()

udata=get(gcf,'UserData');
udata=get(udata.fig1,'UserData');

data.points=[];
data.nodes=[];
k=1;

for i=1:length(udata.d_mark(1).h)
  data.points(i).inds=get(udata.d_mark(1).h(i),'XData');
  data.points(i).color=get(udata.d_mark(1).h(i),'Color');
end

color=get(udata.tmp_patch(1),'FaceVertexCData');
color=reshape(color,[size(color,1) 3]);

for i=1:size(color,1)
  if all(~isnan(color(i,:)))
    tmp.ind=i;
    tmp.color=color(i,:);
    data.nodes(k)=tmp;
    k=k+1;
  end
end

answer=inputdlg('Enter the name of the output variable:','',1);

if isempty(answer) || isempty(answer{1})
  msgbox('Output is not set to workspace.');
  return;
else
  assignin('base',answer{1},data);
  sprintf(1,'Struct is set to the workspace as ''%s''.',answer{1});
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function load_data()

answer = inputdlg('Enter the name of the struct to be loaded:','',1);

if isempty(answer) || isempty(answer{1})
  msgbox('Data is not loaded.');
  return;
end

data=evalin('base',answer{1});

if ~isstruct(data)
  errordlg('Input variable must be a struct.');
  return;
end

tmp1 = fieldnames(data);
tmp2 = {'nodes','points'};

for i=1:length(tmp1)
  for j=1:length(tmp2);
    if ~any(strcmp(tmp2{j},tmp1))
      errordlg('Wrong type of struct.');
      return;
    end
  end
end

if ~isempty(data.points)
  tmp1=fieldnames(data.points(1));
end
if ~isempty(data.nodes)
  tmp2=fieldnames(data.nodes(1));
end

for i=1:length(tmp1)
  if ~any(strcmp(tmp1{i},{'inds','color'}))
    errordlg('Wrong type of struct.');
    return;
  end
end

for i=1:length(tmp2)
  if ~any(strcmp(tmp2{i},{'ind','color'}))
    errordlg('Wrong type of struct.');
    return;
  end
end

udata=get(gcf,'UserData');
udata=get(udata.fig1,'UserData');

clear_markers;
remove_traj;

old = gcf;

for i=1:length(data.points)
  for j=1:length(udata.h);
    set(0,'CurrentFigure',udata.fig1);
    subplot(udata.h(j));
    ydata=getfield(get(udata.d(j),'YData'),{data.points(i).inds});
    udata.d_mark(j).h=[udata.d_mark(j).h;...
                       plot(data.points(i).inds,ydata,...
			    'Color',data.points(i).color,...
			    'LineStyle','none',...
			    'Marker','o',...
			    'ButtonDownFcn',...
			    'vis_trajgui([],''line_down'')')];
    if all(data.points(i).color == [0 0 0])
      udata.new_marks=unique([udata.new_marks; (data.points(i).inds)']);
    else
      udata.all_marks=unique([udata.all_marks; (data.points(i).inds)']);
    end
  end
  if ~isempty(udata.fig2)
    set(0,'CurrentFigure',udata.fig2);
    for j=1:length(udata.h2)
      subplot(udata.h2(j));
      ydata=getfield(get(udata.d2(j),'YData'),{data.points(i).inds});
      udata.d_mark2(j).h=[udata.d_mark2(j).h;...
                          plot(data.points(i).inds,ydata,...
			       'Color',data.points(i).color,...
			       'LineStyle','none',...
			       'Marker','o',...
			       'ButtonDownFcn',...
			       'vis_trajgui([],''line_down'')')];
    end
  end
end

set(0,'CurrentFigure',udata.sM_h);
color=get(udata.tmp_patch(1),'FaceVertexCData');
color=reshape(color,[size(color,1) 3]);
for i=1:length(data.nodes)
  color(data.nodes(i).ind,:)=data.nodes(i).color;
end
for i=1:length(udata.tmp_patch);
  set(udata.tmp_patch(i),'FaceVertexCData',color);
end

set(0,'CurrentFigure',old);
set(udata.fig1,'UserData',udata);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function fuzzy_traj(trajStruct,arg)
%function fuzzy_traj(sM_h,sM,sD,interval,arg)

if isempty(arg)

  if strcmp(trajStruct.lattice,'hexa')
    udata.lattice='hexa';
    udata.form=vis_patch('hexa');
  else
    data.lattice='rect';
    udata.form=vis_patch('rect');
  end

  % interval=[1 size(trajStruct.primary_data,1)];

  l=size(udata.form,1);
  dim = size(trajStruct.primary_data,2);
  udata.a_h=[findobj(get(trajStruct.figure,'Children'),'Tag','Uplane');...
             findobj(get(trajStruct.figure,'Children'),'Tag','Cplane')];

  udata.sM_h=trajStruct.figure;
  udata.msize=trajStruct.msize;

  %%%%%%%%%%%%%%%
  %
  % constructing patch that is drawn above every plane in map
  %

  nx = repmat(udata.form(:,1),1,prod(udata.msize));
  ny = repmat(udata.form(:,2),1,prod(udata.msize));

  x_c=reshape(repmat(1:udata.msize(2),l*udata.msize(1),1),l,prod(udata.msize));
  y_c=repmat(repmat(1:udata.msize(1),l,1),1,udata.msize(2));

  if strcmp(udata.lattice,'hexa')
    t = find(~rem(y_c(1,:),2));
    x_c(:,t)=x_c(:,t)+.5;
  end

  x_c=x_c+nx;
  y_c=y_c+ny;

  udata.orig_c=ones(prod(udata.msize),1)*[NaN NaN NaN];
  colors=reshape(udata.orig_c,[1 size(udata.orig_c,1) 3]);
  set(0,'CurrentFigure',trajStruct.figure);

  %%%%%%%%%
  % drawing

  for i=1:length(udata.a_h);
    subplot(udata.a_h(i));
    v=caxis;
    udata.patch_h(i) =patch(x_c,y_c,colors,'EdgeColor','none');
    caxis(v);
  end

  udata.orig_x=get(udata.patch_h(1),'XData');
  udata.orig_y=get(udata.patch_h(1),'YData');

  %  if interval(1) < 1 | interval(2) > size(trajStruct.primary_data,1)
  %    error('Invalid argument ''interval''.');
  %  end

  x=1:size(trajStruct.primary_data,1);
  udata.fig1=figure;
  set(udata.fig1,'KeyPressFcn',...
                 'vis_trajgui([],''move_fuzzy'')');
  for i=1:size(trajStruct.primary_data,2)
    subplot(size(trajStruct.primary_data,2),1,i);
    udata.h(i)=gca;
    set(udata.h(1),'XTick',[]);
    udata.d(i)=plot(x,trajStruct.primary_data(:,i));
    l_x=1;
    lims(1) = round(min(trajStruct.primary_data(:,i)));
    lims(2) = round(max(trajStruct.primary_data(:,i)));
    udata.l(i) = line([l_x l_x],lims,'Color','red','EraseMode','xor');
  end

  udata.l_x = l_x;
  udata.interval=[1 size(trajStruct.bmus,2)];

  tmp.fig1=udata.fig1;
  %  [K,P] = estimate_kernels(sM,sD);
  %  udata.K=K;
  %  udata.P=P;
  %  udata.codebook=sM.codebook;
  %  udata.data=sD.data;
  udata.bmus=trajStruct.bmus;
  set(udata.fig1,'UserData',udata);
  set(trajStruct.figure,'UserData',tmp);
  draw_fuzzy(l_x);
  return;
end

move_fuzzy;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function draw_fuzzy(x)

udata=get(gcf,'UserData');
udata=get(udata.fig1,'UserData');

inds = find(udata.bmus(:,x));
[row col] = ind2sub(udata.msize,inds);
if strcmp(udata.lattice,'hexa')
  t=find(~mod(row,2));
  col(t)=col(t)+0.5;
end

color=udata.orig_c;
color=reshape(color,[size(color,1) 3]);
xdata=udata.orig_x;
ydata=udata.orig_y;
tmp= ones(size(xdata(:,1),1),1)*udata.bmus(inds,x)';
color(inds,:) = ones(length(inds),1)*[0 0 0];
xdata(:,inds) = udata.form(:,1)*ones(1,length(inds)).*tmp+ones(6,1)*col';
ydata(:,inds) = udata.form(:,2)*ones(1,length(inds)).*tmp+ones(6,1)*row';

set(udata.patch_h,'FaceVertexCData',color,'XData',xdata,'YData',ydata);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function move_fuzzy

% moves pointer lines and draws fuzzy response.

udata=get(gcf,'UserData');
udata=get(udata.fig1,'UserData');

switch get(gcf,'CurrentCharacter');
 case {'<','>'}
  key = get(gcf,'CurrentCharacter');
  if key == '>'
    if udata.l_x + 1 > udata.interval(2)
      return;
    end
    l_x = udata.l_x + 1;
  else
    if udata.l_x - 1 < udata.interval(1)
      return;
    end
    l_x = udata.l_x - 1;
  end
  draw_fuzzy(l_x);
  set(udata.l,'XData',[l_x l_x]);
  udata.l_x=l_x;
  set(udata.fig1,'UserData',udata);
 otherwise
  return;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


function v = cvxtuple( varargin )

if nargin == 1,
    v = varargin{1};
    switch class( v ),
        case 'struct',
            if numel( v ) ~= 1,
                cvx_throw( 'struct arrays not permitted in cvx tuple objects.' );
            end
        case 'cell',
            v = reshape( v, 1, numel( v ) );
        otherwise,
            return
    end
else
    v = varargin;
end
v = class( struct( 'value_', { v }, 'dual_', { [] } ), 'cvxtuple' );

% Copyright 2005-2014 CVX Research, Inc.
% See the file LICENSE.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


function [obj, rawDb, filteredDb] =  get_antelope_traces(obj)
   % GET_ANTELOPE_TRACE gets interesting data from database, and returns the tracebuf object
   % [tr(1:end)] =  get_antelope_trace(startdates, enddates, criteriaList, database)
   %    STARTDATE is a matlab datenum
   %    ENDDATE is also in matlab datenum
   %    CRITERIALIST is a cell of statements used to filter the antelope
   %        database.  example: {'sta=="OKCF"','chan=="BHZ"'}
   %    DATABASE can either be a database name, or an open antelope database
   %    pointer.
   %
   %    TR is a tracebuf object containing the data requested.
   %
   %  In this usage, with a single output argument, TR, the database is opened
   %  and then closed before the function returns.
   %
   % You can opt to keep the database open, which can make subsequent calls to
   % get_antelope_trace much faster.  To do this, ask for the database pointer
   % as one of the output arguments.  The database will be closed by any
   % function call that uses the database pointer as the 'database' parameter,
   % and does not ask for a database pointer back.
   %
   % [tr, mydb] = get_antelope_trace(...)
   %    if mydb is asked for, then the database will not be closed, allowing for
   %    more efficient reuse.  mydb is the unfiltered (and open) wfdisc table
   %
   % [tr, mydb, filteredDB] = get_antelope_trace(...)
   %   returns wfdisc table in mydb, and a filtered wfdisc table in filteredDB
   %
   % if no records are found, then tr will be set to []
   %
   % will generate error message if no records found, so consider using in a
   % TRY-CATCH loop.
   %
   %
   % Example:
   %  % set up the data
   %  sDate = datenum('7/12/2008 05:00:00.00');
   %  eDate = datenum('7/12/2008 05:10:00.00');
   %  stationsToGet = {'OKFG','OKSO','OMG'};
   %  channelsToGet = {'BHZ', 'BHE'};
   %  mydb = '/mydir/my_antelope_database';
   %
   %  % get our criteria together
   %  for st = 1:numel(stationsToGet)
   %    staCriteria(st) = {sprintf('sta=="%s"',stationsToGet(st)};
   %  end
   %  for ch = 1:numel(channelsToGet)
   %    chanCriteria(ch) = {sprintf('chan=="%s"',channelsToGet(ch)};
   %  end
   %
   %  % open the database once, and read in each tracebuf. Then translate into
   %  % waveforms.
   %  n = 1;
   %  for sta = 1:numel(staCriteria)
   %    for ch = 1:numel(chanCriteria)
   %      critera = [chanCriteria(ch),staCriteria(sta)];
   %      [tr, mydb] = get_antelope_trace(sDate,eDate, criteria, mydb)
   %      w(n) = traceToWaveform(tr);
   %      n = n+1;
   %    end
   %  end
   %  % finally, close up shop.
   %  dbclose(mydb)

   % Modifications
   %%% Glenn Thompson 2012/02/06: Occasionally the C program trload_css cannot even load the trace data. Added try...catch..end to handle this.

   useExistingDatabasePtr =  obj.pointsToAntelopeDatabase;

   if useExistingDatabasePtr
      try
         dbnrecs(obj.dbpointer);
      catch
         warning('Waveform:load_antelope:databaseNotOpen', ...
            'a Database Pointer was passed to trace, but the database was not open');
         %tr = trnew; %return a new object, forcing the ability to destroy it later
         obj.trpointer = { -1 };
         return;
      end
   end

   % do not close the database if a pointer is asked for in the return arguments
   onFinishCloseDB = nargout < 2;

   antelope_starts = mep2dep(obj.startdate);
   antelope_ends = mep2dep(obj.enddates);

   if ~obj.isopen()
      obj = obj.open();
   end

   %if the database isn't already open, then open it for reading
   if ~obj.pointsToAntelopeDatabase
      obj = obj.open();
   else
      mydb = obj.dbpointer;
   end
   %check to ensure wfdisk table exists and is populated

   if obj.nrecs == 0,
      cleanUpFail('Waveform:load_antelope:databaseNotFound', ...
         'Database not found: %s', dbquery(mydb,'dbTABLE_FILENAME'));
      return;
   end;

   rawDb = mydb;   % keep a copy of the pre-subset (raw) database

   % subset the data based upon the desired criteria
   %criteriaList = keepCriteriaThatMatchDatabaseFields(criteriaList, mydb);
   %allExp = getAsExpressions(criteriaList);

   %subset the database based on this particular criterion
   mydb = dbsubset(mydb,allExp);
   if safe_dbnrecs(mydb) == 0
      cleanUpFail('Waveform:load_antelope:dataNotFound', 'No records found for criteria [%s].', allExp);
      return;
   end;

   filteredDb = mydb;

   [st, ed] = dbgetv(mydb,'time','endtime');
   %% Get the tracebuf object for this starttime, endtime
   % Loop through all times.  Result is tr(1:numel(starttimes) of all tracebuffers.
   for mytimeIDX = 1:numel(antelope_starts)
      someDataExists = any(antelope_starts(mytimeIDX)<= (ed) & antelope_ends(mytimeIDX) >= (st));
      if someDataExists
         %%% Glenn Thompson 2012/02/06: Occasionally the C program trload_css cannot even load the trace data.
         % This error needs to be handled. So adding a try..catch..end around the original instruction.
         trStructs = safe_trload(db, st, et);
         T = trstruct2SeismicTrace(trStructs);
         try
            obj.trpointer{mytimeIDX} = trload_css(mydb, antelope_starts(mytimeIDX), antelope_ends(mytimeIDX)); %#ok<AGROW>
         catch
            cleanUpFail('Waveform:load_antelope:trload_css failed', ...
               'Database not found: %s', dbquery(mydb,'dbTABLE_FILENAME'));
            disp(obj.dbname)
            disp(allExp)
            starttimes = antelope_starts(mytimeIDX);
            endtimes = antelope_ends(mytimeIDX);
            fprintf('%.0f %.0f\n ',starttimes,endtimes);
            disp(['starttimes: ', datestr(epoch2datenum(starttimes))]);
            disp(['endtimes: ', datestr(epoch2datenum(endtimes))]);
            fprintf('trload_css(mydb, starttimes, endtimes))\n');
            return
         end
         trsplice(obj.trpointer{mytimeIDX},20);
      else
         obj.trpointer{mytimeIDX} = -1; %#ok<AGROW>
      end
   end %mytimeIDX
   closeIfAppropriate(mydb, onFinishCloseDB);

   function cleanUpFail(varargin)
      %cleanUpFail   tidy up database and records and display warning
      closeIfAppropriate(mydb, onFinishCloseDB);
      obj.trpointer = { -1 };
      filteredDb = dbinvalid;
      warning(varargin{:});
   end
end


function newFunction(fxnname)
%CODETEMPLATE creates a new m-file with proper help layout
%
% SYNOPSIS: newFunction(fxnname)
%
% INPUT fxnname: name of the new function. CodeTemplate will check that the
%                function name has not been used yet, and it will ask for
%                additional input, such as H1-line via inputdlg
%
% OUTPUT None. The function creates a new m-file and opens it in the editor
%
% REMARKS
%
% created with MATLAB ver.: 7.10.0.499 (R2010a) on Microsoft Windows 7 Version 6.1 (Build 7600)
%
% created by: Jonas Dorn
% DATE: 31-Mar-2010
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%==============
%% DEFAULTS
%==============

% add common superclass for value and handle classes, respectively
%superclass = {'myClass','myHandle'};
superclass = {[],'handle'};

%===============
%% CHECK INPUT
%===============

% if no input argument, assign empty to functionname
if nargin < 1 || isempty(fxnname) || ~ischar(fxnname)
    fxnname = [];
end

% check whether function already exists - only if given as input
if ~isempty(fxnname)
    fxnCheck = which(fxnname);
    if ~isempty(fxnCheck)
        error('%s already exists: %s',fxnname,fxnCheck)
    end
end

%==============

%================
%% GATHER DATA
%================

% data-gathering stage begins below
% getenv() and version are used to derive environmental variables

% find username. This will return empty on Linux, but we have a line for
% the username in the input dialogue, anyway.
username = getenv('username');

try %#ok<TRYNC>
    % try to resolve user name - I use a function I called username2name to
    % change e.g.  'jdorn' into 'Jonas Dorn'
    username = username2name(username);
end

% get version, OS, date
vers    = version;
datetoday = date;

% getenv('OS') does not work on Mac. Query the OS like ver.m
% find platform OS
if ispc
    platform = [system_dependent('getos'),' ',system_dependent('getwinsys')];
elseif ismac
    [fail, input] = unix('sw_vers');
    if ~fail
        platform = strrep(input, 'ProductName:', '');
        platform = strrep(platform, sprintf('\t'), '');
        platform = strrep(platform, sprintf('\n'), ' ');
        platform = strrep(platform, 'ProductVersion:', ' Version: ');
        platform = strrep(platform, 'BuildVersion:', 'Build: ');
    else
        platform = system_dependent('getos');
    end
else
    platform = system_dependent('getos');
end
os = platform;

% ask for the rest of the input with inputdlg

% set up inputdlg
inPrompt = {'Username',...
    'Function name',...
    'Description: ''FUNCTIONNAME does ...'' (captitalized function name)',...
    'Synopsis: ''[output1, output2] = functionname(input1, input2)',...
    'Description of input arguments (use \n for additional line breaks)',...
    'Description of output arguments (use \n for additional line breaks)',...
    'Function: 1, Value Class: 2, Handle Class: 3, Subclass: superclass-name'};
inTitle = 'Please describe your function';
numLines = repmat([1,100],7,1);
numLines([5,6],1) = 5;
% assign defaultAnswer
[defaultAnswer{1:7}] = deal('');
% assign username in default answers
defaultAnswer{1} = username;
defaultAnswer{7} = '1';
% if we have a function name already, all will be simpler
if ~isempty(fxnname)
    defaultAnswer{2} = fxnname;
    defaultAnswer{3} = sprintf('%s ...', upper(fxnname));
end

% loop till description is ok
ok = false;

while ~ok

    % get input
    description = inputdlg(inPrompt, inTitle, numLines, defaultAnswer);

    % check for user abort
    if isempty(description)
        error('description cancelled by user');
    else
        ok = true; % hope for the best
    end

    % read description. Functionname, description and synopsis are required
    fxnname = description{2};
    if isempty(fxnname) || isempty(description{2})...
            || isempty(description{3}) || isempty(description{4}) ||...
            any(findstr(description{3},'...')) || isempty(regexpi(description{4},fxnname))
        h = errordlg('Username, function name, description and synopsis are required inputs!');
        uiwait(h);
        ok = false;
    end

    % check whether function already exists (again)
    fxnCheck = which(fxnname);
    if ~isempty(fxnCheck)
        h = errordlg('%s already exists: %s',fxnname,fxnCheck);
        uiwait(h);
        ok = false;
    end

    % check for ok and update defaultAnswer with description if necessary
    if ~ok
        defaultAnswer = description;
    end

end % while

% read other input
username = description{1};
desc = description{3};
synopsis = description{4};
% if there are line breaks in inputtext and outputtext: make sure that
% these lines will still be commented!
inputtext = description{5};
% add line breaks if necessary, turn into single line of text
if size(inputtext,1) > 1
    inputtext = [inputtext,repmat('\n',size(inputtext,1),1)];
    inputtext(end,end-1:end) = ' ';
    inputtext = inputtext';
    inputtext = inputtext(:)';
    % kill some white space
    inputtext = regexprep(inputtext,'(\s*)\\n','\\n');
end
if strfind(inputtext,'\n')
    inputtext = regexprep(inputtext,'\\n','\\n%%\\t\\t');
end
outputtext = description{6};
if size(outputtext,1) > 1
    outputtext = [outputtext,repmat('\n',size(outputtext,1),1)];
    outputtext(end,end-1:end) = ' ';
    outputtext = outputtext';
    outputtext = outputtext(:)';
    outputtext = regexprep(outputtext,'(\s*)\\n','\\n');
end
if strfind(outputtext,'\n')
    outputtext = regexprep(outputtext,'\\n','\\n%%\\t\\t\\t');
end

% ask for directory to save the function
dirName = uigetdir(pwd,'select save directory');
if dirName == 0
    error('directory selection cancelled by user')
end
% end of data-gathering stage

%=================

%=================
%% WRITE FUNCTION
%=================

% create the filename based on the function name
fsuffix = '.m';
filename = fullfile(dirName,[fxnname fsuffix]);
% end filename creation

% check for function vs. class and add default superclasses if necessary
d7 = str2double(description{7});
if isnan(d7)
    superclass = description{7};
    isClass = true;
elseif d7 == 2 || d7 == 3
    isClass = true;
    superclass = superclass{d7-1};
else
    isClass = false;
end

if ~isClass % it's a function
    % beginning of file-printing stage
    fid = fopen(filename,'wt');
    fprintf(fid,'function %s\n',synopsis);
    fprintf(fid,'%%%s\n',desc);
    fprintf(fid,'%%\n');
    fprintf(fid,'%% SYNOPSIS: %s\n',synopsis);
    fprintf(fid,'%%\n');
    fprintf(fid,['%% INPUT ',inputtext,'\n']);
    fprintf(fid,'%%\n');
    fprintf(fid,['%% OUTPUT ',outputtext,'\n']);
    fprintf(fid,'%%\n');
    fprintf(fid,'%% REMARKS\n');
    fprintf(fid,'%%\n');
    fprintf(fid,'%% created with MATLAB ver.: %s on %s\n',vers,os);
    fprintf(fid,'%%\n');
    fprintf(fid,'%% created by: %s\n',username);
    fprintf(fid,'%% DATE: %s\n',datetoday);
    fprintf(fid,'%%\n');
    fprintf(fid,'%s\n',repmat('%',1,75));
    fclose(fid);
    % end of file-printing stage
else % it's a class
    fid = fopen(filename,'wt');
    fprintf(fid,'%%%s\n',desc);
    fprintf(fid,'%%\n');
    fprintf(fid,'%% CONSTRUCTOR: %s\n',synopsis);
    fprintf(fid,['%%   IN : ',inputtext,'\n']);
    fprintf(fid,['%%   OUT: ',outputtext,'\n']);
    fprintf(fid,'%%\n');
    fprintf(fid,'%% PROPERTIES\n');
    fprintf(fid,'%%   #property1:\n');
    fprintf(fid,'%%\n');
    fprintf(fid,'%% METHODS\n');
    fprintf(fid,'%%   #method1: short description\n');
    fprintf(fid,'%%        out = method1(obj,in)\n');
    fprintf(fid,'%%        Description of input and output\n');
    fprintf(fid,'%%\n');
    fprintf(fid,'%% REMARKS\n');
    fprintf(fid,'%%\n');
    fprintf(fid,'%% created with MATLAB ver.: %s on %s\n',vers,os);
    fprintf(fid,'%%\n');
    fprintf(fid,'%% created by: %s\n',username);
    fprintf(fid,'%% DATE: %s\n',datetoday);
    fprintf(fid,'%%\n');
    fprintf(fid,'%s\n',repmat('%',1,75));
    % subclass myClass or myHandle by default
    if ~isempty(superclass)
        fprintf(fid,'\nclassdef %s < %s\n\nend',fxnname,superclass); %#ok<PFCEL>
    else
        fprintf(fid,'\nclassdef %s\n\nend',fxnname);
    end
    fclose(fid);
end

% pop up the newly generated file
edit(filename);


function container = properties_load(directory, pattern)
% properties_load Load tracker runtime properties from files
%

candidates = dir(fullfile(directory, sprintf('%s_*.value', pattern)));

container = struct();
container.names = {};
container.data = {};

for p = 1:numel(candidates)

    [~, name, ~] = fileparts(candidates(p).name);

    parameter_name = name(length(pattern)+2:end);

    data = cell(0, 0);

    fp = fopen(fullfile(directory, candidates(p).name), 'r');

    while true
         line = fgets(fp);

         if line == -1
             break;
         end

         [value, numeric] = str2num(line(1:end-1)); %#ok<ST2NM>

         if ~numeric
            value = line(1:end-1);
         end

         if isempty(value)
             value = [];
         end;

         data{end+1, 1} = value; %#ok<AGROW>

    end;

    fclose(fp);

    container.names{end+1} = parameter_name;

    if isempty(container.data)
        container.data = data;
    else
        container.data = cat(1, container.data, data);
    end;

end;


% EEG_EVAL - apply eeglab function to a collection of input datasets
%
% Usage:
%   >> OUTEEG = eeg_eval(funcname, INEEG, 'key1', value1, 'key2', value2 ...);
%
% Inputs:
%   funcname      - [string] name of the function
%   INEEG         - EEGLAB input dataset(s)
%
% Optional inputs
%   'params'      - [cell array] funcname parameters.
%   'warning'     - ['on'|'off'] warning pop-up window if several dataset
%                   stored on disk that will be automatically overwritten.
%                   Default is 'on'.
%
% Outputs:
%   OUTEEG        - output dataset(s)
%
% Author: Arnaud Delorme, SCCN, INC, UCSD, 2005
%
% see also: EEGLAB

% Copyright (C) 2005 Arnaud Delorme, Salk Institute, arno@salk.edu
%
% This file is part of EEGLAB, see http://www.eeglab.org
% for the documentation and details.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%
% 1. Redistributions of source code must retain the above copyright notice,
% this list of conditions and the following disclaimer.
%
% 2. Redistributions in binary form must reproduce the above copyright notice,
% this list of conditions and the following disclaimer in the documentation
% and/or other materials provided with the distribution.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
% THE POSSIBILITY OF SUCH DAMAGE.

function [EEG, com] = eeg_eval( funcname, EEG, varargin)

    com = '';
    if nargin < 2
        help eeg_eval;
        return;
    end

    % check input parameters
    % ----------------------
    g = finputcheck( varargin, { 'params'   'cell'    {}               {};
                                 'warning'  'string'  { 'on','off' }   'off' }, 'eeg_eval');
    if ischar(g), error(g); end

    % warning pop up
    % --------------
    eeglab_options;
    if strcmpi(g.warning, 'on')
        if ~option_storedisk
            res = questdlg2(strvcat( 'When processing multiple datasets, it is not', ...
                                 'possible to enter new names for the newly created', ...
                                 'datasets and old datasets are overwritten.', ...
                                 'You may still cancel this operation though.'), ...
                 'Multiple dataset warning', 'Cancel', 'Proceed', 'Proceed');
        else
            res = questdlg2( [ 'Data files on disk will be automatically overwritten.' 10 ...
                                'Are you sure you want to proceed with this operation?' ], ...
                            'Confirmation', 'Cancel', 'Proceed', 'Proceed');
        end
        switch lower(res)
            case 'cancel', return;
            case 'proceed'
        end
        vPar = ver('parallel');
        if option_parallel && ~isempty(vPar)
            res = questdlg2(strvcat( 'You have selected to use the parallel toolbox,', ...
                                 'to process multiple datasets. If you saturate the ', ...
                                 'memory, this could cause your computer to become.', ...
                                 'unresponsive or even crash.'), ...
                 'Multiple dataset warning', 'Cancel', 'Proceed', 'Proceed');
        end
        switch lower(res)
            case 'cancel', return;
            case 'proceed'
        end
    end

    % execute function
    % ----------------
    v = version;
    if str2num(v(1)) == '5' % Matlab 5
        command = [ 'TMPEEG = ' funcname '( TMPEEG, ' vararg2str(g.params) ');' ];
    elseif isstr(funcname)
        eval( [ 'func = @' funcname ';' ] );
    else
        func = funcname;
    end

%     notCompatibleFunc = {
%         @clean_artifacts
%     };

    NEWEEG = EEG;
    if option_parallel
        disp('Using the parallel toolbox to process multiple datasets (change in File > Preferences)');
        myPool = gcp;
        tmpoptions_store = option_storedisk;
        parfor i = 1:length(EEG)
            fprintf('Processing group dataset %d of %d named: %s ****************\n', i, length(EEG), EEG(i).setname);
            TMPEEG    = eeg_retrieve(EEG, i);
            TMPEEG = feval(func, TMPEEG, g.params{:});
            TMPEEG = eeg_checkset(TMPEEG);
            TMPEEG.saved = 'no';
            if tmpoptions_store
                TMPEEG = pop_saveset(TMPEEG, 'savemode', 'resave');
                TMPEEG = update_datafield(TMPEEG);
                NEWEEG(i) = TMPEEG;
                NEWEEG(i).saved = 'yes'; % eeg_store by default set it to no
            else
                NEWEEG(i) = TMPEEG;
                NEWEEG(i).saved = 'yes'; % eeg_store by default set it to no
            end
        end
    else
        for i = 1:length(EEG)
            fprintf('Processing group dataset %d of %d named: %s ****************\n', i, length(EEG), EEG(i).setname);
            TMPEEG    = eeg_retrieve(EEG, i);
            TMPEEG = feval(func, TMPEEG, g.params{:});
            TMPEEG = eeg_checkset(TMPEEG);
            TMPEEG.saved = 'no';
            if option_storedisk
                TMPEEG = pop_saveset(TMPEEG, 'savemode', 'resave');
                TMPEEG = update_datafield(TMPEEG);
            end
            NEWEEG = eeg_store(NEWEEG, TMPEEG, i);
            if option_storedisk
                NEWEEG(i).saved = 'yes'; % eeg_store by default set it to no
            end
        end
    end
    EEG = NEWEEG;

    % history
    % -------
    if nargout > 1
        com = sprintf('%s = %s( %s,%s);', inputname(2), char(funcname), inputname(2), vararg2str(g.params));
    end

function EEG = update_datafield(EEG)
    if ~isfield(EEG, 'datfile'), EEG.datfile = ''; end
    if ~isempty(EEG.datfile)
        EEG.data = EEG.datfile;
    else
        EEG.data = 'in set file';
    end
    EEG.icaact = [];


function [output,status] = plugin_urlread(urlChar,method,params)
%URLREAD Returns the contents of a URL as a string.
%   S = URLREAD('URL') reads the content at a URL into a string, S.  If the
%   server returns binary data, the string will contain garbage.
%
%   S = URLREAD('URL','method',PARAMS) passes information to the server as
%   part of the request.  The 'method' can be 'get', or 'post' and PARAMS is a
%   cell array of param/value pairs.
%
%   [S,STATUS] = URLREAD(...) catches any errors and returns 1 if the file
%   downloaded successfully and 0 otherwise.
%
%   Examples:
%   s = urlread('http://www.mathworks.com')
%   s = urlread('ftp://ftp.mathworks.com/README')
%   s = urlread(['file:///' fullfile(prefdir,'history.m')])
%
%   From behind a firewall, use the Preferences to set your proxy server.
%
%   See also URLWRITE.

%   Adapted by A. Delorme from
%   Matthew J. Simoneau, 13-Nov-2001
%   Copyright 1984-2011 The MathWorks, Inc.
%   $Revision: 1.3.2.12 $ $Date: 2011/09/03 22:43:00 $

% This function requires Java.
if ~usejava('jvm')
   error(message('MATLAB:urlread:NoJvm'));
end

if exist('OCTAVE_VERSION', 'builtin') == 0
    import com.mathworks.mlwidgets.io.InterruptibleStreamCopier;

    % Be sure the proxy settings are set.
    com.mathworks.mlwidgets.html.HTMLPrefs.setProxySettings
end

% Check number of inputs and outputs.
if ~ischar(urlChar)
    error('MATLAB:urlread:InvalidInput','The first input, the URL, must be a character array.');
end
if (nargin > 1) && ~strcmpi(method,'get') && ~strcmpi(method,'post')
    error('MATLAB:urlread:InvalidInput','Second argument must be either "get" or "post".');
end

% Do we want to throw errors or catch them?
if nargout == 2
    catchErrors = true;
else
    catchErrors = false;
end

% Set default outputs.
output = '';
status = 0;

% GET method.  Tack param/value to end of URL.
if (nargin > 1) && strcmpi(method,'get')
    if mod(length(params),2) == 1
        error('MATLAB:urlread:InvalidInput','Invalid parameter/value pair arguments.');
    end
    for i=1:2:length(params)
        if (i == 1), separator = '?'; else separator = '&'; end
        param = char(java.net.URLEncoder.encode(params{i}));
        value = char(java.net.URLEncoder.encode(params{i+1}));
        urlChar = [urlChar separator param '=' value];
    end
end

% Create a urlConnection.
[urlConnection,errorid,errormsg] = plugin_urlreadwrite(mfilename,urlChar);
if isempty(urlConnection)
    if catchErrors, return
    else error(errorid,errormsg);
    end
end
urlConnection.setReadTimeout(5000); % timeout in 5 seconds

% POST method.  Write param/values to server.
if (nargin > 1) && strcmpi(method,'post')
    try
        urlConnection.setDoOutput(true);
        urlConnection.setRequestProperty( ...
            'Content-Type','application/x-www-form-urlencoded');
        printStream = java.io.PrintStream(urlConnection.getOutputStream);
        for i=1:2:length(params)
            if (i > 1), printStream.print('&'); end
            param = char(java.net.URLEncoder.encode(params{i}));
            value = char(java.net.URLEncoder.encode(params{i+1}));
            printStream.print([param '=' value]);
        end
        printStream.close;
    catch
        if catchErrors, return
        else error('MATLAB:urlread:ConnectionFailed','Could not POST to URL.');
        end
    end
end

% Read the data from the connection.
try
    inputStream = urlConnection.getInputStream;
    byteArrayOutputStream = java.io.ByteArrayOutputStream;
    % This StreamCopier is unsupported and may change at any time.
    isc = InterruptibleStreamCopier.getInterruptibleStreamCopier;
    isc.copyStream(inputStream,byteArrayOutputStream);
    inputStream.close;
    byteArrayOutputStream.close;
    output = native2unicode(typecast(byteArrayOutputStream.toByteArray','uint8'),'UTF-8');
catch
    if catchErrors, return
    else error('MATLAB:urlread:ConnectionFailed','Error downloading URL. Your network connection may be down or your proxy settings improperly configured.');
    end
end

status = 1;


%kkapnmexport 'Flexible PNM export'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros kapnmexport.pane file
%
% Parameters:
% InputFile: i 'Input ', required: 'First Input data object'
% OutputFile: o 'Output', required: 'Resulting output data object'
%
% Example: o = kkapnmexport(i, {'i','';'o',''})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% kapnmexport - Flexible PNM export
%
%  DESCRIPTION
% This kroutine exports the input object (specified with the [-i] parameter) in PNM format (presently only binary PPM is supported). The output file (specified with the [-o] parameter) will serve as the final name for the output object if there is only one frame in the input object, if there are more than one frames (i.e. if d and/or t > 1) the output file [-o] will be a basename, and a separate file will be created for each frame.
% If there is mask in the image, masked pixels will be substituted by a color (specified by the parameter [-maskcolor] for exporting.
%
%
%
%  EXAMPLES
% All examples for the Annotate toolbox are listed on the $ANNOTATE/manual/index.html on-line manual.
%
%  "SEE ALSO"
% kman page for ka_color_decodecolor or on-line manual for information on the color specification schemes.
%
%  RESTRICTIONS
% If there are more than one frames in the input file, the output file name will be used as a basename, and it will not be available for subsequent operators in a cantata workspace.
%
%  REFERENCES
% All references for the Annotate toolbox are listed on the $ANNOTATE/manual/index.html on-line manual.
%
%  COPYRIGHT
% Annotate Toolbox v1.0 Copyright (C) 1997, Rafael Santos.
%

function varargout = kkapnmexport(varargin)
if nargin ==0
  Inputs={};arglist={'',''};
elseif nargin ==1
  Inputs=varargin{1};arglist={'',''};
elseif nargin ==2
  Inputs=varargin{1}; arglist=varargin{2};
else error('Usage: [out1,..] = kkapnmexport(Inputs,arglist).');
end
if size(arglist,2)~=2
  error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
 end
narglist={'i', '__input';'o', '__output'};
maxval={0,0};
minval={0,0};
istoggle=[0,0];
was_set=istoggle * 0;
paramtype={'InputFile','OutputFile'};
% identify the input arrays and assign them to the arguments as stated by the user
if ~iscell(Inputs)
Inputs = {Inputs};
end
NumReqOutputs=1; nextinput=1; nextoutput=1;
  for ii=1:size(arglist,1)
  wasmatched=0;
  for jj=1:size(narglist,1)
   if strcmp(arglist{ii,1},narglist{jj,1})  % a given argument was matched to the possible arguments
     wasmatched = 1;
     was_set(jj) = 1;
     if strcmp(narglist{jj,2}, '__input')
      if (nextinput > length(Inputs))
        error(['Input ' narglist{jj,1} ' has no corresponding input!']);
      end
      narglist{jj,2} = 'OK_in';
      nextinput = nextinput + 1;
     elseif strcmp(narglist{jj,2}, '__output')
      if (nextoutput > nargout)
        error(['Output nr. ' narglist{jj,1} ' is not present in the assignment list of outputs !']);
      end
      if (isempty(arglist{ii,2}))
        narglist{jj,2} = 'OK_out';
      else
        narglist{jj,2} = arglist{ii,2};
      end

      nextoutput = nextoutput + 1;
      if (minval{jj} == 0)
         NumReqOutputs = NumReqOutputs - 1;
      end
     elseif isstr(arglist{ii,2})
      narglist{jj,2} = arglist{ii,2};
     else
        if strcmp(paramtype{jj}, 'Integer') & (round(arglist{ii,2}) ~= arglist{ii,2})
            error(['Argument ' arglist{ii,1} ' is of integer type but non-integer number ' arglist{ii,2} ' was supplied']);
        end
        if (minval{jj} ~= 0 | maxval{jj} ~= 0)
          if (minval{jj} == 1 & maxval{jj} == 1 & arglist{ii,2} < 0)
            error(['Argument ' arglist{ii,1} ' must be bigger or equal to zero!']);
          elseif (minval{jj} == -1 & maxval{jj} == -1 & arglist{ii,2} > 0)
            error(['Argument ' arglist{ii,1} ' must be smaller or equal to zero!']);
          elseif (minval{jj} == 2 & maxval{jj} == 2 & arglist{ii,2} <= 0)
            error(['Argument ' arglist{ii,1} ' must be bigger than zero!']);
          elseif (minval{jj} == -2 & maxval{jj} == -2 & arglist{ii,2} >= 0)
            error(['Argument ' arglist{ii,1} ' must be smaller than zero!']);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} < minval{jj})
            error(['Argument ' arglist{ii,1} ' must be bigger than ' num2str(minval{jj})]);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} > maxval{jj})
            error(['Argument ' arglist{ii,1} ' must be smaller than ' num2str(maxval{jj})]);
          end
        end
     end
     if ~strcmp(narglist{jj,2},'OK_out') &  ~strcmp(narglist{jj,2},'OK_in')
       narglist{jj,2} = arglist{ii,2};
     end
   end
   end
   if (wasmatched == 0 & ~strcmp(arglist{ii,1},''))
        error(['Argument ' arglist{ii,1} ' is not a valid argument for this function']);
   end
end
% match the remaining inputs/outputs to the unused arguments and test for missing required inputs
 for jj=1:size(narglist,1)
     if  strcmp(paramtype{jj}, 'Toggle')
        if (narglist{jj,2} ==0)
          narglist{jj,1} = '';
        end;
        narglist{jj,2} = '';
     end;
     if  ~strcmp(narglist{jj,2},'__input') && ~strcmp(narglist{jj,2},'__output') && istoggle(jj) && ~ was_set(jj)
          narglist{jj,1} = '';
          narglist{jj,2} = '';
     end;
     if strcmp(narglist{jj,2}, '__input')
      if (minval{jj} == 0)  % meaning this input is required
        if (nextinput > size(Inputs))
           error(['Required input ' narglist{jj,1} ' has no corresponding input in the list!']);
        else
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        end
      else  % this is an optional input
        if (nextinput <= length(Inputs))
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end;
     else
     if strcmp(narglist{jj,2}, '__output')
      if (minval{jj} == 0) % this is a required output
        if (nextoutput > nargout & nargout > 1)
           error(['Required output ' narglist{jj,1} ' is not stated in the assignment list!']);
        else
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
          NumReqOutputs = NumReqOutputs-1;
        end
      else % this is an optional output
        if (nargout - nextoutput >= NumReqOutputs)
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end
     end
  end
end
if nargout
   varargout = cell(1,nargout);
else
  varargout = cell(1,1);
end
global KhorosRoot
if exist('KhorosRoot') && ~isempty(KhorosRoot)
w=['"' KhorosRoot];
else
if ispc
  w='"C:\Program Files\dip\khorosBin\';
else
[s,w] = system('which cantata');
w=['"' w(1:end-8)];
end
end
[varargout{:}]=callKhoros([w 'kapnmexport"  '],Inputs,narglist);


% OtTableFields Get a list of fields in a string array.
%
% Usage:
%    list = OtTableFields(htable)

% OtMatlab: Matlab interface to the Omnitrans transport planning software

% Copyright (c) 2008, VORtech Computing
% Copyright (c) 2010, Omnitrans International

% All rights reserved.

% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are
% met:

%     * Redistributions of source code must retain the above copyright
%       notice, this list of conditions and the following disclaimer.
%     * Redistributions in binary form must reproduce the above copyright
%       notice, this list of conditions and the following disclaimer in
%       the documentation and/or other materials provided with the distribution
%     * Neither the name of VORtech Computing and Omnitrans International nor the names
%       of its contributors may be used to endorse or promote products derived
%       from this software without specific prior written permission.

% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
% POSSIBILITY OF SUCH DAMAGE.

% 2006-02-28 Created (Johan Meijdam, VORtech)

function list = OtTableFields(htable)
   list = Ot('table.fields', htable);
end


classdef Voigt2TensorPSrepresentation < handle

    properties (Access = protected)
        indexTransformer
    end

    methods (Access = protected)

        function createIndexTransformer(obj)
            obj.indexTransformer = TensorVoigtIndexTransformerPS();
        end

    end

end


classdef TestBriefDescriptorExtractor
    %TestBriefDescriptorExtractor

    properties (Constant)
        im = fullfile(mexopencv.root(),'test','tsukuba_l.png');
    end

    methods (Static)
        function test_compute_img
            obj = cv.BriefDescriptorExtractor('Bytes',32);
            typename = obj.typeid();
            ntype = obj.defaultNorm();

            img = imread(TestBriefDescriptorExtractor.im);
            kpts = cv.FAST(img, 'Threshold',20);
            [desc, kpts2] = obj.compute(img, kpts);
            validateattributes(kpts2, {'struct'}, {'vector'});
            assert(all(ismember(fieldnames(kpts), fieldnames(kpts2))));
            validateattributes(desc, {obj.descriptorType()}, ...
                {'size',[numel(kpts2) obj.descriptorSize()]});
        end

        function test_compute_imgset
            img = imread(TestBriefDescriptorExtractor.im);
            imgs = {img, img};
            kpts = cv.FAST(img, 'Threshold',20);
            kpts = {kpts, kpts};

            obj = cv.BriefDescriptorExtractor();
            [descs, kpts] = obj.compute(imgs, kpts);
            validateattributes(kpts, {'cell'}, {'vector'});
            validateattributes(descs, {'cell'}, {'vector', 'numel',numel(imgs)});
            cellfun(@(d,k) validateattributes(d, {obj.descriptorType()}, ...
                {'size',[numel(k) obj.descriptorSize()]}), descs, kpts);
        end

        function test_error_1
            try
                cv.BriefDescriptorExtractor('foobar');
                throw('UnitTest:Fail');
            catch e
                assert(strcmp(e.identifier,'mexopencv:error'));
            end
        end
    end

end


function amd_install
%AMD_INSTALL compile and install amd2 for use in MATLAB
%   Your current directory must be AMD/MATLAB for this function to work.
%
% Example:
%   amd_install
%
% See also amd, amd2.

% Copyright 1994-2007, Tim Davis, University of Florida,
% Patrick R. Amestoy, and Iain S. Duff.

% This orders the same matrix as the ANSI C demo, amd_demo.c.  It includes an

amd_make
addpath (pwd)
fprintf ('\nThe following path has been added.  You may wish to add it\n') ;
fprintf ('permanently, using the MATLAB pathtool command.\n') ;
fprintf ('%s\n\n', pwd) ;
amd_demo


%% cleanDir
% Below is a demonstration of the features of the |cleanDir| function

%%
clear; close all; clc;

%% Syntax
% |cleanDir(pathName,extCell);|

%% Description
% This function can clean a folder by removing either all files in a folder
% or all files with the extensions specified in the cell array extCell.
%
% E.g. if one is interested in removing all .txt and .xml files from the
% folder specified by pathName on could use:
% pathName='D:\MATLAB\GIBBON'
% extCell={'txt','xml'}; %Extensions of files to delete
% cleanDir(pathName,extCell);

%% Examples
%

%%
% Create an example folder containing files with 3 different extensions,
% i.e. txt, csv and doc.

% Create temporary example folder
defaultFolder = fileparts(fileparts(mfilename('fullpath')));
pathName=fullfile(defaultFolder,'data','temp','cleanCheck');
mkdir(pathName)

% Create files
n=3; %Number of files for each type
for q=1:1:n %Create n files
    fileID=fopen(fullfile(pathName,['temp',num2str(q),'.txt']),'w');
    fprintf(fileID,'%d\n',pi);
    fclose(fileID);
end

for q=1:1:n %Create n files
    fileID=fopen(fullfile(pathName,['temp',num2str(q),'.csv']),'w');
    fprintf(fileID,'%d\n',pi);
    fclose(fileID);
end

for q=1:1:n %Create n files
    fileID=fopen(fullfile(pathName,['temp',num2str(q),'.xml']),'w');
    fprintf(fileID,'%d\n',pi);
    fclose(fileID);
end

%%
% Show current folder content
disp('Old folder content:')
ls(pathName)

%%
% Clean up directory by removing all files whose extensions are a member of
% the extension set provided.

extCell={'csv','txt'}; %File extensions for files to remove
cleanDir(pathName,extCell)

%%
% Show current folder content
disp('New folder content:')
ls(pathName)

%%
% remove the temporary folder created for this example
rmdir(pathName,'s')

%%
%
% <<gibbVerySmall.gif>>
%
% _*GIBBON*_
% <www.gibboncode.org>
%
% _Kevin Mattheus Moerman_, <gibbon.toolbox@gmail.com>
%%
% _*GIBBON footer text*_
%
% License: <https://github.com/gibbonCode/GIBBON/blob/master/LICENSE>
%
% GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for
% image segmentation, image-based modeling, meshing, and finite element
% analysis.
%
% Copyright (C) 2006-2022 Kevin Mattheus Moerman and the GIBBON contributors
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.


function p = genpathGIT(d)
%GENPATH Generate recursive toolbox path.
%   P = GENPATH returns a new path string by adding all the subdirectories
%   of MATLABROOT/toolbox, including empty subdirectories.
%
%   P = GENPATH(D) returns a path string starting in D, plus, recursively,
%   all the subdirectories of D, including empty subdirectories.
%
%   NOTE 1: GENPATH will not exactly recreate the original MATLAB path.
%
%   NOTE 2: GENPATH only includes subdirectories allowed on the MATLAB
%   path.
%
%   See also PATH, ADDPATH, RMPATH, SAVEPATH.

%   Copyright 1984-2006 The MathWorks, Inc.
%   $Revision: 1.13.4.5 $ $Date: 2008/06/24 17:12:06 $
%------------------------------------------------------------------------------

if nargin==0,
  p = genpath(fullfile(matlabroot,'toolbox'));
  if length(p) > 1, p(end) = []; end % Remove trailing pathsep
  return
end

% initialise variables
classsep = '@';  % qualifier for overloaded class directories
packagesep = '+';  % qualifier for overloaded package directories
p = '';           % path to be returned

% Generate path based on given root directory
files = dir(d);
if isempty(files)
  return
end

% Add d to the path even if it is empty.
p = [p d pathsep];

% set logical vector for subdirectory entries in d
isdir = logical(cat(1,files.isdir));
%
% Recursively descend through directories which are neither
% private nor "class" directories.
%
dirs = files(isdir); % select only directory entries from the current listing

for i=1:length(dirs)
   dirname = dirs(i).name;
   if    ~strcmp( dirname,'.')          && ...
         ~strcmp( dirname,'..')         && ...
         ~strcmp( dirname,'.git')       && ...
         ~strncmp( dirname,classsep,1) && ...
         ~strncmp( dirname,packagesep,1) && ...
         ~strcmp( dirname,'private')
      p = [p genpathGIT(fullfile(d,dirname))]; % recursive calling of this function.
   end
end

%------------------------------------------------------------------------------


function [stateLog, errorStr, errorEventNum] = ma_produceStateLogFromScript(script, maData, celBodyData, allowInterrupt, varargin)
%ma_produceStateLogFromScript Summary of this function goes here
%   Detailed explanation goes here
    if(isempty(varargin))
        stateLog = [];
        eventNum = 1;
    else
        partialExec = varargin{1};
        stateLog = partialExec{1};
        eventNum = partialExec{2};
    end
    initialEventNum = eventNum;

    if(initialEventNum > length(script))
        initialEventNum = length(script);
    end

%     profile on -history
    errorStr = '';
    errorEventNum = -1;
    for(i = initialEventNum:length(script)) %#ok<*NO4LP>
        event = script{i};

        if(allowInterrupt && mod(i,2))
            drawnow;
        end

        try
            eventLog = ma_executeEvent(event, getLastStateLogEntry(stateLog), eventNum, maData, celBodyData);
            stateLog = [stateLog ; eventLog]; %#ok<*AGROW>
            eventNum = eventNum + 1;
        catch ME
            errorStr = ME.message;
            errorEventNum = eventNum;

            disp('################## Propagation Error ###################');
            disp(['Event Num: ', num2str(eventNum)]);
            disp(['Error Msg: ', ME.message]);
            disp('#########################################################');
            try
                disp(ME.cause{1}.message);
                disp('#########################################################');
            catch
            end
            for(i=1:length(ME.stack)) %#ok<FXSET>
                disp(['Index: ', num2str(i)]);
                disp(['File: ',ME.stack(i).file]);
                disp(['Name: ',ME.stack(i).name]);
                disp(['Line: ',num2str(ME.stack(i).line)]);
                disp('####################');
            end
            disp('#########################################################');
            break;
        end
    end
%     profile viewer

    stateLog(all(stateLog==0,2),:)=[];
end


classdef SettingsInterpolation < AbstractSettings

    properties (Access = protected)
        defaultParamsName = 'paramsMaterialInterpolation.json'
    end

    properties (Access = public)
        constitutiveProperties
        typeOfMaterial
        interpolation
        dim
        ndim
        type
        nElem
        ngaus
        simpAllType
    end

    methods (Access = public)

        function obj = SettingsInterpolation(varargin)
            if nargin == 1
                obj.loadParams(varargin{1})
            end
            obj.init();
        end

    end

    methods (Access = private)

        function init(obj)
            s = obj.constitutiveProperties;
            if isstruct(s)
                obj.constitutiveProperties = SettingsConstitutiveProperties(s);
            end
        end

    end

end


function this = MrDimInfo_constructor(this, dimInfoVariants)
% Unit test for MrDimInfo Constructor evoking all 6 variants
%
%   Y = MrUnitTest()
%   run(Y, 'MrDimInfo_constructor');
%
% This is a method of class MrUnitTest.
%
% IN
%
% OUT
%
% EXAMPLE
%   MrDimInfo_constructor
%
%   See also MrUnitTest

% Author:   Saskia Bollmann
% Created:  2017-08-08
% Copyright (C) 2017 Institute for Biomedical Engineering
%                    University of Zurich and ETH Zurich
%
% This file is part of the TAPAS UniQC Toolbox, which is released
% under the terms of the GNU General Public License (GPL), version 3.
% You can redistribute it and/or modify it under the terms of the GPL
% (either version 3 or, at your option, any later version).
% For further details, see the file COPYING or
%  <http://www.gnu.org/licenses/>.
%

% Unit test for MrDimInfo Constructor evoking all 6 variants via
% dimInfoVariants

% construct MrDimInfo object from sampling points - this is the actual
% solution for variant (1) and the expected solution for all other cases
% using make_dimInfo_reference
dimInfo = this.make_dimInfo_reference(0);

switch dimInfoVariants
    %% (1) explicit setting of sampling points for dimension(s)
    case '1'

        % define actual solution
        actSolution = dimInfo;
        % load expected solution
        classesPath = tapas_uniqc_get_path('classes');
        solutionFileName = fullfile(classesPath, '@MrUnitTest' , 'dimInfo.mat');
        expSolution = load(solutionFileName);
        expSolution = expSolution.dimInfo;

        %% (2) nSamples + ranges
    case '2'
        % define expected solution
        expSolution = dimInfo;
        % define actual solution
        % Initialize MrDimInfo via nSamples + ranges (variant (2))
        actSolution = MrDimInfo(...
            'dimLabels', expSolution.dimLabels, ...
            'units', expSolution.units, ...
            'nSamples', expSolution.nSamples, ...
            'ranges', expSolution.ranges);
        % overwrite samplingPoints of coil due to non-uniform sampling
        actSolution.coil.samplingPoints = expSolution.coil.samplingPoints;
        % overwrite samplingWidths since they are retained in case of later
        % changes, but not set because of the construction of the reference
        % MrDimInfo object (= expected Solution)
        actSolution.coil.samplingWidths = nan;

        %% (3) nSamples + resolutions + samplingPoint + arrayIndex
    case '3'
        % define expected solution
        expSolution = dimInfo;
        % define actual solution
        arrayIndex = [81 54 14 321 1];

        actSolution = MrDimInfo(...
            'dimLabels', expSolution.dimLabels, ...
            'units', expSolution.units, ...
            'nSamples', expSolution.nSamples, ...
            'resolutions', expSolution.resolutions, ...
            'samplingPoint', expSolution.index2sample(arrayIndex), ....
            'arrayIndex', arrayIndex);

        % overwrite samplingPoints of coil due to non-uniform sampling
        actSolution.coil.samplingPoints = expSolution.coil.samplingPoints;

        % overwrite samplingWidths since they are retained in case of later
        % changes, but not set because of the construction of the reference
        % MrDimInfo object (= expected Solution)
        actSolution.coil.samplingWidths = nan;

        %% (4) nSamples + resolutions + firstSamplingPoint
    case '4'
        % define expected solution
        expSolution = dimInfo;
        % define actual solution
        arrayIndex = [1 1 1 1 1];

        actSolution = MrDimInfo(...
            'dimLabels', expSolution.dimLabels, ...
            'units', expSolution.units, ...
            'nSamples', expSolution.nSamples, ...
            'resolutions', expSolution.resolutions, ...
            'firstSamplingPoint', expSolution.index2sample(arrayIndex));

        % overwrite samplingPoints of coil due to non-uniform sampling
        actSolution.coil.samplingPoints = expSolution.coil.samplingPoints;

        % overwrite samplingWidths since they are retained in case of later
        % changes, but not set because of the construction of the reference
        % MrDimInfo object (= expected Solution)
        actSolution.coil.samplingWidths = nan;

        %% (5) nSamples + resolutions + lastSamplingPoint
    case '5'
        % define expected solution
        expSolution = dimInfo;
        % define actual solution
        arrayIndex = expSolution.nSamples;

        actSolution = MrDimInfo(...
            'dimLabels', expSolution.dimLabels, ...
            'units', expSolution.units, ...
            'nSamples', expSolution.nSamples, ...
            'resolutions', expSolution.resolutions, ...
            'lastSamplingPoint', expSolution.index2sample(arrayIndex));

        % overwrite samplingPoints of coil due to non-uniform sampling
        actSolution.coil.samplingPoints = expSolution.coil.samplingPoints;

        % overwrite samplingWidths since they are retained in case of later
        % changes, but not set because of the construction of the reference
        % MrDimInfo object (= expected Solution)
        actSolution.coil.samplingWidths = nan;

    case '6'
        %% (6) nSamples only
        % get nSamples from reference object
        nSamples = dimInfo.nSamples;
        nDims = numel(nSamples);

        % make actual solution
        actSolution = MrDimInfo('nSamples', nSamples);

        % make expected solution from ranges and sampling points

        for n = 1:nDims
            if n < 4
                % x y z
                samplingPoints{n} = -(nSamples(n)-1)/2:(nSamples(n)-1)/2;
            else
                samplingPoints{n} = 1:(nSamples(n));
            end
        end
        expSolution = MrDimInfo('samplingPoints', samplingPoints);

    case '7'
        %% (7) resolutions only
        % get resolutions from reference object
        resolutions = dimInfo.resolutions;
        % use only valid (i.e. finite)
        validResolutions = isfinite(resolutions);
        nDims = sum(validResolutions);

        % make actual solution
        actSolution = MrDimInfo('resolutions', resolutions(validResolutions));

        % make expected solution
        for n = 1:nDims
            if n < 4
                % x y z
                samplingPoints{n} = -(resolutions(n))/2:resolutions(n):(resolutions(n))/2;
            else
                samplingPoints{n} = resolutions(n):resolutions(n):2*resolutions(n);
            end
        end

        expSolution = MrDimInfo('samplingPoints', samplingPoints);

    case '8'
        %% (8) ranges only

        % get ranges from reference object
        ranges = dimInfo.ranges;

        % make actual solution
        actSolution = MrDimInfo('ranges', ranges);

        % make expected solution from sampling points
        samplingPoints = mat2cell(ranges', [1 1 1 1 1], 2)';
        expSolution = MrDimInfo('samplingPoints', samplingPoints);

    case '9'
        %% (9) dimLabels only

        % get dimLabels from reference object
        dimLabels = dimInfo.dimLabels;
        nDims = numel(dimLabels);

        % make actual solution
        actSolution = MrDimInfo('dimLabels', dimLabels);

        % make expected solution with standard sampling points, i.e [-0.5
        % 0.5] for dims x,y,z and [1 2] for all other dims

        expSolution.nDims = nDims;
        expSolution.nSamples = 2*ones(1, nDims);
        expSolution.resolutions = ones(1, nDims);
        expSolution.ranges = [-0.5 -0.5 -0.5 1 1; 0.5 0.5 0.5 2 2];
        for n = 1:nDims
            expSolution.dimLabels{n} = dimInfo.get_default_dim_labels(n);
            expSolution.units{n} = dimInfo.get_default_dim_units(n);
        end
        expSolution.samplingPoints = {[-0.5 0.5] [-0.5 0.5] [-0.5 0.5] [1 2] [1 2]};
        expSolution.samplingWidths = expSolution.resolutions;

    case '10'
        %% (10) units only

        % get units from reference object
        units = dimInfo.units;
        nDims = numel(units);

        % make actual solution
        actSolution = MrDimInfo('units', units);

        % make expected solution with standard sampling points, i.e [-0.5
        % 0.5] for dims x,y,z and [1 2] for all other dims
        expSolution.nDims = nDims;
        expSolution.nSamples = 2*ones(1, nDims);
        expSolution.resolutions = ones(1, nDims);
        expSolution.ranges = [-0.5 -0.5 -0.5 1 1; 0.5 0.5 0.5 2 2];
        for n = 1:nDims
            expSolution.dimLabels{n} = dimInfo.get_default_dim_labels(n);
            expSolution.units{n} = dimInfo.get_default_dim_units(n);
        end
        expSolution.samplingPoints = {[-0.5 0.5] [-0.5 0.5] [-0.5 0.5] [1 2] [1 2]};
        expSolution.samplingWidths = expSolution.resolutions;

    case '11'
        %% (11) samplingWidths only
        % note that samplingWidths does not impact resolutions and, thus,
        % sampling points and can therefore also be nan

        % get samplingWidths from reference object
        samplingWidths = dimInfo.samplingWidths;
        nDims = numel(samplingWidths);

        % make actual solution
        actSolution = MrDimInfo('samplingWidths', samplingWidths);

        % make expected solution with standard sampling points, i.e [-0.5
        % 0.5] for dims x,y,z and [1 2] for all other dims
        expSolution.nDims = nDims;
        expSolution.nSamples = 2*ones(1, nDims);
        expSolution.resolutions = ones(1, nDims);
        expSolution.ranges = [-0.5 -0.5 -0.5 1 1; 0.5 0.5 0.5 2 2];
        for n = 1:nDims
            expSolution.dimLabels{n} = dimInfo.get_default_dim_labels(n);
            expSolution.units{n} = dimInfo.get_default_dim_units(n);
        end
        expSolution.samplingPoints = {[-0.5 0.5] [-0.5 0.5] [-0.5 0.5] [1 2] [1 2]};
        expSolution.samplingWidths = samplingWidths;

end

% verify whether expected and actual solution are identical
% Note: convert to struct, since the PublicPropertyComparator (to allow
% nans to be treated as equal) does not compare properties of objects that
% overload subsref

warning('off', 'MATLAB:structOnObject');
this.verifyEqual(struct(actSolution), struct(expSolution), 'absTol', 10e-7);
warning('on', 'MATLAB:structOnObject');
end


clear; clc;
disp('compile native libraries')
mex -O -largeArrayDims sparse_inp.c
mex -O -largeArrayDims sparse_update.c
disp('done compiling.')
test_consist1
test_consist2