initial commit

This commit is contained in:
2026-08-07 15:56:42 +09:00
commit 91ad25aca9
1012 changed files with 159314 additions and 0 deletions
+59
View File
@@ -0,0 +1,59 @@
% FUNCTION full_array = add_to_3D(full_array, small_array, position)
% add one small 3D block into large 3D array
% Inputs:
% full_array
% small_array
% position - offset from (1,1,1) coordinate in pixels
% *-----------------------------------------------------------------------*
% |                                                                       |
% |  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 full_array = add_to_3D(full_array, small_array, position)
position = round(position);
N_f = size(full_array);
N_s = size(small_array);
for i = 1:ndims(full_array)
ind_f{i} = unique(min(N_f(i),max(1,position(i)+(1:N_s(i)))));
ind_s{i} = unique(min(N_s(i),max(1,ind_f{i}-position(i))));
end
full_array(ind_f{:}) = full_array(ind_f{:}) + small_array(ind_s{:});
end
+80
View File
@@ -0,0 +1,80 @@
% IMSHIFT_GENERIC auxiliar function to be performed bu block_fun on GPU
% it applies imshift_fft on the provided image that was first upsampled
% to Npix (if needed) and cropped to region ROI
% after shifting, the image is downsampled by the chosen interpolation
% method "intep_method" that is more accurate than simple binning
%
% img = imshift_generic(img, shift, Npix, affine_matrix, smooth, ROI, downsample, intep_method, interp_sign)
%
% Inputs:
% **img 2D stacked image
% **shift Nx2 vector of shifts applied on the image
% **Npix 2x1 int, size of the img to be upsampled before shift, Npix = [] -> no upsampling
% **affine_matrix affine metrix ! not implemented yet!
% **smooth how many pixels around edges will be smoothed before shifting the array
% **ROI cell array, used to crop the array to smaller size
% **downsample downsample factor , 1 == no downsampling
% **intep_method interpolation method: linear, fft
% **interp_sign sign used for subpixel shifts of the dataset, +1 for unwrapped phase, -1 for phase differene
% *returns*
% ++img 2D stacked image
function img = imshift_generic(img, shift, Npix, affine_matrix, smooth, ROI, downsample, intep_method, interp_sign)
if nargin < 9
interp_sign = 0;
end
import math.*
import utils.*
if isa(img, 'uint8') || (isa(img, 'gpuArray') && strcmpi(classUnderlying(img),'uint8'))
img = single(img) / 255; % assume that the provided image is only compressed into uint8
end
% if needed upsample to the size of the projection
if ~isempty(Npix) && any(Npix(1:2) ~= [size(img,1),size(img,2)])
switch intep_method
case 'linear', img = utils.interpolate_linear(img, Npix);
case 'fft', img = utils.interpolateFT(img, Npix);
end
end
isReal = isreal(img);
if any(shift(:) ~=0 )
smooth_axis = 3-find(any(shift ~= 0));
img = smooth_edges(img, smooth, smooth_axis);
if ~ismatrix(img)
switch intep_method
case 'linear'
img = utils.imshift_linear(img,shift); % interpolation of the weights does not need such precision
case 'fft'
%%% APPLY SHIFT USING FFT -> periodic boundary
img = imshift_fft(img, shift);
end
end
end
% crop the FOV after shift and before "downsample"
if ~isempty(ROI)
img = img(ROI{:},:); % crop to smaller ROI if provided
% apply crop after imshift_fft
end
Np = size(img);
% perform interpolation instead of downsample , it provides more accurate results
if downsample > 1
img = utils.imgaussfilt3_conv(img,[downsample,downsample,0]);
% correct for boundary effects of the convolution based smoothing
img = img ./ utils.imgaussfilt3_conv(ones(Np(1:2), 'like', img),[downsample,downsample,0]);
switch intep_method
case 'linear', img = utils.interpolate_linear(img,ceil(Np(1:2)/downsample/2)*2); % interpolation of the weights does not need such precision
case 'fft', img = utils.interpolateFT_centered(utils.smooth_edges(img, 2*downsample),ceil(Np(1:2)/downsample/2)*2, interp_sign); % accurate interpolation using FFT
end
end
if isReal; img = real(img); end
end
+102
View File
@@ -0,0 +1,102 @@
/* iradon_c.c:
sub-routine of a modified iradon.m, i.e., the time consuming loop
of this routine in C.
Compilation from Matlab:
mex iradon_c.c
maybe a tiny bit faster code is generated by
mex -O COPTIMFLAGS='-O2' LDOPTIMFLAGS='-O2' iradon_c.c
Usage from Matlab:
iradon_c( p, theta, x, y );
*/
#include "mex.h"
#include <math.h>
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
int dim1, dim2, dim1_data;
int i, no_of_angles, ctrIdx;
double *data, *theta, *xorg, *yorg, *imgorg;
/* Check for proper number of arguments. */
if (nrhs != 4)
mexErrMsgTxt("Four input arguments required: Data, theta, x and y.");
else if (nlhs != 1)
mexErrMsgTxt("One output argument has to be specified.");
/* Input must be double. */
if (mxIsDouble(prhs[0]) != 1)
mexErrMsgTxt("Input 1 (data) must be of double precision floating point type.");
if (mxIsDouble(prhs[1]) != 1)
mexErrMsgTxt("Input 2 (theta) must be of double precision floating point type.");
if (mxIsDouble(prhs[2]) != 1)
mexErrMsgTxt("Input 3 (x) must be of double precision floating point type.");
if (mxIsDouble(prhs[3]) != 1)
mexErrMsgTxt("Input 4 (y) must be of double precision floating point type.");
/* get number of different angles */
if (mxGetM(prhs[1]) == 1) {
no_of_angles = mxGetN(prhs[1]);
} else {
if (mxGetN(prhs[1]) == 1) {
no_of_angles = mxGetM(prhs[1]);
} else {
mexErrMsgTxt("Theta has to be a vector, not an array.");
}
}
/* get dimensions and check that they are consistent */
dim1 = mxGetM(prhs[2]);
dim2 = mxGetN(prhs[2]);
if ((dim1 != mxGetM(prhs[3])) || (dim1 != mxGetN(prhs[3])))
mexErrMsgTxt("x and y must have the same dimensions.");
if (no_of_angles > mxGetN(prhs[0]))
mexErrMsgTxt("The second dimension of data must be at least as large as the number of theta angles.");
dim1_data = mxGetM(prhs[0]);
/* allocate memory for image data, to be returned */
plhs[0] =
mxCreateNumericMatrix(dim1, dim2, mxDOUBLE_CLASS, mxREAL);
if (plhs[0] == NULL)
mexErrMsgTxt("Could not allocate memory for return data.");
/* get pointers to input and output data */
data = mxGetPr(prhs[0]);
theta = mxGetPr(prhs[1]);
xorg = mxGetPr(prhs[2]);
yorg = mxGetPr(prhs[3]);
imgorg = mxGetPr(plhs[0]);
/* index to image center */
ctrIdx = ceil(mxGetM(prhs[0]) / 2);
for (i=0; i < no_of_angles; i++) {
double *x = xorg;
double *y = yorg;
double *img = imgorg;
/* temporary variables */
double costheta = cos(*theta);
double sintheta = sin(*theta);
double *proj = &data[i*dim1_data +1];
int j;
for (j=0; j < dim2; j++) {
int k;
for (k=0; k < dim1; k++) {
double t = *x * costheta + *y * sintheta;
int a = floor(t);
*img += (t-a) * proj[a+ctrIdx] + (a+1-t) * proj[a+ctrIdx-1];
x++;
y++;
img++;
}
}
theta++;
}
return;
}
+57
View File
@@ -0,0 +1,57 @@
% FUNCTION full_array = set_to_3D(full_array, small_array, position)
% add one small 3D block into large 3D array
% Inputs:
% full_array
% small_array
% position - [3 x 1] offset from (1,1,1) coordinate in pixels
% *-----------------------------------------------------------------------*
% |                                                                       |
% |  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 full_array = set_to_3D(full_array, small_array, position)
position = round(position);
N_f = size(full_array);
N_s = size(small_array);
for i = 1:3
ind_f{i} = unique(min(N_f(i),max(1,position(i)+(1:N_s(i)))));
end
full_array(ind_f{:}) = small_array;
end