function [object,count]=mcplot(object, options, id)
% mcplot: plot a McStas simulation result
% [object,count]=mcplot(object, options, id)
%
% This function displays a McStas simulation result either as many windows
% or on a single window with subplots. It also returns the McStas simulation
% structure. An 'id' may be specified for filtering names within structure.
%
% input:
% object: one or more simulation name(s) or a single mcstas structure
% or a single detector file name
% if filename does not exist, a file selector is called.
% options may contain keywords
% '-overview' to plot all results on the same window
% '-plot' to plot all results in separate windows
% '-png' to export as a PNG file
% '-ps' to export as a PostScript file
% '-psc' to export as a color PostScript file
% '-eps' to export as a EPS file
% '-epsc' to export as a color EPS file
% '-jpg' to export as an JPEG file
% '-tif' to export as a TIFF file
% '-fig' to export as a Matlab figure (open)
% id is a keyword used for searching within McStas structure fields
% 'filename' and 'title'
%
% examples:
% mcplot;
% s=mcplot('ask me the file','-overview')
% mcplot(s, 'plot -png', 'MyMonitorName');
%
% Written by: E. Farhi
% Date: 21st, March 2003
% Release: McStas 1.6
% Origin: ILL
%
% This file is part of the McStas neutron ray-trace simulation package
% Copyright (C) 1997-2004, All rights reserved
% Risoe National Laborartory, Roskilde, Denmark
% Institut Laue Langevin, Grenoble, France
%
% 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 2 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, write to the Free Software
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
%

% parameter check
if nargin == 0, object=''; end
if nargin <= 1, options=''; end
if nargin <= 2, id = ''; end

if ~ischar(options), options = ''; end
if ~length(options), options = '-overview'; end
options = lower(options); % to lower case
if ~length(findstr(options,'plot')) & ~length(findstr(options,'overview')) & ~length(findstr(options,'action'))
options = [ options '-overview ' ];
end
if strcmp(options,'action')
mcplot_menu_action(object, id);
return
end

pathname = '';
filename = '';

% handle file name specification in 'object'
if ischar(object) % if object is a string
if size(object,1) > 1
for index=1:size(object,2)
[object,count] = mcplot(object(index), options, id);
end
return
end
% if object is a '' string, s = 'mcstas'.
if ~length(object), object = 'mcstas.m'; end
% checks for directories
if exist(object,'dir'), object = [ object filesep 'mcstas.m']; end
[fid, err] = fopen(object, 'r');
if fid == -1 % error occured. Calls fileselector (uigetfile)
if length(findstr(options,'-ps')) ...
| length(findstr(options,'-psc')) ...
| length(findstr(options,'-eps')) ...
| length(findstr(options,'-epsc')) ...
| length(findstr(options,'-jpg')) ...
| length(findstr(options,'-tif')) ...
| length(findstr(options,'-png')) ...
| length(findstr(options,'-fig'))
fprintf(2,'mcplot: Could not open file %s for auto export\n',object);
return;
else
[object, pathname] = uigetfile('*.m', 'Select a McStas/Matlab simulation file to load');
end
if ~ischar(object), return; end
[fid, err] = fopen(object, 'r');
if fid == -1
fprintf(2,'mcplot: Could not open file %s\n',object);
fprintf(2,'mcplot: %s', err);
return
end
end
fclose(fid);
% opens filename and evaluate it
object_orig = object;
[pathname, object, ext]=fileparts(object);
dorename = 0;
if isempty(ext), dorename = 1;
elseif ~strcmp(ext, '.m'), dorename = 1;
end
if dorename
new_name = strrep(object_orig,'.','_');
copyfile(object_orig, [ new_name '.m' ]);
object = new_name;
end
filename = object;
object = strrep(object,'.m','');
if length(pathname)
cur_dir = pwd;
cd(pathname); % go into directory where object is
pathname = [ pathname filesep ];
end
m = [];
m = eval(object,'[]');
if ~length(m)
disp(['mcplot: Could not extract McStas structure from file ' object]);
disp( ' This is not a Matlab script (other format or binary ?)');
disp(['mcplot: ' lasterr]);
if dorename,delete([ new_name '.m' ]); end
if length(pathname), cd(cur_dir); end
return
elseif dorename,delete([ new_name '.m' ]); end
if length(m)
object = m; clear m
end
if length(pathname), cd(cur_dir); end
end

