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