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
+264
View File
@@ -0,0 +1,264 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function:
%
% [theta_corr_sorted,delta_stack_corr_x_filt,delta_stack_corr_y_filt] = give_calibration(obj_interf_pos_x, obj_interf_pos_y, deltastack, deltaslice, param)
%
% Description:
%
% The function (1) saves the alignment arrays for later use and
% (2) saves the vertical correction into a .txt (and .mat) file for
% correcting the vertical fluctuarion throguh SPEC
%
% Input:
%
% obj_interf_pos_x and obj_interf_pos_y: obatined from running get_auto_tomo.m
% deltastack: alignment for x and y
% deltaslice: additional alignment for x
% param. savedata: 0 (default) or 1
% param. surface_calib_file
% param. get_auto_calibration: 0 or 1 (default)
% param. pixsize (mandatory)
% param. theta (mandatory)
% param. scans (mandatory)
% param. output_folder (default: './')
%
% Output:
%
% theta_corr_sorted
% delta_stack_corr_x_filt
% delta_stack_corr_y_filt
%
% 2017-03-30
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%*-----------------------------------------------------------------------*
%|                                                                       |
%|  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 [thetasort,delta_stack_corr_x_filt,delta_stack_corr_y_filt] = ...
give_calibration(obj_interf_pos_x, obj_interf_pos_y, deltastack, deltaslice, theta, scans, param)
if isfield(param,'get_auto_calibration')
get_auto_calibration = param.get_auto_calibration;
else
fprintf('Using get_auto_calibration = 1\n');
get_auto_calibration = 1;
end
if ~isfield(param,'surface_calib_file')
error('Set param.surface_calib_file');
end
if isfield(param,'output_folder')
output_folder = param.output_folder;
else
fprintf('Set output_folder to the pwd \n');
output_folder = './';
end
if isfield(param,'pixel_size')
pixsize = param.pixel_size;
else
error('Need to specify param.pixel_size\n');
end
[thetasort, indsort] = sort(theta);
if get_auto_calibration
Nangles = length(theta);
%%% Get correction from interferometer and alignment values in meters
delta_stack_corr_y = deltastack(1,:)*pixsize;
delta_stack_corr_x = (deltastack(2,:)+deltaslice)*pixsize;
%% %%% remove outliers by median filter %%%%%%%%%%%%%%%%%%%%
%%% Subtract the a*sin(x+b)+c term from x correction
[rigid_shift] = fit_sinus(theta, delta_stack_corr_x');
delta_stack_corr_x = delta_stack_corr_x - rigid_shift';
%%% Remove constant term from y correction
delta_stack_corr_y = delta_stack_corr_y - mean(delta_stack_corr_y);
%%% filtering to avoid outliers in the alignment, seems to work better when it is done
%%% after sinus removal
delta_stack_corr_x_filt = medfilt1(delta_stack_corr_x, 5);
delta_stack_corr_y_filt = medfilt1(delta_stack_corr_y, 5);
delta_stack_corr_x_filt = delta_stack_corr_x_filt + rigid_shift';
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% apply sorting
delta_stack_corr_x_filt = delta_stack_corr_x_filt(indsort)';
delta_stack_corr_y_filt = delta_stack_corr_y_filt(indsort)';
figure(1);
clf;
subplot(2,1,1)
plot(theta,obj_interf_pos_y*1e6,'.')
title('Interferometer y position')
axis tight ; grid on
xlabel('Angles [deg]')
ylabel('Shift [\mum]')
subplot(2,1,2)
plot(theta,obj_interf_pos_x*1e6,'.')
title('Interferometer x position (plus "clicking correction" term) [microns]')
axis tight ; grid on
xlabel('Angles [deg]')
ylabel('Shift [\mum]')
figure(4);
clf;
subplot(2,1,1)
plot(theta,deltastack(1,:)*pixsize*1e6,'.')
title('Alignment in y (without removal of constant term)')
ylabel('Shift [\mum]')
xlabel('Angles [deg]')
axis tight ; grid on
subplot(2,1,2)
plot(theta,( deltastack(2,:)+deltaslice)*pixsize*1e6,'.')
title('Alignment in x (without removal of sinus term)')
ylabel('Shift [\mum]')
xlabel('Angles [deg]')
axis tight ; grid on
figure(3);
clf;
subplot(2,1,1)
plot(thetasort,delta_stack_corr_y_filt*1e6,'.')
title('Correction in y (after removal of constant term)')
ylabel('Shift [\mum]')
axis tight ; grid on
xlabel('Angles [deg]')
subplot(2,1,2)
plot(thetasort,delta_stack_corr_x_filt*1e6,'.')
title('Correction in x (after removal of constant term)')
ylabel('Shift [\mum]')
axis tight ; grid on
xlabel('Angles [deg]')
output_png1 = [ output_folder 'delta_stack_corr.png'];
fprintf('Writting image files \n %s\n',output_png1);
print('-f3','-dpng','-r300',output_png1);
%% Calculate the correction for interferometers
corr(:,1) = delta_stack_corr_x_filt*1e6;
corr(:,2) = delta_stack_corr_y_filt*1e6;
%%% Filter the correction to remove effects of long term drifts !!
corr = medfilt1(corr, 11);
filter = ceil(Nangles / 10);
corr(:,1) = smooth(thetasort, corr(:,1), filter, 'sgolay');
corr(:,2) = smooth(thetasort, corr(:,2), filter, 'sgolay');
calibration_file = sprintf('correction_interferometers_um_S%05d.txt',scans(1));
% -----
figure(50);
clf()
plot(thetasort,corr, '.-'); grid on; ylabel('Correction \mum')
legend({'Horizontal', 'Vertical'})
title(sprintf('%s',output_folder),'interpreter','none');
xlabel('Angles [deg]')
axis tight; grid on
plotting.suptitle(sprintf('Final interferometer correction in file \n%s', calibration_file),'interpreter', 'none')
output_png1 = fullfile( output_folder, 'y_alignment.png');
fprintf('Writting image files \n %s\n',output_png1);
print('-f50','-dpng','-r300',output_png1);
figure(51);
plot(1:length(theta),theta); grid on;
title(sprintf('%d projections',length(theta)));
output_png1 = fullfile( output_folder , 'theta.png');
fprintf('Writting image files \n %s\n',output_png1);
print('-f51','-dpng','-r300',output_png1);
%%% Save file
utils.verbose(0, 'Saving interferometer correction to %s', param.surface_calib_file)
obj_interf_pos_x_sort = obj_interf_pos_x(indsort);
obj_interf_pos_y_sort = obj_interf_pos_y(indsort);
utils.savefast_safe(param.surface_calib_file, 'thetasort','delta_stack_corr_x_filt','delta_stack_corr_y_filt', 'obj_interf_pos_x_sort', 'obj_interf_pos_y_sort')
%%% save correction for SPEC
if ~exist(calibration_file, 'file') || strcmpi(input(sprintf('Do you want to overwrite %s (y/N)? ', calibration_file),'s'),'y')
utils.verbose(0, 'Saving interferometer correction to %s', calibration_file)
h = fopen(calibration_file,'w');
fprintf(h,'corr_elements = %d \n', Nangles);
fprintf(h,'corr_elements_x = %d \n', Nangles);
for jj = 1:Nangles
fprintf(h,'%s[%d] = %.6f \n',...
'corr_angle',jj-1,thetasort(jj));
fprintf(h,'%s[%d] = %.6f \n',...
'corr_angle_x',jj-1,thetasort(jj));
fprintf(h,'%s[%d] = %.6f \n',...
'corr_pos',jj-1, corr(jj,2));
fprintf(h,'%s[%d] = %.6f \n',...
'corr_pos_x',jj-1, corr(jj,1));
end
fclose(h);
end
end
end
function [rigid_shift] = fit_sinus(theta, signal)
% subtract the a*sin(x+b) from the data
orthbase = [sind(theta(:)), cosd(theta(:)),ones(length(theta),1)]; %
coefs = (orthbase'*orthbase) \ (orthbase'*signal);
% avoid object drifts within the reconstructed FOV
coefs(3) = 0; % preserve the offset
rigid_shift = orthbase*coefs;
end