23 float rot_rad = M_PI *
rotation / 180;
24 float cos_rot = cos(rot_rad);
25 float sin_rot = sin(rot_rad);
39 float d = ix_s * ix_s + iy_s * iy_s;
40 int ix_e =
k_area - iy_e + ix - 1;
44 float ix_sd = (ix_s / d);
45 float iy_sd = (iy_s / d);
46 kernel_x[ix_e] = cos_rot * ix_sd - sin_rot * iy_sd;
47 kernel_y[ix_e] = sin_rot * ix_sd + cos_rot * iy_sd;
78 if (dist <= ub && dist > lb)
90 std::vector<std::complex<float>> x2c = FFT2D::r2c(
kernel_x);
91 std::vector<std::complex<float>> y2c = FFT2D::r2c(
kernel_y);
94 for (
int id = 0;
id <
k_area;
id++)
102 fft2d.ifft(x2c, x2c);
103 fft2d.ifft(y2c, y2c);
104 for (
int id = 0;
id <
k_area;
id++)
116 for (
size_t i = 0; i < nx_im; i++)
118 float x = 2 * i * M_PI;
119 f_approx[i] = (nx_im / x) * (1 - cos(k / 2 * (x / nx_im)));
135 std::cout <<
"Surface could not be created! SDL Error: " << SDL_GetError() << std::endl;
140 std::cout <<
"Surface could not be created! SDL Error: " << SDL_GetError() << std::endl;
143 std::pair kx_min_max = std::minmax_element(
kernel_x.begin(),
kernel_x.end());
144 std::pair ky_min_max = std::minmax_element(
kernel_y.begin(),
kernel_y.end());
152 float valx = (
kernel_x[ic + x] - kx_min_max.first[0]) / (kx_min_max.second[0] - kx_min_max.first[0]);
154 float valy = (
kernel_y[ic + x] - ky_min_max.first[0]) / (ky_min_max.second[0] - ky_min_max.first[0]);
167 id_list.reserve(nx_cam * ny_cam);
169 for (
int iy = 0; iy < ny_cam; iy++)
171 for (
int ix = 0; ix < nx_cam; ix++)
173 d2 = pow((
float)ix - offset[0], 2) + pow((
float)iy - offset[1], 2);
176 id_list.push_back(iy * nx_cam + ix);
186 void Ricom::init_surface()
192 std::cout <<
"Surface could not be created! SDL Error: " << SDL_GetError() << std::endl;
196 srf_stem = SDL_CreateRGBSurface(0,
nx,
ny, 32, 0, 0, 0, 0);
199 std::cout <<
"Surface could not be created! SDL Error: " << SDL_GetError() << std::endl;
206 std::cout <<
"Surface could not be created! SDL Error: " << SDL_GetError() << std::endl;
214 std::cout <<
"Surface could not be created! SDL Error: " << SDL_GetError() << std::endl;
223 e_mag_max(-FLT_MAX), e_mag_min(FLT_MAX),
224 ricom_max(-FLT_MAX), ricom_min(FLT_MAX),
226 ricom_mutex(), stem_mutex(), counter_mutex(), e_field_mutex(),
227 socket(), file_path(
""),
241 b_plot2SDL(false), b_recompute_detector(false),
242 b_recompute_kernel(false), detector(),
244 offset{128, 128}, com_public{0.0, 0.0},
245 comx_image(), comy_image(),
248 nx(1024), ny(1024), nxy(0),
250 skip_row(1), skip_img(0),
251 n_threads(1), queue_size(64),
252 fr_freq(0.0), fr_count(0.0), fr_count_total(0.0),
253 rescale_ricom(false), rescale_stem(false),
255 srf_ricom(NULL), ricom_cmap(9),
256 srf_stem(NULL), stem_cmap(9),
257 srf_cbed(NULL), cbed_cmap(5),
258 srf_e_mag(NULL), e_mag_cmap(12)
268 std::lock_guard<std::mutex> lock(ricom_mutex);
269 for (
int y = 0; y <
ny; y++)
271 for (
int x = 0; x <
nx; x++)
273 set_ricom_pixel(x, y);
281 std::lock_guard<std::mutex> lock(ricom_mutex);
287 for (
int y = y0; y <= ye; y++)
289 for (
int x = 0; x <
nx; x++)
291 set_ricom_pixel(x, y);
298 void Ricom::set_ricom_pixel(
int idx,
int idy)
302 int idr = idy *
nx + idx;
306 float val = (
ricom_image[idr] - ricom_min) / ((ricom_max - ricom_min));
315 std::lock_guard<std::mutex> lock(stem_mutex);
316 for (
int y = 0; y <
ny; y++)
318 for (
int x = 0; x <
nx; x++)
320 set_stem_pixel(x, y);
333 std::lock_guard<std::mutex> lock(stem_mutex);
334 for (
int y = y0; y <= ye; y++)
336 for (
int x = 0; x <
nx; x++)
338 set_stem_pixel(x, y);
345 std::lock_guard<std::mutex> lock(e_field_mutex);
347 for (
int y = y0; y <= ye; y++)
349 for (
int x = 0; x <
nx; x++)
351 set_e_field_pixel(x, y);
359 std::lock_guard<std::mutex> lock(e_field_mutex);
360 for (
int y = 0; y <
ny; y++)
362 for (
int x = 0; x <
nx; x++)
364 set_e_field_pixel(x, y);
371 void Ricom::set_stem_pixel(
size_t idx,
size_t idy)
374 int idr = idy *
nx + idx;
379 float val = (
stem_image[idr] - stem_min) / (stem_max - stem_min);
387 void Ricom::set_e_field_pixel(
size_t idx,
size_t idy)
390 int idr = idy *
nx + idx;
391 float mag = (abs(
e_field_data[idr]) - e_mag_min) / (e_mag_max - e_mag_min);
401 inline void Ricom::rescales_recomputes()
436 void Ricom::compute_electric_field(std::array<float, 2> &com_xy,
size_t id)
438 float e_mag = std::hypot(com_xy[0] -
offset[0], com_xy[1] -
offset[1]);
439 float e_ang = atan2(com_xy[0] -
offset[0], com_xy[1] -
offset[1]);
440 if (e_mag > e_mag_max)
445 if (e_mag < e_mag_min)
453 template <
typename T>
454 void Ricom::update_surfaces(
int iy, std::vector<T> &frame)
482 size_t first_frame = img_num *
nxy;
483 size_t end_frame = (img_num + 1) *
nxy;
484 size_t fr_total_u = (size_t)
fr_total;
489 reinit_vectors_limits();
505 void Ricom::line_processor(
524 std::array<float, 2> com_xy = {0.0, 0.0};
525 std::array<float, 2> com_xy_sum = {0.0, 0.0};
526 for (
size_t i = 0; i < (size_t)
nx; i++)
528 int idxx_p_i = idxx + i;
529 if ((idxx_p_i >= 0) | (
nx > 1))
550 compute_electric_field(com_xy, idxx_p_i);
557 pool->
push_task([=]{ icom_group_classical(idxx); });
562 icom_group_classical(idxx);
566 if ((prog_mon->
report_set) && (update_line)>0)
569 rescales_recomputes();
570 for (
int i = 0; i < 2; i++)
581 if (prog_mon->
fr_count >= end_frame)
588 if (prog_mon->
fr_count != fr_total_u)
591 first_frame = img_num *
nxy;
592 end_frame = (img_num + 1) *
nxy;
614 void Ricom::icom_group_classical(
int idxx)
627 i_line++, idr_delay++)
635 i_line++, idr_delay++)
637 idc = idr_delay + iy *
nx;
638 idr_x = idr_delay %
nx;
642 if (((idr_x + ix) >= 0) & ((idr_x + ix) <
nx))
673 using namespace ADVAPIX_ADDITIONAL;
674 ADVAPIX<EVENT, BUFFER_SIZE, N_BUFFER> cam(
704 using namespace CHEETAH_ADDITIONAL;
705 CHEETAH<EVENT, BUFFER_SIZE, N_BUFFER> cam(
742 std::cout << std::endl
743 <<
"Reconstruction finished successfully." << std::endl;
747 void Ricom::reset_limits()
757 void Ricom::reinit_vectors_limits()
771 reinit_vectors_limits();
804 for (
int i=0; i<2; i++)
void init(int n_threads, int limit)
void push_task(const T &task)
void wait_for_completion()
std::atomic< bool > report_set
std::atomic< size_t > fr_count
std::array< float, 2 > radius2
std::array< float, 2 > radius
std::vector< int > id_list
void compute_detector(int nx_cam, int ny_cam, std::array< float, 2 > &offset)
std::vector< float > kernel_x
std::vector< float > kernel_y
std::vector< float > f_approx
void approximate_frequencies(size_t n_im)
std::array< int, 2 > kernel_filter_frequency
std::vector< float > kernel_filter
std::vector< float > stem_image
std::vector< size_t > frame
std::vector< float > comy_image
std::vector< size_t > sumy_data[2]
std::array< float, 2 > com_public
bool b_recompute_detector
void draw_e_field_image()
std::atomic< bool > rescale_ricom
std::vector< float > airpi_image
std::vector< float > comx_image
std::vector< std::complex< float > > e_field_data
std::vector< size_t > sumx_data[2]
std::vector< size_t > stem_data[2]
ProgressMonitor * p_prog_mon
std::vector< size_t > dose_data[2]
std::array< std::atomic< size_t >, 3 > frame_id_plot_cbed
std::vector< float > ricom_image
std::atomic< int > last_y
std::atomic< bool > rescale_e_mag
std::array< float, 2 > offset
std::atomic< bool > rescale_stem
void draw_pixel(SDL_Surface *surface, int x, int y, float val, int col_map)