% Call function without arguments for instructions on how to use it % Filename: $RCSfile: image_show.m,v $ % % $Revision: 1.18 $ $Date: 2011/05/29 13:52:28 $ % $Author: $ % $Tag: $ % % Description: % read and display a 2D data frame % % Note: % Call without arguments for a brief help text. % % Dependencies: % - image_read % % % history: % % April 16th 2009: % bug-fix in histogram scaling, the intensity base level was not properly % taken into account, % auto-scaling is activated by a separate parameter to allow for arbitrary % scales % % February 23rd 2009: % add histogram scaling % % September 4th 2009: % add DisplayFtime and DisplayExptime parameters, % use new rowcol_from field of th eframe structure rather than handling the % region of interest specification here, % remove leading home directory and beamline specific path from displayed % filename % % February 23rd 2009: % add ImageHandle parameter for updating existing plots, % earlier the XScange and YScange parameters have been added % % August 28th 2008: % plot 1D data using plot % % May 9th 2008: % use image_read and named parameters, other changes since the last % history entry, rename from pilatus_show to image_show % % November 2006: 1st version %*-----------------------------------------------------------------------* %|                                                                       | %|  Except where otherwise noted, this work is licensed under a          | %|  Creative Commons Attribution-NonCommercial-ShareAlike 4.0            | %|  International (CC BY-NC-SA 4.0) license.                             | %|                                                                       | %|  Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch)    | %|                                                                       | %|      Author: CXS group, PSI  | %*-----------------------------------------------------------------------* % You may use this code with the following provisions: % % If the code is fully or partially redistributed, or rewritten in another % computing language this notice should be included in the redistribution. % % If this code, or subfunctions or parts of it, is used for research in a % publication or if it is fully or partially rewritten for another % computing language the authors and institution should be acknowledged % in written form in the publication: “Data processing was carried out % using the “cSAXS matlab package” developed by the CXS group, % Paul Scherrer Institut, Switzerland.” % Variations on the latter text can be incorporated upon discussion with % the CXS group if needed to more specifically reflect the use of the package % for the published work. % % A publication that focuses on describing features, or parameters, that % are already existing in the code should be first discussed with the % authors. % % This code and subroutines are part of a continuous development, they % are provided “as they are” without guarantees or liability on part % of PSI or the authors. It is the user responsibility to ensure its % proper use and the correctness of the results. function [frame,image_handle] = image_show(filename,varargin) import io.* import plotting.image_show import utils.default_parameter_value % accept cell array with name/value pairs as well no_of_in_arg = nargin; if (nargin == 2) if (isempty(varargin)) % ignore empty cell array no_of_in_arg = no_of_in_arg -1; else if (iscell(varargin{1})) % use a filled one given as first and only variable parameter varargin = varargin{1}; no_of_in_arg = 1 + length(varargin); end end end % set default values fig_no = default_parameter_value(mfilename,'FigNo'); fig_clear = default_parameter_value(mfilename,'FigClear'); auto_scale = default_parameter_value(mfilename,'AutoScale'); axis_min = default_parameter_value(mfilename,'AxisMin'); axis_max = default_parameter_value(mfilename,'AxisMax'); hist_scale = default_parameter_value(mfilename,'HistScale'); log_scale = default_parameter_value(mfilename,'LogScale'); x_scale =default_parameter_value(mfilename,'XScale'); y_scale =default_parameter_value(mfilename,'YScale'); x_offs =default_parameter_value(mfilename,'XOffs'); display_colorbar = default_parameter_value(mfilename,'ColorBar'); display_axes = default_parameter_value(mfilename,'Axes'); display_time = default_parameter_value(mfilename,'DisplayTime'); display_ftime = default_parameter_value(mfilename,'DisplayFtime'); display_exptime = default_parameter_value(mfilename,'DisplayExptime'); color_map = default_parameter_value(mfilename,'ColorMap'); bgr_data = default_parameter_value(mfilename,'BgrData'); image_handle = default_parameter_value(mfilename,'ImageHandle'); frame_number = default_parameter_value(mfilename,'FrameNumber'); frame = []; % check minimum number of input arguments and % check number of input arguments if ((nargin < 1) || (rem(no_of_in_arg,2) ~= 1)) image_read_help('ext',mfilename,'Examples',0,'ExtensionReturned',1); fprintf('''BgrData'', subtract this background from the data read\n'); fprintf('''FrameNumber'', in case of multiple frames per file select one or 0 for the average of all frames, default is %d\n',frame_number); fprintf('''FigNo'',
display figure in this window, default is %d\n',fig_no); fprintf('''FigClear'',<0-no, 1-yes> clear figure before plotting, default is %d (only used if no image handle is specified)\n',fig_clear); fprintf('''ImageHandle'', update the specified image which may be faster and can be used to keep constant zoom level\n'); fprintf('''AutoScale'',<[0-no/1-yes 0-no/1-yes]> intensity auto scaling of lower/upper limit, default is [%d %d]\n',auto_scale(1),auto_scale(2)); fprintf('''AxisMin'', intensity scaling if not in auto-scale mode, default is %.3e\n',axis_min); fprintf('''AxisMax'', intensity scaling if not in auto-scale mode, default is %.3e\n',axis_max); fprintf('''AxisMinMax'',<[ min max]> specify both min and max value\n'); fprintf('''HistScale'',<[low high]> in case of auto scaling scale the data to see the portion of the intensity values from low to high, default is [ %.2f %.2f]\n',hist_scale(1),hist_scale(2)); fprintf('''LogScale'',<0-no,1-yes> default is %d\n',log_scale); fprintf('''XScale'', default is %.3e\n',x_scale); fprintf('''YScale'', default is %.3e\n',y_scale); fprintf('''XOffs'', default is %.3e\n',x_offs); fprintf('''ColorBar'',<0-no,1-yes> display colorbar, default is %d\n',display_colorbar); fprintf('''ColorMap'',<''map-name''> choose colormap, default is ''%s''\n',color_map); fprintf('''Axes'',<0-no,1-yes> display axes, default is %d\n',display_axes); fprintf('''TitleString'',<''text''> fixed part of the title\n'); fprintf('''DisplayTime'',<0-no,1-yes> default is yes\n'); fprintf('\n'); fprintf('\n'); fprintf('Examples:\n'); fprintf('[frame,image_handle]=%s(''~/Data10/pilatus/image_1_ct.cbf'');\n',mfilename); fprintf('[frame,image_handle]=%s(''~/Data10/pilatus/image_1_ct.cbf'');\n',mfilename); fprintf('[frame,image_handle]=%s(''~/Data10/pilatus/image_1_ct.cbf'',''RowFrom'',100,''RowTo'',800,''ColumnFrom'',200,''ColumnTo'',1200,''AxisMin'',1,''AxisMax'',1e6);\n',mfilename); fprintf('[frame,image_handle]=%s(''~/Data10/pilatus/image_1_ct.cbf'',''AxisMax'',1e4);\n',mfilename); fprintf('\n'); fprintf('The returned structure has the fields data, header and extension.\n'); if (nargin < 1) error('At least the filename has to be specified as input parameter.'); else error('The optional parameters have to be specified as ''name'',''value'' pairs'); end end % parse the variable input arguments not handled by or on purpose not % passed to the image_read routine vararg = cell(0,0); for ind = 1:2:length(varargin) name = varargin{ind}; value = varargin{ind+1}; switch name case 'FigNo' fig_no = value; case 'FigClear' fig_clear = value; case 'ImageHandle' image_handle = value; case 'AxisMin' axis_min = value; case 'AxisMax' axis_max = value; case 'AxisMinMax' axis_min = value(1); axis_max = value(2); case 'AutoScale' auto_scale = value; case 'HistScale' hist_scale = value; case 'LogScale' log_scale = value; case 'XScale' x_scale = value; case 'YScale' y_scale = value; case 'XOffs' x_offs = value; case 'ColorBar' display_colorbar = value; case 'ColorMap' color_map = value; case 'Axes' display_axes = value; case 'DisplayTime' display_time = value; case 'DisplayFtime' display_ftime = value; case 'DisplayExptime' display_exptime = value; case 'BgrData' bgr_data = value; case 'FrameNumber' frame_number = value; case 'Frame' frame = value; otherwise vararg{end+1} = name; %#ok vararg{end+1} = value; %#ok end end % get the home directory path [stat,homedir] = system('echo ~'); if (stat ~= 0) homedir = ''; else if (~isempty(homedir)) homedir = homedir(1:end-1); end end % remove a beamline specific part [stat,username] = system('echo $USER'); if (stat == 0) if (~isempty(username)) username = username(1:end-1); end std_path = [ '/sls/X12SA/Data10/' username ]; if ((length(filename) > length(std_path)) && ... (strcmp(filename(1:length(std_path)),std_path))) filename = [ '~/Data10' filename(length(std_path)+1:end) ]; end end % read the frame if (isempty(frame)) [frame] = image_read(filename,vararg); end if (isempty(frame.data)) fprintf('%s: frame empty (file %s)\n',mfilename,filename); return; end if (axis_max <= axis_min) error('AxisMax must be greater than AxisMin'); end % subtract background if (~isempty(bgr_data)) if (size(bgr_data) ~= size(frame.data)) error('Background data dimension does not match data dimension.'); end frame.data = frame.data - bgr_data; end % define axes range x = x_scale * ... frame.rowcol_from{1}(2):(frame.rowcol_from{1}(2)+size(frame.data,2)-1) + ... x_offs; y = y_scale * ... frame.rowcol_from{1}(1):(frame.rowcol_from{1}(1)+size(frame.data,1)-1); % select the plot window if ((isempty(image_handle)) || (image_handle <= 0)) if (gcf ~= fig_no) figure(fig_no); end if (fig_clear) hold off; clf; end end % for dat files (like MCS data) display the last data set as a 1D plot if ((strcmp(frame.extension{1},'dat')) && (ndims(frame.data) > 1)) x = x_scale * (1:size(frame.data,1)) + x_offs; y = y_scale; end_ind = floor(frame.no_of_el_read{1} / length(x)) * length(x); begin_ind = end_ind - length(x) +1; if (begin_ind < 1) begin_ind = 1; end frame_plot = frame.data(begin_ind:end_ind); else if (ndims(frame.data) > 2) if (frame_number == 0) frame_plot = squeeze(mean(frame.data,3)); else frame_plot = squeeze(frame.data(:,:,frame_number)); end else frame_plot = frame.data; end end % display the frame if (log_scale) frame_plot(frame_plot < 1e-15) = 1e-15; end ax_min = axis_min; ax_max = axis_max; if ((length(x) == 1) || (length(y) ==1)) if (length(y) == 1) if (log_scale) semilogy(x,frame_plot); else plot(x,frame_plot); end xlabel('x [ pixel ]','FontSize',12); x_range = [ x(1) x(end) ]; else if (log_scale) semilogy(y,frame_plot); else plot(y,frame_plot); end xlabel('y [ pixel ]','FontSize',12); x_range = [ y(1) y(end) ]; end % axis scaling etc. ylabel('intensity','FontSize',12); as = axis; as(1:2) = x_range; % auto scale lower/upper limit if specified if (auto_scale(1)) ax_min = min(min(frame_plot)); end if (auto_scale(2)) ax_max = max(max(frame_plot)); end as(3) = ax_min; as(4) = ax_max; if (as(4) <= as(3)) as(4) = as(3) +1; end axis(as); else if (log_scale) ax_min = log10( axis_min ); ax_max = log10( axis_max ); frame_plot = log10( double(frame_plot) ); end if ((isempty(image_handle)) || (image_handle <= 0)) % initialize a new plot image_handle = imagesc(x,y,frame_plot); axis xy; axis equal; axis tight; if (~display_axes) axis off; end jet_mod = jet; for (i = 1:8) jet_mod(i,3) = i/8; end if (isempty(color_map)) colormap(jet_mod); else colormap(color_map); end if (display_colorbar) colorbar; end xlabel('x [ pixel ]','FontSize',12); ylabel('y [ pixel ]','FontSize',12); zlabel('intensity'); else % update an existing plot set(image_handle,'CData', frame_plot ); end % auto scale, if specified if (nnz(auto_scale)) % use one million intensity bins over the intensity range int_min = min(min(frame_plot)); int_max = max(max(frame_plot)); int_step = (int_max-int_min) / 2^20; % calculate the bin indices from the intensities hist_ind = round((frame_plot(:)-int_min) / int_step) +1; % increase each bin an index is pointing to by one hist_bins = zeros(1,max(hist_ind)-min(hist_ind)+1); for (ind_hist = 1:numel(hist_ind)) hist_bins(hist_ind(ind_hist)) = hist_bins(hist_ind(ind_hist)) +1; end % calculate the cumulative sum hist_bins = cumsum(hist_bins); % find the indices to the bins with more pixels than the threshold n_low = find(hist_bins > hist_scale(1) * numel(frame_plot),1,'first'); if (n_low >= length(hist_bins)) n_low = length(hist_bins) -1; end n_high = find(hist_bins > hist_scale(2) * numel(frame_plot),1,'first'); if (n_high <= n_low) n_high = n_low +1; end if (n_high > length(hist_bins)) n_high = length(hist_bins); end % use the corresponding intensities to scale the image if (auto_scale(1)) ax_min = (n_low-1) * int_step + int_min; end if (auto_scale(2)) ax_max = (n_high-1) * int_step + int_min; end % for (hist_iter = 1:4) % hist_bins = int_min:((int_max-int_min)/1e3):int_max; % [no_of_int_values] = hist(frame.data(:),hist_bins); % % calculate the cumulative sum and find the position above the % % lower and upper number of pixels threshold % cumsum_no_of_int_values = cumsum(no_of_int_values); % n_low = find(cumsum_no_of_int_values > hist_scale(1) * numel(frame_plot),1,'first') -1; % if (n_low >= length(hist_bins)) % n_low = length(hist_bins) -1; % end % if (n_low < 1) % n_low = 1; % end % n_high = find(cumsum_no_of_int_values > hist_scale(2) * numel(frame_plot),1,'first'); % if (n_high <= n_low) % n_high = n_low +1; % end % if (n_high > length(hist_bins)) % n_high = length(hist_bins); % end % % % sufficiently fine resolution is reached % if ((n_high > 5) && (n_high < length(hist_bins))) % % fprintf('%d: %d %d',hist_iter,n_low,n_high); % break; % end % % % change to a finer histogram spacing % int_min = hist_bins(n_low); % int_max = hist_bins(n_high); % end % % use the corresponding intensities to scale the image % if (ax_min <= 0) % ax_min = hist_bins(n_low); % end % if (ax_max <= 0) % ax_max = hist_bins(n_high); % end % frame_med = medfilt2(frame_plot,[ 3 3 ]); % if (ax_min <= 0) % ax_min = 0.1 * mean(mean(frame_med)); % end % if (ax_max <= 0) % ax_max = max(max(frame_med)); % end end caxis( [ ax_min ax_max ] ); end % compile title string: % replace home directory by tilde if ((length(filename) > length(homedir)) && ... (strcmp(filename(1:length(homedir)),homedir))) title_str = [ '~' filename(length(homedir)+1:end) ]; else title_str = filename; end % escape underscore characters from LaTeX-like use title_str = strrep(title_str,'_','\_'); if (log_scale) title_str = [ title_str ' (log.)' ]; end % add current time if (display_time) clock_now = clock(); title_str = [ title_str ' ' ... num2str(clock_now(4)) ':' num2str(clock_now(5),'%02.0f') ... ':' num2str(clock_now(6),'%02.0f') ]; end % get and display date string from file if (display_ftime) title_str = [ title_str '\newlinefile date: ' ... common_header_value(frame.header{1},frame.extension{1},'Date') ]; end % get and display exposure time if (display_exptime) title_str = [ title_str ', exposure time = ' ... num2str(common_header_value(frame.header{1},frame.extension{1},... 'ExposureTime'),'%.3f') ' sec' ]; end % add the frame number to the title string if (frame_number == 0) title_str = [ title_str ', frame average' ]; else title_str = [ title_str sprintf(', frame %d',frame_number) ]; end % display the compiled title string title(title_str,'FontSize',14); return;