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)));
125 std::for_each(
f_approx.begin(),
f_approx.end(), [f_max](
float &x) { x/=f_max; });
134 std::cout <<
"Surface could not be created! SDL Error: " << SDL_GetError() << std::endl;
139 std::cout <<
"Surface could not be created! SDL Error: " << SDL_GetError() << std::endl;
142 std::pair kx_min_max = std::minmax_element(
kernel_x.begin(),
kernel_x.end());
143 std::pair ky_min_max = std::minmax_element(
kernel_y.begin(),
kernel_y.end());
151 float valx = (
kernel_x[ic + x] - kx_min_max.first[0]) / (kx_min_max.second[0] - kx_min_max.first[0]);
153 float valy = (
kernel_y[ic + x] - ky_min_max.first[0]) / (ky_min_max.second[0] - ky_min_max.first[0]);
166 id_list.reserve(nx_cam * ny_cam);
168 for (
int iy = 0; iy < ny_cam; iy++)
170 for (
int ix = 0; ix < nx_cam; ix++)
172 d2 = pow((
float)ix - offset[0], 2) + pow((
float)iy - offset[1], 2);
175 id_list.push_back(iy * nx_cam + ix);
194 this->kernel = kernel;
202 ids[idul] = {(idy * nx + idx),
false};
213 res = {id_sft, y >= 0 && y < ny && x < nx && x >= 0};
219 void Ricom::init_surface()
225 std::cout <<
"Surface could not be created! SDL Error: " << SDL_GetError() << std::endl;
229 srf_stem = SDL_CreateRGBSurface(0,
nx,
ny, 32, 0, 0, 0, 0);
232 std::cout <<
"Surface could not be created! SDL Error: " << SDL_GetError() << std::endl;
239 std::cout <<
"Surface could not be created! SDL Error: " << SDL_GetError() << std::endl;
247 std::cout <<
"Surface could not be created! SDL Error: " << SDL_GetError() << std::endl;
257 e_mag_max(-FLT_MAX), e_mag_min(FLT_MAX),
258 ricom_max(-FLT_MAX), ricom_min(FLT_MAX),
260 ricom_mutex(), stem_mutex(), counter_mutex(), e_field_mutex(),
261 socket(), file_path(
""),
270 b_vSTEM(false), b_e_mag(false), b_plot_cbed(true), b_plot2SDL(false),
271 b_recompute_detector(false), b_recompute_kernel(false),
274 offset{127.5, 127.5}, com_public{0.0, 0.0},
275 com_map_x(), com_map_y(),
279 nx(256), ny(256), nxy(0),
281 skip_row(1), skip_img(0),
282 n_threads(1), queue_size(64),
283 fr_freq(0.0), fr_count(0.0), fr_count_total(0.0),
284 rescale_ricom(false), rescale_stem(false),
286 srf_ricom(NULL), ricom_cmap(9),
287 srf_stem(NULL), stem_cmap(9),
288 srf_cbed(NULL), cbed_cmap(5),
289 srf_e_mag(NULL), e_mag_cmap(12)
297 template <
typename T>
298 void Ricom::swap_endianess(T &val)
305 val = (val >> 8) | ((val & 0xff) << 8);
308 val = (val >> 24) | ((val & 0xff) << 24) | ((val & 0xff00) << 8) | ((val & 0xff0000) >> 8);
316 template <
typename T>
317 void Ricom::com(std::vector<T> *data, std::array<float, 2> &com)
329 size_t sum_x_temp = 0;
332 T px = data->data()[y_nx + idx];
337 sum_x[idy] = sum_x_temp;
345 com[0] += sum_x[i] *
camera.
v[i];
349 com[1] += sum_y[i] *
camera.
u[i];
351 for (
int i = 0; i < 2; i++)
353 com[i] = (com[i] / dose);
359 template <
typename T>
360 void Ricom::stem(std::vector<T> *data,
size_t id_stem)
363 size_t stem_temp = 0;
371 if (stem_temp > stem_max)
373 stem_max = stem_temp;
376 if (stem_temp < stem_min)
378 stem_min = stem_temp;
387 void Ricom::icom(std::array<float, 2> *com,
int x,
int y)
389 float com_x = (*com)[0] -
offset[0];
390 float com_y = (*com)[1] -
offset[1];
392 int idc = x + y *
nx;
396 update_list.
shift(idr,
id, idc);
415 void Ricom::icom(std::array<float, 2> com,
int x,
int y)
417 float com_x = com[0] -
offset[0];
418 float com_y = com[1] -
offset[1];
420 int idc = x + y *
nx;
424 update_list.
shift(idr,
id, idc);
445 std::lock_guard<std::mutex> lock(ricom_mutex);
446 for (
int y = 0; y <
ny; y++)
448 for (
int x = 0; x <
nx; x++)
450 set_ricom_pixel(x, y);
458 std::lock_guard<std::mutex> lock(ricom_mutex);
459 for (
int y = y0; y <= ye; y++)
461 for (
int x = 0; x <
nx; x++)
463 set_ricom_pixel(x, y);
470 void Ricom::set_ricom_pixel(
int idx,
int idy)
473 int idr = idy *
nx + idx;
474 float val = (
ricom_data[idr] - ricom_min) / (ricom_max - ricom_min);
483 std::lock_guard<std::mutex> lock(stem_mutex);
484 for (
int y = 0; y <
ny; y++)
486 for (
int x = 0; x <
nx; x++)
488 set_stem_pixel(x, y);
496 std::lock_guard<std::mutex> lock(stem_mutex);
497 for (
int y = y0; y <= ye; y++)
499 for (
int x = 0; x <
nx; x++)
501 set_stem_pixel(x, y);
508 std::lock_guard<std::mutex> lock(e_field_mutex);
509 for (
int y = y0; y <= ye; y++)
511 for (
int x = 0; x <
nx; x++)
513 set_e_field_pixel(x, y);
520 std::lock_guard<std::mutex> lock(e_field_mutex);
521 for (
int y = 0; y <
ny; y++)
523 for (
int x = 0; x <
nx; x++)
525 set_e_field_pixel(x, y);
532 void Ricom::set_stem_pixel(
size_t idx,
size_t idy)
535 int idr = idy *
nx + idx;
536 float val = (
stem_data[idr] - stem_min) / (stem_max - stem_min);
544 void Ricom::set_e_field_pixel(
size_t idx,
size_t idy)
547 int idr = idy *
nx + idx;
548 float mag = (abs(
e_field_data[idr]) - e_mag_min) / (e_mag_max - e_mag_min);
556 template <
typename T>
559 float v_min = INFINITY;
562 for (
size_t id = 0;
id < (*cbed_data).size();
id++)
564 T vl = (*cbed_data)[id];
566 float vl_f = log1p((
float)vl);
578 float v_rng = v_max - v_min;
584 float vl_f = cbed_log[iy_t +
camera.
u[iy]];
585 float val = (vl_f - v_min) / v_rng;
593 inline void Ricom::rescales_recomputes()
629 template <
typename T,
class CameraInterface>
632 for (
int si = 0; si < n_skip; si++)
634 camera_fr->read_frame(data,
true);
639 template <
typename T>
640 void Ricom::com_icom(std::vector<T> data,
int ix,
int iy, std::array<float, 2> *com_xy_sum,
ProgressMonitor *p_prog_mon)
642 std::vector<T> *data_ptr = &data;
644 std::array<float, 2> com_xy = {0.0, 0.0};
645 com<T>(data_ptr, com_xy);
646 icom(com_xy, ix, iy);
648 size_t id = iy *
nx + ix;
656 compute_electric_field(com_xy,
id);
659 com_xy_sum->at(0) += com_xy[0];
660 com_xy_sum->at(1) += com_xy[1];
665 counter_mutex.lock();
670 update_surfaces(iy, data_ptr);
673 rescales_recomputes();
674 for (
int i = 0; i < 2; i++)
677 com_xy_sum->at(i) = 0;
681 counter_mutex.unlock();
685 template <
typename T>
686 void Ricom::com_icom(std::vector<T> *data_ptr,
int ix,
int iy, std::array<float, 2> *com_xy_sum,
ProgressMonitor *p_prog_mon)
688 std::array<float, 2> com_xy = {0.0, 0.0};
689 com<T>(data_ptr, com_xy);
690 icom(com_xy, ix, iy);
692 size_t id = iy *
nx + ix;
699 compute_electric_field(com_xy,
id);
701 com_xy_sum->at(0) += com_xy[0];
702 com_xy_sum->at(1) += com_xy[1];
710 update_surfaces(iy, data_ptr);
713 rescales_recomputes();
714 for (
int i = 0; i < 2; i++)
717 com_xy_sum->at(i) = 0;
724 void Ricom::compute_electric_field(std::array<float, 2> &com_xy,
size_t id)
726 float e_mag = std::hypot(com_xy[0] -
offset[0], com_xy[1] -
offset[1]);
727 float e_ang = atan2(com_xy[0] -
offset[0], com_xy[1] -
offset[1]);
728 if (e_mag > e_mag_max)
733 if (e_mag < e_mag_min)
742 template <
typename T,
class CameraInterface>
747 std::vector<T> data(cam_xy);
748 std::vector<T> *p_data = &data;
755 std::array<float, 2> com_xy_sum = {0.0, 0.0};
756 std::array<float, 2> *p_com_xy_sum = &com_xy_sum;
762 for (
int ir = 0; ir <
rep; ir++)
764 reinit_vectors_limits();
765 for (
int iy = 0; iy <
ny; iy++)
767 for (
int ix = 0; ix <
nx; ix++)
774 { com_icom<T>(data, ix, iy, p_com_xy_sum,
p_prog_mon); });
778 com_icom<T>(p_data, ix, iy, p_com_xy_sum,
p_prog_mon);
788 skip_frames(
skip_row, data, camera_spec);
790 skip_frames(
skip_img, data, camera_spec);
804 template <
typename T>
805 void Ricom::update_surfaces(
int iy, std::vector<T> *p_frame)
825 template <
class CameraInterface>
829 std::vector<size_t> dose_map(
nxy);
830 std::vector<size_t> sumx_map(
nxy);
831 std::vector<size_t> sumy_map(
nxy);
832 std::vector<uint16_t> frame(camera_spec->
nx_cam * camera_spec->
ny_cam);
833 std::vector<uint16_t> *p_frame = &frame;
841 std::array<float, 2> com_xy = {0.0, 0.0};
842 std::array<float, 2> *p_com_xy = &com_xy;
843 std::array<float, 2> com_xy_sum = {0.0, 0.0};
851 size_t first_frame = img_num *
nxy;
852 size_t end_frame = (img_num + 1) *
nxy;
853 size_t fr_total_u = (size_t)
fr_total;
858 dose_map.assign(
nxy, 0);
859 sumx_map.assign(
nxy, 0);
860 sumy_map.assign(
nxy, 0);
861 reinit_vectors_limits();
873 camera_spec->read_frame_com_cbed(prog_mon.
fr_count,
874 dose_map, sumx_map, sumy_map,
878 first_frame, end_frame);
883 camera_spec->read_frame_com(prog_mon.
fr_count,
884 dose_map, sumx_map, sumy_map,
887 first_frame, end_frame);
892 if (dose_map[idxx] == 0)
899 com_xy[0] = sumx_map[idxx] / dose_map[idxx];
900 com_xy[1] = sumy_map[idxx] / dose_map[idxx];
904 com_xy_sum[0] += com_xy[0];
905 com_xy_sum[1] += com_xy[1];
908 iy = floor(idxx /
nx);
913 { icom(com_xy, ix, iy); });
917 icom(p_com_xy, ix, iy);
921 compute_electric_field(com_xy, idxx);
927 update_surfaces(iy, p_frame);
930 frame.assign(camera_spec->
nx_cam * camera_spec->
ny_cam, 0);
935 rescales_recomputes();
936 for (
int i = 0; i < 2; i++)
947 if (prog_mon.
fr_count != fr_total_u)
950 first_frame = img_num *
nxy;
951 end_frame = (img_num + 1) *
nxy;
952 reinit_vectors_limits();
953 dose_map.assign(
nxy, 0);
954 sumx_map.assign(
nxy, 0);
955 sumy_map.assign(
nxy, 0);
976 template <
class CameraInterface>
1014 camera_interface.run(
this);
1020 camera_interface.run(
this);
1025 std::cout << std::endl
1026 <<
"Reconstruction finished successfully." << std::endl;
1030 template void Ricom::run_reconstruction<MerlinInterface>(
RICOM::modes);
1031 template void Ricom::run_reconstruction<TimepixInterface>(
RICOM::modes);
1037 void Ricom::reset_limits()
1039 ricom_max = -FLT_MAX;
1040 ricom_min = FLT_MAX;
1041 stem_max = -FLT_MAX;
1045 void Ricom::reinit_vectors_limits()
1059 reinit_vectors_limits();
1065 if (std::filesystem::path(filename).extension() ==
".t3p")
1070 else if (std::filesystem::path(filename).extension() ==
".mib")
1101 std::ofstream run_script(
"run_script.py");
1102 run_script <<
"from merlin_interface.merlin_interface import MerlinInterface" << std::endl;
1103 run_script <<
"m = MerlinInterface(tcp_ip = \"" << ricom->
socket.
ip <<
"\" , tcp_port=" << merlin->com_port <<
")" << std::endl;
1104 run_script <<
"m.hvbias = " << merlin->hvbias << std::endl;
1105 run_script <<
"m.threshold0 = " << merlin->threshold0 << std::endl;
1106 run_script <<
"m.threshold1 = " << merlin->threshold1 << std::endl;
1107 run_script <<
"m.continuousrw = " << (int)merlin->continuousrw << std::endl;
1108 run_script <<
"m.counterdepth = " << ricom->
camera.
depth << std::endl;
1109 run_script <<
"m.acquisitiontime = " << merlin->dwell_time << std::endl;
1110 run_script <<
"m.acquisitionperiod = " << merlin->dwell_time << std::endl;
1111 run_script <<
"m.numframestoacquire = " << m_fr_total + 1 << std::endl;
1112 run_script <<
"m.fileenable = " << (
int)merlin->save << std::endl;
1113 run_script <<
"m.runheadless = " << (int)merlin->headless << std::endl;
1114 run_script <<
"m.fileformat = " << (
int)merlin->raw * 2 << std::endl;
1115 run_script <<
"m.triggerstart = " << merlin->trigger << std::endl;
1116 run_script <<
"m.startacquisition()";
1119 std::string command = python_path +
" run_script.py";
1120 int r = std::system(command.c_str());
1123 std::cout <<
"main::run_connection_script: Cannot execute python run_script. Shell exited with code " << r << std::endl;
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_i
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::array< float, 2 > com_public
bool b_recompute_detector
std::vector< float > stem_data
void draw_e_field_image()
std::vector< float > ricom_data
std::atomic< bool > rescale_ricom
std::vector< std::complex< float > > e_field_data
void run_reconstruction(RICOM::modes mode)
std::vector< float > com_map_x
ProgressMonitor * p_prog_mon
enum CAMERA::Camera_model select_mode_by_file(const char *filename)
void plot_cbed(std::vector< T > *p_data)
std::vector< float > com_map_y
CAMERA::Camera_BASE camera
void process_data(CAMERA::Camera< CameraInterface, CAMERA::FRAME_BASED > *camera)
std::atomic< bool > rescale_e_mag
std::array< float, 2 > offset
std::atomic< bool > rescale_stem
void init(Ricom_kernel kernel, int nx_ricom, int ny_ricom)
std::vector< id_x_y > ids
void shift(id_x_y &id_sft, int id, int shift)
void run_connection_script(Ricom *r, MerlinSettings *merlin, const std::string &python_path)
void run_ricom(Ricom *r, RICOM::modes mode)
void draw_pixel(SDL_Surface *surface, int x, int y, float val, int col_map)