initial commit

This commit is contained in:
2026-08-07 15:56:42 +09:00
commit 91ad25aca9
1012 changed files with 159314 additions and 0 deletions
+429
View File
@@ -0,0 +1,429 @@
% Call function without arguments for instructions on how to use it
% Filename: $RCSfile: mcs_mesh.m,v $
%
% $Revision: 1.7 $ $Date: 2016/08/03 08:38:32 $
% $Author: $
% $Tag: $
%
% Description:
% Macro for reading .dat files in self-defined data formats
%
% Note:
% Call without arguments for a brief help text.
%
% Dependencies:
% - image_read_set_default
% - fopen_until_exists
% - get_hdr_val
% - compiling cbf_uncompress.c increases speed but is not mandatory
%
%
% history:
%
% February 18th 2009: 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 [mcs_data, data_adjusted, pos_data] = mcs_mesh(first_scan_no,no_of_intervals,varargin)
import io.*
import utils.adjust_projection
import utils.fopen_until_exists
import utils.get_hdr_val
% initialize return arguments
mcs_data = [];
% legacy_sgalil = false; % A flag that keeps track of different commands needed if the older legacy file of reading positions is used - 2019.04
% set default parameter
% plot this MCS channel
ch_to_plot = 4;
snake_scan=0;
fast_axis_x = 1;
% create the plot in this figure
fig_no = 123;
% exit with an error message if unhandled named parameters are left at the
% end of this macro
unhandled_par_error = 1;
% file name base
fname_base = '';
% first part of directory path
dir_base = '~/Data10/mcs/';
% scaling factors for the axes
x_scale = 1.0;
y_scale = 1.0;
%
axis_minmax = [];
% save resulting figure
figure_dir = '~/Data10/analysis/online/stxm/figures/';
% save the resulting data
data_dir = '~/Data10/analysis/online/stxm/data/';
pos_file = '~/Data10/sgalil/S%05d.dat';
positions_only = false;
% check minimum number of input arguments
if (nargin < 2)
fprintf('[mcs_data data_adjusted pos_data]=%s(<first scan no.>, <no. of line intervals> [[,<name>,<value>] ...]);\n',...
mfilename);
fprintf('The optional <name>,<value> pairs are:\n');
fprintf('''ChToPlot'',<channel no.> if greater than zero than this channel is plotted, default is %d\n',ch_to_plot);
fprintf('''SnakeScan'',<0-no, 1-yes> scan mode is a snake pattern, default is 0\n');
fprintf('''FastAxisX'',<0-no, 1-yes> fast scan axis is along x, default is 1\n');
fprintf('''FigNo'',<figure number> plot the data in this figure, 0 for no figure, default is %d\n',fig_no);
fprintf('''XScale'',<scale factor> scale the x-axis with this factor\n');
fprintf('''YScale'',<scale factor> scale the y-axis with this factor\n');
fprintf('''AxisMinMax'',<[ min max]> specify both min and max value\n');
fprintf('''DirBase'',<first part of data path> including an ending slash, default is ''%s''\n',dir_base);
fprintf('''FnameBase'',<first part of file name> in case of an empty string the current Unix user name is used followed by an underscore, default if ''%s''\n',fname_base);
fprintf('''FigureDir'',''directory'' save the resulting plot in eps, jpeg and Matlab fig format, '''' for no saving, default is %s\n',figure_dir);
fprintf('''DataDir'',''directory'' save the resulting data as Matlab file, '''' for no saving, default is %s\n',data_dir);
fprintf('''Pos_file'',''path and filename structure'' checks the flipping of images using the positions found in these files. It gives a warning if it detects the wrong fast axis and it flips the lines for snake scans.\n');
fprintf(' If the filename structure includes an %% it tries to read positions assuming one dat file for each scan. If it does not include an %% then it uses spec_read.\n');
fprintf(' Default is %s, set to empty =[ ] to avoid warnings \n',pos_file);
fprintf('''Positions_only'',<0-no, 1-yes> if you only use the routine to get and check positions of a scan but you don''t have a MCS scalar measurement, default is %d.\n', positions_only);
fprintf('The data are in the format ''fast to slow axis'', i.e., the first dimension is the MCS channel,\n');
fprintf('the second dimension is the exposure index, the third dimension is the fast axis of a mesh scan\n');
fprintf('and the fourth dimension is the slow axis of a mesh scan.\n');
fprintf('An optional second output ''data_adjusted'' can be obtained. This is a structure that has been adjusted and flipped according to the scan parameters in order to reflect\n');
fprintf(' the sample physical orientation. One of the fields is ''transm'' which is the sample transmissivity. Other fields are positions_out, scan_num, and scan_point.\n');
error('At least the number of the first scan and the number of line intervals need to be specified as input parameter.');
end
% accept cell array with name/value pairs as well
no_of_in_arg = nargin;
if (nargin == 3)
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
% check number of input arguments
if (rem(no_of_in_arg,2) ~= 0)
error('The optional parameters have to be specified as ''name'',''value'' pairs');
end
% parse the variable input arguments
vararg = cell(0,0);
for ind = 1:2:length(varargin)
name = varargin{ind};
value = varargin{ind+1};
switch name
case 'ChToPlot'
ch_to_plot = value;
case 'SnakeScan'
snake_scan = value;
case 'FastAxisX'
fast_axis_x = value;
case 'FigNo'
fig_no = value;
case 'XScale'
x_scale = value;
case 'YScale'
y_scale = value;
case 'AxisMinMax'
axis_minmax = value;
case 'UnhandledParError'
unhandled_par_error = value;
case 'FnameBase'
fname_base = value;
case 'DirBase'
dir_base = value;
case 'DataDir'
data_dir = value;
case 'FigureDir'
figure_dir = value;
case 'Pos_file'
pos_file = value;
case 'Positions_only'
positions_only = value;
otherwise
vararg{end+1} = name; %#ok<AGROW>
vararg{end+1} = value; %#ok<AGROW>
end
end
% initialize the list of unhandled parameters
vararg_remain = cell(0,0);
% get the current user name
if (length(fname_base) < 1)
[stat,usr]=unix('echo $USER');
fname_base = [ sscanf(usr,'%s') '_' ];
end
% initialize the output figure
if ~positions_only
figure(fig_no);
hold off;
clf;
end
last_scan_no = first_scan_no + no_of_intervals;
store_ind = 1;
last_draw_time = clock;
% over all the scan lines
for scan_no = first_scan_no:last_scan_no
dir = [ dir_base 'S' num2str(floor(scan_no/1000)*1000,'%05d') '-' ...
num2str(floor(scan_no/1000)*1000+999,'%05d') '/S' num2str(scan_no,'%05d') '/' ];
filename = [ fname_base num2str(scan_no,'%05d') '.dat' ];
% read the frame until all data are available
ind_rep = 0;
ind_max = 3;
last_no_of_el_read = 0;
if ~positions_only
while (ind_rep < ind_max)
frame = image_read([dir filename ], 'RetryReadSleep',10, ...
'RetryReadMax',1, 'RetrySleepWhenFound',10);
if ~isempty(frame.data)&&(frame.no_of_el_read{1} >= numel(frame.data))
% the complete data set has been read
break;
end
if ~isempty(frame.data)&&(frame.no_of_el_read{1} <= last_no_of_el_read)
% no progress, increase timeout counter
ind_rep = ind_rep +1;
else
ind_rep = 0;
end
if ~isempty(frame.no_of_el_read)
last_no_of_el_read = frame.no_of_el_read{1};
end
if ~isempty(frame.header)
exp_time = get_hdr_val(frame.header{1},'Exposure_time','%f',1);
end
wait_time = numel(frame.no_of_el_read)*exp_time;
if (wait_time > 2.0)
fprintf('%d/%d: frame incomplete (%d/%d), waiting %.1fs and retrying\n',...
ind_rep+1,ind_max,frame.no_of_el_read{1},numel(frame.data));
end
pause(wait_time);
end
end
if ~isempty(pos_file)
if contains(pos_file,'%')
positions_from_spec = false;
filepos = sprintf(pos_file,scan_no);
try
positions = beamline.read_position_file(filepos);
positions.data(1,:) = positions.Avg_x;
positions.data(2,:) = positions.Avg_y;
numpts = numel(positions.Avg_x);
catch
warning('The reading of positions for sgalil did not work, now trying legacy mode in older sgalil position format')
positions = image_read(filepos,'RetryReadSleep',10,'RetryReadMax',0);
numpts = size(positions.data,2);
% legacy_sgalil = true;
end
else % If it does not contain % delimiter then we assume is a spec file
positions_from_spec = true;
if scan_no == last_scan_no % Only read spec positions once all scans are done, otherwise is too slow to read each time
try
fprintf('Reading positions from spec file %s \n',pos_file)
positions = io.read_scan_positions_spec(pos_file,first_scan_no:last_scan_no,{'samx','samy'});
catch
warning('io.read_scan_positions_spec failed, pausing 5 seconds and retrying')
pause(5);
positions = io.read_scan_positions_spec(pos_file,first_scan_no:last_scan_no,{'samx','samy'});
end
else
positions.data = [];
end
end
end
% initialize return array
if (scan_no == first_scan_no)
if ~positions_only
mcs_data = zeros(size(frame.data,1),size(frame.data,2),...
size(frame.data,3) + 1 ,no_of_intervals+1);
numpts = size(frame.data,3) + 1;
else
mcs_data = [];
numpts = size(positions.data,2);
end
[scan_num, scan_point] = meshgrid(first_scan_no:last_scan_no,0:numpts-1);
% Check positions of stage for flipping
if ~isempty(pos_file)
pos_data = zeros(numpts, no_of_intervals+1, 2);
else
pos_data = [];
end
end
if ~positions_only
store_ind_to = store_ind + size(frame.data,4) - 1;
else
store_ind_to = store_ind;
end
%%% Special about MCS is that it does not take the first image because
%%% it is triggered in a strange way, so here to match other
%%% detectors we make the matrix one element larger and we replicate
%%% the first value
if ~positions_only
mcs_data(:,:,2:end,store_ind:(store_ind+size(frame.data,4)-1)) = frame.data;
mcs_data(:,:,1,store_ind:(store_ind+size(frame.data,4)-1)) = frame.data(:,1,2,:);
end
if ~isempty(pos_file)
if ~positions_from_spec
pos_data(:,store_ind,:) = positions.data.';
else % if positions are from spec they are read only at the end and arranged in a structure so they need special handling
if scan_no == last_scan_no
pos_data = zeros(size(positions(1).data,1),no_of_intervals+1,2);
for ii = numel(positions)
pos_data(:,ii,:) = positions(ii).data;
end
end
end
end
store_ind = store_ind_to +1;
if ((scan_no == first_scan_no) || (scan_no == last_scan_no) || ...
(etime(clock,last_draw_time) > 10))
if (size(mcs_data,2) == 1)
data_plot = squeeze(mcs_data(ch_to_plot,1,:,:));
elseif ~isempty(mcs_data)
data_plot = squeeze(mcs_data(ch_to_plot,:,:,1));
else
data_plot = [];
end
if (~positions_only)&&((size(data_plot,1) > 1) && (size(data_plot,2) > 1))
%CHANGE
[data_plot, positions_out] = adjust_projection(data_plot, snake_scan, fast_axis_x, pos_data);
% 2D plot
x_values = (1:size(data_plot,2)) * x_scale;
y_values = (1:size(data_plot,1)) * y_scale;
if (~isempty(axis_minmax))
caxis(axis_minmax);
end
%plot the image
figure(fig_no)
imagesc(data_plot);
axis xy;
axis equal;
axis tight;
colormap gray;
colorbar;
title( [ fname_base ': #' num2str(first_scan_no) ' -' num2str(scan_no)] );
drawnow;
elseif (~positions_only)
% 1D plot if only one line has been read
x_values = (1:length(data_plot)) * x_scale;
plot(x_values,data_plot);
else
[data_plot, positions_out] = adjust_projection(data_plot, snake_scan, fast_axis_x, pos_data);
end
last_draw_time = clock;
end
end
[scan_num] = adjust_projection(scan_num, snake_scan, fast_axis_x, pos_data);
[scan_point] = adjust_projection(scan_point, snake_scan, fast_axis_x, pos_data);
data_adjusted.transm = data_plot;
data_adjusted.positions_out = positions_out;
data_adjusted.scan_num = scan_num;
data_adjusted.scan_point = scan_point;
% file name for saving
filename = sprintf('stxm_scans_%05d-%05d_mcs',first_scan_no,...
last_scan_no);
% save figures
if (~isempty(figure_dir))&&(~positions_only)
figure(fig_no);
% create output directories and write the plot in different formats
if (~exist(figure_dir,'dir'))
mkdir(figure_dir)
end
if ((figure_dir(end) ~= '/') && (figure_dir(end) ~= '\'))
figure_dir = [ figure_dir '/' ];
end
fprintf('output directory for figures is %s\n',figure_dir);
subdir = [ figure_dir 'jpg/' ];
if (~exist(subdir,'dir'))
mkdir(subdir);
end
fprintf('saving %s.jpg\n',filename);
print('-djpeg','-r300',[subdir filename '.jpg'] );
subdir = [ figure_dir 'eps/' ];
if (~exist(subdir,'dir'))
mkdir(subdir);
end
fprintf('saving %s.eps\n',filename);
print('-depsc','-r1200',[subdir filename '.eps'] );
subdir = [ figure_dir 'fig/' ];
if (~exist(subdir,'dir'))
mkdir(subdir);
end
fprintf('saving %s.fig\n',filename);
hgsave([subdir filename '.fig']);
end
% save resulting data
if (~isempty(data_dir))
if ((data_dir(end) ~= '/') && (data_dir(end) ~= '\'))
data_dir = [ data_dir '/' ];
end
% create output directory
if (~exist(data_dir,'dir'))
mkdir(data_dir)
end
% save data
fprintf('saving %s.mat\n',[data_dir filename]);
save([data_dir filename],'mcs_data','first_scan_no','last_scan_no','pos_data','data_adjusted');
end
return