% handles structure loading and ploting
if ~isstruct(object)
disp('mcplot: Could not extract the McStas simulation structure.')
return;
else % if 's' is a 'struct'
% send to mcplot_scan(s, options)
[count, object] = mcplot_scan(object, options, id);

% set title to instrument+dirname+filename+parameters
fud = get(gcf,'UserData');
source = eval('fud.instrument.Source','[]');
if ~length(source), source = eval('fud.Source','''McStas'''); end
sdate = eval('fud.Date','now');
% The datestr call below is partly broken:
% If sdate comes from the data file, we will not take offset
% from GMT into account... Have made a query to comp.soft-sys.matlab
% to ask for a solution...
if ~ischar(sdate), sdate = datestr(sdate/60/60/24 + 719529); end
ncount = eval('fud.Ncount','''unknown''');
overview = eval('fud.overview','[]');
if ~length(filename) & isfield(object,'filename'), filename=object.filename; end
if ~length(filename) & isfield(fud,'filename'), filename=fud.filename; end
if ~length(pathname) & isfield(object,'pathname'), pathname=object.pathname; end
fud.pathname = pathname;
set(gcf,'UserData',fud);
t1 = [ '[' source '] ' pathname filename ];
if length(overview), set(gcf,'Name',t1,'unit','pixel'); end
% print simulation informations
t2 = [ 'Ncount:' ncount '; Date: ' sdate ];
if isfield(fud,'superdata')
if isfield(fud.superdata, 'scannedvar')
t2 = [ t2 '; Scan of ' fud.superdata.scannedvar '=' num2str(fud.superdata.minvar) ':' num2str(fud.superdata.maxvar) ' in ' num2str(fud.superdata.numpoints) ' points.'];
end
end
parameters = eval('fud.parameters','[]');
if ~isempty(parameters)
t3 = '';
% scan parameters structure, excluding 'class','parent','name'
tmp_fields = fieldnames(parameters);
for field=1:length(tmp_fields)
switch tmp_fields{field}
case {'class','parent','name'}
otherwise
t3 = [ t3 tmp_fields{field} '=' num2str(getfield(parameters, tmp_fields{field})) ' ' ];
end
end
else
t3 = 'unknown parameters';
end

% redimension all subplot axes in figure to make room for legend
set(gcf,'unit','characters');
posf = get(gcf,'position');
ratio = max(posf(end)-4,5)/posf(end);
h = findobj(gcf,'type','axes');
for index=1:length(h)
pos = get(h(index),'position');
pos = pos.*[1 ratio 1 ratio];
set(h(index),'position',pos);
end

% create legend uicontrol
pos = [ 1 posf(end)-4 posf(3) 4 ];
NL = sprintf('\n');
h = uicontrol('style','edit','max',4,'min',0,'unit','characters',...
'position',pos,'string',{t1;t2;t3},...
'ToolTipString',[ 'Simulation: ' t1 NL ' with ' t2 NL 'Parameters: ' t3]);
set(h,'unit','normalized');

% if it is a scan overview, add a menu item to call scan step selection
if length(fud.overview) & isfield(fud,'superdata')
h = findobj(gcf,'Tag','McStasMenu');
uimenu(h,'Separator','on','Label','View scan step...','callback',['mcplot(''scanstep'',''action'', gcf);']);
end
set(gcf,'Toolbar','figure'); % make sure the tool bar is there

