riCOM_cpp
This repository contains the C++ implementation of the riCOM (Real Time Centre Of Mass) algorithm for 4D Scanning electron microscopy.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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