riCOM_cpp
This repository contains the C++ implementation of the riCOM (Real Time Centre Of Mass) algorithm for 4D Scanning electron microscopy.
RunCLI.cpp
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 #include <string>
15 #include <thread>
16 
17 #include "Ricom.h"
18 #include "SdlImageWindow.h"
19 #include "GuiUtils.h"
20 
21 int run_cli(int argc, char *argv[], Ricom *ricom, CAMERA::Default_configurations &hardware_configurations)
22 {
23  ricom->b_plot_cbed = false;
24  std::string save_img = "";
25  std::string save_dat = "";
26 
27  // command line arguments
28  for (int i = 1; i < argc; i++)
29  {
30  if (i + 1 != argc)
31  {
32  // Set filename to read from .mib file
33  if (strcmp(argv[i], "-filename") == 0)
34  {
35  ricom->camera = hardware_configurations[ricom->select_mode_by_file(argv[i + 1])];
36  i++;
37  }
38  // Set IP of camera for TCP connection
39  if (strcmp(argv[i], "-ip") == 0)
40  {
41  ricom->socket.ip = argv[i + 1];
42  ricom->mode = RICOM::TCP;
43  i++;
44  }
45  // Set port data-read port of camera
46  if (strcmp(argv[i], "-port") == 0)
47  {
48  ricom->socket.port = std::stoi(argv[i + 1]);
49  ricom->mode = RICOM::TCP;
50  i++;
51  }
52  // Set width of image
53  if (strcmp(argv[i], "-nx") == 0)
54  {
55  ricom->nx = std::stoi(argv[i + 1]);
56  i++;
57  }
58  // Set height of image
59  if (strcmp(argv[i], "-ny") == 0)
60  {
61  ricom->ny = std::stoi(argv[i + 1]);
62  i++;
63  }
64  // Set width of camera
65  if (strcmp(argv[i], "-cam_nx") == 0)
66  {
67  ricom->camera.nx_cam = std::stoi(argv[i + 1]);
68  ricom->offset[0] = ((float)ricom->camera.nx_cam - 1) / 2;
69  i++;
70  }
71  // Set height of camera
72  if (strcmp(argv[i], "-cam_ny") == 0)
73  {
74  ricom->camera.ny_cam = std::stoi(argv[i + 1]);
75  ricom->offset[1] = ((float)ricom->camera.ny_cam - 1) / 2;
76  i++;
77  }
78  // Set skip per row
79  if (strcmp(argv[i], "-skipr") == 0)
80  {
81  ricom->skip_row = std::stoi(argv[i + 1]);
82  i++;
83  }
84  // Set skip per image
85  if (strcmp(argv[i], "-skipi") == 0)
86  {
87  ricom->skip_img = std::stoi(argv[i + 1]);
88  i++;
89  }
90  // Set kernel size
91  if (strcmp(argv[i], "-k") == 0)
92  {
93  ricom->kernel.kernel_size = std::stoi(argv[i + 1]);
94  i++;
95  }
96  // Set CBED Rotation
97  if (strcmp(argv[i], "-r") == 0)
98  {
99  ricom->kernel.rotation = std::stof(argv[i + 1]);
100  i++;
101  }
102  // Set CBED center offset
103  if (strcmp(argv[i], "-offset") == 0)
104  {
105  ricom->offset[0] = std::stof(argv[i + 1]);
106  i++;
107  ricom->offset[1] = std::stof(argv[i + 1]);
108  i++;
109  }
110  // Set CBED center offset
111  if (strcmp(argv[i], "-update_offset") == 0)
112  {
113  ricom->update_offset = (bool)std::stoi(argv[i + 1]);
114  i++;
115  }
116  // Set STEM radii
117  if (strcmp(argv[i], "-radius") == 0)
118  {
119  ricom->b_vSTEM = true;
120  ricom->detector.radius[0] = std::stof(argv[i + 1]);
121  i++;
122  ricom->detector.radius[1] = std::stof(argv[i + 1]);
123  i++;
124  }
125  // Set kernel filter
126  if (strcmp(argv[i], "-f") == 0)
127  {
128  ricom->kernel.b_filter = true;
129  ricom->kernel.kernel_filter_frequency[0] = std::stoi(argv[i + 1]);
130  i++;
131  ricom->kernel.kernel_filter_frequency[1] = std::stoi(argv[i + 1]);
132  i++;
133  }
134  // Set depth of pixel for raw mode
135  if (strcmp(argv[i], "-depth") == 0)
136  {
137  ricom->camera.depth = std::stoi(argv[i + 1]);
138  ricom->camera.model = CAMERA::MERLIN;
139  i++;
140  }
141  // Set number of repetitions
142  if (strcmp(argv[i], "-rep") == 0)
143  {
144  ricom->rep = std::stoi(argv[i + 1]);
145  i++;
146  }
147  // Set Dwell Time
148  if (strcmp(argv[i], "-dwell_time") == 0)
149  {
150  ricom->camera.dwell_time = std::stof(argv[i + 1]);
151  ricom->camera.model = CAMERA::TIMEPIX;
152  i++;
153  }
154  // Set Number of threads
155  if (strcmp(argv[i], "-threads") == 0)
156  {
157  ricom->n_threads = std::stoi(argv[i + 1]);
158  i++;
159  }
160  // Set Number queue size
161  if (strcmp(argv[i], "-queue_size") == 0)
162  {
163  ricom->queue_size = std::stoi(argv[i + 1]);
164  i++;
165  }
166  // Set redraw interval in ms
167  if (strcmp(argv[i], "-redraw_interval") == 0)
168  {
169  ricom->redraw_interval = std::stoi(argv[i + 1]);
170  ricom->b_plot2SDL = true;
171  i++;
172  }
173  // Set path to save reconstruction image
174  if (strcmp(argv[i], "-save_img_path") == 0)
175  {
176  save_img = argv[i + 1];
177  ricom->b_plot2SDL = true;
178  i++;
179  }
180  // Set path to save reconstruction data
181  if (strcmp(argv[i], "-save_data_path") == 0)
182  {
183  save_dat = argv[i + 1];
184  i++;
185  }
186  // plot electric field
187  if (strcmp(argv[i], "-plot_e_field") == 0)
188  {
189  ricom->b_e_mag = (bool)std::stoi(argv[i + 1]);
190  i++;
191  }
192  }
193  }
194 
195  if (ricom->b_plot2SDL)
196  {
197  std::vector<SdlImageWindow> image_windows;
198  std::thread run_thread;
199  run_thread = std::thread(RICOM::run_ricom, ricom, ricom->mode);
200  while (ricom->srf_ricom == NULL)
201  {
202  SDL_Delay(ricom->redraw_interval);
203  }
204 
205  run_thread.detach();
206 
207  // // Initializing SDL
208  SDL_DisplayMode DM; // To get the current display size
209  SDL_Event event; // Event variable
210 
211  SDL_Init(SDL_INIT_EVERYTHING);
212  SDL_GetCurrentDisplayMode(0, &DM);
213  float scale = (std::min)(((float)DM.w) / ricom->nx, ((float)DM.h) / ricom->ny) * 0.8;
214  bool b_redraw = false;
215  image_windows.push_back(SdlImageWindow("riCOM", ricom->srf_ricom, ricom->nx, ricom->ny, scale));
216  if (ricom->b_vSTEM)
217  {
218  image_windows.push_back(SdlImageWindow("vSTEM", ricom->srf_stem, ricom->nx, ricom->ny, scale));
219  }
220  if (ricom->b_e_mag)
221  {
222  image_windows.push_back(SdlImageWindow("E-Field", ricom->srf_e_mag, ricom->nx, ricom->ny, scale));
223  }
224 
225  bool b_open_window = true;
226  while (b_open_window)
227  {
228  if (ricom->p_prog_mon != nullptr)
229  {
230  if (ricom->p_prog_mon->report_set_public)
231  {
232  b_redraw = true;
233  ricom->p_prog_mon->report_set_public = false;
234  }
235  else
236  {
237  b_redraw = true;
238  }
239  }
240 
241  if (b_redraw)
242  {
243  for (auto &wnd : image_windows)
244  {
245  wnd.update_image();
246  }
247  }
248 
249  while (SDL_PollEvent(&event))
250  {
251  if (event.type == SDL_QUIT ||
252  (event.type == SDL_WINDOWEVENT &&
253  event.window.event == SDL_WINDOWEVENT_CLOSE))
254  {
255  ricom->rc_quit = true;
256  SDL_Delay(ricom->redraw_interval);
257  b_open_window = false;
258  }
259  }
260  }
261  }
262  else
263  {
264  RICOM::run_ricom(ricom, ricom->mode);
265  }
266  if (save_dat != "")
267  {
268  save_numpy(&save_dat, ricom->nx, ricom->ny, &ricom->ricom_data);
269  std::cout << "riCOM reconstruction data saved as " + save_dat << std::endl;
270  }
271  if (save_img != "")
272  {
273  save_image(&save_img, ricom->srf_ricom);
274  std::cout << "riCOM reconstruction image saved as " + save_img << std::endl;
275  }
276  return 0;
277 }
void save_numpy(std::string *path, int nx, int ny, std::vector< T > *data)
Definition: GuiUtils.cpp:17
void save_image(std::string *path, SDL_Surface *sdl_srf)
Definition: GuiUtils.cpp:30
int run_cli(int argc, char *argv[], Ricom *ricom, CAMERA::Default_configurations &hardware_configurations)
Definition: RunCLI.cpp:21
Camera_model model
Definition: Camera.h:43
std::atomic< bool > report_set_public
std::array< float, 2 > radius
Definition: Ricom.h:128
bool b_filter
Definition: Ricom.h:57
float rotation
Definition: Ricom.h:61
std::array< int, 2 > kernel_filter_frequency
Definition: Ricom.h:58
int kernel_size
Definition: Ricom.h:56
Definition: Ricom.h:152
int skip_img
Definition: Ricom.h:249
SocketConnector socket
Definition: Ricom.h:216
int redraw_interval
Definition: Ricom.h:221
int n_threads
Definition: Ricom.h:252
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
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
ProgressMonitor * p_prog_mon
Definition: Ricom.h:223
enum CAMERA::Camera_model select_mode_by_file(const char *filename)
Definition: Ricom.cpp:1062
bool b_plot_cbed
Definition: Ricom.h:228
SDL_Surface * srf_stem
Definition: Ricom.h:265
CAMERA::Camera_BASE camera
Definition: Ricom.h:218
int skip_row
Definition: Ricom.h:248
bool b_vSTEM
Definition: Ricom.h:226
int ny
Definition: Ricom.h:244
std::array< float, 2 > offset
Definition: Ricom.h:234
Ricom_kernel kernel
Definition: Ricom.h:233
std::string ip
@ TIMEPIX
Definition: Camera.h:30
@ MERLIN
Definition: Camera.h:29
@ TCP
Definition: Ricom.h:145
void run_ricom(Ricom *r, RICOM::modes mode)
Definition: Ricom.cpp:1081