% if output is not empty, setup output file
if length(findstr(options,'-gif'))
disp('McPlot: GIF output not available, substituting with PNG.')
options = strrep(options, '-gif','-png');
end
if length(findstr(options,'-ps')) ...
| length(findstr(options,'-psc')) ...
| length(findstr(options,'-eps')) ...
| length(findstr(options,'-epsc')) ...
| length(findstr(options,'-jpg')) ...
| length(findstr(options,'-tif')) ...
| length(findstr(options,'-png')) ...
| length(findstr(options,'-fig')),
filename = eval('object.File','[]');
if length(filename) == 0, filename = eval('object.filename','[]'); end
if length(filename) == 0, filename='mcstas'; end
mcplot_output(options, gcf, filename);
end
end
% end mcplot

% script for definition of colormaps and usefull functions for McStas/McPlot

% optional routines required by mcplot ---------------------------------------

function win = mcplot_addmenu()
% set up a mcplot local menu
win = gcf;
% remove McStas menu (if any)
h = findobj(win, 'Tag', 'McStasMenu');
if ~isempty(h), delete(h); end
% creates a local McStas menu for looking at data files, and direct exporting
h = uimenu(win, 'Label', '&McStas', 'Tag', 'McStasMenu');
hcolor = uimenu(h, 'Label', '&Colors');
hsave = uimenu(h, 'Label', '&Save');
hedit = uimenu(h, 'Label', '&Edit');
t = {'Save as &PNG', 'save_png', ...
'Save as EPS (BW)', 'save_eps', ...
'Save as &EPS (Color)', 'save_epsc', ...
'Save as JPEG', 'save_jpg', ...
'Save as TIFF', 'save_tif', ...
'Save as Fig (Matlab)', 'save_fig', ...
'Colormap &Jet', 'cmap_jet', ...
'Colormap &HSV', 'cmap_hsv', ...
'Colormap Hot (red)', 'cmap_hot', ...
'Colormap Cool (&blue)', 'cmap_cool', ...
'Colormap Gray', 'cmap_gray', ...
'Colormap Pink', 'cmap_pink', ...
'Colormap Inv. Pink', 'cmap_rpink', ...
'Colormap : others...','set_color', ...
'Edit &data file', 'edit_data', ...
'Edit &instrument file', 'edit_instr', ...
'View &the instrument','view_instr', ...
'Add colorbar', 'add_colorbar', ...
'Intensity: Linear scale', 'log_linear',...
'Exit...', 'exit', ...
'About McStas...', 'about'};
for index = 1:2:length(t) % setup the callbacks
this_item = t{index};
if length(strmatch(strtok(this_item),'Colormap')), sub_menu=hcolor;
elseif length(strmatch(strtok(this_item),'Save')), sub_menu=hsave;
elseif length(strmatch(strtok(this_item),'Edit')), sub_menu=hedit;
else sub_menu=h; end
uimenu(sub_menu, 'Label', this_item, ...
'callback', ['mcplot(''' t{index+1} ''',''action'', gcf);']);
end
% end mcplot_addmenu

function mcplot_menu_action(action, object)

fud = get(gcf, 'UserData');
if nargin == 1, object = ''; end
if isempty(object), object = gco; end
if isempty(object), object = gcf; end

% extract global data
filename = '';
filename = eval('fud.filename','[]');

switch action
case 'set_color' % Sets a colormap
if any([strcmp(get(object,'Type'), 'surface') strcmp(get(object,'Type'), 'figure')])
ColordListDlg = {...
'Default (usually Jet)',...
'HSV (from red, throught yellow, green, cyan, blue, magenta, to red...)','Jet (from blue, through cyan, yellow, and orange, to red)',...
'Autumn (red, through orange, to yellow)','Spring (shades of magenta and yellow)','Summer (shades of green and yellow)','Winter (shades of blue and green)',...
'Bone (grayscale plus blue)','Copper (black to bright copper)','Gray (grayscale)','Pink (pastel shades of pink)',...
'Cool (from cyan to magenta)','Hot (from black, through red, orange, and yellow, to white)',...
'Flag (4 pure red, white, blue, and black)','Lines (8 regularly pure colors+gray)','Prism (6 regularly pure colors)','ColorCube (many regularly pure colors)'};
% display colormap list
[Selection, Ok] = listdlg('ListString', ColordListDlg, ...
'SelectionMode', 'single', 'Name', 'Color map Selection (for surfaces)', ...
'PromptString', 'Please select a ColorMap','ListSize', [300 270]);
if (Ok == 1)
% set colormaps on all Common.CurrentFigure
ColorMap = ColordListDlg{Selection};
ColorMap = lower(strtok(ColorMap));
colormap(ColorMap);
end
elseif any(strcmp(get(object,'Type'), 'line'))
if exist('scribelinedlg')
scribelinedlg(object);
else
C = uisetcolor(object, 'Set Plot Color');
set(object, 'Color', C);
end
end
case 'edit_data' % Edit/_data file
if ~length(filename)
filename = eval('fud.filename','[]');
end
if length(filename), mcplot_edit_file(filename); end
case 'duplicate' % duplicate graph
d=get(object,'UserData');
fud0 = get(gcf, 'UserData');
if ~isfield(d,'Source') & isfield(fud0,'Source'), d.Source = fud0.Source; end
if ~isfield(d,'Ncount') & isfield(fud0,'Ncount'), d.Ncount = fud0.Ncount; end
if ~isfield(d,'parameters') & isfield(fud0,'parameters'), d.parameters = fud0.parameters; end
if ~isfield(d,'pathname') & isfield(fud0,'pathname'), d.pathname = fud0.pathname; end
mcplot(d,'-plot');
case 'edit_instr' % Edit/instrument file
filename = eval('fud.Source','[]');
if length(filename), mcplot_edit_file(filename); end
case 'view_instr' % Plot existing .fig if available
figname = eval('fud.Source','[]');
% get the file name without the path and the extension
[tmp_path, figname] = fileparts(figname);
if ~exist([figname '.fig'],'file')
parameters = eval('fud.parameters','[]');
if ~isempty(parameters)
% scan parameters structure, excluding 'class','parent','name'
if ispc
tmp_parcmd = [ '!mcdisplay.pl -pMatlab --save ' figname '.exe ' ];
else
tmp_parcmd = [ '!mcdisplay -pMatlab --save ./' figname '.out ' ];
end
tmp_fields = fieldnames(parameters);
for field=1:length(tmp_fields)
switch tmp_fields{field}
case {'class','parent','name'}
otherwise
tmp_parcmd = [ tmp_parcmd ' ' tmp_fields{field} '=' num2str(getfield(parameters, tmp_fields{field})) ];
end
end
% launch the mcdisplay process to generate the instr view as a fig file
fprintf(1,'Executing:%s\n',tmp_parcmd);
eval(tmp_parcmd,'[]');
end
end
if exist([figname '.fig'])==2, openfig([figname '.fig'],'reuse'); end
case 'add_colorbar' % Add _colorbar
colorbar;
case 'del_colorbar' % Add _colorbar
delete(colorbar);
case 'add_text' % add text
t = 'Enter the text to add, and click the OK button';
setstatus(t); fprintf(1,'%s\n',t);
answer = inpudlg(['Text to add to Figure ' num2str(gwin)],'McPlot: add text');
if length(answer)
t = 'Select the position where to paste the text.';
setstatus(t); fprintf(1,'%s\n',t);
gtext(answer);
setstatus('Ready');
end
case 'save_png' % Save as/_GIF
mcplot_output('-png',[],filename);
case 'save_eps' % Save as/EPS (b-w)
mcplot_output('-eps' ,[],filename);
case 'save_epsc' % Save as/EPS (color)
mcplot_output('-epsc',[],filename);
case 'save_jpg' % Save as/JPEG
mcplot_output('-jpg',[],filename);
case 'save_tif' % Save as/TIFF
mcplot_output('-tif',[],filename);
case 'save_fig' % Save as/Matlab
mcplot_output('-fig',[],filename);
case 'cmap_jet' % Colormap/_Jet
colormap(jet);
case 'cmap_hsv' % Colormap/HSV
colormap(hsv);
case 'cmap_hot' % Colormap/hot
colormap(hot);
case 'cmap_cool' % Colormap/cool
colormap(cool);
case 'cmap_gray' % Colormap/gray
colormap(gray);
case 'cmap_pink' % Colormap/pink
colormap(pink);
case 'cmap_rpink' % Colormap/inverted pink
colormap(1-pink);
case 'scanstep' % opens a list dialog for a Scan Step selection to open
pathname = eval('fud.pathname','[]');
filename = eval('fud.filename','[]');
source = eval('fud.Source','[]');
ncount = eval('fud.Ncount','''unknown''');
if isfield(fud,'superdata')
if isfield(fud.superdata, 'scannedvar')
% make a list of scan step items
index = cellstr(num2str(transpose(0:(fud.superdata.numpoints-1))));
scannedvar = linspace(fud.superdata.minvar, fud.superdata.maxvar, fud.superdata.numpoints);
scannedvar = cellstr(num2str(transpose(scannedvar)));
scannedvar = strcat('[#', index, '] ', [ fud.superdata.scannedvar '=' ], scannedvar);
prompt = {'Select scan step(s) open for',[ '[' source '] ' pathname filename ], ...
[ 'Scan of ' fud.superdata.scannedvar '=' num2str(fud.superdata.minvar) ':' num2str(fud.superdata.maxvar) ' in ' num2str(fud.superdata.numpoints) ' points.']};
selection = listdlg('ListString',scannedvar, 'SelectionMode','multiple',...
'PromptString', prompt, 'ListSize', [200 100], ...
'Name',[ '[' source '] Select scan step for ' filename ]);
if ~isempty(selection)
for index=1:length(selection)
disp([ 'mcplot(''' deblank([ pathname num2str(selection(index)-1) ]) ''',''-overview'');' ]);
figure;
mcplot(deblank([ pathname num2str(selection(index)-1) ]),'-overview');
end
end
end
end
case 'log_linear' % toggle linear/log scale
if length(findstr(get(gcbo,'Label'),'Log'))
set(gcbo,'Label', 'Intensity: Linear scale');
scale = 'linear';
else
set(gcbo,'Label', 'Intensity: Log scale');
scale = 'log';
end
all_axes = findobj(gcf, 'Type','axes');
for index_a = 1:length(all_axes)
all_plots = get(all_axes(index_a), 'Children');
for index_p = 1:length(all_plots)
this_child = all_plots(index_p);
if strcmp(get(this_child, 'Type'), 'line')
set(all_axes(index_a), 'YScale', scale);
elseif strcmp(get(this_child, 'Type'), 'surface')
set(all_axes(index_a), 'ZScale', scale);
if strcmp(scale,'log')
zdat=get(this_child,'zdata');
cdat=log(zdat);
set(this_child,'cdata',cdat)
else
zdat=get(this_child,'zdata');
set(this_child,'cdata',zdat)
end
end
end
end
case 'exit' % Close all
Stop=questdlg('Exit Matlab/McPlot ?','McPlot: Exit ?','Yes','No','Yes');
if strcmp(Stop,'Yes')
exit
end
case 'about'
t = {'McStas McPlot menu',...
'', ...
'This is the McStas McPlot tool menu',...
'It enables to customize the plot aspects and colors,'...
'add objects, as well as export in various formats.', ...
'','Use contextual menus on lines and surfaces to access',...
'additional functionalities',...
'','Please visit <http://www.neutron.risoe.dk/mcstas>','', ...
'McStas comes with ABSOLUTELY NO WARRANTY',...
'This is free software, and you are welcome',...
'to redistribute it under certain conditions',...
'as specified in Licence files.'};
msgbox(t, 'McPlot: About','help','non-modal');
end
% end mcplot_menu_action

function mcplot_edit_file(filename)
% edit a file using either the EDITOR variable, or default editor

if length(filename)
if ~exist(filename, 'file'), filename = [ '..' filesep filename]; end % try one level up
if ~exist(filename, 'file'), filename = [ '..' filesep filename]; end % try two levels up
if exist(filename, 'file')
t = ['McPlot: Editing file ' filename];
setstatus(t); fprintf(1,'%s\n',t);
edit(filename);
end
end
% end mcplot_edit_file

function mcplot_output(form, win, filename)
% output the current graphic window in the specified format (default is GIF)
% format may be: gif, ps, psc, fig, scilab
if nargin == 0, form='GIF'; end
if nargin <= 1, win = -1; end
if nargin <= 2, filename=''; end
if length(win) == 0, win = -1; end
if win < 0, win = gcf; end
if length(filename) == 0, filename='mcstas'; end
form = lower(form);

ext = ''; dr = '';
if length(findstr(form,'-gif'))
disp('McPlot: GIF output not available, substituting with PNG.')
form = strrep(form, '-gif','-png');
end
% if output is not empty, open driver+xinit(filename)
if length(findstr(form,'-ps')), ext = '.ps'; dr='-dps'; colormap(gray);
elseif length(findstr(form,'-psc')), ext = '.ps'; dr='-dpsc';
elseif length(findstr(form,'-eps')), ext = '.eps'; dr='-deps'; colormap(gray);
elseif length(findstr(form,'-epsc')),ext = '.eps'; dr='-depsc';
elseif length(findstr(form,'-jpg')), ext = '.jpg'; dr='-djpeg';
elseif length(findstr(form,'-tif')), ext = '.tif'; dr='-dtiff';
elseif length(findstr(form,'-png')), ext = '.png'; dr='-dpng';
elseif length(findstr(form,'-fig')), ext = '.fig'; dr=''; end
if length(ext)
filename = [ filename ext ];
if ~strcmp(ext,'.fig')
print(gcf, dr, filename);
else saveas(gcf, filename, 'fig');
end
t=['mcplot: McStas plot exported as file ' filename ' (' form ')'];
setstatus(t); fprintf(1,'%s\n',t);
end
% end mcplot_output

% basic routines required by mcplot ------------------------------------------

function d=mcplot_load(d)
% local inline function to load data
S=d.type;
StartIdx=findstr('(',S)+1;
eval(['S=[ ' S(StartIdx:(length(S)-1)) ' ];']);
if isempty(d.data)
if ~length(findstr(d.format, 'binary'))
copyfile(d.filename,[d.func,'.m']);p=d.parent;
path(path);
eval(['d=',d.func,';']);d.parent=p;delete([d.func,'.m']);
else
if length(findstr(d.format, 'float')), t='single';
elseif length(findstr(d.format, 'double')), t='double';
else return; end
if length(S) == 1, S=[S 1]; end
fid=fopen(d.filename, 'r');
pS = prod(S);
x = fread(fid, 3*pS, t);
d.data =reshape(x(1:pS), S);
if prod(size(x)) >= 3*pS,
d.errors=reshape(x((pS+1):(2*pS)), S);
d.events=reshape(x((2*pS+1):(3*pS)), S);end
fclose(fid);
end
if length(strindex(d.type,'1d'))
if size(d.data,2) > 1 & size(d.errors,2) ==0
d.errors = d.data(:,2);
d.data = d.data(:,1);
end
end
end

function d=mcplot_plot(d,p)
% func to plot data
if isempty(findstr(d.type,'0d')), d=mcplot_load(d); end
if ~length(d.values), d.values = [ num2str(sum(sum(d.data)),'%.4g') ' ' num2str(sum(sum(d.errors)),'%.4g') ]; end
if ~length(d.signal), d.signal = [ 'Min=' num2str(min(min(d.data)),'%.4g') '; Max=' num2str(max(max(d.data)),'%.4g') '; Mean=' num2str(mean(mean(d.data)),'%.4g') ]; end
if ~p, return; end;
eval(['l=[',d.xylimits,'];']);
S=size(d.data);
t1=['[',d.parent,'] ',d.filename,': ',d.title];
t = strvcat(t1,[' ',d.variables,'=[',d.values,']'],[' ',d.signal],[' ',d.statistics]);
disp(t);
if ~isempty(findstr(d.type,'0d')),return;
else
if p==1 & ~isempty(findobj(gcf, 'Type','axes'))
w=figure;
else w = gcf; end
if ~isempty(findstr(d.type,'2d'))
d.x=linspace(l(1),l(2),S(2));
d.y=linspace(l(3),l(4),S(1));
h=surface(d.x,d.y,d.data);
shading flat;
elseif ~isempty(findstr(d.type,'1d'))
d.x=linspace(l(1),l(2),max(S));
h=errorbar(d.x,d.data,d.errors);
else
d.x=linspace(l(1),l(2),max(S));
h=plot(d.x,d.data);
end
set(h, 'UserData', d);
hm = uicontextmenu;
uimenu(hm, 'Label',['Duplicate ' d.filename], 'Callback', ...
'mcplot(''duplicate'', ''action'', gco);');
uimenu(hm, 'Label',['Edit ' d.filename], 'Callback', ...
[ 'mcplot(''edit_data'', ''action'', gco);' ]);
uimenu(hm, 'Label','Select Color', 'Callback', ...
[ 'mcplot(''set_color'', ''action'', gco);' ]);
uimenu(hm, 'Label','Reset View', 'Callback','view(0,90);lighting none;alpha(1);');
if ~isempty(findstr(d.type,'2d'))
uimenu(hm, 'Label','Add Light','Callback', 'light;lighting phong;');
uimenu(hm, 'Label','Transparency','Callback', 'alpha(0.5);');
end
uimenu(hm, 'Label',['Export into ' d.filename ],'Callback', [ 'evalin(''base'',''' d.filename ' = get(gco,''''userdata''''); disp([''''Exported data into variable ' d.filename ''''']);'');'])
fud = get(gcf,'UserData');
if isfield(fud,'superdata')
uimenu(hm,'Separator','on','Label','View scan step...','callback',['mcplot(''scanstep'',''action'', gcf);']);
end
set(h, 'UIContextMenu', hm);
% Also set this UIContextMenu on the axis...
% Could also be done using gca as handle, but
% can break in certain setups...
for j=1:length(h)
set(get(h(j),'parent'), 'UIContextMenu', hm, 'userdata',get(h(j),'userdata'));
end
end
if p == 2, t = t1; end
xlabel(d.xlabel); ylabel(d.ylabel); h=title(t); set(h,'interpreter','none');
axis tight;
if p==1, set(gca,'position',[.18,.18,.7,.65]); end
set(gcf,'name',t1);grid on;
% if ~isempty(findstr(d.type,'2d')), colorbar; end
% end mcplot_plot

