Skip to content
Snippets Groups Projects
Commit 0513477a authored by David Hammer's avatar David Hammer
Browse files

Fix weighted ss / fs indices (thought I did already)

parent cb82cd89
No related branches found
No related tags found
2 merge requests!145Fixes found during BUD winter 2025,!118Draft: MID: put arbiter on manager scene
...@@ -4,15 +4,15 @@ ...@@ -4,15 +4,15 @@
class MaskedImageFrame { class MaskedImageFrame {
public: public:
const float* data_start; const float* data_start;
const unsigned short num_rows; const unsigned short ss_dim;
const unsigned short num_cols; const unsigned short fs_dim;
__device__ MaskedImageFrame(const float* data_start, const unsigned short num_rows, const unsigned short num_cols): __device__ MaskedImageFrame(const float* data_start, const unsigned short ss_dim, const unsigned short fs_dim):
data_start(data_start), num_rows(num_rows), num_cols(num_cols) {} data_start(data_start), ss_dim(ss_dim), fs_dim(fs_dim) {}
__device__ bool is_masked(const unsigned short i, const unsigned short j) { __device__ bool is_masked(const unsigned short i, const unsigned short j) {
return isnan(data_start[i * num_cols + j]); return isnan(data_start[i * fs_dim + j]);
} }
__device__ float get(const unsigned short i, const unsigned short j) { __device__ float get(const unsigned short i, const unsigned short j) {
return data_start[i * num_cols + j]; return data_start[i * fs_dim + j];
} }
__device__ float get(const unsigned short i, const unsigned short j, const float fallback) { __device__ float get(const unsigned short i, const unsigned short j, const float fallback) {
if (is_masked(i, j)) { if (is_masked(i, j)) {
...@@ -56,8 +56,8 @@ public: ...@@ -56,8 +56,8 @@ public:
}; };
extern "C" __global__ void pf9(const unsigned short num_frames, extern "C" __global__ void pf9(const unsigned short num_frames,
const unsigned short num_rows, const unsigned short ss_dim,
const unsigned short num_cols, const unsigned short fs_dim,
const unsigned short window_radius, const unsigned short window_radius,
const float min_peak_over_border, const float min_peak_over_border,
const float min_snr_biggest_pixel, const float min_snr_biggest_pixel,
...@@ -73,37 +73,37 @@ extern "C" __global__ void pf9(const unsigned short num_frames, ...@@ -73,37 +73,37 @@ extern "C" __global__ void pf9(const unsigned short num_frames,
// execution model: one thread handles one pixel in one frame // execution model: one thread handles one pixel in one frame
const unsigned short frame = blockDim.x * blockIdx.x + threadIdx.x; const unsigned short frame = blockDim.x * blockIdx.x + threadIdx.x;
const unsigned short row = blockDim.y * blockIdx.y + threadIdx.y; const unsigned short ss_index = blockDim.y * blockIdx.y + threadIdx.y;
const unsigned short col = blockDim.z * blockIdx.z + threadIdx.z; const unsigned short fs_index = blockDim.z * blockIdx.z + threadIdx.z;
if (frame >= num_frames || if (frame >= num_frames ||
row < window_radius || row >= num_rows - window_radius || ss_index < window_radius || ss_index >= ss_dim - window_radius ||
col < window_radius || col >= num_cols - window_radius) { fs_index < window_radius || fs_index >= fs_dim - window_radius) {
return; return;
} }
// wrap thin helper class around for convenience // wrap thin helper class around for convenience
MaskedImageFrame masked_frame(image + frame * (num_rows * num_cols), MaskedImageFrame masked_frame(image + frame * (ss_dim * fs_dim),
num_rows, ss_dim,
num_cols); fs_dim);
// candidate should not be masked // candidate should not be masked
if (masked_frame.is_masked(row, col)) { if (masked_frame.is_masked(ss_index, fs_index)) {
return; return;
} }
float pixel_val = masked_frame.get(row, col); float pixel_val = masked_frame.get(ss_index, fs_index);
// candidate should be greater than immediate neighbors // candidate should be greater than immediate neighbors
// with tie breaking: in case of equality, lowest row, col is candidate // with tie breaking: in case of equality, lowest row, fs_index is candidate
if (pixel_val <= masked_frame.get(row-1, col-1, -INFINITY) || if (pixel_val <= masked_frame.get(ss_index-1, fs_index-1, -INFINITY) ||
pixel_val <= masked_frame.get(row-1, col, -INFINITY) || pixel_val <= masked_frame.get(ss_index-1, fs_index, -INFINITY) ||
pixel_val <= masked_frame.get(row-1, col+1, -INFINITY) || pixel_val <= masked_frame.get(ss_index-1, fs_index+1, -INFINITY) ||
pixel_val <= masked_frame.get(row, col-1, -INFINITY) || pixel_val <= masked_frame.get(ss_index, fs_index-1, -INFINITY) ||
pixel_val < masked_frame.get(row, col+1, -INFINITY) || pixel_val < masked_frame.get(ss_index, fs_index+1, -INFINITY) ||
pixel_val < masked_frame.get(row+1, col, -INFINITY) || pixel_val < masked_frame.get(ss_index+1, fs_index, -INFINITY) ||
pixel_val < masked_frame.get(row+1, col, -INFINITY) || pixel_val < masked_frame.get(ss_index+1, fs_index, -INFINITY) ||
pixel_val < masked_frame.get(row+1, col, -INFINITY)) { pixel_val < masked_frame.get(ss_index+1, fs_index, -INFINITY)) {
return; return;
} }
...@@ -112,7 +112,7 @@ extern "C" __global__ void pf9(const unsigned short num_frames, ...@@ -112,7 +112,7 @@ extern "C" __global__ void pf9(const unsigned short num_frames,
// (full border for window radius 2, less for higher) // (full border for window radius 2, less for higher)
{ {
float border_max = -INFINITY; float border_max = -INFINITY;
masked_frame.fun_ring(row, col, window_radius, [&] (unsigned short, unsigned short, float val) { masked_frame.fun_ring(ss_index, fs_index, window_radius, [&] (unsigned short, unsigned short, float val) {
border_max = max(border_max, val); border_max = max(border_max, val);
}); });
if (pixel_val - min_peak_over_border <= border_max) { if (pixel_val - min_peak_over_border <= border_max) {
...@@ -127,7 +127,7 @@ extern "C" __global__ void pf9(const unsigned short num_frames, ...@@ -127,7 +127,7 @@ extern "C" __global__ void pf9(const unsigned short num_frames,
// https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm // https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm
unsigned short count = 0; unsigned short count = 0;
float M2 = 0; float M2 = 0;
masked_frame.fun_ring(row, col, window_radius, [&] (unsigned short, unsigned short, float val) { masked_frame.fun_ring(ss_index, fs_index, window_radius, [&] (unsigned short, unsigned short, float val) {
++count; ++count;
float delta = val - mean; float delta = val - mean;
mean += delta / static_cast<float>(count); mean += delta / static_cast<float>(count);
...@@ -147,44 +147,47 @@ extern "C" __global__ void pf9(const unsigned short num_frames, ...@@ -147,44 +147,47 @@ extern "C" __global__ void pf9(const unsigned short num_frames,
} }
// whole peak should have sufficent SNR // whole peak should have sufficent SNR
float peak_weighted_row; float peak_weighted_ss;
float peak_weighted_col; float peak_weighted_fs;
float peak_total_mass = pixel_val - mean; float peak_total_mass = 0;
{ {
/* TODO: more compact form */ /* TODO: more compact form */
float peak_weighted_row_nom = static_cast<float>(row) * pixel_val; float peak_weighted_ss_nom = 0;
float peak_weighted_col_nom = static_cast<float>(col) * pixel_val; float peak_weighted_fs_nom = 0;
const float peak_pixel_threshold = mean + min_snr_peak_pixels * sigma; // expand peak in rings
for (unsigned short layer=1; layer<=window_radius; ++layer) { {
float total_mass_before = peak_total_mass; const float peak_pixel_threshold = mean + min_snr_peak_pixels * sigma;
masked_frame.fun_ring(row, col, layer, [&] (unsigned short i, unsigned short j, float val) { for (unsigned short layer=1; layer<=window_radius; ++layer) {
if (val > peak_pixel_threshold) { float total_mass_before = peak_total_mass;
float val_over_mean = val - mean; masked_frame.fun_ring(ss_index, fs_index, layer, [&] (unsigned short i, unsigned short j, float val) {
peak_total_mass += val_over_mean; if (val > peak_pixel_threshold) {
peak_weighted_row_nom += val_over_mean * static_cast<float>(i); float val_over_mean = val - mean;
peak_weighted_col_nom += val_over_mean * static_cast<float>(j); peak_total_mass += val_over_mean;
} peak_weighted_ss_nom += val_over_mean * static_cast<float>(i);
}); peak_weighted_fs_nom += val_over_mean * static_cast<float>(j);
// in case nothing was added, stop expanding }
if (peak_total_mass == total_mass_before) { });
break; // in case nothing was added, stop expanding
} if (peak_total_mass == total_mass_before) {
} break;
}
}
}
if (peak_total_mass <= mean + min_snr_whole_peak * sigma) { if (peak_total_mass <= mean + min_snr_whole_peak * sigma) {
return; return;
} }
if (peak_total_mass == 0) { if (peak_total_mass == 0) {
float peak_weighted_row = static_cast<float>(row); peak_weighted_ss = static_cast<float>(ss_index);
float peak_weighted_col = static_cast<float>(col); peak_weighted_fs = static_cast<float>(fs_index);
} else { } else {
peak_weighted_row = peak_weighted_row_nom / peak_total_mass; peak_weighted_ss = peak_weighted_ss_nom / peak_total_mass;
peak_weighted_col = peak_weighted_col_nom / peak_total_mass; peak_weighted_fs = peak_weighted_fs_nom / peak_total_mass;
} }
} }
unsigned int output_index = atomicInc(output_counts + frame, max_peaks); unsigned int output_index = atomicInc(output_counts + frame, max_peaks);
unsigned int output_pos = frame * max_peaks + output_index; unsigned int output_pos = frame * max_peaks + output_index;
output_x[output_pos] = peak_weighted_row; output_x[output_pos] = peak_weighted_ss;
output_y[output_pos] = peak_weighted_col; output_y[output_pos] = peak_weighted_fs;
output_intensity[output_pos] = peak_total_mass; output_intensity[output_pos] = peak_total_mass;
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment