mirror of
https://github.com/c-sooyoung/fold_slice.git
synced 2026-09-17 20:39:08 +09:00
initial commit
This commit is contained in:
@@ -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');
|
||||
Reference in New Issue
Block a user