function mcplot_set_global(s, gwin, p_in)

if length(p_in) == 3
m = p_in(1);
n = p_in(2);
p = p_in(3);
p_in = p;
else m=0; n=0; p=p_in; end
if ~p, p=1; end

if ~length(gwin), gwin = gcf; end
ThisFigure = get(gcf,'UserData');

if ~length(ThisFigure)
filename = eval('s.File','[]');
if length(filename) == 0, filename = eval('s.filename','[]'); end
if length(filename), ThisFigure.filename = filename; end
ThisFigure.overview = [];
end
if isfield(s,'Source'), ThisFigure.Source = s.Source; end
if isfield(s,'Date'), ThisFigure.Date = s.Date; end
if isfield(s,'Ncount'), ThisFigure.Ncount = s.Ncount; end
if isfield(s,'parameters'), ThisFigure.parameters = s.parameters; end
if strcmp(s.class,'instrument')
instrument.Source = s.Source;
instrument.name = s.name;
instrument.Parameters = s.Parameters;
instrument.class = 'instrument';
ThisFigure.instrument = instrument;
elseif strcmp(s.class,'simulation')
[a,b,ext] = fileparts(s.name);
if ~strcmp(ext,'.m')
ThisFigure.filename = [s.name '.m'];
else ThisFigure.filename = s.name; end
elseif strcmp(s.class,'parameters')
ThisFigure.parameters = s;
elseif strcmp(s.class,'data')
if ~p_in, ThisFigure.filename = s.filename; end
if isfield(s,'ratio') & ~isfield(ThisFigure,'Ncount')
ThisFigure.Ncount = s.ratio; end
elseif strcmp(s.class,'superdata')
ThisFigure.superdata = s;
end % ignore other classes

