mirror of
https://github.com/c-sooyoung/fold_slice.git
synced 2026-09-17 23:59:11 +09:00
initial commit
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
function Vst = TVDerivative(img)
|
||||
|
||||
fxy = padarray(img, [1,1], 0, 'both');
|
||||
fxnegy = circshift(fxy, [-1, 0]);
|
||||
fxposy = circshift(fxy, [1, 0]);
|
||||
fnegxy = circshift(fxy, [0, -1]);
|
||||
fposxy = circshift(fxy, [0, 1]);
|
||||
fposxnegy = circshift(fxy, [-1 1]);
|
||||
fnegxposy = circshift(fxy, [1 -1]);
|
||||
eps = realmin;
|
||||
|
||||
vst1 = (2*(fxy - fnegxy) + 2*(fxy - fxnegy))./sqrt(eps + (fxy - fnegxy).^2 ...
|
||||
+ (fxy - fxnegy).^2);
|
||||
|
||||
vst2 = (2*(fposxy - fxy))./sqrt(eps + (fposxy - fxy).^2 ...
|
||||
+ (fposxy - fposxnegy).^2);
|
||||
|
||||
vst3 = (2*(fxposy - fxy))./sqrt(eps + (fxposy - fxy).^2 ...
|
||||
+ (fxposy - fnegxposy).^2);
|
||||
|
||||
vst = vst1 - vst2 - vst3;
|
||||
Vst = vst(2:end-1,2:end-1);
|
||||
|
||||
end
|
||||
@@ -0,0 +1,64 @@
|
||||
function [recon_constrained] = TV_Fourier_smoothing(I, I_f, Niter, show_figure)
|
||||
%UNTITLED3 Summary of this function goes here
|
||||
% Detailed explanation goes here
|
||||
%Convergence Parameters
|
||||
%Niter = 10;
|
||||
iter_TVdecent = 30;
|
||||
a = 0.5; %Decent Parameter
|
||||
|
||||
% Create a mask that will remove the region of interest (ROI).
|
||||
mask = I_f~=0;
|
||||
|
||||
%Create Random Image
|
||||
[nx, ny] = size(I);
|
||||
recon_init = rand(nx,ny);
|
||||
|
||||
%recon_init = I;
|
||||
|
||||
%%
|
||||
for i = 1:Niter
|
||||
|
||||
% Counter.
|
||||
disp(i)
|
||||
|
||||
% FFT of Reconstructed Image.
|
||||
FFTr = fftshift(fft2(ifftshift(recon_init)));
|
||||
|
||||
% Remove the ROI with Data Constraint.
|
||||
FFTr(mask) = I_f(mask);
|
||||
|
||||
%Inverse FFT
|
||||
recon_constrained = real(fftshift(ifft2(ifftshift(FFTr))));
|
||||
|
||||
%Positivity Constraint.
|
||||
%recon_constrained(recon_constrained<0) = 0;
|
||||
|
||||
%TV Minimization.
|
||||
recon_minTV = recon_constrained;
|
||||
d = (sum(sum((recon_minTV-recon_init).^2))).^(1/2);
|
||||
for j = 1:iter_TVdecent
|
||||
|
||||
Vst = TVDerivative(recon_minTV);
|
||||
L2norm = (sum(sum(Vst.^2))).^(1/2);
|
||||
Vst = Vst/L2norm;
|
||||
recon_minTV = recon_minTV - a*d*Vst;
|
||||
|
||||
end
|
||||
|
||||
% Initialize next loop.
|
||||
recon_init = recon_minTV;
|
||||
|
||||
end
|
||||
if show_figure
|
||||
% Show the Reconstruction
|
||||
figure
|
||||
imagesc((recon_minTV+recon_constrained)/2); axis image; colormap gray
|
||||
figure
|
||||
f = fftshift(fft2(recon_constrained));
|
||||
imagesc(abs(f).^0.2); axis image; colormap jet
|
||||
end
|
||||
%Save the Reconstructions
|
||||
%imwrite(mat2gray(recon_constrained), [fname '_Reconstruction.tif'], 'tiff')
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
function [n_out, w, trivalwin] = check_order(n_in)
|
||||
%CHECK_ORDER Checks the order passed to the window functions.
|
||||
% [N,W,TRIVALWIN] = CHECK_ORDER(N_ESTIMATE) will round N_ESTIMATE to the
|
||||
% nearest integer if it is not already an integer. In special cases (N is
|
||||
% [], 0, or 1), TRIVALWIN will be set to flag that W has been modified.
|
||||
|
||||
% Copyright 1988-2002 The MathWorks, Inc.
|
||||
|
||||
w = [];
|
||||
trivalwin = 0;
|
||||
|
||||
if ~(isnumeric(n_in) && isfinite(n_in))
|
||||
error(message('signal:check_order:InvalidOrderFinite', 'N'));
|
||||
end
|
||||
|
||||
% Special case of negative orders:
|
||||
if n_in < 0
|
||||
error(message('signal:check_order:InvalidOrderNegative'));
|
||||
end
|
||||
|
||||
% Check if order is already an integer or empty
|
||||
% If not, round to nearest integer.
|
||||
if isempty(n_in) || n_in == floor(n_in)
|
||||
n_out = n_in;
|
||||
else
|
||||
n_out = round(n_in);
|
||||
warning(message('signal:check_order:InvalidOrderRounding'));
|
||||
end
|
||||
|
||||
% Special cases:
|
||||
if isempty(n_out) || n_out == 0
|
||||
w = zeros(0,1); % Empty matrix: 0-by-1
|
||||
trivalwin = 1;
|
||||
elseif n_out == 1
|
||||
w = 1;
|
||||
trivalwin = 1;
|
||||
end
|
||||
@@ -0,0 +1,43 @@
|
||||
function ellipse_fit_positions(samposx,samposy,scans,lamni_fit_file,bath_path)
|
||||
|
||||
% addpath ../
|
||||
%
|
||||
% cf{1} = load('Claire_click_squarymcsquareface.mat');
|
||||
% samposx_all = [];
|
||||
% samposy_all = [];
|
||||
% scans_all = [];
|
||||
% for ii = 1:numel(cf)
|
||||
% samposx_all = [samposx_all cf{ii}.samposx];
|
||||
% samposy_all = [samposy_all cf{ii}.samposy];
|
||||
% scans_all = [scans_all cf{ii}.scans];
|
||||
% end
|
||||
|
||||
figure(1);
|
||||
clf
|
||||
plot(samposx,samposy,'o')
|
||||
|
||||
%%
|
||||
if exist('lamni_fit_file')
|
||||
[~,lamni_name,~] = fileparts(lamni_fit_file);
|
||||
%theta = prepare.read_angles_from_position_files('~/specES1/scan_positions/scan_%05d.dat',scans);
|
||||
theta = prepare.read_angles_from_position_files(strcat(bath_path,'/scan_positions/scan_%05d.dat'),scans);
|
||||
|
||||
theta_interp = [min(theta)-1:max(theta)+1];
|
||||
|
||||
samposx_interp = interp1(theta,samposx,theta_interp,'spline');
|
||||
samposy_interp = interp1(theta,samposy,theta_interp,'spline');
|
||||
hold on
|
||||
plot(samposx_interp, samposy_interp,'--')
|
||||
hold off
|
||||
|
||||
corr_filename = sprintf('correction_lamni_um_S%05d_%s.txt',scans(1),lamni_name);
|
||||
h = fopen(corr_filename,'w');
|
||||
fprintf(h,'corr_elements = %d \n',length(theta_interp));
|
||||
for ii = 1:length(samposx_interp)
|
||||
fprintf(h,'%s[%d] = %.6f \n','corr_angle',ii-1,theta_interp(ii));
|
||||
fprintf(h,'%s[%d] = %.6f \n','corr_pos_x',ii-1, samposx_interp(ii));
|
||||
fprintf(h,'%s[%d] = %.6f \n','corr_pos_y',ii-1, samposy_interp(ii));
|
||||
end
|
||||
fclose(h);
|
||||
fprintf('Wrote succesfully to %s\n',corr_filename)
|
||||
end
|
||||
@@ -0,0 +1,95 @@
|
||||
% FIND_ML_RECON_FILES_NAMES find names of ML ptychographic reconstructions given
|
||||
% the param structure defined by YJ for the APS datasets.
|
||||
% user can search for differernt # of probes and OPR modes
|
||||
%
|
||||
% filename = find_projection_files_names(par, scan_num)
|
||||
%
|
||||
% Inputs
|
||||
% **par tomo par structure
|
||||
% **scan_num scan number
|
||||
% *returns*
|
||||
% ++filename filename of the found scan
|
||||
|
||||
|
||||
function [filename,method,roi,scanNo] = find_ML_recon_files_names(par, scan_num)
|
||||
N_roi = linspace(1,length(par.MLrecon.roi),length(par.MLrecon.roi));
|
||||
[N_roi_temp, Nprobe_s_temp,var_probe_modes_s_temp] = ndgrid(N_roi,par.MLrecon.Nprobes, par.MLrecon.var_probe_modes);
|
||||
N_roi_temp = reshape(N_roi_temp,[],1);
|
||||
Nprobe_s_temp = reshape(Nprobe_s_temp,[],1);
|
||||
var_probe_modes_s_temp = reshape(var_probe_modes_s_temp,[],1);
|
||||
filename = [];
|
||||
scanNo = num2str(scan_num);
|
||||
for i=1:length(Nprobe_s_temp)
|
||||
roi = par.MLrecon.roi{N_roi_temp(i)};
|
||||
Nprobe = Nprobe_s_temp(i);
|
||||
vp_modes = var_probe_modes_s_temp(i);
|
||||
%method = sprintf(par.MLrecon.method,Nprobe,vp_modes,Nprobe,vp_modes);
|
||||
method = '';
|
||||
for j=1:length(par.MLrecon.method)
|
||||
method = strcat(method,sprintf(par.MLrecon.method{j},Nprobe,vp_modes));
|
||||
end
|
||||
|
||||
filename_temp = strcat(par.MLrecon.path, sprintf(par.scan_string_format, scan_num),roi, method,'/Niter',num2str(par.MLrecon.Niter),'.mat');
|
||||
%disp('filename_temp:')
|
||||
%disp(filename_temp)
|
||||
if ~isempty(dir(filename_temp))
|
||||
d = dir(filename_temp);
|
||||
%filename = filename_temp;
|
||||
filename = strcat(d(1).folder,'/',d(1).name);
|
||||
%disp('filename:')
|
||||
%disp(filename)
|
||||
%disp(strcat(d.folder,'/',d.name))
|
||||
|
||||
%disp(strcat(sprintf(par.scan_string_format, scan_num),'--',method,'Niter',num2str(par.MLrecon.Niter),'.mat'))
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
%{
|
||||
%bug?
|
||||
%%%data_in_subfolders = exist(fullfile(par.analysis_path, 'S00000-00999'), 'dir');
|
||||
data_in_subfolders = exist(fullfile(par.analysis_path, 'S02000-02999'), 'dir');
|
||||
|
||||
if data_in_subfolders
|
||||
% new x12sa path format
|
||||
% bug?
|
||||
%%%path = fullfile(par.analysis_path, utils.compile_x12sa_dirname(scan_num) , [par.fileprefix '*' par.filesuffix '*.' par.file_extension]);
|
||||
%modified by YJ
|
||||
path = fullfile(par.analysis_path, utils.compile_x12sa_dirname(scan_num) , [sprintf('S%05i',scan_num), par.fileprefix '*' par.filesuffix '*.' par.file_extension]);
|
||||
|
||||
else
|
||||
% compatibility option for original analysis paths
|
||||
%path = fullfile(par.analysis_path,sprintf('S%05i',scan_num),[par.fileprefix '*' par.filesuffix '*.' par.file_extension]);
|
||||
% path = strcat(par.analysis_path,sprintf(par.scan_string_format,scan_num),'.', par.file_extension);
|
||||
%generate a list of possibe recon parameters
|
||||
%current support: number of probe modes; number of OPR modes
|
||||
[Nprobe_s_temp,var_probe_modes_s_temp] = meshgrid(par.MLrecon.Nprobes, par.MLrecon.var_probe_modes);
|
||||
Nprobe_s_temp = reshape(Nprobe_s_temp,[],1);
|
||||
var_probe_modes_s_temp = reshape(var_probe_modes_s_temp,[],1);
|
||||
for i=1:length(Nprobe_s_temp)
|
||||
Nprobe = Nprobe_s_temp(i);
|
||||
vp_modes = var_probe_modes_s_temp(i);
|
||||
method = sprintf(par.MLrecon.method,Nprobe,vp_modes,Nprobe,vp_modes);
|
||||
filename = strcat(par.MLrecon.path, sprintf(par.scan_string_format, scan_num),par.MLrecon.roi, method,'Niter',num2str(par.MLrecon.Niter),'.mat');
|
||||
if ~isempty(dir(filename))
|
||||
disp(strcat(sprintf(par.scan_string_format, scan_num),'--',method,'Niter',num2str(par.MLrecon.Niter),'.mat'))
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
%}
|
||||
%{
|
||||
while contains(path, '**')
|
||||
path = replace(path, '**', '*'); % prevent failure when path string contains multiple asterix
|
||||
end
|
||||
path = utils.abspath(path);
|
||||
path = dir(path);
|
||||
if isempty(path)
|
||||
filename = [];
|
||||
return
|
||||
end
|
||||
% take the last file fitting the constraints
|
||||
[~,ind]=sort([path.datenum]);
|
||||
filename = fullfile(path(ind(1)).folder, path(ind(1)).name);
|
||||
%}
|
||||
end
|
||||
@@ -0,0 +1,65 @@
|
||||
%FIND_BASE_PACKAGE
|
||||
% finds the path to the cSAXS base package by looking for a specific file (+math)
|
||||
%
|
||||
% returns:
|
||||
% ++ base_package_path path to the cSAXS base package
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 base_package_path = find_base_package()
|
||||
maxdepth = 3;
|
||||
test_path = '+math'; % one file to find them all
|
||||
|
||||
lvl = 1;
|
||||
cpath = '';
|
||||
ret = '';
|
||||
while isempty(ret) && ~contains(strtrim(ret), test_path)
|
||||
[~, ret] = system(sprintf('find -L %s -maxdepth 2 -type d -name "%s"', cpath, test_path));
|
||||
if lvl > maxdepth
|
||||
break
|
||||
end
|
||||
lvl = lvl + 1;
|
||||
cpath = [cpath '../'];
|
||||
end
|
||||
ret = split(ret);
|
||||
base_package_path = strtrim(ret{1});
|
||||
base_package_path = base_package_path(1:end-length(test_path));
|
||||
|
||||
if isempty(base_package_path)
|
||||
error('cSAXS base package was not found')
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,79 @@
|
||||
% FIND_PROJECTION_FILES_NAMES find names of ptychography projections given
|
||||
% the tomo param structure, if more files are found, return path to the
|
||||
% newest one
|
||||
%
|
||||
% filename = find_projection_files_names(par, scan_num)
|
||||
%
|
||||
% Inputs
|
||||
% **par tomo par structure
|
||||
% **scan_num scan number
|
||||
% *returns*
|
||||
% ++filename filename of the found scan
|
||||
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 filename = find_projection_files_names(par, scan_num)
|
||||
%bug?
|
||||
data_in_subfolders = exist(fullfile(par.analysis_path, 'S00000-00999'), 'dir');
|
||||
%data_in_subfolders = exist(fullfile(par.analysis_path, 'S02000-02999'), 'dir');
|
||||
%disp(data_in_subfolders)
|
||||
if data_in_subfolders
|
||||
% new x12sa path format
|
||||
% bug?
|
||||
path = fullfile(par.analysis_path, utils.compile_x12sa_dirname(scan_num) , [par.fileprefix '*' par.filesuffix '*.' par.file_extension]);
|
||||
|
||||
%modified by YJ
|
||||
%path = fullfile(par.analysis_path, utils.compile_x12sa_dirname(scan_num) , [sprintf('S%05i',scan_num), par.fileprefix '*' par.filesuffix '*.' par.file_extension]);
|
||||
else
|
||||
% compatibility option for original analysis paths
|
||||
path = fullfile(par.analysis_path,sprintf('S%05i',scan_num),[par.fileprefix '*' par.filesuffix '*.' par.file_extension]);
|
||||
end
|
||||
%disp(path)
|
||||
|
||||
while contains(path, '**')
|
||||
path = replace(path, '**', '*'); % prevent failure when path string contains multiple asterix
|
||||
end
|
||||
path = utils.abspath(path);
|
||||
path = dir(path);
|
||||
if isempty(path)
|
||||
filename = [];
|
||||
return
|
||||
end
|
||||
% take the last file fitting the constraints
|
||||
[~,ind]=sort([path.datenum]);
|
||||
filename = fullfile(path(ind(1)).folder, path(ind(1)).name);
|
||||
end
|
||||
@@ -0,0 +1,46 @@
|
||||
% FIND_PROJECTION_FILES_NAMES_APS find names of ptychography projections given
|
||||
% the tomo param structure, if more files are found, return path to the
|
||||
% newest one. Written by YJ for ML reconstructions
|
||||
%
|
||||
% filename = find_projection_files_names(par, scan_num)
|
||||
%
|
||||
% Inputs
|
||||
% **par tomo par structure
|
||||
% **scan_num scan number
|
||||
% *returns*
|
||||
% ++filename filename of the found scan
|
||||
|
||||
function filename = find_projection_files_names_aps(par, scan_num)
|
||||
%bug?
|
||||
%%%data_in_subfolders = exist(fullfile(par.analysis_path, 'S00000-00999'), 'dir');
|
||||
data_in_subfolders = exist(fullfile(par.analysis_path, 'S02000-02999'), 'dir');
|
||||
|
||||
if data_in_subfolders
|
||||
% new x12sa path format
|
||||
% bug?
|
||||
%%%path = fullfile(par.analysis_path, utils.compile_x12sa_dirname(scan_num) , [par.fileprefix '*' par.filesuffix '*.' par.file_extension]);
|
||||
%modified by YJ
|
||||
path = fullfile(par.analysis_path, utils.compile_x12sa_dirname(scan_num) , [sprintf('S%05i',scan_num), par.fileprefix '*' par.filesuffix '*.' par.file_extension]);
|
||||
|
||||
else
|
||||
% compatibility option for original analysis paths
|
||||
|
||||
%path = fullfile(par.analysis_path,sprintf(par.scan_string_format,scan_num),[par.fileprefix '*' par.filesuffix '*.' par.file_extension]);
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
while contains(path, '**')
|
||||
path = replace(path, '**', '*'); % prevent failure when path string contains multiple asterix
|
||||
end
|
||||
path = utils.abspath(path);
|
||||
path = dir(path);
|
||||
if isempty(path)
|
||||
filename = [];
|
||||
return
|
||||
end
|
||||
% take the last file fitting the constraints
|
||||
[~,ind]=sort([path.datenum]);
|
||||
filename = fullfile(path(ind(1)).folder, path(ind(1)).name);
|
||||
end
|
||||
Binary file not shown.
@@ -0,0 +1,849 @@
|
||||
% Usage
|
||||
% This function can be used standalone using "Load stack"
|
||||
% Can also be run from a script with optional inputs
|
||||
% [stack_phase_corr mask] = findmask(stack_object)
|
||||
% Inputs
|
||||
% stack_object - Stack of complex valued projections
|
||||
% Outputs
|
||||
% stack_phase_corr - Stack of corrected complex valued projections
|
||||
% mask - Mask used for correction
|
||||
% Manuel Guizar, Cameron Kewish 2012-10-25
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 varargout = findmask(varargin)
|
||||
% FINDMASK MATLAB code for findmask.fig
|
||||
% FINDMASK, by itself, creates a new FINDMASK or raises the existing
|
||||
% singleton*.
|
||||
%
|
||||
% H = FINDMASK returns the handle to a new FINDMASK or the handle to
|
||||
% the existing singleton*.
|
||||
%
|
||||
% FINDMASK('CALLBACK',hObject,eventData,handles,...) calls the local
|
||||
% function named CALLBACK in FINDMASK.M with the given input arguments.
|
||||
%
|
||||
% FINDMASK('Property','Value',...) creates a new FINDMASK or raises the
|
||||
% existing singleton*. Starting from the left, property value pairs are
|
||||
% applied to the GUI before findmask_OpeningFcn gets called. An
|
||||
% unrecognized property name or invalid value makes property application
|
||||
% stop. All inputs are passed to findmask_OpeningFcn via varargin.
|
||||
%
|
||||
% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
|
||||
% instance to run (singleton)".
|
||||
%
|
||||
% See also: GUIDE, GUIDATA, GUIHANDLES
|
||||
|
||||
% Edit the above text to modify the response to help findmask
|
||||
|
||||
% Last Modified by GUIDE v2.5 25-Oct-2012 15:54:12
|
||||
|
||||
% Begin initialization code - DO NOT EDIT
|
||||
|
||||
gui_Singleton = 1;
|
||||
gui_State = struct('gui_Name', mfilename, ...
|
||||
'gui_Singleton', gui_Singleton, ...
|
||||
'gui_OpeningFcn', @findmask_OpeningFcn, ...
|
||||
'gui_OutputFcn', @findmask_OutputFcn, ...
|
||||
'gui_LayoutFcn', [] , ...
|
||||
'gui_Callback', []);
|
||||
if nargin && ischar(varargin{1})
|
||||
gui_State.gui_Callback = str2func(varargin{1});
|
||||
end
|
||||
|
||||
if nargout
|
||||
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
|
||||
else
|
||||
gui_mainfcn(gui_State, varargin{:});
|
||||
end
|
||||
% End initialization code - DO NOT EDIT
|
||||
|
||||
|
||||
% --- Executes just before findmask is made visible.
|
||||
function findmask_OpeningFcn(hObject, eventdata, handles, varargin)
|
||||
% This function has no output args, see OutputFcn.
|
||||
% hObject handle to figure
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
% varargin command line arguments to findmask (see VARARGIN)
|
||||
|
||||
% Choose default command line output for findmask
|
||||
handles.output = hObject;
|
||||
%%%% Initialization with variable %%%
|
||||
if nargin >= 4
|
||||
handles.stack_object = varargin{1};
|
||||
if numel(varargin)>1
|
||||
handles.mask_ramp = varargin{2};
|
||||
end
|
||||
if ~isfield(handles,'mask_ramp')
|
||||
handles.mask_ramp = logical(handles.stack_object*0);
|
||||
else
|
||||
if ~all(size(handles.stack_object) == size(handles.mask_ramp))
|
||||
msgbox('Size of mask and projections does not match','Wrong mask','error')
|
||||
end
|
||||
end
|
||||
handles.corrected = ones(size(handles.stack_object,3),1);
|
||||
handles.see_mask_only = get(handles.checkbox_see_mask_only,'Value');
|
||||
handles.projnum = 1;
|
||||
handles.linecut = round(size(handles.stack_object,1)/2);
|
||||
clear stack_object
|
||||
set(handles.edit_line,'String',num2str(handles.linecut))
|
||||
handles.region_select = handles.stack_object(:,:,handles.projnum)*0;
|
||||
show_image(handles)
|
||||
%%% Make shape %%%
|
||||
set(handles.make_square,'Enable','on')
|
||||
set(handles.make_poly,'Enable','on')
|
||||
%%% Save %%%
|
||||
set(handles.save_stack,'Enable','on')
|
||||
set(handles.save_mask,'Enable','on')
|
||||
set(handles.return_to_script,'Enable','on')
|
||||
%%% Display %%%
|
||||
set(handles.edit1,'Enable','on')
|
||||
set(handles.prev_proj,'Enable','on')
|
||||
set(handles.stop_button,'Enable','on')
|
||||
set(handles.play,'Enable','on')
|
||||
set(handles.next_proj,'Enable','on')
|
||||
set(handles.edit_line,'Enable','on')
|
||||
set(handles.checkbox_see_mask_only,'Enable','on')
|
||||
end
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Update handles structure
|
||||
guidata(hObject, handles);
|
||||
|
||||
% UIWAIT makes findmask wait for user response (see UIRESUME)
|
||||
% uiwait(handles.figure1);
|
||||
|
||||
|
||||
% --- Outputs from this function are returned to the command line.
|
||||
function varargout = findmask_OutputFcn(hObject, eventdata, handles)
|
||||
% varargout cell array for returning output args (see VARARGOUT);
|
||||
% hObject handle to figure
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
|
||||
% Get default command line output from handles structure
|
||||
varargout{1} = handles.output;
|
||||
|
||||
|
||||
|
||||
% --- Executes on button press in load_stack.
|
||||
function load_stack_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to load_stack (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
[handles.stack_filename handles.stack_path Filterindex] = uigetfile('*.mat');
|
||||
load([handles.stack_path handles.stack_filename]);
|
||||
handles.stack_object = stack_object;
|
||||
if ~exist('stack_object')
|
||||
msgbox('Variable stack_object does not exist in the file','Variable not found','error')
|
||||
end
|
||||
if ~isfield(handles,'mask_ramp')
|
||||
handles.mask_ramp = logical(stack_object*0);
|
||||
else
|
||||
if ~all(size(handles.stack_object) == size(handles.mask_ramp))
|
||||
msgbox('Size of mask and projections does not match','Wrong mask','error')
|
||||
end
|
||||
end
|
||||
handles.corrected = ones(size(stack_object,3),1);
|
||||
handles.see_mask_only = get(handles.checkbox_see_mask_only,'Value');
|
||||
handles.projnum = 1;
|
||||
handles.linecut = round(size(stack_object,1)/2);
|
||||
clear stack_object
|
||||
set(handles.edit_line,'String',num2str(handles.linecut))
|
||||
handles.region_select = handles.stack_object(:,:,handles.projnum)*0;
|
||||
show_image(handles)
|
||||
%%% Make shape %%%
|
||||
set(handles.make_square,'Enable','on')
|
||||
set(handles.make_poly,'Enable','on')
|
||||
%%% Save %%%
|
||||
set(handles.save_stack,'Enable','on')
|
||||
set(handles.save_mask,'Enable','on')
|
||||
%%% Display %%%
|
||||
set(handles.edit1,'Enable','on')
|
||||
set(handles.prev_proj,'Enable','on')
|
||||
set(handles.stop_button,'Enable','on')
|
||||
set(handles.play,'Enable','on')
|
||||
set(handles.next_proj,'Enable','on')
|
||||
set(handles.edit_line,'Enable','on')
|
||||
set(handles.checkbox_see_mask_only,'Enable','on')
|
||||
%%%%%%%%%%%%%%%
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
% --- Executes on button press in load_mask.
|
||||
function load_mask_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to load_mask (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
[handles.mask_filename handles.mask_path Filterindex] = uigetfile('*.mat');
|
||||
load([handles.mask_path handles.mask_filename]);
|
||||
if ~exist('mask')
|
||||
msgbox('Variable mask does not exist in the file','Variable not found','error')
|
||||
end
|
||||
handles.mask_ramp = mask;
|
||||
if isfield(handles,'stack_object')
|
||||
if ~all(size(handles.stack_object) == size(handles.mask_ramp))
|
||||
msgbox('Size of mask and projections do not match','Wrong mask','error')
|
||||
end
|
||||
end
|
||||
handles.corrected = zeros(size(handles.mask_ramp,3),1);
|
||||
handles.projnum = 1;
|
||||
clear mask_ramp
|
||||
handles.region_select = handles.mask_ramp(:,:,handles.projnum)*0;
|
||||
if isfield(handles,'stack_object')
|
||||
show_image(handles)
|
||||
end
|
||||
enable_mask_panel(hObject, handles)
|
||||
enable_ramp_panel(hObject, handles)
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles)
|
||||
|
||||
|
||||
|
||||
% --- Executes on button press in save_stack.
|
||||
function save_stack_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to save_stack (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
if any(handles.corrected == 0)
|
||||
msgbox('Mask has not been applied to all projections. Not saving.','Current mask not applied yet','warn')
|
||||
else
|
||||
stack_object = handles.stack_object;
|
||||
if isfield(handles,'stack_path')
|
||||
uisave('stack_object',[handles.stack_path 'phase_corr_' handles.stack_filename]);
|
||||
else
|
||||
uisave('stack_object',['phase_corr_.mat']);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
% --- Executes on button press in save_mask.
|
||||
function save_mask_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to save_mask (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
mask = handles.mask_ramp;
|
||||
if isfield(handles,'stack_path')
|
||||
uisave('mask',[handles.stack_path 'mask_' handles.stack_filename]);
|
||||
else
|
||||
uisave('mask',['mask_.mat']);
|
||||
end
|
||||
|
||||
|
||||
|
||||
% --- Executes on button press in return_to_script.
|
||||
function varargout = return_to_script_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to return_to_script (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
|
||||
if any(handles.corrected == 0)
|
||||
msgbox('Mask has not been applied to all projections. Not ready to return to script.','Current mask not applied yet','warn')
|
||||
else
|
||||
msgbox('Load variable from script and close figure.','Exit to script','help')
|
||||
end
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%
|
||||
%%% Make mask %%%
|
||||
%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% --- Executes on button press in make_square.
|
||||
function make_square_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to make_square (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
set(handles.figure_text,'string','Click on two corners of the desired rectangle',...
|
||||
'foregroundcolor',[0 0 1])
|
||||
set(gcf,'CurrentAxes',handles.axes_phase)
|
||||
[x y] = ginput(2);
|
||||
hold on,
|
||||
plot([x(1) x(1)],[y(1) y(2)])
|
||||
plot([x(2) x(2)],[y(1) y(2)])
|
||||
plot([x(1) x(2)],[y(1) y(1)])
|
||||
plot([x(1) x(2)],[y(2) y(2)])
|
||||
hold off,
|
||||
x = round(x);
|
||||
y = round(y);
|
||||
handles.region_select = handles.region_select*0;
|
||||
handles.region_select(min(y):max(y),min(x):max(x)) = 1;
|
||||
set(handles.figure_text,'string','Choose to add or remove from mask',...
|
||||
'foregroundcolor',[0 0 1])
|
||||
enable_mask_panel(hObject, handles)
|
||||
enable_ramp_panel(hObject, handles)
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles)
|
||||
|
||||
|
||||
% --- Executes on button press in make_poly.
|
||||
function make_poly_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to make_poly (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
% h = msgbox(['Please click on the image to choose the corners ' ...
|
||||
% 'of the polygon ROI. When finished, double-click the last vertex to ' ...
|
||||
% 'close the polygon.'], 'Make Poly', 'help');
|
||||
set(handles.figure_text,'string','Click closed polygon corners. Double-click when done',...
|
||||
'foregroundcolor',[0 0 1])
|
||||
set(gcf,'CurrentAxes',handles.axes_phase)
|
||||
[handles.region_select x y] = roipoly;
|
||||
% do we want to plot the roi border?
|
||||
hold on,
|
||||
plot(x,y)
|
||||
hold off,
|
||||
set(handles.figure_text,'string','Choose to add or remove from mask',...
|
||||
'foregroundcolor',[0 0 1])
|
||||
enable_mask_panel(hObject, handles)
|
||||
enable_ramp_panel(hObject, handles)
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles)
|
||||
|
||||
|
||||
|
||||
% --- Executes on button press in next_proj.
|
||||
function next_proj_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to next_proj (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
handles.projnum = min(handles.projnum + 1,size(handles.stack_object,3));
|
||||
show_image(handles);
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles);
|
||||
|
||||
|
||||
|
||||
% --- Executes on button press in prev_proj.
|
||||
function prev_proj_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to prev_proj (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
handles.projnum = max(handles.projnum - 1,1);
|
||||
show_image(handles);
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles);
|
||||
|
||||
|
||||
function edit1_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to edit1 (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
|
||||
% Hints: get(hObject,'String') returns contents of edit1 as text
|
||||
% str2double(get(hObject,'String')) returns contents of edit1 as a double
|
||||
handles.projnum = str2double(get(hObject,'String'));
|
||||
show_image(handles)
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles)
|
||||
|
||||
|
||||
% --- Executes during object creation, after setting all properties.
|
||||
function edit1_CreateFcn(hObject, eventdata, handles)
|
||||
% hObject handle to edit1 (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles empty - handles not created until after all CreateFcns called
|
||||
|
||||
% Hint: edit controls usually have a white background on Windows.
|
||||
% See ISPC and COMPUTER.
|
||||
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
|
||||
set(hObject,'BackgroundColor','white');
|
||||
end
|
||||
|
||||
|
||||
% --- Executes on button press in play.
|
||||
function play_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to play (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
% persistent playmovie
|
||||
% playmovie = true;
|
||||
ii = handles.projnum;
|
||||
handles.playmovie = true;
|
||||
guidata(hObject,handles);
|
||||
% % while playmovie
|
||||
while handles.playmovie
|
||||
handles = guidata(hObject);
|
||||
% display(handles.playmovie)
|
||||
handles.projnum = ii;
|
||||
if ii == size(handles.stack_object,3)
|
||||
ii = 1;
|
||||
else
|
||||
ii = ii + 1;
|
||||
end
|
||||
show_image(handles);
|
||||
pause(0.2)
|
||||
end
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles);
|
||||
|
||||
|
||||
% --- Executes on button press in stop_button.
|
||||
function stop_button_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to stop_button (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
% persistent playmovie
|
||||
% playmovie = false;
|
||||
handles.playmovie = false;
|
||||
% display('Trying to stop movie')
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles)
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%% Mask Operations %%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% --- Executes on button press in add_to_mask.
|
||||
function add_to_mask_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to add_to_mask (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
handles.mask_ramp(:,:,handles.projnum) = handles.mask_ramp(:,:,handles.projnum)|handles.region_select;
|
||||
handles.corrected(handles.projnum) = 0;
|
||||
show_image(handles)
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles)
|
||||
|
||||
|
||||
|
||||
% --- Executes on button press in remove_from_mask.
|
||||
function remove_from_mask_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to remove_from_mask (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
handles.mask_ramp(:,:,handles.projnum) = handles.mask_ramp(:,:,handles.projnum)&(1-handles.region_select);
|
||||
handles.corrected(handles.projnum) = 0;
|
||||
show_image(handles)
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles)
|
||||
|
||||
|
||||
|
||||
% --- Executes on button press in add_toall_masks.
|
||||
function add_toall_masks_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to add_toall_masks (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
for ii = 1:size(handles.stack_object,3)
|
||||
handles.mask_ramp(:,:,ii) = handles.mask_ramp(:,:,ii)|handles.region_select;
|
||||
end
|
||||
handles.corrected = zeros(size(handles.stack_object,3),1);
|
||||
|
||||
show_image(handles)
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles)
|
||||
|
||||
|
||||
|
||||
% --- Executes on button press in remove_fromall_masks.
|
||||
function remove_fromall_masks_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to remove_fromall_masks (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
for ii = 1:size(handles.stack_object,3)
|
||||
handles.mask_ramp(:,:,ii) = handles.mask_ramp(:,:,ii)&(1-handles.region_select);
|
||||
end
|
||||
handles.corrected = zeros(size(handles.stack_object,3),1);
|
||||
show_image(handles)
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles)
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%% Ramp removal %%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% --- Executes on button press in apply_removal_current.
|
||||
function apply_removal_current_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to apply_removal_current (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
set(handles.figure_text,'String',['Removing offset on projection ' ...
|
||||
num2str(handles.projnum) ' ...'],...
|
||||
'foregroundcolor',[0 0 1])
|
||||
upsamp = 100;
|
||||
% [handles.stack_object(:,:,handles.projnum) errorm] = utils.remove_linearphase(handles.stack_object(:,:,handles.projnum),handles.mask_ramp(:,:,handles.projnum),upsamp);
|
||||
[handles.stack_object(:,:,handles.projnum) errorm] = utils.remove_linearphase(exp(1i*angle(handles.stack_object(:,:,handles.projnum))),handles.mask_ramp(:,:,handles.projnum),upsamp);
|
||||
handles.corrected(handles.projnum) = 1;
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles)
|
||||
show_image(handles)
|
||||
|
||||
% --- Executes on button press in apply_removal_all.
|
||||
function apply_removal_all_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to apply_removal_all (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
upsamp = 100;
|
||||
hwait = waitbar(0,'Patience is a virtue');
|
||||
|
||||
tmp = handles.stack_object;
|
||||
tmpmask = handles.mask_ramp;
|
||||
|
||||
% CMK: Added a parfor loop to save time here, but it broke the "Patience" waitbar...
|
||||
% if isempty(gcp('nocreate')) == 0
|
||||
% parpool
|
||||
% end
|
||||
|
||||
parfor ii = 1:size(tmp,3)
|
||||
[tmp(:,:,ii) errorm] = utils.remove_linearphase(tmp(:,:,ii),tmpmask(:,:,ii), upsamp);
|
||||
display(ii)
|
||||
end
|
||||
handles.stack_object = tmp;
|
||||
|
||||
% for ii = 1:size(handles.stack_object,3)
|
||||
% set(handles.figure_text,'String',['Removing offset on projection ' ...
|
||||
% num2str(ii) ' ...'],...
|
||||
% 'foregroundcolor',[0 0 1])
|
||||
% guidata(hObject,handles)
|
||||
% if ~handles.corrected(ii)
|
||||
% [handles.stack_object(:,:,ii) errorm] = utils.remove_linearphase(handles.stack_object(:,:,ii),handles.mask_ramp(:,:,ii),upsamp);
|
||||
% handles.corrected(ii) == 1;
|
||||
% end
|
||||
% waitbar(ii/size(handles.stack_object,3),hwait);
|
||||
% end
|
||||
|
||||
close(hwait)
|
||||
handles.corrected = ones(size(handles.stack_object,3),1);
|
||||
show_image(handles)
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles)
|
||||
|
||||
|
||||
|
||||
function edit_line_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to edit_line (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
|
||||
% Hints: get(hObject,'String') returns contents of edit_line as text
|
||||
% str2double(get(hObject,'String')) returns contents of edit_line as a double
|
||||
handles.linecut = str2double(get(hObject,'String'));
|
||||
show_image(handles)
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles)
|
||||
|
||||
% --- Executes during object creation, after setting all properties.
|
||||
function edit_line_CreateFcn(hObject, eventdata, handles)
|
||||
% hObject handle to edit_line (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles empty - handles not created until after all CreateFcns called
|
||||
|
||||
% Hint: edit controls usually have a white background on Windows.
|
||||
% See ISPC and COMPUTER.
|
||||
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
|
||||
set(hObject,'BackgroundColor','white');
|
||||
end
|
||||
|
||||
|
||||
% --- Executes on button press in checkbox_see_mask_only.
|
||||
function checkbox_see_mask_only_Callback(hObject, eventdata, handles)
|
||||
% hObject handle to checkbox_see_mask_only (see GCBO)
|
||||
% eventdata reserved - to be defined in a future version of MATLAB
|
||||
% handles structure with handles and user data (see GUIDATA)
|
||||
handles.see_mask_only = get(handles.checkbox_see_mask_only,'Value');
|
||||
show_image(handles);
|
||||
% Hint: get(hObject,'Value') returns toggle state of checkbox_see_mask_only
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles)
|
||||
|
||||
function enable_mask_panel(hObject, handles)
|
||||
set(handles.add_to_mask, 'Enable','on')
|
||||
set(handles.add_toall_masks, 'Enable','on')
|
||||
set(handles.remove_from_mask, 'Enable','on')
|
||||
set(handles.remove_fromall_masks,'Enable','on')
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles)
|
||||
|
||||
function enable_ramp_panel(hObject, handles)
|
||||
set(handles.apply_removal_current,'Enable','on')
|
||||
set(handles.apply_removal_all, 'Enable','on')
|
||||
|
||||
% save the changes to the structure
|
||||
guidata(hObject,handles)
|
||||
|
||||
function show_image(handles)
|
||||
phase_plot = angle(handles.stack_object(:,:,handles.projnum));
|
||||
min_phaseplot = min(phase_plot(:));
|
||||
max_phaseplot = max(phase_plot(:));
|
||||
phase_plot = phase_plot - min_phaseplot;
|
||||
phase_plot = phase_plot.*(handles.mask_ramp(:,:,handles.projnum) + ...
|
||||
0.5*(~handles.mask_ramp(:,:,handles.projnum)))+min_phaseplot;
|
||||
% handles.axes_phase = imagesc(phase_plot);
|
||||
%%%
|
||||
set(gcf,'CurrentAxes',handles.axes_phase);
|
||||
if ~handles.see_mask_only
|
||||
imagesc(phase_plot);
|
||||
caxis([min_phaseplot max_phaseplot]);
|
||||
else
|
||||
imagesc(phase_plot.*handles.mask_ramp(:,:,handles.projnum));
|
||||
end
|
||||
axis xy equal tight
|
||||
colormap bone
|
||||
%%%
|
||||
set(gcf,'CurrentAxes',handles.axes_linecut);
|
||||
plot(angle(handles.stack_object(handles.linecut,:,handles.projnum)));
|
||||
xlim([1 size(handles.stack_object,2)]);
|
||||
grid on
|
||||
%%%
|
||||
set(handles.figure_text,'String', ...
|
||||
['Projection ' num2str(handles.projnum)],'foregroundcolor',[0 0 0])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%% Auxiliary functions %%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
function [output Greg] = dftregistration(buf1ft,buf2ft,usfac)
|
||||
% function [output Greg] = dftregistration(buf1ft,buf2ft,usfac);
|
||||
% Efficient subpixel image registration by crosscorrelation. This code
|
||||
% gives the same precision as the FFT upsampled cross correlation in a
|
||||
% small fraction of the computation time and with reduced memory
|
||||
% requirements. It obtains an initial estimate of the crosscorrelation peak
|
||||
% by an FFT and then refines the shift estimation by upsampling the DFT
|
||||
% only in a small neighborhood of that estimate by means of a
|
||||
% matrix-multiply DFT. With this procedure all the image points are used to
|
||||
% compute the upsampled crosscorrelation.
|
||||
% Manuel Guizar - Dec 13, 2007
|
||||
|
||||
% Portions of this code were taken from code written by Ann M. Kowalczyk
|
||||
% and James R. Fienup.
|
||||
% J.R. Fienup and A.M. Kowalczyk, "Phase retrieval for a complex-valued
|
||||
% object by using a low-resolution image," J. Opt. Soc. Am. A 7, 450-458
|
||||
% (1990).
|
||||
|
||||
% Citation for this algorithm:
|
||||
% Manuel Guizar-Sicairos, Samuel T. Thurman, and James R. Fienup,
|
||||
% "Efficient subpixel image registration algorithms," Opt. Lett. 33,
|
||||
% 156-158 (2008).
|
||||
|
||||
% Inputs
|
||||
% buf1ft Fourier transform of reference image,
|
||||
% DC in (1,1) [DO NOT FFTSHIFT]
|
||||
% buf2ft Fourier transform of image to register,
|
||||
% DC in (1,1) [DO NOT FFTSHIFT]
|
||||
% usfac Upsampling factor (integer). Images will be registered to
|
||||
% within 1/usfac of a pixel. For example usfac = 20 means the
|
||||
% images will be registered within 1/20 of a pixel. (default = 1)
|
||||
|
||||
% Outputs
|
||||
% output = [error,diffphase,net_row_shift,net_col_shift]
|
||||
% error Translation invariant normalized RMS error between f and g
|
||||
% diffphase Global phase difference between the two images (should be
|
||||
% zero if images are non-negative).
|
||||
% net_row_shift net_col_shift Pixel shifts between images
|
||||
% Greg (Optional) Fourier transform of registered version of buf2ft,
|
||||
% the global phase difference is compensated for.
|
||||
|
||||
% Default usfac to 1
|
||||
if exist('usfac')~=1, usfac=1; end
|
||||
|
||||
% Compute error for no pixel shift
|
||||
if usfac == 0,
|
||||
CCmax = sum(sum(buf1ft.*conj(buf2ft)));
|
||||
rfzero = sum(abs(buf1ft(:)).^2);
|
||||
rgzero = sum(abs(buf2ft(:)).^2);
|
||||
error = 1.0 - CCmax.*conj(CCmax)/(rgzero*rfzero);
|
||||
error = sqrt(abs(error));
|
||||
diffphase=atan2(imag(CCmax),real(CCmax));
|
||||
output=[error,diffphase];
|
||||
|
||||
% Whole-pixel shift - Compute crosscorrelation by an IFFT and locate the
|
||||
% peak
|
||||
elseif usfac == 1,
|
||||
[m,n]=size(buf1ft);
|
||||
CC = ifft2(buf1ft.*conj(buf2ft));
|
||||
[max1,loc1] = max(CC);
|
||||
[max2,loc2] = max(max1);
|
||||
rloc=loc1(loc2);
|
||||
cloc=loc2;
|
||||
CCmax=CC(rloc,cloc);
|
||||
rfzero = sum(abs(buf1ft(:)).^2)/(m*n);
|
||||
rgzero = sum(abs(buf2ft(:)).^2)/(m*n);
|
||||
error = 1.0 - CCmax.*conj(CCmax)/(rgzero(1,1)*rfzero(1,1));
|
||||
error = sqrt(abs(error));
|
||||
diffphase=atan2(imag(CCmax),real(CCmax));
|
||||
md2 = fix(m/2);
|
||||
nd2 = fix(n/2);
|
||||
if rloc > md2
|
||||
row_shift = rloc - m - 1;
|
||||
else
|
||||
row_shift = rloc - 1;
|
||||
end
|
||||
|
||||
if cloc > nd2
|
||||
col_shift = cloc - n - 1;
|
||||
else
|
||||
col_shift = cloc - 1;
|
||||
end
|
||||
output=[error,diffphase,row_shift,col_shift];
|
||||
|
||||
% Partial-pixel shift
|
||||
else
|
||||
|
||||
% First upsample by a factor of 2 to obtain initial estimate
|
||||
% Embed Fourier data in a 2x larger array
|
||||
[m,n]=size(buf1ft);
|
||||
mlarge=m*2;
|
||||
nlarge=n*2;
|
||||
CC=zeros(mlarge,nlarge);
|
||||
CC(m+1-fix(m/2):m+1+fix((m-1)/2),n+1-fix(n/2):n+1+fix((n-1)/2)) = ...
|
||||
fftshift(buf1ft).*conj(fftshift(buf2ft));
|
||||
|
||||
% Compute crosscorrelation and locate the peak
|
||||
CC = ifft2(ifftshift(CC)); % Calculate cross-correlation
|
||||
[max1,loc1] = max(CC);
|
||||
[max2,loc2] = max(max1);
|
||||
rloc=loc1(loc2);cloc=loc2;
|
||||
CCmax=CC(rloc,cloc);
|
||||
|
||||
% Obtain shift in original pixel grid from the position of the
|
||||
% crosscorrelation peak
|
||||
[m,n] = size(CC); md2 = fix(m/2); nd2 = fix(n/2);
|
||||
if rloc > md2
|
||||
row_shift = rloc - m - 1;
|
||||
else
|
||||
row_shift = rloc - 1;
|
||||
end
|
||||
if cloc > nd2
|
||||
col_shift = cloc - n - 1;
|
||||
else
|
||||
col_shift = cloc - 1;
|
||||
end
|
||||
row_shift=row_shift/2;
|
||||
col_shift=col_shift/2;
|
||||
|
||||
% If upsampling > 2, then refine estimate with matrix multiply DFT
|
||||
if usfac > 2,
|
||||
%%% DFT computation %%%
|
||||
% Initial shift estimate in upsampled grid
|
||||
row_shift = round(row_shift*usfac)/usfac;
|
||||
col_shift = round(col_shift*usfac)/usfac;
|
||||
dftshift = fix(ceil(usfac*1.5)/2); %% Center of output array at dftshift+1
|
||||
% Matrix multiply DFT around the current shift estimate
|
||||
CC = conj(dftups(buf2ft.*conj(buf1ft),ceil(usfac*1.5),ceil(usfac*1.5),usfac,...
|
||||
dftshift-row_shift*usfac,dftshift-col_shift*usfac))/(md2*nd2*usfac^2);
|
||||
% Locate maximum and map back to original pixel grid
|
||||
[max1,loc1] = max(CC);
|
||||
[max2,loc2] = max(max1);
|
||||
rloc = loc1(loc2); cloc = loc2;
|
||||
CCmax = CC(rloc,cloc);
|
||||
rg00 = dftups(buf1ft.*conj(buf1ft),1,1,usfac)/(md2*nd2*usfac^2);
|
||||
rf00 = dftups(buf2ft.*conj(buf2ft),1,1,usfac)/(md2*nd2*usfac^2);
|
||||
rloc = rloc - dftshift - 1;
|
||||
cloc = cloc - dftshift - 1;
|
||||
row_shift = row_shift + rloc/usfac;
|
||||
col_shift = col_shift + cloc/usfac;
|
||||
|
||||
% If upsampling = 2, no additional pixel shift refinement
|
||||
else
|
||||
rg00 = sum(sum( buf1ft.*conj(buf1ft) ))/m/n;
|
||||
rf00 = sum(sum( buf2ft.*conj(buf2ft) ))/m/n;
|
||||
end
|
||||
error = 1.0 - CCmax.*conj(CCmax)/(rg00*rf00);
|
||||
error = sqrt(abs(error));
|
||||
diffphase=atan2(imag(CCmax),real(CCmax));
|
||||
% If its only one row or column the shift along that dimension has no
|
||||
% effect. We set to zero.
|
||||
if md2 == 1,
|
||||
row_shift = 0;
|
||||
end
|
||||
if nd2 == 1,
|
||||
col_shift = 0;
|
||||
end
|
||||
output=[error,diffphase,row_shift,col_shift];
|
||||
end
|
||||
|
||||
% Compute registered version of buf2ft
|
||||
if (nargout > 1)&&(usfac > 0),
|
||||
[nr,nc]=size(buf2ft);
|
||||
Nr = ifftshift([-fix(nr/2):ceil(nr/2)-1]);
|
||||
Nc = ifftshift([-fix(nc/2):ceil(nc/2)-1]);
|
||||
[Nc,Nr] = meshgrid(Nc,Nr);
|
||||
Greg = buf2ft.*exp(i*2*pi*(-row_shift*Nr/nr-col_shift*Nc/nc));
|
||||
Greg = Greg*exp(i*diffphase);
|
||||
elseif (nargout > 1)&&(usfac == 0)
|
||||
Greg = buf2ft*exp(i*diffphase);
|
||||
end
|
||||
return
|
||||
|
||||
function out=dftups(in,nor,noc,usfac,roff,coff)
|
||||
% function out=dftups(in,nor,noc,usfac,roff,coff);
|
||||
% Upsampled DFT by matrix multiplies, can compute an upsampled DFT in just
|
||||
% a small region.
|
||||
% usfac Upsampling factor (default usfac = 1)
|
||||
% [nor,noc] Number of pixels in the output upsampled DFT, in
|
||||
% units of upsampled pixels (default = size(in))
|
||||
% roff, coff Row and column offsets, allow to shift the output array to
|
||||
% a region of interest on the DFT (default = 0)
|
||||
% Recieves DC in upper left corner, image center must be in (1,1)
|
||||
% Manuel Guizar - Dec 13, 2007
|
||||
% Modified from dftus, by J.R. Fienup 7/31/06
|
||||
|
||||
% This code is intended to provide the same result as if the following
|
||||
% operations were performed
|
||||
% - Embed the array "in" in an array that is usfac times larger in each
|
||||
% dimension. ifftshift to bring the center of the image to (1,1).
|
||||
% - Take the FFT of the larger array
|
||||
% - Extract an [nor, noc] region of the result. Starting with the
|
||||
% [roff+1 coff+1] element.
|
||||
|
||||
% It achieves this result by computing the DFT in the output array without
|
||||
% the need to zeropad. Much faster and memory efficient than the
|
||||
% zero-padded FFT approach if [nor noc] are much smaller than [nr*usfac nc*usfac]
|
||||
|
||||
[nr,nc]=size(in);
|
||||
% Set defaults
|
||||
if exist('roff')~=1, roff=0; end
|
||||
if exist('coff')~=1, coff=0; end
|
||||
if exist('usfac')~=1, usfac=1; end
|
||||
if exist('noc')~=1, noc=nc; end
|
||||
if exist('nor')~=1, nor=nr; end
|
||||
% Compute kernels and obtain DFT by matrix products
|
||||
kernc=exp((-i*2*pi/(nc*usfac))*( ifftshift([0:nc-1]).' - floor(nc/2) )*( [0:noc-1] - coff ));
|
||||
kernr=exp((-i*2*pi/(nr*usfac))*( [0:nor-1].' - roff )*( ifftshift([0:nr-1]) - floor(nr/2) ));
|
||||
out=kernr*in*kernc;
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
|
||||
% function fourier_interpolate(val,theta,numord)
|
||||
% This function uses a Fourier transform approximation to obtain the zero
|
||||
% and first coefficient of a periodic function (a sine wave fit) if only data
|
||||
% of half a period is available. Data within 0 and 180 degrees (inclusive)
|
||||
% is given. Completes and takes fft of data, theta is only used for some
|
||||
% checks, should be given in radians.
|
||||
%
|
||||
% a*sin(x*pi/180+b)+c
|
||||
% Output phase is in radians
|
||||
%
|
||||
% It is meant to work with equally spaced angles in the range of 180
|
||||
% degrees, including 180 degrees. It allows not exactly equally spaced but then
|
||||
% accuracy cannot be guaranteed.
|
||||
%
|
||||
% Optional parameter numord can be used in order to retrieve higher orders
|
||||
% of the fit
|
||||
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 fit = fourier_interpolate(val,theta,numord,sym_flip)
|
||||
% sym_flip For a function that is only measured from 0 to 180 then the
|
||||
% data is flipped mirrored in order to complete the period of
|
||||
% the sinewave
|
||||
|
||||
% theta = [0:45:180]*pi/180;
|
||||
% val = 5 + sin(theta+0.5);
|
||||
if nargin<3
|
||||
numord = 1;
|
||||
end
|
||||
|
||||
if ~exist('sym_flip')
|
||||
sym_flip = true;
|
||||
end
|
||||
|
||||
% if any(theta)>1.05*pi;
|
||||
% error('This routine cannot account for angles larger than 180 at the moment')
|
||||
% end
|
||||
|
||||
if ~all(size(theta)==size(val))
|
||||
error(['theta and val dont have the same number of elements'])
|
||||
end
|
||||
val = val(:);
|
||||
theta = theta(:);
|
||||
clear auxval
|
||||
if sym_flip
|
||||
auxval = [val(:);-fliplr(val(2:end-1))+val(1)+val(end)];
|
||||
else
|
||||
auxval = val;
|
||||
end
|
||||
auxfft = fft(auxval)/numel(auxval);
|
||||
fit.a = abs(auxfft(2:1+numord)*2*1i);
|
||||
fit.b = angle(auxfft(2:1+numord)*2*1i);
|
||||
fit.c = auxfft(1);
|
||||
|
||||
|
||||
% thetafine = linspace(0,pi,100);
|
||||
% figure(1);
|
||||
% plot(theta,val,'.-')
|
||||
% hold on
|
||||
% plot(thetafine,fit.a*sin(thetafine+fit.b)+fit.c,'-r')
|
||||
% hold off
|
||||
%
|
||||
% figure(2);
|
||||
% plot(auxval,'.-');
|
||||
@@ -0,0 +1,44 @@
|
||||
%GAUSSWIN Gaussian window.
|
||||
% REPLAENEMENT OF THE MATLAB VERSION THAT OFTEN
|
||||
% FAILS DUE TO SOME DEPENDENCIES
|
||||
% GAUSSWIN(N) returns an N-point Gaussian window.
|
||||
%
|
||||
% GAUSSWIN(N, ALPHA) returns the ALPHA-valued N-point Gaussian
|
||||
% window. ALPHA is defined as the reciprocal of the standard
|
||||
% deviation and is a measure of the width of its Fourier Transform.
|
||||
% As ALPHA increases, the width of the window will decrease. If omitted,
|
||||
% ALPHA is 2.5.
|
||||
%
|
||||
% EXAMPLE:
|
||||
% N = 32;
|
||||
% wvtool(gausswin(N));
|
||||
%
|
||||
%
|
||||
% See also CHEBWIN, KAISER, TUKEYWIN, WINDOW.
|
||||
|
||||
% Reference:
|
||||
% [1] fredric j. harris [sic], On the Use of Windows for Harmonic
|
||||
% Analysis with the Discrete Fourier Transform, Proceedings of
|
||||
% the IEEE, Vol. 66, No. 1, January 1978
|
||||
|
||||
% Copyright 1988-2013 The MathWorks, Inc.
|
||||
|
||||
function w = gausswin(L, a)
|
||||
|
||||
narginchk(1,2);
|
||||
|
||||
% Default value for Alpha
|
||||
if nargin < 2 || isempty(a),
|
||||
a = 2.5;
|
||||
end
|
||||
|
||||
%Cast to enforce Precision Rules
|
||||
L = double(L); % data type of L is checked in check_order
|
||||
|
||||
% Compute window according to [1]
|
||||
N = L-1;
|
||||
n = (0:N)'-N/2;
|
||||
w = exp(-(1/2)*(a*n/(N/2)).^2);
|
||||
|
||||
|
||||
end
|
||||
@@ -0,0 +1,28 @@
|
||||
function [paraName] = generate_para_name(par, extra)
|
||||
%Generate output names based on alignment parameters
|
||||
% Written by YJ.
|
||||
|
||||
paraName = strcat('_hps',num2str(par.high_pass_filter));
|
||||
if isfield(par,'angle_correction') && par.angle_correction~=0
|
||||
paraName = strcat(paraName,'_angle_corr',num2str(par.angle_correction));
|
||||
end
|
||||
if par.binning~=1
|
||||
paraName = strcat(paraName,'_bin',num2str(par.binning));
|
||||
end
|
||||
if par.use_localTV
|
||||
paraName = strcat(paraName,'_TV',num2str(par.localTV_lambda));
|
||||
end
|
||||
if par.apply_positivity
|
||||
paraName = strcat(paraName,'_pos');
|
||||
end
|
||||
if par.position_update_smoothing>0
|
||||
paraName = strcat(paraName,'_smooth',num2str(par.position_update_smoothing));
|
||||
end
|
||||
paraName = strcat(paraName,'_sc',num2str(par.min_step_size));
|
||||
|
||||
if nargin==2
|
||||
paraName = strcat(paraName,extra);
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
% GET_ROI find optimal rectange containing the region given by a binary mask
|
||||
%
|
||||
% [ROI] = get_ROI(mask, extent, multiply_of)
|
||||
%
|
||||
% Inputs:
|
||||
% **mask - binary mask, true for valid region
|
||||
% **extent - extra region around the mask calculated as extent*[W,H], default == 0
|
||||
% **multiply_of - make the selected ROI dividable by this number, default = 1
|
||||
% *returns*:
|
||||
% ++ROI - 2x1 cell containing indices of the selected region
|
||||
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 [ROI] = get_ROI(mask, extent, multiply_of)
|
||||
|
||||
|
||||
if all(mask(:) == 0)
|
||||
error('Empty mask')
|
||||
end
|
||||
|
||||
if nargin < 3
|
||||
multiply_of = 1;
|
||||
end
|
||||
if nargin < 2
|
||||
extent = 0;
|
||||
end
|
||||
|
||||
if ~islogical(mask)
|
||||
error('Not implemented')
|
||||
end
|
||||
|
||||
x = any(mask,2);
|
||||
y = any(mask,1);
|
||||
coord = gather([find(x, 1,'first'), find(x, 1,'last'), find(y, 1,'first'), find(y, 1,'last')]);
|
||||
|
||||
w = (coord(2) - coord(1));
|
||||
h = (coord(4) - coord(3));
|
||||
Cx = (coord(2) +coord(1))/2;
|
||||
Cy = (coord(4) + coord(3))/2;
|
||||
|
||||
%YJ: HAS BUG - WRONG INDEX FOR ENTIRE FOV.
|
||||
%CHEAP FIX: USE A SMALL NEGATIVE EXTENT
|
||||
|
||||
%why only use extent for horitonal direction?
|
||||
coord(1) = floor(Cx - ceil( (0.5 + extent) *w ));
|
||||
coord(2) = ceil(Cx + ceil((0.5 + extent) * w ));
|
||||
%% added by YJ to apply extend to vertical direction
|
||||
coord(3) = floor(Cy - ceil( (0.5 + extent) *h ));
|
||||
coord(4) = ceil(Cy + ceil((0.5 + extent) * h )) ;
|
||||
%%
|
||||
w = floor((coord(2) - coord(1))/multiply_of)*multiply_of;
|
||||
h = floor((coord(4) - coord(3))/multiply_of)*multiply_of;
|
||||
|
||||
coord(2) = coord(1)+w-1;
|
||||
coord(4) = coord(3)+h-1;
|
||||
|
||||
coord([1,3]) = max(1,coord([1,3]));
|
||||
coord([2,4]) = min(size(mask),coord([2,4]));
|
||||
|
||||
ROI = {coord(1):coord(2), coord(3):coord(4)};
|
||||
|
||||
end
|
||||
@@ -0,0 +1,103 @@
|
||||
% IMFILTER_HIGH_PASS_1D applies fft filter along AX dimension that
|
||||
% removes SIGMA ratio of the low frequencies
|
||||
%
|
||||
% img = imfilter_high_pass_1d(img, ax, sigma, padding)
|
||||
%
|
||||
% Inputs:
|
||||
% **img - ndim filtered image
|
||||
% **ax - filtering axis
|
||||
% **sigma - filtering intensity [0-1 range], sigma <= 0 no filtering
|
||||
% **padding - pad the array to avoid edge artefacts (in pixels) [default==0]
|
||||
% **apply_fft - if true assume that img is in real space, [default == true]
|
||||
% *returns*
|
||||
% ++img - highpass filtered image
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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
|
||||
%
|
||||
|
||||
|
||||
function img = imfilter_high_pass_1d(img, ax, sigma, padding, apply_fft)
|
||||
|
||||
if nargin < 4, padding = 0; end
|
||||
if nargin < 5, apply_fft = true; end
|
||||
|
||||
Ndims = ndims(img);
|
||||
|
||||
padding = ceil(padding);
|
||||
|
||||
if padding > 0
|
||||
pad_vec = zeros(Ndims,1);
|
||||
pad_vec(ax) = padding; % padding only along axis "ax"
|
||||
img = padarray(img,pad_vec,'symmetric','both');
|
||||
end
|
||||
|
||||
Npix = size(img);
|
||||
shape = ones(1,Ndims);
|
||||
shape(ax) = Npix(ax);
|
||||
isReal = isreal(img);
|
||||
|
||||
if apply_fft
|
||||
img = fft(img,[],ax);
|
||||
end
|
||||
|
||||
x = reshape((-Npix(ax)/2:Npix(ax)/2-1)/Npix(ax), shape);
|
||||
|
||||
sigma = 256/(Npix(ax)-2*padding)*sigma; % solution to make the filter resolution independend ->
|
||||
% -> for different level of scaling the filtered field will look the same
|
||||
|
||||
if sigma == 0
|
||||
% use derivative filter
|
||||
spectral_filter = 2i*pi*(fftshift((0:Npix(ax)-1)/Npix(ax))-0.5);
|
||||
else
|
||||
spectral_filter = fftshift(exp(1./(-(x.^2)/(sigma)^2)));
|
||||
end
|
||||
|
||||
img = bsxfun(@times, img, spectral_filter);
|
||||
|
||||
if apply_fft
|
||||
img = ifft(img,[],ax);
|
||||
end
|
||||
if isReal
|
||||
img = real(img);
|
||||
end
|
||||
|
||||
if padding > 0
|
||||
crop_vec = repmat({':'},Ndims,1);
|
||||
crop_vec{ax} = 1+padding:(size(img,ax)-padding);
|
||||
img = img(crop_vec{:});
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
@@ -0,0 +1,301 @@
|
||||
%LOAD_PTYCHO_ML_RECONS Load ML reconstructions from h5 or mat file and return it as
|
||||
% structure, single dataset or directly into the workspace.
|
||||
% An additional argument can be passed to select subsections of the data.
|
||||
% Loading single datasets is only supported for at least 2 output
|
||||
% arguments.
|
||||
% Created by YJ based on PSI's function.
|
||||
%
|
||||
|
||||
function [object, probe, dx_spec] = load_aps_ML_recons( filename_with_path)
|
||||
|
||||
if ~ischar(filename_with_path)
|
||||
error('First argument has to be string')
|
||||
end
|
||||
|
||||
filename_with_path = utils.abspath(filename_with_path);
|
||||
%disp(filename_with_path)
|
||||
if ~exist(filename_with_path, 'file')
|
||||
error('Could not find reconstruction file %s', filename_with_path)
|
||||
end
|
||||
|
||||
object = load(filename_with_path,'object');
|
||||
object = object.object;
|
||||
|
||||
probe = load(filename_with_path,'probe');
|
||||
probe = probe.probe;
|
||||
parameter = load(filename_with_path,'p');
|
||||
dx_spec = parameter.p.dx_spec; %pixel size
|
||||
|
||||
%% legacy code: read recon from processed h5 files
|
||||
%{
|
||||
object_r = h5read(filename_with_path,'/object_r');
|
||||
object_i = h5read(filename_with_path,'/object_i');
|
||||
object = object_r + 1i*object_i;
|
||||
|
||||
probe_r = h5read(filename_with_path,'/probe_r');
|
||||
probe_i = h5read(filename_with_path,'/probe_i');
|
||||
probe = probe_r + 1i*probe_i;
|
||||
|
||||
% load pixel size
|
||||
dx_spec = h5read(filename_with_path,'/dx_spec');
|
||||
|
||||
% load projection angle
|
||||
%ang = h5read(filename_with_path,'/angle');
|
||||
%}
|
||||
|
||||
end
|
||||
|
||||
%% old PSI code, too complex for APS data
|
||||
%{
|
||||
function varargout = load_ptycho_ML_recons( filename_with_path, varargin )
|
||||
|
||||
import io.HDF.hdf5_load
|
||||
|
||||
varargout = {};
|
||||
|
||||
if ~ischar(filename_with_path)
|
||||
error('First argument has to be string')
|
||||
end
|
||||
|
||||
filename_with_path = utils.abspath(filename_with_path);
|
||||
|
||||
if ~exist(filename_with_path, 'file')
|
||||
error('Could not find reconstruction file %s', filename_with_path)
|
||||
end
|
||||
|
||||
if nargin > 1
|
||||
switch varargin{1}
|
||||
case {'pr'; 'probe'; 'probes'}
|
||||
section = 'probe';
|
||||
case {'ob'; 'obj'; 'objects'}
|
||||
section = 'object';
|
||||
otherwise
|
||||
section = varargin{1};
|
||||
end
|
||||
else
|
||||
section = 'full';
|
||||
end
|
||||
|
||||
if ~nargout
|
||||
output = 0;
|
||||
elseif nargout >=2
|
||||
output = 2;
|
||||
else
|
||||
output = 1;
|
||||
end
|
||||
|
||||
function assign_struct(val, val_name)
|
||||
switch output
|
||||
case 1
|
||||
varargout{1}.(val_name) = val;
|
||||
case 2
|
||||
varargout{end+1} = val;
|
||||
otherwise
|
||||
assignin('base', val_name, val);
|
||||
end
|
||||
end
|
||||
|
||||
function assign_val(struc)
|
||||
switch output
|
||||
case 1
|
||||
varargout{1} = struc;
|
||||
|
||||
case 2
|
||||
if isfield(struc, 'object')
|
||||
varargout{end+1} = struc.object;
|
||||
end
|
||||
if isfield(struc, 'probe')
|
||||
varargout{end+1} = struc.probe;
|
||||
end
|
||||
if isfield(struc, 'p')
|
||||
varargout{end+1} = struc.p;
|
||||
end
|
||||
|
||||
otherwise
|
||||
fn = fieldnames(struc);
|
||||
for ii=1:length(fn)
|
||||
assignin('base', fn{ii}, struc.(fn{ii}))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
% check if it is a .mat file or a .cxs file
|
||||
[~, ~, ext] = fileparts(filename_with_path);
|
||||
switch ext
|
||||
%{
|
||||
case '.mat'
|
||||
switch section
|
||||
case 'recon'
|
||||
S = load(filename_with_path, 'object', 'probe');
|
||||
assign_val(S);
|
||||
|
||||
case 'full'
|
||||
S = load(filename_with_path);
|
||||
assign_val(S);
|
||||
|
||||
case 'object'
|
||||
S = load(filename_with_path, 'object');
|
||||
assign_val(S);
|
||||
|
||||
case 'probe'
|
||||
S = load(filename_with_path, 'probe');
|
||||
size(S)
|
||||
assign_val(S);
|
||||
|
||||
case 'p'
|
||||
S = load(filename_with_path, 'p');
|
||||
assign_val(S);
|
||||
|
||||
otherwise
|
||||
error('Unknown data section %s', section);
|
||||
end
|
||||
%}
|
||||
case {'.cxs','.h5'}
|
||||
%{
|
||||
if io.HDF.hdf5_dset_exists(filename_with_path, 'object', '/reconstruction', true)
|
||||
h5_path = '/reconstruction';
|
||||
else
|
||||
h5_path = '';
|
||||
end
|
||||
%}
|
||||
% reconstruction
|
||||
switch section
|
||||
%{
|
||||
case 'recon'
|
||||
% load object
|
||||
h = hdf5_load(filename_with_path, [h5_path '/object']);
|
||||
assign_struct(load_data_cell(h), 'object');
|
||||
% load probe
|
||||
h = hdf5_load(filename_with_path, [h5_path '/probes']);
|
||||
assign_struct(load_data_cell(h), 'probe');
|
||||
case 'full'
|
||||
% load object
|
||||
h = hdf5_load(filename_with_path, [h5_path '/object']);
|
||||
assign_struct(load_data_cell(h), 'object');
|
||||
% load probe
|
||||
h = hdf5_load(filename_with_path, [h5_path '/probes']);
|
||||
assign_struct(load_data_cell(h), 'probe');
|
||||
% load p
|
||||
p = convert2p(hdf5_load(filename_with_path, '/reconstruction/p', '-c'));
|
||||
if io.HDF.hdf5_dset_exists(filename_with_path, 'meta_all', '/measurement', true)
|
||||
p.meta = hdf5_load(filename_with_path, '/measurement/meta_all', '-c');
|
||||
elseif io.HDF.hdf5_dset_exists(filename_with_path, 'spec_all', '/measurement', true)
|
||||
p.meta = hdf5_load(filename_with_path, '/measurement/spec_all', '-c');
|
||||
end
|
||||
assign_struct(p, 'p');
|
||||
%}
|
||||
case 'object'
|
||||
% load object
|
||||
%h = hdf5_load(filename_with_path, [h5_path '/object']);
|
||||
%assign_struct(load_data_cell(h), 'object');
|
||||
object_r = h5read(filename_with_path,'/object_r');
|
||||
object_i = h5read(filename_with_path,'/object_i');
|
||||
object = object_r + 1i*object_i;
|
||||
assign_struct(object, 'object');
|
||||
|
||||
case 'probe'
|
||||
% load probe
|
||||
%h = hdf5_load(filename_with_path, [h5_path '/probes']);
|
||||
%assign_struct(load_data_cell(h), 'probe');
|
||||
probe_r = h5read(filename_with_path,'/probe_r');
|
||||
probe_i = h5read(filename_with_path,'/probe_i');
|
||||
probe = probe_r + 1i*probe_i;
|
||||
|
||||
assign_struct(probe, 'probe');
|
||||
|
||||
case 'p'
|
||||
% load p
|
||||
p = convert2p(hdf5_load(filename_with_path, '/reconstruction/p', '-c'));
|
||||
if io.HDF.hdf5_dset_exists(filename_with_path, 'meta_all', '/measurement', true)
|
||||
p.meta = hdf5_load(filename_with_path, '/measurement/meta_all', '-c');
|
||||
elseif io.HDF.hdf5_dset_exists(filename_with_path, 'spec_all', '/measurement', true)
|
||||
p.meta = hdf5_load(filename_with_path, '/measurement/spec_all', '-c');
|
||||
end
|
||||
assign_struct(p, 'p');
|
||||
otherwise
|
||||
error('Unknown data section %s', section);
|
||||
end
|
||||
|
||||
|
||||
|
||||
otherwise
|
||||
error('Unknown ptycho datatype %s.', ext)
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
function tmp = load_data_cell(h)
|
||||
|
||||
fn = fieldnames(h);
|
||||
num_end = str2double(subsref(strsplit(fn{1}, '_'), struct('type', '{}', 'subs',{{length(strsplit(fn{1},'_'))}})));
|
||||
if length(fn)==2 && (strcmpi(fn{1}, 'i') || strcmpi(fn{1}, 'r'))
|
||||
tmp = permute(h.r + 1i*h.i, [2,1,3,4]);
|
||||
elseif isnumeric(num_end) && ~isnan(num_end)
|
||||
for ii=1:length(fn)
|
||||
if isstruct(h.(fn{ii}))
|
||||
tmp{ii} = load_data_cell(h.(fn{ii}));
|
||||
else
|
||||
if isnumeric(h.(fn{ii}))
|
||||
tmp{ii} = double(h.(fn{ii}));
|
||||
else
|
||||
tmp{ii} = h.(fn{ii});
|
||||
end
|
||||
end
|
||||
end
|
||||
% tmp = h;
|
||||
else
|
||||
for ii=1:length(fn)
|
||||
if isstruct(h.(fn{ii}))
|
||||
tmp.(fn{ii}) = load_data_cell(h.(fn{ii}));
|
||||
else
|
||||
if isnumeric(h.(fn{ii}))
|
||||
tmp.(fn{ii}) = double(h.(fn{ii}));
|
||||
else
|
||||
tmp.(fn{ii}) = h.(fn{ii});
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function tmp = convert2p(h)
|
||||
|
||||
fn = fieldnames(h);
|
||||
for ii=1:length(fn)
|
||||
if isstruct(h.(fn{ii}))
|
||||
h.(fn{ii}) = load_data_cell(h.(fn{ii}));
|
||||
elseif isnumeric(h.(fn{ii}))
|
||||
h.(fn{ii}) = double(h.(fn{ii}));
|
||||
else
|
||||
continue;
|
||||
end
|
||||
end
|
||||
tmp = h;
|
||||
|
||||
% object
|
||||
for ii=1:length(h.objects)
|
||||
tmp.object{ii} = permute(h.objects{ii}, [2 1 3 4]);
|
||||
end
|
||||
tmp = rmfield(tmp, 'objects');
|
||||
|
||||
% probes
|
||||
pr = tmp.probes;
|
||||
tmp.probes = [];
|
||||
for ii=1:length(pr)
|
||||
tmp.probes(:,:,ii,:) = permute(pr{ii}, [2 1 3 4]);
|
||||
end
|
||||
|
||||
% positions
|
||||
tmp.positions = transpose(tmp.positions);
|
||||
tmp.positions_real = transpose(tmp.positions_real);
|
||||
tmp.positions_orig = transpose(tmp.positions_orig);
|
||||
|
||||
% ctr
|
||||
tmp.ctr = transpose(tmp.ctr);
|
||||
|
||||
end
|
||||
%}
|
||||
@@ -0,0 +1,67 @@
|
||||
%LOAD_ASTRA_RECONS Load tomographic reconstructions from astra toolbox
|
||||
% Currently supports reconstruction produced on Summit@OLCF with MPI parallelization.
|
||||
% Created by YJ.
|
||||
%
|
||||
|
||||
function [recon_astra, par_astra] = load_astra_recons( par_astra, par, np, Nblocks)
|
||||
|
||||
par_astra.dir = strcat('rec_',par_astra.algorithm,'_Niter',num2str(par_astra.Niter));
|
||||
par_astra.file_name = strcat('rec_',par_astra.algorithm,'_Niter',num2str(par_astra.Niter));
|
||||
|
||||
if isfield(par_astra,'min_con')
|
||||
par_astra.dir = strcat(par_astra.dir,'_minCon',num2str(par_astra.min_con));
|
||||
par_astra.file_name = strcat(par_astra.file_name,'_minCon',num2str(par_astra.min_con));
|
||||
end
|
||||
|
||||
if isfield(par_astra,'upsample_method') && ~isempty(par_astra.upsample_method)
|
||||
par_astra.dir = strcat(par_astra.dir,'_',par_astra.upsample_method);
|
||||
par_astra.file_name = strcat(par_astra.file_name,'_',par_astra.upsample_method);
|
||||
end
|
||||
|
||||
par_astra.dir = strcat(par_astra.dir,'_v',num2str(par_astra.N_y),'_h',num2str(par_astra.N_x));
|
||||
|
||||
|
||||
par_astra.time_recon = zeros(Nblocks,1);
|
||||
par_astra.time_save = zeros(Nblocks,1);
|
||||
|
||||
if par_astra.sp>1
|
||||
par_astra.dir = strcat(par_astra.dir,'_sp',num2str(sp));
|
||||
par_astra.file_name = strcat(par_astra.file_name,'_sp',num2str(sp));
|
||||
end
|
||||
par_astra.file_name = strcat(par_astra.file_name,'_np',num2str(np));
|
||||
|
||||
recon_temp = {};%
|
||||
|
||||
Nslice = 0;
|
||||
disp('Loading astra reconstructions...')
|
||||
for i = 1:Nblocks
|
||||
disp(strcat(par_astra.file_name,'_',num2str(i),'.hdf5'))
|
||||
try
|
||||
recon_temp{i} = h5read(strcat(par.output_path,'/tomograms/',par_astra.dir,'/',par_astra.file_name,'_',num2str(i),'.hdf5'),'/rec');
|
||||
catch
|
||||
disp(strcat(par.output_path,'/tomograms/',par_astra.dir,'/',par_astra.file_name,'_',num2str(i),'.hdf5'))
|
||||
|
||||
end
|
||||
par_astra.time_recon(i) = sum(h5read(strcat(par.output_path,'/tomograms/',par_astra.dir,'/',par_astra.file_name,'_',num2str(i),'.hdf5'),'/t_recon'));
|
||||
par_astra.time_save(i) = sum(h5read(strcat(par.output_path,'/tomograms/',par_astra.dir,'/',par_astra.file_name,'_',num2str(i),'.hdf5'),'/t_save'));
|
||||
disp(strcat('recon time:',num2str(par_astra.time_recon(i)/60),'mins.','save time:',num2str(par_astra.time_save(i)/60),'mins'))
|
||||
Nslice = Nslice + size(recon_temp{i},3);
|
||||
end
|
||||
|
||||
disp('Processing astra reconstructions...')
|
||||
|
||||
recon_astra = zeros(size(recon_temp{i},2),size(recon_temp{1},1),Nslice,'single');
|
||||
ind_start = 1;
|
||||
for i = 1:Nblocks
|
||||
disp(strcat(par_astra.file_name,'_',num2str(i),'.hdf5'))
|
||||
%ind_start = (i-1)*size(rec,1)+1;
|
||||
ind_end = ind_start + size(recon_temp{i},3)-1;
|
||||
if strcmp(par_astra.algorithm,'SIRT') || strcmp(par_astra.algorithm,'SART') || strcmp(par_astra.algorithm,'FBP')%2D algorithms
|
||||
recon_astra(:,:,ind_start:ind_end) = single(flipud(permute(recon_temp{i},[2 1 3])));
|
||||
else
|
||||
recon_astra(:,:,ind_start:ind_end) = single((permute(recon_temp{i},[2 1 3])));
|
||||
end
|
||||
ind_start = ind_end+1;
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,66 @@
|
||||
% LOAD_STORED_OBJECT load stored complex projections, ( + angles and par structure) saved by function utils.savefast_save
|
||||
%
|
||||
% [stack_object, theta, par] = load_stored_object(path)
|
||||
%
|
||||
% Inputs:
|
||||
% **path -path to the stored object
|
||||
% *returns*
|
||||
% ++stack_object measured projections
|
||||
% ++theta projection angles
|
||||
% ++par parameter structure
|
||||
%
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 tomography 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 [stack_object, theta, par] = load_stored_object(path)
|
||||
utils.verbose(0, 'Loading cached object ..... ')
|
||||
load(path)
|
||||
try
|
||||
% create a complex number
|
||||
stack_object = complex(stack_object_r, stack_object_i);
|
||||
catch
|
||||
try
|
||||
stack_object_r = complex(stack_object_r);
|
||||
% create a complex number inplace of the stack_object_r
|
||||
stack_object = tomo.block_fun(@(re,im)(re+1i*im),stack_object_r, stack_object_i, struct('use_GPU',false, 'inplace', true));
|
||||
catch err
|
||||
warning('Loading failed')
|
||||
disp(err)
|
||||
keyboard
|
||||
end
|
||||
end
|
||||
utils.verbose(0, 'Loading cached object done ')
|
||||
end
|
||||
@@ -0,0 +1,278 @@
|
||||
% mdaload.m - MATLAB/Octave routine for loading MDA files
|
||||
|
||||
% Copyright (c) 2016 UChicago Argonne, LLC,
|
||||
% as Operator of Argonne National Laboratory.
|
||||
% This file is distributed subject to a Software License Agreement
|
||||
% found in file LICENSE that is included with this distribution.
|
||||
|
||||
% Written by Dohn A. Arms, Argonne National Laboratory
|
||||
% Send comments to dohnarms@anl.gov
|
||||
|
||||
% 1.0 -- July 2016
|
||||
% Initial version
|
||||
|
||||
function mda = mdaload(filename)
|
||||
[fileID,errmsg] = fopen( filename,'r','b');
|
||||
if fileID < 0
|
||||
error( errmsg)
|
||||
end
|
||||
mda.version = float32grab(fileID);
|
||||
ver = round(mda.version*100.0);
|
||||
if ver ~= 140 && ver ~= 130 && ver ~= 120
|
||||
error('Incorrect MDA version')
|
||||
end
|
||||
mda.scan_number = int32grab(fileID);
|
||||
mda.data_rank = int16grab(fileID);
|
||||
if mda.data_rank < 1
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
[mda.dimensions,cnt] = fread(fileID,mda.data_rank,'int32=>int32');
|
||||
if (cnt ~= mda.data_rank) || any(mda.dimensions < 1)
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
mda.regular = int16grab(fileID);
|
||||
extra_offset = int32grab(fileID);
|
||||
mda.scan = scangrab( fileID,mda.data_rank);
|
||||
if extra_offset > 0
|
||||
fseek( fileID, extra_offset, 'bof');
|
||||
mda.extra = extragrab(fileID);
|
||||
else
|
||||
mda.extra = [];
|
||||
end
|
||||
fclose(fileID);
|
||||
end
|
||||
|
||||
function scan = scangrab(fileID,data_rank)
|
||||
scan.scan_rank = int16grab(fileID);
|
||||
if scan.scan_rank ~= data_rank
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
scan.requested_points = int32grab(fileID);
|
||||
if scan.requested_points < 1
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
scan.last_point = int32grab(fileID);
|
||||
if (scan.last_point < 0) || (scan.last_point > scan.requested_points)
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
if scan.scan_rank > 1
|
||||
[offsets,cnt] = fread(fileID,scan.requested_points,'int32=>int32');
|
||||
if (cnt ~= scan.requested_points) || any(offsets(1:scan.last_point) == 0) || any(offsets < 0)
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
end
|
||||
scan.name = strgrab(fileID);
|
||||
scan.time = strgrab(fileID);
|
||||
scan.number_positioners = int16grab(fileID);
|
||||
if scan.number_positioners < 0
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
scan.number_detectors = int16grab(fileID);
|
||||
if scan.number_detectors < 0
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
scan.number_triggers = int16grab(fileID);
|
||||
if scan.number_triggers < 0
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
if scan.number_positioners > 0
|
||||
for i = 1:scan.number_positioners
|
||||
scan.positioners(i) = posgrab(fileID);
|
||||
end
|
||||
else
|
||||
scan.positioners = [];
|
||||
end
|
||||
if scan.number_detectors > 0
|
||||
for i = 1:scan.number_detectors
|
||||
scan.detectors(i) = detgrab(fileID);
|
||||
end
|
||||
else
|
||||
scan.detectors = [];
|
||||
end
|
||||
if scan.number_triggers > 0
|
||||
for i = 1:scan.number_triggers
|
||||
scan.triggers(i) = triggrab(fileID);
|
||||
end
|
||||
else
|
||||
scan.triggers = [];
|
||||
end
|
||||
[scan.positioners_data,cnt] = fread(fileID, [scan.requested_points,scan.number_positioners],'float64=>float64');
|
||||
if cnt ~= scan.requested_points*int32(scan.number_positioners)
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
[scan.detectors_data,cnt] = fread(fileID, [scan.requested_points,scan.number_detectors],'float32=>float32');
|
||||
if cnt ~= scan.requested_points*int32(scan.number_detectors)
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
if scan.last_point < scan.requested_points
|
||||
scan.positioners_data(scan.last_point+1:end,:) = [];
|
||||
scan.detectors_data(scan.last_point+1:end,:) = [];
|
||||
end
|
||||
if scan.scan_rank > 1
|
||||
for i = 1:scan.last_point
|
||||
if fseek( fileID, offsets(i), 'bof') == -1
|
||||
error('Premature end of file');
|
||||
end
|
||||
scan.sub_scans(i) = scangrab(fileID,scan.scan_rank-1);
|
||||
end
|
||||
else
|
||||
scan.subscans = [];
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function pos = posgrab(fileID)
|
||||
pos.number = int16grab(fileID);
|
||||
pos.name = strgrab(fileID);
|
||||
pos.description = strgrab(fileID);
|
||||
pos.step_mode = strgrab(fileID);
|
||||
pos.unit = strgrab(fileID);
|
||||
pos.readback_name = strgrab(fileID);
|
||||
pos.readback_description = strgrab(fileID);
|
||||
pos.readback_unit = strgrab(fileID);
|
||||
end
|
||||
|
||||
function det = detgrab(fileID)
|
||||
det.number = int16grab(fileID);
|
||||
det.name = strgrab(fileID);
|
||||
det.description = strgrab(fileID);
|
||||
det.unit = strgrab(fileID);
|
||||
end
|
||||
|
||||
function trig = triggrab(fileID)
|
||||
trig.number = int16grab(fileID);
|
||||
trig.name = strgrab(fileID);
|
||||
trig.command = float32grab(fileID);
|
||||
end
|
||||
|
||||
function extra = extragrab(fileID)
|
||||
extra.number_pvs = int16grab(fileID);
|
||||
for i = 1:extra.number_pvs
|
||||
extra.pvs(i) = pvgrab(fileID);
|
||||
end
|
||||
end
|
||||
|
||||
function pv = pvgrab(fileID)
|
||||
pv.name = strgrab(fileID);
|
||||
pv.descr = strgrab(fileID);
|
||||
type = int16grab(fileID);
|
||||
switch type
|
||||
case 0
|
||||
pv.type = 'char';
|
||||
case 29
|
||||
pv.type = 'int16';
|
||||
case 30
|
||||
pv.type = 'float32';
|
||||
case 32
|
||||
pv.type = 'int8';
|
||||
case 33
|
||||
pv.type = 'int32';
|
||||
case 34
|
||||
pv.type = 'float64';
|
||||
otherwise
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
if type > 0
|
||||
pv.count = int16grab(fileID);
|
||||
if pv.count < 1
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
pv.unit = strgrab(fileID);
|
||||
else
|
||||
pv.count = 1;
|
||||
pv.unit = '';
|
||||
end
|
||||
switch type
|
||||
case 0
|
||||
pv.values = strgrab(fileID);
|
||||
pv.count = length(pv.values);
|
||||
case 29
|
||||
[pv.values,cnt] = fread(fileID,pv.count,'int16=>int16');
|
||||
if cnt ~= pv.count
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
if mod(pv.count,2) == 1
|
||||
[~,cnt] = fread(fileID,1,'int16=>int16');
|
||||
if cnt ~= 1
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
end
|
||||
case 30
|
||||
[pv.values,cnt] = fread(fileID,pv.count,'float32=>float32');
|
||||
if cnt ~= pv.count
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
case 32
|
||||
[pv.values,cnt] = fread(fileID,pv.count,'int8=>int8');
|
||||
if cnt ~= pv.count
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
len = mod(pv.count,4);
|
||||
if len > 0
|
||||
[~,cnt] = fread(fileID,4-len,'int8=>int8');
|
||||
if cnt ~= 4-len
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
end
|
||||
case 33
|
||||
[pv.values,cnt] = fread(fileID,pv.count,'int32=>int32');
|
||||
if cnt ~= pv.count
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
case 34
|
||||
[pv.values,cnt] = fread(fileID,pv.count,'float64=>float64');
|
||||
if cnt ~= pv.count
|
||||
error('Internal inconsistency')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function val = int32grab(fileID)
|
||||
[val,cnt] = fread(fileID,1,'int32=>int32');
|
||||
if cnt ~= 1
|
||||
error('Premature end of file');
|
||||
end
|
||||
end
|
||||
|
||||
function val = int16grab(fileID)
|
||||
[val,cnt] = fread(fileID,1,'int32=>int16');
|
||||
if cnt ~= 1
|
||||
error('Premature end of file');
|
||||
end
|
||||
end
|
||||
|
||||
function val = float32grab(fileID)
|
||||
[val,cnt] = fread(fileID,1,'float32=>float32');
|
||||
if cnt ~= 1
|
||||
error('Premature end of file');
|
||||
end
|
||||
end
|
||||
|
||||
function str = strgrab(fileID)
|
||||
[len1,cnt]=fread(fileID,1,'int32=>int16');
|
||||
if cnt ~= 1
|
||||
error('Premature end of file');
|
||||
end
|
||||
if len1 > 0
|
||||
[len2,cnt]=fread(fileID,1,'int32=>int16');
|
||||
if cnt ~= 1
|
||||
error('Premature end of file');
|
||||
end
|
||||
[str,cnt]=fread(fileID,[1,len2],'char=>char');
|
||||
if cnt ~= len2
|
||||
error('Premature end of file');
|
||||
end
|
||||
m = mod(len2,4);
|
||||
if m > 0
|
||||
[~,cnt]=fread(fileID,4-m,'char=>char');
|
||||
if cnt ~= 4-m
|
||||
error('Premature end of file');
|
||||
end
|
||||
end
|
||||
else
|
||||
str='';
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
% tomo_filtered = filter_x(tomo_filtered,freq_scale)
|
||||
% Receives a tomogram and applies filtering only along the third index of
|
||||
% a 3D matrix.
|
||||
% Inputs:
|
||||
% tomo Input tomogram matrix
|
||||
% freq_scale Frequency cutoff
|
||||
% Manuel Guizar Feb 14, 2016
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 tomo_filtered = filter_x(tomo_filtered,freq_scale)
|
||||
|
||||
|
||||
%%% Filter a tomogram along the last index %%%
|
||||
% freq_scale = 0.1;
|
||||
%
|
||||
% %%% Create example %%%
|
||||
% N = 200;
|
||||
% tomo_filtered = zeros([N N N]);
|
||||
% for ii = 1:N
|
||||
% tomo_filtered(ii,:,:) = phantom(N);
|
||||
% end
|
||||
% tomo_filtered = repmat(tomo_filtered,[1 1 N]);
|
||||
%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
%%% Create filter %%%
|
||||
|
||||
Nfilt = size(tomo_filtered,2);
|
||||
|
||||
filt = zeros([Nfilt 1]);
|
||||
d = freq_scale;
|
||||
|
||||
w = [-Nfilt/2:Nfilt/2-1]+mod(Nfilt/2,2);
|
||||
w = 2*pi*w/Nfilt;
|
||||
|
||||
filt = (1+cos(w/d)) / 2;
|
||||
filt(abs(w)/d>pi) = 0;
|
||||
filt = ifftshift(filt);
|
||||
|
||||
% figure(1);
|
||||
% plot(filt);
|
||||
%%%%%%
|
||||
%
|
||||
|
||||
filt3D = repmat(reshape(filt,[1,Nfilt,1]),[size(tomo_filtered,1) 1 size(tomo_filtered,3)]);
|
||||
|
||||
tomo_filtered = real(ifft( fft(tomo_filtered,[],2).*filt3D ,[],2));
|
||||
|
||||
|
||||
|
||||
% %% Image %%%
|
||||
% figure(1)
|
||||
% imagesc(squeeze(tomo_filtered(2,:,:)));
|
||||
% % imagesc(squeeze(filt3D(1,:,:)));
|
||||
% colorbar
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
% tomo_filtered = filter_y(tomo,freq_scale)
|
||||
% Receives a tomogram and applies filtering only along the third index of
|
||||
% a 3D matrix.
|
||||
% Inputs:
|
||||
% tomo Input tomogram matrix
|
||||
% freq_scale Frequency cutoff
|
||||
% Manuel Guizar Feb 14, 2016
|
||||
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 tomo_filtered = filter_y(tomo_filtered,freq_scale)
|
||||
|
||||
|
||||
%%% Filter a tomogram along the last index %%%
|
||||
% freq_scale = 0.1;
|
||||
%
|
||||
% %%% Create example %%%
|
||||
% N = 200;
|
||||
% tomo_filtered = zeros([N N N]);
|
||||
% for ii = 1:N
|
||||
% tomo_filtered(ii,:,:) = phantom(N);
|
||||
% end
|
||||
% tomo_filtered = repmat(tomo_filtered,[1 1 N]);
|
||||
%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
%%% Create filter %%%
|
||||
|
||||
Nfilt = size(tomo_filtered,3);
|
||||
|
||||
filt = zeros([Nfilt 1]);
|
||||
d = freq_scale;
|
||||
|
||||
w = [-Nfilt/2:Nfilt/2-1]+mod(Nfilt/2,2);
|
||||
w = 2*pi*w/Nfilt;
|
||||
|
||||
filt = (1+cos(w/d)) / 2;
|
||||
filt(abs(w)/d>pi) = 0;
|
||||
filt = ifftshift(filt);
|
||||
|
||||
% figure(1);
|
||||
% plot(filt);
|
||||
%%%%%%
|
||||
%
|
||||
|
||||
filt3D = repmat(reshape(filt,[1,1,Nfilt]),[size(tomo_filtered,1) size(tomo_filtered,2) 1]);
|
||||
|
||||
tomo_filtered = real(ifft( fft(tomo_filtered,[],3).*filt3D ,[],3));
|
||||
|
||||
|
||||
|
||||
% %% Image %%%
|
||||
% figure(1)
|
||||
% imagesc(squeeze(tomo_filtered(2,:,:)));
|
||||
% % imagesc(squeeze(filt3D(1,:,:)));
|
||||
% colorbar
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
% tomo_filtered = filter_y(tomo,freq_scale)
|
||||
% Receives a tomogram and applies filtering only along the third index of
|
||||
% a 3D matrix.
|
||||
% Inputs:
|
||||
% tomo Input tomogram matrix
|
||||
% freq_scale Frequency cutoff
|
||||
% Manuel Guizar Feb 14, 2016
|
||||
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 tomo_filtered = filter_z(tomo_filtered,freq_scale)
|
||||
|
||||
|
||||
%%% Filter a tomogram along the last index %%%
|
||||
% freq_scale = 0.1;
|
||||
%
|
||||
% %%% Create example %%%
|
||||
% N = 200;
|
||||
% tomo_filtered = zeros([N N N]);
|
||||
% for ii = 1:N
|
||||
% tomo_filtered(ii,:,:) = phantom(N);
|
||||
% end
|
||||
% tomo_filtered = repmat(tomo_filtered,[1 1 N]);
|
||||
%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
%%% Create filter %%%
|
||||
|
||||
Nfilt = size(tomo_filtered,1);
|
||||
|
||||
filt = zeros([Nfilt 1]);
|
||||
d = freq_scale;
|
||||
|
||||
w = [-Nfilt/2:Nfilt/2-1]+mod(Nfilt/2,2);
|
||||
w = 2*pi*w/Nfilt;
|
||||
|
||||
filt = (1+cos(w/d)) / 2;
|
||||
filt(abs(w)/d>pi) = 0;
|
||||
filt = ifftshift(filt);
|
||||
|
||||
% figure(1);
|
||||
% plot(filt);
|
||||
%%%%%%
|
||||
%
|
||||
|
||||
filt3D = repmat(reshape(filt,[Nfilt,1,1]),[1 size(tomo_filtered,2) size(tomo_filtered,3)]);
|
||||
|
||||
tomo_filtered = real(ifft( fft(tomo_filtered,[],1).*filt3D ,[],1));
|
||||
|
||||
|
||||
|
||||
% %% Image %%%
|
||||
% figure(1)
|
||||
% imagesc(squeeze(tomo_filtered(2,:,:)));
|
||||
% % imagesc(squeeze(filt3D(1,:,:)));
|
||||
% colorbar
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
% FUNCTION [ sub_thetaT sub_ind_T] = split_tomogram( indices, theta, num_sub_tomograms )
|
||||
% Divides up the tomogram into sub tomograms according to the matrix
|
||||
% indices.
|
||||
% A combined tomogram is in each row. The single tomograms contained in each
|
||||
% row are given in the columns.
|
||||
% For example, four sub tomograms out of 8 with a pairing of 1 2 , 3 4 etc
|
||||
% would be given by indices = [[1 2];[3 4];[5 6];[7 8]]
|
||||
% All of the first 4 sub tomograms will be returned by indices = [[1] [2] [3] [4]]
|
||||
% The output are cells.
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 [ sub_thetaT sub_ind_T] = split_tomogram( indices, theta, num_sub_tomograms )
|
||||
|
||||
[sortedTheta, ind] = sort(theta);
|
||||
|
||||
%% no_subtomos = 16
|
||||
n = log2(num_sub_tomograms);
|
||||
if mod(n,1) > 0.000001
|
||||
disp(['Error - impossible number of subtomograms chosen'])
|
||||
subtomo_order = NaN;
|
||||
return
|
||||
end
|
||||
subtomos = zeros(1,num_sub_tomograms);
|
||||
k= 1;
|
||||
jj=1;
|
||||
k_prev = k;
|
||||
for i=1:n
|
||||
|
||||
k = k_prev/2;
|
||||
while k <= 1
|
||||
jj = jj+1;
|
||||
subtomos(jj)=k;
|
||||
k=k+k_prev;
|
||||
end
|
||||
k_prev = k_prev/2;
|
||||
end
|
||||
[dump,subtomo_order]= sort(subtomos);
|
||||
|
||||
|
||||
%%
|
||||
|
||||
subtomo_order = [1 5 3 7 2 6 4 8];
|
||||
|
||||
|
||||
for i = 1: num_sub_tomograms;
|
||||
sub_theta_u{i} = sortedTheta(subtomo_order(i):num_sub_tomograms:end);
|
||||
sub_ind_u{i} = ind(subtomo_order(i):num_sub_tomograms:end);
|
||||
end
|
||||
|
||||
for i = 1 : size(indices,1);
|
||||
Combined_Angle = [sub_theta_u{indices(i,1:end)}];
|
||||
Combined_Index = [sub_ind_u{indices(i,1:end)}];
|
||||
Combined = sortrows(transpose([ Combined_Index ; Combined_Angle ]),2);
|
||||
sub_ind_T{i} = Combined(:,1);
|
||||
if std(diff(Combined(:,2)))/mean(diff(Combined(:,2))) > 0.03
|
||||
disp(['Combined sub tomogram ', num2str(i), ' has too large deviations in the angles. The sub tomograms are probably not equally spaced'])
|
||||
end
|
||||
% std(diff(Combined(:,2)))/mean(diff(Combined(:,2)))
|
||||
sub_thetaT{i} = Combined(:,2);
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,143 @@
|
||||
% PROJECTION_PROPAGATION_OPTIMIZATION Estimate optimal propagation distance to minimize amplitude
|
||||
%
|
||||
% optimum = projection_propagation_optimization( stack_object, angles, range, ROI, par)
|
||||
%
|
||||
% Inputs:
|
||||
% **stack_object - complex projections
|
||||
% **angles - projection angles
|
||||
% **range - scanning range
|
||||
% **ROI - region of interest, cell
|
||||
% **par - parameter structure
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 optimum = projection_propagation_optimization( stack_object, angles, range, ROI, par)
|
||||
|
||||
disp('Estimation of optimal focus')
|
||||
|
||||
propagation_score = tomo.block_fun(@scan_propagation, stack_object, range, par, struct('use_fp16', false,'use_GPU', true, 'ROI', {ROI}, 'GPU_list', par.GPU_list));
|
||||
|
||||
propagation_score = propagation_score - mean(mean(propagation_score,1),3);
|
||||
propagation_score = propagation_score ./ std(std(propagation_score,[],1),[],3);
|
||||
|
||||
score = squeeze(trimmean(propagation_score,10,'round',3));
|
||||
|
||||
subplot(1,3,1)
|
||||
plot(range'*1e6,squeeze(propagation_score(:,1,:)) , '-')
|
||||
title('Variance amplitude')
|
||||
xlabel('Propagation distance [\mum]')
|
||||
ylabel('Normalized local variance')
|
||||
grid on
|
||||
|
||||
hold all
|
||||
plotting.vline(1e6*range(math.argmin(score(:,1))))
|
||||
hold off
|
||||
subplot(1,3,2)
|
||||
plot(range*1e6,squeeze(propagation_score(:,2,:)) , '-')
|
||||
title('Variance phase')
|
||||
xlabel('Propagation distance [\mum]')
|
||||
ylabel('Normalized local variance')
|
||||
grid on
|
||||
hold all
|
||||
plotting.vline(1e6*range(math.argmax(score(:,2))), 'r:', 'Optimal propagation')
|
||||
hold off
|
||||
|
||||
|
||||
optimum = sort([math.argmax(score(:,2)),math.argmin(score(:,1))]);
|
||||
optimum = 1e6*range(optimum);
|
||||
%suptitle(sprintf('Optimal propagation %3.1f - %3.1f um',optimum ))
|
||||
sprintf('Optimal propagation %3.1f - %3.1f um',optimum )
|
||||
propagation_score(:,2,:) = -propagation_score(:,2,:);
|
||||
|
||||
propagation_score = propagation_score ./ min(propagation_score,[],1);
|
||||
|
||||
[optim_shift_amp,ind] = find(squeeze(propagation_score(:,1,:)) == 1);
|
||||
[~,uind] = unique(ind);
|
||||
optim_shift_amp = optim_shift_amp(uind);
|
||||
|
||||
[optim_shift_phase,ind] = find(squeeze(propagation_score(:,2,:)) == 1);
|
||||
[~,uind] = unique(ind);
|
||||
optim_shift_phase = optim_shift_phase(uind);
|
||||
|
||||
subplot(2,3,3)
|
||||
plot(1e6*range(optim_shift_amp)+randn(size(optim_shift_amp))'*0.01, 1e6*range(optim_shift_phase)+randn(size(optim_shift_amp))'*0.01, 'o');
|
||||
title(sprintf('Correlation between phase/amplitude %3.2f', corr(optim_shift_amp, optim_shift_phase)))
|
||||
axis equal square
|
||||
grid on
|
||||
xlabel('Optimal shift from amplitude')
|
||||
ylabel('Optimal shift from phase')
|
||||
|
||||
|
||||
subplot(2,3,6)
|
||||
hold all
|
||||
plot(angles, 1e6*range(optim_shift_amp), '.')
|
||||
plot(angles, 1e6*range(optim_shift_phase), '.')
|
||||
hold off
|
||||
xlabel('Angles [deg]')
|
||||
ylabel('Optimal offset [\mum]')
|
||||
legend({'Amplitude', 'Phase'})
|
||||
axis tight
|
||||
grid on
|
||||
|
||||
% optimum = (range(optim_shift_amp) + range(optim_shift_phase))/2;
|
||||
optimum = range(optim_shift_amp);
|
||||
|
||||
end
|
||||
|
||||
|
||||
function variance = scan_propagation(stack_object, range, par)
|
||||
|
||||
Nproj = size(stack_object, 3);
|
||||
for kk = 1:length(range)
|
||||
shift = range(kk);
|
||||
stack_object_prop = utils.prop_free_nf(stack_object, par.lambda, shift, par.pixel_size);
|
||||
stack_object_amp = abs(stack_object_prop);
|
||||
stack_object_phase = -math.unwrap2D_fft2(stack_object_prop,par.air_gap,0,1,0);
|
||||
clear stack_object_prop
|
||||
|
||||
|
||||
% estimate local variance for amplitude
|
||||
stack_object_amp = stack_object_amp-utils.imgaussfilt2_fft(stack_object_amp,3);
|
||||
stack_object_amp = reshape(stack_object_amp,[],Nproj);
|
||||
variance(kk,1,:) = std(stack_object_amp);
|
||||
|
||||
% estimate local variance for phase
|
||||
stack_object_phase = stack_object_phase-utils.imgaussfilt2_fft(stack_object_phase,3);
|
||||
stack_object_phase = reshape(stack_object_phase,[],Nproj);
|
||||
variance(kk,2,:) = std(stack_object_phase);
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,62 @@
|
||||
function [I_phase_new, f] = remove_grid_artifact(I_phase, dx, stepSize_x,stepSize_y, windowSize, direction, showFigure)
|
||||
%UNTITLED2 Summary of this function goes here
|
||||
% Detailed explanation goes here
|
||||
Nx = size(I_phase,2);
|
||||
Ny = size(I_phase,1);
|
||||
dk_x = 1/dx/Nx;
|
||||
dk_y = 1/dx/Ny;
|
||||
cen_x = floor(Nx/2)+1;
|
||||
cen_y = floor(Ny/2)+1;
|
||||
|
||||
k_max = 1/dx;
|
||||
f0 = fftshift(fft2(ifftshift(I_phase)));
|
||||
f = f0;
|
||||
dk_s_x = 1/stepSize_x;
|
||||
dk_s_y = 1/stepSize_y;
|
||||
|
||||
switch direction
|
||||
case 'xy'
|
||||
x_range = ceil(-k_max/2/dk_s_x):floor(k_max/2/dk_s_x);
|
||||
y_range = ceil(-k_max/2/dk_s_y):floor(k_max/2/dk_s_y);
|
||||
case 'x'
|
||||
x_range = ceil(-k_max/2/dk_s_x):floor(k_max/2/dk_s_x);
|
||||
y_range = 0;
|
||||
case 'y'
|
||||
x_range = 0;
|
||||
y_range = ceil(-k_max/2/dk_s_y):floor(k_max/2/dk_s_y);
|
||||
end
|
||||
for i=1:length(x_range)
|
||||
for j=1:length(y_range)
|
||||
|
||||
if ~(x_range(i)==0 && y_range(j)==0)
|
||||
window_x_lb = max(round(x_range(i)*dk_s_x/dk_x) + cen_x - windowSize, 1);
|
||||
window_x_ub = min(round(x_range(i)*dk_s_x/dk_x) + cen_x + windowSize, Nx);
|
||||
|
||||
window_y_lb = max(round(y_range(j)*dk_s_y/dk_y) + cen_y - windowSize, 1);
|
||||
window_y_ub = min(round(y_range(j)*dk_s_y/dk_y) + cen_y + windowSize, Ny);
|
||||
%window_y_lb
|
||||
%window_y_ub
|
||||
f(window_y_lb:window_y_ub,window_x_lb:window_x_ub) = 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
I_phase_new = real(fftshift(ifft2(ifftshift(f))));
|
||||
|
||||
if showFigure
|
||||
figure
|
||||
subplot(2,2,1)
|
||||
imagesc(I_phase); axis image;
|
||||
subplot(2,2,2)
|
||||
imagesc(abs(f0).^0.2); axis image;
|
||||
|
||||
subplot(2,2,3)
|
||||
imagesc(I_phase_new); axis image;
|
||||
subplot(2,2,4)
|
||||
imagesc(abs(f).^0.2); axis image;
|
||||
colormap jet
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
% SAVE_MOVIE Function to save stack of images as a movie
|
||||
%
|
||||
% save_movie(img_stack, movie_filename, theta, par, varargin)
|
||||
%
|
||||
% ** img_stack stack of input images, real or complex
|
||||
% ** movie_filename name of the movie to be saved
|
||||
% *optional*
|
||||
% ** theta angles of the projections, default = []
|
||||
% ** par structure with tomo parameters, default = []
|
||||
% ** varargin other parameters, see the code for more details
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 pareters, 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 save_movie(img_stack, movie_filename, theta, par, varargin)
|
||||
|
||||
import math.*
|
||||
|
||||
parser = inputParser;
|
||||
parser.addParameter('pixel_size', nan , @isnumeric )
|
||||
parser.addParameter('colormap', bone , @isnumeric )
|
||||
parser.addParameter('output_folder', '' , @isstr )
|
||||
parser.addParameter('fps', 10 , @isnumeric )
|
||||
parser.addParameter('quality', 100 , @isnumeric ) % 100 is maximal
|
||||
parser.addParameter('baraxis','auto')
|
||||
parser.addParameter('windowautopos',false)
|
||||
|
||||
parser.parse(varargin{:})
|
||||
r = parser.Results;
|
||||
|
||||
if nargin < 4
|
||||
par = struct();
|
||||
end
|
||||
|
||||
% load all to the param structure
|
||||
for name = fieldnames(r)'
|
||||
if ~isfield(par, name{1}) || ~ismember(name, parser.UsingDefaults) % prefer values in param structure
|
||||
par.(name{1}) = r.(name{1});
|
||||
end
|
||||
end
|
||||
|
||||
movie_path = [par.output_folder, movie_filename];
|
||||
|
||||
if exist(movie_path,'file')
|
||||
disp(['File ' movie_path ' exists,' ])
|
||||
userans = input(['Do you want to overwrite (Y/n)? '],'s');
|
||||
if strcmpi(userans,'n')
|
||||
disp(['Did not save ' par.saveprojfile])
|
||||
return
|
||||
end
|
||||
else
|
||||
delete(movie_path);
|
||||
end
|
||||
|
||||
Nslices = size(img_stack,3);
|
||||
|
||||
|
||||
frames = 1:Nslices;
|
||||
if ~isempty(theta) && par.showsorted
|
||||
[~, ind] = sort(theta);
|
||||
frames = ind(frames);
|
||||
end
|
||||
|
||||
|
||||
clf()
|
||||
if isfield(par, 'baraxis') && strcmpi(par.baraxis,'auto') && isreal(img_stack)
|
||||
% set the same range for all the frames using quantile range
|
||||
range = gather(sp_quantile(img_stack, [1e-3, 1-1e-3], 10));
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
disp(['Saving movie to ' movie_path]);
|
||||
writeobj = VideoWriter(movie_path);
|
||||
writeobj.Quality=par.quality;
|
||||
writeobj.FrameRate=par.fps;
|
||||
|
||||
open(writeobj);
|
||||
|
||||
% Create an animation.
|
||||
plotting.imagesc3D(img_stack(:,:,1))
|
||||
axis off image
|
||||
colormap(par.colormap)
|
||||
|
||||
set(gca,'nextplot','replacechildren');
|
||||
|
||||
if par.windowautopos
|
||||
screensize = get( groot, 'Screensize' );
|
||||
win_size = [1060 767];
|
||||
set(gcf,'Outerposition',[141 min(257,screensize(2)-win_size(2)) 1060 767]);
|
||||
end
|
||||
|
||||
|
||||
|
||||
disp('Creating movie')
|
||||
for kk = 1:Nslices
|
||||
utils.progressbar(kk, Nslices)
|
||||
% use imagesc3D to image also complex valued images
|
||||
plotting.imagesc3D(img_stack(:,:,frames(kk)))
|
||||
if isreal(img_stack) && isfield(par, 'baraxis')
|
||||
if ~strcmpi(par.baraxis,'auto')
|
||||
caxis(par.baraxis)
|
||||
else
|
||||
caxis(range)
|
||||
end
|
||||
end
|
||||
axis xy
|
||||
% Write each frame to the file.
|
||||
currFrame = getframe;
|
||||
writeVideo(writeobj,currFrame);
|
||||
end
|
||||
|
||||
close(writeobj);
|
||||
|
||||
disp('Movie finished')
|
||||
|
||||
|
||||
|
||||
end
|
||||
@@ -0,0 +1,670 @@
|
||||
function [c,ww] = smooth(varargin)
|
||||
%SMOOTH Smooth data.
|
||||
% Z = SMOOTH(Y) smooths data Y using a 5-point moving average.
|
||||
%
|
||||
% Z = SMOOTH(Y,SPAN) smooths data Y using SPAN as the number of points used
|
||||
% to compute each element of Z.
|
||||
%
|
||||
% Z = SMOOTH(Y,SPAN,METHOD) smooths data Y with specified METHOD. The
|
||||
% available methods are:
|
||||
%
|
||||
% 'moving' - Moving average (default)
|
||||
% 'lowess' - Lowess (linear fit)
|
||||
% 'loess' - Loess (quadratic fit)
|
||||
% 'sgolay' - Savitzky-Golay
|
||||
% 'rlowess' - Robust Lowess (linear fit)
|
||||
% 'rloess' - Robust Loess (quadratic fit)
|
||||
%
|
||||
% Z = SMOOTH(Y,METHOD) uses the default SPAN 5.
|
||||
%
|
||||
% Z = SMOOTH(Y,SPAN,'sgolay',DEGREE) and Z = SMOOTH(Y,'sgolay',DEGREE)
|
||||
% additionally specify the degree of the polynomial to be used in the
|
||||
% Savitzky-Golay method. The default DEGREE is 2. DEGREE must be smaller
|
||||
% than SPAN.
|
||||
%
|
||||
% Z = SMOOTH(X,Y,...) additionally specifies the X coordinates. If X is
|
||||
% not provided, methods that require X coordinates assume X = 1:N, where
|
||||
% N is the length of Y.
|
||||
%
|
||||
% Notes:
|
||||
% 1. When X is given and X is not uniformly distributed, the default method
|
||||
% is 'lowess'. The 'moving' method is not recommended.
|
||||
%
|
||||
% 2. For the 'moving' and 'sgolay' methods, SPAN must be odd.
|
||||
% If an even SPAN is specified, it is reduced by 1.
|
||||
%
|
||||
% 3. If SPAN is greater than the length of Y, it is reduced to the
|
||||
% length of Y.
|
||||
%
|
||||
% 4. In the case of (robust) lowess and (robust) loess, it is also
|
||||
% possible to specify the SPAN as a percentage of the total number
|
||||
% of data points. When SPAN is less than or equal to 1, it is
|
||||
% treated as a percentage.
|
||||
%
|
||||
% For example:
|
||||
%
|
||||
% Z = SMOOTH(Y) uses the moving average method with span 5 and
|
||||
% X=1:length(Y).
|
||||
%
|
||||
% Z = SMOOTH(Y,7) uses the moving average method with span 7 and
|
||||
% X=1:length(Y).
|
||||
%
|
||||
% Z = SMOOTH(Y,'sgolay') uses the Savitzky-Golay method with DEGREE=2,
|
||||
% SPAN = 5, X = 1:length(Y).
|
||||
%
|
||||
% Z = SMOOTH(X,Y,'lowess') uses the lowess method with SPAN=5.
|
||||
%
|
||||
% Z = SMOOTH(X,Y,SPAN,'rloess') uses the robust loess method.
|
||||
%
|
||||
% Z = SMOOTH(X,Y) where X is unevenly distributed uses the
|
||||
% 'lowess' method with span 5.
|
||||
%
|
||||
% Z = SMOOTH(X,Y,8,'sgolay') uses the Savitzky-Golay method with
|
||||
% span 7 (8 is reduced by 1 to make it odd).
|
||||
%
|
||||
% Z = SMOOTH(X,Y,0.3,'loess') uses the loess method where span is
|
||||
% 30% of the data, i.e. span = ceil(0.3*length(Y)).
|
||||
%
|
||||
% See also SPLINE.
|
||||
|
||||
% Copyright 2001-2016 The MathWorks, Inc.
|
||||
|
||||
if nargin < 1
|
||||
error(message('curvefit:smooth:needMoreArgs'));
|
||||
end
|
||||
|
||||
if nargout > 1 % Called from the GUI cftool
|
||||
ws = warning('off', 'all'); % turn warning off and record the previous warning state.
|
||||
[lw,lwid] = lastwarn;
|
||||
lastwarn('');
|
||||
else
|
||||
ws = warning('query','all'); % Leave warning state alone but save it so resets are no-ops.
|
||||
end
|
||||
|
||||
% is x given as the first argument?
|
||||
if nargin==1 || ( nargin > 1 && (length(varargin{2})==1 || ischar(varargin{2})) )
|
||||
% smooth(Y) | smooth(Y,span,...) | smooth(Y,method,...)
|
||||
is_x = 0; % x is not given
|
||||
y = varargin{1};
|
||||
y = y(:);
|
||||
x = (1:length(y))';
|
||||
else % smooth(X,Y,...)
|
||||
is_x = 1;
|
||||
y = varargin{2};
|
||||
x = varargin{1};
|
||||
y = y(:);
|
||||
x = x(:);
|
||||
end
|
||||
|
||||
% is span given?
|
||||
span = [];
|
||||
if nargin == 1+is_x || ischar(varargin{2+is_x})
|
||||
% smooth(Y), smooth(X,Y) || smooth(X,Y,method,..), smooth(Y,method)
|
||||
is_span = 0;
|
||||
else
|
||||
% smooth(...,SPAN,...)
|
||||
is_span = 1;
|
||||
span = varargin{2+is_x};
|
||||
end
|
||||
|
||||
% is method given?
|
||||
method = [];
|
||||
if nargin >= 2+is_x+is_span
|
||||
% smooth(...,Y,method,...) | smooth(...,Y,span,method,...)
|
||||
method = varargin{2+is_x+is_span};
|
||||
end
|
||||
|
||||
t = length(y);
|
||||
if t == 0
|
||||
c = y;
|
||||
ww = '';
|
||||
if nargout > 1
|
||||
ww = lastwarn;
|
||||
lastwarn(lw,lwid);
|
||||
warning(ws); % turn warning back to the previous state.
|
||||
end
|
||||
return
|
||||
elseif length(x) ~= t
|
||||
warning(ws); % reset warn state before erroring
|
||||
error(message('curvefit:smooth:XYmustBeSameLength'));
|
||||
end
|
||||
|
||||
if isempty(method)
|
||||
diffx = diff(x);
|
||||
if uniformx(diffx,x,y)
|
||||
method = 'moving'; % uniformly distributed X.
|
||||
else
|
||||
method = 'lowess';
|
||||
end
|
||||
end
|
||||
|
||||
% realize span
|
||||
if span <= 0
|
||||
warning(ws); % reset warn state before erroring
|
||||
error(message('curvefit:smooth:spanMustBePositive'));
|
||||
end
|
||||
if span < 1, span = ceil(span*t); end % percent convention
|
||||
if isempty(span), span = 5; end % smooth(Y,[],method)
|
||||
|
||||
idx = 1:t;
|
||||
|
||||
sortx = any(diff(isnan(x))<0); % if NaNs not all at end
|
||||
if sortx || any(diff(x)<0) % sort x
|
||||
[x,idx] = sort(x);
|
||||
y = y(idx);
|
||||
end
|
||||
|
||||
if islogical(y)
|
||||
y = double(y);
|
||||
end
|
||||
|
||||
c = NaN(size(y),'like',y);
|
||||
|
||||
ok = ~isnan(x);
|
||||
switch method
|
||||
case 'moving'
|
||||
c(ok) = moving(x(ok),y(ok),span);
|
||||
case {'lowess','loess','rlowess','rloess'}
|
||||
robust = 0;
|
||||
iter = 5;
|
||||
if method(1)=='r'
|
||||
robust = 1;
|
||||
method = method(2:end);
|
||||
end
|
||||
c(ok) = lowess(x(ok),y(ok),span, method,robust,iter);
|
||||
case 'sgolay'
|
||||
if nargin >= 3+is_x+is_span
|
||||
degree = varargin{3+is_x+is_span};
|
||||
else
|
||||
degree = 2;
|
||||
end
|
||||
if degree < 0 || degree ~= floor(degree) || degree >= span
|
||||
warning(ws); % reset warn state before erroring
|
||||
error(message('curvefit:smooth:invalidDegree'));
|
||||
end
|
||||
c(ok) = sgolay(x(ok),y(ok),span,degree);
|
||||
otherwise
|
||||
warning(ws); % reset warn state before erroring
|
||||
error(message('curvefit:smooth:unrecognizedMethod'));
|
||||
end
|
||||
|
||||
c(idx) = c;
|
||||
|
||||
if nargout > 1
|
||||
ww = lastwarn;
|
||||
lastwarn(lw,lwid);
|
||||
warning(ws); % turn warning back to the previous state.
|
||||
end
|
||||
%--------------------------------------------------------------------
|
||||
function c = moving(x,y, span)
|
||||
% moving average of the data.
|
||||
|
||||
ynan = isnan(y);
|
||||
span = floor(span);
|
||||
n = length(y);
|
||||
span = min(span,n);
|
||||
width = span-1+mod(span,2); % force it to be odd
|
||||
xreps = any(diff(x)==0);
|
||||
if width==1 && ~xreps && ~any(ynan), c = y; return; end
|
||||
if ~xreps && ~any(ynan)
|
||||
% simplest method for most common case
|
||||
c = filter(ones(width,1)/width,1,y);
|
||||
cbegin = cumsum(y(1:width-2));
|
||||
cbegin = cbegin(1:2:end)./(1:2:(width-2))';
|
||||
cend = cumsum(y(n:-1:n-width+3));
|
||||
cend = cend(end:-2:1)./(width-2:-2:1)';
|
||||
c = [cbegin;c(width:end);cend];
|
||||
elseif ~xreps
|
||||
% with no x repeats, can take ratio of two smoothed sequences
|
||||
yy = y;
|
||||
yy(ynan) = 0;
|
||||
nn = double(~ynan);
|
||||
ynum = moving(x,yy,span);
|
||||
yden = moving(x,nn,span);
|
||||
c = ynum ./ yden;
|
||||
else
|
||||
% with some x repeats, loop
|
||||
notnan = ~ynan;
|
||||
yy = y;
|
||||
yy(ynan) = 0;
|
||||
c = zeros(n,1,'like',y);
|
||||
for i=1:n
|
||||
if i>1 && x(i)==x(i-1)
|
||||
c(i) = c(i-1);
|
||||
continue;
|
||||
end
|
||||
R = i; % find rightmost value with same x
|
||||
while(R<n && x(R+1)==x(R))
|
||||
R = R+1;
|
||||
end
|
||||
hf = ceil(max(0,(span - (R-i+1))/2)); % need this many more on each side
|
||||
hf = min(min(hf,(i-1)), (n-R));
|
||||
L = i-hf; % find leftmost point needed
|
||||
while(L>1 && x(L)==x(L-1))
|
||||
L = L-1;
|
||||
end
|
||||
R = R+hf; % find rightmost point needed
|
||||
while(R<n && x(R)==x(R+1))
|
||||
R = R+1;
|
||||
end
|
||||
c(i) = sum(yy(L:R)) / sum(notnan(L:R));
|
||||
end
|
||||
end
|
||||
%--------------------------------------------------------------------
|
||||
function c = lowess(x,y, span, method, robust, iter)
|
||||
% LOWESS Smooth data using Lowess or Loess method.
|
||||
%
|
||||
% The difference between LOWESS and LOESS is that LOWESS uses a
|
||||
% linear model to do the local fitting whereas LOESS uses a
|
||||
% quadratic model to do the local fitting. Some other software
|
||||
% may not have LOWESS, instead, they use LOESS with order 1 or 2 to
|
||||
% represent these two smoothing methods.
|
||||
%
|
||||
% Reference:
|
||||
% [C79] W.S.Cleveland, "Robust Locally Weighted Regression and Smoothing
|
||||
% Scatterplots", _J. of the American Statistical Ass._, Vol 74, No. 368
|
||||
% (Dec.,1979), pp. 829-836.
|
||||
% http://www.math.tau.ac.il/~yekutiel/MA%20seminar/Cleveland%201979.pdf
|
||||
|
||||
|
||||
n = length(y);
|
||||
span = floor(span);
|
||||
span = min(span,n);
|
||||
c = y;
|
||||
if span == 1
|
||||
return;
|
||||
end
|
||||
|
||||
useLoess = false;
|
||||
if isequal(method,'loess')
|
||||
useLoess = true;
|
||||
end
|
||||
|
||||
diffx = diff(x);
|
||||
|
||||
% For problems where x is uniform, there's a faster way
|
||||
isuniform = uniformx(diffx,x,y);
|
||||
if isuniform
|
||||
% For uniform data, an even span actually covers an odd number of
|
||||
% points. For example, the four closest points to 5 in the
|
||||
% sequence 1:10 are {3,4,5,6}, but 7 is as close as 3.
|
||||
% Therefore force an odd span.
|
||||
span = 2*floor(span/2) + 1;
|
||||
|
||||
c = unifloess(y,span,useLoess);
|
||||
if ~robust || span<=2
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
% Turn off warnings when called from command line (already off if called from
|
||||
% cftool).
|
||||
ws = warning( 'off', 'MATLAB:rankDeficientMatrix' );
|
||||
cleanup = onCleanup( @() warning( ws ) );
|
||||
|
||||
|
||||
ynan = isnan(y);
|
||||
anyNans = any(ynan(:));
|
||||
seps = sqrt(eps);
|
||||
theDiffs = [1; diffx; 1];
|
||||
|
||||
if isuniform
|
||||
% We've already computed the non-robust smooth, so in preparation for
|
||||
% the robust smooth, compute the following arrays directly
|
||||
halfw = floor(span/2);
|
||||
|
||||
% Each local interval is from |halfw| below the current index to |halfw|
|
||||
% above
|
||||
lbound = (1:n)-halfw;
|
||||
rbound = (1:n)+halfw;
|
||||
% However, there always has to be at least |span| points to the right of the
|
||||
% left bound
|
||||
lbound = min( n+1-span, lbound );
|
||||
% ... and at least |span| points to the left of the right bound
|
||||
rbound = max( span, rbound );
|
||||
% Furthermore, because these bounds index into vectors of length n, they
|
||||
% must contain valid indices
|
||||
lbound = max( 1, lbound );
|
||||
rbound = min( n, rbound );
|
||||
|
||||
% Since the input is uniform we can use natural numbers for the input when
|
||||
% we need them.
|
||||
x = (1:numel(x))';
|
||||
else
|
||||
if robust
|
||||
% pre-allocate space for lower and upper indices for each fit,
|
||||
% to avoid re-computing this information in robust iterations
|
||||
lbound = zeros(n,1,'like',y);
|
||||
rbound = zeros(n,1,'like',y);
|
||||
end
|
||||
|
||||
% Compute the non-robust smooth for non-uniform x
|
||||
for i=1:n
|
||||
% if x(i) and x(i-1) are equal we just use the old value.
|
||||
if theDiffs(i) == 0
|
||||
c(i) = c(i-1);
|
||||
if robust
|
||||
lbound(i) = lbound(i-1);
|
||||
rbound(i) = rbound(i-1);
|
||||
end
|
||||
continue;
|
||||
end
|
||||
|
||||
% Find nearest neighbours
|
||||
idx = iKNearestNeighbours( span, i, x, ~ynan );
|
||||
if robust
|
||||
% Need to store neighborhoods for robust loop
|
||||
lbound(i) = min(idx);
|
||||
rbound(i) = max(idx);
|
||||
end
|
||||
|
||||
if isempty(idx)
|
||||
c(i) = NaN;
|
||||
continue
|
||||
end
|
||||
|
||||
x1 = x(idx)-x(i); % center around current point to improve conditioning
|
||||
d1 = abs(x1);
|
||||
y1 = y(idx);
|
||||
|
||||
weight = iTricubeWeights( d1 );
|
||||
if all(weight<seps)
|
||||
weight(:) = 1; % if all weights are 0, just skip weighting
|
||||
end
|
||||
|
||||
v = [ones(size(x1)) x1];
|
||||
if useLoess
|
||||
v = [v x1.*x1]; %#ok<AGROW> There is no significant growth here
|
||||
end
|
||||
|
||||
v = weight(:,ones(1,size(v,2))).*v;
|
||||
y1 = weight.*y1;
|
||||
if size(v,1)==size(v,2)
|
||||
% Square v may give infs in the \ solution, so force least squares
|
||||
b = [v;zeros(1,size(v,2))]\[y1;0];
|
||||
else
|
||||
b = v\y1;
|
||||
end
|
||||
c(i) = b(1);
|
||||
end
|
||||
end
|
||||
|
||||
% now that we have a non-robust fit, we can compute the residual and do
|
||||
% the robust fit if required
|
||||
maxabsyXeps = max(abs(y))*eps;
|
||||
if robust
|
||||
for k = 1:iter
|
||||
r = y-c;
|
||||
|
||||
% Compute robust weights
|
||||
rweight = iBisquareWeights( r, maxabsyXeps );
|
||||
|
||||
% Find new value for each point.
|
||||
for i=1:n
|
||||
if i>1 && x(i)==x(i-1)
|
||||
c(i) = c(i-1);
|
||||
continue;
|
||||
end
|
||||
if isnan(c(i)),
|
||||
continue;
|
||||
end
|
||||
|
||||
idx = lbound(i):rbound(i);
|
||||
if anyNans
|
||||
idx = idx(~ynan(idx));
|
||||
end
|
||||
% check robust weights for removed points
|
||||
if any( rweight(idx) <= 0 )
|
||||
idx = iKNearestNeighbours( span, i, x, (rweight > 0) );
|
||||
end
|
||||
|
||||
x1 = x(idx) - x(i);
|
||||
d1 = abs(x1);
|
||||
y1 = y(idx);
|
||||
|
||||
weight = iTricubeWeights( d1 );
|
||||
if all(weight<seps)
|
||||
weight(:) = 1; % if all weights 0, just skip weighting
|
||||
end
|
||||
|
||||
v = [ones(size(x1)) x1];
|
||||
if useLoess
|
||||
v = [v x1.*x1]; %#ok<AGROW> There is no significant growth here
|
||||
end
|
||||
|
||||
% Modify the weights based on x values by multiplying them by
|
||||
% robust weights.
|
||||
weight = weight.*rweight(idx);
|
||||
|
||||
v = weight(:,ones(1,size(v,2))).*v;
|
||||
y1 = weight.*y1;
|
||||
if size(v,1)==size(v,2)
|
||||
% Square v may give infs in the \ solution, so force least squares
|
||||
b = [v;zeros(1,size(v,2))]\[y1;0];
|
||||
else
|
||||
b = v\y1;
|
||||
end
|
||||
c(i) = b(1);
|
||||
end
|
||||
end
|
||||
end
|
||||
%--------------------------------------------------------------------
|
||||
function c=sgolay(x,y,f,k)
|
||||
% savitziki-golay smooth
|
||||
% (x,y) are given data. f is the frame length to be taken, should
|
||||
% be an odd number. k is the degree of polynomial filter. It should
|
||||
% be less than f.
|
||||
|
||||
% Reference: Orfanidis, S.J., Introduction to Signal Processing,
|
||||
% Prentice-Hall, Englewood Cliffs, NJ, 1996.
|
||||
|
||||
n = length(x);
|
||||
f = floor(f);
|
||||
f = min(f,n);
|
||||
f = f-mod(f-1,2); % will subtract 1 if frame is even.
|
||||
diffx = diff(x);
|
||||
notnan = ~isnan(y);
|
||||
nomissing = all(notnan);
|
||||
if f <= k && all(diffx>0) && nomissing, c = y; return; end
|
||||
hf = (f-1)/2; % half frame length
|
||||
|
||||
idx = 1:n;
|
||||
if any(diffx<0) % make sure x is monotonically increasing
|
||||
[x,idx]=sort(x);
|
||||
y = y(idx);
|
||||
notnan = notnan(idx);
|
||||
diffx = diff(x);
|
||||
end
|
||||
% note that x is sorted so max(abs(x)) must be abs(x(1)) or abs(x(end));
|
||||
% already calculated diffx for monotonic case, so use it again. Only
|
||||
% recalculate if we sort x.
|
||||
if nomissing && uniformx(diffx,x,y)
|
||||
v = ones(f,k+1);
|
||||
t=(-hf:hf)';
|
||||
for i=1:k
|
||||
v(:,i+1)=t.^i;
|
||||
end
|
||||
[q,~]=qr(v,0);
|
||||
ymid = filter(q*q(hf+1,:)',1,y);
|
||||
ybegin = q(1:hf,:)*q'*y(1:f);
|
||||
yend = q((hf+2):end,:)*q'*y(n-f+1:n);
|
||||
c = [ybegin;ymid(f:end);yend];
|
||||
return;
|
||||
end
|
||||
|
||||
% non-uniformly distributed data
|
||||
c = y;
|
||||
|
||||
% Turn off warnings when called from command line (already off if called from
|
||||
% cftool).
|
||||
ws = warning('off', 'all');
|
||||
[lastwarnmsg,lastwarnid]=lastwarn;
|
||||
|
||||
for i = 1:n
|
||||
if i>1 && x(i)==x(i-1)
|
||||
c(i) = c(i-1);
|
||||
continue
|
||||
end
|
||||
L = i; R = i; % find leftmost and rightmost values
|
||||
while(R<n && x(R+1)==x(i))
|
||||
R = R+1;
|
||||
end
|
||||
while(L>1 && x(L-1)==x(i))
|
||||
L = L-1;
|
||||
end
|
||||
HF = ceil(max(0,(f - (R-L+1))/2)); % need this many more on each side
|
||||
|
||||
L = min(n-f+1,max(1,L-HF)); % find leftmost point needed
|
||||
while(L>1 && x(L)==x(L-1))
|
||||
L = L-1;
|
||||
end
|
||||
R = min(n,max(R+HF,L+f-1)); % find rightmost point needed
|
||||
while(R<n && x(R)==x(R+1))
|
||||
R = R+1;
|
||||
end
|
||||
|
||||
tidx = L:R;
|
||||
tidx = tidx(notnan(tidx));
|
||||
if isempty(tidx)
|
||||
c(i) = NaN;
|
||||
continue;
|
||||
end
|
||||
q = x(tidx) - x(i); % center to improve conditioning
|
||||
vrank = 1 + sum(diff(q)>0);
|
||||
ncols = min(k+1, vrank);
|
||||
v = ones(length(q),ncols,'like',q);
|
||||
for j = 1:ncols-1
|
||||
v(:,j+1) = q.^j;
|
||||
end
|
||||
if size(v,1)==size(v,2)
|
||||
% Square v may give infs in the \ solution, so force least squares
|
||||
d = [v;zeros(1,size(v,2))]\[y(tidx);0];
|
||||
else
|
||||
d = v\y(tidx);
|
||||
end
|
||||
c(i) = d(1);
|
||||
end
|
||||
c(idx) = c;
|
||||
|
||||
lastwarn(lastwarnmsg,lastwarnid);
|
||||
warning(ws);
|
||||
%--------------------------------------------------------------------
|
||||
function ys = unifloess(y,span,useLoess)
|
||||
%UNIFLOESS Apply loess on uniformly spaced X values
|
||||
|
||||
y = y(:);
|
||||
|
||||
% Omit points at the extremes, which have zero weight
|
||||
halfw = (span-1)/2; % halfwidth of entire span
|
||||
d = abs((1-halfw:halfw-1)); % distances to pts with nonzero weight
|
||||
dmax = halfw; % max distance for tri-cubic weight
|
||||
|
||||
% Set up weighted Vandermonde matrix using equally spaced X values
|
||||
x1 = (2:span-1)-(halfw+1);
|
||||
weight = (1 - (d/dmax).^3).^1.5; % tri-cubic weight
|
||||
v = [ones(length(x1),1) x1(:)];
|
||||
if useLoess
|
||||
v = [v x1(:).^2];
|
||||
end
|
||||
V = v .* repmat(weight',1,size(v,2));
|
||||
|
||||
% Do QR decomposition
|
||||
[Q,~] = qr(V,0);
|
||||
|
||||
% The projection matrix is Q*Q'. We want to project onto the middle
|
||||
% point, so we can take just one row of the first factor.
|
||||
alpha = Q(halfw,:)*Q';
|
||||
|
||||
% This alpha defines the linear combination of the weighted y values that
|
||||
% yields the desired smooth values. Incorporate the weights into the
|
||||
% coefficients of the linear combination, then apply filter.
|
||||
alpha = alpha .* weight;
|
||||
ys = filter(alpha,1,y);
|
||||
|
||||
% We need to slide the values into the center of the array.
|
||||
ys(halfw+1:end-halfw) = ys(span-1:end-1);
|
||||
|
||||
% Now we have taken care of everything except the end effects. Loop over
|
||||
% the points where we don't have a complete span. Now the Vandermonde
|
||||
% matrix has span-1 points, because only 1 has zero weight.
|
||||
x1 = 1:span-1;
|
||||
v = [ones(length(x1),1) x1(:)];
|
||||
if useLoess
|
||||
v = [v x1(:).^2];
|
||||
end
|
||||
for j=1:halfw
|
||||
% Compute weights based on deviations from the jth point,
|
||||
% then compute weights and apply them as above.
|
||||
d = abs((1:span-1) - j);
|
||||
weight = (1 - (d/(span-j)).^3).^1.5;
|
||||
V = v .* repmat(weight(:),1,size(v,2));
|
||||
[Q,~] = qr(V,0);
|
||||
alpha = Q(j,:)*Q';
|
||||
alpha = alpha .* weight;
|
||||
ys(j) = alpha * y(1:span-1);
|
||||
|
||||
% These coefficients can be applied to the other end as well
|
||||
ys(end+1-j) = alpha * y(end:-1:end-span+2);
|
||||
end
|
||||
%--------------------------------------------------------------------
|
||||
function isuniform = uniformx(diffx,x,y)
|
||||
%ISUNIFORM True if x is of the form a:b:c
|
||||
|
||||
if any(isnan(y)) || any(isnan(x))
|
||||
isuniform = false;
|
||||
else
|
||||
isuniform = all(abs(diff(diffx)) <= eps*max(abs([x(1),x(end)])));
|
||||
end
|
||||
%--------------------------------------------------------------------
|
||||
function idx = iKNearestNeighbours( k, i, x, in )
|
||||
% Find the k points from x(in) closest to x(i)
|
||||
|
||||
if nnz( in ) <= k
|
||||
% If we have k points or fewer, then return them all
|
||||
idx = find( in );
|
||||
else
|
||||
% Find the distance to the k closest point
|
||||
d = abs( x - x(i) );
|
||||
ds = sort( d(in) );
|
||||
dk = ds(k);
|
||||
|
||||
% Find all points that are as close as or closer than the k closest point
|
||||
close = (d <= dk);
|
||||
|
||||
% The required indices are those points that are both close and "in"
|
||||
idx = find( close & in );
|
||||
end
|
||||
%--------------------------------------------------------------------
|
||||
% Bi-square (robust) weight function
|
||||
function delta = iBisquareWeights( r, myeps )
|
||||
% Convert residuals to weights using the bi-square weight function.
|
||||
% NOTE that this function returns the square root of the weights
|
||||
|
||||
% Only use non-NaN residuals to compute median
|
||||
idx = ~isnan( r );
|
||||
% And bound the median away from zero
|
||||
s = max( 1e8 * myeps, median( abs( r(idx) ) ) );
|
||||
% Covert the residuals to weights
|
||||
delta = iBisquare( r/(6*s) );
|
||||
% Everything with NaN residual should have zero weight
|
||||
delta(~idx) = 0;
|
||||
function b = iBisquare( x )
|
||||
% This is this bi-square function defined at the top of the left hand
|
||||
% column of page 831 in [C79]
|
||||
% NOTE that this function returns the square root of the weights
|
||||
b = zeros( size( x ) , 'like', x);
|
||||
idx = abs( x ) < 1;
|
||||
b(idx) = abs( 1 - x(idx).^2 );
|
||||
%--------------------------------------------------------------------
|
||||
% Tri-cubic weight function
|
||||
function w = iTricubeWeights( d )
|
||||
% Convert distances into weights using tri-cubic weight function.
|
||||
% NOTE that this function returns the square-root of the weights.
|
||||
%
|
||||
% Protect against divide-by-zero. This can happen if more points than the span
|
||||
% are coincident.
|
||||
maxD = max( d );
|
||||
if maxD > 0
|
||||
d = d/max( d );
|
||||
end
|
||||
w = (1 - d.^3).^1.5;
|
||||
@@ -0,0 +1,677 @@
|
||||
% tomo_quantitative.m
|
||||
import plotting.franzmap
|
||||
|
||||
matlab_tomo_path='/mnt/das-gpfs/work/p16167/matlab_new/tomo/';
|
||||
cd(matlab_tomo_path)
|
||||
addpath([matlab_tomo_path 'utils'])
|
||||
return
|
||||
|
||||
|
||||
%% Constants:
|
||||
|
||||
scrsz = get(0,'ScreenSize');
|
||||
tomo_folder='tomo_S03041_to_S04042_500x500_run_1_c';
|
||||
tomo_path_read= ['/sls/X12SA/Data20/e16167/analysis_tomo/' tomo_folder '/'];
|
||||
tomo_file_name='tomogram_delta_S03041_S04042_Hann_freqscl_1.00.mat';
|
||||
|
||||
%% Read tomographic reconstruction:
|
||||
|
||||
load([tomo_path_read tomo_file_name]);
|
||||
tomo_path_write= sprintf('/mnt/das-gpfs/work/p16167/analysis_tomo_offline/%s/quantitative_%s_%4.2f/',tomo_folder,filter_type,freq_scale);
|
||||
|
||||
%% Make histogram of whole sample
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%Choose parameters
|
||||
sam=1000; % Number of bins in histogram
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% Remove data ouside computed tomogram
|
||||
N = size(tomogram_delta,1);
|
||||
xt = [-N/2:N/2-1];
|
||||
[Xt Yt] = meshgrid(xt,xt);
|
||||
circulo = 1-radtap(Xt,Yt,10,N/2-3);
|
||||
cylinder=repmat(circulo,[1 1 size(tomogram_delta,3)]);
|
||||
data=tomogram_delta.*cylinder;
|
||||
|
||||
% Calculate whole histogram
|
||||
M=size(data,1)*size(data,2)*size(data,3);
|
||||
data_long=reshape(data,M,1);
|
||||
cylinder_long=reshape(cylinder,M,1);
|
||||
data_nozeros=data_long(cylinder_long == 1);
|
||||
[hst,bins]=hist(data_nozeros,sam);
|
||||
|
||||
clear circulo
|
||||
clear cylinder
|
||||
clear tomogram_delta
|
||||
|
||||
%% Plot histogram
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%Choose parameters
|
||||
quant='eden'; % Choose quantity to plot: 'delta' for delta or 'eden' for electron density
|
||||
yaxis='log'; % Y axis can be linear ('lin') or logaritmic ('log')
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
figure(1);
|
||||
|
||||
if isstr(quant)&&strcmpi('eden',quant)
|
||||
bins_plot=bins*factor_edensity;
|
||||
xaxis_label='electron density (A^{-3})';
|
||||
elseif isstr(quant)&&strcmpi('delta',quant)
|
||||
bins_plot=bins;
|
||||
xaxis_label='delta';
|
||||
else
|
||||
error('Supported strings for quant are delta or eden')
|
||||
end
|
||||
|
||||
if isstr(yaxis)&&strcmpi('lin',yaxis)
|
||||
plot(bins_plot,hst); xlabel(xaxis_label); ylabel('number of voxels');
|
||||
elseif isstr(yaxis)&&strcmpi('log',yaxis)
|
||||
semilogy(bins_plot,hst); xlabel(xaxis_label); ylabel('number of voxels');
|
||||
else
|
||||
error('Supported strings for yaxis are lin or log')
|
||||
end
|
||||
|
||||
%% Save histogram data
|
||||
|
||||
savedata=0; % Equal to 1 for saving data, or 0 for not saving
|
||||
|
||||
if savedata
|
||||
fid=fopen([tomo_path_write sprintf('histogram_%s.txt',tomo_folder)],'w');
|
||||
fprintf(fid, '# delta \t electron density (Angtrom-3) \t number of voxels\n');
|
||||
for hh=1:length(bins)
|
||||
fprintf(fid, '%e \t %e \t %e\n', bins(hh),factor_edensity*bins(hh),hst(hh));
|
||||
end
|
||||
fclose(fid)
|
||||
|
||||
save(sprintf('%shistogram_%s.mat',tomo_path_write,tomo_folder),'bins','factor_edensity','hst','tomo_path_read');
|
||||
|
||||
print('-f1','-depsc2', [ tomo_path_write sprintf('histogram_%s.eps',tomo_folder)]);
|
||||
print('-f1','-dpng', [ tomo_path_write sprintf('histogram_%s.png',tomo_folder)]);
|
||||
|
||||
end
|
||||
|
||||
|
||||
%% Plot slices to navigate in 3D data (with color lines)
|
||||
|
||||
%Choose parameters %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
analysis_case='cell1_nucleolus'; % please chose a different name for different slected volumes to save data in separate folders
|
||||
quant='eden'; % choose quantity to plot: 'delta' for delta or 'eden' for electron density
|
||||
scl=[0.25 0.45]; % color scale can be 'auto' for automatic or e.g. [0.25 0.45]
|
||||
valz=80; % z coordinate to select slice in xy plane
|
||||
valx=797; % x coordinate to select slice in yz plane
|
||||
valy=795; % y coordinate to select slice in xz plane
|
||||
sidex=20; % box size in x for volume of interest
|
||||
sidey=20; % box size in y for volume of interest
|
||||
sidez=20; % box size in z for volume of interest
|
||||
colorx='r';
|
||||
colory='b';
|
||||
colorz='g';
|
||||
color_map='jet';
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
xs=valx-round(sidex/2);
|
||||
xf=valx+round(sidex/2);
|
||||
ys=valy-round(sidey/2);
|
||||
yf=valy+round(sidey/2);
|
||||
zs=valz-round(sidez/2);
|
||||
zf=valz+round(sidez/2);
|
||||
|
||||
if isstr(quant)&&strcmpi('eden',quant)
|
||||
data_corr=data*factor_edensity;
|
||||
xaxis_label='electron density (A^{-3})';
|
||||
elseif isstr(quant)&&strcmpi('delta',quant)
|
||||
data_corr=data;
|
||||
xaxis_label='delta';
|
||||
else
|
||||
error('Supported strings for quant are delta or eden')
|
||||
end
|
||||
|
||||
if isstr(scl)&&strcmpi('auto',scl)
|
||||
scale=[min(data_corr(:)) max(data_corr(:))];
|
||||
else
|
||||
scale=scl;
|
||||
end
|
||||
|
||||
figure(2);
|
||||
%figure('Position',[1,400,800,800]);
|
||||
subplot(2,2,3);
|
||||
imagesc(data_corr(:,:,valz), scale); axis xy equal tight;
|
||||
xlabel('x'); ylabel('y')
|
||||
title(sprintf('z = %d',valz)); colormap bone(256); hold on;
|
||||
plot([valx,valx],[1,size(data_corr,1)],colorx);
|
||||
plot([1,size(data_corr,2)],[valy,valy],colory);
|
||||
plot([1,size(data_corr,2)],[1,1],colorz,'Linewidth',3);
|
||||
plot([1,size(data_corr,2)],[size(data_corr,1),size(data_corr,1)],colorz,'Linewidth',3);
|
||||
plot([1,1],[1,size(data_corr,1)],colorz,'Linewidth',3);
|
||||
plot([size(data_corr,2),size(data_corr,2)],[1,size(data_corr,1)],colorz,'Linewidth',3);
|
||||
plot([xs,xf],[ys,ys],colorz);
|
||||
plot([xs,xf],[yf,yf],colorz);
|
||||
plot([xs,xs],[ys,yf],colorz);
|
||||
plot([xf,xf],[ys,yf],colorz);
|
||||
hold off;
|
||||
|
||||
subplot(2,2,4);
|
||||
imageyz=(squeeze(data_corr(:,valx,:)));
|
||||
imagesc(imageyz, scale); axis xy equal tight; colorbar;
|
||||
xlabel('z'); ylabel('y');
|
||||
title(sprintf('x = %d',valx)); colormap bone(256); hold on;
|
||||
plot([valz,valz],[1,size(data_corr,1)],colorz);
|
||||
plot([1,size(data_corr,3)],[valy,valy],colory);
|
||||
plot([1,size(data_corr,3)],[1,1],colorx,'Linewidth',3);
|
||||
plot([1,size(data_corr,3)],[size(data_corr,1),size(data_corr,1)],colorx,'Linewidth',3);
|
||||
plot([1,1],[1,size(data_corr,1)],colorx,'Linewidth',3);
|
||||
plot([size(data_corr,3),size(data_corr,3)],[1,size(data_corr,1)],colorx,'Linewidth',3);
|
||||
plot([zs,zf],[ys,ys],colorx);
|
||||
plot([zs,zf],[yf,yf],colorx);
|
||||
plot([zs,zs],[ys,yf],colorx);
|
||||
plot([zf,zf],[ys,yf],colorx);
|
||||
hold off;
|
||||
|
||||
subplot(2,2,1);
|
||||
imagexz=(squeeze(data_corr(valy,:,:)))';
|
||||
imagesc(imagexz, scale); axis xy equal tight;
|
||||
xlabel('x'); ylabel('z');
|
||||
title(sprintf('y = %d',valy)); colormap bone(256); hold on;
|
||||
plot([valx,valx],[1,size(data_corr,3)],colorx);
|
||||
plot([1,size(data_corr,2)],[valz,valz],colorz);
|
||||
plot([1,size(data_corr,2)],[1,1],colory,'Linewidth',3);
|
||||
plot([1,size(data_corr,2)],[size(data_corr,3),size(data_corr,3)],colory,'Linewidth',3);
|
||||
plot([1,1],[1,size(data_corr,3)],colory,'Linewidth',3);
|
||||
plot([size(data_corr,2),size(data_corr,2)],[1,size(data_corr,3)],colory,'Linewidth',3);
|
||||
plot([xs,xf],[zs,zs],colory);
|
||||
plot([xs,xf],[zf,zf],colory);
|
||||
plot([xs,xs],[zs,zf],colory);
|
||||
plot([xf,xf],[zs,zf],colory);
|
||||
hold off;
|
||||
set(gcf,'Outerposition',[1 5 800 800])
|
||||
|
||||
%% Histogram of selected voi
|
||||
|
||||
% Choose parameters %%%%%%%%%%%%%%%%
|
||||
sampling_sel=50; % Number of bins in histogram
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
data_sel=data_corr(ys:yf,xs:xf,zs:zf);
|
||||
|
||||
figure(3);
|
||||
%figure('Position',[1,400,800,800]);
|
||||
subplot(2,2,3);
|
||||
imagesc(data_sel(:,:,round((zf-zs)/2)), scale); axis xy equal tight;
|
||||
xlabel('x'); ylabel('y')
|
||||
title(sprintf('z = %d',valz)); colormap bone(256); hold on;
|
||||
hold off;
|
||||
|
||||
subplot(2,2,4);
|
||||
imagesc(squeeze(data_sel(:,round((xf-xs)/2),:)), scale); axis xy equal tight;
|
||||
xlabel('z'); ylabel('y');
|
||||
title(sprintf('x = %d',valx)); colormap bone(256); hold on;
|
||||
hold off;
|
||||
|
||||
subplot(2,2,1);
|
||||
imagesc(squeeze(data_sel(round((yf-ys)/2),:,:))', scale); axis xy equal tight;
|
||||
xlabel('x'); ylabel('z');
|
||||
title(sprintf('y = %d',valy)); colormap bone(256); hold on;
|
||||
hold off;
|
||||
|
||||
M_sel=size(data_sel,1)*size(data_sel,2)*size(data_sel,3);
|
||||
data_sel_long=reshape(data_sel,M_sel,1);
|
||||
[hst_sel,bins_sel]=hist(data_sel_long,sampling_sel);
|
||||
|
||||
figure(4)
|
||||
plot(bins_sel, hst_sel)
|
||||
xlabel(xaxis_label)
|
||||
ylabel('number of voxels')
|
||||
title('histogram of VOI')
|
||||
|
||||
%% Make individual plots without lines
|
||||
|
||||
x=((1:size(data_corr,2))-round(size(data_corr,2))/2)*pixsize*1e6; % [microns]
|
||||
y=((1:size(data_corr,1))-round(size(data_corr,1))/2)*pixsize*1e6; % [microns]
|
||||
z=((1:size(data_corr,3))-round(size(data_corr,3))/2)*pixsize*1e6; % [microns]
|
||||
|
||||
figure(5)
|
||||
imagexz=(squeeze(data_corr(valy,:,:)))';
|
||||
imagesc(x,z,imagexz, scale); axis xy equal tight;
|
||||
xlabel('x (microns)'); ylabel('z (microns)');
|
||||
title(sprintf('electron density [e/A^3]; y = %d',valy)); colormap bone(256);
|
||||
colorbar;
|
||||
|
||||
figure(6)
|
||||
imageyz=(squeeze(data_corr(:,valx,:)))';
|
||||
imagesc(y,z,imageyz, scale); axis xy equal tight; colorbar;
|
||||
xlabel('y (microns)'); ylabel('z (microns)');
|
||||
title(sprintf('electron density [e/A^3]; x = %d',valx)); colormap bone(256);
|
||||
colorbar;
|
||||
|
||||
figure(7)
|
||||
imagesc(x,y,data_corr(:,:,valz), scale); axis xy equal tight;
|
||||
title(sprintf('electron density [e/A^3]; z = %d',valz)); colormap bone(256);
|
||||
xlabel('x (microns)'); ylabel('y (microns)');
|
||||
colorbar
|
||||
|
||||
%% Fit histogram peak to Gaussian curve
|
||||
|
||||
fit_type='gauss2'; % try 'gauss1' for one peak and 'gauss2' for a double peak fit
|
||||
|
||||
f = fit(bins_sel.',hst_sel.',fit_type)
|
||||
figure(8)
|
||||
plot(f,bins_sel,hst_sel)
|
||||
|
||||
value=f.b1;
|
||||
sigma=f.c1/sqrt(2);
|
||||
FWHM=2.35482*sigma;
|
||||
|
||||
if isstr(quant)&&strcmpi('eden',quant)
|
||||
display(sprintf('electron density: %f4.2 +/- %f4.2',value,sigma))
|
||||
else isstr(quant)&&strcmpi('delta',quant)
|
||||
display(sprintf('delta: %e +/- %e',value*factor_edensity,sigma*factor_edensity))
|
||||
end
|
||||
|
||||
if isstr(fit_type)&&strcmpi('gauss2',fit_type)
|
||||
value2=f.b2;
|
||||
sigma2=f.c2/sqrt(2);
|
||||
FWHM2=2.35482*sigma2;
|
||||
if isstr(quant)&&strcmpi('eden',quant)
|
||||
display(sprintf('electron density: %f4.2 +/- %f4.2',value2,sigma2))
|
||||
else isstr(quant)&&strcmpi('eden',quant)
|
||||
display(sprintf('delta: %e +/- %e',value2*factor_edensity,sigma2*factor_edensity))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
%% Estimate mass density
|
||||
% Choose parameters %%%%%%%%%%%%%%%%%%%
|
||||
AZ_ratio=1.85; % Estimation of molar mass (g/mol)
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
NA=6.022e23; %[mol-1]
|
||||
|
||||
if isstr(quant)&&strcmpi('eden',quant)
|
||||
mass_density=value*AZ_ratio/NA*1e24;
|
||||
mass_density_sigma=sigma*AZ_ratio/NA*1e24
|
||||
else isstr(quant)&&strcmpi('delta',quant)
|
||||
mass_density=value*factor_edensity*AZ_ratio/NA*1e24;
|
||||
mass_density_sigma=sigma*factor_edensity*AZ_ratio/NA*1e24
|
||||
end
|
||||
|
||||
if isstr(fit_type)&&strcmpi('gauss2',fit_type)
|
||||
if isstr(quant)&&strcmpi('eden',quant)
|
||||
mass_density2=value2*AZ_ratio/NA*1e24;
|
||||
mass_density_sigma2=sigma2*AZ_ratio/NA*1e24
|
||||
else isstr(quant)&&strcmpi('delta',quant)
|
||||
mass_density2=value2*factor_edensity*AZ_ratio/NA*1e24;
|
||||
mass_density_sigma2=sigma2*factor_edensity*AZ_ratio/NA*1e24
|
||||
end
|
||||
end
|
||||
|
||||
display(sprintf('mass density: %f4.2 +/- %f4.2',mass_density,mass_density_sigma))
|
||||
|
||||
if isstr(fit_type)&&strcmpi('gauss2',fit_type)
|
||||
display(sprintf('mass density: %f4.2 +/- %f4.2',mass_density2,mass_density_sigma2))
|
||||
end
|
||||
%% Save analysis
|
||||
savedata=1;
|
||||
casefolder=[tomo_path_write analysis_case '/'];
|
||||
savename=['histogram_VOI_' analysis_case];
|
||||
if savedata == 1
|
||||
if ~exist('casefolder','dir'); mkdir(casefolder); end
|
||||
print('-f2','-depsc2', [ casefolder savename '_3D_orientation_all.eps']);
|
||||
print('-f2','-dtiff', [ casefolder savename '_3D_orientation_all.tif']);
|
||||
print('-f3','-depsc2', [ casefolder savename '_3D_orientation.eps']);
|
||||
print('-f3','-dtiff', [ casefolder savename '_3D_orientation.tif']);
|
||||
print('-f4','-depsc2', [ casefolder savename '_histogram.eps']);
|
||||
print('-f4','-dtiff', [ casefolder savename '_histogram.tif']);
|
||||
print('-f5','-depsc2', [ casefolder savename '_slice_y.eps']);
|
||||
print('-f5','-dtiff', [ casefolder savename '_slice_y.tif']);
|
||||
print('-f6','-depsc2', [ casefolder savename '_slice_x.eps']);
|
||||
print('-f6','-dtiff', [ casefolder savename '_slice_x.tif']);
|
||||
print('-f7','-depsc2', [ casefolder savename '_slice_z.eps']);
|
||||
print('-f7','-dtiff', [ casefolder savename '_slice_z.tif']);
|
||||
print('-f8','-depsc2', [ casefolder savename '_Gauss_fit.eps']);
|
||||
print('-f8','-dtiff', [ casefolder savename '_Gauss_fit.tif']);
|
||||
|
||||
fid=fopen([casefolder savename 'histogram.txt'],'w');
|
||||
fprintf(fid, '# electron density (Angtrom-3) / number of voxels\n');
|
||||
for hh=1:length(bins_sel)
|
||||
fprintf(fid, '%e %e\n', bins_sel(hh),hst_sel(hh));
|
||||
end
|
||||
fclose(fid)
|
||||
|
||||
save([casefolder savename '.m'],'bins_sel','hst_sel','valx','valy',...
|
||||
'valz','sidex','sidey','sidez','analysis_case','tomo_path_read',...
|
||||
'tomo_path_write','output_folder','pixsize','sampling_sel','scale',...
|
||||
'quant','f','value','sigma','FWHM','AZ_ratio','mass_density','mass_density_sigma');
|
||||
if isstr(fit_type)&&strcmpi('gauss2',fit_type)
|
||||
save([casefolder savename '.m'],'bins_sel','hst_sel','valx','valy',...
|
||||
'valz','sidex','sidey','sidez','analysis_case','tomo_path_read',...
|
||||
'tomo_path_write','output_folder','pixsize','sampling_sel','scale',...
|
||||
'quant','f','value','sigma','FWHM','AZ_ratio','mass_density','mass_density_sigma',...
|
||||
'value2','sigma2','FWHM2','mass_density2','mass_density_sigma2');
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
%% Delete large variables
|
||||
% After this the code needs to be run from the very beginning to read the
|
||||
% full tomogram
|
||||
clear data0
|
||||
clear data_corr
|
||||
|
||||
|
||||
% %% Read amplitude data:
|
||||
%
|
||||
% % This needs to be changed for each sample:
|
||||
% filename_amp=[tomo_path 'tomogram_beta_S04693_S05999_Hann_freqscl_0.35.mat']; % tomorec
|
||||
% ampdata = load(filename_amp) ;
|
||||
% data_amp_sel=ampdata.tomogram_beta(ys:yf,xs:xf,zs:zf);
|
||||
%
|
||||
% %% Plot full amplitude slices to navigate in 3D data (with color lines)
|
||||
%
|
||||
% scale_amp=[-0.1e-6,1.3e-6];
|
||||
%
|
||||
% figure(11);
|
||||
% %figure('Position',[1,400,800,800]);
|
||||
% subplot(2,2,3);
|
||||
% imagesc(ampdata.tomogram_beta(:,:,valz), scale_amp); axis xy equal tight;
|
||||
% xlabel('x'); ylabel('y')
|
||||
% title(sprintf('z = %d',valz)); colormap bone(256); hold on;
|
||||
% plot([valx,valx],[1,size(ampdata.tomogram_beta,1)],colorx);
|
||||
% plot([1,size(ampdata.tomogram_beta,2)],[valy,valy],colory);
|
||||
% plot([1,size(ampdata.tomogram_beta,2)],[1,1],colorz,'Linewidth',3);
|
||||
% plot([1,size(ampdata.tomogram_beta,2)],[size(ampdata.tomogram_beta,1),size(ampdata.tomogram_beta,1)],colorz,'Linewidth',3);
|
||||
% plot([1,1],[1,size(ampdata.tomogram_beta,1)],colorz,'Linewidth',3);
|
||||
% plot([size(ampdata.tomogram_beta,2),size(ampdata.tomogram_beta,2)],[1,size(ampdata.tomogram_beta,1)],colorz,'Linewidth',3);
|
||||
% plot([xs,xf],[ys,ys],colorz);
|
||||
% plot([xs,xf],[yf,yf],colorz);
|
||||
% plot([xs,xs],[ys,yf],colorz);
|
||||
% plot([xf,xf],[ys,yf],colorz);
|
||||
% hold off;
|
||||
%
|
||||
% subplot(2,2,4);
|
||||
% imageyz=(squeeze(ampdata.tomogram_beta(:,valx,:)));
|
||||
% imagesc(imageyz, scale_amp); axis xy equal tight; colorbar;
|
||||
% xlabel('z'); ylabel('y');
|
||||
% title(sprintf('x = %d',valx)); colormap bone(256); hold on;
|
||||
% plot([valz,valz],[1,size(ampdata.tomogram_beta,1)],colorz);
|
||||
% plot([1,size(ampdata.tomogram_beta,3)],[valy,valy],colory);
|
||||
% plot([1,size(ampdata.tomogram_beta,3)],[1,1],colorx,'Linewidth',3);
|
||||
% plot([1,size(ampdata.tomogram_beta,3)],[size(ampdata.tomogram_beta,1),size(ampdata.tomogram_beta,1)],colorx,'Linewidth',3);
|
||||
% plot([1,1],[1,size(ampdata.tomogram_beta,1)],colorx,'Linewidth',3);
|
||||
% plot([size(ampdata.tomogram_beta,3),size(ampdata.tomogram_beta,3)],[1,size(ampdata.tomogram_beta,1)],colorx,'Linewidth',3);
|
||||
% plot([zs,zf],[ys,ys],colorx);
|
||||
% plot([zs,zf],[yf,yf],colorx);
|
||||
% plot([zs,zs],[ys,yf],colorx);
|
||||
% plot([zf,zf],[ys,yf],colorx);
|
||||
% hold off;
|
||||
%
|
||||
% subplot(2,2,1);
|
||||
% imagexz=(squeeze(ampdata.tomogram_beta(valy,:,:)))';
|
||||
% imagesc(imagexz, scale_amp); axis xy equal tight;
|
||||
% xlabel('x'); ylabel('z');
|
||||
% title(sprintf('y = %d',valy)); colormap bone(256); hold on;
|
||||
% plot([valx,valx],[1,size(ampdata.tomogram_beta,3)],colorx);
|
||||
% plot([1,size(ampdata.tomogram_beta,2)],[valz,valz],colorz);
|
||||
% plot([1,size(ampdata.tomogram_beta,2)],[1,1],colory,'Linewidth',3);
|
||||
% plot([1,size(ampdata.tomogram_beta,2)],[size(ampdata.tomogram_beta,3),size(ampdata.tomogram_beta,3)],colory,'Linewidth',3);
|
||||
% plot([1,1],[1,size(ampdata.tomogram_beta,3)],colory,'Linewidth',3);
|
||||
% plot([size(ampdata.tomogram_beta,2),size(ampdata.tomogram_beta,2)],[1,size(ampdata.tomogram_beta,3)],colory,'Linewidth',3);
|
||||
% plot([xs,xf],[zs,zs],colory);
|
||||
% plot([xs,xf],[zf,zf],colory);
|
||||
% plot([xs,xs],[zs,zf],colory);
|
||||
% plot([xf,xf],[zs,zf],colory);
|
||||
% hold off;
|
||||
% set(gcf,'Outerposition',[1 300 800 800])
|
||||
% %% Make individual plots without lines
|
||||
%
|
||||
% figure(12)
|
||||
% imagexz=(squeeze(ampdata.tomogram_beta(valy,:,:)))';
|
||||
% imagesc(x,z,imagexz, scale_amp); axis xy equal tight;
|
||||
% xlabel('x (microns)'); ylabel('z (microns)');
|
||||
% title(sprintf('electron density [e/A^3]; y = %d',valy)); colormap bone(256);
|
||||
% colorbar;
|
||||
%
|
||||
% figure(13)
|
||||
% imageyz=(squeeze(ampdata.tomogram_beta(:,valx,:)))';
|
||||
% imagesc(y,z,imageyz, scale_amp); axis xy equal tight; colorbar;
|
||||
% xlabel('y (microns)'); ylabel('z (microns)');
|
||||
% title(sprintf('electron density [e/A^3]; x = %d',valx)); colormap bone(256);
|
||||
% colorbar;
|
||||
%
|
||||
% figure(14)
|
||||
% imagesc(x,y,ampdata.tomogram_beta(:,:,valz), scale_amp); axis xy equal tight;
|
||||
% title(sprintf('electron density [e/A^3]; z = %d',valz)); colormap bone(256);
|
||||
% xlabel('x (microns)'); ylabel('y (microns)');
|
||||
% colorbar
|
||||
%
|
||||
% %% Histogram of selected amplitude voi
|
||||
% sampling_amp_sel=70;
|
||||
% scale_amp=[-0.1e-6,1.3e-6];
|
||||
%
|
||||
% figure(8);
|
||||
% %figure('Position',[1,400,800,800]);
|
||||
% subplot(2,2,3);
|
||||
% imagesc(data_amp_sel(:,:,round((zf-zs)/2)), scale_amp); axis xy equal tight;
|
||||
% xlabel('x'); ylabel('y')
|
||||
% title(sprintf('z = %d',valz)); colormap bone(256); hold on;
|
||||
% hold off;
|
||||
%
|
||||
% subplot(2,2,4);
|
||||
% imagesc(squeeze(data_amp_sel(:,round((xf-xs)/2),:)), scale_amp)
|
||||
% xlabel('z'); ylabel('y');
|
||||
% title(sprintf('x = %d',valx)); colormap bone(256); hold on;
|
||||
% hold off;
|
||||
%
|
||||
% subplot(2,2,1);
|
||||
% imagesc(squeeze(data_amp_sel(round((yf-ys)/2),:,:))', scale_amp)
|
||||
% xlabel('x'); ylabel('z');
|
||||
% title(sprintf('y = %d',valy)); colormap bone(256); hold on;
|
||||
% hold off;
|
||||
%
|
||||
% M_amp_sel=size(data_amp_sel,1)*size(data_amp_sel,2)*size(data_amp_sel,3);
|
||||
% data_amp_sel_long=reshape(data_amp_sel,M_amp_sel,1);
|
||||
% [hst_amp_sel,bins_amp_sel]=hist(data_amp_sel_long,sampling_amp_sel);
|
||||
%
|
||||
% figure(9)
|
||||
% plot(bins_amp_sel, hst_amp_sel)
|
||||
% xlabel('beta')
|
||||
% ylabel('number of voxels')
|
||||
% title('histogram of VOI')
|
||||
% %% Add path for Franzmap
|
||||
% addpath('/mnt/das-gpfs/work/p15232/matlab/');
|
||||
% %% Make bivariate histogram of voi
|
||||
%
|
||||
% bins = 256; % number of bins of the histogram
|
||||
% spacing = 'lin'; %'lin'; 'log'; % lin is better
|
||||
%
|
||||
% delta_slice=data_sel./factor_edensity;
|
||||
% abs_slice=data_amp_sel;
|
||||
%
|
||||
% % find indices corresponding to the materials phase only (exclude air)
|
||||
% % clear mask mask_ind
|
||||
% mask=data_sel>1E-6;
|
||||
% mask_ind=find(delta_slice>1E-6);
|
||||
%
|
||||
% % Reshape the images into 1D vectors
|
||||
% x=abs_slice(mask_ind);
|
||||
% y=delta_slice(mask_ind);
|
||||
%
|
||||
% clear xedges yedges
|
||||
% switch lower(spacing)
|
||||
% case 'lin'
|
||||
% % linearly spaced edges of the histogram
|
||||
% xedges = linspace(min(x),max(x)+0.11e-6,bins);
|
||||
% yedges = linspace(min(y),max(y),bins);
|
||||
% case 'log'
|
||||
% xedges = linspace(min(x),max(x),bins);
|
||||
% yedges = logspace(log10(min(y)),log10(max(y)),bins);
|
||||
% end
|
||||
%
|
||||
% % Calculate the 1D histogram
|
||||
% [xn, xbin] = histc(x,xedges);
|
||||
% [yn, ybin] = histc(y,yedges);
|
||||
%
|
||||
% %xbin, ybin zero for out of range values
|
||||
% % (see the help of histc) force this event to the
|
||||
% % first bins
|
||||
% xbin(find(xbin == 0)) = inf;
|
||||
% ybin(find(ybin == 0)) = inf;
|
||||
%
|
||||
% xnbin = length(xedges);
|
||||
% ynbin = length(yedges);
|
||||
%
|
||||
% if xnbin >= ynbin
|
||||
% xy = ybin*(xnbin) + xbin;
|
||||
% indexshift = xnbin;
|
||||
% else
|
||||
% xy = xbin*(ynbin) + ybin;
|
||||
% indexshift = ynbin;
|
||||
% end
|
||||
%
|
||||
% %[xyuni, m, n] = unique(xy);
|
||||
% xyuni = unique(xy);
|
||||
% xyuni(end) = [];
|
||||
% hstres = histc(xy,xyuni);
|
||||
% clear xy;
|
||||
%
|
||||
% histmat = zeros(ynbin,xnbin);
|
||||
% histmat(xyuni-indexshift) = hstres;
|
||||
% % %% Add path for Franzmap
|
||||
% addpath('/afs/psi.ch/project/cxs/matlab/cSAXS_matlab_base_package/');
|
||||
% %% display the bivariate histogram
|
||||
% figure(10)
|
||||
% sub1=subplot(3,3,[4,5,7,8]);
|
||||
% imagesc(xedges.*1e7, yedges.*1e5, log10(histmat')), axis xy square tight
|
||||
% xlim([0 14]);
|
||||
% ylim([0.1 2.2]);
|
||||
%
|
||||
%
|
||||
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% %%%%%% For drawing the lines %%%%
|
||||
% %lineh1= 1.0; % value in beta .*1e-5
|
||||
% %lineh2= 1.0; % value in beta .*1e-5
|
||||
% %linev1= 2.5; % value in delta .*1e-7
|
||||
% %linev2= 2.5; % value in delta .*1e-7
|
||||
% %%%%%%% end of edit %%%%%%%%%%%%%%%%
|
||||
% hold on
|
||||
% %plot([-4 12],[lineh1 lineh1],'-b')
|
||||
% %plot([-4 12],[lineh2 lineh2],'-b')
|
||||
% %plot([linev1 linev1],[0.2 2],'-b')
|
||||
% %plot([linev2 linev2],[0.2 2],'-b')
|
||||
% hold off
|
||||
%
|
||||
% thisfontsize=12;
|
||||
%
|
||||
% colormap('franzmap')
|
||||
% Contours =[1e0 1e1 1e2 1e3 1e4 1e5 1e6 1e7];
|
||||
% hColorbar = colorbar('East','YTick',log10(Contours),'YTickLabel',Contours);
|
||||
% hXLabel = xlabel('Absorption index, \beta [x 10^{-7}]');
|
||||
% hYLabel = ylabel('Refractive index decrement, \delta [x 10^{-5}] ');
|
||||
% set(gca,...
|
||||
% 'FontName' , 'Helvetica',...
|
||||
% 'FontSize' , thisfontsize ,...
|
||||
% 'Box' , 'off' ,...
|
||||
% 'OuterPosition', [0 0 0.53 0.73] ,...
|
||||
% 'TickDir' , 'out' ,...'YAxisLocation','right'
|
||||
% 'XMinorTick', 'on' ,...
|
||||
% 'YMinorTick', 'on' ,...
|
||||
% 'XColor' , [.0 .0 .0] ,...
|
||||
% 'YColor' , [.0 .0 .0] ,...
|
||||
% 'YTick' , 0:0.2:2.2 ,...
|
||||
% 'XTick' , -6:2:20 ,...
|
||||
% 'LineWidth' , 1 );
|
||||
% set([hXLabel,hYLabel],...
|
||||
% 'FontName', 'Arial',...
|
||||
% 'FontSize', thisfontsize-1 );
|
||||
% set(hColorbar,...
|
||||
% 'Box' , 'on' ,...
|
||||
% 'TickDir', 'in' ,...
|
||||
% 'Direction','normal', ...
|
||||
% 'YAxisLocation','left',...
|
||||
% 'YColor' , [0.9 0.9 0.9] ,...
|
||||
% 'XColor' , [0.9 0.9 0.9] , ...
|
||||
% 'Position',[0.47 0.11 0.03 0.3]);
|
||||
%
|
||||
% subplot(3,3,[1,2])
|
||||
% b=bar(xedges.*1e7,xn*.1e-5,1)
|
||||
% b.FaceColor='b';
|
||||
% b.EdgeColor='b';
|
||||
% axis xy tight
|
||||
% xlim([0 14]);
|
||||
% %ylim([0 4])
|
||||
% hYLabel1 = ylabel('Freq. [x 10^{6}]')
|
||||
% set(gca,...
|
||||
% 'FontName' , 'Helvetica',...
|
||||
% 'FontSize' , thisfontsize ,...
|
||||
% 'Box' , 'off' ,...
|
||||
% 'OuterPosition', [0.012 0.72 0.515 0.22], ...
|
||||
% 'TickDir' , 'out' ,...
|
||||
% 'XMinorTick', 'off' ,...
|
||||
% 'XTick' , [] ,...
|
||||
% 'XTickLabel', [] ,...
|
||||
% 'Layer' , 'top' ,...
|
||||
% 'YMinorTick', 'on' ,...
|
||||
% 'XColor' , [.0 .0 .0] ,...
|
||||
% 'YColor' , [.0 .0 .0] ,...
|
||||
% 'LineWidth' , 1 );
|
||||
% set(hYLabel1,...
|
||||
% 'FontName', 'Arial',...
|
||||
% 'FontSize', thisfontsize );
|
||||
%
|
||||
% subplot(3,3,[6,9])
|
||||
% b=barh(yedges.*1e5,yn.*1e-6,1),
|
||||
% b.FaceColor='r';
|
||||
% b.EdgeColor='r';
|
||||
% axis xy tight
|
||||
% ylim([0.1 2.2]);
|
||||
% %xlim([0 20]);
|
||||
% hXLabel1=xlabel('Freq. [x 10^{6}]')
|
||||
% set(gca,...
|
||||
% 'FontName' , 'Helvetica',...
|
||||
% 'FontSize' , thisfontsize ,...
|
||||
% 'Box' , 'off' ,...
|
||||
% 'OuterPosition', [0.534 0.0010 0.17 0.796],...
|
||||
% 'TickDir' , 'out' ,...
|
||||
% 'XAxisLocation', 'top' ,...
|
||||
% 'XMinorTick', 'off' ,...
|
||||
% 'YTick' , [] ,...
|
||||
% 'YTickLabel', [] ,...
|
||||
% 'Layer' , 'top' ,...
|
||||
% 'XMinorTick', 'on' ,...
|
||||
% 'XTick' , 0:20:150 ,...
|
||||
% 'XColor' , [.0 .0 .0] ,...
|
||||
% 'YColor' , [.0 .0 .0] ,...
|
||||
% 'LineWidth' , 1 );
|
||||
% set(hXLabel1,...
|
||||
% 'FontName', 'Arial',...
|
||||
% 'FontSize', thisfontsize );
|
||||
% % %xlim([0 10]);
|
||||
% %hXLabel = xlabel('Absorption index, \beta [x 10^{-7}]');
|
||||
% %hYLabel = ylabel('Refractive index decrement, \delta [x 10^{-5}] ');
|
||||
% set(figure(1),'OuterPosition',[402 189 874 720])
|
||||
%
|
||||
% %% Save plots with amplitude
|
||||
% savedata=1;
|
||||
% %casefolder=[histogram_path analysis_case '/'];
|
||||
% %savename=['histogram_VOI_' analysis_case];
|
||||
% if savedata == 1
|
||||
% if ~exist('casefolder','dir'); mkdir(casefolder); end
|
||||
% print('-f11','-depsc2', [ casefolder savename '_3D_orientation_all_beta.eps']);
|
||||
% print('-f11','-dtiff', [ casefolder savename '_3D_orientation_all_beta.tif']);
|
||||
% print('-f8','-depsc2', [ casefolder savename '_3D_orientation_beta.eps']);
|
||||
% print('-f8','-dtiff', [ casefolder savename '_3D_orientation_beta.tif']);
|
||||
% print('-f9','-depsc2', [ casefolder savename '_histogram_beta.eps']);
|
||||
% print('-f9','-dtiff', [ casefolder savename '_histogram_beta.tif']);
|
||||
% print('-f10','-depsc2', [ casefolder savename '_bivariate_hist.eps']);
|
||||
% print('-f10','-dtiff', [ casefolder savename '_bivariate_hist.tif']);
|
||||
% print('-f12','-depsc2', [ casefolder savename '_slice_y_beta.eps']);
|
||||
% print('-f12','-dtiff', [ casefolder savename '_slice_y_beta.tif']);
|
||||
% print('-f13','-depsc2', [ casefolder savename '_slice_x_beta.eps']);
|
||||
% print('-f13','-dtiff', [ casefolder savename '_slice_x_beta.tif']);
|
||||
% print('-f14','-depsc2', [ casefolder savename '_slice_z_beta.eps']);
|
||||
% print('-f14','-dtiff', [ casefolder savename '_slice_z_beta.tif']);
|
||||
% end
|
||||
@@ -0,0 +1,56 @@
|
||||
function w = tukeywin(n,r)
|
||||
%TUKEYWIN Tukey window.
|
||||
% TUKEYWIN(N) returns an N-point Tukey window in a column vector.
|
||||
%
|
||||
% W = TUKEYWIN(N,R) returns an N-point Tukey window in a column vector. A
|
||||
% Tukey window is also known as the cosine-tapered window. The R
|
||||
% parameter specifies the ratio of the length of taper section to the
|
||||
% total length of the window. For a Tukey window, R is normalized to 1
|
||||
% (i.e., 0 < R < 1). If omitted, R is set to 0.500.
|
||||
%
|
||||
% If R is outside the region of (0, 1), the Tukey window degenerates into
|
||||
% other common windows. Thus when R = 1, it is equivalent to a Hanning
|
||||
% window. Conversely, for R = 0 the Tukey window is equivalent to a
|
||||
% boxcar window.
|
||||
%
|
||||
% EXAMPLE:
|
||||
% N = 64;
|
||||
% w = tukeywin(N,0.5);
|
||||
% plot(w); title('64-point Tukey window, Ratio = 0.5');
|
||||
%
|
||||
% See also CHEBWIN, GAUSSWIN, KAISER, WINDOW.
|
||||
|
||||
% Reference:
|
||||
% [1] fredric j. harris [sic], On the Use of Windows for Harmonic Analysis
|
||||
% with the Discrete Fourier Transform, Proceedings of the IEEE,
|
||||
% Vol. 66, No. 1, January 1978, Page 67, Equation 38.
|
||||
|
||||
% Author(s): A. Dowd
|
||||
% Copyright 1988-2005 The MathWorks, Inc.
|
||||
|
||||
narginchk(1,2);
|
||||
|
||||
% Default value for R parameter.
|
||||
if nargin < 2 || isempty(r)
|
||||
r = 0.500;
|
||||
end
|
||||
|
||||
[n,w,trivialwin] = check_order(n);
|
||||
if trivialwin, return, end
|
||||
|
||||
if r <= 0
|
||||
w = ones(n,1);
|
||||
elseif r >= 1
|
||||
w = hann(n);
|
||||
else
|
||||
t = linspace(0,1,n)';
|
||||
% Defines period of the taper as 1/2 period of a sine wave.
|
||||
per = r/2;
|
||||
tl = floor(per*(n-1))+1;
|
||||
th = n-tl+1;
|
||||
% Window is defined in three sections: taper, constant, taper
|
||||
w = [ ((1+cos(pi/per*(t(1:tl) - per)))/2); ones(th-tl-1,1); ((1+cos(pi/per*(t(th:end) - 1 + per)))/2)];
|
||||
end
|
||||
|
||||
|
||||
% [EOF]
|
||||
@@ -0,0 +1,86 @@
|
||||
% UPLOAD_IMAGE_TO_OMNY_DATABASE upload images of the reconstruction to image gallery tomography database
|
||||
%
|
||||
% upload_image_to_OMNY_database(tomogram_delta, par)
|
||||
%
|
||||
% Inputs
|
||||
% **tomogram_delta delta tomogram
|
||||
% **par tomography parameter structure
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 upload_image_to_OMNY_database(tomogram_delta, par)
|
||||
|
||||
% save snapshots for online viewer
|
||||
plotting.smart_figure(1)
|
||||
par.displayslice = [];
|
||||
|
||||
par.displayaxis = 3;
|
||||
tomo.show_tomogram_cuts(tomogram_delta, par.scanstomo, par)
|
||||
path = sprintf('%s_xy_tomo.png',par.online_tomo_path);
|
||||
print('-f1','-djpeg','-r300',path);
|
||||
system(sprintf('convert -trim %s %s', path, path));
|
||||
system(sprintf('cp %s %s', path, sprintf('%s/preview_xy_tomo.png',par.output_folder)));
|
||||
|
||||
|
||||
par.displayaxis = 1;
|
||||
tomo.show_tomogram_cuts(tomogram_delta, par.scanstomo, par)
|
||||
path = sprintf('%s_xz_tomo.png',par.online_tomo_path);
|
||||
print('-f1','-djpeg','-r300',path);
|
||||
system(sprintf('convert -trim %s %s', path, path));
|
||||
system(sprintf('cp %s %s', path, sprintf('%s/preview_xz_tomo.png',par.output_folder)));
|
||||
|
||||
par.displayaxis = 2;
|
||||
tomo.show_tomogram_cuts(tomogram_delta, par.scanstomo, par)
|
||||
path = sprintf('%s_yz_tomo.png',par.online_tomo_path);
|
||||
print('-f1','-djpeg','-r300',path);
|
||||
system(sprintf('convert -trim %s %s', path, path));
|
||||
system(sprintf('cp %s %s', path, sprintf('%s/preview_yz_tomo.png',par.output_folder)));
|
||||
|
||||
|
||||
path = fullfile(par.output_folder,'Database_xy_tomo.png');
|
||||
print('-f1','-dpng','-r300',path);
|
||||
system(sprintf('convert -trim "%s" "%s"', path, path));
|
||||
|
||||
utils.verbose(0, 'Uploading images to OMNY database')
|
||||
|
||||
unix_cmd = sprintf('/work/sls/spec/local/XOMNY/bin/upload/upload_tomography_slice.sh %d %s',par.tomo_id, path);
|
||||
utils.verbose(0,'Uploading to database %s',path)
|
||||
fprintf('%s\n',unix_cmd)
|
||||
unix(unix_cmd);
|
||||
delete('upload.php') % remove some leftover from the upload_tomography_slice
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user