mirror of
https://github.com/c-sooyoung/fold_slice.git
synced 2026-09-18 00:09:10 +09:00
initial commit
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
% OMNY_get_scan_numbers( OMNY_angles_file, scannums )
|
||||
% OMNY_angles_file - File with Scan number, angle target, angle readout
|
||||
% tomo_id - Index specifying the range of scan numbers
|
||||
%
|
||||
% out - returns scan numbers for tomo_id
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 [ out ] = OMNY_get_scan_numbers( OMNY_angles_file, tomo_id )
|
||||
|
||||
fid = fopen(OMNY_angles_file);
|
||||
|
||||
ln = fgetl(fid);
|
||||
if numel(strsplit(ln, ' '))<=6
|
||||
error('OMNY file does contain tomo_ids')
|
||||
end
|
||||
|
||||
outmat = textscan(fid,'%f %f %f %f %f %f %s');
|
||||
fclose(fid);
|
||||
|
||||
|
||||
ind = find(outmat{4}==tomo_id);
|
||||
out = outmat{1}(ind);
|
||||
out = out';
|
||||
|
||||
end
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,229 @@
|
||||
% Call function without arguments for a detailed explanation of its use
|
||||
|
||||
% Filename: $RCSfile: beamstop_mask.m,v $
|
||||
%
|
||||
% $Revision: 1.8 $ $Date: 2011/08/23 17:17:53 $
|
||||
% $Author: $
|
||||
% $Tag: $
|
||||
%
|
||||
% Description:
|
||||
% remove a polygonic region from the valid pixel mask
|
||||
%
|
||||
% Note:
|
||||
% This is a template. The coordinates of the polygon have to be manually
|
||||
% edited.
|
||||
% Call without arguments for a brief help text.
|
||||
%
|
||||
% Dependencies:
|
||||
% - image_read
|
||||
%
|
||||
% history:
|
||||
%
|
||||
% May 19th 2010:
|
||||
% add XyCoord and xCoord, yCoord command line parameters
|
||||
%
|
||||
% May 9th 2008: 1st documented version
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| Except where otherwise noted, this work is licensed under a |
|
||||
%| Creative Commons Attribution-NonCommercial-ShareAlike 4.0 |
|
||||
%| International (CC BY-NC-SA 4.0) license. |
|
||||
%| |
|
||||
%| Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch) |
|
||||
%| |
|
||||
%| Author: CXS group, PSI |
|
||||
%*-----------------------------------------------------------------------*
|
||||
% You may use this code with the following provisions:
|
||||
%
|
||||
% If the code is fully or partially redistributed, or rewritten in another
|
||||
% computing language this notice should be included in the redistribution.
|
||||
%
|
||||
% If this code, or subfunctions or parts of it, is used for research in a
|
||||
% publication or if it is fully or partially rewritten for another
|
||||
% computing language the authors and institution should be acknowledged
|
||||
% in written form in the publication: “Data processing was carried out
|
||||
% using the “cSAXS matlab package” developed by the CXS group,
|
||||
% Paul Scherrer Institut, Switzerland.”
|
||||
% Variations on the latter text can be incorporated upon discussion with
|
||||
% the CXS group if needed to more specifically reflect the use of the package
|
||||
% for the published work.
|
||||
%
|
||||
% A publication that focuses on describing features, or parameters, that
|
||||
% are already existing in the code should be first discussed with the
|
||||
% authors.
|
||||
%
|
||||
% This code and subroutines are part of a continuous development, they
|
||||
% are provided “as they are” without guarantees or liability on part
|
||||
% of PSI or the authors. It is the user responsibility to ensure its
|
||||
% proper use and the correctness of the results.
|
||||
|
||||
function [ bmask_ind ] = beamstop_mask(filename,varargin)
|
||||
import beamline.pilatus_valid_pixel_roi
|
||||
import beamline.prep_valid_mask
|
||||
import io.image_read
|
||||
import plotting.display_valid_mask
|
||||
|
||||
% set default values for the variable input arguments:
|
||||
% valid pixel mask
|
||||
filename_valid_mask = '~/Data10/analysis/data/pilatus_valid_mask.mat';
|
||||
% do not update the valid pixel mask
|
||||
save_data = 0;
|
||||
% figure number for display
|
||||
fig_no = 220;
|
||||
% mask corners
|
||||
xy_coord = []; %#ok<NASGU>
|
||||
x_coord = [];
|
||||
y_coord = [];
|
||||
|
||||
% check minimum number of input arguments
|
||||
if (nargin < 1)
|
||||
display_help(filename_valid_mask,save_data,fig_no);
|
||||
error('At least the filename has to be specified as input parameter.');
|
||||
end
|
||||
|
||||
% accept cell array with name/value pairs as well
|
||||
no_of_in_arg = nargin;
|
||||
if (nargin == 2)
|
||||
if (isempty(varargin))
|
||||
% ignore empty cell array
|
||||
no_of_in_arg = no_of_in_arg -1;
|
||||
else
|
||||
if (iscell(varargin{1}))
|
||||
% use a filled one given as first and only variable parameter
|
||||
varargin = varargin{1};
|
||||
no_of_in_arg = 1 + length(varargin);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% check number of input arguments
|
||||
if (rem(no_of_in_arg,2) ~= 1)
|
||||
display_help(filename_valid_mask,save_data,fig_no);
|
||||
error('The optional parameters have to be specified as ''name'',''value'' pairs');
|
||||
end
|
||||
|
||||
|
||||
% parse the variable input arguments
|
||||
vararg_remain = cell(0,0);
|
||||
for ind = 1:2:length(varargin)
|
||||
name = varargin{ind};
|
||||
value = varargin{ind+1};
|
||||
switch name
|
||||
case 'SaveData'
|
||||
save_data = value;
|
||||
case 'FilenameValidMask'
|
||||
filename_valid_mask = value;
|
||||
case 'xyCoord'
|
||||
xy_coord = value;
|
||||
x_coord = xy_coord(:,1);
|
||||
y_coord = xy_coord(:,2);
|
||||
case 'xCoord'
|
||||
x_coord = value;
|
||||
case 'yCoord'
|
||||
y_coord = value;
|
||||
otherwise
|
||||
vararg_remain{end+1} = name; %#ok<AGROW>
|
||||
vararg_remain{end+1} = value; %#ok<AGROW>
|
||||
end
|
||||
end
|
||||
|
||||
% read file for test display
|
||||
frame = image_read(filename,vararg_remain);
|
||||
frame.data = double(frame.data);
|
||||
dimensions = size(frame.data);
|
||||
if (numel(dimensions) > 2)
|
||||
frame.data = mean(frame.data,3);
|
||||
dimensions = size(frame.data);
|
||||
end
|
||||
|
||||
% get indices to pixels within beam stop
|
||||
if ((isempty(x_coord)) || (isempty(y_coord)))
|
||||
bmask_ind = 1:(dimensions(1)*dimensions(2));
|
||||
else
|
||||
[bmask] = uint8(1 - roipoly( dimensions(1), dimensions(2), x_coord, y_coord ));
|
||||
bmask_ind = find(bmask == 0);
|
||||
end
|
||||
|
||||
% plot the result
|
||||
figure(5);
|
||||
frame_plot = frame.data;
|
||||
frame_plot(frame_plot < 1) = 1;
|
||||
% plot the masked region with lower intensity
|
||||
frame_plot(bmask_ind) = 0.1 * frame_plot(bmask_ind);
|
||||
imagesc(log10(frame_plot));
|
||||
axis xy;
|
||||
axis equal;
|
||||
axis tight;
|
||||
colorbar;
|
||||
title('beamstop mask shape');
|
||||
|
||||
% show the current valid pixel mask
|
||||
display_valid_mask('FilenameValidMask',filename_valid_mask,'FigNo',fig_no+1,...
|
||||
'NoHelp',1);
|
||||
title('current valid pixel mask');
|
||||
|
||||
% load ind_valid, the indices of the valid pixels
|
||||
fprintf('loading %s\n',filename_valid_mask);
|
||||
load(filename_valid_mask);
|
||||
% cut out the current region of interest
|
||||
valid_mask = pilatus_valid_pixel_roi(valid_mask,'RoiSize',size(frame.data));
|
||||
|
||||
% remove beam-stop pixels from it
|
||||
valid_mask.indices = setdiff(valid_mask.indices,bmask_ind); %#ok<NODEF>
|
||||
|
||||
if (save_data)
|
||||
% create a backup of the mask
|
||||
if (exist(filename_valid_mask,'file'))
|
||||
filename_valid_mask_backup = [ filename_valid_mask '.bak' ];
|
||||
fprintf('Copying the current mask %s to %s\n',filename_valid_mask,...
|
||||
filename_valid_mask_backup);
|
||||
copyfile(filename_valid_mask,filename_valid_mask_backup);
|
||||
end
|
||||
|
||||
% save the updated mask
|
||||
fprintf('saving updated mask %s\n',filename_valid_mask);
|
||||
save(filename_valid_mask,'valid_mask');
|
||||
|
||||
% display the new mask
|
||||
display_valid_mask('FilenameValidMask',filename_valid_mask,'FigNo',fig_no+2,...
|
||||
'NoHelp',1);
|
||||
else
|
||||
% mark the valid pixels as 1, leave the invalid at 0
|
||||
pframe = zeros(valid_mask.framesize);
|
||||
pframe(valid_mask.indices) = 1;
|
||||
|
||||
% plot the result
|
||||
figure(fig_no+2);
|
||||
imagesc(pframe);
|
||||
axis xy;
|
||||
axis equal;
|
||||
axis tight;
|
||||
colorbar;
|
||||
title('valid pixels');
|
||||
title('updated valid pixel mask (not saved!)');
|
||||
set(gcf,'Name','valid pixels');
|
||||
end
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
function [] = display_help(filename_valid_mask,save_data,fig_no)
|
||||
|
||||
fprintf('Usage:\n');
|
||||
fprintf('%s(filename_for_display, [[<name>,<value>],...]);\n',mfilename)
|
||||
fprintf('The specified file is used to display the beamstop mask with reduced intensity.\n');
|
||||
fprintf('The optional <name>,<value> pairs are:\n');
|
||||
fprintf('''xyCoord'',[ x1 y1; x2 y2; ...] coordinates of the beamstop mask\n');
|
||||
fprintf('''xCoord'',[ x1 x2 ...] x-coordinates of the beamstop mask, alternative to specifying xy pairs, may be useful if roipoly is used\n');
|
||||
fprintf('''yCoord'',[ y1 y2 ...] y-coordinates of the beamstop mask, alternative to specifying xy pairs, may be useful if roipoly is used\n');
|
||||
fprintf('''FilenameValidMask'',<path and filename> Matlab file with the valid pixel indices ind_valid,\n');
|
||||
fprintf(' default is %s\n',filename_valid_mask);
|
||||
fprintf('''SaveData'',<0-no,1-yes> 0 for displaying the result without updating the mask, default is %d\n',...
|
||||
save_data);
|
||||
fprintf('''FigNo'',<integer> number of the figure in which the result is displayed, default is %d\n',...
|
||||
fig_no);
|
||||
fprintf('\n');
|
||||
fprintf('A valid pixel mask can be created using the macro prep_valid_mask.\n')
|
||||
fprintf('You will find a valid pixel mask in %s but you may consider to measure a new one.\n',...
|
||||
filename_valid_mask);
|
||||
fprintf('\n');
|
||||
@@ -0,0 +1,224 @@
|
||||
% [mask_coord,bmask_ind] = choose_beamstop_mask(filename,varargin)
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 [mask_coord,bmask_ind] = choose_beamstop_mask(filename,varargin)
|
||||
import beamline.beamstop_mask
|
||||
import plotting.image_show
|
||||
|
||||
% set default values for the variable input arguments:
|
||||
% File with mask coordinates
|
||||
filename_coord = '~/Data10/analysis/data/mask_coordinates.mat';
|
||||
% border size
|
||||
border = 3;
|
||||
% save coordinates
|
||||
save_coord = 1;
|
||||
% select corrdinates
|
||||
select_points = 1;
|
||||
% do not read prevously saved coordinates
|
||||
read_coord = 1;
|
||||
% start with an empty set of coordinates
|
||||
mask_coord = [];
|
||||
bmask_ind = [];
|
||||
% figure number for display
|
||||
fig_no_sel = 555 ;
|
||||
% run 'beamstop_mask' at the end
|
||||
create_mask = 1;
|
||||
% Arguments to be passed to imageshow
|
||||
imageshow_args = {};
|
||||
|
||||
|
||||
% check minimum number of input arguments
|
||||
if (nargin < 1)
|
||||
fprintf('\n');
|
||||
fprintf('Usage:\n');
|
||||
fprintf('%s(filename,[[<name>,<value>],...]);\n',mfilename);
|
||||
fprintf('\n');
|
||||
fprintf('The optional <name>,<value> pairs are:\n');
|
||||
fprintf('''Border'', size of the ''sticky'' edge border, default is %d, 0 to disable\n',border);
|
||||
fprintf('''SaveCoord'',<0-no,1-yes> 1 for saving the coordinates, default is %d\n',save_coord);
|
||||
fprintf('''FilenameCoord'',<path and filename> Matlab file with the mask coordinates,\n');
|
||||
fprintf(' default is %s\n',filename_coord);
|
||||
fprintf('''SelectPoints'',<0-no,1-yes> 1 for selecting the points in the image, default is %d\n',select_points);
|
||||
fprintf(' if 0, points should be either read from the file or \n');
|
||||
fprintf(' supplied as options for ''beamstop_mask'' function\n');
|
||||
fprintf('''ReadCoord'',<0-no,1-yes> 1 for reading the coordinates from the file, default is %d\n',read_coord);
|
||||
fprintf('''CreateMask'',<0-no,1-yes> 1 for running ''beamstop_mask'', default is %d\n',create_mask);
|
||||
fprintf('''FigNoSel'',<integer> number of the figure in which the coordinates are selected, default is %d\n',...
|
||||
fig_no_sel);
|
||||
fprintf('''ImageShowArgs'', cell additional parameters to be passed to image_show, default is an empty cell {} \n');
|
||||
fprintf('\n');
|
||||
fprintf('Additional <name>,<value> pairs recognized by ''beamstop_mask'' can be specified.\n');
|
||||
error('At least the filename has to be specified as input parameter.');
|
||||
end
|
||||
|
||||
|
||||
% accept cell array with name/value pairs as well
|
||||
no_of_in_arg = nargin;
|
||||
if (nargin == 2)
|
||||
if (isempty(varargin))
|
||||
% ignore empty cell array
|
||||
no_of_in_arg = no_of_in_arg -1;
|
||||
else
|
||||
if (iscell(varargin{1}))
|
||||
% use a filled one given as first and only variable parameter
|
||||
varargin = varargin{1};
|
||||
no_of_in_arg = 1 + length(varargin);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% check number of input arguments
|
||||
if (rem(no_of_in_arg,2) ~= 1)
|
||||
display_help(filename_coord,save_coord,create_mask,select_points,border,read_coord,fig_no_sel);
|
||||
error('The optional parameters have to be specified as ''name'',''value'' pairs');
|
||||
end
|
||||
|
||||
|
||||
% parse the variable input arguments
|
||||
vararg_remain = cell(0,0);
|
||||
for ind = 1:2:length(varargin)
|
||||
name = varargin{ind};
|
||||
value = varargin{ind+1};
|
||||
switch name
|
||||
case 'SaveCoord'
|
||||
save_coord = value;
|
||||
case 'Border'
|
||||
border = value;
|
||||
case 'SelectPoints'
|
||||
select_points = value;
|
||||
case 'ReadCoord'
|
||||
read_coord = value;
|
||||
case 'FilenameCoord'
|
||||
filename_coord = value;
|
||||
case 'FigNoSel'
|
||||
fig_no_sel = value;
|
||||
case 'xyCoord'
|
||||
mask_coord = value;
|
||||
case 'CreateMask'
|
||||
create_mask = value;
|
||||
case 'ImageShowArgs'
|
||||
imageshow_args = value;
|
||||
otherwise
|
||||
vararg_remain{end+1} = name;
|
||||
vararg_remain{end+1} = value;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
% Read the coordinates from the file
|
||||
if (read_coord == 1)
|
||||
if (exist(filename_coord,'file'))
|
||||
load(filename_coord);
|
||||
% don't use if there are less than two points in the mask
|
||||
% makes it impossible to add new points
|
||||
if size(mask_coord,1) < 2
|
||||
mask_coord = [];
|
||||
end
|
||||
else
|
||||
fprintf('Mask coordinates file %s was not found.\n',filename_coord);
|
||||
fprintf('Continuing with no starting mask.\n');
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
% select/change the mask coordinates in the image
|
||||
if (select_points == 1)
|
||||
|
||||
[qq] = image_show(filename,'FigNo',fig_no_sel, imageshow_args{:});
|
||||
|
||||
% h=impoly(gca,mask_coord);
|
||||
% mask_coord=getPosition(h);
|
||||
% addNewPositionCallback(h,@(pos)eval('mask_coord=pos;'));
|
||||
% % wait for the changes while the image is open
|
||||
% waitfor(fig_no_sel)
|
||||
msgbox({'Instructions:', '1) Create a closed polygon around the beamstop (don''t double-click when you finish)'...
|
||||
, '2) Adjust the corners of polygon if needed',...
|
||||
'3) Double-click on polygon to finish'},'Choose beamstop mask');
|
||||
h = impoly(gca,mask_coord);
|
||||
mask_coord = wait(h);
|
||||
|
||||
% move points to the edge
|
||||
if border
|
||||
im_dim(1) = size(qq.data,2);
|
||||
im_dim(2) = size(qq.data,1);
|
||||
|
||||
for jj = 1:size(mask_coord,1)
|
||||
for kk = 1:2
|
||||
|
||||
if mask_coord(jj,kk) < border
|
||||
mask_coord(jj,kk) = 0;
|
||||
end
|
||||
|
||||
if abs(mask_coord(jj,kk) - im_dim(kk)) < border
|
||||
mask_coord(jj,kk) = im_dim(kk);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% mask coordinates should be integers
|
||||
mask_coord = round(mask_coord);
|
||||
end
|
||||
|
||||
% save the mask coordinates file, if specified
|
||||
if save_coord
|
||||
% create a backup of the mask coordinates file
|
||||
if (exist(filename_coord,'file'))
|
||||
filename_coord_backup = [ filename_coord '.bak' ];
|
||||
fprintf('Copying the current mask coordinates file %s to %s\n',filename_coord,...
|
||||
filename_coord_backup);
|
||||
copyfile(filename_coord,filename_coord_backup);
|
||||
end
|
||||
fprintf('saving updated mask coordinates file %s\n',filename_coord);
|
||||
save(filename_coord,'mask_coord');
|
||||
end
|
||||
|
||||
% run the beamstop_mask function, if specified
|
||||
if create_mask
|
||||
vararg_remain{end+1} = 'xyCoord';
|
||||
vararg_remain{end+1} = mask_coord;
|
||||
bmask_ind = beamstop_mask(filename,vararg_remain{:},imageshow_args{:});
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
%CREATE_MASK
|
||||
% create a binary mask for the current figure
|
||||
% The following arguments have to be given as name/value pairs. However,
|
||||
% they can also be set within the GUI.
|
||||
%
|
||||
% *optional*
|
||||
% ** mask initial mask; either a file, an array or a structure (indicies + asize)
|
||||
% ** fig pass figure handle; default: current figure
|
||||
% ** ind convert mask to indicies
|
||||
% ** file save mask to disk; specify path + filename
|
||||
%
|
||||
% returns:
|
||||
% ++ out 2D binary mask or structure containing the asize and the indicies
|
||||
%
|
||||
% EXAMPLE:
|
||||
% img = io.image_read('~/Data10/pilatus_1/S00000-00999/S00170/*.cbf'); % load image stack
|
||||
% plotting.imagesc3D(log10(img.data)); axis equal tight xy; % plot image stack
|
||||
% beamline.create_mask(); % open the GUI and create the mask
|
||||
%
|
||||
% see also: beamline.mask2ind
|
||||
|
||||
% Academic License Agreement
|
||||
%
|
||||
% Source Code
|
||||
%
|
||||
% Introduction
|
||||
% • This license agreement sets forth the terms and conditions under which the PAUL SCHERRER INSTITUT (PSI), CH-5232 Villigen-PSI, Switzerland (hereafter "LICENSOR")
|
||||
% will grant you (hereafter "LICENSEE") a royalty-free, non-exclusive license for academic, non-commercial purposes only (hereafter "LICENSE") to use the cSAXS
|
||||
% ptychography MATLAB package computer software program and associated documentation furnished hereunder (hereafter "PROGRAM").
|
||||
%
|
||||
% Terms and Conditions of the LICENSE
|
||||
% 1. LICENSOR grants to LICENSEE a royalty-free, non-exclusive license to use the PROGRAM for academic, non-commercial purposes, upon the terms and conditions
|
||||
% hereinafter set out and until termination of this license as set forth below.
|
||||
% 2. LICENSEE acknowledges that the PROGRAM is a research tool still in the development stage. The PROGRAM is provided without any related services, improvements
|
||||
% or warranties from LICENSOR and that the LICENSE is entered into in order to enable others to utilize the PROGRAM in their academic activities. It is the
|
||||
% LICENSEE’s responsibility to ensure its proper use and the correctness of the results.”
|
||||
% 3. THE PROGRAM IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR
|
||||
% A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. IN NO EVENT SHALL THE LICENSOR, THE AUTHORS OR THE COPYRIGHT
|
||||
% HOLDERS BE LIABLE FOR ANY CLAIM, DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR OTHER LIABILITY ARISING FROM, OUT OF OR IN CONNECTION WITH THE PROGRAM OR THE USE
|
||||
% OF THE PROGRAM OR OTHER DEALINGS IN THE PROGRAM.
|
||||
% 4. LICENSEE agrees that it will use the PROGRAM and any modifications, improvements, or derivatives of PROGRAM that LICENSEE may create (collectively,
|
||||
% "IMPROVEMENTS") solely for academic, non-commercial purposes and that any copy of PROGRAM or derivatives thereof shall be distributed only under the same
|
||||
% license as PROGRAM. The terms "academic, non-commercial", as used in this Agreement, mean academic or other scholarly research which (a) is not undertaken for
|
||||
% profit, or (b) is not intended to produce works, services, or data for commercial use, or (c) is neither conducted, nor funded, by a person or an entity engaged
|
||||
% in the commercial use, application or exploitation of works similar to the PROGRAM.
|
||||
% 5. LICENSEE agrees that it shall make the following acknowledgement in any publication resulting from the use of the PROGRAM or any translation of the code into
|
||||
% another computing language:
|
||||
% "Data processing was carried out using the cSAXS ptychography MATLAB package developed by the Science IT and the coherent X-ray scattering (CXS) groups, Paul
|
||||
% Scherrer Institut, Switzerland."
|
||||
%
|
||||
% Additionally, any publication using the package, or any translation of the code into another computing language should cite for difference map:
|
||||
% P. Thibault, M. Dierolf, A. Menzel, O. Bunk, C. David, F. Pfeiffer, High-resolution scanning X-ray diffraction microscopy, Science 321, 379–382 (2008).
|
||||
% (doi: 10.1126/science.1158573),
|
||||
% for maximum likelihood:
|
||||
% P. Thibault and M. Guizar-Sicairos, Maximum-likelihood refinement for coherent diffractive imaging, New J. Phys. 14, 063004 (2012).
|
||||
% (doi: 10.1088/1367-2630/14/6/063004),
|
||||
% for mixed coherent modes:
|
||||
% P. Thibault and A. Menzel, Reconstructing state mixtures from diffraction measurements, Nature 494, 68–71 (2013). (doi: 10.1038/nature11806),
|
||||
% and/or for multislice:
|
||||
% E. H. R. Tsai, I. Usov, A. Diaz, A. Menzel, and M. Guizar-Sicairos, X-ray ptychography with extended depth of field, Opt. Express 24, 29089–29108 (2016).
|
||||
% (doi: 10.1364/OE.24.029089).
|
||||
% 6. Except for the above-mentioned acknowledgment, LICENSEE shall not use the PROGRAM title or the names or logos of LICENSOR, nor any adaptation thereof, nor the
|
||||
% names of any of its employees or laboratories, in any advertising, promotional or sales material without prior written consent obtained from LICENSOR in each case.
|
||||
% 7. Ownership of all rights, including copyright in the PROGRAM and in any material associated therewith, shall at all times remain with LICENSOR, and LICENSEE
|
||||
% agrees to preserve same. LICENSEE agrees not to use any portion of the PROGRAM or of any IMPROVEMENTS in any machine-readable form outside the PROGRAM, nor to
|
||||
% make any copies except for its internal use, without prior written consent of LICENSOR. LICENSEE agrees to place the following copyright notice on any such copies:
|
||||
% © All rights reserved. PAUL SCHERRER INSTITUT, Switzerland, Laboratory for Macromolecules and Bioimaging, 2017.
|
||||
% 8. The LICENSE shall not be construed to confer any rights upon LICENSEE by implication or otherwise except as specifically set forth herein.
|
||||
% 9. DISCLAIMER: LICENSEE shall be aware that Phase Focus Limited of Sheffield, UK has an international portfolio of patents and pending applications which relate
|
||||
% to ptychography and that the PROGRAM may be capable of being used in circumstances which may fall within the claims of one or more of the Phase Focus patents,
|
||||
% in particular of patent with international application number PCT/GB2005/001464. The LICENSOR explicitly declares not to indemnify the users of the software
|
||||
% in case Phase Focus or any other third party will open a legal action against the LICENSEE due to the use of the program.
|
||||
% 10. This Agreement shall be governed by the material laws of Switzerland and any dispute arising out of this Agreement or use of the PROGRAM shall be brought before
|
||||
% the courts of Zürich, Switzerland.
|
||||
|
||||
function [out] = create_mask(varargin)
|
||||
|
||||
check_input_mask = @(x) ischar(x) || (isnumeric(x)|| islogical(x)) || isstruct(x);
|
||||
|
||||
par = inputParser;
|
||||
par.addParameter('mask', [], check_input_mask)
|
||||
par.addParameter('fig', [], @ishandle)
|
||||
par.addParameter('ind', false, @islogical)
|
||||
par.addParameter('file', [], @ischar)
|
||||
par.parse(varargin{:})
|
||||
vars = par.Results;
|
||||
|
||||
% Check screen size
|
||||
try
|
||||
scrsz = get(0,'ScreenSize');
|
||||
catch
|
||||
scrsz = [1 1 2560 1024];
|
||||
end
|
||||
|
||||
% get fig
|
||||
if isempty(vars.fig)
|
||||
fig = gcf;
|
||||
end
|
||||
|
||||
current_pos = fig.Position;
|
||||
new_fig_pos(2:4) = current_pos(2:4);
|
||||
|
||||
if current_pos(1)+current_pos(3)/2 - scrsz(3)/2 > 0
|
||||
% figure to the left
|
||||
new_fig_pos(1) = current_pos(1)-current_pos(3);
|
||||
else
|
||||
% figure to the right
|
||||
new_fig_pos(1) = current_pos(1)+current_pos(3);
|
||||
end
|
||||
|
||||
|
||||
% get axis
|
||||
ax = gca;
|
||||
% get current data size
|
||||
if ~isempty(ax.Children)
|
||||
asize = size(ax.Children.CData);
|
||||
else
|
||||
fig = gcf;
|
||||
close(fig)
|
||||
error('Failed to connect to figure instance.')
|
||||
end
|
||||
|
||||
% prepare mask
|
||||
if isempty(vars.mask)
|
||||
mask = ones(asize);
|
||||
else
|
||||
if ischar(vars.mask)
|
||||
% load a mask from disk
|
||||
try
|
||||
f = load(vars.mask);
|
||||
mask = f.mask;
|
||||
clear f
|
||||
catch
|
||||
fprintf('Failed to load mask. Using empty mask instead.\n')
|
||||
mask = ones(asize);
|
||||
end
|
||||
elseif isnumeric(vars.mask) || islogical(vars.mask)
|
||||
mask = vars.mask;
|
||||
elseif isstruct(vars.mask)
|
||||
mask = beamline.ind2mask(vars.mask);
|
||||
else
|
||||
error('Unknown mask data format.')
|
||||
end
|
||||
assert(all(size(mask)==asize), 'Mask size and data size does not match')
|
||||
|
||||
end
|
||||
pause(0.1)
|
||||
|
||||
|
||||
% apply mask
|
||||
CData_orig = ax.Children.CData;
|
||||
if ax.isprop('img')
|
||||
img_orig = ax.img;
|
||||
ax.img = ax.img .* mask;
|
||||
mask_dims = ndims(img_orig);
|
||||
if mask_dims==3
|
||||
mask3D = true;
|
||||
else
|
||||
mask3D = false;
|
||||
end
|
||||
mask_dims = size(img_orig,3);
|
||||
else
|
||||
mask3D = false;
|
||||
mask_dims = 1;
|
||||
end
|
||||
ax.Children.CData = ax.Children.CData .* mask;
|
||||
|
||||
s = create_mask_GUI_export('mask', mask, 'mask3D', mask3D, 'mask_dims', mask_dims);
|
||||
s.figure1.UserData.ax = ax;
|
||||
s.figure1.UserData.fig = fig;
|
||||
s.figure1.UserData.asize = asize;
|
||||
s.figure1.UserData.CData = CData_orig;
|
||||
if ax.isprop('img')
|
||||
s.figure1.UserData.img_orig = img_orig;
|
||||
if s.figure1.UserData.mask3D
|
||||
orig_fig_listener = s.figure1.UserData.ax.slider_handle.listener('Value','PostSet',@(src, evnt)orig_fig_slice_update(s));
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
try
|
||||
while ~s.figure1.UserData.done
|
||||
mask = s.figure1.UserData.mask;
|
||||
pause(0.1)
|
||||
end
|
||||
|
||||
set(groot,'CurrentFigure',fig);
|
||||
ax.Children.CData = CData_orig;
|
||||
if ax.isprop('img')
|
||||
ax.img = img_orig;
|
||||
end
|
||||
catch
|
||||
if ~isprop(s, 'figure1')
|
||||
fprintf('Lost connection to GUI.\n')
|
||||
end
|
||||
end
|
||||
|
||||
try
|
||||
if s.figure1.UserData.mask3D
|
||||
delete(orig_fig_listener)
|
||||
end
|
||||
delete(s.figure1)
|
||||
catch
|
||||
end
|
||||
|
||||
|
||||
% if needed, convert 2D mask to indicies
|
||||
if vars.ind
|
||||
out = beamline.mask2ind(mask);
|
||||
else
|
||||
out = mask;
|
||||
end
|
||||
|
||||
|
||||
|
||||
% save to disk
|
||||
if ~isempty(vars.file)
|
||||
valid_mask = out;
|
||||
try
|
||||
utils.savefast_safe(vars.file, 'valid_mask');
|
||||
catch
|
||||
fprintf('Failed to save mask to disk.');
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
function orig_fig_slice_update(s)
|
||||
val = s.figure1.UserData.ax.slider_handle.Value;
|
||||
set(s.axes1.slider_handle, 'Value', val);
|
||||
set(s.axes1.edit_handle, 'String', num2str(val));
|
||||
s.axes1.update_fig(s.axes1);
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
% function mark = energy2mark(E,calib_file)
|
||||
% After calibrating using beamline.mark_interpolation_setup you can use
|
||||
% this function to input a desired energy and a linear interpolation will
|
||||
% determine and give you the mark
|
||||
% Inputs
|
||||
% E Array of energies in keV
|
||||
% calib_file Name of the file with the calibration
|
||||
%
|
||||
% Outputs
|
||||
% mark Array of marks corresponding to input energies
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 mark = energy2mark(E,calib_file)
|
||||
|
||||
if ~nargin<2
|
||||
calib_file = 'mark_calib.mat';
|
||||
end
|
||||
|
||||
calib = load(calib_file);
|
||||
|
||||
mark = interp1(calib.E,calib.marks,E,'linear');
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
% [varargout] = find_capillary(varargin)
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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] = find_capillary(varargin)
|
||||
import io.spec_read
|
||||
|
||||
vararg = varargin;
|
||||
vararg{end+1} = 'UnhandledParError';
|
||||
vararg{end+1} = 0;
|
||||
[S] = spec_read(vararg{1},vararg{2:end});
|
||||
vararg = vararg(2:end);
|
||||
for jj = 1:2:length(vararg)
|
||||
name = vararg{jj};
|
||||
value = vararg{jj+1};
|
||||
switch name
|
||||
case 'Counter'
|
||||
counter = S.(value);
|
||||
end
|
||||
end
|
||||
|
||||
arrout = regexp(S.S,' +','split');
|
||||
motor = S.(arrout{4});
|
||||
threshold = .1 * max(counter);
|
||||
|
||||
motor = motor(counter>threshold);
|
||||
counter = counter(counter>threshold);
|
||||
|
||||
|
||||
threshold = .9 * max(counter);
|
||||
i_i = find(counter>threshold,1,'first');
|
||||
i_f = find(counter>threshold,1,'last');
|
||||
|
||||
p = polyfit(motor(counter>threshold),counter(counter>threshold),1);
|
||||
dy = polyval(p,motor)-counter;
|
||||
COM = sum(motor(i_i:i_f).*dy(i_i:i_f))/sum(dy(i_i:i_f));
|
||||
|
||||
do_plot = 0;
|
||||
if (do_plot)
|
||||
figure(1)
|
||||
plot(motor,dy)
|
||||
hold on
|
||||
area(motor(i_i:i_f),dy(i_i:i_f))
|
||||
plot([1 1]*COM,[0 max(dy(i_i:i_f))],'r','LineWidth',2)
|
||||
hold off
|
||||
end
|
||||
|
||||
varargout{1} = COM;
|
||||
|
||||
|
||||
|
||||
end
|
||||
@@ -0,0 +1,69 @@
|
||||
% this script contains the necessary loop for 'find_capillary.m' to be called
|
||||
% as function of 'spec'
|
||||
% written by (last change: 2011-06-16)
|
||||
% in case of bugs, problems, and suggestions for improvements, please contact
|
||||
% CXS group
|
||||
%
|
||||
% note that EPICS communication works only on local machines at the beamline, i.e.,
|
||||
% NOT on the compute nodes
|
||||
% run this (or related scripts that use EPICS for communication), for instance, on
|
||||
% x12sa-cons-1
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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.
|
||||
|
||||
lastscan = 0;
|
||||
|
||||
while(1)
|
||||
scall = sprintf('caget ''X12SA-ES1-DOUBLE-00''');
|
||||
[err,io] = system(scall);
|
||||
arrout = regexp(io,' +','split');
|
||||
scannr = str2double(arrout{2});
|
||||
if (scannr > lastscan)
|
||||
try
|
||||
COM = +beamline.find_capillary('..','ScanNr',scannr,'Counter','diode')
|
||||
catch
|
||||
fprintf('Failed find capillary, pausing 5 sec and retrying\n')
|
||||
pause(5)
|
||||
COM = +beamline.find_capillary('..','ScanNr',scannr,'Counter','diode')
|
||||
end
|
||||
else
|
||||
pause(1);
|
||||
end
|
||||
scall = sprintf('caputq X12SA-ES1-DOUBLE-02 %f',COM);
|
||||
[err,io] = system(scall);
|
||||
scall = sprintf('caputq X12SA-ES1-DOUBLE-01 %d',scannr);
|
||||
[err,io] = system(scall);
|
||||
lastscan = scannr;
|
||||
end
|
||||
@@ -0,0 +1,100 @@
|
||||
% function specDatFile = find_specDatFile(specDatFile)
|
||||
% find location of the spec file in the provided folder / path
|
||||
% if the variable specDatFile is not a complete path to a file
|
||||
% try to guess where a spec data file can be found, by
|
||||
% - look for directories called 'spec' or 'dat-files'
|
||||
% - look for files called '*.dat'
|
||||
% - take the newest one
|
||||
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 specDatFile = find_specDatFile(specDatFile)
|
||||
while (exist(specDatFile,'file') ~= 2)
|
||||
% if the variable specDatFile is not a complete path to a file
|
||||
% try to guess where a spec data file can be found, by
|
||||
% - look for directories called 'spec' or 'dat-files'
|
||||
% - look for files called '*.dat'
|
||||
% - take the newest one
|
||||
compare_str = specDatFile;
|
||||
fname = dir(specDatFile);
|
||||
if (exist(specDatFile,'dir'))
|
||||
if (specDatFile(end) ~= '/')
|
||||
specDatFile = strcat(specDatFile,'/');
|
||||
end
|
||||
|
||||
for ii=1:numel(fname)
|
||||
if (regexp(fname(ii).name,'.dat$'))
|
||||
specDatFile = strcat(specDatFile,'*.dat');
|
||||
fname = [];
|
||||
break;
|
||||
end
|
||||
end
|
||||
for ii=1:numel(fname)
|
||||
if (strcmp(fname(ii).name,'dat-files'))
|
||||
specDatFile = strcat(specDatFile,fname(ii).name);
|
||||
fname = [];
|
||||
break;
|
||||
end
|
||||
end
|
||||
for ii=1:numel(fname)
|
||||
if (strcmp(fname(ii).name,'specES1'))
|
||||
specDatFile = strcat(specDatFile,fname(ii).name);
|
||||
break;
|
||||
end
|
||||
if (strcmp(fname(ii).name,'spec'))
|
||||
specDatFile = strcat(specDatFile,fname(ii).name);
|
||||
break;
|
||||
end
|
||||
end
|
||||
else
|
||||
if (numel(fname)>0)
|
||||
[~,ii] = max(cell2mat({fname.datenum}));
|
||||
specDatFile = regexprep(specDatFile,'\*\.dat$',fname(ii).name);
|
||||
else
|
||||
error('''%s'' cannot be found.', specDatFile);
|
||||
break
|
||||
end
|
||||
end
|
||||
if (strcmp(specDatFile,compare_str))
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if ~exist(specDatFile, 'file') || exist(specDatFile, 'dir')
|
||||
error('Spec dat file not found in the provided path %s', specDatFile)
|
||||
end
|
||||
|
||||
end
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,77 @@
|
||||
% Return the current e-account user name in case this function is executed
|
||||
% at the X12SA beamline, [] otherwise.
|
||||
|
||||
% Filename: $RCSfile: identify_eaccount.m,v $
|
||||
%
|
||||
% $Revision: 1.1 $ $Date: 2010/04/28 18:00:56 $
|
||||
% $Author: $
|
||||
% $Tag: $
|
||||
%
|
||||
% Description:
|
||||
% Return the current e-account user name in case this function is executed
|
||||
% at the X12SA beamline, [] otherwise.
|
||||
%
|
||||
% Note:
|
||||
% none
|
||||
%
|
||||
% Dependencies:
|
||||
% identify_system.m
|
||||
%
|
||||
%
|
||||
% history:
|
||||
%
|
||||
% April 28th, 2010: 1st version
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| Except where otherwise noted, this work is licensed under a |
|
||||
%| Creative Commons Attribution-NonCommercial-ShareAlike 4.0 |
|
||||
%| International (CC BY-NC-SA 4.0) license. |
|
||||
%| |
|
||||
%| Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch) |
|
||||
%| |
|
||||
%| Author: CXS group, PSI |
|
||||
%*-----------------------------------------------------------------------*
|
||||
% You may use this code with the following provisions:
|
||||
%
|
||||
% If the code is fully or partially redistributed, or rewritten in another
|
||||
% computing language this notice should be included in the redistribution.
|
||||
%
|
||||
% If this code, or subfunctions or parts of it, is used for research in a
|
||||
% publication or if it is fully or partially rewritten for another
|
||||
% computing language the authors and institution should be acknowledged
|
||||
% in written form in the publication: “Data processing was carried out
|
||||
% using the “cSAXS matlab package” developed by the CXS group,
|
||||
% Paul Scherrer Institut, Switzerland.”
|
||||
% Variations on the latter text can be incorporated upon discussion with
|
||||
% the CXS group if needed to more specifically reflect the use of the package
|
||||
% for the published work.
|
||||
%
|
||||
% A publication that focuses on describing features, or parameters, that
|
||||
% are already existing in the code should be first discussed with the
|
||||
% authors.
|
||||
%
|
||||
% This code and subroutines are part of a continuous development, they
|
||||
% are provided “as they are” without guarantees or liability on part
|
||||
% of PSI or the authors. It is the user responsibility to ensure its
|
||||
% proper use and the correctness of the results.
|
||||
|
||||
function [return_user_name] = identify_eaccount()
|
||||
import utils.identify_system
|
||||
|
||||
persistent user_name;
|
||||
|
||||
if (isempty(user_name))
|
||||
user_name = [];
|
||||
% at the cSAXS beamline return the name of the current user as
|
||||
% e-account name
|
||||
sys_id = identify_system();
|
||||
if (strcmp(sys_id,'X12SA'))
|
||||
[st,un] = system('echo $USER');
|
||||
if ((st == 0) && (length(un) > 1))
|
||||
user_name = un(1:end-1);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return_user_name = user_name;
|
||||
@@ -0,0 +1,80 @@
|
||||
%IND2MASK
|
||||
% convert mask structure (indices + framesize) to a 2D binary mask
|
||||
%
|
||||
% ** s mask structure; must contain s.indices and s.framesize
|
||||
%
|
||||
% returns:
|
||||
% ++ mask 2D binary mask
|
||||
%
|
||||
% see also: beamline.mask2ind
|
||||
|
||||
% Academic License Agreement
|
||||
%
|
||||
% Source Code
|
||||
%
|
||||
% Introduction
|
||||
% • This license agreement sets forth the terms and conditions under which the PAUL SCHERRER INSTITUT (PSI), CH-5232 Villigen-PSI, Switzerland (hereafter "LICENSOR")
|
||||
% will grant you (hereafter "LICENSEE") a royalty-free, non-exclusive license for academic, non-commercial purposes only (hereafter "LICENSE") to use the cSAXS
|
||||
% ptychography MATLAB package computer software program and associated documentation furnished hereunder (hereafter "PROGRAM").
|
||||
%
|
||||
% Terms and Conditions of the LICENSE
|
||||
% 1. LICENSOR grants to LICENSEE a royalty-free, non-exclusive license to use the PROGRAM for academic, non-commercial purposes, upon the terms and conditions
|
||||
% hereinafter set out and until termination of this license as set forth below.
|
||||
% 2. LICENSEE acknowledges that the PROGRAM is a research tool still in the development stage. The PROGRAM is provided without any related services, improvements
|
||||
% or warranties from LICENSOR and that the LICENSE is entered into in order to enable others to utilize the PROGRAM in their academic activities. It is the
|
||||
% LICENSEE’s responsibility to ensure its proper use and the correctness of the results.”
|
||||
% 3. THE PROGRAM IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR
|
||||
% A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. IN NO EVENT SHALL THE LICENSOR, THE AUTHORS OR THE COPYRIGHT
|
||||
% HOLDERS BE LIABLE FOR ANY CLAIM, DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR OTHER LIABILITY ARISING FROM, OUT OF OR IN CONNECTION WITH THE PROGRAM OR THE USE
|
||||
% OF THE PROGRAM OR OTHER DEALINGS IN THE PROGRAM.
|
||||
% 4. LICENSEE agrees that it will use the PROGRAM and any modifications, improvements, or derivatives of PROGRAM that LICENSEE may create (collectively,
|
||||
% "IMPROVEMENTS") solely for academic, non-commercial purposes and that any copy of PROGRAM or derivatives thereof shall be distributed only under the same
|
||||
% license as PROGRAM. The terms "academic, non-commercial", as used in this Agreement, mean academic or other scholarly research which (a) is not undertaken for
|
||||
% profit, or (b) is not intended to produce works, services, or data for commercial use, or (c) is neither conducted, nor funded, by a person or an entity engaged
|
||||
% in the commercial use, application or exploitation of works similar to the PROGRAM.
|
||||
% 5. LICENSEE agrees that it shall make the following acknowledgement in any publication resulting from the use of the PROGRAM or any translation of the code into
|
||||
% another computing language:
|
||||
% "Data processing was carried out using the cSAXS ptychography MATLAB package developed by the Science IT and the coherent X-ray scattering (CXS) groups, Paul
|
||||
% Scherrer Institut, Switzerland."
|
||||
%
|
||||
% Additionally, any publication using the package, or any translation of the code into another computing language should cite for difference map:
|
||||
% P. Thibault, M. Dierolf, A. Menzel, O. Bunk, C. David, F. Pfeiffer, High-resolution scanning X-ray diffraction microscopy, Science 321, 379–382 (2008).
|
||||
% (doi: 10.1126/science.1158573),
|
||||
% for maximum likelihood:
|
||||
% P. Thibault and M. Guizar-Sicairos, Maximum-likelihood refinement for coherent diffractive imaging, New J. Phys. 14, 063004 (2012).
|
||||
% (doi: 10.1088/1367-2630/14/6/063004),
|
||||
% for mixed coherent modes:
|
||||
% P. Thibault and A. Menzel, Reconstructing state mixtures from diffraction measurements, Nature 494, 68–71 (2013). (doi: 10.1038/nature11806),
|
||||
% and/or for multislice:
|
||||
% E. H. R. Tsai, I. Usov, A. Diaz, A. Menzel, and M. Guizar-Sicairos, X-ray ptychography with extended depth of field, Opt. Express 24, 29089–29108 (2016).
|
||||
% (doi: 10.1364/OE.24.029089).
|
||||
% 6. Except for the above-mentioned acknowledgment, LICENSEE shall not use the PROGRAM title or the names or logos of LICENSOR, nor any adaptation thereof, nor the
|
||||
% names of any of its employees or laboratories, in any advertising, promotional or sales material without prior written consent obtained from LICENSOR in each case.
|
||||
% 7. Ownership of all rights, including copyright in the PROGRAM and in any material associated therewith, shall at all times remain with LICENSOR, and LICENSEE
|
||||
% agrees to preserve same. LICENSEE agrees not to use any portion of the PROGRAM or of any IMPROVEMENTS in any machine-readable form outside the PROGRAM, nor to
|
||||
% make any copies except for its internal use, without prior written consent of LICENSOR. LICENSEE agrees to place the following copyright notice on any such copies:
|
||||
% © All rights reserved. PAUL SCHERRER INSTITUT, Switzerland, Laboratory for Macromolecules and Bioimaging, 2017.
|
||||
% 8. The LICENSE shall not be construed to confer any rights upon LICENSEE by implication or otherwise except as specifically set forth herein.
|
||||
% 9. DISCLAIMER: LICENSEE shall be aware that Phase Focus Limited of Sheffield, UK has an international portfolio of patents and pending applications which relate
|
||||
% to ptychography and that the PROGRAM may be capable of being used in circumstances which may fall within the claims of one or more of the Phase Focus patents,
|
||||
% in particular of patent with international application number PCT/GB2005/001464. The LICENSOR explicitly declares not to indemnify the users of the software
|
||||
% in case Phase Focus or any other third party will open a legal action against the LICENSEE due to the use of the program.
|
||||
% 10. This Agreement shall be governed by the material laws of Switzerland and any dispute arising out of this Agreement or use of the PROGRAM shall be brought before
|
||||
% the courts of Zürich, Switzerland.
|
||||
|
||||
function [mask] = ind2mask(s)
|
||||
|
||||
if ~isfield(s, 'framesize')
|
||||
error('Please specify your frame size.')
|
||||
end
|
||||
|
||||
if ~isfield(s, 'indices')
|
||||
error('Please specify the indices.')
|
||||
end
|
||||
|
||||
mask = reshape(zeros(s.framesize),1,[]);
|
||||
mask(s.indices) = 1;
|
||||
mask = reshape(mask, s.framesize);
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
% Call function without arguments for instructions on how to use it
|
||||
|
||||
% Filename: $RCSfile: integrate_range.m,v $
|
||||
%
|
||||
% $Revision: 1.7 $ $Date: 2012/09/02 15:13:04 $
|
||||
% $Author: $
|
||||
% $Tag: $
|
||||
%
|
||||
% Description:
|
||||
% azimuthal integration of a range of scans
|
||||
%
|
||||
% Note:
|
||||
% Call without arguments for a brief help text.
|
||||
% The integration masks need to be prepared first using prep_integ_masks.m
|
||||
%
|
||||
% Dependencies:
|
||||
% - compile_x12sa_filename
|
||||
% - find_files
|
||||
% - radial_integ
|
||||
%
|
||||
% history:
|
||||
%
|
||||
% May 19th 2010: 1st documented version
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| Except where otherwise noted, this work is licensed under a |
|
||||
%| Creative Commons Attribution-NonCommercial-ShareAlike 4.0 |
|
||||
%| International (CC BY-NC-SA 4.0) license. |
|
||||
%| |
|
||||
%| Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch) |
|
||||
%| |
|
||||
%| Author: CXS group, PSI |
|
||||
%*-----------------------------------------------------------------------*
|
||||
% You may use this code with the following provisions:
|
||||
%
|
||||
% If the code is fully or partially redistributed, or rewritten in another
|
||||
% computing language this notice should be included in the redistribution.
|
||||
%
|
||||
% If this code, or subfunctions or parts of it, is used for research in a
|
||||
% publication or if it is fully or partially rewritten for another
|
||||
% computing language the authors and institution should be acknowledged
|
||||
% in written form in the publication: “Data processing was carried out
|
||||
% using the “cSAXS matlab package” developed by the CXS group,
|
||||
% Paul Scherrer Institut, Switzerland.”
|
||||
% Variations on the latter text can be incorporated upon discussion with
|
||||
% the CXS group if needed to more specifically reflect the use of the package
|
||||
% for the published work.
|
||||
%
|
||||
% A publication that focuses on describing features, or parameters, that
|
||||
% are already existing in the code should be first discussed with the
|
||||
% authors.
|
||||
%
|
||||
% This code and subroutines are part of a continuous development, they
|
||||
% are provided “as they are” without guarantees or liability on part
|
||||
% of PSI or the authors. It is the user responsibility to ensure its
|
||||
% proper use and the correctness of the results.
|
||||
|
||||
function [] = integrate_range(scan_no_from,scan_no_to,scan_no_step,varargin)
|
||||
import beamline.prep_integ_masks
|
||||
import beamline.radial_integ
|
||||
import utils.compile_x12sa_filename
|
||||
import utils.find_files
|
||||
|
||||
% set default values for the variable input arguments:
|
||||
% select PILATUS 2M
|
||||
pilatus_det_no = 1;
|
||||
% writing cbf files
|
||||
file_extension = 'cbf';
|
||||
save_format = '-v6';
|
||||
|
||||
if (nargin < 2)
|
||||
fprintf('\nUsage:\n');
|
||||
fprintf('%s(scan_no_from,scan_no_to,scan_no_step [[,<name>,<value>] ...]);\n',mfilename);
|
||||
fprintf('integrates the scans within the range [scan_no_from, scan_no_to].\n');
|
||||
fprintf('The optional <name>,<value> pairs are:\n');
|
||||
fprintf('''PilatusDetNo'',<number> Detector number, 1 for 2M, default is %d\n',pilatus_det_no);
|
||||
fprintf('''FileExtension'',<extension string> default is %s\n',file_extension);
|
||||
fprintf('''SaveFormat'',<format string> default is %s\n',save_format);
|
||||
fprintf('Example:\n');
|
||||
fprintf('%s(100,500);\n',mfilename);
|
||||
fprintf('Additional <name>,<value> pairs recognized by radial_integ can be specified.\n');
|
||||
error('At least the scan number range has to be specified as input argument.');
|
||||
end
|
||||
% accept cell array with name/value pairs as well
|
||||
no_of_in_arg = nargin;
|
||||
if (nargin == 4)
|
||||
if (isempty(varargin))
|
||||
% ignore empty cell array
|
||||
no_of_in_arg = no_of_in_arg -1;
|
||||
else
|
||||
if (iscell(varargin{1}))
|
||||
% use a filled one given as first and only variable parameter
|
||||
varargin = varargin{1};
|
||||
no_of_in_arg = 1 + length(varargin);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% check number of input arguments
|
||||
if (rem(no_of_in_arg,2) ~= 1)
|
||||
error('The optional parameters have to be specified as ''name'',''value'' pairs');
|
||||
end
|
||||
|
||||
% parse the variable input arguments:
|
||||
% initialize the list of unhandled parameters
|
||||
vararg_remain = cell(0,0);
|
||||
for ind = 1:2:length(varargin)
|
||||
name = varargin{ind};
|
||||
value = varargin{ind+1};
|
||||
switch name
|
||||
case 'PilatusDetNo'
|
||||
pilatus_det_no = value;
|
||||
case 'SaveFormat'
|
||||
save_format = value;
|
||||
case 'FileExtension'
|
||||
file_extension = value;
|
||||
vararg_remain{end+1} = name; %#ok<AGROW>
|
||||
vararg_remain{end+1} = value; %#ok<AGROW>
|
||||
otherwise
|
||||
vararg_remain{end+1} = name; %#ok<AGROW>
|
||||
vararg_remain{end+1} = value; %#ok<AGROW>
|
||||
end
|
||||
end
|
||||
|
||||
vararg_remain{end+1} = 'UnhandledParError';
|
||||
vararg_remain{end+1} = 0;
|
||||
|
||||
vararg_remain_x12sa_filename = vararg_remain;
|
||||
vararg_remain_x12sa_filename{end+1} = 'DetectorNumber';
|
||||
vararg_remain_x12sa_filename{end+1} = pilatus_det_no;
|
||||
|
||||
vararg_remain_x12sa_filename_wildcard = vararg_remain_x12sa_filename;
|
||||
vararg_remain_x12sa_filename_wildcard{end+1} = 'PointWildcard';
|
||||
vararg_remain_x12sa_filename_wildcard{end+1} = 1;
|
||||
vararg_remain_x12sa_filename_wildcard{end+1} = 'SubExpWildcard';
|
||||
vararg_remain_x12sa_filename_wildcard{end+1} = 1;
|
||||
|
||||
|
||||
% highest number of an existing scan
|
||||
scan_no_exists = scan_no_from -1;
|
||||
scan_no_check = scan_no_from;
|
||||
|
||||
for scan_no = scan_no_from:scan_no_step:scan_no_to
|
||||
% wait until the first file of the next scan is available
|
||||
while (scan_no >= scan_no_exists)
|
||||
scan_no_check = scan_no_check +1;
|
||||
if (scan_no_check > scan_no + 100)
|
||||
scan_no_check = scan_no +1;
|
||||
fprintf('Pausing for 1 minute.\n');
|
||||
pause(60);
|
||||
|
||||
% check if the data directory and first file exists
|
||||
filename_mask = compile_x12sa_filename(scan_no,0,vararg_remain_x12sa_filename);
|
||||
[ddir fnames] = find_files(filename_mask);
|
||||
if (~isempty(fnames))
|
||||
% integrate all data available until now
|
||||
filename_mask = [ compile_x12sa_filename(scan_no,-1,vararg_remain_x12sa_filename) '*_' num2str(pilatus_det_no) '_' ['*' file_extension] ];
|
||||
radial_integ(filename_mask,vararg_remain);
|
||||
end
|
||||
end
|
||||
filename_next = compile_x12sa_filename(scan_no_check,0,vararg_remain_x12sa_filename);
|
||||
[ddir fnames] = find_files(filename_next);
|
||||
if (~isempty(fnames))
|
||||
scan_no_exists = scan_no_check;
|
||||
end
|
||||
end
|
||||
|
||||
% integrate scan if a following scan has been started, i.e.,
|
||||
% if the current one must be finished
|
||||
if (scan_no < scan_no_exists)
|
||||
% check if the data directory and first file exists
|
||||
filename_mask = compile_x12sa_filename(scan_no,0,vararg_remain_x12sa_filename);
|
||||
[ddir fnames] = find_files(filename_mask);
|
||||
if (isempty(fnames))
|
||||
fprintf('Skipping scan no %d: no data found\n',scan_no);
|
||||
continue;
|
||||
end
|
||||
|
||||
% integrate all data, i.e., all points and sub exposures
|
||||
filename_mask = [ compile_x12sa_filename(scan_no,0,vararg_remain_x12sa_filename_wildcard) ];
|
||||
radial_integ(filename_mask,vararg_remain);
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,184 @@
|
||||
% Description:
|
||||
% Return beam intensity in photons / sec based on calibration with
|
||||
% a glassy carbon sample and and air
|
||||
%
|
||||
% Dependencies:
|
||||
% spec_read
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 “cSA% Description:
|
||||
% Return beam intensity in photons / sec based on calibration with
|
||||
% a glassy carbon sample and and air
|
||||
%
|
||||
% Dependencies:
|
||||
% spec_readXS 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 [ diodescale ] = intensity_calibration(specfile, air_scanno, gc_scanno, det_dist_mm, varargin)
|
||||
import io.spec_read
|
||||
import utils.find_files
|
||||
|
||||
pixel_size_mm = 0.172;
|
||||
gc_file = 'glassycarbon_L14_xsection.dat';
|
||||
binned_path = '~/Data10/analysis/radial_integration/';
|
||||
|
||||
if (nargin < 4)
|
||||
fprintf('\nUsage:\n');
|
||||
fprintf('%s(specfile, air_scanno, gc_scanno, det_dist_mm, [[,<name>,<value>] ...]);\n\n',mfilename);
|
||||
fprintf('specfile is the full path to the SPEC dat-file.\n');
|
||||
fprintf('air_scanno and gc_scanno are SPEC scan numbers for empty and Glassy Carbon L14 measurements.\n');
|
||||
fprintf('det_dist_mm is the sample to detector distance in mm.\n');
|
||||
fprintf('\nThe optional <name>,<value> pairs are:\n');
|
||||
fprintf('''PixelSize_mm'', <value in mm> Size of detector pixel in mm, default is %s\n', pixel_size_mm);
|
||||
fprintf('''CrossSectionFile'', <filename> Full path to file containing the cross section of the standard, default is ''%s''\n', gc_file);
|
||||
fprintf('''BinnedPath'', <filepath> Directory containing the radially binned detector frames, default is ''%s''\n', binned_path);
|
||||
fprintf('\n');
|
||||
error('Not enough input arguments.');
|
||||
end
|
||||
|
||||
% accept cell array with name/value pairs as well
|
||||
no_of_in_arg = nargin;
|
||||
if (nargin == 5)
|
||||
if (isempty(varargin))
|
||||
% ignore empty cell array
|
||||
no_of_in_arg = no_of_in_arg -1;
|
||||
else
|
||||
if (iscell(varargin{1}))
|
||||
% use a filled one given as first and only variable parameter
|
||||
varargin = varargin{1};
|
||||
no_of_in_arg = 1 + length(varargin);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% check number of input arguments
|
||||
if (rem(no_of_in_arg,2) ~= 0)
|
||||
error('The optional parameters have to be specified as ''name'',''value'' pairs');
|
||||
end
|
||||
|
||||
% parse the variable input arguments
|
||||
vararg = cell(0,0);
|
||||
for ind = 1:2:length(varargin)
|
||||
name = varargin{ind};
|
||||
value = varargin{ind+1};
|
||||
switch name
|
||||
case 'PixelSize_mm'
|
||||
pixel_size_mm = value;
|
||||
case 'CrossSectionFile'
|
||||
gc_file = value;
|
||||
case 'BinnedPath'
|
||||
binned_path= value;
|
||||
otherwise
|
||||
vararg{end+1} = name; %#ok<AGROW>
|
||||
vararg{end+1} = value; %#ok<AGROW>
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
s_air = spec_read(specfile, 'ScanNr', air_scanno);
|
||||
s_gc = spec_read(specfile, 'ScanNr', gc_scanno);
|
||||
|
||||
[dd, air_intfile] = find_files(sprintf(strcat(binned_path, 'e*_1_%05d_00000_00000_integ.mat'), air_scanno));
|
||||
airint = load(strcat(dd, air_intfile.name));
|
||||
[dd, gc_intfile] = find_files(sprintf(strcat(binned_path, 'e*_1_%05d_00000_00000_integ.mat'), gc_scanno));
|
||||
gcint = load(strcat(dd, gc_intfile.name));
|
||||
|
||||
lambda = 12.39852 / s_gc.mokev;
|
||||
q_gc = 4*pi * sin(0.5*atan(gcint.radius*pixel_size_mm/det_dist_mm)) / lambda;
|
||||
gc_transmission = (sum(s_gc.diode)/sum(s_gc.sec)) / (sum(s_air.diode)/sum(s_air.sec));
|
||||
gc_time = sum(s_gc.sec);
|
||||
I_gc = sum(sum(gcint.I_all, 3), 2) - (sum(s_gc.diode)/sum(s_air.diode)) * sum(sum(airint.I_all, 3), 2);
|
||||
Ierr_gc = sqrt(sum(sum(gcint.I_std.^2, 3), 2) + (sum(s_gc.diode)/sum(s_air.diode)).^2 * sum(sum(airint.I_std.^2, 3), 2));
|
||||
|
||||
gc = load(gc_file);
|
||||
qmin = max(q_gc(1), gc(1,1));
|
||||
qmax = min(q_gc(end), gc(end,1));
|
||||
qind = find(qmin < gc(:,1) & gc(:,1) < qmax);
|
||||
q = gc(qind, 1);
|
||||
tth = 2*asin(lambda * q / (4*pi));
|
||||
|
||||
% Cross section per q-bin. Factors for thickness, transmission and solid angle
|
||||
xsection_scale = (1 / 10) * 1/gc_transmission * pixel_size_mm^2 / (4*pi*det_dist_mm^2);
|
||||
gc_xsection = xsection_scale * gc(qind,2);
|
||||
gc_xsection_err = xsection_scale * gc(qind,3);
|
||||
|
||||
% interpolate and scale w. angle dependent pixel solid angle and tilt
|
||||
gc_exp = interp1(q_gc, I_gc, q) ./ (cos(tth).^3);
|
||||
gc_exp_err = interp1(q_gc, Ierr_gc, q) ./ (cos(tth).^3);
|
||||
|
||||
s2 = gc_xsection_err.^2 + gc_exp_err.^2;
|
||||
% Solve for scaling factor, weigh with combined variance^-1
|
||||
wscale = sum(gc_xsection.*gc_exp./s2) / sum(gc_exp.^2 ./ s2);
|
||||
fitchi = sum((gc_xsection - wscale*gc_exp).^2./(gc_xsection_err.^2 + (wscale*gc_exp_err).^2));
|
||||
clf()
|
||||
hold on
|
||||
errband(q, gc_xsection, gc_xsection_err, 'r');
|
||||
errband(q, wscale*gc_exp, wscale*gc_exp_err, 'b');
|
||||
legend('Cross section', ' 1 std', 'Experimental', ' 1 std');
|
||||
hold off
|
||||
|
||||
% scaling without error weighing
|
||||
% scale = gc_exp \ gc_xsection;
|
||||
%semilogy(q, gc_xsection, '*', q, scale*gc_exp)
|
||||
|
||||
% incoming flux (photons/s) determined for each q-channel:
|
||||
%plot((1/gc_time) * gc_exp ./ gc_xsection)
|
||||
inphotons = 1/gc_time * mean(gc_exp./gc_xsection);
|
||||
diodescale = inphotons / (sum(s_gc.diode)/gc_time/gc_transmission);
|
||||
fprintf('Glassy carbon transmission: %g\n', gc_transmission);
|
||||
fprintf('Chi^2 to known cross-section: %g\n', fitchi);
|
||||
fprintf('Flux on sample: %g ph/sec\n', inphotons);
|
||||
fprintf('Scaling factor for diode readings: %g\n', diodescale);
|
||||
|
||||
|
||||
function errband(x, y, yerr, colour);
|
||||
%function errband(x, y, yerr, colour);
|
||||
%
|
||||
% Plot an error band between y-yerr and y+yerr.
|
||||
% The colour defaults to blue.
|
||||
|
||||
if nargin<4
|
||||
colour='b';
|
||||
end
|
||||
|
||||
x = x(:).';
|
||||
y = y(:).';
|
||||
yerr = yerr(:).';
|
||||
|
||||
lower = y-yerr;
|
||||
upper = y+yerr;
|
||||
|
||||
hold on
|
||||
plot(x, y, colour);
|
||||
h = fill([x, fliplr(x)], [upper, fliplr(lower)], colour);
|
||||
alpha(h, 0.5);
|
||||
@@ -0,0 +1,51 @@
|
||||
% out = is_scan_finished(specDatFile,scanno)
|
||||
% Detect 'X# ' in spec file to detect the end of a scan
|
||||
% From spec compile post_scan.mac
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 out = is_scan_finished(specDatFile,scanno)
|
||||
|
||||
specDatFile = beamline.find_specDatFile(specDatFile);
|
||||
|
||||
cmd = sprintf('grep -n ''#X %d'' %s', scanno,specDatFile);
|
||||
[~,sysout] = system(cmd);
|
||||
arrout = regexp(sysout,'[:\n]','split');
|
||||
if any(strcmp(arrout,sprintf('#X %d',scanno)))
|
||||
out = true;
|
||||
else
|
||||
out = false;
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,56 @@
|
||||
% out = is_scan_started(specDatFile,scanno)
|
||||
% Detect 'X# ' in spec file to detect the end of a scan
|
||||
% From spec compile post_scan.mac
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 out = is_scan_started(specDatFile,scanno)
|
||||
|
||||
specDatFile = beamline.find_specDatFile(specDatFile);
|
||||
|
||||
cmd = sprintf('grep -n ''#S %d'' %s', scanno,specDatFile);
|
||||
[~,sysout] = system(cmd);
|
||||
arrout = regexp(sysout,'[:\n ]','split');
|
||||
indS = find(strcmp(regexp(sysout,'[:\n ]','split'),'#S')==1); % Indices where #S is found
|
||||
for ii=indS % Loop over all #S found, this is to make sure we dont recognize S# 191 when looking for S# 19
|
||||
if strcmp(arrout(ii+1),sprintf('%d',scanno))
|
||||
out = true;
|
||||
return
|
||||
end
|
||||
end
|
||||
% If not found
|
||||
out = false;
|
||||
return
|
||||
end
|
||||
@@ -0,0 +1,60 @@
|
||||
% If you do scans with different marks for energy you can use this code to
|
||||
% calibrate the marks vs energy
|
||||
% Run this code, it will save a calibration and then you can use
|
||||
% energy2mark function
|
||||
|
||||
% User input
|
||||
scans = [134:163];
|
||||
marks = [0:0.2:5.99];
|
||||
|
||||
data = io.spec_read('~/Data10/','ScanNr',scans);
|
||||
|
||||
clear E
|
||||
for ii = 1:numel(data)
|
||||
E(ii) = data{ii}.mokev;
|
||||
end
|
||||
|
||||
% Remove the last
|
||||
E = E(1:end-1);
|
||||
marks = marks(1:end-1);
|
||||
|
||||
figure(1);
|
||||
plot(E,marks,'o-')
|
||||
xlabel('E (keV)')
|
||||
ylabel('marks')
|
||||
|
||||
save('mark_calib.mat','marks','E');
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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.
|
||||
@@ -0,0 +1,74 @@
|
||||
%MASK2IND
|
||||
% convert a 2D binary mask to indices
|
||||
%
|
||||
% ** mask 2D binary mask
|
||||
%
|
||||
% returns:
|
||||
% ++ s mask structure; must contain s.indices and s.framesize
|
||||
%
|
||||
% see also: beamline.ind2mask
|
||||
|
||||
% Academic License Agreement
|
||||
%
|
||||
% Source Code
|
||||
%
|
||||
% Introduction
|
||||
% • This license agreement sets forth the terms and conditions under which the PAUL SCHERRER INSTITUT (PSI), CH-5232 Villigen-PSI, Switzerland (hereafter "LICENSOR")
|
||||
% will grant you (hereafter "LICENSEE") a royalty-free, non-exclusive license for academic, non-commercial purposes only (hereafter "LICENSE") to use the cSAXS
|
||||
% ptychography MATLAB package computer software program and associated documentation furnished hereunder (hereafter "PROGRAM").
|
||||
%
|
||||
% Terms and Conditions of the LICENSE
|
||||
% 1. LICENSOR grants to LICENSEE a royalty-free, non-exclusive license to use the PROGRAM for academic, non-commercial purposes, upon the terms and conditions
|
||||
% hereinafter set out and until termination of this license as set forth below.
|
||||
% 2. LICENSEE acknowledges that the PROGRAM is a research tool still in the development stage. The PROGRAM is provided without any related services, improvements
|
||||
% or warranties from LICENSOR and that the LICENSE is entered into in order to enable others to utilize the PROGRAM in their academic activities. It is the
|
||||
% LICENSEE’s responsibility to ensure its proper use and the correctness of the results.”
|
||||
% 3. THE PROGRAM IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR
|
||||
% A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. IN NO EVENT SHALL THE LICENSOR, THE AUTHORS OR THE COPYRIGHT
|
||||
% HOLDERS BE LIABLE FOR ANY CLAIM, DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR OTHER LIABILITY ARISING FROM, OUT OF OR IN CONNECTION WITH THE PROGRAM OR THE USE
|
||||
% OF THE PROGRAM OR OTHER DEALINGS IN THE PROGRAM.
|
||||
% 4. LICENSEE agrees that it will use the PROGRAM and any modifications, improvements, or derivatives of PROGRAM that LICENSEE may create (collectively,
|
||||
% "IMPROVEMENTS") solely for academic, non-commercial purposes and that any copy of PROGRAM or derivatives thereof shall be distributed only under the same
|
||||
% license as PROGRAM. The terms "academic, non-commercial", as used in this Agreement, mean academic or other scholarly research which (a) is not undertaken for
|
||||
% profit, or (b) is not intended to produce works, services, or data for commercial use, or (c) is neither conducted, nor funded, by a person or an entity engaged
|
||||
% in the commercial use, application or exploitation of works similar to the PROGRAM.
|
||||
% 5. LICENSEE agrees that it shall make the following acknowledgement in any publication resulting from the use of the PROGRAM or any translation of the code into
|
||||
% another computing language:
|
||||
% "Data processing was carried out using the cSAXS ptychography MATLAB package developed by the Science IT and the coherent X-ray scattering (CXS) groups, Paul
|
||||
% Scherrer Institut, Switzerland."
|
||||
%
|
||||
% Additionally, any publication using the package, or any translation of the code into another computing language should cite for difference map:
|
||||
% P. Thibault, M. Dierolf, A. Menzel, O. Bunk, C. David, F. Pfeiffer, High-resolution scanning X-ray diffraction microscopy, Science 321, 379–382 (2008).
|
||||
% (doi: 10.1126/science.1158573),
|
||||
% for maximum likelihood:
|
||||
% P. Thibault and M. Guizar-Sicairos, Maximum-likelihood refinement for coherent diffractive imaging, New J. Phys. 14, 063004 (2012).
|
||||
% (doi: 10.1088/1367-2630/14/6/063004),
|
||||
% for mixed coherent modes:
|
||||
% P. Thibault and A. Menzel, Reconstructing state mixtures from diffraction measurements, Nature 494, 68–71 (2013). (doi: 10.1038/nature11806),
|
||||
% and/or for multislice:
|
||||
% E. H. R. Tsai, I. Usov, A. Diaz, A. Menzel, and M. Guizar-Sicairos, X-ray ptychography with extended depth of field, Opt. Express 24, 29089–29108 (2016).
|
||||
% (doi: 10.1364/OE.24.029089).
|
||||
% 6. Except for the above-mentioned acknowledgment, LICENSEE shall not use the PROGRAM title or the names or logos of LICENSOR, nor any adaptation thereof, nor the
|
||||
% names of any of its employees or laboratories, in any advertising, promotional or sales material without prior written consent obtained from LICENSOR in each case.
|
||||
% 7. Ownership of all rights, including copyright in the PROGRAM and in any material associated therewith, shall at all times remain with LICENSOR, and LICENSEE
|
||||
% agrees to preserve same. LICENSEE agrees not to use any portion of the PROGRAM or of any IMPROVEMENTS in any machine-readable form outside the PROGRAM, nor to
|
||||
% make any copies except for its internal use, without prior written consent of LICENSOR. LICENSEE agrees to place the following copyright notice on any such copies:
|
||||
% © All rights reserved. PAUL SCHERRER INSTITUT, Switzerland, Laboratory for Macromolecules and Bioimaging, 2017.
|
||||
% 8. The LICENSE shall not be construed to confer any rights upon LICENSEE by implication or otherwise except as specifically set forth herein.
|
||||
% 9. DISCLAIMER: LICENSEE shall be aware that Phase Focus Limited of Sheffield, UK has an international portfolio of patents and pending applications which relate
|
||||
% to ptychography and that the PROGRAM may be capable of being used in circumstances which may fall within the claims of one or more of the Phase Focus patents,
|
||||
% in particular of patent with international application number PCT/GB2005/001464. The LICENSOR explicitly declares not to indemnify the users of the software
|
||||
% in case Phase Focus or any other third party will open a legal action against the LICENSEE due to the use of the program.
|
||||
% 10. This Agreement shall be governed by the material laws of Switzerland and any dispute arising out of this Agreement or use of the PROGRAM shall be brought before
|
||||
% the courts of Zürich, Switzerland.
|
||||
|
||||
|
||||
function [s] = mask2ind(mask)
|
||||
|
||||
s.framesize = size(mask);
|
||||
|
||||
s.indices = find(reshape(mask, 1, [])~=0);
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
%NEXT_SCAN_STARTED if the next scan has started, the first return value is
|
||||
% true.
|
||||
% [started, scanNr] = next_scan_started(specDatFile,scanno);
|
||||
%
|
||||
% ** specDatFile path to the SPEC file / spec directory
|
||||
% ** scanno current scan number
|
||||
%
|
||||
% returns:
|
||||
% ++ started true if scanno is not the last scan
|
||||
% ++ nextScanno next scan number
|
||||
% ++ specDatFile specDatFile used to determine if the next scan has started
|
||||
%
|
||||
% see also: beamline.find_specDatFile
|
||||
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 [started, nextScanno, specDatFile] = next_scan_started(dataPath,scanno)
|
||||
|
||||
specDatFile = beamline.find_specDatFile(dataPath);
|
||||
|
||||
cmd = sprintf('grep ''#S '' %s | grep -A 1 ''#S %d '' | tail -1', specDatFile, scanno);
|
||||
[~,sysout] = system(cmd);
|
||||
arrout = regexp(sysout,'[:\n ]','split');
|
||||
nextScanno = str2double(arrout{2});
|
||||
|
||||
if nextScanno>scanno
|
||||
started = true;
|
||||
else
|
||||
started = false;
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,207 @@
|
||||
% Call function without arguments for instructions on how to use it
|
||||
|
||||
% Filename: $RCSfile: pilatus_valid_pixel_roi.m,v $
|
||||
%
|
||||
% $Revision: 1.5 $ $Date: 2011/05/19 16:44:24 $
|
||||
% $Author: $
|
||||
% $Tag: $
|
||||
%
|
||||
% Description:
|
||||
% cut out of the valid pixel mask for the full detector the one for the
|
||||
% current region of interest
|
||||
%
|
||||
% Note:
|
||||
% The location of the ROI is not stored in the data files. It is deduced
|
||||
% from the known readoiut modes. So far only the 1x2 module mode is
|
||||
% implemented.
|
||||
%
|
||||
% Dependencies:
|
||||
% none
|
||||
%
|
||||
% history:
|
||||
%
|
||||
% January 31st 2009: add arbitrary ROIs via named parameters
|
||||
%
|
||||
% May 9th 2008: 1st version
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| Except where otherwise noted, this work is licensed under a |
|
||||
%| Creative Commons Attribution-NonCommercial-ShareAlike 4.0 |
|
||||
%| International (CC BY-NC-SA 4.0) license. |
|
||||
%| |
|
||||
%| Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch) |
|
||||
%| |
|
||||
%| Author: CXS group, PSI |
|
||||
%*-----------------------------------------------------------------------*
|
||||
% You may use this code with the following provisions:
|
||||
%
|
||||
% If the code is fully or partially redistributed, or rewritten in another
|
||||
% computing language this notice should be included in the redistribution.
|
||||
%
|
||||
% If this code, or subfunctions or parts of it, is used for research in a
|
||||
% publication or if it is fully or partially rewritten for another
|
||||
% computing language the authors and institution should be acknowledged
|
||||
% in written form in the publication: “Data processing was carried out
|
||||
% using the “cSAXS matlab package” developed by the CXS group,
|
||||
% Paul Scherrer Institut, Switzerland.”
|
||||
% Variations on the latter text can be incorporated upon discussion with
|
||||
% the CXS group if needed to more specifically reflect the use of the package
|
||||
% for the published work.
|
||||
%
|
||||
% A publication that focuses on describing features, or parameters, that
|
||||
% are already existing in the code should be first discussed with the
|
||||
% authors.
|
||||
%
|
||||
% This code and subroutines are part of a continuous development, they
|
||||
% are provided “as they are” without guarantees or liability on part
|
||||
% of PSI or the authors. It is the user responsibility to ensure its
|
||||
% proper use and the correctness of the results.
|
||||
|
||||
function [valid_mask] = pilatus_valid_pixel_roi(valid_mask,varargin)
|
||||
|
||||
% sub-detector readout size
|
||||
roi_size = [];
|
||||
|
||||
% alternatively:
|
||||
% from/to row 0 means all rows
|
||||
row_from = 0;
|
||||
row_to = 0;
|
||||
% from/to column 0 means all lines
|
||||
column_from = 0;
|
||||
column_to = 0;
|
||||
|
||||
% accept cell array with name/value pairs as well
|
||||
no_of_in_arg = nargin;
|
||||
if (nargin == 2)
|
||||
if (isempty(varargin))
|
||||
% ignore empty cell array
|
||||
no_of_in_arg = no_of_in_arg -1;
|
||||
else
|
||||
if (iscell(varargin{1}))
|
||||
% use a filled one given as first and only variable parameter
|
||||
varargin = varargin{1};
|
||||
no_of_in_arg = 1 + length(varargin);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% check number of input arguments
|
||||
if ((nargin < 1) || (rem(no_of_in_arg,2) ~= 1))
|
||||
fprintf('Usage:\n')
|
||||
fprintf('%s(valid_mask,[[<name>,<value>], ...]);\n',mfilename);
|
||||
fprintf('The name value pairs are:\n');
|
||||
fprintf('''RoiSize'',[<size-y> <size-x>] size of sub-detector readout ROIs\n');
|
||||
fprintf('Alternatively:\n');
|
||||
fprintf('''RowFrom'',<0-max> region of interest definition, 0 for full frame\n');
|
||||
fprintf('''RowTo'',<0-max> region of interest definition, 0 for full frame\n');
|
||||
fprintf('''ColumnFrom'',<0-max> region of interest definition, 0 for full frame\n');
|
||||
fprintf('''ColumnTo'',<0-max> region of interest definition, 0 for full frame\n');
|
||||
fprintf('''ROI'',s[ <ColumnFrom> <RowFrom> <ColumnTo> <RowTo> ]\n');
|
||||
fprintf(' region of interest definition of all four coordinates together\n');
|
||||
end
|
||||
|
||||
|
||||
% parse the variable input arguments
|
||||
vararg = cell(0,0);
|
||||
for ind = 1:2:length(varargin)
|
||||
name = varargin{ind};
|
||||
value = varargin{ind+1};
|
||||
switch name
|
||||
case 'ROI'
|
||||
if (length(value) ~= 4)
|
||||
error('The ROI parameter needs a vector of length four as argument.');
|
||||
end
|
||||
column_from = value(1);
|
||||
row_from = value(2);
|
||||
column_to = value(3);
|
||||
row_to = value(4);
|
||||
case 'RowFrom'
|
||||
row_from = value;
|
||||
roi_size = [];
|
||||
case 'RowTo'
|
||||
row_to = value;
|
||||
roi_size = [];
|
||||
case 'ColumnFrom'
|
||||
column_from = value;
|
||||
roi_size = [];
|
||||
case 'ColumnTo'
|
||||
column_to = value;
|
||||
roi_size = [];
|
||||
case 'RoiSize'
|
||||
roi_size = value;
|
||||
otherwise
|
||||
vararg{end+1} = name; %#ok<AGROW>
|
||||
vararg{end+1} = value; %#ok<AGROW>
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
% if (valid_mask.framesize ~= [1679 1475])
|
||||
% error('can not handle the source size (%d,%d)',...
|
||||
% valid_mask.framesize(1),valid_mask.framesize(2));
|
||||
% end
|
||||
|
||||
|
||||
if (isempty(roi_size))
|
||||
if (row_from < 1)
|
||||
row_from = 1;
|
||||
end
|
||||
if (row_to < 1)
|
||||
row_to = valid_mask.framesize(1);
|
||||
end
|
||||
if (column_from < 1)
|
||||
column_from = 1;
|
||||
end
|
||||
if (column_to < 1)
|
||||
column_to = valid_mask.framesize(2);
|
||||
end
|
||||
% nothing to do
|
||||
if ((row_from == 1) && (column_from == 1) && ...
|
||||
(row_to == valid_mask.framesize(1)) && (column_to == valid_mask.framesize(2)))
|
||||
return;
|
||||
end
|
||||
|
||||
x_from = column_from;
|
||||
y_from = row_from;
|
||||
roi_size = [ row_to-row_from+1 column_to-column_from+1 ];
|
||||
else
|
||||
% nothing to do
|
||||
if (valid_mask.framesize == roi_size)
|
||||
return;
|
||||
end
|
||||
|
||||
% determine the location of the ROI from its size via the known modi
|
||||
x_from = 0;
|
||||
y_from = 0;
|
||||
% two modules
|
||||
if (roi_size == [407 487])
|
||||
x_from = 495;
|
||||
y_from = 637;
|
||||
end
|
||||
if (roi_size == [831 1475])
|
||||
x_from = 1;
|
||||
y_from = 425;
|
||||
end
|
||||
if (roi_size == [831 981])
|
||||
x_from = 495;
|
||||
y_from = 425;
|
||||
end
|
||||
if ((x_from == 0) || (y_from == 0))
|
||||
error('can not handle the ROI size (%d,%d)',roi_size(1),roi_size(2));
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
% create the full valid pixel mask
|
||||
vpm = zeros(valid_mask.framesize);
|
||||
vpm(valid_mask.indices) = 1;
|
||||
% cut out the region of interest
|
||||
vpm = vpm(y_from:(y_from+roi_size(1)-1), ...
|
||||
x_from:(x_from+roi_size(2)-1));
|
||||
|
||||
% return the indices of valid pixels within this ROI
|
||||
valid_mask.indices = find(vpm == 1);
|
||||
valid_mask.framesize = size(vpm);
|
||||
@@ -0,0 +1,456 @@
|
||||
% Call function without arguments for instructions on how to use it
|
||||
|
||||
% Filename: $RCSfile: prep_integ_masks.m,v $
|
||||
%
|
||||
% $Revision: 1.9 $ $Date: 2016/01/21 14:51:57 $
|
||||
% $Author: $
|
||||
% $Tag: $
|
||||
%
|
||||
% Description:
|
||||
% prepare masks for the radial integration of SAXS patterns
|
||||
%
|
||||
% Note:
|
||||
% Call without arguments for a brief help text.
|
||||
%
|
||||
% Dependencies:
|
||||
% - image_read
|
||||
% - pilatus_valid_pixel_roi
|
||||
%
|
||||
% history:
|
||||
%
|
||||
% September 4th 2009:
|
||||
% correct in help text one of the RadiusFrom to RadiusTo
|
||||
%
|
||||
% May 9th 2008: 1st documented version
|
||||
%
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| Except where otherwise noted, this work is licensed under a |
|
||||
%| Creative Commons Attribution-NonCommercial-ShareAlike 4.0 |
|
||||
%| International (CC BY-NC-SA 4.0) license. |
|
||||
%| |
|
||||
%| Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch) |
|
||||
%| |
|
||||
%| Author: CXS group, PSI |
|
||||
%*-----------------------------------------------------------------------*
|
||||
% You may use this code with the following provisions:
|
||||
%
|
||||
% If the code is fully or partially redistributed, or rewritten in another
|
||||
% computing language this notice should be included in the redistribution.
|
||||
%
|
||||
% If this code, or subfunctions or parts of it, is used for research in a
|
||||
% publication or if it is fully or partially rewritten for another
|
||||
% computing language the authors and institution should be acknowledged
|
||||
% in written form in the publication: “Data processing was carried out
|
||||
% using the “cSAXS matlab package” developed by the CXS group,
|
||||
% Paul Scherrer Institut, Switzerland.”
|
||||
% Variations on the latter text can be incorporated upon discussion with
|
||||
% the CXS group if needed to more specifically reflect the use of the package
|
||||
% for the published work.
|
||||
%
|
||||
% A publication that focuses on describing features, or parameters, that
|
||||
% are already existing in the code should be first discussed with the
|
||||
% authors.
|
||||
%
|
||||
% This code and subroutines are part of a continuous development, they
|
||||
% are provided “as they are” without guarantees or liability on part
|
||||
% of PSI or the authors. It is the user responsibility to ensure its
|
||||
% proper use and the correctness of the results.
|
||||
|
||||
function [ integ_masks ] = prep_integ_masks(filename, center_xy, varargin)
|
||||
import beamline.pilatus_valid_pixel_roi
|
||||
import io.image_read
|
||||
import plotting.display_valid_mask
|
||||
import utils.pixel_to_q
|
||||
|
||||
% set number of radii
|
||||
no_of_radii = 0;
|
||||
% number of angular segments per radius
|
||||
no_of_segments = 1;
|
||||
% pixel size in mm
|
||||
pixel_size_mm = [];%.172;
|
||||
% detector distance in mm
|
||||
det_dist_mm = [];%2000;
|
||||
calculate_q=0; %only calculate q if exact detector distance is given
|
||||
% wavelength (unit inconsequential, will be reflected in q)
|
||||
lambda = [];%1;
|
||||
% output directory for the masks
|
||||
out_dir = '~/Data10/analysis/data/';
|
||||
filename_valid_mask = [ out_dir 'pilatus_valid_mask.mat' ];
|
||||
filename_integ_masks = [ out_dir 'pilatus_integration_masks.mat' ];
|
||||
% output figure number
|
||||
fig_no = 240;
|
||||
% save integration masks
|
||||
save_data = 1;
|
||||
% display valid pixel mask
|
||||
display_valid_mask_flag = 1;
|
||||
% detector number
|
||||
det_no= 1;
|
||||
% angular range to be excluded to cut out the beam stop
|
||||
bs_angle_from = 0;
|
||||
bs_angle_to = 0;
|
||||
|
||||
% check minimum number of input arguments
|
||||
if (nargin < 2)
|
||||
fprintf('\nUsage:\n');
|
||||
fprintf('[integ_masks]=%s( filename, center_xy [[,<name>,<value>]...]);\n',mfilename);
|
||||
fprintf('Prepare the masks for an efficient radial integration.\n');
|
||||
fprintf('The optional angular range in degree can be used to cut out a beam stop.\n');
|
||||
fprintf('Angle 0 is horizontally to the left, positive in counterclockwise direction.\n');
|
||||
fprintf('The specified data file is loaded and some of the integration masks are plotted into that frame.\n');
|
||||
fprintf('\n');
|
||||
fprintf('The optional <name>,<value> pairs are:\n');
|
||||
|
||||
fprintf('''NormalXY'',[x y] pixel coordinates, from where the detector normal points\n');
|
||||
fprintf(' toward the sample. Default is equal to center_xy\n');
|
||||
fprintf('''PixelSize_mm'',<double> pixel size in mm, default is %.3f\n',pixel_size_mm);
|
||||
fprintf('''DetDist_mm'',<double> detector distance in mm, default is %.1f\n',det_dist_mm);
|
||||
fprintf('''Wavelength'',<double> wavelength. The units chosen here will determine the units of q\n');
|
||||
fprintf(' The defaults is %.1f\n',lambda);
|
||||
fprintf('''NoOfRadii'',<integer> radial integration start radius, default is %d\n',no_of_radii);
|
||||
fprintf(' or ,<vector>, defining the limits of radius bins\n');
|
||||
fprintf('''NoOfSegments'',<integer> Number of angular segments. If an integer, this number of equally wide azimuthal\n')
|
||||
fprintf(' bins over 360 degrees are created. default is %d\n',no_of_segments);
|
||||
fprintf(' or ,<vector>, defining the limits of angular bins\n');
|
||||
fprintf('''SaveData'',<0-no,1-yes> save the integration masks, default is %d\n',save_data);
|
||||
fprintf('''FilenameValidMask'',<path and filename> Matlab file with the valid pixel indices ind_valid,\n');
|
||||
fprintf(' default is %s\n',filename_valid_mask);
|
||||
fprintf('''FilenameIntegMasks'',<path and filename> output file name for the structure integ_masks,\n');
|
||||
fprintf(' default is %s\n',filename_integ_masks);
|
||||
fprintf('''FigNo'',<integer> number of the figure in which the result is displayed\n');
|
||||
fprintf('''DetNo'',<integer> number of detector 1 for SAXS and 2 for WAXS\n');
|
||||
fprintf(' Default is 1 (SAXS)\n');
|
||||
fprintf('''BeamstopAngleFrom'',<float> exclude an angular region from the integration, default for the start value is %d\n',...
|
||||
bs_angle_from);
|
||||
fprintf('''BeamstopAngleTo'',<float> exclude an angular region from the integration, default for the end value is %d\n',...
|
||||
bs_angle_to);
|
||||
fprintf('\n');
|
||||
fprintf('\n');
|
||||
fprintf('The file name should be the name of a single file without wildcards\n');
|
||||
fprintf('that is displayed as an example.\n');
|
||||
fprintf('The image file has no other function beyond being displayed as example.\n');
|
||||
fprintf('Example:\n');
|
||||
fprintf('[integ_masks]=%s(''~/Data10/pilatus/image.cbf'',[512 512]);\n',...
|
||||
mfilename);
|
||||
|
||||
error('At least the filename and the beam center have to be specified as input parameter.');
|
||||
end
|
||||
|
||||
% check number of center coordinates
|
||||
if (length(center_xy) ~= 2)
|
||||
error('The beam center needs to be specified as a two component vector [cen_x cen_y].\n');
|
||||
end
|
||||
center_x = center_xy(1);
|
||||
center_y = center_xy(2);
|
||||
norm_x = center_x;
|
||||
norm_y = center_y;
|
||||
|
||||
% accept cell array with name/value pairs as well
|
||||
no_of_in_arg = nargin;
|
||||
if (nargin == 3)
|
||||
if (isempty(varargin))
|
||||
% ignore empty cell array
|
||||
no_of_in_arg = no_of_in_arg -1;
|
||||
else
|
||||
if (iscell(varargin{1}))
|
||||
% use a filled one given as first and only variable parameter
|
||||
varargin = varargin{1};
|
||||
no_of_in_arg = 2 + length(varargin);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% check number of input arguments
|
||||
if (rem(no_of_in_arg,2) ~= 0)
|
||||
error('The optional parameters have to be specified as ''name'',''value'' pairs');
|
||||
end
|
||||
|
||||
|
||||
% parse the variable input arguments
|
||||
vararg = cell(0,0);
|
||||
for ind = 1:2:length(varargin)
|
||||
name = varargin{ind};
|
||||
value = varargin{ind+1};
|
||||
switch name
|
||||
case 'NormalXY'
|
||||
if (numel(value)==2)
|
||||
norm_x = value(1);
|
||||
norm_y = value(2);
|
||||
end
|
||||
case 'PixelSize_mm'
|
||||
pixel_size_mm = value;
|
||||
case 'DetDist_mm'
|
||||
det_dist_mm = value;
|
||||
calculate_q=1;
|
||||
case 'Wavelength_nm'
|
||||
lambda = value;
|
||||
case 'Wavelength'
|
||||
lambda = value/10;
|
||||
case 'NoOfRadii'
|
||||
no_of_radii = value;
|
||||
case 'NoOfSegments'
|
||||
no_of_segments = value;
|
||||
case 'FilenameValidMask'
|
||||
filename_valid_mask = value;
|
||||
case 'FilenameIntegMasks'
|
||||
filename_integ_masks = value;
|
||||
case 'SaveData'
|
||||
save_data = value;
|
||||
case 'DisplayValidMask'
|
||||
display_valid_mask_flag = value;
|
||||
case 'FigNo'
|
||||
fig_no = value;
|
||||
case 'DetNo'
|
||||
det_no = value;
|
||||
case 'BeamstopAngleFrom'
|
||||
bs_angle_from = value;
|
||||
case 'BeamstopAngleTo'
|
||||
bs_angle_to = value;
|
||||
otherwise
|
||||
vararg{end+1} = name;
|
||||
vararg{end+1} = value;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
% MGS - The fact that the detector number is dictating whether to have a
|
||||
% radius variable or q is not ideal. Additional arguments should be given
|
||||
% for this such as calculate_q or save_radius_var.
|
||||
% initialize return arguments
|
||||
if (det_no == 1)||(det_no == 3)
|
||||
calculate_radius = true;
|
||||
elseif (det_no == 2)
|
||||
calculate_radius = false;
|
||||
else
|
||||
error('Only det_no 1, 2, and 3 are recognized')
|
||||
end
|
||||
if ( calculate_radius ) && (calculate_q)
|
||||
integ_masks = struct('radius',[], 'indices',[], 'norm_sum', [],'q',[]);
|
||||
elseif (calculate_radius) && (calculate_q == 0)
|
||||
integ_masks = struct('radius',[], 'indices',[], 'norm_sum', []);
|
||||
elseif (~calculate_radius)
|
||||
integ_masks = struct('indices',[], 'norm_sum', [],'q',[]);
|
||||
end
|
||||
|
||||
|
||||
% check radius
|
||||
%if (exist('r_from','var'))
|
||||
if (size(no_of_radii)>1)
|
||||
if (no_of_radii(1) < 1)
|
||||
%if (r_from < 1)
|
||||
error('The minimum radius is 1, %d is invalid.',r_from);
|
||||
end
|
||||
%end
|
||||
%if (exist('r_from','var') && exist('r_to','var'))
|
||||
if (no_of_radii(end) < no_of_radii(1))
|
||||
%if ((r_to ~= 0) && (r_to < r_from))
|
||||
error('The maximum radius must be greater than the minimum one, %d is invalid.\n',no_of_radii(end));
|
||||
end
|
||||
end
|
||||
|
||||
% check number of angular segments
|
||||
if (no_of_segments < 1)
|
||||
error('The number of angular segments must be at least 1');
|
||||
end
|
||||
if (numel(no_of_segments)>1)
|
||||
angular_segments = no_of_segments;
|
||||
no_of_segments = numel(no_of_segments)-1;
|
||||
else
|
||||
angular_segments = 360/no_of_segments * (0:no_of_segments);
|
||||
end
|
||||
angular_segments = mod(angular_segments, 360);
|
||||
|
||||
% check beamstop region
|
||||
if ((bs_angle_from < 0.0) || (bs_angle_to > 360.0))
|
||||
error('The angular range for the beam stop region is 0 to 360 degree.');
|
||||
end
|
||||
if (bs_angle_to < bs_angle_from)
|
||||
error('The maximum beam stop angle must be less than or equal to the minimum one.\n');
|
||||
end
|
||||
|
||||
% load the indices of valid pixels
|
||||
fprintf('loading the valid pixel mask %s\n',filename_valid_mask);
|
||||
load(filename_valid_mask);
|
||||
dim_x = valid_mask.framesize(2);
|
||||
dim_y = valid_mask.framesize(1);
|
||||
|
||||
|
||||
if (~isempty(filename))
|
||||
% load test frame
|
||||
frame = image_read(filename,vararg);
|
||||
% select the first frame for display
|
||||
frame.data = frame.data(:,:,1);
|
||||
% in case of less than full detector readout cut out the right part of
|
||||
% the valid pixel mask
|
||||
valid_mask = pilatus_valid_pixel_roi(valid_mask,'RoiSize',size(frame.data));
|
||||
dim_x = size(frame.data,2);
|
||||
dim_y = size(frame.data,1);
|
||||
end
|
||||
|
||||
% plot valid pixel mask
|
||||
if (display_valid_mask_flag)
|
||||
figure(fig_no);
|
||||
vpm = zeros(dim_y,dim_x);
|
||||
vpm(valid_mask.indices) = 1;
|
||||
imagesc(vpm);
|
||||
axis xy;
|
||||
axis equal;
|
||||
axis tight;
|
||||
title('valid pixels');
|
||||
set(gcf,'Name','valid pixels');
|
||||
drawnow;
|
||||
end
|
||||
|
||||
if calculate_radius
|
||||
%if (exist('r_to','var'))
|
||||
% choose maximum radius, if specified via r_to=0
|
||||
if (no_of_radii < 1)
|
||||
no_of_radii = max( [ sqrt(center_x^2+center_y^2) ...
|
||||
sqrt((dim_x-center_x)^2+center_y^2) ...
|
||||
sqrt(center_x^2+(dim_y-center_y)^2) ...
|
||||
sqrt((dim_x-center_x)^2+(dim_y-center_y)^2) ] );
|
||||
end
|
||||
if size(no_of_radii)==1
|
||||
no_of_radii=1:1:no_of_radii;
|
||||
end
|
||||
end
|
||||
|
||||
fprintf('preparing the integration masks ...\n');
|
||||
|
||||
% create an array of the (x,y) coordinates relative to the beam center and
|
||||
% convert it to polar coordinates
|
||||
%
|
||||
if calculate_radius % For SAXS detector - MGS, should be fixed, why is it neded different calculation for different detectors?
|
||||
% angular range to be excluded to cut out the beam stop
|
||||
|
||||
[ x, y ] = meshgrid( (1:dim_x)-center_x, (1:dim_y)-center_y );
|
||||
[ theta, rho ] = cart2pol( x, y );
|
||||
% convert angular range from -pi/pi to 0/360
|
||||
theta = (theta/pi +1) * 180.0;
|
||||
|
||||
% prepare circular masks of the integer width r_step (in pixel)
|
||||
integ_masks.radius = no_of_radii;
|
||||
r_step=no_of_radii(2)-no_of_radii(1);
|
||||
if calculate_q
|
||||
integ_masks.q = pixel_to_q(no_of_radii,pixel_size_mm,det_dist_mm, 12.39852/lambda);
|
||||
end
|
||||
no_of_radii = length(integ_masks.radius);
|
||||
integ_masks.indices = cell( no_of_radii, no_of_segments );
|
||||
integ_masks.norm_sum = zeros( no_of_radii, no_of_segments );
|
||||
seg_inds = cell(no_of_segments,1);
|
||||
for ind_seg = 1:no_of_segments
|
||||
seg_from = angular_segments(ind_seg);
|
||||
seg_to = angular_segments(ind_seg+1);
|
||||
if (seg_from >= seg_to)
|
||||
ind_curr = find( ((theta > seg_from) | (theta <= seg_to) ) & ...
|
||||
((theta <= bs_angle_from) | (theta >= bs_angle_to)) );
|
||||
else
|
||||
ind_curr = find( ((theta > seg_from) & (theta <= seg_to) ) & ...
|
||||
((theta <= bs_angle_from) | (theta >= bs_angle_to)) );
|
||||
end
|
||||
% only take valid pixels into account
|
||||
ind_curr = intersect(ind_curr, valid_mask.indices);
|
||||
seg_inds{ind_seg} = ind_curr;
|
||||
end
|
||||
|
||||
for ind_r=1:no_of_radii
|
||||
if (rem(ind_r,100) == 0)
|
||||
fprintf('%4d / %d',ind_r,no_of_radii);
|
||||
if (ind_r <= no_of_radii-100)
|
||||
fprintf(', ');
|
||||
end
|
||||
end
|
||||
r_inds = find( (rho >= integ_masks.radius(ind_r)) & ...
|
||||
(rho < integ_masks.radius(ind_r)+r_step) );
|
||||
for ind_seg = 1:no_of_segments
|
||||
integ_masks.indices{ind_r, ind_seg} = intersect( r_inds, seg_inds{ind_seg} );
|
||||
% calculate the normalization value (sum of the pixels within the mask)
|
||||
integ_masks.norm_sum(ind_r, ind_seg) = ...
|
||||
length( integ_masks.indices{ind_r, ind_seg} );
|
||||
end
|
||||
end
|
||||
fprintf('\n');
|
||||
|
||||
else
|
||||
[ x, y ] = meshgrid( (1:dim_x)-norm_x, (1:dim_y)-norm_y );
|
||||
if (norm_x == center_x && norm_y == center_y)
|
||||
[ theta, rho ] = cart2pol( x, y );
|
||||
q = 4*pi/lambda*sin(atan2(rho,det_dist_mm/pixel_size_mm)/2);
|
||||
% convert angular range from -pi/pi to 0/360
|
||||
theta = theta/pi*180.0;
|
||||
else
|
||||
if (norm_x ~= center_x)
|
||||
angle = atan((norm_x - center_x) / (det_dist_mm/pixel_size_mm));
|
||||
z = -x*sin(angle) + det_dist_mm/pixel_size_mm*cos(angle);
|
||||
x = x*cos(angle) + det_dist_mm/pixel_size_mm*sin(angle);
|
||||
else
|
||||
fprintf('not implemented yet!!!\n');
|
||||
exit
|
||||
end
|
||||
q = 4*pi/lambda*sin(atan2(sqrt(x.^2 + y.^2),z)/2);
|
||||
theta = atan2(y,x)/pi*180;
|
||||
end
|
||||
t_1d = reshape(theta(valid_mask.indices),1,[]);
|
||||
q_1d = reshape(q(valid_mask.indices),1,[]);
|
||||
|
||||
t_ed = linspace( -180, 180,1e0+1);
|
||||
integ_masks.theta = t_ed(1:end-1);
|
||||
integ_masks.theta_end = t_ed(end);
|
||||
q_ed = linspace(min(q_1d),max(q_1d),1e3+1);
|
||||
integ_masks.q = q_ed(1:end-1);
|
||||
integ_masks.q_end = q_ed(end);
|
||||
|
||||
[~,t_bin] = histc(t_1d,t_ed);
|
||||
[~,q_bin] = histc(q_1d,q_ed);
|
||||
|
||||
integ_masks.indices = cell(numel(q_ed)-1,numel(t_ed)-1);
|
||||
integ_masks.norm_sum = zeros(size(integ_masks.indices));
|
||||
for q_i=1:numel(q_ed)-1
|
||||
for t_i=1:numel(t_ed)-1
|
||||
integ_masks.indices{q_i,t_i} = ...
|
||||
valid_mask.indices(and(q_bin==q_i,t_bin==t_i));
|
||||
integ_masks.norm_sum(q_i,t_i) = numel(integ_masks.indices{q_i,t_i});
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
% save integration masks
|
||||
if (save_data)
|
||||
fprintf('Saving center_xy, no_of_segments, integ_masks to %s\n',...
|
||||
filename_integ_masks);
|
||||
if angular_segments(end) == 0
|
||||
angular_segments(end) = 360;
|
||||
end
|
||||
phi_det = (angular_segments(2:end) + angular_segments(1:end-1))/2; %% Center of the angular sector in degrees
|
||||
save(filename_integ_masks,'center_xy','no_of_segments','integ_masks','angular_segments','phi_det');
|
||||
end
|
||||
|
||||
% display some integration circles
|
||||
if (~isempty(filename))
|
||||
figure(fig_no+1);
|
||||
hold off;
|
||||
clf;
|
||||
frame_plot = double(frame.data);
|
||||
frame_plot( frame_plot < 1 ) = 1;
|
||||
|
||||
plot_step = round(length(integ_masks.indices)/50);
|
||||
if (plot_step < 2)
|
||||
plot_step = 2;
|
||||
end
|
||||
for (ind_r = 1:plot_step:size(integ_masks.indices,1))
|
||||
for (ind_seg = 1:2:no_of_segments)
|
||||
frame_plot(integ_masks.indices{ind_r,ind_seg}) = 10^(6*ind_seg/no_of_segments);
|
||||
end
|
||||
end
|
||||
|
||||
imagesc(log10(frame_plot));
|
||||
axis xy;
|
||||
axis equal;
|
||||
axis tight;
|
||||
colorbar;
|
||||
title([ 'integration segment test plot for ' strrep(filename,'_','\_') ]);
|
||||
set(gcf,'Name','integration masks');
|
||||
end
|
||||
@@ -0,0 +1,345 @@
|
||||
% Call function without arguments for instructions on how to use it
|
||||
|
||||
% Filename: $RCSfile: prep_valid_mask.m,v $
|
||||
%
|
||||
% $Revision: 1.8 $ $Date: 2016/01/21 15:07:41 $
|
||||
% $Author: guizar_m $
|
||||
% $Tag: $
|
||||
%
|
||||
% Description:
|
||||
% prepare a list of the linear indices for the valid pixels
|
||||
%
|
||||
% Note:
|
||||
% Call without arguments for a brief help text.
|
||||
%
|
||||
% Dependencies:
|
||||
% - image_read
|
||||
%
|
||||
% history:
|
||||
%
|
||||
% May 15th 2010, Oliver Bunk:
|
||||
% add command line argument for ThresholdMedian
|
||||
%
|
||||
% September 4th 2009, Oliver Bunk:
|
||||
% use find_files rather than dir to find the files
|
||||
%
|
||||
% May 9th 2008, Oliver Bunk: 1st documented version
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| Except where otherwise noted, this work is licensed under a |
|
||||
%| Creative Commons Attribution-NonCommercial-ShareAlike 4.0 |
|
||||
%| International (CC BY-NC-SA 4.0) license. |
|
||||
%| |
|
||||
%| Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch) |
|
||||
%| |
|
||||
%| Author: CXS group, PSI |
|
||||
%*-----------------------------------------------------------------------*
|
||||
% You may use this code with the following provisions:
|
||||
%
|
||||
% If the code is fully or partially redistributed, or rewritten in another
|
||||
% computing language this notice should be included in the redistribution.
|
||||
%
|
||||
% If this code, or subfunctions or parts of it, is used for research in a
|
||||
% publication or if it is fully or partially rewritten for another
|
||||
% computing language the authors and institution should be acknowledged
|
||||
% in written form in the publication: “Data processing was carried out
|
||||
% using the “cSAXS matlab package” developed by the CXS group,
|
||||
% Paul Scherrer Institut, Switzerland.”
|
||||
% Variations on the latter text can be incorporated upon discussion with
|
||||
% the CXS group if needed to more specifically reflect the use of the package
|
||||
% for the published work.
|
||||
%
|
||||
% A publication that focuses on describing features, or parameters, that
|
||||
% are already existing in the code should be first discussed with the
|
||||
% authors.
|
||||
%
|
||||
% This code and subroutines are part of a continuous development, they
|
||||
% are provided “as they are” without guarantees or liability on part
|
||||
% of PSI or the authors. It is the user responsibility to ensure its
|
||||
% proper use and the correctness of the results.
|
||||
|
||||
|
||||
function [valid_mask] = prep_valid_mask(data_dir, varargin)
|
||||
import io.image_read
|
||||
import plotting.display_valid_mask
|
||||
import utils.find_files
|
||||
|
||||
% initialize return arguments
|
||||
valid_mask = struct('indices',[], 'framesize',[]);
|
||||
|
||||
% set default values for the variable input arguments:
|
||||
% use all cbf files
|
||||
filename_mask = '*.cbf';
|
||||
% filename for loading and saving the valid pixel mask
|
||||
filename_valid_mask = '~/Data10/analysis/data/pilatus_valid_mask.mat';
|
||||
% below this threshold intensity a pixel is considered to be dark
|
||||
threshold_dark = 1;
|
||||
% above this threshold intensity a pixel is considered to be hot
|
||||
threshold_hot = 20;
|
||||
% this value times the square root of the intensity is used as hot pixel
|
||||
% threshold
|
||||
threshold_median = 5.0;
|
||||
% replace the existing mask
|
||||
extend = 'no';
|
||||
% save the mask
|
||||
save_data = 1;
|
||||
% display result in this figure
|
||||
fig_no = 200;
|
||||
|
||||
% check minimum number of input arguments
|
||||
if (nargin < 1)
|
||||
fprintf('\nUsage:\n');
|
||||
fprintf('[valid_mask]=%s(data_dir [[,<name>,<value>]...]);\n',mfilename);
|
||||
fprintf('Prepare a list of the linear indices for the valid pixels.\n');
|
||||
fprintf('To get reliable data a series of at least 10 frames should be analyzed.\n');
|
||||
fprintf('The direct beam region will be regarded as invalid since it is out of the\n');
|
||||
fprintf('range for valid pixels. To ''repair'' this one should take a second series of\n');
|
||||
fprintf('exposures at a different detector position and call this macro with the ''Extend'',''or''\n');
|
||||
fprintf('option.\n');
|
||||
fprintf('\n');
|
||||
fprintf('The optional <name>,<value> pairs are:\n');
|
||||
fprintf('''FilenameMask'',<file specifier> specify the files to be used from the data directory, empty string for all, default is ''%s''\n',...
|
||||
filename_mask);
|
||||
fprintf('''ThresholdDark'',<float> pixels permanently below this value are considered to be dark, default is %d\n',...
|
||||
threshold_dark);
|
||||
fprintf('''ThresholdHot'',<float> pixels at least once above this value are considered to be hot, default is %d\n',...
|
||||
threshold_hot);
|
||||
fprintf('''ThresholdMedian'',<float> pixels of intensity I above the constant ThresholdHot and above\n');
|
||||
fprintf(' ThresholdMedian times (I+sqrt(I)) are considered to be hot, 0 to deactivate this additional threshold,\n');
|
||||
fprintf(' default is %.1f\n',...
|
||||
threshold_median);
|
||||
fprintf('''SaveData'',<0-no,1-yes> save the valid pixel mask, default is %d\n',save_data);
|
||||
fprintf('''FilenameValidMask'',<path and filename> Matlab file with the valid pixel indices,\n');
|
||||
fprintf(' default is %s\n',filename_valid_mask);
|
||||
fprintf('''Extend'',<''and'', ''or'' or ''no''> update an existing mask using the specified conjunction, default is %s\n',...
|
||||
extend);
|
||||
fprintf('''FigNo'',<integer> number of the figure in which the result is displayed, default is %d\n',...
|
||||
fig_no);
|
||||
fprintf('\n');
|
||||
fprintf('Examples:\n');
|
||||
fprintf('[valid_mask]=%s(''~/Data10/pilatus/air_scattering/'');\n',...
|
||||
mfilename);
|
||||
fprintf('[valid_mask]=%s(''~/Data10/pilatus/air_scattering_det_pos_2/'',''Extend'',''or'');\n',...
|
||||
mfilename);
|
||||
|
||||
error('At least the data directory has to be specified as input parameter.');
|
||||
end
|
||||
|
||||
% accept cell array with name/value pairs as well
|
||||
no_of_in_arg = nargin;
|
||||
if (nargin == 2)
|
||||
if (isempty(varargin))
|
||||
% ignore empty cell array
|
||||
no_of_in_arg = no_of_in_arg -1;
|
||||
else
|
||||
if (iscell(varargin{1}))
|
||||
% use a filled one given as first and only variable parameter
|
||||
varargin = varargin{1};
|
||||
no_of_in_arg = no_of_in_arg -1 + length(varargin);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% check number of input arguments
|
||||
if (rem(no_of_in_arg,2) ~= 1)
|
||||
error('The optional parameters have to be specified as ''name'',''value'' pairs');
|
||||
end
|
||||
|
||||
|
||||
% parse the variable input arguments:
|
||||
% initialize the list of unhandled parameters
|
||||
vararg_remain = cell(0,0);
|
||||
for ind = 1:2:length(varargin)
|
||||
name = varargin{ind};
|
||||
value = varargin{ind+1};
|
||||
switch name
|
||||
case 'ThresholdDark'
|
||||
threshold_dark = value;
|
||||
case 'ThresholdHot'
|
||||
threshold_hot = value;
|
||||
case 'ThresholdMedian'
|
||||
threshold_median = value;
|
||||
case 'FilenameMask'
|
||||
filename_mask = value;
|
||||
case 'FilenameValidMask'
|
||||
filename_valid_mask = value;
|
||||
case 'SaveData'
|
||||
save_data = value;
|
||||
case 'FigNo'
|
||||
fig_no = value;
|
||||
case 'Extend'
|
||||
extend = value;
|
||||
otherwise
|
||||
vararg_remain{end+1} = name; %#ok<AGROW>
|
||||
vararg_remain{end+1} = value; %#ok<AGROW>
|
||||
end
|
||||
end
|
||||
|
||||
vararg_remain{end+1} = 'UnhandledParError';
|
||||
vararg_remain{end+1} = 0;
|
||||
|
||||
% check extend parameter
|
||||
if ((~strcmp(extend,'no')) && ...
|
||||
(~strcmp(extend,'and')) && (~strcmp(extend,'or')))
|
||||
error('extend must be ''and'', ''or'' or ''no''\n');
|
||||
end
|
||||
|
||||
% set some default values for the plot window
|
||||
set(0, 'DefaultAxesfontsize', 12);
|
||||
set(0, 'DefaultAxeslinewidth', 1, 'DefaultAxesfontsize', 12);
|
||||
set(0, 'DefaultLinelinewidth', 1);
|
||||
|
||||
% get all matching filenames
|
||||
if (data_dir(end) ~= '/')
|
||||
data_dir(end+1) = '/';
|
||||
end
|
||||
[data_dir,fnames,vararg_remain] = ...
|
||||
find_files( [ data_dir filename_mask ], vararg_remain );
|
||||
|
||||
if (length(fnames) < 1)
|
||||
error('No matching files found for %s%s.\n',data_dir,filename_mask);
|
||||
end
|
||||
|
||||
if (~strcmp(extend,'no'))
|
||||
if exist(filename_valid_mask,'file')
|
||||
fprintf('loading the existing valid mask %s\n', ...
|
||||
filename_valid_mask);
|
||||
load(filename_valid_mask);
|
||||
ind_existing_valid = valid_mask.indices;
|
||||
else
|
||||
fprintf('no prior valid mask %s found\n', ...
|
||||
filename_valid_mask);
|
||||
ind_existing_valid = '';
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
% process the frames
|
||||
ind_hot = [];
|
||||
ind_dark = [];
|
||||
fprintf('data directory is %s\n',data_dir);
|
||||
for (f_ind=1:length(fnames))
|
||||
fprintf('%3d/%3d: reading %s%s\n',f_ind,length(fnames),...
|
||||
data_dir,fnames(f_ind).name);
|
||||
[frame] = image_read([data_dir fnames(f_ind).name ],vararg_remain);
|
||||
frame.data = double(frame.data);
|
||||
for (frame_ind = 1:size(frame.data,3))
|
||||
% median filtered data for comparison
|
||||
if (threshold_median ~= 0)
|
||||
data_med = frame.data(:,:,frame_ind);
|
||||
|
||||
% add pixels at the module boundary to ease median filtering
|
||||
ind = find(data_med == 0);
|
||||
data_med_shift = circshift(data_med,[2 2]);
|
||||
data_med(ind) = data_med_shift(ind);
|
||||
|
||||
ind = find(data_med == 0);
|
||||
data_med_shift = circshift(data_med,[-2 -2]);
|
||||
data_med(ind) = data_med_shift(ind);
|
||||
|
||||
ind = find(data_med == 0);
|
||||
data_med_shift = circshift(data_med,[-2 2]);
|
||||
data_med(ind) = data_med_shift(ind);
|
||||
|
||||
ind = find(data_med == 0);
|
||||
data_med_shift = circshift(data_med,[2 -2]);
|
||||
data_med(ind) = data_med_shift(ind);
|
||||
|
||||
% median filter the data
|
||||
data_med = medfilt2(data_med,[5 5]);
|
||||
|
||||
% the square root of the intensity estimates the standard deviation
|
||||
data_med_sqrt = data_med.^0.5;
|
||||
end
|
||||
|
||||
if (f_ind == 1)
|
||||
framesize1 = size(frame.data,1);
|
||||
framesize2 = size(frame.data,2);
|
||||
framesize = framesize1 * framesize2;
|
||||
end
|
||||
|
||||
% check that the file have identical dimensions
|
||||
if ((framesize1 ~= size(frame.data,1)) || ...
|
||||
(framesize2 ~= size(frame.data,2)))
|
||||
error('The previous file(s) had %d x %d pixels, this frame has %d x %d pixels',...
|
||||
framesize1,framesize2,size(frame.data,1),size(frame.data,2));
|
||||
end
|
||||
|
||||
% pixels are considered to be dark if the intensity is below the
|
||||
% constant threshold
|
||||
ind = find(frame.data(:,:,frame_ind) < threshold_dark);
|
||||
fprintf('%6d dark pixels below %10.3e counts, ', ...
|
||||
length(ind),threshold_dark);
|
||||
if (f_ind == 1)
|
||||
ind_dark = ind;
|
||||
else
|
||||
% dark pixels must be dark in all frames
|
||||
ind_dark = intersect(ind_dark,ind);
|
||||
end
|
||||
|
||||
% hot pixels are hot if they are above the threshold
|
||||
ind = find(frame.data(:,:,frame_ind) > threshold_hot);
|
||||
% and, if active, above the intensity plus a threshold times the square
|
||||
% root of the intensity as an estimation of the countin statistics
|
||||
% error
|
||||
if (threshold_median ~= 0.0)
|
||||
ind = intersect(ind,find((frame.data(:,:,frame_ind) > data_med+threshold_median*data_med_sqrt)));
|
||||
fprintf('%4d hot pixels above %d and %.1f * sqrt(intensity) counts\n', ...
|
||||
length(ind),threshold_hot,threshold_median);
|
||||
else
|
||||
fprintf('%4d hot pixels above %d counts\n', ...
|
||||
length(ind),threshold_hot);
|
||||
end
|
||||
% for hot pixels it is enough to be above the threshold in one frame
|
||||
ind_hot = union(ind_hot,ind);
|
||||
end
|
||||
end
|
||||
|
||||
% calculate the complementary masks of the valid pixels
|
||||
valid_mask.indices = setdiff(1:framesize,union(ind_dark,ind_hot));
|
||||
|
||||
fprintf('In total %d dark and %d hot pixels found.\n',...
|
||||
length(ind_dark),length(ind_hot));
|
||||
fprintf('%d valid pixels remain.\n',length(valid_mask.indices));
|
||||
|
||||
if (~strcmp(extend,'no'))
|
||||
fprintf('Extending the existing valid pixel mask of %d pixels\n',...
|
||||
length(ind_existing_valid));
|
||||
if (strcmp(extend,'and'))
|
||||
fprintf('using the and conjugation\n');
|
||||
valid_mask.indices = ...
|
||||
intersect(valid_mask.indices,ind_existing_valid);
|
||||
else
|
||||
fprintf('using the or conjugation\n');
|
||||
if ~isempty(ind_existing_valid)
|
||||
valid_mask.indices = ...
|
||||
union(valid_mask.indices,ind_existing_valid);
|
||||
end
|
||||
end
|
||||
fprintf('The combined mask has %d valid pixels.\n',...
|
||||
length(valid_mask.indices));
|
||||
end
|
||||
|
||||
% store the frame size in the return data
|
||||
valid_mask.framesize = [framesize1 framesize2];
|
||||
|
||||
if (save_data)
|
||||
% create a backup of the mask
|
||||
if (exist(filename_valid_mask,'file'))
|
||||
filename_mask_backup = [ filename_valid_mask '.bak' ];
|
||||
fprintf('Copying the current mask %s to %s\n',filename_valid_mask,...
|
||||
filename_mask_backup);
|
||||
copyfile(filename_valid_mask,filename_mask_backup);
|
||||
end
|
||||
|
||||
% save the masks
|
||||
fprintf('Saving valid_mask to %s\n',filename_valid_mask);
|
||||
save(filename_valid_mask,'valid_mask');
|
||||
end
|
||||
|
||||
% plot new valid pixel mask
|
||||
if (fig_no > 0)
|
||||
display_valid_mask('FilenameValidMask',filename_valid_mask,...
|
||||
'NoHelp',1,'FigNo',fig_no);
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,179 @@
|
||||
// RADIAL_INTEG_MEX perform radial integration for a 2D frame
|
||||
//
|
||||
// ** ind_r_max int32
|
||||
// ** no_of_segments int32
|
||||
// ** norm_sum double
|
||||
// ** indices cell
|
||||
// ** frame_data 2D or 3D array, double
|
||||
//
|
||||
// return:
|
||||
// ++ frame_I 2D or 3D array, double
|
||||
// ++ frame_std 2D or 3D array, double
|
||||
//
|
||||
//
|
||||
// Example:
|
||||
// [frame_I(:,:,ind_frame), frame_std(:,:,ind_frame)] = radial_integ_mex(int32(ind_r_max),int32(no_of_segments), integ_masks.norm_sum, integ_masks.indices, frame_data);
|
||||
//
|
||||
// compile with:
|
||||
// mex 'CFLAGS="\$CFLAGS -O3 -std=c++17 -fopenmp"' LDFLAGS="\$LDFLAGS -fopenmp" radial_integ_mex.cpp
|
||||
//
|
||||
// MATLAB code:
|
||||
// for (ind_r = 1:ind_r_max)
|
||||
// for (ind_seg = 1:no_of_segments)
|
||||
// if (integ_masks.norm_sum(ind_r,ind_seg) > 0)
|
||||
// frame_I_one_frame(ind_r,ind_seg) = ...
|
||||
// mean(frame_data(integ_masks.indices{ind_r,ind_seg}));
|
||||
// frame_std_one_frame(ind_r,ind_seg) = ...
|
||||
// std(frame_data(integ_masks.indices{ind_r,ind_seg}));
|
||||
// else
|
||||
// % mark unknown intensities
|
||||
// frame_I_one_frame(ind_r,ind_seg) = -1;
|
||||
// frame_std_one_frame(ind_r,ind_seg) = -1;
|
||||
// end
|
||||
// end
|
||||
// end
|
||||
|
||||
// *-----------------------------------------------------------------------*
|
||||
// | |
|
||||
// | 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.
|
||||
|
||||
#include "mex.h"
|
||||
#include "matrix.h"
|
||||
#include <iostream>
|
||||
#include <math.h>
|
||||
#include <omp.h>
|
||||
|
||||
void mexFunction( int nlhs, mxArray *plhs[],
|
||||
int nrhs, const mxArray *prhs[])
|
||||
{
|
||||
double *norm_sum;
|
||||
double *frame_data;
|
||||
uint ind_r_max, no_of_segments;
|
||||
const mwSize *pDims;
|
||||
int nDimNum;
|
||||
int maxSlice;
|
||||
|
||||
/* check for proper number of arguments */
|
||||
if(nrhs!=5) {
|
||||
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs","Five inputs required.");
|
||||
}
|
||||
if(nlhs!=2) {
|
||||
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs","Two output containers are required.");
|
||||
}
|
||||
/* make sure the first two input arguments are of type int */
|
||||
if( !mxIsClass(prhs[0], "int32")) {
|
||||
mexErrMsgIdAndTxt("cxsSoftware:radialIntegMex:notInteger","r_max must be of type integer.");
|
||||
}
|
||||
if( !mxIsClass(prhs[1], "int32")) {
|
||||
mexErrMsgIdAndTxt("cxsSoftware:radialIntegMex:notInteger","no_of_segments must be of type integer.");
|
||||
}
|
||||
if( !mxIsClass(prhs[2], "double")) {
|
||||
mexErrMsgIdAndTxt("cxsSoftware:radialIntegMex:notInteger","norm_sum must be of type double.");
|
||||
}
|
||||
if( !mxIsCell(prhs[3])) {
|
||||
mexErrMsgIdAndTxt("cxsSoftware:radialIntegMex:notInteger","indices must be of type cell.");
|
||||
}
|
||||
if( !mxIsClass(prhs[4], "double")) {
|
||||
mexErrMsgIdAndTxt("cxsSoftware:radialIntegMex:notInteger","frame_data must be of type double.");
|
||||
}
|
||||
ind_r_max = mxGetScalar(prhs[0]);
|
||||
no_of_segments = mxGetScalar(prhs[1]);
|
||||
norm_sum = mxGetPr(prhs[2]);
|
||||
|
||||
frame_data = mxGetPr(prhs[4]);
|
||||
|
||||
nDimNum = mxGetNumberOfDimensions(prhs[4]);
|
||||
pDims = mxGetDimensions(prhs[4]);
|
||||
|
||||
if (nDimNum==2){
|
||||
plhs[0] = mxCreateNumericMatrix((mwSize)ind_r_max, (mwSize)no_of_segments, mxDOUBLE_CLASS, mxREAL);
|
||||
plhs[1] = mxCreateNumericMatrix((mwSize)ind_r_max, (mwSize)no_of_segments, mxDOUBLE_CLASS, mxREAL);
|
||||
maxSlice = 1;
|
||||
} else if (nDimNum==3) {
|
||||
maxSlice = pDims[2];
|
||||
mwSize dims[3] = {(mwSize)ind_r_max,(mwSize)no_of_segments,(mwSize)maxSlice};
|
||||
plhs[0] = mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL);
|
||||
plhs[1] = mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL);
|
||||
} else {
|
||||
mexErrMsgIdAndTxt("cxsSoftware:radialIntegMex:dimsError","frame_data must be 2D or 3D.");
|
||||
}
|
||||
|
||||
double* outputMatrixMean = (double *)mxGetData(plhs[0]);
|
||||
double* outputMatrixStdDev = (double *)mxGetData(plhs[1]);
|
||||
|
||||
#pragma omp parallel for collapse(2)
|
||||
for (uint slID=0; slID < maxSlice; slID++){
|
||||
for (uint ind_r=0; ind_r<ind_r_max; ind_r++){
|
||||
for (uint ind_seg=0; ind_seg<no_of_segments; ind_seg++){
|
||||
double tmpMean = 0;
|
||||
double tmpStdDev = 0;
|
||||
|
||||
if (norm_sum[ind_r+ind_seg*ind_r_max] > 0){
|
||||
mxArray *subarray = mxGetCell(prhs[3], ind_r+ind_seg*ind_r_max);
|
||||
double *indicesSub = mxGetPr(subarray);
|
||||
uint dim = mxGetNumberOfElements(subarray);
|
||||
|
||||
|
||||
for (uint ii=0; ii<dim; ii++){
|
||||
tmpMean += frame_data[(int)indicesSub[ii]-1 + slID*pDims[0]*pDims[1]];
|
||||
}
|
||||
if (tmpMean>0){
|
||||
tmpMean /= dim;
|
||||
}
|
||||
for (uint ii=0; ii<dim; ii++){
|
||||
tmpStdDev += std::pow(std::abs(frame_data[(int)indicesSub[ii]-1 + slID*pDims[0]*pDims[1]]-tmpMean),2);
|
||||
|
||||
}
|
||||
|
||||
if (tmpMean>0 && dim>1){
|
||||
tmpStdDev = sqrt(tmpStdDev/(dim-1));
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
tmpMean = -1;
|
||||
tmpStdDev = -1;
|
||||
}
|
||||
|
||||
outputMatrixMean[ind_r+ind_seg*ind_r_max+slID*(ind_r_max)*(no_of_segments)] = tmpMean;
|
||||
outputMatrixStdDev[ind_r+ind_seg*ind_r_max+slID*(ind_r_max)*(no_of_segments)] = tmpStdDev;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,710 @@
|
||||
% Call function without arguments for instructions on how to use it
|
||||
|
||||
% Filename: $RCSfile: radial_integ.m,v $
|
||||
%
|
||||
% $Revision: 1.12 $ $Date: 2016/01/21 15:11:50 $
|
||||
% $Author: $
|
||||
% $Tag: $
|
||||
%
|
||||
% Description:
|
||||
% radial integration of 2D data read from file(s)
|
||||
%
|
||||
% Note:
|
||||
% Call without arguments for a brief help text.
|
||||
% The integration masks need to be prepared first using prep_integ_masks.m
|
||||
%
|
||||
% Dependencies:
|
||||
% - image_read
|
||||
%
|
||||
% history:
|
||||
%
|
||||
% February 18 2015:
|
||||
% updated to use new function names of parallel toolbox in Matlab 2014b
|
||||
%
|
||||
% July 22nd 2010:
|
||||
% add simple parallel processing using parfor
|
||||
%
|
||||
% April 28th 2010:
|
||||
% use default_parameter_value
|
||||
%
|
||||
% June 5th 2008: 1st documented version
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| Except where otherwise noted, this work is licensed under a |
|
||||
%| Creative Commons Attribution-NonCommercial-ShareAlike 4.0 |
|
||||
%| International (CC BY-NC-SA 4.0) license. |
|
||||
%| |
|
||||
%| Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch) |
|
||||
%| |
|
||||
%| Author: CXS group, PSI |
|
||||
%*-----------------------------------------------------------------------*
|
||||
% You may use this code with the following provisions:
|
||||
%
|
||||
% If the code is fully or partially redistributed, or rewritten in another
|
||||
% computing language this notice should be included in the redistribution.
|
||||
%
|
||||
% If this code, or subfunctions or parts of it, is used for research in a
|
||||
% publication or if it is fully or partially rewritten for another
|
||||
% computing language the authors and institution should be acknowledged
|
||||
% in written form in the publication: “Data processing was carried out
|
||||
% using the “cSAXS matlab package” developed by the CXS group,
|
||||
% Paul Scherrer Institut, Switzerland.”
|
||||
% Variations on the latter text can be incorporated upon discussion with
|
||||
% the CXS group if needed to more specifically reflect the use of the package
|
||||
% for the published work.
|
||||
%
|
||||
% A publication that focuses on describing features, or parameters, that
|
||||
% are already existing in the code should be first discussed with the
|
||||
% authors.
|
||||
%
|
||||
% This code and subroutines are part of a continuous development, they
|
||||
% are provided “as they are” without guarantees or liability on part
|
||||
% of PSI or the authors. It is the user responsibility to ensure its
|
||||
% proper use and the correctness of the results.
|
||||
|
||||
function [ I,vararg_remain ] = radial_integ(filename_masks,varargin)
|
||||
import beamline.prep_integ_masks
|
||||
import io.image_read
|
||||
import plotting.plot_radial_integ
|
||||
import utils.default_parameter_value
|
||||
import utils.find_files
|
||||
import utils.abspath
|
||||
|
||||
% initialize return arguments
|
||||
I = struct('I_all',[], 'I_std',[],'filenames_all',[],'q',[],'radius',[]);
|
||||
|
||||
% set default values for the variable input arguments:
|
||||
outdir_data = default_parameter_value(mfilename,'OutdirData');
|
||||
filename_integ_masks = default_parameter_value(mfilename,'FilenameIntegMasks');
|
||||
r_max_forced = default_parameter_value(mfilename,'rMaxForced');
|
||||
fig_no = default_parameter_value(mfilename,'FigNo');
|
||||
save_combined_I = default_parameter_value(mfilename,'SaveCombinedI');
|
||||
recursive = default_parameter_value(mfilename,'Recursive');
|
||||
use_find = default_parameter_value(mfilename,'UseFind');
|
||||
unhandled_par_error = default_parameter_value(mfilename,'UnhandledParError');
|
||||
parallel_tasks_max = 1; %default_parameter_value(mfilename,'ParTasksMax');
|
||||
save_format = '-v6';
|
||||
use_mex = true;
|
||||
c_reader = true;
|
||||
useStack = true;
|
||||
|
||||
% check minimum number of input arguments
|
||||
if (nargin < 1)
|
||||
fprintf('\nUsage:\n');
|
||||
fprintf('%s(filename_mask, [[,<name>,<value>] ...]);\n',mfilename);
|
||||
fprintf('filename_mask can be something like ''*.cbf'' or ''image.cbf'' or\n');
|
||||
fprintf('a cell array of filenames or filename masks like {''dir1/*.cbf'',''dir2/*.cbf''}.\n');
|
||||
fprintf('The optional <name>,<value> pairs are:\n');
|
||||
fprintf('''OutdirData'',<directory> save the integrated intensities to files in this directory, '''' for no saving, default is %s\n',outdir_data);
|
||||
fprintf('''FilenameIntegMasks'',<filename> Matlab file containing the integration masks, default is ''%s''\n',filename_integ_masks);
|
||||
fprintf('''rMaxForced'',<radius in pixel> stop integration at this maximum r even if the integration masks reach further, default is 0 - do not stop\n');
|
||||
fprintf('''FigNo'',<figure number> number of the figure for an online plot of the intensities in case parallel processing is not used, 0 for no plot, default is %d\n',fig_no);
|
||||
fprintf('''SaveFormat'',<format string> default is %s\n',save_format);
|
||||
fprintf('''SaveCombinedI'',<0-no, 1-yes> save intensities from all specified files found in one directory in a single file, default is yes\n');
|
||||
fprintf('''Recursive'',<0-no, 1-yes> recursively integrate files in all matching sub-directories, default is yes\n');
|
||||
fprintf('''ParTasksMax'',<integer> specify the maximum number of CPU cores to use, 1 to deactivate the use of parallel computing, default is %d\n',parallel_tasks_max);
|
||||
fprintf('''UseFind'',<0-no, 1-yes> use Linux/Unix command find to interprete the filename mask, default is yes\n');
|
||||
fprintf('''UseMex'', <0-no, 1-yes> use radial_integ_mex; usually faster than MATLAB, default is yes\n');
|
||||
fprintf('''CReader'', <0-no, 1-yes> use the fast measurement reader; usually faster than image_read, default is yes\n');
|
||||
fprintf('''UseStack'', <0-no, 1-yes> load all detector frames into memory before calling the radial_integ functions; default is yes\n');
|
||||
fprintf('''UnhandledParError'',<0-no,1-yes> exit in case not all named parameters are used/known, default is %d\n',unhandled_par_error);
|
||||
fprintf('Examples:\n');
|
||||
fprintf('%s(''~/Data10/pilatus/mydatadir/*.cbf'',''OutdirData'',''~/Data10/analysis/radial_integ/'');\n',mfilename);
|
||||
fprintf('Additional <name>,<value> pairs recognized by image_read can be specified.\n');
|
||||
error('At least the filename mask has to be specified as input argument.');
|
||||
end
|
||||
|
||||
|
||||
% accept cell array with name/value pairs as well
|
||||
no_of_in_arg = nargin;
|
||||
if (nargin == 2)
|
||||
if (isempty(varargin))
|
||||
% ignore empty cell array
|
||||
no_of_in_arg = no_of_in_arg -1;
|
||||
else
|
||||
if (iscell(varargin{1}))
|
||||
% use a filled one given as first and only variable parameter
|
||||
varargin = varargin{1};
|
||||
no_of_in_arg = 1 + length(varargin);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% check number of input arguments
|
||||
if (rem(no_of_in_arg,2) ~= 1)
|
||||
error('The optional parameters have to be specified as ''name'',''value'' pairs');
|
||||
end
|
||||
|
||||
% parse the variable input arguments
|
||||
vararg = cell(0,0);
|
||||
for ind = 1:2:length(varargin)
|
||||
name = varargin{ind};
|
||||
value = varargin{ind+1};
|
||||
switch name
|
||||
case 'OutdirData'
|
||||
outdir_data = value;
|
||||
case 'SaveFormat'
|
||||
save_format = value;
|
||||
case 'FilenameIntegMasks'
|
||||
filename_integ_masks = value;
|
||||
case 'rMaxForced'
|
||||
r_max_forced = value;
|
||||
case 'FigNo'
|
||||
fig_no = value;
|
||||
case 'SaveCombinedI'
|
||||
save_combined_I = value;
|
||||
case 'Recursive'
|
||||
recursive = value;
|
||||
case 'UseFind'
|
||||
use_find = value;
|
||||
case 'UnhandledParError'
|
||||
unhandled_par_error = value;
|
||||
case 'ParTasksMax'
|
||||
parallel_tasks_max = value;
|
||||
case 'UseMex'
|
||||
use_mex = value;
|
||||
case 'CReader'
|
||||
c_reader = value;
|
||||
case 'UseStack'
|
||||
useStack = value;
|
||||
otherwise
|
||||
vararg{end+1} = name; %#ok<AGROW>
|
||||
vararg{end+1} = value; %#ok<AGROW>
|
||||
end
|
||||
end
|
||||
|
||||
% initialize the list of unhandled parameters
|
||||
vararg_remain = cell(0,0);
|
||||
|
||||
% do not exit in image_par in case of unhandled parameters
|
||||
if (~unhandled_par_error)
|
||||
vararg{end+1} = 'UnhandledParError';
|
||||
vararg{end+1} = 0;
|
||||
end
|
||||
|
||||
if (~isempty(outdir_data))
|
||||
% add slash to output directory
|
||||
if (outdir_data(end) ~= '/')
|
||||
outdir_data = [ outdir_data '/' ];
|
||||
end
|
||||
|
||||
% create output directory
|
||||
[mkdir_stat,mkdir_message] = mkdir(outdir_data);
|
||||
if (~mkdir_stat)
|
||||
error('invalid directory %s: %s',outdir_data,mkdir_message);
|
||||
end
|
||||
if ((mkdir_stat) && (isempty(mkdir_message)))
|
||||
fprintf('The output directory %s has been created.\n',outdir_data);
|
||||
else
|
||||
fprintf('The output directory is %s.\n',outdir_data);
|
||||
end
|
||||
else
|
||||
fprintf('data are not saved\n');
|
||||
end
|
||||
|
||||
% load integration masks from this file
|
||||
% this loads:
|
||||
% center_xy, no_of_segments, integ_masks
|
||||
fprintf('loading integration masks from %s\n',filename_integ_masks);
|
||||
load(filename_integ_masks);
|
||||
if ((~exist('center_xy','var')) && (exist('center_x','var')))
|
||||
center_xy(1) = center_x;
|
||||
center_xy(2) = center_y;
|
||||
if (~exist('integ_masks','var'))
|
||||
integ_masks.radius = r;
|
||||
integ_masks.indices = masks_r;
|
||||
integ_masks.norm_sum = mask_r_sum;
|
||||
end
|
||||
end
|
||||
fprintf('center at (x, y) = (%.1f, %.1f)\n',center_xy(1),center_xy(2));
|
||||
|
||||
% limit radial range
|
||||
if (r_max_forced > 0)
|
||||
ind = find( integ_masks.radius < r_max_forced );
|
||||
if (length(ind) < 1)
|
||||
fprintf('No radii below rMaxForced = %d found\n',r_max_forced);
|
||||
return;
|
||||
end
|
||||
integ_masks.radius = integ_masks.radius(1:ind(end));
|
||||
integ_masks.norm_sum = integ_masks.norm_sum(1:ind(end), :);
|
||||
end
|
||||
if isfield(integ_masks,'radius')
|
||||
fprintf('radii from %d to %d\n',...
|
||||
integ_masks.radius(1),integ_masks.radius(end));
|
||||
else
|
||||
fprintf('radii from %d to %d\n',...
|
||||
integ_masks.q(1),integ_masks.q(end));
|
||||
end
|
||||
% ease handling by ensuring that filename_masks is a cell array
|
||||
if (~iscell(filename_masks))
|
||||
filename_masks = { filename_masks };
|
||||
end
|
||||
|
||||
|
||||
% initialize parallel processing if this is enabled and not yet done
|
||||
if (parallel_tasks_max > 1)
|
||||
%matlabpool_size = matlabpool('size');
|
||||
%if (matlabpool_size < 1)
|
||||
if isempty(gcp('nocreate')) %MGS2015 If there is no current pool
|
||||
% create a scheduler object using the default configuration, which is a
|
||||
% local scheduler if nothing else has been installed
|
||||
% scheduler = findResource('scheduler','type', defaultParallelConfig);
|
||||
scheduler = parcluster; %MGS2015
|
||||
|
||||
% adapt maximum number of tasks/workers, if necessary
|
||||
%cluster_size = get(scheduler,'ClusterSize');
|
||||
cluster_size = scheduler.NumWorkers; %MGS2015
|
||||
if (parallel_tasks_max > cluster_size)
|
||||
fprintf('Adapting the maximum number of tasks from %d to %d.\n',...
|
||||
parallel_tasks_max, cluster_size);
|
||||
parallel_tasks_max = cluster_size;
|
||||
end
|
||||
|
||||
% open a Matlab pool for simple parallel processing
|
||||
if (parallel_tasks_max > 1)
|
||||
%matlabpool('open',parallel_tasks_max);%MGS2015
|
||||
pool = parpool(parallel_tasks_max);
|
||||
fprintf('Using parallel processing with %d tasks.\n', ...
|
||||
parallel_tasks_max);
|
||||
end
|
||||
else
|
||||
pool = gcp;%MGS2015
|
||||
if ( pool.NumWorkers < parallel_tasks_max )
|
||||
fprintf('%s: usage of up to %d CPUs in parallel has been specified but an already open matlabpool with %d workers has been found and will be used instead\n', ...
|
||||
mfilename, parallel_tasks_max, pool.NumWorkers);
|
||||
parallel_tasks_max = pool.NumWorkers;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
pool.IdleTimeout = Inf;
|
||||
|
||||
if ((parallel_tasks_max > 1) && (fig_no > 0))
|
||||
fprintf('%s: Online plotting is disabled since parallel processing is enabled.\n', ...
|
||||
mfilename);
|
||||
end
|
||||
|
||||
% loop over all filename masks
|
||||
ind_mask_max = length(filename_masks);
|
||||
|
||||
% Initialize variables for saving
|
||||
no_of_segments = size(integ_masks.indices,2);
|
||||
if isfield(integ_masks,'radius')
|
||||
radius = integ_masks.radius;
|
||||
ind_r_max = length(radius);
|
||||
else
|
||||
radius = [];
|
||||
q = integ_masks.q;
|
||||
ind_r_max = length(q);
|
||||
end
|
||||
if isfield(integ_masks,'q')
|
||||
q = integ_masks.q;
|
||||
else
|
||||
q = [];
|
||||
end
|
||||
|
||||
for (ind_mask = 1:ind_mask_max) %#ok<*NO4LP>
|
||||
filename_mask = filename_masks{ind_mask};
|
||||
fprintf('%s:\n',filename_mask);
|
||||
[data_dir,fnames] = find_files( filename_mask, 'UseFind',use_find );
|
||||
|
||||
if (length(fnames) < 1)
|
||||
fprintf('No matching files found for %s.\n',filename_mask);
|
||||
continue;
|
||||
end
|
||||
|
||||
% collect recursively all matching file names
|
||||
[ filenames_all ] = ...
|
||||
collect_radial_integ_filenames(data_dir, fnames, ...
|
||||
recursive, ...
|
||||
vararg);
|
||||
|
||||
% prepare for integration of the so far identified files
|
||||
file_ind_max = length(filenames_all);
|
||||
for file_ind=1:file_ind_max
|
||||
filenames_all{file_ind}=abspath(filenames_all{file_ind});
|
||||
end
|
||||
|
||||
% get the number of frames per file by loading the first file (not very
|
||||
% elegant)
|
||||
[frame] = image_read(filenames_all{1}, vararg);
|
||||
no_of_frames = size(frame.data,3);
|
||||
I_all = zeros(ind_r_max, no_of_segments, no_of_frames, file_ind_max);
|
||||
I_std = zeros(ind_r_max, no_of_segments, no_of_frames, file_ind_max);
|
||||
|
||||
if (parallel_tasks_max > 1)
|
||||
% integration using parallel processing
|
||||
parfor (file_ind = 1:file_ind_max)
|
||||
|
||||
% read the raw data frame and integrate it
|
||||
[frame_I, frame_std] = ...
|
||||
perform_radial_integ_parallel(file_ind, file_ind_max, ...
|
||||
filenames_all{file_ind}, ...
|
||||
integ_masks, ind_r_max, no_of_segments, ...
|
||||
vararg);
|
||||
|
||||
% no_of_frames = size(frame_I,3);
|
||||
% if (no_of_frames ~= size(I_all,3))
|
||||
% error('number of frames per file changes from %d to %d',size(I_all,3),no_of_frames);
|
||||
% end
|
||||
|
||||
I_all(:,:,:,file_ind) = frame_I;
|
||||
I_std(:,:,:,file_ind) = frame_std;
|
||||
end
|
||||
else
|
||||
% read the raw data
|
||||
if c_reader
|
||||
try
|
||||
[~, ~, ext] = fileparts(filenames_all{1});
|
||||
arg.data_path = filenames_all';
|
||||
arg.nthreads = min(round(feature('numcores')*0.8),14);
|
||||
arg.precision = 'single';
|
||||
arg.extension = ext(2:end);
|
||||
if strcmpi(ext(1:end), 'h5') && ~isempty(find(strcmp(varargin, 'H5Location')))
|
||||
arg.data_location = varargin{find(strcmp(varargin, 'H5Location'))+1};
|
||||
end
|
||||
frameStorage.data = io.read_measurement(arg);
|
||||
frameStorage.data = permute(frameStorage.data,[2 1 3]);
|
||||
frameStorage.data = flip(flip(frameStorage.data,1),2);
|
||||
catch ME
|
||||
fprintf('Failed to load data. If the problem persists, set c_reader=false.\n');
|
||||
rethrow(ME);
|
||||
end
|
||||
else
|
||||
[frameStorage] = image_read(filename_masks, vararg);
|
||||
end
|
||||
if ~useStack
|
||||
for (file_ind = 1:file_ind_max)
|
||||
|
||||
% read the raw data frame and integrate it
|
||||
[frame_I, frame_std] = ...
|
||||
perform_radial_integ(file_ind, file_ind_max, ...
|
||||
frameStorage.data(:,:,file_ind), ...
|
||||
integ_masks, ind_r_max, no_of_segments, use_mex, ...
|
||||
vararg);
|
||||
|
||||
I_all(:,:,:,file_ind) = frame_I;
|
||||
I_std(:,:,:,file_ind) = frame_std;
|
||||
|
||||
% plot integrated intensities as feedback
|
||||
if (fig_no > 0)
|
||||
if isfield(integ_masks,'radius')
|
||||
d.radius = radius;
|
||||
else
|
||||
d.radius= q;
|
||||
end
|
||||
d.I_all = frame_I;
|
||||
d.I_std = frame_std;
|
||||
plot_radial_integ(d,'FigNo',fig_no);
|
||||
drawnow;
|
||||
end
|
||||
end
|
||||
else
|
||||
% integrate it
|
||||
try
|
||||
[frame_I, frame_std] = radial_integ_mex(int32(ind_r_max),int32(no_of_segments), integ_masks.norm_sum, integ_masks.indices, double(frameStorage.data));
|
||||
catch
|
||||
tmpPath = fileparts(mfilename('fullpath'));
|
||||
fprintf('Recompiling mex function...\n');
|
||||
|
||||
% Fall back to single thread if the OpenMP fail.
|
||||
|
||||
eval(['mex ' fullfile(tmpPath, 'private', 'radial_integ_mex.cpp') ' -outdir ' fullfile(tmpPath, 'private')]);
|
||||
try
|
||||
[frame_I, frame_std] = radial_integ_mex(int32(ind_r_max),int32(no_of_segments), integ_masks.norm_sum, integ_masks.indices, double(frameStorage.data));
|
||||
catch ME
|
||||
fprintf('radial_integ_mex failed. If the problem persists, consider setting use_mex=false.\n');
|
||||
rethrow(ME);
|
||||
end
|
||||
end
|
||||
I_all(:,:,1,:) = frame_I;
|
||||
I_std(:,:,1,:) = frame_std;
|
||||
end
|
||||
end
|
||||
|
||||
% reshuffle the data to get rid off the frame-within-file dimension,
|
||||
% dimension 3.
|
||||
% This would be easier with linear indexing in case the frame and file
|
||||
% dimensions would be 1 and 2.
|
||||
I_all_org = I_all;
|
||||
I_std_org = I_std;
|
||||
I_all = zeros(size(I_all_org,1), size(I_all_org,2), size(I_all_org,3) * size(I_all_org,4));
|
||||
I_std = zeros(size(I_all));
|
||||
for (ind_frame = 1:size(I_all_org,3))
|
||||
for (ind_file = 1:size(I_all_org,4))
|
||||
I_all(:,:,(ind_file-1)*size(I_all_org,3)+ind_frame) = I_all_org(:,:,ind_frame,ind_file);
|
||||
I_std(:,:,(ind_file-1)*size(I_std_org,3)+ind_frame) = I_std_org(:,:,ind_frame,ind_file);
|
||||
end
|
||||
end
|
||||
|
||||
% save data, if this option is enabled
|
||||
if (~isempty(outdir_data))
|
||||
if (save_combined_I)
|
||||
% save all integrated frames as single Matlab file
|
||||
|
||||
if (exist('I_all','var'))
|
||||
% use first file as file-name base
|
||||
[~, name] = fileparts(filenames_all{1});
|
||||
% name = name(1:end-12);
|
||||
fname_out = fullfile(outdir_data, [ name '_integ.mat' ]);
|
||||
fprintf('saving %s\n',fname_out);
|
||||
% remove directory information before storing the filenames
|
||||
for (file_ind = 1:file_ind_max)
|
||||
[~, name, extension] = fileparts(filenames_all{file_ind});
|
||||
filenames_all{file_ind} = [ name extension ];
|
||||
end
|
||||
norm_sum = integ_masks.norm_sum;
|
||||
save(fname_out,'I_all','I_std', 'norm_sum', 'filenames_all','radius','q','angular_segments','phi_det', save_format);
|
||||
else
|
||||
fprintf('No data to save for directory %s\n',data_dir);
|
||||
end
|
||||
else
|
||||
|
||||
% save the integrated data for each frame as separate ASCII
|
||||
% file
|
||||
savedat = zeros(ind_r_max, no_of_segments +1);
|
||||
if isfield(integ_masks,'radius')
|
||||
savedat(:,1) = radius;
|
||||
else
|
||||
savedat(:,1)= q;
|
||||
end
|
||||
for (file_ind = 1:file_ind_max)
|
||||
% save integrated data for this image in the output arrays
|
||||
savedat(:,2:end) = I_all(:,:,file_ind);
|
||||
|
||||
[pathstr, name] = fileparts(filenames_all{file_ind});
|
||||
fname_out = fullfile(pathstr, [ name '_integ.txt' ]);
|
||||
fprintf('saving %s\n',fname_out);
|
||||
save([outdir_data fname_out],'savedat','-ascii');
|
||||
end
|
||||
|
||||
fprintf('\nOutput data format:\n');
|
||||
fprintf('- first column with radius of circle in pixel\n');
|
||||
fprintf('- further columns with average intensity in circle segment\n');
|
||||
end
|
||||
end
|
||||
|
||||
% compile return value
|
||||
I(ind_mask).I_all = I_all;
|
||||
I(ind_mask).I_std = I_std;
|
||||
if isfield(integ_masks,'radius')
|
||||
I(ind_mask).radius = integ_masks.radius;
|
||||
end
|
||||
I(ind_mask).norm_sum = integ_masks.norm_sum;
|
||||
I(ind_mask).filenames_all = filenames_all;
|
||||
if isfield(integ_masks,'q')
|
||||
I(ind_mask).q = integ_masks.q;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
function [ filenames_all ] = ...
|
||||
collect_radial_integ_filenames(data_dir, fnames, ...
|
||||
recursive, ...
|
||||
vararg)
|
||||
import beamline.prep_integ_masks
|
||||
import io.image_read
|
||||
import plotting.plot_radial_integ
|
||||
import utils.default_parameter_value
|
||||
import utils.find_files
|
||||
% add slashes to directories
|
||||
if ((~isempty(data_dir)) && (data_dir(end) ~= '/'))
|
||||
data_dir = [ data_dir '/' ];
|
||||
end
|
||||
|
||||
% define some variables which depend on the input arguments
|
||||
file_ind_max = length(fnames);
|
||||
|
||||
% initialize variables used in the loop
|
||||
filenames_all_max = 0;
|
||||
filenames_all = cell(file_ind_max,1);
|
||||
|
||||
% loop over all matching files
|
||||
for (file_ind=1:file_ind_max)
|
||||
% % skip single frames created using the spec macro ct
|
||||
% if (length(fnames(file_ind).name) > 7)
|
||||
% fprintf('');
|
||||
% if (strcmp(fnames(file_ind).name((end-6):(end-3)),'_ct.'))
|
||||
% fprintf('skipping %s\n',fnames(file_ind).name);
|
||||
% continue
|
||||
% end
|
||||
% end
|
||||
% directory: recursion
|
||||
if ((fnames(file_ind).isdir) && (recursive))
|
||||
% ignore . and .. directories
|
||||
if ((strcmp(fnames(file_ind).name,'.')) || ...
|
||||
(strcmp(fnames(file_ind).name,'..')))
|
||||
fprintf('skipping %s\n',fnames(file_ind).name);
|
||||
continue
|
||||
end
|
||||
data_dir_sub = [ data_dir fnames(file_ind).name '/' ];
|
||||
fnames_sub = dir( data_dir_sub );
|
||||
fprintf('recursion for %s\n',fnames(file_ind).name);
|
||||
[ filenames_all_rec,vararg_remain ] = ...
|
||||
collect_radial_integ_filenames(data_dir_sub, ...
|
||||
fnames_sub, ...
|
||||
integ_masks, ...
|
||||
fig_no, save_combined_I, recursive, ...
|
||||
vararg);
|
||||
% store result of this recursion
|
||||
if (~isempty(filenames_all_rec))
|
||||
filenames_all_ind = (filenames_all_max+1):(filenames_all_max+length(filenames_all_rec));
|
||||
filenames_all(filenames_all_ind) = filenames_all_rec;
|
||||
filenames_all_max = filenames_all_ind(end);
|
||||
end
|
||||
continue;
|
||||
end
|
||||
if ((length(fnames(file_ind).name) <= 4) || ...
|
||||
(strcmp(fnames(file_ind).name(end-3:end),'.tmp')) || ...
|
||||
(strcmp(fnames(file_ind).name(end-3:end),'.log')))
|
||||
fprintf('skipping %s\n',fnames(file_ind).name);
|
||||
continue
|
||||
end
|
||||
|
||||
|
||||
|
||||
% store matching filenames in one array
|
||||
filenames_all_max = filenames_all_max +1;
|
||||
filenames_all{filenames_all_max} = [ data_dir fnames(file_ind).name ];
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
if (~exist('filenames_all','var'))
|
||||
filenames_all = [];
|
||||
end
|
||||
|
||||
|
||||
if (length(filenames_all) > filenames_all_max)
|
||||
filenames_all = filenames_all{1:filenames_all_max};
|
||||
end
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
function [frame_I,frame_std] = ...
|
||||
perform_radial_integ(file_ind, file_ind_max, ...
|
||||
frame, ...
|
||||
integ_masks, ind_r_max, no_of_segments, use_mex, ...
|
||||
vararg)
|
||||
import beamline.prep_integ_masks
|
||||
import io.image_read
|
||||
import plotting.plot_radial_integ
|
||||
import utils.default_parameter_value
|
||||
import utils.find_files
|
||||
% read the raw data frame
|
||||
% fprintf('%6d /%6d: ',file_ind,file_ind_max);
|
||||
% [frame] = image_read(filename, vararg);
|
||||
if (isempty(frame))
|
||||
error('could not load frame %u',file_ind);
|
||||
end
|
||||
|
||||
% get the number of frames in case of multi-frame data files like HDF5
|
||||
no_of_frames = size(frame,3);
|
||||
|
||||
% initialize result variables
|
||||
frame_I = zeros(ind_r_max,no_of_segments,no_of_frames);
|
||||
frame_std = zeros(ind_r_max,no_of_segments,no_of_frames);
|
||||
|
||||
if use_mex
|
||||
for (ind_frame = 1:no_of_frames)
|
||||
% get the current frame
|
||||
frame_data = double(frame(:,:,ind_frame));
|
||||
try
|
||||
[frame_I(:,:,ind_frame), frame_std(:,:,ind_frame)] = radial_integ_mex(int32(ind_r_max),int32(no_of_segments), integ_masks.norm_sum, integ_masks.indices, frame_data);
|
||||
catch
|
||||
tmpPath = fileparts(mfilename('fullpath'));
|
||||
fprintf('Recompiling mex function...\n');
|
||||
|
||||
% Fall back to single thread if the OpenMP fail.
|
||||
|
||||
eval(['mex ' fullfile(tmpPath, 'private', 'radial_integ_mex.cpp') ' -outdir ' fullfile(tmpPath, 'private')]);
|
||||
try
|
||||
[frame_I(:,:,ind_frame), frame_std(:,:,ind_frame)] = radial_integ_mex(int32(ind_r_max),int32(no_of_segments), integ_masks.norm_sum, integ_masks.indices, frame_data);
|
||||
catch ME
|
||||
fprintf('radial_integ_mex failed. If the problem persists, consider setting use_mex=false.\n');
|
||||
rethrow(ME);
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
for (ind_frame = 1:no_of_frames)
|
||||
|
||||
% get the current frame
|
||||
frame_data = double(frame(:,:,ind_frame));
|
||||
% initialize output variables for current data
|
||||
frame_I_one_frame = zeros(ind_r_max,no_of_segments);
|
||||
frame_std_one_frame = zeros(ind_r_max,no_of_segments);
|
||||
for (ind_r = 1:ind_r_max)
|
||||
for (ind_seg = 1:no_of_segments)
|
||||
if (integ_masks.norm_sum(ind_r,ind_seg) > 0)
|
||||
frame_I_one_frame(ind_r,ind_seg) = ...
|
||||
mean(frame_data(integ_masks.indices{ind_r,ind_seg}));
|
||||
frame_std_one_frame(ind_r,ind_seg) = ...
|
||||
std(frame_data(integ_masks.indices{ind_r,ind_seg}));
|
||||
else
|
||||
% mark unknown intensities
|
||||
frame_I_one_frame(ind_r,ind_seg) = -1;
|
||||
frame_std_one_frame(ind_r,ind_seg) = -1;
|
||||
end
|
||||
end
|
||||
end
|
||||
frame_I(:,:,ind_frame) = frame_I_one_frame;
|
||||
frame_std(:,:,ind_frame) = frame_std_one_frame;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
%%%%%%%%%%
|
||||
function [frame_I,frame_std] = ...
|
||||
perform_radial_integ_parallel(file_ind, file_ind_max, ...
|
||||
filename, ...
|
||||
integ_masks, ind_r_max, no_of_segments, ...
|
||||
vararg)
|
||||
import beamline.prep_integ_masks
|
||||
import io.image_read
|
||||
import plotting.plot_radial_integ
|
||||
import utils.default_parameter_value
|
||||
import utils.find_files
|
||||
% read the raw data frame
|
||||
fprintf('%6d /%6d: ',file_ind,file_ind_max);
|
||||
[frame] = image_read(filename, vararg);
|
||||
if (isempty(frame.data))
|
||||
error('could not load %s',filename);
|
||||
end
|
||||
|
||||
% get the number of frames in case of multi-frame data files like HDF5
|
||||
no_of_frames = size(frame.data,3);
|
||||
|
||||
% initialize result variables
|
||||
frame_I = zeros(ind_r_max,no_of_segments,no_of_frames);
|
||||
frame_std = zeros(ind_r_max,no_of_segments,no_of_frames);
|
||||
|
||||
|
||||
parfor (ind_frame = 1:no_of_frames)
|
||||
% get the current frame
|
||||
frame_data = double(frame.data(:,:,ind_frame));
|
||||
% initialize output variables for current data
|
||||
frame_I_one_frame = zeros(ind_r_max,no_of_segments);
|
||||
frame_std_one_frame = zeros(ind_r_max,no_of_segments);
|
||||
|
||||
for (ind_r = 1:ind_r_max)
|
||||
for (ind_seg = 1:no_of_segments)
|
||||
if (integ_masks.norm_sum(ind_r,ind_seg) > 0)
|
||||
frame_I_one_frame(ind_r,ind_seg) = ...
|
||||
mean(frame_data(integ_masks.indices{ind_r,ind_seg}));
|
||||
frame_std_one_frame(ind_r,ind_seg) = ...
|
||||
std(frame_data(integ_masks.indices{ind_r,ind_seg}));
|
||||
else
|
||||
% mark unknown intensities
|
||||
frame_I_one_frame(ind_r,ind_seg) = -1;
|
||||
frame_std_one_frame(ind_r,ind_seg) = -1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
frame_I(:,:,ind_frame) = frame_I_one_frame;
|
||||
frame_std(:,:,ind_frame) = frame_std_one_frame;
|
||||
end
|
||||
@@ -0,0 +1,194 @@
|
||||
% (beamline.)radial_integ_wrapper()
|
||||
% Reads the radial integration filequeue when the filequeue is enabled
|
||||
% by _filequeue_on in SPEC, and calls the radial integration script with
|
||||
% parameters generated by radial_integration_SAXS_and_WAXS from scan of
|
||||
% standards.
|
||||
% This function is called without arguments to run on multiple nodes in
|
||||
% parallel.
|
||||
% Make sure your current matlab directory is Data10/matlab/.
|
||||
% To change default settings modify the starting lines in function body.
|
||||
%
|
||||
% see also: beamline.radial_integ
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 radial_integ_wrapper()
|
||||
|
||||
import utils.verbose
|
||||
|
||||
p=struct();
|
||||
p.queue_path = utils.abspath('../specES1/radial_integ_queue');
|
||||
p.det_todo = [1 2];
|
||||
p.recon_latest_first = 0; % =0 from first; =1 from last; =2 random.
|
||||
|
||||
|
||||
% ----- Modify until here -----
|
||||
|
||||
finishup = utils.onCleanup(@(x) radial_integ_exit(x), p);
|
||||
for i=1:numel(p.det_todo)
|
||||
mat_todo=[utils.abspath('../analysis/radial_integration_todo') sprintf('/vargin_det%d.mat',p.det_todo(i))];
|
||||
try
|
||||
m=load(mat_todo);
|
||||
catch err
|
||||
error(sprintf('Did not find vargin file for detector %d, check current folder is in matlab/, and the radial integration standards are finished.\n',p.det_todo(i)));
|
||||
end
|
||||
args_todo{i}=m.args;
|
||||
end
|
||||
|
||||
|
||||
while 1==1
|
||||
|
||||
finishup.update(p);
|
||||
|
||||
if ~exist(fullfile(p.queue_path,'in_progress'),'dir')
|
||||
mkdir(fullfile(p.queue_path,'in_progress'));
|
||||
end
|
||||
|
||||
if ~exist(fullfile(p.queue_path,'failed'),'dir')
|
||||
mkdir(fullfile(p.queue_path,'failed'));
|
||||
end
|
||||
|
||||
if ~exist(fullfile(p.queue_path,'done'),'dir')
|
||||
mkdir(fullfile(p.queue_path,'done'));
|
||||
end
|
||||
|
||||
fext = 'dat';
|
||||
|
||||
status_ok = true;
|
||||
verbose(1,['Touching folder and looking for files in the queue in ' p.queue_path]);
|
||||
system(sprintf('touch %s',p.queue_path));
|
||||
files_recons = dir(fullfile(p.queue_path,'scan*.dat'));
|
||||
|
||||
% Found one file to reconstruct
|
||||
if ~isempty(files_recons)
|
||||
if p.recon_latest_first==0
|
||||
p.file_this_recons = files_recons(1).name;
|
||||
elseif p.recon_latest_first==1
|
||||
p.file_this_recons = files_recons(end).name;
|
||||
else
|
||||
p.file_this_recons = files_recons(randi([1 numel(files_recons)])).name;
|
||||
end
|
||||
finishup.update(p);
|
||||
verbose(1,['Found file in queue ' fullfile(p.queue_path,p.file_this_recons)]);
|
||||
% now move it quickly before someone else will take it
|
||||
try
|
||||
io.movefile_fast(fullfile(p.queue_path,p.file_this_recons),fullfile(p.queue_path,'in_progress'))
|
||||
verbose(1,['Moving file to ' fullfile(p.queue_path,'in_progress')]);
|
||||
catch
|
||||
verbose(1,['Failed moving file to ' fullfile(p.queue_path,'in_progress')]);
|
||||
pause(1);
|
||||
status_ok = false;
|
||||
end
|
||||
|
||||
if status_ok
|
||||
% parse the file
|
||||
|
||||
fid = fopen(fullfile(p.queue_path,'in_progress',p.file_this_recons),'r');
|
||||
|
||||
tline = fgetl(fid);
|
||||
while ischar(tline)
|
||||
str_parts = strsplit(tline, ' ');
|
||||
if numel(str_parts)>1
|
||||
fname = strtrim(str_parts{1});
|
||||
if strcmpi(fname(1:2), 'p.')
|
||||
% found p entry
|
||||
val = [];
|
||||
for ii=2:numel(str_parts)
|
||||
if ~isempty(strtrim(str_parts{ii}))
|
||||
if ~isnan(str2double(str_parts{ii}))
|
||||
% found number
|
||||
val = [val, str2double(str_parts{ii})];
|
||||
else
|
||||
% found char
|
||||
val = [val, strtrim(str_parts{ii})];
|
||||
end
|
||||
end
|
||||
end
|
||||
p.(fname(3:end)) = val;
|
||||
|
||||
|
||||
elseif strcmpi(str_parts{1}, 'samplename')
|
||||
p.samplename = strjoin(strtrim(str_parts(2:end)), '_');
|
||||
end
|
||||
end
|
||||
tline = fgetl(fid);
|
||||
end
|
||||
|
||||
fclose(fid);
|
||||
finishup.update(p);
|
||||
try
|
||||
for i=1:numel(p.det_todo)
|
||||
beamline.integrate_range(p.scan_number,p.scan_number,1,args_todo{i});
|
||||
end
|
||||
verbose(1,['Radial integration of scan ' num2str(p.scan_number) ' finished, moving queue file to ' fullfile(p.queue_path,'done')]);
|
||||
file_move_from = fullfile(p.queue_path,'in_progress',p.file_this_recons);
|
||||
file_move_to = fullfile(p.queue_path,'done',p.file_this_recons);
|
||||
io.movefile_fast(file_move_from,file_move_to);
|
||||
catch err
|
||||
try
|
||||
verbose(1,['Error encountered at scan ' num2str(p.scan_number) ', moving queue file to ' fullfile(p.queue_path,'failed')]);
|
||||
file_move_from = fullfile(p.queue_path,'in_progress',p.file_this_recons);
|
||||
file_move_to = fullfile(p.queue_path,'failed',p.file_this_recons);
|
||||
io.movefile_fast(file_move_from,file_move_to);
|
||||
disp(err);
|
||||
catch err
|
||||
verbose(1,['Error with file system delays, skipping.']);
|
||||
disp(err);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
verbose(1,'Did not find enough files in queue, pausing 10 seconds.');
|
||||
pause(10);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function radial_integ_exit(p)
|
||||
import utils.verbose;
|
||||
verbose(1,'Radial integration interrupted');
|
||||
if isfile(fullfile(p.queue_path,'in_progress',p.file_this_recons))
|
||||
try
|
||||
verbose(1,['Moving current queue file back to ' p.queue_path]);
|
||||
file_move_from = fullfile(p.queue_path,'in_progress',p.file_this_recons);
|
||||
file_move_to = fullfile(p.queue_path,p.file_this_recons);
|
||||
io.movefile_fast(file_move_from,file_move_to);
|
||||
catch
|
||||
disp(err);
|
||||
verbose(1,'File system error, aborting.');
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,548 @@
|
||||
% radial_integration_SAXS_and_WAXS.m
|
||||
% Template for radial integration made around 2015
|
||||
% Changes:
|
||||
% 2016-08-22: define mask files at the beginning, allowing for a flag in case it needs to be repeated
|
||||
% add the save fast and v6
|
||||
|
||||
% License at the end of script
|
||||
|
||||
clear all
|
||||
close all
|
||||
|
||||
%% step 0: add the path for the matlab-scripts (fill in userID,detno and specdatfile)
|
||||
addpath ..
|
||||
%e-account followed by underline
|
||||
userID = [beamline.identify_eaccount '_'];
|
||||
% detector number: 1 for SAXS Pilatus 2M, 2 for WAXS Pilatus 300k, 3 for
|
||||
% SAXS Eiger 500 k
|
||||
detno = 1;
|
||||
% which data format to save? '-v6' is the standard.
|
||||
save_format = '-v6';
|
||||
% flag for filenames for valid pixel mask, beamstop mask coordinates and integration mask.
|
||||
% Example: '_2M_at_two_meters'
|
||||
% Leave empty '' for default folder and filenames.
|
||||
file_flag='';
|
||||
|
||||
% change here for offline analysis
|
||||
homedir = sprintf('~/Data10/');
|
||||
%homedir = '/mnt/das-gpfs/work/p16268/';
|
||||
|
||||
%CHANGE: spec dat file
|
||||
SpecDatFile = '~/Data10';
|
||||
|
||||
if (detno == 1 )||(detno == 2)
|
||||
datadir = fullfile(sprintf('%s',homedir),sprintf('pilatus_%d/',detno));
|
||||
elseif detno == 3
|
||||
datadir = fullfile(sprintf('%s',homedir),sprintf('eiger'));
|
||||
end
|
||||
if detno == 2
|
||||
integdir = sprintf('%sanalysis/radial_integration_waxs%s/',homedir,file_flag);
|
||||
elseif detno == 1
|
||||
integdir = sprintf('%sanalysis/radial_integration%s/',homedir,file_flag);
|
||||
elseif detno == 3
|
||||
integdir = sprintf('%sanalysis/radial_integration_eiger%s/',homedir,file_flag);
|
||||
end
|
||||
if detno == 2
|
||||
outdir = sprintf('%sanalysis/data_waxs%s/',homedir,file_flag);
|
||||
elseif detno == 1
|
||||
outdir = sprintf('%sanalysis/data/%s',homedir,file_flag);
|
||||
elseif detno == 3
|
||||
outdir = sprintf('%sanalysis/data_eiger%s/',homedir,file_flag);
|
||||
end
|
||||
addpath(sprintf('%smatlab/',homedir));
|
||||
if (detno == 1 )||(detno == 2)
|
||||
maskfilename = sprintf('%spilatus_%d_valid_mask%s.mat', outdir,detno,file_flag);
|
||||
integmaskfilename=sprintf('%spilatus_%d_integration_masks%s.mat',outdir,detno,file_flag);
|
||||
elseif detno == 3
|
||||
maskfilename = sprintf('%seiger_%d_valid_mask%s.mat', outdir,detno,file_flag);
|
||||
integmaskfilename=sprintf('%seiger_%d_integration_masks%s.mat',outdir,detno,file_flag);
|
||||
end
|
||||
maskcoordfilename=sprintf('%smask_coordinates_%d%s.mat',outdir,detno, file_flag);
|
||||
|
||||
dirs = whos('-regexp','.*dir$');
|
||||
for ii=1:numel(dirs)
|
||||
dir_to_do = eval(dirs(ii).name);
|
||||
if ~exist(dir_to_do,'dir')
|
||||
fprintf('creating directory %s\n', dir_to_do);
|
||||
system(sprintf('mkdir -p %s',dir_to_do));
|
||||
end
|
||||
end
|
||||
%% enter scan numbers of standards
|
||||
%glassy carbon, glassy carbon moved detector to side, air scattering, first
|
||||
%one is glassy carbon used to remove beamstop later
|
||||
scannr = [14 15 14];
|
||||
%AgBE (for SAXS and WAXS), LaB6 (for WAXS), Si (for WAXS)
|
||||
todo = [12 13 14];
|
||||
legendstr = {'AgBE';'LaB6';'Si'};
|
||||
|
||||
%% step 1: prepare the valid pixel mask
|
||||
redo = 1;
|
||||
|
||||
if (redo)
|
||||
fprintf('preparing the valid pixel mask\n');
|
||||
|
||||
% calculating the union of several valid pixel masks
|
||||
% starting with a rather dark file to discriminate hot pixels
|
||||
system(sprintf('rm -f %s', maskfilename));
|
||||
|
||||
if (detno == 1 )||(detno == 2)
|
||||
prepvalidmask_args = {};
|
||||
compilex12sa_args = {'DetectorNumber',detno,'FileExtension','cbf'};
|
||||
integrate_range_args = {'PilatusDetNo',detno,'FileExtension','cbf'};
|
||||
elseif detno == 3
|
||||
prepvalidmask_args = {'H5Location','/eh5/images/','FilenameMask','*'};
|
||||
compilex12sa_args = {'FileExtension','h5'};
|
||||
end
|
||||
|
||||
for ii=scannr
|
||||
beamline.prep_valid_mask(utils.compile_x12sa_filename(ii,-1, ...
|
||||
'BasePath',datadir,'BaseName',userID,compilex12sa_args{:}), ...
|
||||
'ThresholdDark',1, ...
|
||||
'ThresholdHot',20, ...
|
||||
'Extend','or', ...
|
||||
'FilenameValidMask',maskfilename,prepvalidmask_args{:});
|
||||
% 'FigNo',ii==scannr(end));
|
||||
end
|
||||
end
|
||||
%% step 2: cut out beam stop and shadows manually (for WAXS only necessary if there is a shadow)
|
||||
|
||||
redo = 1;
|
||||
if (redo)
|
||||
scannr = scannr(1);
|
||||
if (detno == 1)||(detno == 2)
|
||||
compilex12sa_args = {'DetectorNumber',detno,'FileExtension','cbf'};
|
||||
imageshow_args = {};
|
||||
elseif (detno == 3)
|
||||
compilex12sa_args = {'FileExtension','h5'};
|
||||
imageshow_args = {'H5Location','/eh5/images/'};
|
||||
end
|
||||
% include the beamstop in the valid pixel mask - follow instructions in
|
||||
% popup box
|
||||
beamline.choose_beamstop_mask(utils.compile_x12sa_filename(scannr(1),0, 'BasePath',datadir,'BaseName',userID, compilex12sa_args{:}),...
|
||||
'ReadCoord',0,'SaveCoord',1, 'SaveData',1,'FilenameValidMask',maskfilename,'FilenameCoord',maskcoordfilename, 'ImageShowArgs', imageshow_args)
|
||||
|
||||
end
|
||||
%% show silver behenate scattering to find the radius of the first ring (only SAXS)
|
||||
if (detno==1)
|
||||
plotting.image_show(utils.compile_x12sa_filename(todo(1),0, ...
|
||||
'PointWildcard', 1, ...
|
||||
'SubExpWildcard', 1, ...
|
||||
'DetectorNumber',detno, ...
|
||||
'BasePath',datadir,'BaseName',userID), ...
|
||||
'IsFmask', true);
|
||||
elseif (detno == 3)
|
||||
filepath = utils.compile_x12sa_dirname(todo(1));
|
||||
D = dir(fullfile(datadir,filepath,'*.h5'));
|
||||
plotting.image_show(fullfile(D(1).folder,D(1).name), ...
|
||||
'H5Location','/eh5/images/');
|
||||
end
|
||||
%% here you have to give some manual inputs to run step 3
|
||||
% for SAXS you have to put y pixel value of the the silver behenate ring above the beamstop, and the order of the peak that you chose
|
||||
if (detno==1)||(detno == 3)
|
||||
order_AgBE = 1;
|
||||
y_from = 509;
|
||||
y_to = 514;
|
||||
cen_guess = []; %[y,x] ; leave empty, i.e. cen_guess=[], for automatic guess;
|
||||
%and choose how many sectors you want to do the integration (16 for
|
||||
%anisotropic scattering, 1 for isotropic scattering
|
||||
num_segments=16;
|
||||
elseif (detno==2)
|
||||
%for WAXS you can run with the default values to start with and adjust in
|
||||
%case an error appears or the fit (shown in figure 4) is bad
|
||||
|
||||
open('+beamline/WAXS_standards.fig');
|
||||
%give the order of the first silver behenate ring appearing
|
||||
%(compare with WAXS_standards.fig)
|
||||
order_AgBe=7;
|
||||
|
||||
%parameter used in finding the x-position, default 5, if in figure 20 the
|
||||
%blue curve is all zeros, lower this value (necessary for low intensity of
|
||||
%silver behenate measurement
|
||||
d = 5;
|
||||
|
||||
%threshold to find WAXS peak of standards, default is 50, might be lowered
|
||||
%for lower intensities
|
||||
threshold=[2 50 100];
|
||||
%if wrong peaks are found tune finding the right peaks with the window
|
||||
%where peaks are being searched here, default is min=0 and max=1500,
|
||||
%(see WAXS_standards.fig)
|
||||
min_AgBE=0;
|
||||
max_AgBE=1500;
|
||||
min_Si=0;
|
||||
max_Si=1500;
|
||||
min_LaB6=0;
|
||||
max_LaB6=1500;
|
||||
|
||||
end
|
||||
% step 3: prepare integration mask
|
||||
% For the WAXS mask this is still a bit clunky. You can adjust above the
|
||||
% min and max values where it will look for a peak and the threshold. Also
|
||||
% in the fit for the horizonal position make sure there is both red and
|
||||
% blue peaks for the fitting, if not you can adjust the d parameter above.
|
||||
% Decreasing it helps when the silver behenate scattering is low.
|
||||
|
||||
if (detno==1)
|
||||
scannr = todo(1);
|
||||
else
|
||||
%here enter the scannumbers of the standards
|
||||
% todo = [211,208,212];
|
||||
% legendstr = {'AgBE';'LaB6';'Si'};
|
||||
scannr = todo(1);
|
||||
S = io.spec_read(SpecDatFile,'ScanNr',todo(1));
|
||||
end
|
||||
|
||||
if (detno==1)||(detno==2)
|
||||
I = plotting.image_show(utils.compile_x12sa_filename(scannr,0, ...
|
||||
'PointWildcard', 1, ...
|
||||
'SubExpWildcard', 1, ...
|
||||
'DetectorNumber',detno, ...
|
||||
'BasePath',datadir,'BaseName',userID), ...
|
||||
'IsFmask', true);
|
||||
elseif (detno == 3)
|
||||
filepath = utils.compile_x12sa_dirname(scannr);
|
||||
D = dir(fullfile(datadir,filepath,'*.h5'));
|
||||
I = plotting.image_show(fullfile(D(1).folder,D(1).name), ...
|
||||
'H5Location','/eh5/images/');
|
||||
end
|
||||
|
||||
|
||||
mask = getfield(load(maskfilename),'valid_mask');
|
||||
mask.frame = zeros(mask.framesize);
|
||||
mask.frame(mask.indices) = 1;
|
||||
|
||||
I = mean(I.data,3).*mask.frame;
|
||||
if (detno==1)||(detno == 3)
|
||||
J = ifftn(fftn(I,size(I)*2-[1 1]).^2);
|
||||
if isempty(cen_guess)
|
||||
cen_guess = math.peakfit2d(J)/2; %[y,x]
|
||||
end
|
||||
|
||||
if (detno == 1)
|
||||
filename_center = utils.compile_x12sa_filename(scannr(1),0, 'BasePath',datadir,'BaseName',userID);
|
||||
imageshow_args = {};
|
||||
elseif (detno == 3)
|
||||
filename_center = fullfile(D(1).folder,D(1).name);
|
||||
imageshow_args = {'H5Location','/eh5/images/'};
|
||||
end
|
||||
|
||||
[cen]=utils.get_beam_center(filename_center,'GuessX',cen_guess(2),'GuessY',cen_guess(1), ...
|
||||
'RadiusFrom',y_from-cen_guess(1),'RadiusTo',y_to-cen_guess(1), ...
|
||||
'TestX',4,'TestY',4,'FilenameValidMask',maskfilename, imageshow_args{:});
|
||||
|
||||
else
|
||||
% this isn't nice yet
|
||||
% i) it depends on the chosen orientation on how to read
|
||||
% detector-2 images
|
||||
% ii) it merely finds maximum values instead of fitting, possibly
|
||||
% with sub-pixel precision
|
||||
% iii) as a consequence, figuring out which values are trustworthy
|
||||
% is done rather crudly
|
||||
%d = 3; %5 seams not to work if intensity of silver behenate is too low??
|
||||
if (detno == 2)
|
||||
imageshow_args = {};
|
||||
end
|
||||
dx = 30;
|
||||
[s1,s2] = size(I);
|
||||
|
||||
J = ifft(fft(I,s1*2-1,1).^2,[],1);
|
||||
[~,n] = max(J);
|
||||
w = std(I,1,1)./sqrt(mean(I,1));
|
||||
o = 1:numel(n);
|
||||
|
||||
o = o(w>d);
|
||||
n = n(w>d)/2;
|
||||
|
||||
o = o(abs(n-s1/2)<dx);
|
||||
n = n(abs(n-s1/2)<dx);
|
||||
|
||||
x = s1/2+linspace(-dx,dx,4*dx+1);
|
||||
|
||||
figure(20)
|
||||
m = histc(n,x);
|
||||
[~,n0] = max(m);
|
||||
plot(x,m)
|
||||
hold on
|
||||
|
||||
s = fitoptions('Method','NonlinearLeastSquares',...
|
||||
'Lower',[ 0,s1/2-dx, 0, 0, 0],...
|
||||
'Upper',[Inf,s1/2+dx,Inf,Inf,Inf],...
|
||||
'Startpoint',[10,x(n0),1,10,1]);
|
||||
f = fittype('a*exp(-((x-b)/c)^2)+d*exp(-((x-n)/e)^2)', ...
|
||||
'problem','n','options',s);
|
||||
[c,~] = fit(x',m',f,'problem',s1/2);
|
||||
figure(50)
|
||||
plot(c,'r');
|
||||
hold off
|
||||
|
||||
figure(10)
|
||||
cen1 = c.b;
|
||||
o = o(abs(n-cen1)<=1);
|
||||
n = n(abs(n-cen1)<=1);
|
||||
hold on
|
||||
plot(o,n,'w.')
|
||||
plot([1 s2],[1 1]*round(cen1),'w')
|
||||
x = 1:s2;
|
||||
plot(x(mask.frame(round(cen1),:)>0), ...
|
||||
log(I(round(cen1),mask.frame(round(cen1),:)>0))/ ...
|
||||
max(log(I(round(cen1),mask.frame(round(cen1),:)>0)))*s1, ...
|
||||
'k')
|
||||
hold off
|
||||
|
||||
figure(30)
|
||||
WAXS = zeros(s2,numel(todo));
|
||||
WAXS(:,1) = I(round(cen1),:);
|
||||
for ii=2:numel(todo)
|
||||
I = io.image_read(utils.compile_x12sa_filename(todo(ii),0, ...
|
||||
'PointWildcard', 1, ...
|
||||
'SubExpWildcard', 1, ...
|
||||
'DetectorNumber',detno, ...
|
||||
'BasePath',datadir,'BaseName',userID), ...
|
||||
'IsFmask', 1);
|
||||
WAXS(:,ii) = mean(I.data(round(cen1),:,:),3);
|
||||
end
|
||||
|
||||
h = semilogy(WAXS);
|
||||
legend(legendstr)
|
||||
|
||||
% finding peaks "automatically"
|
||||
x_coord = [];
|
||||
q_coord = [];
|
||||
hold on
|
||||
peaks = cell(1,size(WAXS,2));
|
||||
for ii=1:size(WAXS,2)
|
||||
%the treshhold value, default set to 50, might be adjusted
|
||||
peaks{ii} = utils.peakfinder((WAXS(:,ii)),threshold(ii));
|
||||
%peaks{ii} = peakfinder((WAXS(:,ii)),50);
|
||||
if strcmp(legendstr{ii},'AgBE')
|
||||
tmp = peaks{ii};
|
||||
tmp = tmp(tmp>=min_AgBE);
|
||||
peaks{ii} = tmp(tmp<=max_AgBE);
|
||||
|
||||
end
|
||||
if strcmp(legendstr{ii},'Si')
|
||||
tmp = peaks{ii};
|
||||
tmp = tmp(tmp>=min_Si);
|
||||
peaks{ii} = tmp(tmp<=max_Si);
|
||||
end
|
||||
if strcmp(legendstr{ii},'LaB6')
|
||||
tmp = peaks{ii};
|
||||
tmp = tmp(tmp<=max_LaB6);
|
||||
peaks{ii} = tmp(tmp>=min_LaB6);
|
||||
|
||||
end
|
||||
|
||||
|
||||
x_coord = vertcat(x_coord,peaks{ii});
|
||||
if strcmp(legendstr{ii},'AgBE')
|
||||
q0 = 2*pi/58.38;
|
||||
q_coord = horzcat(q_coord,q0*(order_AgBe+(0:numel(peaks{ii})-1)));
|
||||
elseif strcmp(legendstr{ii},'LaB6')
|
||||
q0 = 2*pi/4.1549;
|
||||
q_coord = horzcat(q_coord,q0*sqrt((1:numel(peaks{ii}))));
|
||||
elseif strcmp(legendstr{ii},'Si')
|
||||
q0 = 2*pi/5.4308;
|
||||
q_coord = horzcat(q_coord,q0*sqrt(3));
|
||||
end
|
||||
semilogy(peaks{ii},WAXS(peaks{ii},ii),'.', ...
|
||||
'Color',get(h(ii),'Color'), ...
|
||||
'MarkerSize',24)
|
||||
end
|
||||
hold off
|
||||
|
||||
figure(40); clf
|
||||
if (numel(x_coord)>3)
|
||||
% fprintf('%f\t%f\n',[x_coord';q_coord])
|
||||
% % a
|
||||
% % b
|
||||
% % c
|
||||
s = fitoptions('Method','NonlinearLeastSquares',...
|
||||
'Lower' ,[-Inf,-Inf, 0],...
|
||||
'Upper' ,[ Inf, 0,1e3],...
|
||||
'Startpoint',[s2/2, 200,550]);
|
||||
f = fittype('4*pi/l*sin((atan((a-b)*p/c)+atan((x-a)*p/c))/2)', ...
|
||||
'problem',{'p','l'},'options',s);
|
||||
[c,~] = fit(x_coord,q_coord',f,'problem',{.172,12.398/S.mokev});
|
||||
subplot(2,1,1)
|
||||
plot(x_coord,q_coord,'x');
|
||||
hold on
|
||||
drawnow;
|
||||
tmp = axis;
|
||||
x = linspace(c.b,tmp(2));
|
||||
plot(x,feval(c,x),'r');
|
||||
subplot(2,1,2)
|
||||
bar(x_coord,feval(c,x_coord)-q_coord');
|
||||
xlim(tmp(1:2));
|
||||
dc = confint(c);
|
||||
dc = (dc(2,:)-dc(1,:))/2;
|
||||
fprintf(['detector distance:\t%.1fmm, \t%.1fmm\n', ...
|
||||
'center of rings: \t%.1fpixels,\t%.1fpixels\n', ...
|
||||
'angle of detector:\t%.1fdeg, \t%.1fdeg.\n'], ...
|
||||
c.c,dc(3), ...
|
||||
c.b,dc(2), ...
|
||||
atan((c.a-c.b)*c.p/c.c)/pi*180, ...
|
||||
180/pi*c.p/c.c*sqrt(dc(1)^2+dc(2)^2 + ((c.a-c.b)/c.c*dc(3))^2));
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
tic
|
||||
if (detno==1)||(detno==3)
|
||||
S = io.spec_read(SpecDatFile,'ScanNr',todo(1));
|
||||
fprintf('preparing the integration mask(s)\n');
|
||||
beamline.prep_integ_masks(utils.compile_x12sa_filename(todo(1),0, ...
|
||||
'BasePath',datadir,'BaseName',userID, compilex12sa_args{:}), ...
|
||||
cen, ...
|
||||
'DetNo',detno, ...
|
||||
'NoOfSegments',num_segments, ...
|
||||
'FilenameValidMask',maskfilename, ...
|
||||
'FilenameIntegMasks',integmaskfilename, imageshow_args{:});
|
||||
|
||||
beamline.integrate_range(todo(1),todo(1),1, ... % change for not re-running on already integrated files
|
||||
'OutdirData',integdir, ...
|
||||
'BasePath',datadir,'BaseName',userID, ...
|
||||
'FilenameIntegMasks',integmaskfilename, ...
|
||||
compilex12sa_args{:},imageshow_args{:});
|
||||
|
||||
elseif (detno==2)
|
||||
S = io.spec_read(SpecDatFile,'ScanNr',todo(1));
|
||||
fprintf('preparing the integration mask(s)\n');
|
||||
beamline.prep_integ_masks(utils.compile_x12sa_filename(todo(1),0, ...
|
||||
'DetectorNumber',detno, ...
|
||||
'BasePath',datadir,'BaseName',userID), ...
|
||||
[c.b cen1], ...
|
||||
'DetNo',detno, ...
|
||||
'Wavelength_nm', 12.398/S.mokev, ...
|
||||
'NormalXY', [c.a cen1], ...
|
||||
'DetDist_mm', c.c, ...
|
||||
'PixelSize_mm', .172, ...
|
||||
'NoOfSegments',1, ...
|
||||
'FilenameValidMask',maskfilename, ...
|
||||
'FilenameIntegMasks',integmaskfilename, ...
|
||||
'DisplayValidMask',0);
|
||||
end
|
||||
toc
|
||||
|
||||
|
||||
%% calculate detector distance (SAXS only) check in Figure 100 if the peak_agbe really is the 1st order AgBE
|
||||
if (detno==1)||(detno==3)
|
||||
[x,y] = plotting.plot_radial_integ(sprintf('%s%s%d_%05d_00000_00000_integ.mat',integdir,userID,1,todo(1)));
|
||||
%%the 1st order silver behenate is at ... pixels
|
||||
%peakfinder(log(y(10:end)),1);
|
||||
peaks2 = utils.peakfinder(log(y(10:end)),1);
|
||||
peak_agbe = x(peaks2(order_AgBE+1))+9 %normally the 1st order AgBE, check!
|
||||
wavelength = 12.398/S.mokev;
|
||||
detector_distance = peak_agbe*.172/tan(2*asin(wavelength*order_AgBE/(2*58.38)))
|
||||
end
|
||||
%% redo SAXS integration mask now it will take the detector distance into account and also save the q-value
|
||||
if (detno==1)||(detno==3)
|
||||
if (detno == 1)
|
||||
detector_pixelsize = 0.172;
|
||||
elseif (detno == 3)
|
||||
detector_pixelsize = 0.075;
|
||||
end
|
||||
S = io.spec_read(SpecDatFile,'ScanNr',todo(1));
|
||||
fprintf('preparing the integration mask(s)\n');
|
||||
beamline.prep_integ_masks(utils.compile_x12sa_filename(todo(1),0, ...
|
||||
'BasePath',datadir,'BaseName',userID,compilex12sa_args{:}), ...
|
||||
cen, ...
|
||||
'DetNo',detno, ...
|
||||
'NoOfSegments',num_segments, ...
|
||||
'Wavelength_nm', 12.398/S.mokev, ...
|
||||
'DetDist_mm', detector_distance, ...
|
||||
'PixelSize_mm', detector_pixelsize, ...
|
||||
'FilenameValidMask',maskfilename, ...
|
||||
'FilenameIntegMasks',integmaskfilename, imageshow_args{:});
|
||||
end
|
||||
%% step 5: radial integration & averaging of files --
|
||||
%start here again if you merely want to integreat
|
||||
%for fast measurements (i.e. scanning SAXS) start on several cn parallel
|
||||
%adjust therefor integrate_range(scan_no_from,scan_no_to,scan_no_step)
|
||||
%and rund only step 0 and step 5
|
||||
save_format = '-v6';
|
||||
|
||||
close all
|
||||
% beamline.integrate_range(107,1e8,3, ... % change for not re-running on already integrated files
|
||||
% 'PilatusDetNo',detno, ...
|
||||
% 'OutdirData',integdir, ...
|
||||
% 'BasePath',datadir,'BaseName',userID, ...
|
||||
% 'FilenameIntegMasks',integmaskfilename, 'SaveFormat', save_format);
|
||||
|
||||
beamline.integrate_range(136,137,1, ... % change for not re-running on already integrated files
|
||||
'OutdirData',integdir, ...
|
||||
'BasePath',datadir,'BaseName',userID, ...
|
||||
'FilenameIntegMasks',integmaskfilename, 'SaveFormat', save_format, ...
|
||||
integrate_range_args{:},imageshow_args{:});
|
||||
|
||||
|
||||
%% or alternatively when computers node are ready and matlab is open
|
||||
save_format = '-v6';
|
||||
fprintf('beamline.integrate_range(107,1e8,4,''OutdirData'',''%s'',''BasePath'',''%s'',''BaseName'',''%s'',''FilenameIntegMasks'',''%s'',''SaveFormat'', ''%s''',integdir,datadir,userID,integmaskfilename,save_format)
|
||||
args={'OutdirData', integdir,'BasePath',datadir ,'BaseName',userID ,'FilenameIntegMasks',integmaskfilename ,'SaveFormat',save_format };
|
||||
|
||||
for ii = 1:2:numel(integrate_range_args)
|
||||
if ischar(integrate_range_args{ii+1})
|
||||
straux = '''%s''';
|
||||
elseif isnumeric(integrate_range_args{ii+1})
|
||||
straux = '%d';
|
||||
end
|
||||
fprintf( [',''%s'',' straux ' '] ,integrate_range_args{ii},integrate_range_args{ii+1});
|
||||
args=[args,integrate_range_args{ii},integrate_range_args{ii+1}];
|
||||
end
|
||||
for ii = 1:2:numel(imageshow_args)
|
||||
if ischar(imageshow_args{ii+1})
|
||||
straux = '''%s''';
|
||||
elseif isnumeric(imageshow_args{ii+1})
|
||||
straux = '%d';
|
||||
end
|
||||
fprintf([',''%s'',' straux ' '],imageshow_args{ii},imageshow_args{ii+1});
|
||||
args=[args,imageshow_args{ii},imageshow_args{ii+1}];
|
||||
end
|
||||
|
||||
% if detno==2 % Disable CReader for WAXS detector since currently it's not supported.
|
||||
% fprintf([',''CReader'',0 ']);
|
||||
% args=[args,'CReader',0];
|
||||
% end
|
||||
|
||||
fprintf(');\n')
|
||||
|
||||
folder_todo=utils.abspath('~/Data10/analysis/radial_integration_todo/');
|
||||
if ~exist(folder_todo)
|
||||
mkdir(folder_todo);
|
||||
end
|
||||
|
||||
save(sprintf([folder_todo 'vargin_det%d.mat'],detno),'args');
|
||||
fprintf(['Parameters saved to' folder_todo 'vargin_det%d.mat\n'],detno);
|
||||
%%
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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.
|
||||
@@ -0,0 +1,130 @@
|
||||
% read_omny_angles( OMNY_angles_file, scannums, tomo_id )
|
||||
% OMNY_angles_file - File with Scan number, angle target, angle readout
|
||||
% scannums - Array of scan numbers
|
||||
% tomo_id - integer or list of integers, only if the scannums is empty
|
||||
%
|
||||
% out - Contains fields with scan, target_angle, readout_angle
|
||||
% errorflag - = 1 if at least one scan was not found
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 [ out errorflag ] = read_omny_angles( OMNY_angles_file, scannums, tomo_id )
|
||||
|
||||
if ~exist(OMNY_angles_file, 'file')
|
||||
error('Missing OMNY file: %s', OMNY_angles_file)
|
||||
end
|
||||
|
||||
if ~exist('tomo_id')
|
||||
tomo_id = [];
|
||||
end
|
||||
|
||||
if (~isempty(scannums))&&(~isempty(tomo_id))
|
||||
error('You have provided both scannums and tomo_id, please provide just either scannums OR tomo_id. One of them should be empty ( =[] ).')
|
||||
end
|
||||
if (isempty(scannums))&&(isempty(tomo_id))
|
||||
error('You have not provided scannums or tomo_id, please provide either scannums OR tomo_id. One of them should be empty ( =[] ).')
|
||||
end
|
||||
fid = fopen(OMNY_angles_file);
|
||||
|
||||
% check omny file type
|
||||
ln = fgetl(fid);
|
||||
switch numel(strsplit(ln, ' '))
|
||||
case {3,6}
|
||||
outmat = textscan(fid,'%f %f %f %f %f %s');
|
||||
fclose(fid);
|
||||
out = [];
|
||||
errorflag = 0;
|
||||
counter = 1;
|
||||
|
||||
for ii = 1:numel(scannums)
|
||||
ind = find(outmat{1}==scannums(ii),1,'last');
|
||||
if isempty(ind)
|
||||
fprintf('Did not find Scan %d in %s\n',scannums(ii),OMNY_angles_file);
|
||||
errorflag = 1;
|
||||
else
|
||||
out.scan(counter) = outmat{1}(ind);
|
||||
out.target_angle(counter) = outmat{2}(ind);
|
||||
out.readout_angle(counter) = outmat{3}(ind);
|
||||
out.subtomo_num(counter) = outmat{4}(ind);
|
||||
out.detpos_num(counter) = outmat{5}(ind);
|
||||
out.sample_name(counter) = outmat{6}(ind);
|
||||
counter = counter+1;
|
||||
end
|
||||
end
|
||||
case 7
|
||||
outmat = textscan(fid,'%f %f %f %f %f %f %s');
|
||||
fclose(fid);
|
||||
out = [];
|
||||
errorflag = 0;
|
||||
counter = 1;
|
||||
if ~isempty(scannums)
|
||||
for ii = 1:numel(scannums)
|
||||
ind = find(outmat{1}==scannums(ii),1,'last');
|
||||
if isempty(ind)
|
||||
fprintf('Did not find Scan %d in %s\n',scannums(ii),OMNY_angles_file);
|
||||
errorflag = 1;
|
||||
else
|
||||
out.scan(counter) = outmat{1}(ind);
|
||||
out.target_angle(counter) = outmat{2}(ind);
|
||||
out.readout_angle(counter) = outmat{3}(ind);
|
||||
out.tomo_id(counter) = outmat{4}(ind);
|
||||
out.subtomo_num(counter) = outmat{5}(ind);
|
||||
out.detpos_num(counter) = outmat{6}(ind);
|
||||
out.sample_name(counter) = outmat{7}(ind);
|
||||
counter = counter+1;
|
||||
end
|
||||
end
|
||||
elseif ~isempty(tomo_id)
|
||||
ind = find(ismember(outmat{4},tomo_id));
|
||||
if isempty(ind)
|
||||
fprintf(['Did not find tomo_id ',repmat('%i ',1,length(tomo_id)),' in %s\n'],tomo_id,OMNY_angles_file);
|
||||
errorflag = 1;
|
||||
end
|
||||
out.scan = outmat{1}(ind);
|
||||
out.target_angle = outmat{2}(ind);
|
||||
out.readout_angle = outmat{3}(ind);
|
||||
out.tomo_id = outmat{4}(ind);
|
||||
out.subtomo_num = outmat{5}(ind);
|
||||
out.detpos_num = outmat{6}(ind);
|
||||
out.sample_name = outmat{7}(ind);
|
||||
end
|
||||
otherwise
|
||||
error('Unknown OMNY file format.')
|
||||
end
|
||||
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
% Read interferometer positions written by Orchestra
|
||||
% Input is the filename with path
|
||||
% Output is a structure containing fields:
|
||||
% The two values of the one line header originally 'Scan' and 'Samroy'
|
||||
% Values for each point of 10 expected columns of numbers
|
||||
% 12 June 2013
|
||||
% June6 2015 - Changed in order to accept an arbitrary number
|
||||
% of values in order to be compatible with 10 columns for flOMNI and 19 for
|
||||
% OMNY
|
||||
% This function should be replaced by beamline.read_position_file in the
|
||||
% ptycho codes and deprecated.
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 struct_out = read_omny_pos( omnyposfile )
|
||||
%disp(omnyposfile)
|
||||
struct_out = beamline.read_position_file( omnyposfile );
|
||||
%disp(size(struct_out.TotalPoints))
|
||||
end
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
% READ_POSITION_FILE Read positions from a file, the format and header are
|
||||
% compatible with multiple interferometer positions and standard deviations
|
||||
% as written by Orchestra and the sgalil spec macro.
|
||||
%
|
||||
% struct_out = read_position_file( posfile )
|
||||
% Inputs:
|
||||
% **posfile filename with path
|
||||
% *returns*
|
||||
% ++struct_out is a structure containing fields including the values
|
||||
% for header and for each scanning point
|
||||
|
||||
% 12 June 2013
|
||||
% June6 2015 - Changed in order to accept an arbitrary number
|
||||
% of values in order to be compatible with 10 columns for flOMNI and 19 for
|
||||
% OMNY
|
||||
% 15 Apr 2019 - Changed name and generalized description beyond OMNY and
|
||||
% Orchestra
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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 struct_out = read_position_file( posfile )
|
||||
|
||||
assert(exist(posfile, 'file')>0, ['Position file ', posfile, ' not found'])
|
||||
|
||||
f = fopen(posfile,'r');
|
||||
header = textscan(f,'%s %d, %s %f',1);
|
||||
struct_out.(header{1}{1}) = header{2};
|
||||
struct_out.(header{3}{1}) = header{4};
|
||||
names = textscan(f,'%s',1,'Delimiter','\r');
|
||||
names = strsplit(char(names{1}));
|
||||
reading_string = ['%f', repmat(' %f',1,numel(names)-1)];
|
||||
values = textscan(f,reading_string);
|
||||
fclose(f);
|
||||
|
||||
for ii = 1:numel(names)
|
||||
struct_out.(char(names(ii))) = values{ii};
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,803 @@
|
||||
% Call function without arguments for instructions on how to use it
|
||||
|
||||
% Filename: $RCSfile: stxm_online.m,v $
|
||||
%
|
||||
% $Revision: 1.16 $ $Date: 2011/04/04 17:03:48 $
|
||||
% $Author: $
|
||||
% $Tag: $
|
||||
%
|
||||
% Description:
|
||||
% plot a STXM scan
|
||||
%
|
||||
% Note:
|
||||
% Call without arguments for a brief help text.
|
||||
%
|
||||
% Dependencies:
|
||||
% - image_read
|
||||
%
|
||||
% history:
|
||||
%
|
||||
% April 4th 2011:
|
||||
% do not normalize the dark field since this is problematic for SAXS with a
|
||||
% beam stop
|
||||
%
|
||||
% September 29th 2010:
|
||||
% include changes by Martin Dierolf and Joan Vila in the standard version
|
||||
% of stxm_online
|
||||
%
|
||||
% December 10th 2008:
|
||||
% add bug-fixes and suggestions from Martin Dierolf:
|
||||
% DirPerLine parameter could not be set via the command line,
|
||||
% BurstMode flag was always active, is now coupled to dir_per_line,
|
||||
% new Parameter ZeroOrderR
|
||||
%
|
||||
% September 5th 2008:
|
||||
% use compile_x12sa_filename,
|
||||
% plot as 2x2 sub figures
|
||||
%
|
||||
% June 14th 2008: 1st documented version based on work
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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] = stxm_online(first_scan_number, Ny, varargin)
|
||||
import beamline.pilatus_valid_pixel_roi
|
||||
import io.image_read
|
||||
import plotting.image_show
|
||||
import utils.compile_x12sa_filename
|
||||
import utils.find_files
|
||||
|
||||
% set default values
|
||||
% Pilatus 2M
|
||||
detector_number = 1;
|
||||
% single directory or directory per line format
|
||||
dir_per_line = 1;
|
||||
% figure number for display
|
||||
fig_no = 2;
|
||||
% number of points along a scan line, 0 for automatic determination from
|
||||
% the first line
|
||||
Nx = 0;
|
||||
% size of the regio of interest
|
||||
roi_dim = 128;
|
||||
% automatic determination of the center position
|
||||
cen_x = 0;
|
||||
cen_y = 0;
|
||||
% dark field integration starting radius
|
||||
dark_field_r = 20;
|
||||
% radius of excluded area around center
|
||||
zero_order_r = 0;
|
||||
% calculate the first moment rather than a Fourier transform to get the
|
||||
% differential phase contrast
|
||||
first_moment = 1;
|
||||
% use additionally differentiation of the integrated phase
|
||||
integrated_phase = 1;
|
||||
% do not update the plot every line to save some time
|
||||
update_interval = 3;
|
||||
% save resulting figure
|
||||
figure_dir = '~/Data10/analysis/online/stxm/figures/';
|
||||
% save the resulting data
|
||||
data_dir = '~/Data10/analysis/online/stxm/data/';
|
||||
% valid pixel mask
|
||||
filename_valid_mask = '~/Data10/analysis/data/pilatus_valid_mask.mat';
|
||||
|
||||
phase = [];
|
||||
gx = [];
|
||||
gy = [];
|
||||
|
||||
full_screen_position_integrated_phase = [ 5 525 1201 420];
|
||||
print_a4_position_integrated_phase = [ 5 525 743 420 ];
|
||||
full_screen_position_standard = [ 5 109 1201 836];
|
||||
print_a4_position_standard = [ 5 109 743 836 ];
|
||||
|
||||
% check minimum number of input arguments
|
||||
if (nargin < 2)
|
||||
fprintf('Usage:\n')
|
||||
fprintf('[trans,dpcx,dpcy,df]=%s(<(first) scan number>, <no. of scan lines> [[,<name>,<value>] ...]);\n',...
|
||||
mfilename);
|
||||
fprintf('The optional <name>,<value> pairs are:\n');
|
||||
fprintf('''DetectorNumber'',<1-Pilatus 2M, 2-Pilatus 300k, 3-Pilatus 100k>\n');
|
||||
fprintf('''Nx'',<no. of points per line> default is %d (0 means automatic determination from first scan line)\n',Nx);
|
||||
fprintf('''ROIdim'',<no. of points> region of interest used for data analysis, default is %d\n',roi_dim);
|
||||
fprintf('''CenX'',<point> 0 means automatic determination, default is %d\n',cen_x);
|
||||
fprintf('''CenY'',<point> 0 means automatic determination, default is %d\n',cen_y);
|
||||
fprintf('''DarkFieldR'',<min. radius> dark field integration starts at this radius, default is %.0f\n',dark_field_r);
|
||||
fprintf('''FigNo'',<integer value> figure number for data display, default is %d\n',fig_no);
|
||||
fprintf('''DirPerLine'',<0-no,1-yes> separate directory for each scan line, default is %d\n',dir_per_line);
|
||||
fprintf('''ZeroOrderR'', <min. radius> pixel values inside this radius are set to zero, default is %d\n', zero_order_r);
|
||||
fprintf('''FirstMoment'',<0-no,1-yes> calculate the first moment rather than a Fourier transform to get the differential phase contrast, default is %d\n',first_moment);
|
||||
fprintf('''IntegratedPhase'',<0-no,1-yes> differentiate additionally the sum signal and re-differentiate it, default is %d\n',integrated_phase);
|
||||
fprintf('''UpdateInterval'',<integer N> update the plot each Nth line, default is %d\n',update_interval);
|
||||
fprintf('''FigureDir'',''directory'' save the resulting plot in eps, jpeg and Matlab fig format, '''' for no saving, default is %s\n',figure_dir);
|
||||
fprintf('''DataDir'',''directory'' save the resulting data as Matlab file, '''' for no saving, default is %s\n',data_dir);
|
||||
fprintf('''FilenameValidMask'',<path and filename> Matlab file with the valid pixel indices ind_valid, [] for no valid pixel mask,\n');
|
||||
fprintf(' default is %s\n',filename_valid_mask);
|
||||
fprintf('Additional <name>,<value> pairs recognized by compile_x12sa_filename and by image_read can be specified. Please call them for an overview\n');
|
||||
fprintf('\n');
|
||||
error('At least the (first) scan number and the number of scan lines have to be specified as input parameter.');
|
||||
end
|
||||
|
||||
% accept cell array with name/value pairs as well
|
||||
no_of_in_arg = nargin;
|
||||
if (nargin == 3)
|
||||
if (isempty(varargin))
|
||||
% ignore empty cell array
|
||||
no_of_in_arg = no_of_in_arg -1;
|
||||
else
|
||||
if (iscell(varargin{1}))
|
||||
% use a filled one given as first and only variable parameter
|
||||
varargin = varargin{1};
|
||||
no_of_in_arg = 2 + length(varargin);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% check number of input arguments
|
||||
if (rem(no_of_in_arg,2) ~= 0)
|
||||
error('The optional parameters have to be specified as ''name'',''value'' pairs');
|
||||
end
|
||||
|
||||
|
||||
% parse the variable input arguments
|
||||
vararg = cell(0,0);
|
||||
for ind = 1:2:length(varargin)
|
||||
name = varargin{ind};
|
||||
value = varargin{ind+1};
|
||||
switch name
|
||||
case 'DetectorNumber'
|
||||
detector_number = value;
|
||||
case 'Nx'
|
||||
Nx = value;
|
||||
case 'ROIdim'
|
||||
roi_dim = value;
|
||||
case 'CenX'
|
||||
cen_x = value;
|
||||
case 'CenY'
|
||||
cen_y = value;
|
||||
case 'DarkFieldR'
|
||||
dark_field_r = value;
|
||||
case 'FigNo'
|
||||
fig_no = value;
|
||||
case 'DirPerLine'
|
||||
dir_per_line = value;
|
||||
case 'ZeroOrderR'
|
||||
zero_order_r = value;
|
||||
case 'FirstMoment'
|
||||
first_moment = value;
|
||||
case 'IntegratedPhase'
|
||||
integrated_phase = value;
|
||||
case 'UpdateInterval'
|
||||
update_interval = value;
|
||||
case 'FilenameValidMask'
|
||||
filename_valid_mask = value;
|
||||
otherwise
|
||||
vararg{end+1} = name; %#ok<AGROW>
|
||||
vararg{end+1} = value; %#ok<AGROW>
|
||||
end
|
||||
end
|
||||
|
||||
% pass some parameters to image_show
|
||||
vararg(11:(end+10)) = vararg;
|
||||
vararg{ 1} = 'RetryReadSleep';
|
||||
vararg{ 2} = 5.0;
|
||||
vararg{ 3} = 'RetryReadMax';
|
||||
vararg{ 4} = 5;
|
||||
vararg{ 5} = 'ErrorIfNotFound';
|
||||
vararg{ 6} = 0;
|
||||
% vararg{ 7} = 'BurstMode';
|
||||
% if (dir_per_line)
|
||||
% vararg{ 8} = 1;
|
||||
% else
|
||||
% vararg{ 8} = 0;
|
||||
% end
|
||||
vararg{7} = 'UnhandledParError';
|
||||
vararg{8} = 0;
|
||||
vararg{9} = 'DetectorNumber';
|
||||
vararg{10} = detector_number;
|
||||
|
||||
% region of interest index in each dimension
|
||||
roi_rel_ind = -round(0.5*roi_dim):(round(0.5*roi_dim)-1);
|
||||
|
||||
% load the indices of valid pixels
|
||||
if ((~isempty(filename_valid_mask)) && (exist(filename_valid_mask,'file')))
|
||||
fprintf('loading the valid pixel mask %s\n',filename_valid_mask);
|
||||
load(filename_valid_mask);
|
||||
end
|
||||
|
||||
% wait for the data to be available
|
||||
scan_no_check = first_scan_number;
|
||||
if ((dir_per_line) && (Ny > 1))
|
||||
scan_no_check = scan_no_check +1;
|
||||
end
|
||||
filename_mask = compile_x12sa_filename(scan_no_check,0,'DetectorNumber',detector_number);
|
||||
[~, fnames] = find_files(filename_mask);
|
||||
data_available = (~isempty(fnames));
|
||||
if (~data_available)
|
||||
fprintf('Waiting for %s to become available.\n',filename_mask);
|
||||
while (~data_available);
|
||||
pause(1);
|
||||
[~, fnames] = find_files(filename_mask);
|
||||
data_available = (~isempty(fnames));
|
||||
end
|
||||
end
|
||||
|
||||
% check that number of points per line determination will be possible
|
||||
|
||||
% determine number of points per line
|
||||
if (Nx <= 0)
|
||||
if (~dir_per_line)
|
||||
error('The number of points per line can only automatically be determined if separate scan directories are used for each line.');
|
||||
end
|
||||
vararg_remain = vararg;
|
||||
vararg_remain(3:(end+2)) = vararg_remain;
|
||||
vararg_remain{1} = 'SubExpWildcard';
|
||||
vararg_remain{2} = 1;
|
||||
[fmask,vararg_remain] = ...
|
||||
compile_x12sa_filename(first_scan_number,0,vararg_remain); %#ok<NASGU>
|
||||
Nx = length(dir(fmask));
|
||||
if (Nx < 1)
|
||||
error('No matching files found for %s',fmask);
|
||||
end
|
||||
end
|
||||
fprintf('%d lines with %d points per line in\n',Ny,Nx);
|
||||
|
||||
|
||||
if (integrated_phase)
|
||||
figure(fig_no +1);
|
||||
hold off;
|
||||
clf;
|
||||
% print as layed out on the screen, i.e., preserve aspect ratio
|
||||
set(gcf,'PaperPositionMode','auto');
|
||||
% paper size
|
||||
set(gcf,'PaperType','A4');
|
||||
% background color
|
||||
set(gcf,'Color','white');
|
||||
% resize and position
|
||||
set(gcf,'Position',full_screen_position_integrated_phase);
|
||||
|
||||
colormap(bone(256));
|
||||
end
|
||||
|
||||
|
||||
figure(fig_no);
|
||||
hold off;
|
||||
clf;
|
||||
% print as layed out on the screen, i.e., preserve aspect ratio
|
||||
set(gcf,'PaperPositionMode','auto');
|
||||
% paper size
|
||||
set(gcf,'PaperType','A4');
|
||||
% background color
|
||||
set(gcf,'Color','white');
|
||||
% resize and position
|
||||
set(gcf,'Position',full_screen_position_standard);
|
||||
|
||||
colormap(bone(256));
|
||||
|
||||
|
||||
% STXM display loop
|
||||
point_no = 0;
|
||||
scan_number = first_scan_number;
|
||||
|
||||
frame = [];
|
||||
for ii=Ny:-1:1
|
||||
sub_exp_no = 0;
|
||||
for jj=Nx:-1:1
|
||||
if (dir_per_line)
|
||||
vararg_remain = vararg;
|
||||
vararg_remain(3:(end+2)) = vararg_remain;
|
||||
vararg_remain{1} = 'SubExpNo';
|
||||
vararg_remain{2} = sub_exp_no;
|
||||
[filename,vararg_remain] = ...
|
||||
compile_x12sa_filename(scan_number,0,vararg_remain);
|
||||
else
|
||||
[filename,vararg_remain] = ...
|
||||
compile_x12sa_filename(scan_number,point_no,vararg);
|
||||
end
|
||||
last_frame = frame;
|
||||
[frame,vararg_remain] = image_read(filename,vararg_remain);
|
||||
if (isempty(frame.data))
|
||||
fprintf('%s not found, repeating the previous frame\n',filename);
|
||||
frame = last_frame;
|
||||
end
|
||||
if (~isempty(vararg_remain))
|
||||
vararg_remain
|
||||
error('There are unhandled parameters.');
|
||||
end
|
||||
|
||||
if (point_no == 0)
|
||||
trans = zeros(Ny,Nx);
|
||||
dpcx = trans;
|
||||
dpcy = trans;
|
||||
df = trans;
|
||||
|
||||
if ((cen_x <= 0) || (cen_y <= 0))
|
||||
[cx, cy] = find_center(frame.data);
|
||||
fprintf('Beam cemter guess (x,y) = (%d,%d)\n',cx,cy);
|
||||
if (cen_x <= 0)
|
||||
cen_x = cx;
|
||||
end
|
||||
if (cen_y <= 0)
|
||||
cen_y = cy;
|
||||
end
|
||||
end
|
||||
|
||||
roi_x_ind = cen_x + roi_rel_ind;
|
||||
if ((roi_x_ind(1) < 1) || (roi_x_ind(end) > size(frame.data,2)))
|
||||
error('Region of interest out of range in x\n');
|
||||
end
|
||||
roi_y_ind = cen_y + roi_rel_ind;
|
||||
if ((roi_y_ind(1) < 1) || (roi_y_ind(end) > size(frame.data,1)))
|
||||
error('Region of interest out of range in y\n');
|
||||
end
|
||||
|
||||
[yy,xx] = meshgrid(roi_rel_ind,roi_rel_ind);
|
||||
[~, rho] = cart2pol(xx,yy);
|
||||
|
||||
ind_df = find((rho > dark_field_r) & (rho < roi_rel_ind(end)));
|
||||
|
||||
if (~isempty(filename_valid_mask))
|
||||
% in case of less than full detector readout cut out the right part of
|
||||
% the valid pixel mask
|
||||
valid_mask = pilatus_valid_pixel_roi(valid_mask,'RoiSize',size(frame.data));
|
||||
else
|
||||
% if the valid pixel mask is not used specify all pixels to
|
||||
% be valid
|
||||
valid_mask.indices = 1:(size(frame.data,1)*size(frame.data,2));
|
||||
end
|
||||
|
||||
% calculate the indices of the valid and invalid pixels within
|
||||
% the region of interest
|
||||
frame_valid = zeros(size(frame.data));
|
||||
frame_valid(valid_mask.indices) = 1;
|
||||
frame_valid = frame_valid(roi_y_ind,roi_x_ind);
|
||||
ind_invalid = find(frame_valid == 0);
|
||||
% ind_valid = find(frame_valid ~= 0);
|
||||
ind_df = setdiff(ind_df,ind_invalid);
|
||||
end
|
||||
|
||||
% cut out the region of interest
|
||||
frame_roi = frame.data(roi_y_ind,roi_x_ind);
|
||||
frame_roi(ind_invalid) = 0;
|
||||
|
||||
% set central part of detector frame to zero, if specified
|
||||
if (zero_order_r> 0)
|
||||
frame_roi(rho<zero_order_r) = 0; %min(frame_roi(:));
|
||||
end
|
||||
|
||||
% data analysis for the current point
|
||||
if (first_moment)
|
||||
[tr,px,py] = stxm_pt2(frame_roi);
|
||||
else
|
||||
[tr,px,py] = stxm_pt(frame_roi);
|
||||
end
|
||||
trans(ii,jj) = tr;
|
||||
dpcx(ii,jj) = px;
|
||||
dpcy(ii,jj) = py;
|
||||
|
||||
% df(ii,jj) = sum(frame_roi(ind_df)) / sum(sum(frame_roi(ind_valid)));
|
||||
df(ii,jj) = sum(frame_roi(ind_df));
|
||||
|
||||
point_no = point_no +1;
|
||||
sub_exp_no = sub_exp_no +1;
|
||||
end
|
||||
|
||||
% plot linewise each update_interval-th line
|
||||
if (Nx > 1) && (Ny > 1)
|
||||
if ((ii == Ny) || (rem(ii,update_interval) == 1) || (ii == 1))
|
||||
if(gcf ~= fig_no)
|
||||
figure(fig_no);
|
||||
end
|
||||
iv = 2;
|
||||
ih = 2;
|
||||
colormap(bone(256));
|
||||
|
||||
subplot(iv,ih,1);
|
||||
imagesc(trans);
|
||||
axis xy; axis equal; axis tight;
|
||||
colorbar;
|
||||
axis_min = min(min(trans(trans ~= 0)));
|
||||
if (isnan(axis_min))
|
||||
axis_min = 0;
|
||||
end
|
||||
axis_max = max(max(trans(trans ~= 0)));
|
||||
if (isnan(axis_max))
|
||||
axis_max = 0;
|
||||
end
|
||||
caxis([(axis_min-.0001) (axis_max+.0001)]);
|
||||
title_str = [ 'transmission #' num2str(first_scan_number,'%d') ];
|
||||
if (dir_per_line)
|
||||
title_str = [ title_str '-' num2str(first_scan_number+Ny-1,'%d') ]; %#ok<AGROW>
|
||||
end
|
||||
title_str = sprintf('%s (detector %d)',title_str,detector_number);
|
||||
title(title_str);
|
||||
|
||||
subplot(iv,ih,2);
|
||||
imagesc(df);
|
||||
axis xy; axis equal; axis tight;
|
||||
colorbar;
|
||||
axis_min = min(min(df(df ~= 0)));
|
||||
if (isnan(axis_min))
|
||||
axis_min = 0;
|
||||
end
|
||||
axis_max = max(max(df(df~=0)));
|
||||
if (isnan(axis_max))
|
||||
axis_max = 0;
|
||||
end
|
||||
caxis([(axis_min-.0001) (axis_max+.0001)]);
|
||||
title('dark field');
|
||||
|
||||
subplot(iv,ih,3);
|
||||
imagesc(dpcx);
|
||||
axis xy; axis equal; axis tight;
|
||||
colorbar;
|
||||
axis_min = min(min(dpcx(dpcx ~= 0)));
|
||||
if (isnan(axis_min))
|
||||
axis_min = 0;
|
||||
end
|
||||
axis_max = max(max(dpcx(dpcx~=0)));
|
||||
if (isnan(axis_max))
|
||||
axis_max = 0;
|
||||
end
|
||||
caxis([(axis_min-.0001) (axis_max+.0001)]);
|
||||
title('DPC x');
|
||||
|
||||
subplot(iv,ih,4);
|
||||
imagesc(dpcy);
|
||||
axis xy; axis equal; axis tight;
|
||||
colorbar;
|
||||
axis_min = min(min(dpcy(dpcy ~= 0)));
|
||||
if (isnan(axis_min))
|
||||
axis_min = 0;
|
||||
end
|
||||
axis_max = max(max(dpcy(dpcy~=0)));
|
||||
if (isnan(axis_max))
|
||||
axis_max = 0;
|
||||
end
|
||||
caxis([(axis_min-.0001) (axis_max+.0001)]);
|
||||
title('DPC y');
|
||||
|
||||
drawnow;
|
||||
end
|
||||
end
|
||||
|
||||
if (dir_per_line)
|
||||
scan_number = scan_number +1;
|
||||
end
|
||||
end
|
||||
|
||||
% store return arguments
|
||||
if nargout > 0
|
||||
varargout{1} = trans;
|
||||
end
|
||||
if nargout > 1
|
||||
varargout{2} = dpcx;
|
||||
end
|
||||
if nargout > 2
|
||||
varargout{3} = dpcy;
|
||||
end
|
||||
if nargout > 3
|
||||
varargout{4} = df;
|
||||
end
|
||||
|
||||
if nargout > 4
|
||||
varargout{5} = phase;
|
||||
end
|
||||
|
||||
if nargout > 5
|
||||
varargout{6} = gx;
|
||||
end
|
||||
|
||||
if nargout > 6
|
||||
varargout{7} = gy;
|
||||
end
|
||||
|
||||
if (integrated_phase)
|
||||
% calculate the integrated phase from the differential phase contrast
|
||||
% in horizontal and vertical direction
|
||||
phase = phase_from_dpc(dpcx,dpcy, 'fourier');
|
||||
|
||||
% calculate the 1D differential phase contrast from the integrated
|
||||
% phase
|
||||
[gx, gy] = gradient(phase);
|
||||
|
||||
figure(fig_no +1);
|
||||
iv = 1;
|
||||
ih = 3;
|
||||
colormap(bone(256));
|
||||
|
||||
subplot(iv,ih,1);
|
||||
imagesc(phase);
|
||||
axis xy; axis equal; axis tight;
|
||||
colorbar;
|
||||
axis_min = min(phase(phase ~= 0));
|
||||
if (isnan(axis_min))
|
||||
axis_min = 0;
|
||||
end
|
||||
axis_max = max(phase(phase~=0));
|
||||
if (isnan(axis_max))
|
||||
axis_max = 0;
|
||||
end
|
||||
caxis([(axis_min-.0001) (axis_max+.0001)]);
|
||||
title_str = [ 'integrated phase #' num2str(first_scan_number,'%d') ];
|
||||
if (dir_per_line)
|
||||
title_str = [ title_str '-' num2str(first_scan_number+Ny-1,'%d') ];
|
||||
end
|
||||
title_str = sprintf('%s (detector %d)',title_str,detector_number);
|
||||
title(title_str);
|
||||
|
||||
subplot(iv,ih,2);
|
||||
imagesc(gx);
|
||||
axis xy; axis equal; axis tight;
|
||||
colorbar;
|
||||
axis_min = min(gx(gx ~= 0));
|
||||
if (isnan(axis_min))
|
||||
axis_min = 0;
|
||||
end
|
||||
axis_max = max(gx(gx ~= 0));
|
||||
if (isnan(axis_max))
|
||||
axis_max = 0;
|
||||
end
|
||||
caxis([(axis_min-.0001) (axis_max+.0001)]);
|
||||
title('DPC x from integrated phase');
|
||||
|
||||
subplot(iv,ih,3);
|
||||
imagesc(gy);
|
||||
axis xy; axis equal; axis tight;
|
||||
colorbar;
|
||||
axis_min = min(gy(gy ~= 0));
|
||||
if (isnan(axis_min))
|
||||
axis_min = 0;
|
||||
end
|
||||
axis_max = max(gy(gy ~= 0));
|
||||
if (isnan(axis_max))
|
||||
axis_max = 0;
|
||||
end
|
||||
caxis([(axis_min-.0001) (axis_max+.0001)]);
|
||||
title('DPC y from integrated phase');
|
||||
|
||||
drawnow;
|
||||
|
||||
end
|
||||
|
||||
|
||||
% file name for saving
|
||||
filename = sprintf('stxm_scans_%d_%05d-%05d',detector_number,...
|
||||
first_scan_number,first_scan_number+Ny-1);
|
||||
|
||||
|
||||
% save figures
|
||||
if (~isempty(figure_dir))
|
||||
figure(fig_no);
|
||||
|
||||
% create output directories and write the plot in different formats
|
||||
if (~exist(figure_dir,'dir'))
|
||||
mkdir(figure_dir)
|
||||
end
|
||||
if ((figure_dir(end) ~= '/') && (figure_dir(end) ~= '\'))
|
||||
figure_dir = [ figure_dir '/' ];
|
||||
end
|
||||
fprintf('output directory for figures is %s\n',figure_dir);
|
||||
|
||||
% resize to a smaller width as print layout
|
||||
set(gcf,'Position',print_a4_position_standard);
|
||||
|
||||
subdir = [ figure_dir 'jpg/' ];
|
||||
if (~exist(subdir,'dir'))
|
||||
mkdir(subdir);
|
||||
end
|
||||
fprintf('saving %s.jpg\n',filename);
|
||||
print('-djpeg','-r300',[subdir filename '.jpg'] );
|
||||
|
||||
subdir = [ figure_dir 'eps/' ];
|
||||
if (~exist(subdir,'dir'))
|
||||
mkdir(subdir);
|
||||
end
|
||||
fprintf('saving %s.eps\n',filename);
|
||||
print('-depsc','-r1200',[subdir filename '.eps'] );
|
||||
|
||||
% resize to full screen
|
||||
set(gcf,'Position',full_screen_position_standard);
|
||||
|
||||
subdir = [ figure_dir 'fig/' ];
|
||||
if (~exist(subdir,'dir'))
|
||||
mkdir(subdir);
|
||||
end
|
||||
fprintf('saving %s.fig\n',filename);
|
||||
hgsave([subdir filename '.fig']);
|
||||
|
||||
if (integrated_phase)
|
||||
figure(fig_no +1);
|
||||
|
||||
subdir = [ figure_dir 'jpg/' ];
|
||||
if (~exist(subdir,'dir'))
|
||||
mkdir(subdir);
|
||||
end
|
||||
|
||||
% resize to a smaller width as print layout
|
||||
set(gcf,'Position',print_a4_position_integrated_phase);
|
||||
|
||||
fprintf('saving %s_integrated_phase.jpg\n',filename);
|
||||
print('-djpeg','-r300',[subdir filename '_integrated_phase.jpg'] );
|
||||
|
||||
subdir = [ figure_dir 'eps/' ];
|
||||
if (~exist(subdir,'dir'))
|
||||
mkdir(subdir);
|
||||
end
|
||||
fprintf('saving %s_integrated_phase.eps\n',filename);
|
||||
print('-depsc','-r1200',[subdir filename '_integrated_phase.eps'] );
|
||||
|
||||
% resize to a smaller width as print layout
|
||||
set(gcf,'Position',full_screen_position_integrated_phase);
|
||||
|
||||
subdir = [ figure_dir 'fig/' ];
|
||||
if (~exist(subdir,'dir'))
|
||||
mkdir(subdir);
|
||||
end
|
||||
fprintf('saving %s_integrated_phase.fig\n',filename);
|
||||
hgsave([subdir filename '_integrated_phase.fig']);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
% save resulting data
|
||||
if (~isempty(data_dir))
|
||||
if ((data_dir(end) ~= '/') && (data_dir(end) ~= '\'))
|
||||
data_dir = [ data_dir '/' ];
|
||||
end
|
||||
|
||||
% create output directory
|
||||
if (~exist(data_dir,'dir'))
|
||||
mkdir(data_dir)
|
||||
end
|
||||
|
||||
% save data
|
||||
fprintf('saving %s.mat\n',[data_dir filename]);
|
||||
if (integrated_phase)
|
||||
save([data_dir filename],'trans','dpcx','dpcy','df', 'phase', 'gx', 'gy');
|
||||
else
|
||||
save([data_dir filename],'trans','dpcx','dpcy','df');
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
function [cx, cy] = find_center(f)
|
||||
|
||||
f = medfilt2(f,[5 5]);
|
||||
|
||||
[~, cx] = max(sum(f,1));
|
||||
[~, cy] = max(sum(f,2));
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
function [tr, px, py] = stxm_pt(a)
|
||||
|
||||
persistent c1 c2 s1 s2 sz
|
||||
|
||||
if (isempty(sz)) || (any(sz ~= size(a)))
|
||||
sz = size(a);
|
||||
c1 = -cos(2*pi*(0:sz(1)-1)/sz(1));
|
||||
s1 = sin(2*pi*(0:sz(1)-1)/sz(1));
|
||||
c2 = -cos(2*pi*(0:sz(2)-1)/sz(2));
|
||||
s2 = sin(2*pi*(0:sz(2)-1)/sz(2));
|
||||
end
|
||||
|
||||
a1 = sum(a,1);
|
||||
a2 = sum(a,2)';
|
||||
|
||||
tr = sum(a1);
|
||||
px = atan2(sum(a1.*c1), sum(a1.*s1));
|
||||
py = atan2(sum(a2.*c2), sum(a2.*s2));
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
function [tr, px, py ] = stxm_pt2(a)
|
||||
|
||||
persistent x y sz
|
||||
|
||||
if (isempty(sz)) || (any(sz ~= size(a)))
|
||||
sz = size(a);
|
||||
% masking out the invalid pixels is done by setting the
|
||||
% corresponding intensities to zero before calling this function
|
||||
[y,x] = ndgrid((0:sz(1)-1)-sz(1)/2, (0:sz(1)-1)-sz(1)/2);
|
||||
% x2 = x.^2;
|
||||
end
|
||||
|
||||
tr = sum(sum(a));
|
||||
px = sum(sum(a.*x))/tr;
|
||||
py = sum(sum(a.*y))/tr;
|
||||
% p2 = (sum(a1.*x2)/tr + sum(a2.*x2)/tr - px^2 - py^2);
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
function p = phase_from_dpc(dpcx,dpcy,varargin)
|
||||
%
|
||||
% Integrates the phase from a combination of x and y gradients.
|
||||
% phase_from_dpc(dpcx,dpcy,'fourier') uses the Fourier method (default),
|
||||
% phase_from_dpc(dpcx,dpcy,'finitdiff') uses a finite difference method.
|
||||
|
||||
if nargin > 2
|
||||
method = varargin{1};
|
||||
else
|
||||
%method = 'fourier';
|
||||
method = 'finitediff';
|
||||
end
|
||||
|
||||
px = -dpcy;
|
||||
py = -dpcx;
|
||||
|
||||
sz = size(px);
|
||||
|
||||
switch lower(method)
|
||||
case 'fourier'
|
||||
f = zeros(2*sz);
|
||||
f(1:sz(1),1:sz(2)) = px + 1i*py;
|
||||
f(1:sz(1),sz(2)+1:end) = fliplr(px + 1i*py);
|
||||
f(sz(1)+1:end,1:sz(2)) = flipud(px + 1i*py);
|
||||
f(sz(1)+1:end,sz(2)+1:end) = rot90(px + 1i*py,2);
|
||||
[x1,x2] = ndgrid(-sz(1):(sz(1)-1),-sz(2):(sz(2)-1));
|
||||
q1 = pi*fftshift(x1)/sz(1);
|
||||
q2 = pi*fftshift(x2)/sz(2);
|
||||
qc = q2 - 1i*q1;
|
||||
inv_qc = 1./qc;
|
||||
inv_qc(1,1) = 0;
|
||||
nf = ifftn(fftn(f).*inv_qc);
|
||||
p = real(nf(1:sz(1),1:sz(2)));
|
||||
case 'finitediff'
|
||||
ggx = pgradient(dpcx);
|
||||
[~, ggy] = pgradient(dpcy);
|
||||
f = .25*(ggx + ggy);
|
||||
ta = zeros(sz);
|
||||
for i = 1:10000
|
||||
ta = ta + (pdel2(ta) - f);
|
||||
|
||||
% Zero boundary conditions
|
||||
%ta(1,:) = 0;
|
||||
%ta(:,1) = 0;
|
||||
%ta(end,:) = 0;
|
||||
%ta(:,end) = 0;
|
||||
|
||||
% Zero normal gradient boundary condition
|
||||
ta(1,:) = ta(2,:);
|
||||
ta(:,1) = ta(:,2);
|
||||
ta(end,:) = ta(end-1,:);
|
||||
ta(:,end) = ta(:,end-1);
|
||||
|
||||
if mod(i,1000)==0
|
||||
figure(1); imagesc(real(ta)); colormap(bone(256)); colorbar; drawnow;
|
||||
end
|
||||
|
||||
p = ta;
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import beamline.stxm_online
|
||||
|
||||
first_scan_nr = 15;
|
||||
nr_lines = 21;
|
||||
centerx = 224;
|
||||
centery = 98;
|
||||
dark_field_radius = 20;
|
||||
roi = 128;
|
||||
|
||||
[trans,dpcx,dpcy,df]=stxm_online(first_scan_nr, nr_lines , 'ROIdim',roi,'CenX', centerx, 'CenY', centery, 'DarkFieldR', dark_field_radius,'FilenameValidMask',[]);
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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.
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
first_scan_nr = 2175;
|
||||
Nx=21;
|
||||
nr_lines = 19;
|
||||
centerx = 224;
|
||||
centery = 98;
|
||||
dark_field_radius = 20;
|
||||
roi = 128;
|
||||
|
||||
[trans,dpcx,dpcy,df]=stxm_online(first_scan_nr, nr_lines , 'Nx',Nx,'ROIdim',roi,'CenX', centerx, 'CenY', centery, 'DarkFieldR', dark_field_radius,'FilenameValidMask',[],'DirPerLine',0);
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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.
|
||||
@@ -0,0 +1,414 @@
|
||||
% Call function without arguments for instructions on how to use it
|
||||
|
||||
% Filename: $RCSfile: tune_valid_mask.m,v $
|
||||
%
|
||||
% $Revision: 1.5 $ $Date: 2012/09/02 15:13:40 $
|
||||
% $Author: bunk $
|
||||
% $Tag: $
|
||||
%
|
||||
% Description:
|
||||
% remove outlyers of intensity that deviates from the azimuthal integration
|
||||
% from the valid pixel mask
|
||||
%
|
||||
% Note:
|
||||
% Call without arguments for a brief help text.
|
||||
%
|
||||
% Dependencies:
|
||||
% - image_read
|
||||
%
|
||||
% history:
|
||||
%
|
||||
% May 21st 2010, Oliver Bunk:
|
||||
% 1st version
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| Except where otherwise noted, this work is licensed under a |
|
||||
%| Creative Commons Attribution-NonCommercial-ShareAlike 4.0 |
|
||||
%| International (CC BY-NC-SA 4.0) license. |
|
||||
%| |
|
||||
%| Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch) |
|
||||
%| |
|
||||
%| Author: CXS group, PSI |
|
||||
%*-----------------------------------------------------------------------*
|
||||
% You may use this code with the following provisions:
|
||||
%
|
||||
% If the code is fully or partially redistributed, or rewritten in another
|
||||
% computing language this notice should be included in the redistribution.
|
||||
%
|
||||
% If this code, or subfunctions or parts of it, is used for research in a
|
||||
% publication or if it is fully or partially rewritten for another
|
||||
% computing language the authors and institution should be acknowledged
|
||||
% in written form in the publication: “Data processing was carried out
|
||||
% using the “cSAXS matlab package” developed by the CXS group,
|
||||
% Paul Scherrer Institut, Switzerland.”
|
||||
% Variations on the latter text can be incorporated upon discussion with
|
||||
% the CXS group if needed to more specifically reflect the use of the package
|
||||
% for the published work.
|
||||
%
|
||||
% A publication that focuses on describing features, or parameters, that
|
||||
% are already existing in the code should be first discussed with the
|
||||
% authors.
|
||||
%
|
||||
% This code and subroutines are part of a continuous development, they
|
||||
% are provided “as they are” without guarantees or liability on part
|
||||
% of PSI or the authors. It is the user responsibility to ensure its
|
||||
% proper use and the correctness of the results.
|
||||
|
||||
function [valid_mask] = tune_valid_mask(data_dir, varargin)
|
||||
import beamline.radial_integ
|
||||
import io.image_read
|
||||
import plotting.display_valid_mask
|
||||
import utils.find_files
|
||||
|
||||
|
||||
% set default values for the variable input arguments:
|
||||
% directory with the integrated data files
|
||||
indir_integ_data = '~/Data10/analysis/radial_integration/';
|
||||
% filename of the integrated data, empty to determine it from the raw data
|
||||
% file name
|
||||
filename_integ_data = [];
|
||||
% use all cbf files
|
||||
filename_mask = '*.cbf';
|
||||
% filename for loading and saving the valid pixel mask
|
||||
filename_valid_mask = '~/Data10/analysis/data/pilatus_valid_mask.mat';
|
||||
% integration masks
|
||||
filename_integ_masks = '~/Data10/analysis/data/pilatus_integration_masks.mat';
|
||||
|
||||
% size of the median filter that is use to smooth the data for identifying
|
||||
% outlyers
|
||||
median_size = 11;
|
||||
% first pixel to start at
|
||||
radius_from = 20;
|
||||
% last pixel to check
|
||||
radius_to = 0;
|
||||
% only intensities above this threshold are considered for being hot
|
||||
threshold_hot = 5;
|
||||
% this value times the standard deviation of the intensity is used as hot pixel
|
||||
% threshold
|
||||
threshold_median = 3.0;
|
||||
% save the updated mask
|
||||
save_data = 0;
|
||||
% display result in this figure
|
||||
fig_no = 201;
|
||||
% matching files to use
|
||||
point_range = [];
|
||||
|
||||
% check minimum number of input arguments
|
||||
if (nargin < 1)
|
||||
fprintf('\nUsage:\n');
|
||||
fprintf('[valid_mask]=%s(data_dir [[,<name>,<value>]...]);\n',mfilename);
|
||||
fprintf('Remove outlyers from the valid pixel mask by comparing azimuthally integrated data\n');
|
||||
fprintf('against the same data median filtered and rejecting pixels with a deviation\n');
|
||||
fprintf('in intensity specified in multiples of the standard deviation.\n');
|
||||
fprintf('\n');
|
||||
fprintf('The optional <name>,<value> pairs are:\n');
|
||||
fprintf('''FilenameMask'',<file specifier> specify the files to be used from the data directory, empty string for all, default is ''%s''\n',...
|
||||
filename_mask);
|
||||
fprintf('''PointRange'',<vector or []> matching files to use, default is [] for all files\n');
|
||||
fprintf('''IndirIntegData'',<filename.mat> directory with the azimuthally integrated data, default is %s\n',...
|
||||
indir_integ_data);
|
||||
fprintf('''FilenameIntegData'',<filename.mat> filename for the azimuthally integrated data, empty to determine the name\n');
|
||||
fprintf(' from the first raw data file name, default is ''%s''\n',...
|
||||
filename_integ_data);
|
||||
fprintf('''FilenameIntegMasks'',<filename> Matlab file containing the integration masks, default is ''%s''\n',filename_integ_masks);
|
||||
fprintf('''RadiusFrom'',<integer> no. of the pixel to start with, default is %.0f\n',radius_from);
|
||||
fprintf('''RadiusTo'',<integer> no. of the last pixel to check, default is %.0f\n',radius_to);
|
||||
fprintf('''MedianSize'',<integer> size of the median filter in pixels, default is %.0f\n',...
|
||||
median_size);
|
||||
fprintf('''ThresholdHot'',<float> pixels above this value are considered for being hot, default is %d\n',...
|
||||
threshold_hot);
|
||||
fprintf('''ThresholdMedian'',<float> pixels outside the range (I+/-threshold_median*sqrt(I))\n');
|
||||
fprintf(' of the median filtered data are considered to be hot,\n');
|
||||
fprintf(' default is %.1f\n',...
|
||||
threshold_median);
|
||||
fprintf('''SaveData'',<0-no,1-yes> save the valid pixel mask, default is %d\n',save_data);
|
||||
fprintf('''FilenameValidMask'',<path and filename> Matlab file with the valid pixel indices,\n');
|
||||
fprintf(' default is %s\n',filename_valid_mask);
|
||||
fprintf('''FigNo'',<integer> number of the figure in which the result is displayed, default is %d\n',...
|
||||
fig_no);
|
||||
fprintf('\n');
|
||||
fprintf('Examples:\n');
|
||||
fprintf('[valid_mask]=%s(''~/Data10/pilatus/S05000-05999/S05715/e12612_1_05715_00000_00000.cbf'');\n',...
|
||||
mfilename);
|
||||
fprintf('[valid_mask]=%s(''~/Data10/pilatus/S05000-05999/S05715/*.cbf'');\n',...
|
||||
mfilename);
|
||||
|
||||
error('At least the filename of the raw data has to be specified as input parameter.');
|
||||
end
|
||||
|
||||
% accept cell array with name/value pairs as well
|
||||
no_of_in_arg = nargin;
|
||||
if (nargin == 2)
|
||||
if (isempty(varargin))
|
||||
% ignore empty cell array
|
||||
no_of_in_arg = no_of_in_arg -1;
|
||||
else
|
||||
if (iscell(varargin{1}))
|
||||
% use a filled one given as first and only variable parameter
|
||||
varargin = varargin{1};
|
||||
no_of_in_arg = no_of_in_arg -1 + length(varargin);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% check number of input arguments
|
||||
if (rem(no_of_in_arg,2) ~= 1)
|
||||
error('The optional parameters have to be specified as ''name'',''value'' pairs');
|
||||
end
|
||||
|
||||
|
||||
% parse the variable input arguments:
|
||||
% initialize the list of unhandled parameters
|
||||
vararg_remain = cell(0,0);
|
||||
for ind = 1:2:length(varargin)
|
||||
name = varargin{ind};
|
||||
value = varargin{ind+1};
|
||||
switch name
|
||||
case 'FilenameIntegMasks'
|
||||
filename_integ_masks = value;
|
||||
case 'FilenameMask'
|
||||
filename_mask = value;
|
||||
case 'PointRange'
|
||||
point_range = value;
|
||||
case 'IndirIntegData'
|
||||
indir_integ_data = value;
|
||||
case 'FilenameIntegData'
|
||||
filename_integ_data = value;
|
||||
case 'RadiusFrom',
|
||||
radius_from = round(value);
|
||||
case 'RadiusTo',
|
||||
radius_to = round(value);
|
||||
case 'MedianSize'
|
||||
median_size = round(value);
|
||||
case 'ThresholdMedian'
|
||||
threshold_median = value;
|
||||
case 'ThresholdHot'
|
||||
threshold_hot = value;
|
||||
case 'FilenameValidMask'
|
||||
filename_valid_mask = value;
|
||||
case 'SaveData'
|
||||
save_data = value;
|
||||
case 'FigNo'
|
||||
fig_no = value;
|
||||
otherwise
|
||||
vararg_remain{end+1} = name; %#ok<AGROW>
|
||||
vararg_remain{end+1} = value; %#ok<AGROW>
|
||||
end
|
||||
end
|
||||
|
||||
vararg_remain{end+1} = 'UnhandledParError';
|
||||
vararg_remain{end+1} = 0;
|
||||
vararg_remain{end+1} = 'DisplayFilename';
|
||||
vararg_remain{end+1} = 0;
|
||||
|
||||
% set some default values for the plot window
|
||||
set(0, 'DefaultAxesfontsize', 12);
|
||||
set(0, 'DefaultAxeslinewidth', 1, 'DefaultAxesfontsize', 12);
|
||||
set(0, 'DefaultLinelinewidth', 1);
|
||||
|
||||
% get all matching filenames
|
||||
if (data_dir(end) ~= '/')
|
||||
data_dir(end+1) = '/';
|
||||
end
|
||||
[data_dir,fnames,vararg_remain] = ...
|
||||
find_files( [ data_dir filename_mask ], vararg_remain );
|
||||
|
||||
if (length(fnames) < 1)
|
||||
error('No matching files found for %s%s.\n',data_dir,filename_mask);
|
||||
end
|
||||
|
||||
% load the current valid pixel mask in variable valid_mask
|
||||
fprintf('loading the existing valid mask %s\n',filename_valid_mask);
|
||||
load(filename_valid_mask);
|
||||
framesize = valid_mask.framesize(1) * valid_mask.framesize(2);
|
||||
|
||||
% load the integration masks in variable integ_masks
|
||||
fprintf('Loading the integration masks from %s\n',filename_integ_masks);
|
||||
load(filename_integ_masks);
|
||||
no_of_radii = length(integ_masks.radius);
|
||||
|
||||
if ((radius_to < radius_from) || (radius_to > no_of_radii))
|
||||
radius_to = no_of_radii;
|
||||
end
|
||||
|
||||
% process the frames
|
||||
ind_hot = [];
|
||||
ind_dark = [];
|
||||
integ_data = [];
|
||||
fprintf('data directory is %s\n',data_dir);
|
||||
if (isempty(point_range))
|
||||
point_range = 1:length(fnames);
|
||||
else
|
||||
ind = find(point_range <= length(fnames));
|
||||
if (length(point_range) ~= length(ind))
|
||||
fprintf('Warning, %d value(s) from the specified point range are out of the range [1,%.0f] and not used.\n',...
|
||||
length(point_range)-length(ind),length(fnames));
|
||||
point_range = point_range(ind);
|
||||
end
|
||||
end
|
||||
|
||||
for (point_ind=1:length(point_range))
|
||||
f_ind = point_range(point_ind);
|
||||
% read the raw data
|
||||
fprintf('%3d/%3d: reading %s%s\n',f_ind,length(point_range),...
|
||||
data_dir,fnames(f_ind).name);
|
||||
filename_raw = [data_dir fnames(f_ind).name ];
|
||||
[frame] = image_read(filename_raw,vararg_remain);
|
||||
|
||||
% check that the files have identical dimensions
|
||||
if ((size(frame.data,1) ~= valid_mask.framesize(1)) || ...
|
||||
(size(frame.data,2) ~= valid_mask.framesize(2)))
|
||||
error('The valid pixel mask has %d x %d pixels, this frame has %d x %d pixels',...
|
||||
valid_mask.framesize(1),valid_mask.framesize(2),...
|
||||
size(frame.data,1),size(frame.data,2));
|
||||
end
|
||||
|
||||
% read the radially integrated data
|
||||
if (isempty(integ_data))
|
||||
% determine filename for the integrated data from the first raw
|
||||
% data filename
|
||||
if (isempty(filename_integ_data))
|
||||
[pathstr, filename_integ_data] = fileparts(fnames(f_ind).name);
|
||||
filename_integ_data = [ filename_integ_data '_integ.mat' ]; %#ok<AGROW>
|
||||
end
|
||||
filename_integ_data = fullfile(indir_integ_data,filename_integ_data);
|
||||
fprintf('Loading the integrated intensities from %s\n',...
|
||||
filename_integ_data);
|
||||
integ_data = load(filename_integ_data);
|
||||
|
||||
% take the median of all segments with positive intensities, i.e.,
|
||||
% skip negative intensities
|
||||
I_all_prev = integ_data.I_all;
|
||||
no_of_segments = size(I_all_prev,2);
|
||||
no_of_points = size(I_all_prev,3);
|
||||
I_all = zeros(no_of_radii,no_of_points);
|
||||
I_std = zeros(no_of_radii,no_of_points);
|
||||
if (no_of_segments > 1)
|
||||
fprintf('Using the median of %d segments.\n',no_of_segments);
|
||||
end
|
||||
for (ind1=1:no_of_radii)
|
||||
for (ind3=1:no_of_points)
|
||||
no_of_el = 0;
|
||||
I_use = zeros(1,no_of_segments);
|
||||
ind_I_use = zeros(1,no_of_segments);
|
||||
for (ind2=1:no_of_segments)
|
||||
if (I_all_prev(ind1,ind2,ind3) >= 0)
|
||||
no_of_el = no_of_el +1;
|
||||
I_use(no_of_el) = I_all_prev(ind1,ind2,ind3);
|
||||
ind_I_use(no_of_el) = ind2;
|
||||
end
|
||||
end
|
||||
if (no_of_el > 1)
|
||||
[I_sorted,ind_sorted] = sort(I_use(1:no_of_el));
|
||||
ind_median = round(0.5*no_of_el);
|
||||
I_all(ind1,ind3) = I_sorted(ind_median);
|
||||
% get the standard deviation of this intensity
|
||||
I_std(ind1,ind3) = integ_data.I_std(ind1,ind_I_use(ind_sorted(ind_median)),ind3);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% print this information once rather than for each file
|
||||
fprintf('Checking radii from %d to %d.\n',radius_from,radius_to);
|
||||
end
|
||||
|
||||
% get the index to the integrated data
|
||||
ind = 1;
|
||||
ind_max = length(integ_data.filenames_all);
|
||||
while ((ind <= ind_max) && ...
|
||||
(isempty(strfind(integ_data.filenames_all{ind},fnames(f_ind).name))))
|
||||
ind = ind +1;
|
||||
end
|
||||
if (ind > ind_max)
|
||||
error('Could not find integrated data for raw data file %s in %s.',...
|
||||
filename_raw,filename_integ_data);
|
||||
end
|
||||
data_integ = squeeze(I_all(:,ind));
|
||||
data_integ_std = squeeze(I_std(:,ind));
|
||||
|
||||
% median filtered data for comparison
|
||||
data_integ_med = medfilt1(data_integ,median_size,size(data_integ,1),1);
|
||||
|
||||
% figure(fig_no+2);
|
||||
% hold off;
|
||||
% clf;
|
||||
% semilogy(data_integ);
|
||||
% hold all;
|
||||
% semilogy(data_integ_med);
|
||||
% semilogy(data_integ_med+data_integ_std*threshold_median);
|
||||
% semilogy(data_integ_med-data_integ_std*threshold_median);
|
||||
|
||||
frame_cmp = ones(valid_mask.framesize) -2;
|
||||
frame_cmp_std = zeros(valid_mask.framesize);
|
||||
for (ind_r = radius_from:radius_to)
|
||||
for (ind_seg = 1:no_of_segments)
|
||||
if (integ_masks.norm_sum(ind_r,ind_seg) > 0)
|
||||
frame_cmp(integ_masks.indices{ind_r,ind_seg}) = ...
|
||||
data_integ_med(ind_r);
|
||||
frame_cmp_std(integ_masks.indices{ind_r,ind_seg}) = ...
|
||||
data_integ_std(ind_r);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
%
|
||||
ind_dark = union(ind_dark, ...
|
||||
find((frame.data >= 0) & ...
|
||||
(frame_cmp >= 0) & ...
|
||||
(frame.data < frame_cmp - threshold_median*frame_cmp_std)));
|
||||
% only consider pixels of sufficient intensity for being hot
|
||||
ind_hot = union(ind_hot, ...
|
||||
find((frame.data > threshold_hot) & ...
|
||||
(frame_cmp >= 0) & ...
|
||||
(frame.data > frame_cmp + threshold_median*frame_cmp_std)));
|
||||
end
|
||||
|
||||
|
||||
% calculate the complementary masks of the valid pixels
|
||||
valid_mask.indices = intersect(valid_mask.indices,...
|
||||
setdiff(1:framesize,union(ind_dark,ind_hot)));
|
||||
|
||||
fprintf('In total %d dark and %d hot pixels found.\n',...
|
||||
length(ind_dark),length(ind_hot));
|
||||
fprintf('%d valid pixels remain.\n',length(valid_mask.indices));
|
||||
|
||||
|
||||
if (save_data)
|
||||
% create a backup of the mask
|
||||
if (exist(filename_valid_mask,'file'))
|
||||
filename_mask_backup = [ filename_valid_mask '.bak' ];
|
||||
fprintf('Copying the current mask %s to %s\n',filename_valid_mask,...
|
||||
filename_mask_backup);
|
||||
copyfile(filename_valid_mask,filename_mask_backup);
|
||||
end
|
||||
|
||||
% save the masks
|
||||
fprintf('Saving valid_mask to %s\n',filename_valid_mask);
|
||||
save(filename_valid_mask,'valid_mask');
|
||||
% plot new valid pixel mask
|
||||
display_valid_mask('FilenameValidMask',filename_valid_mask,...
|
||||
'NoHelp',1,'FigNo',fig_no);
|
||||
else
|
||||
fprintf('The updated valid pixel mask is NOT saved.\n');
|
||||
end
|
||||
|
||||
% plot the additional invalid pixels
|
||||
figure(fig_no+1);
|
||||
|
||||
% mark the valid pixels as 1, leave the invalid at 0
|
||||
frame = zeros(valid_mask.framesize);
|
||||
frame(valid_mask.indices) = 1;
|
||||
frame(ind_dark) = -10;
|
||||
frame(ind_hot) = 10;
|
||||
imagesc(frame);
|
||||
caxis([-10 10]);
|
||||
axis xy;
|
||||
axis equal;
|
||||
axis tight;
|
||||
colorbar;
|
||||
title_str = ['valid pixels, ' ...
|
||||
num2str(length(ind_dark)+length(ind_hot),'%d') ...
|
||||
' update(s) marked with intensity -10/10'];
|
||||
title(title_str);
|
||||
set(gcf,'Name','valid pixels, updates marked');
|
||||
@@ -0,0 +1,95 @@
|
||||
%% UDPATE_MASK
|
||||
% This small script guides you to update an alread existing mask for
|
||||
% ptychography. The main tool for creating a new mask is
|
||||
% beamline.create_mask, a GUI that lets you select bad/hot pixels.
|
||||
% UPDATE_MASK loads the data, specified by file_path, plots it and starts
|
||||
% the GUI. Although you can create a 3D mask, i.e. a mask which varies from
|
||||
% frame to frame, a 2D mask is sufficient for most datasets.
|
||||
|
||||
% You can load an already existing mask within the GUI.
|
||||
|
||||
close all
|
||||
|
||||
|
||||
file_path = '~/Data10/eiger_4/S00000-00999/S00089/run_00089_000000000000.h5';
|
||||
single_file = true; % if you have multiple files use * in file_path
|
||||
H5Location = '/entry/data/eiger_4/'; % check the location within the h5 file in ptycho/+detector
|
||||
orientation = [1 0 0]; % check the detector orientation in ptycho/+detector
|
||||
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% load the data
|
||||
|
||||
image_read_args = [];
|
||||
|
||||
image_read_args{1} = 'Orientation';
|
||||
image_read_args{2} = orientation;
|
||||
image_read_args{3} = 'OrientByExtension';
|
||||
image_read_args{4} = false;
|
||||
|
||||
if ~single_file
|
||||
image_read_args{end+1} = 'IsFmask';
|
||||
image_read_args{end+1} = 1;
|
||||
end
|
||||
|
||||
if ~isempty(H5Location)
|
||||
image_read_args{end+1} = 'H5Location';
|
||||
image_read_args{end+1} = H5Location;
|
||||
end
|
||||
|
||||
|
||||
data = io.image_read(file_path, image_read_args(:));
|
||||
|
||||
%% plot the data
|
||||
figure(1),
|
||||
plotting.imagesc3D(abs(log10(double(data.data)+1)));
|
||||
colorbar
|
||||
axis xy equal tight
|
||||
colorbar
|
||||
title('Detector raw data')
|
||||
colormap jet
|
||||
|
||||
%% iterative step for a mask update (add dead pixels to the current mask)
|
||||
mask = beamline.create_mask;
|
||||
|
||||
%% check it again
|
||||
figure (2),
|
||||
imagesc(mask); axis equal tight xy
|
||||
title('Final mask')
|
||||
|
||||
%*-----------------------------------------------------------------------*
|
||||
%| |
|
||||
%| 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) 2018 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.
|
||||
|
||||
Reference in New Issue
Block a user