if m*n, ThisFigure.overview = [m n p]; end

% store Figure McPlot info
set(gcf,'UserData', ThisFigure);
% end mcplot_set_global

function [data_count, s] = mcplot_scan(s,action, m,n,p, id)
% scans the structure s recursively and opens a graphic window
% for all found 'data' structures having curves/surfaces data.
% input: s: structre where we look for data blocks
% action: may be 'count', '-plot' and '-overview'
% m,n,p: indexes for subplot windows
% m may also be used as a string keyword used for searching within McStas
% structure fields 'filename','title', 'type'

if nargin == 0, data_count = 0; return; end
if ~isstruct(s), data_count = 0; return; end
tag_names = fieldnames(s);
if length(strmatch('class', tag_names)) == 0
if length(strmatch('data', tag_names)), s.class = 'data';
else
s.class = 'root';
data_count = 0;
end
end
if nargin == 1, action = ''; end
if nargin == 3, id = m; end
if ~length(action), action = '-overview'; end
if length(findstr(action,'-overview')) & nargin == 3
% first count the number of data blocks
data_count = mcplot_scan(s,'count',id);
if ~data_count, return; end
m = floor(sqrt(data_count));
n = ceil(data_count/m);
p = 1;
subplot(m,n,p);
mcplot_addmenu;
data_count = 0;
elseif nargin == 3,
m=0; n=0; p=0;
data_count = p;
else data_count = p;
end
if ~strcmp(s.class,'data')
if strcmp(s.class,'parameters') | strcmp(s.class,'simulation') | ...
strcmp(s.class,'instrument') | strcmp(s.class,'superdata')
mcplot_set_global(s, [], 0);
end
for i=1:max(size(tag_names))
d = getfield(s,tag_names{i});
if isstruct(d)
[ndc, d] = mcplot_scan(d,action,m,n,data_count,id);
data_count = ndc;
if length(d) > 0
setfield(s, tag_names{i}, d);
end
end
end
else
doplot = 1;
if length(id)
if ~length(findstr(s.filename,id)) & ~length(findstr(s.title,id)) & ~length(findstr(s.type,id))
doplot = 0;
end
end
if doplot
if length(findstr(action,'count'))
s = mcplot_plot(s, 0);
elseif length(findstr(action,'-plot'))
s = mcplot_plot(s, 1);
mcplot_set_global(s, [], 0);
mcplot_addmenu;
elseif length(findstr(action,'-overview'))
subplot(m,n,data_count+1);
s = mcplot_plot(s, 2);
mcplot_set_global(s, [], [m,n,data_count+1]);
end
data_count = data_count+1;
end
end % else class == 'data'
% end mcplot_scan