Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
2d6d482
create python file
agvesga Nov 16, 2023
22b1295
test
HannahSHeil Nov 16, 2023
b9a0da6
Update SRMetrics.ipynb
agvesga Nov 30, 2023
ccd7a87
initial implementation of 3D interpolator
brunomsaraiva Dec 13, 2023
b682bbd
initial testing notebook for 3desrrf
brunomsaraiva Dec 13, 2023
836413a
added a LE class for eSRRF 3D and added unthreaded calling 3D gradients
brunomsaraiva Dec 13, 2023
6d7e130
removed old python version
brunomsaraiva Dec 14, 2023
228d12c
fixed a bug with gradients calculation
brunomsaraiva Dec 14, 2023
4d3e9cd
changed 3d interpolation to calculate interpolations on xz and yz and…
brunomsaraiva Dec 14, 2023
e197a10
added rgc3D
agvesga Dec 14, 2023
d42b6bc
Merge branch 'esrrf3d' of https://github.com/HenriquesLab/NanoPyx int…
agvesga Dec 14, 2023
872e5f7
added rgd3D and dk3D
agvesga Dec 14, 2023
d6c2923
added z magnification
agvesga Dec 14, 2023
95b4f19
split weighting in XY and Z separately
agvesga Dec 14, 2023
77e042f
added rgc calculation to 3desrrf
brunomsaraiva Dec 14, 2023
5e9559d
test single distance weight
agvesga Dec 14, 2023
3baa396
back to 2 component weight
agvesga Dec 14, 2023
1a6b7cd
more bugfixing
brunomsaraiva Dec 14, 2023
2bb83f3
correct colon
agvesga Dec 14, 2023
89ec3b3
make sure magnification is int
agvesga Dec 14, 2023
ad47df5
defaulted magnification to ints
brunomsaraiva Dec 14, 2023
6a0a501
Merge branch 'esrrf3d' of https://github.com/HenriquesLab/NanoPyx int…
brunomsaraiva Dec 14, 2023
c7f61f6
added handling of timepoints
brunomsaraiva Dec 14, 2023
415a79b
change to isotropic calculation
agvesga Dec 14, 2023
f4390fd
latest iteration
brunomsaraiva Dec 15, 2023
8a751e1
pad only in one side
agvesga Dec 15, 2023
83ed932
chage output and put back for debugging
agvesga Dec 15, 2023
80f4c06
added more variations of 3d esrrf
brunomsaraiva Dec 18, 2023
b98c0c3
fixes index acess in gradients
agvesga Dec 18, 2023
17a31ff
slices in RGC can access up to slicesM - 2
agvesga Dec 18, 2023
9ce22e9
new iteration
brunomsaraiva Dec 19, 2023
7c301ea
minor bugfix to gradient calculation
brunomsaraiva Dec 20, 2023
e087c7f
corrected zo in RGC
agvesga Dec 20, 2023
0db9ca2
interpolate before computing gradient
agvesga Dec 20, 2023
ed385fd
sort pixel referencing prblem
agvesga Jan 22, 2024
c0ad80d
rename intermediate magnification
agvesga Jan 22, 2024
fe25568
commented unused variables for debugging
agvesga Jan 22, 2024
06d80cd
corrected referencing pixels for rgc
agvesga Jan 22, 2024
93d6175
create developer eSRRF3D_dev function
agvesga Jan 22, 2024
f6c753c
fixed RGC computation
agvesga Feb 13, 2024
f2943e4
updated development function
agvesga Feb 13, 2024
7609229
added time average still needs some fix
agvesga Feb 13, 2024
c2890b5
time average implemented
agvesga Feb 14, 2024
3a9b0e5
removed _dev version. added placeholder variables to also provide use…
brunomsaraiva Feb 14, 2024
231a9ec
added 3d esrrf method
brunomsaraiva Feb 14, 2024
f7f8f97
added threaded implementation
brunomsaraiva Feb 14, 2024
1bcfdd8
added time analysis as external function + rolling average
agvesga Feb 14, 2024
d1962d9
minor changes
agvesga Feb 14, 2024
c770ca2
fixed
brunomsaraiva Feb 14, 2024
0b82fff
Merge branch 'esrrf3d' of https://github.com/HenriquesLab/NanoPyx int…
brunomsaraiva Feb 14, 2024
1c7fafd
fix for time_analysis function
agvesga Feb 14, 2024
4de47e6
added keep interpolated image
agvesga Feb 14, 2024
8b5b8b9
refactored time analysis methods
brunomsaraiva Feb 15, 2024
ce390fd
fixed and added docstring
agvesga Feb 15, 2024
2a707a2
added keep interp
agvesga Feb 15, 2024
1578ffb
added arguments as kwargs
agvesga Feb 15, 2024
0efd4ac
added full stack averaging
agvesga Feb 29, 2024
03d0f3c
added SRRF calculation iwth z axis
agvesga Mar 1, 2024
26fcc49
added 1D interpolation
agvesga Mar 1, 2024
4232425
added linear interpolation in z
agvesga Mar 1, 2024
13f22b9
Added ellipsoidal exclusion shape
agvesga Mar 1, 2024
8d96fb7
added todo
agvesga Mar 1, 2024
5535d17
added pixel ratio
agvesga Mar 4, 2024
d4a6087
added pixel ratio
agvesga Mar 4, 2024
e453507
added ratio px in headers
agvesga Mar 4, 2024
21ce4ba
corrected starting pixel in rgc3D
agvesga Mar 4, 2024
a1551a3
.
agvesga Mar 4, 2024
c4dcb6a
added comment
agvesga Mar 4, 2024
b259c1f
test script
agvesga Mar 19, 2024
86f1a0c
added one-frame case
agvesga Mar 19, 2024
f2e7020
.
agvesga Mar 19, 2024
2dfac1c
added blue lines for plotting profiles
agvesga Mar 19, 2024
5416ea8
fixes plane referencing
agvesga Mar 21, 2024
67ee90d
finished figure
agvesga Mar 21, 2024
9717e25
testing different planes
agvesga Mar 21, 2024
b2d2356
gradient declaration improve
agvesga Mar 22, 2024
c6df103
access slices properly
agvesga Mar 22, 2024
852f9af
changed 1D interpolator
brunomsaraiva Mar 22, 2024
829f03f
Merge branch 'esrrf3d' of https://github.com/HenriquesLab/NanoPyx int…
brunomsaraiva Mar 22, 2024
ccbbea6
corrected for
agvesga Mar 22, 2024
c7bd3e6
dirty working version
agvesga Mar 22, 2024
c7c3a1d
dirty working version
agvesga Mar 22, 2024
e0953a2
clean working version
agvesga Mar 22, 2024
b8b9795
dirty notebooks
agvesga Mar 22, 2024
4e0f3c0
clean working version
agvesga Mar 22, 2024
a0c59fb
Merge branch 'esrrf3d' of https://github.com/HenriquesLab/NanoPyx int…
agvesga Mar 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion notebooks/SRMetrics.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
47 changes: 35 additions & 12 deletions src/include/_c_gradients.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <math.h>

