initial commit

This commit is contained in:
2026-08-07 15:56:42 +09:00
commit 91ad25aca9
1012 changed files with 159314 additions and 0 deletions
+24
View File
@@ -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
+64
View File
@@ -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
+37
View File
@@ -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
+43
View File
@@ -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
+95
View File
@@ -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
+65
View File
@@ -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
+79
View File
@@ -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.
+849
View File
@@ -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
+99
View File
@@ -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,'.-');
+44
View File
@@ -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
+28
View File
@@ -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
+95
View File
@@ -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
+103
View File
@@ -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
+301
View File
@@ -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
%}
+67
View File
@@ -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
+66
View File
@@ -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
+278
View File
@@ -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
+89
View File
@@ -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
+90
View File
@@ -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
+90
View File
@@ -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
+95
View File
@@ -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
+62
View File
@@ -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
+154
View File
@@ -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
+670
View File
@@ -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;
+677
View File
@@ -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
+56
View File
@@ -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