riCOM_cpp
This repository contains the C++ implementation of the riCOM (Real Time Centre Of Mass) algorithm for 4D Scanning electron microscopy.
Ricom.h
Go to the documentation of this file.
1 /* Copyright (C) 2021 Thomas Friedrich, Chu-Ping Yu,
2  * University of Antwerp - All Rights Reserved.
3  * You may use, distribute and modify
4  * this code under the terms of the GPL3 license.
5  * You should have received a copy of the GPL3 license with
6  * this file. If not, please visit:
7  * https://www.gnu.org/licenses/gpl-3.0.en.html
8  *
9  * Authors:
10  * Thomas Friedrich <thomas.friedrich@uantwerpen.be>
11  * Chu-Ping Yu <chu-ping.yu@uantwerpen.be>
12  */
13 
14 #ifndef RICOM_H
15 #define RICOM_H
16 
17 #ifdef _WIN32
18 #include <io.h>
19 #pragma warning(disable : 4005 4333 34)
20 #else
21 #include <unistd.h>
22 #endif
23 
24 #define _USE_MATH_DEFINES
25 #include <cmath>
26 
27 #include <stdio.h>
28 #include <complex>
29 #include <cfloat>
30 #include <vector>
31 #include <string>
32 #include <SDL.h>
33 #include <mutex>
34 #include <future>
35 #include <thread>
36 #include <fftw3.h>
37 #include <chrono>
38 #include <algorithm>
39 
40 #include "BoundedThreadPool.hpp"
41 #include "tinycolormap.hpp"
42 #include "fft2d.hpp"
43 #include "SocketConnector.h"
44 #include "ProgressMonitor.h"
45 #include "MerlinInterface.h"
46 #include "TimepixInterface.h"
47 #include "Camera.h"
48 #include "GuiUtils.h"
49 
50 namespace chc = std::chrono;
51 
53 {
54 public:
55  // Properties
57  bool b_filter;
58  std::array<int, 2> kernel_filter_frequency;
60  int k_area;
61  float rotation;
62  std::vector<float> kernel_x;
63  std::vector<float> kernel_y;
64  std::vector<float> kernel_filter;
65  std::vector<float> f_approx;
66  SDL_Surface *srf_kx;
67  SDL_Surface *srf_ky;
68  // Methods
69  void compute_kernel();
70  void compute_filter();
71  void include_filter();
72  std::vector<int> fftshift_map(int x, int y);
73  // Constructor
75  b_filter(false),
77  k_width_sym(0),
78  k_area(0),
79  rotation(0.0),
80  kernel_x(),
81  kernel_y(),
82  kernel_filter(),
83  f_approx(),
84  srf_kx(), srf_ky()
85  {
87  };
88  void approximate_frequencies(size_t n_im);
89  void draw_surfaces();
90  // Destructor
92 };
93 
95 // Helper class for ricom data indexing //
97 class id_x_y
98 {
99 public:
100  int id;
101  bool valid;
102  id_x_y() : id(0), valid(false){};
103  id_x_y(int id, bool valid);
104 };
105 
107 {
108 private:
109  // Properties
110  Ricom_kernel kernel;
111  int nx;
112  int ny;
113 
114 public:
115  // Properties
116  std::vector<id_x_y> ids;
117  // Methods
118  void init(Ricom_kernel kernel, int nx_ricom, int ny_ricom);
119  inline void shift(id_x_y &id_sft, int id, int shift);
120  // Constructor
121  Update_list() : kernel(), nx(0), ny(0){};
122 };
123 
125 {
126 public:
127  // Properties
128  std::array<float, 2> radius;
129  std::array<float, 2> radius2;
130  std::vector<int> id_list;
131 
132  // Methods
133  void compute_detector(int nx_cam, int ny_cam, std::array<float, 2> &offset);
134  // Constructor
135  Ricom_detector() : radius{0, 0}, radius2{0, 0}, id_list(){};
136  // Destructor
138 };
139 
140 namespace RICOM
141 {
142  enum modes
143  {
145  TCP
146  };
147  void run_ricom(Ricom *r, RICOM::modes mode);
148  void run_connection_script(Ricom *r, MerlinSettings *merlin, const std::string &python_path);
149 }
150 
151 class Ricom
152 {
153 private:
154  // vSTEM Variables
155  float stem_max;
156  float stem_min;
157 
158  // ricom variables
159  std::vector<int> u;
160  std::vector<int> v;
161 
162  Update_list update_list;
163 
164  // Electric field magnitude
165  float e_mag_max;
166  float e_mag_min;
167 
168  // Variables for potting in the SDL2 frame
169  float ricom_max;
170  float ricom_min;
171  std::vector<float> cbed_log;
172 
173  // Thread Synchronization Variables
174  std::mutex ricom_mutex;
175  std::mutex stem_mutex;
176  std::mutex counter_mutex;
177  std::mutex e_field_mutex;
178 
179  // Private Methods - General
180  void init_surface();
181  template <typename T>
182  inline void update_surfaces(int iy, std::vector<T> *p_frame);
183  void reinit_vectors_limits();
184  void reset_limits();
185  void reset_file();
186  void calculate_update_list();
187  inline void rescales_recomputes();
188  template <typename T, class CameraInterface>
189  inline void skip_frames(int n_skip, std::vector<T> &data, CAMERA::Camera<CameraInterface, CAMERA::FRAME_BASED> *camera_fr);
190  template <typename T>
191  inline void swap_endianess(T &val);
192 
193  // Private Methods - riCOM
194  inline void icom(std::array<float, 2> *com, int x, int y);
195  inline void icom(std::array<float, 2> com, int x, int y);
196  template <typename T>
197  inline void com(std::vector<T> *data, std::array<float, 2> &com);
198  template <typename T>
199  void read_com_merlin(std::vector<T> &data, std::array<float, 2> &com);
200  inline void set_ricom_pixel(int idx, int idy);
201  template <typename T>
202  inline void com_icom(std::vector<T> data, int ix, int iy, std::array<float, 2> *com_xy_sum, ProgressMonitor *p_prog_mon);
203  template <typename T>
204  inline void com_icom(std::vector<T> *p_data, int ix, int iy, std::array<float, 2> *com_xy_sum, ProgressMonitor *p_prog_mon);
205 
206  // Private Methods - vSTEM
207  template <typename T>
208  inline void stem(std::vector<T> *data, size_t id_stem);
209  inline void set_stem_pixel(size_t idx, size_t idy);
210 
211  // Private Methods electric field
212  inline void compute_electric_field(std::array<float, 2> &p_com_xy, size_t id);
213  inline void set_e_field_pixel(size_t idx, size_t idy);
214 
215 public:
217  std::string file_path;
222  int last_y;
224  bool b_busy;
226  bool b_vSTEM;
227  bool b_e_mag;
234  std::array<float, 2> offset;
235  std::array<float, 2> com_public;
236  std::vector<float> com_map_x;
237  std::vector<float> com_map_y;
238  std::vector<float> ricom_data;
239  std::vector<float> stem_data;
240  std::vector<std::complex<float>> e_field_data;
241 
242  // Scan Area Variables
243  int nx;
244  int ny;
245  int nxy;
246  int rep;
247  int fr_total;
248  int skip_row;
249  int skip_img;
250 
251  // Variables for progress and performance
255  float fr_freq; // Frequncy per frame
256  float fr_count; // Count all Frames processed in an image
257  float fr_count_total; // Count all Frames in a scanning session
258  std::atomic<bool> rescale_ricom;
259  std::atomic<bool> rescale_stem;
260  std::atomic<bool> rescale_e_mag;
261  bool rc_quit;
262 
263  SDL_Surface *srf_ricom; // Surface for the ricom window;
265  SDL_Surface *srf_stem; // Surface for the vSTEM window;
267  SDL_Surface *srf_cbed; // Surface for the CBED window;
269  SDL_Surface *srf_e_mag; // Surface for the E-Field window;
271 
272  // Public Methods
273  void draw_ricom_image();
274  void draw_ricom_image(int y0, int ye);
275  void draw_stem_image();
276  void draw_stem_image(int y0, int ye);
277  void draw_e_field_image();
278  void draw_e_field_image(int y0, int ye);
279  template <class CameraInterface>
281  void reset();
282  template <typename T>
283  void plot_cbed(std::vector<T> *p_data);
284  template <typename T, class CameraInterface>
286  template <class CameraInterface>
288  enum CAMERA::Camera_model select_mode_by_file(const char *filename);
289 
290  // Constructor
291  Ricom();
292 
293  // Destructor
294  ~Ricom();
295 };
296 
297 #endif // __RICOM_H__
std::array< float, 2 > radius2
Definition: Ricom.h:129
~Ricom_detector()
Definition: Ricom.h:137
std::array< float, 2 > radius
Definition: Ricom.h:128
std::vector< int > id_list
Definition: Ricom.h:130
Ricom_detector()
Definition: Ricom.h:135
void compute_detector(int nx_cam, int ny_cam, std::array< float, 2 > &offset)
Definition: Ricom.cpp:159
~Ricom_kernel()
Definition: Ricom.h:91
int k_area
Definition: Ricom.h:60
Ricom_kernel()
Definition: Ricom.h:74
void include_filter()
Definition: Ricom.cpp:87
std::vector< float > kernel_x
Definition: Ricom.h:62
SDL_Surface * srf_kx
Definition: Ricom.h:66
void compute_kernel()
Definition: Ricom.cpp:21
std::vector< float > kernel_y
Definition: Ricom.h:63
int k_width_sym
Definition: Ricom.h:59
void draw_surfaces()
Definition: Ricom.cpp:128
bool b_filter
Definition: Ricom.h:57
std::vector< float > f_approx
Definition: Ricom.h:65
void approximate_frequencies(size_t n_im)
Definition: Ricom.cpp:111
float rotation
Definition: Ricom.h:61
SDL_Surface * srf_ky
Definition: Ricom.h:67
std::array< int, 2 > kernel_filter_frequency
Definition: Ricom.h:58
std::vector< float > kernel_filter
Definition: Ricom.h:64
void compute_filter()
Definition: Ricom.cpp:66
std::vector< int > fftshift_map(int x, int y)
int kernel_size
Definition: Ricom.h:56
Definition: Ricom.h:152
int skip_img
Definition: Ricom.h:249
std::array< float, 2 > com_public
Definition: Ricom.h:235
SocketConnector socket
Definition: Ricom.h:216
int nxy
Definition: Ricom.h:245
int redraw_interval
Definition: Ricom.h:221
int last_y
Definition: Ricom.h:222
bool b_busy
Definition: Ricom.h:224
int cbed_cmap
Definition: Ricom.h:268
bool b_recompute_detector
Definition: Ricom.h:230
int e_mag_cmap
Definition: Ricom.h:270
int n_threads
Definition: Ricom.h:252
std::vector< float > stem_data
Definition: Ricom.h:239
void draw_stem_image()
Definition: Ricom.cpp:481
void draw_e_field_image()
Definition: Ricom.cpp:518
int rep
Definition: Ricom.h:246
bool update_offset
Definition: Ricom.h:225
bool b_plot2SDL
Definition: Ricom.h:229
std::vector< float > ricom_data
Definition: Ricom.h:238
SDL_Surface * srf_e_mag
Definition: Ricom.h:269
RICOM::modes mode
Definition: Ricom.h:219
std::atomic< bool > rescale_ricom
Definition: Ricom.h:258
float fr_count_total
Definition: Ricom.h:257
int n_threads_max
Definition: Ricom.h:253
float fr_count
Definition: Ricom.h:256
std::vector< std::complex< float > > e_field_data
Definition: Ricom.h:240
std::string file_path
Definition: Ricom.h:217
void draw_ricom_image()
Definition: Ricom.cpp:443
void run_reconstruction(RICOM::modes mode)
Definition: Ricom.cpp:977
int nx
Definition: Ricom.h:243
Ricom_detector detector
Definition: Ricom.h:232
bool rc_quit
Definition: Ricom.h:261
int queue_size
Definition: Ricom.h:254
bool b_e_mag
Definition: Ricom.h:227
SDL_Surface * srf_ricom
Definition: Ricom.h:263
SDL_Surface * srf_cbed
Definition: Ricom.h:267
int fr_total
Definition: Ricom.h:247
std::vector< float > com_map_x
Definition: Ricom.h:236
ProgressMonitor * p_prog_mon
Definition: Ricom.h:223
int ricom_cmap
Definition: Ricom.h:264
enum CAMERA::Camera_model select_mode_by_file(const char *filename)
Definition: Ricom.cpp:1062
void reset()
Definition: Ricom.cpp:1055
bool b_plot_cbed
Definition: Ricom.h:228
float fr_freq
Definition: Ricom.h:255
SDL_Surface * srf_stem
Definition: Ricom.h:265
void plot_cbed(std::vector< T > *p_data)
Definition: Ricom.cpp:557
Ricom()
Definition: Ricom.cpp:255
bool b_recompute_kernel
Definition: Ricom.h:231
std::vector< float > com_map_y
Definition: Ricom.h:237
CAMERA::Camera_BASE camera
Definition: Ricom.h:218
void process_data(CAMERA::Camera< CameraInterface, CAMERA::FRAME_BASED > *camera)
Definition: Ricom.cpp:743
int skip_row
Definition: Ricom.h:248
std::atomic< bool > rescale_e_mag
Definition: Ricom.h:260
bool b_vSTEM
Definition: Ricom.h:226
int ny
Definition: Ricom.h:244
~Ricom()
Definition: Ricom.cpp:294
bool b_print2file
Definition: Ricom.h:220
std::array< float, 2 > offset
Definition: Ricom.h:234
std::atomic< bool > rescale_stem
Definition: Ricom.h:259
int stem_cmap
Definition: Ricom.h:266
Ricom_kernel kernel
Definition: Ricom.h:233
void init(Ricom_kernel kernel, int nx_ricom, int ny_ricom)
Definition: Ricom.cpp:190
std::vector< id_x_y > ids
Definition: Ricom.h:116
Update_list()
Definition: Ricom.h:121
void shift(id_x_y &id_sft, int id, int shift)
Definition: Ricom.cpp:208
Definition: Ricom.h:98
int id
Definition: Ricom.h:100
bool valid
Definition: Ricom.h:101
id_x_y()
Definition: Ricom.h:102
Camera_model
Definition: Camera.h:28
Definition: Ricom.h:141
void run_connection_script(Ricom *r, MerlinSettings *merlin, const std::string &python_path)
Definition: Ricom.cpp:1096
modes
Definition: Ricom.h:143
@ TCP
Definition: Ricom.h:145
@ FILE
Definition: Ricom.h:144
void run_ricom(Ricom *r, RICOM::modes mode)
Definition: Ricom.cpp:1081