void _c_gradient_radiality(float* image, float* imGc, float* imGr, int rows,
int cols) {
Expand Down Expand Up @@ -66,23 +67,27 @@ void _c_gradient_roberts_cross(float* image, float* imGc, float* imGr, int rows,

// as in https://www.nature.com/articles/s41592-022-01669-y#MOESM1
// 3D Gradient calculation
void _c_gradient_3d(float* image, float* imGc, float* imGr, float* imGs, int slice,
void _c_gradient_3d(float* image, float* imGc, float* imGr, float* imGs, int slices,
int rows, int cols) {
float ip0, ip1, ip2, ip3, ip4, ip5, ip6, ip7;

int z_i, y_i, x_i;
int z_i, y_i, x_i, z_1, y_1, x_1;

for (z_i = 0; z_i < slice - 1; z_i++) {
for (y_i = 0; y_i < rows - 1; y_i++) {
for (x_i = 0; x_i < cols - 1; x_i++) {
for (z_i = 0; z_i < slices; z_i++) {
for (y_i = 0; y_i < rows; y_i++) {
for (x_i = 0; x_i < cols; x_i++) {

z_1 = z_i >= slices - 1 ? slices - 1 : z_i + 1;
y_1 = y_i >= rows - 1 ? rows - 1 : y_i + 1;
x_1 = x_i >= cols - 1 ? cols - 1 : x_i + 1;
ip0 = image[z_i * rows * cols + y_i * cols + x_i];
ip1 = image[z_i * rows * cols + y_i * cols + x_i + 1];
ip2 = image[z_i * rows * cols + (y_i + 1) * cols + x_i];
ip3 = image[z_i * rows * cols + (y_i + 1) * cols + x_i + 1];
ip4 = image[(z_i + 1) * rows * cols + y_i * cols + x_i];
ip5 = image[(z_i + 1) * rows * cols + y_i * cols + x_i + 1];
ip6 = image[(z_i + 1) * rows * cols + (y_i + 1) * cols + x_i];
ip7 = image[(z_i + 1) * rows * cols + (y_i + 1) * cols + x_i + 1];
ip1 = image[z_i * rows * cols + y_i * cols + x_1];
ip2 = image[z_i * rows * cols + y_1 * cols + x_i];
ip3 = image[z_i * rows * cols + y_1 * cols + x_1];
ip4 = image[z_1 * rows * cols + y_i * cols + x_i];
ip5 = image[z_1 * rows * cols + y_i * cols + x_1];
ip6 = image[z_1 * rows * cols + y_1 * cols + x_i];
ip7 = image[z_1 * rows * cols + y_1 * cols + x_1];
imGc[z_i * rows* cols + y_i * cols + x_i] =
(ip1 + ip3 + ip5 + ip7 - ip0 - ip2 - ip4 - ip6) / 4;
imGr[z_i * rows* cols + y_i * cols + x_i] =
Expand All @@ -93,3 +98,21 @@ void _c_gradient_3d(float* image, float* imGc, float* imGr, float* imGs, int sli
}
}
}

void _c_gradient_2_point_3d(float* image, float* imGc, float* imGr, float* imGs, int slices, int rows, int cols) {
int s_i, y_i, x_i, s0, y0, x0;

for (s_i=0; s_i<slices; s_i++) {
for (y_i=0; y_i<rows; y_i++) {
for (x_i=0; x_i<cols; x_i++) {
s0 = s_i > 0 ? s_i - 1 : 0;
y0 = y_i > 0 ? y_i - 1 : 0;
x0 = x_i > 0 ? x_i - 1 : 0;
imGc[s_i*rows*cols + y_i*cols + x_i] = image[s_i*rows*cols + y_i*cols + x_i] - image[s_i*rows*cols + y_i*cols + x0];
imGr[s_i*rows*cols + y_i*cols + x_i] = image[s_i*rows*cols + y_i*cols + x_i] - image[s_i*rows*cols + y0*cols + x_i];
imGs[s_i*rows*cols + y_i*cols + x_i] = image[s_i*rows*cols + y_i*cols + x_i] - image[s0*rows*cols + y_i*cols + x_i];

}
}
}
}
4 changes: 3 additions & 1 deletion src/include/_c_gradients.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ void _c_gradient_2point(float* image, float* imGc, float* imGr, int rows,

void _c_gradient_roberts_cross(float* image, float* imGc, float* imGr, int rows, int cols);

void _c_gradient_3d(float* image, float* imGc, float* imGr, float* imGs, int slice,
void _c_gradient_3d(float* image, float* imGc, float* imGr, float* imGs, int slices,
int rows, int cols);

void _c_gradient_2_point_3d(float* image, float* imGc, float* imGr, float* imGs, int slices, int rows, int cols);

#endif
134 changes: 134 additions & 0 deletions src/include/_c_sr_radial_gradient_convergence.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <math.h>
#include <stdio.h>

double _c_calculate_dw(double distance, double tSS) {
return pow((distance * exp((-distance * distance) / tSS)), 4);
Expand Down Expand Up @@ -68,3 +69,136 @@ float _c_calculate_rgc(int xM, int yM, float* imIntGx, float* imIntGy, int colsM

return RGC;
}

double _c_calculate_dw3D_isotropic(double distance, double tSS) {
return pow((distance * exp(-(distance * distance) / tSS)), 4);
}

double _c_calculate_dw3D(double distance, double distance_xy, double distance_z,double tSS, double tSS_z) {
float D_weight_xy, D_weight_z, D_weight;
D_weight_xy = (exp((-distance_xy * distance_xy) / tSS));
D_weight_z = (exp((-distance_z * distance_z) / tSS_z));
D_weight = distance * (D_weight_xy * D_weight_z);
return pow(D_weight, 4);
}

double _c_calculate_dw_xy(double distance_xy, double tSS) {
return pow((distance_xy * exp((-distance_xy * distance_xy) / tSS)), 4);
}

double _c_calculate_dw_z(double distance_z, double tSS_z) {
return pow((distance_z * exp((-distance_z * distance_z) / tSS_z)), 4);
}

double _c_calculate_dk3D(float Gx, float Gy, float Gz, float dx, float dy, float dz, float distance) {
float Dk = sqrtf((Gy * dz - Gz * dy) * (Gy * dz - Gz * dy) + (Gz * dx - Gx * dz) * (Gz * dx - Gx * dz) + (Gx * dy - Gy * dx) * (Gx * dy - Gy * dx)) / sqrt(Gx * Gx + Gy * Gy + Gz * Gz);
if (isnan(Dk)) {
Dk = distance;
}
Dk = 1 - Dk / distance;
return Dk;
}

float _c_get_bound_value(float* im, int slices, int rows, int cols, int s, int r, int c){
int _s = s > 0 ? s : 0;
_s = _s < slices - 1 ? _s : slices - 1;
int _r = r > 0 ? r : 0;
_r = _r < rows - 1 ? _r : rows - 1;
int _c = c > 0 ? c : 0;
_c = _c < cols - 1 ? _c : cols - 1;

return im[_s * rows * cols + _r * cols + _c];
}

float _c_calculate_rgc3D(int xM, int yM, int sliceM, float* imIntGx, float* imIntGy, float* imIntGz, int colsM, int rowsM, int slicesM, int magnification_xy, int magnification_z, float ratio_px, float Gx_Gy_MAGNIFICATION, float Gz_MAGNIFICATION, float fwhm, float fwhm_z, float tSO, float tSO_z, float tSS, float tSS_z, float sensitivity) {

float vx, vy, vz, Gx, Gy, Gz, dx, dy, dz, dz_real, distance, distance_xy, distance_z, distanceWeight, distanceWeight_xy, distanceWeight_z, GdotR, Dk;

float xc = (xM + 0.5) / magnification_xy;
float yc = (yM + 0.5) / magnification_xy;
float zc = (sliceM + 0.5) / magnification_z;

float RGC = 0;
float distanceWeightSum = 0;
float distanceWeightSum_xy = 0;
float distanceWeightSum_z = 0;

int _start = -(int)(Gx_Gy_MAGNIFICATION * fwhm);
int _end = (int)(Gx_Gy_MAGNIFICATION * fwhm + 1);

int _start_z = -(int)(Gz_MAGNIFICATION * fwhm_z);
int _end_z = (int)(Gz_MAGNIFICATION * fwhm_z + 1);

for (int j = _start; j <= _end; j++) {
vy = ((float) ((int) (Gx_Gy_MAGNIFICATION*yc)) + j)/(float) Gx_Gy_MAGNIFICATION;

if (0 < vy && vy < rowsM - 1) {
for (int i = _start; i <= _end; i++) {
vx = ((float) ((int) (Gx_Gy_MAGNIFICATION*xc)) + i)/(float) Gx_Gy_MAGNIFICATION;

if (0 < vx && vx < colsM - 1) {
for (int k = _start_z; k <= _end_z; k++) {
vz = ((float) ((int) (zc)) + k);

if (0 < vz && vz < slicesM - 1) {
dx = vx - xc;
dy = vy - yc;
dz = vz - zc;
dz_real = dz * ratio_px; // This has been already divided by magnification_z
distance = sqrt(dx * dx + dy * dy + dz_real * dz_real);
distance_xy = sqrt(dx * dx + dy * dy);
distance_z = dz_real;

if (distance != 0 && distance_xy <= tSO && distance_z <= tSO_z) {
Gx = _c_get_bound_value(imIntGx, slicesM*Gz_MAGNIFICATION, rowsM*Gx_Gy_MAGNIFICATION, colsM*Gx_Gy_MAGNIFICATION, vz * magnification_z * Gz_MAGNIFICATION, magnification_xy * Gx_Gy_MAGNIFICATION * vy, magnification_xy * Gx_Gy_MAGNIFICATION * vx);
Gy = _c_get_bound_value(imIntGy, slicesM*Gz_MAGNIFICATION, rowsM*Gx_Gy_MAGNIFICATION, colsM*Gx_Gy_MAGNIFICATION, vz * magnification_z * Gz_MAGNIFICATION, magnification_xy * Gx_Gy_MAGNIFICATION * vy, magnification_xy * Gx_Gy_MAGNIFICATION * vx);
Gz = _c_get_bound_value(imIntGz, slicesM*Gz_MAGNIFICATION, rowsM*Gx_Gy_MAGNIFICATION, colsM*Gx_Gy_MAGNIFICATION, vz * magnification_z * Gz_MAGNIFICATION, magnification_xy * Gx_Gy_MAGNIFICATION * vy, magnification_xy * Gx_Gy_MAGNIFICATION * vx);

// distanceWeight = _c_calculate_dw3D_isotropic(distance, tSS);
distanceWeight = _c_calculate_dw3D(distance, distance_xy, distance_z, tSS, tSS_z);

// distanceWeight_xy = _c_calculate_dw_xy(distance_xy, tSS);
// distanceWeight_z = _c_calculate_dw_z(distance_z, tSS_z);

distanceWeightSum += distanceWeight;
// distanceWeightSum_xy += distanceWeight_xy;
// distanceWeightSum_z += distanceWeight_z;
GdotR = Gx*dx + Gy*dy + Gz*dz_real;

if (GdotR < 0) {
Dk = _c_calculate_dk3D(Gx, Gy, Gz, dx, dy, dz_real, distance);
RGC += (Dk * distanceWeight);
}
}
}
}
}
}
}
}

RGC /= distanceWeightSum;

if (RGC >= 0) {
RGC = pow(RGC, sensitivity);
} else {
RGC = 0;
}

return RGC;
}

float _c_calculate_dk_3d(float dx, float dy, float dz, float Gx, float Gy, float Gz, float Gmag, float distance) {
float G1 = dy*Gz - dz*Gy;
float G2 = dz*Gx - dx*Gz;
float G3 = dx*Gy - dy*Gx;
float cross_product = sqrt(G1*G1 + G2*G2 + G3*G3)/Gmag;

if (isnan(cross_product)) {
cross_product = distance;
}

cross_product = 1 - cross_product / distance;

return cross_product;
}
14 changes: 14 additions & 0 deletions src/include/_c_sr_radial_gradient_convergence.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,18 @@ double _c_calculate_dk(float Gx, float Gy, float dx, float dy, float distance);

float _c_calculate_rgc(int xM, int yM, float* imIntGx, float* imIntGy, int colsM, int rowsM, int magnification, float Gx_Gy_MAGNIFICATION, float fwhm, float tSO, float tSS, float sensitivity);

double _c_calculate_dw3D_isotropic(double distance, double tSS);

double _c_calculate_dw3D(double distance, double distance_xy, double distance_z, double tSS, double tSS_z);

double _c_calculate_dw_xy(double distance_xy, double tSS);

double _c_calculate_dw_z(double distance_z, double tSS_z);

double _c_calculate_dk3D(float Gx, float Gy, float Gz, float dx, float dy, float dz, float distance);

float _c_calculate_rgc3D(int xM, int yM, int sliceM, float* imIntGx, float* imIntGy, float* imIntGz, int colsM, int rowsM, int slicesM, int magnification_xy, int magnification_z, float ratio_px, float Gx_Gy_MAGNIFICATION, float Gz_MAGNIFICATION, float fwhm, float fwhm_z, float tSO, float tSO_z, float tSS, float tSS_z, float sensitivity);

float _c_calculate_rgc_3d(int cM, int rM, int sM, float* imIntGx, float* imIntGy, float* imIntGz, int colsM, int rowsM, int slicesM, int magnification_xy, int magnification_z, float Gx_Gy_MAGNIFICATION, float fwhm, float fwhm_z, float tSO, float tSS, float sensitivity);

#endif
36 changes: 36 additions & 0 deletions src/nanopyx/core/transform/_interpolation.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ cimport numpy as np

import cython

from ._le_interpolation_catmull_rom import ShiftAndMagnify as ShiftMagnify_CR


cdef extern from "_c_interpolation_catmull_rom.h":
float _c_cr_interpolate "_c_interpolate" (float *image, float row, float col, int rows, int cols)
Expand All @@ -18,3 +20,37 @@ def cr_interpolate(img_stack, row, col):
img_stack = np.array(img_stack, dtype=np.float32)
return _cr_interpolate(img_stack, row, col)

def interpolate_3d(image, magnification_xy: int = 5, magnification_z: int = 5):
interpolator = ShiftMagnify_CR()

xy_interpolated = interpolator.run(image, 0, 0, magnification_xy, magnification_xy)

yz_interpolated = np.transpose(interpolator.run(np.transpose(xy_interpolated, axes=[1, 0, 2]).copy(), 0, 0, magnification_z, 1), axes=[1, 0, 2]).copy()
xz_interpolated = np.transpose(interpolator.run(np.transpose(xy_interpolated, axes=[2, 1, 0]).copy(), 0, 0, 1, magnification_z), axes=[2,1,0]).copy()

return np.mean(np.array([yz_interpolated, xz_interpolated]), axis=0)

def linear_interpolation_1D_z(image, magnification):
# linear interpolator that takes a 3D image and do linear interpolation in a 1D column in the chosen axis

image_interpolated = np.zeros((image.shape[0] * magnification, image.shape[1], image.shape[2]), dtype=np.float32)

z_coords = np.linspace(0, image.shape[0], image.shape[0])
new_z_coords = np.linspace(0, image.shape[0], image.shape[0] * magnification)

for r in range(image.shape[1]):
for c in range(image.shape[2]):
slc = image[:, r, c]
image_interpolated[:, r, c] = np.interp(new_z_coords, z_coords, slc)


return image_interpolated


def interpolate_3d_zlinear(image, magnification_xy: int = 5, magnification_z: int = 5):
interpolator_xy = ShiftMagnify_CR()

xy_interpolated = interpolator_xy.run(np.ascontiguousarray(image), 0, 0, magnification_xy, magnification_xy)
z_interpolated = linear_interpolation_1D_z(xy_interpolated, magnification_z)

return z_interpolated
Loading