riCOM_cpp
This repository contains the C++ implementation of the riCOM (Real Time Centre Of Mass) algorithm for 4D Scanning electron microscopy.
Loading...
Searching...
No Matches
Functions
main.cpp File Reference
#include <string>
#include "Ricom.h"
#include "Camera.h"
Include dependency graph for main.cpp:

Go to the source code of this file.

Functions

int run_cli (int argc, char *argv[], Ricom *ricom, CAMERA::Default_configurations &hardware_configurations)
 
int run_gui (Ricom *ricom, CAMERA::Default_configurations &hardware_configurations)
 
void log2file (Ricom *ricom)
 
std::string get_os ()
 
int main (int argc, char *argv[])
 

Function Documentation

◆ get_os()

std::string get_os ( )

Definition at line 59 of file main.cpp.

59{return "Unknown"};

◆ log2file()

void log2file ( Ricom ricom)

Definition at line 83 of file main.cpp.

84{
85 if (freopen("ricom.log", "a", stdout) == NULL)
86 {
87 std::cout << "Error redirecting output to log file" << std::endl;
88 }
89 if (freopen("ricom.log", "a", stderr) == NULL)
90 {
91 std::cout << "Error redirecting error output to log file" << std::endl;
92 }
93 ricom->b_print2file = true;
94 auto t = std::time(nullptr);
95 auto tm = *std::localtime(&t);
96 std::cout << std::endl;
97 std::cout << "Ricom version " << version << " started at " << std::put_time(&tm, "%d/%m/%Y %H:%M:%S") << std::endl;
98 std::cout << "OS: " << get_os() << std::endl;
99}
bool b_print2file
Definition Ricom.h:220
std::string get_os()
Definition main.cpp:59

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 62 of file main.cpp.

63{
64
65 Ricom ricom;
66 CAMERA::Default_configurations hardware_configurations;
67
68 if (argc == 1)
69 {
70#ifdef _WIN32
71 FreeConsole();
72#endif
73 log2file(&ricom);
74 return run_gui(&ricom, hardware_configurations);
75 }
76 else
77 {
78 return run_cli(argc, argv, &ricom, hardware_configurations);
79 }
80}
Definition Ricom.h:152
int run_gui(Ricom *ricom, CAMERA::Default_configurations &hardware_configurations)
Definition RunGUI.cpp:68
int run_cli(int argc, char *argv[], Ricom *ricom, CAMERA::Default_configurations &hardware_configurations)
Definition RunCLI.cpp:21
void log2file(Ricom *ricom)
Definition main.cpp:83

◆ run_cli()

int run_cli ( int  argc,
char *  argv[],
Ricom ricom,
CAMERA::Default_configurations hardware_configurations 
)

Definition at line 21 of file RunCLI.cpp.

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]);
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
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
int skip_img
Definition Ricom.h:250
SocketConnector socket
Definition Ricom.h:216
int redraw_interval
Definition Ricom.h:221
int n_threads
Definition Ricom.h:253
int rep
Definition Ricom.h:247
bool update_offset
Definition Ricom.h:225
bool b_plot2SDL
Definition Ricom.h:230
std::vector< float > ricom_data
Definition Ricom.h:239
SDL_Surface * srf_e_mag
Definition Ricom.h:270
RICOM::modes mode
Definition Ricom.h:219
int nx
Definition Ricom.h:244
Ricom_detector detector
Definition Ricom.h:233
bool rc_quit
Definition Ricom.h:262
int queue_size
Definition Ricom.h:255
bool b_e_mag
Definition Ricom.h:227
SDL_Surface * srf_ricom
Definition Ricom.h:264
ProgressMonitor * p_prog_mon
Definition Ricom.h:223
enum CAMERA::Camera_model select_mode_by_file(const char *filename)
Definition Ricom.cpp:1070
bool b_plot_cbed
Definition Ricom.h:228
SDL_Surface * srf_stem
Definition Ricom.h:266
CAMERA::Camera_BASE camera
Definition Ricom.h:218
int skip_row
Definition Ricom.h:249
bool b_vSTEM
Definition Ricom.h:226
int ny
Definition Ricom.h:245
std::array< float, 2 > offset
Definition Ricom.h:235
Ricom_kernel kernel
Definition Ricom.h:234
@ 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:1089

◆ run_gui()

int run_gui ( Ricom ricom,
CAMERA::Default_configurations hardware_configurations 
)

Definition at line 68 of file RunGUI.cpp.

69{
70 std::thread run_thread;
71 std::thread py_thread;
72 if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
73 {
74 printf("Error: %s\n", SDL_GetError());
75 return -1;
76 }
77
78 // Decide GL+GLSL versions
79#if defined(IMGUI_IMPL_OPENGL_ES2)
80 // GL ES 2.0 + GLSL 100
81 const char *glsl_version = "#version 100";
82 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
83 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
84 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
85 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
86#elif defined(__APPLE__)
87 // GL 3.2 Core + GLSL 150
88 const char *glsl_version = "#version 150";
89 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); // Always required on Mac
90 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
91 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
92 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
93#else
94 // GL 3.0 + GLSL 130
95 const char *glsl_version = "#version 130";
96 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
97 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
98 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
99 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
100#endif
101
102 // Create window with graphics context
103 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
104 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
105 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
106 SDL_Window *window = SDL_CreateWindow("riCOM", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1200, 800, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL);
107 if (window == NULL)
108 {
109 std::cout << "Window could not be created! SDL Error: " << SDL_GetError() << std::endl;
110 }
111 SDL_GLContext gl_context = SDL_GL_CreateContext(window);
112 SDL_GL_MakeCurrent(window, gl_context);
113 SDL_GL_SetSwapInterval(1); // Enable vsync
114
115 // Setup Dear ImGui context
116 IMGUI_CHECKVERSION();
117 ImGui::CreateContext();
118 ImGuiIO &io = ImGui::GetIO();
119 (void)io;
120
121 mINI::INIFile ini_file("imgui.ini");
122 mINI::INIStructure ini_cfg;
123 ini_file.read(ini_cfg);
124
125 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
126 // Setup Platform/Renderer backends
127 ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
128 ImGui_ImplOpenGL3_Init(glsl_version);
129
130 io.Fonts->AddFontFromMemoryCompressedTTF(KarlaRegular_compressed_data, KarlaRegular_compressed_size, 14.0f);
131 io.Fonts->AddFontFromMemoryCompressedTTF(RobotoMedium_compressed_data, RobotoMedium_compressed_size, 14.0f);
132 io.Fonts->AddFontFromMemoryCompressedTTF(CousineRegular_compressed_data, CousineRegular_compressed_size, 14.0f);
133 io.Fonts->AddFontFromMemoryCompressedTTF(DroidSans_compressed_data, DroidSans_compressed_size, 14.0f);
134 io.Fonts->AddFontFromMemoryCompressedTTF(ProggyClean_compressed_data, ProggyClean_compressed_size, 14.0f);
135 io.Fonts->AddFontFromMemoryCompressedTTF(ProggyTiny_compressed_data, ProggyTiny_compressed_size, 14.0f);
136
137 io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
138 io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
139 // Multi-Viewport not yet supported with SDL2
140 // io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;// Enable Multi-Viewport / Platform Windows
141
142 ImVec2 uv_min = ImVec2(0.0f, 0.0f); // Top-left
143 ImVec2 uv_max = ImVec2(1.0f, 1.0f); // Lower-right
144 ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint
145 ImVec4 border_col = ImVec4(1.0f, 1.0f, 1.0f, 0.5f); // 50% opaque white
146
147 ImVec2 menu_bar_size;
148 ImVec2 control_menu_size(200, 800);
149
150 const size_t n_textures = 16;
151 GLuint uiTextureIDs[n_textures];
152 glGenTextures(n_textures, uiTextureIDs);
153
154 for (size_t i = 0; i < n_textures; i++)
155 {
156 glBindTexture(GL_TEXTURE_2D, uiTextureIDs[i]);
157 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
158 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
159 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
160 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
161 }
162
163 // create a file browser instances
164 ImGui::FileBrowser openFileDialog;
165 openFileDialog.SetTitle("Open .mib or .t3p file");
166 openFileDialog.SetTypeFilters({".mib", ".t3p"});
167 ImGui::FileBrowser saveFileDialog(ImGuiFileBrowserFlags_EnterNewFilename | ImGuiFileBrowserFlags_CreateNewDir);
168 saveFileDialog.SetTitle("Save image as .png");
169 ImGui::FileBrowser saveDataDialog(ImGuiFileBrowserFlags_EnterNewFilename | ImGuiFileBrowserFlags_CreateNewDir);
170 saveDataDialog.SetTitle("Save COM data in binary format");
171 std::string filename = "";
172
173 // Main loop conditional flags
174 bool b_done = false;
175 bool b_merlin_live_menu = true;
176 bool b_acq_open = false;
177 bool b_started = false;
178 bool b_file_selected = false;
179 bool b_restarted = false;
180 bool b_show_kernel = false;
181 bool b_show_frequencies = true;
182
183 // Merlin Settings (to send to the Camera)
184 struct MerlinSettings merlin_settings;
185
186 // INI file settings to restore previous session settings
187 // Appearance
188 int font_index = 0;
189 int style_index = 0;
190 ImGuiINI::check_ini_setting(ini_cfg, "Appearance", "CBED Colormap", ricom->cbed_cmap);
191 ImGuiINI::check_ini_setting(ini_cfg, "Appearance", "Font", font_index);
192 ImGuiINI::set_font(font_index);
193 ImGuiINI::check_ini_setting(ini_cfg, "Appearance", "Style", style_index);
194 ImGuiINI::set_style(style_index);
195 ImGuiINI::check_ini_setting(ini_cfg, "Appearance", "Show Kernel", b_show_kernel);
196 ImGuiINI::check_ini_setting(ini_cfg, "Appearance", "Show Frequencies", b_show_frequencies);
197 // Hardware Settings
198 std::string python_path;
199#ifdef _WIN32
200 python_path = "py";
201#else
202 python_path = "python3";
203#endif
204 ImGuiINI::check_ini_setting(ini_cfg, "Hardware", "Threads", ricom->n_threads);
205 ImGuiINI::check_ini_setting(ini_cfg, "Hardware", "Queue Size", ricom->queue_size);
206 ImGuiINI::check_ini_setting(ini_cfg, "Hardware", "Image Refresh Interval [ms]", ricom->redraw_interval);
207 // Merlin Settings
208 ImGuiINI::check_ini_setting(ini_cfg, "Merlin", "Live Interface Menu", b_merlin_live_menu);
209 ImGuiINI::check_ini_setting(ini_cfg, "Merlin", "nx", hardware_configurations[CAMERA::MERLIN].nx_cam);
210 ImGuiINI::check_ini_setting(ini_cfg, "Merlin", "ny", hardware_configurations[CAMERA::MERLIN].ny_cam);
211 ImGuiINI::check_ini_setting(ini_cfg, "Merlin", "com_port", merlin_settings.com_port);
212 ImGuiINI::check_ini_setting(ini_cfg, "Merlin", "data_port", ricom->socket.port);
213 ImGuiINI::check_ini_setting(ini_cfg, "Merlin", "ip", ricom->socket.ip);
214 ImGuiINI::check_ini_setting(ini_cfg, "Merlin", "python_path", python_path);
215 // Timepix Settings
216 ImGuiINI::check_ini_setting(ini_cfg, "Timepix", "nx", hardware_configurations[CAMERA::MERLIN].nx_cam);
217 ImGuiINI::check_ini_setting(ini_cfg, "Timepix", "ny", hardware_configurations[CAMERA::MERLIN].ny_cam);
218
219 const char *cmaps[] = {"Parula", "Heat", "Jet", "Turbo", "Hot", "Gray", "Magma", "Inferno", "Plasma", "Viridis", "Cividis", "Github", "HSV"};
220 bool b_redraw = false;
221 bool b_trigger_update = false;
222 float menu_split_v = control_menu_size.y * 0.8f;
223
224 // Initialize Frequency approximation (for plotting only)
225 ricom->kernel.approximate_frequencies((size_t)ricom->nx);
226
227 // Initialize all possible Windows, so everything is on the stack
228 bool show_com_x = false;
229 bool show_com_y = false;
230 bool ricom_fft = false;
231 bool vstem_fft = false;
232 bool e_field_fft = false;
234 std::map<std::string, ImGuiImageWindow<float>> generic_windows_f;
235 std::map<std::string, ImGuiImageWindow<std::complex<float>>> generic_windows_c;
236 generic_windows_f.emplace("RICOM", ImGuiImageWindow<float>("RICOM", &uiTextureIDs[1], true, 9, common_flags | GIM_Flags::FftButton));
237 generic_windows_f.emplace("RICOM-FFT", ImGuiImageWindow<float>("RICOM-FFT", &uiTextureIDs[2], false, 4, common_flags, &ricom_fft));
238 GENERIC_WINDOW("RICOM").fft_window = &GENERIC_WINDOW("RICOM-FFT");
239
240 generic_windows_f.emplace("vSTEM", ImGuiImageWindow<float>("vSTEM", &uiTextureIDs[3], true, 9, common_flags | GIM_Flags::FftButton, &ricom->b_vSTEM));
241 generic_windows_f.emplace("vSTEM-FFT", ImGuiImageWindow<float>("vSTEM-FFT", &uiTextureIDs[4], false, 4, common_flags, &vstem_fft));
242 GENERIC_WINDOW("vSTEM").fft_window = &GENERIC_WINDOW("vSTEM-FFT");
243
244 generic_windows_f.emplace("COM-X", ImGuiImageWindow<float>("RICOM-COMX", &uiTextureIDs[5], true, 9, common_flags, &show_com_x));
245 generic_windows_f.emplace("COM-Y", ImGuiImageWindow<float>("RICOM-COMY", &uiTextureIDs[6], true, 9, common_flags, &show_com_y));
246
247 generic_windows_c.emplace("E-FIELD", ImGuiImageWindow<std::complex<float>>("E-Field", &uiTextureIDs[7], true, 12, common_flags | GIM_Flags::FftButton, &ricom->b_e_mag));
248 generic_windows_f.emplace("E-Field-FFT", ImGuiImageWindow<float>("E-Field-FFT", &uiTextureIDs[8], false, 4, common_flags, &e_field_fft));
249 GENERIC_WINDOW_C("E-FIELD").fft_window = &GENERIC_WINDOW("E-Field-FFT");
250
251 // Initial draw of the Kernel surfaces
252 ricom->kernel.draw_surfaces();
253 bind_tex(ricom->kernel.srf_kx, uiTextureIDs[9]);
254 bind_tex(ricom->kernel.srf_ky, uiTextureIDs[10]);
255
256 ImGuiID dock_id = 3775;
257 Main_Dock main_dock(dock_id);
258
259 // Main loop
260 while (!b_done)
261 {
262 // Poll and handle events (inputs, window resize, etc.)
263 SDL_Event event;
264 while (SDL_PollEvent(&event))
265 {
266 ImGui_ImplSDL2_ProcessEvent(&event);
267 if (event.type == SDL_QUIT)
268 b_done = true;
269 if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
270 b_done = true;
271 }
272
273 // Start the Dear ImGui frame
274 ImGui_ImplOpenGL3_NewFrame();
275 ImGui_ImplSDL2_NewFrame();
276 ImGui::NewFrame();
277
278 // Menu
279 if (ImGui::BeginMainMenuBar())
280 {
281 if (ImGui::BeginMenu("Appearance"))
282 {
283 ImGui::Combo("CBED Colormap", &ricom->cbed_cmap, cmaps, IM_ARRAYSIZE(cmaps));
284 ImGuiINI::ShowFontSelector("Font", font_index, ini_cfg);
285 ImGuiINI::ShowStyleSelector("Style", style_index, ini_cfg);
286 ImGui::Checkbox("Show Kernel", &b_show_kernel);
287 ImGui::Checkbox("Show Frequencies", &b_show_frequencies);
288 ImGui::EndMenu();
289 }
290 if (ImGui::BeginMenu("Hardware Settings"))
291 {
292 ImGui::Text("Plotting");
293 if (ImGui::DragInt("Image Refresh Interval [ms]", &ricom->redraw_interval, 20, 10, 1000))
294 {
295 ini_cfg["Hardware"]["Image Refresh Interval [ms]"] = std::to_string(ricom->redraw_interval);
296 }
297 ImGui::Separator();
298
299 ImGui::Text("Multithreading");
300 if (ImGui::DragInt("Threads", &ricom->n_threads, 1, 1, *&ricom->n_threads_max))
301 {
302 ini_cfg["Hardware"]["Threads"] = std::to_string(ricom->n_threads);
303 }
304 if (ImGui::DragInt("Queue Size", &ricom->queue_size, 1, 1, 256))
305 {
306 ini_cfg["Hardware"]["Queue Size"] = std::to_string(ricom->queue_size);
307 }
308 ImGui::Separator();
309
310 ImGui::Text("Merlin Camera");
311 if (ImGui::Checkbox("Live Interface Menu", &b_merlin_live_menu))
312 {
313 ini_cfg["Merlin"]["Live Interface Menu"] = std::to_string(b_merlin_live_menu);
314 }
315 if (ImGui::DragInt("nx Merlin", &hardware_configurations[CAMERA::MERLIN].nx_cam, 1, 1, 2048))
316 {
317 ini_cfg["Merlin"]["nx"] = std::to_string(hardware_configurations[CAMERA::MERLIN].nx_cam);
318 }
319 if (ImGui::DragInt("ny Merlin", &hardware_configurations[CAMERA::MERLIN].ny_cam, 1, 1, 2048))
320 {
321 ini_cfg["Merlin"]["ny"] = std::to_string(hardware_configurations[CAMERA::MERLIN].ny_cam);
322 }
323 if (ImGui::InputText("IP", &ricom->socket.ip))
324 {
325 ini_cfg["Merlin"]["ip"] = ricom->socket.ip;
326 }
327 if (ImGui::InputInt("COM-Port", &merlin_settings.com_port, 8))
328 {
329 ini_cfg["Merlin"]["com_port"] = std::to_string(ricom->socket.port);
330 }
331 if (ImGui::InputInt("Data-Port", &ricom->socket.port, 8))
332 {
333 ini_cfg["Merlin"]["data_port"] = std::to_string(ricom->socket.port);
334 }
335 if (ImGui::InputText("python path", &python_path))
336 {
337 ini_cfg["Merlin"]["python path"] = python_path;
338 }
339 ImGui::Separator();
340
341 ImGui::Text("Timepix Camera");
342 // ImGui::Checkbox("Live Interface Menu", &b_timepix_live_menu);
343 if (ImGui::DragInt("nx Timepix", &hardware_configurations[CAMERA::TIMEPIX].nx_cam, 1, 1, 2048))
344 {
345 ini_cfg["Timepix"]["nx"] = std::to_string(hardware_configurations[CAMERA::TIMEPIX].nx_cam);
346 }
347 if (ImGui::DragInt("ny Timepix", &hardware_configurations[CAMERA::TIMEPIX].ny_cam, 1, 1, 2048))
348 {
349 ini_cfg["Timepix"]["ny"] = std::to_string(hardware_configurations[CAMERA::TIMEPIX].ny_cam);
350 }
351 ImGui::EndMenu();
352 }
353 if (ImGui::BeginMenu("Additional Imaging Modes"))
354 {
355 if (ImGui::Checkbox("Show CoM-X", &show_com_x))
356 {
357 if (show_com_x)
358 {
359 GENERIC_WINDOW("COM-X").set_data(ricom->nx, ricom->ny, &ricom->com_map_x);
360 }
361 else
362 {
363 *GENERIC_WINDOW("COM-X").pb_open = false;
364 }
365 }
366 if (ImGui::Checkbox("Show CoM-Y", &show_com_y))
367 {
368 if (show_com_y)
369 {
370 GENERIC_WINDOW("COM-Y").set_data(ricom->nx, ricom->ny, &ricom->com_map_y);
371 }
372 else
373 {
374 *GENERIC_WINDOW("COM-Y").pb_open = false;
375 }
376 }
377 if (ImGui::Checkbox("Show E-Field", &ricom->b_e_mag))
378 {
379 if (ricom->b_e_mag)
380 {
381 GENERIC_WINDOW_C("E-FIELD").set_data(ricom->nx, ricom->ny, &ricom->e_field_data);
382 }
383 else
384 {
385 *GENERIC_WINDOW_C("E-FIELD").pb_open = false;
386 }
387 }
388 if (ImGui::Checkbox("View vSTEM Image", &ricom->b_vSTEM))
389 {
390 if (ricom->b_vSTEM)
391 {
392 GENERIC_WINDOW("vSTEM").set_data(ricom->nx, ricom->ny, &ricom->stem_data);
393 }
394 else
395 {
396 *GENERIC_WINDOW("vSTEM").pb_open = false;
397 }
398 }
399 ImGui::EndMenu();
400 }
401 menu_bar_size = ImGui::GetWindowSize();
402 ImGui::EndMainMenuBar();
403 }
404
405 const ImGuiViewport *viewport = ImGui::GetMainViewport();
406 if (ricom->p_prog_mon != nullptr)
407 {
408 if (ricom->p_prog_mon->report_set_public)
409 {
410 b_redraw = true;
411 ricom->p_prog_mon->report_set_public = false;
412 }
413 }
414 else
415 {
416 b_redraw = true;
417 }
418
419 ImVec2 pos = viewport->Pos;
420 pos[1] += menu_bar_size.y;
421 ImGui::SetNextWindowPos(pos);
422
423 control_menu_size.y = viewport->Size.y - menu_bar_size.y;
424 ImGui::SetNextWindowSize(control_menu_size);
425 ImGui::SetNextWindowSizeConstraints(ImVec2(0, -1), ImVec2(FLT_MAX, -1));
426
427 ImGui::Begin("Navigation", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar);
428
429 bool b_nx_changed = false;
430 ImGui::BeginChild("Controls", ImVec2(0, menu_split_v), false);
431 if (ImGui::CollapsingHeader("General Settings", ImGuiTreeNodeFlags_DefaultOpen))
432 {
433 ImGui::Text("Scan Area");
434 b_nx_changed = ImGui::DragInt("nx", &ricom->nx, 1, 1, SDL_MAX_SINT32);
435 ImGui::DragInt("ny", &ricom->ny, 1, 1, SDL_MAX_SINT32);
436 ImGui::DragInt("Repetitions", &ricom->rep, 1, 1, SDL_MAX_SINT32);
437 ImGui::BeginGroup();
438 ImGui::DragInt("skip row", &ricom->skip_row, 1, 0, SDL_MAX_SINT32);
439 ImGui::DragInt("skip img", &ricom->skip_img, 1, 0, SDL_MAX_SINT32);
440 ImGui::EndGroup();
441 if (ImGui::IsItemHovered())
442 {
443 ImGui::SetTooltip("Adjustments for Flyback time:\n skip row: skip n frames after each scan line\n skip img: skip n frames after each scan (when using repetitions)");
444 }
445
446 ImGui::Text("CBED Centre");
447 int *max_nx = (std::max)(&ricom->camera.nx_cam, &ricom->camera.ny_cam);
448 bool offset_changed = ImGui::DragFloat2("Centre", &ricom->offset[0], 0.1f, 0.0, (float)*max_nx);
449 if (offset_changed)
450 {
451 ricom->b_recompute_detector = true;
452 ricom->b_recompute_kernel = true;
453 }
454 ImGui::Checkbox("Auto Centering", &ricom->update_offset);
455 }
456
457 if (ImGui::CollapsingHeader("RICOM Settings", ImGuiTreeNodeFlags_DefaultOpen))
458 {
459 static int filter_max = 8;
460 static bool init_kernel_img = true;
461 bool kernel_changed = ImGui::DragInt("Kernel Size", &ricom->kernel.kernel_size, 1, 1, 300);
462 if (kernel_changed)
463 filter_max = ceil(sqrt(pow(ricom->kernel.kernel_size, 2) * 2));
464 bool rot_changed = ImGui::SliderFloat("Rotation", &ricom->kernel.rotation, 0.0f, 360.0f, "%.1f deg");
465 bool filter_changed = ImGui::Checkbox("Use filter?", &ricom->kernel.b_filter);
466 bool filter_changed2 = ImGui::DragInt2("low / high", &ricom->kernel.kernel_filter_frequency[0], 1, 0, filter_max);
467 if (init_kernel_img || rot_changed || kernel_changed || filter_changed || filter_changed2)
468 {
469 init_kernel_img = false;
470 if (ricom->b_busy)
471 {
472 ricom->b_recompute_kernel = true;
473 }
474 else
475 {
476 ricom->kernel.compute_kernel();
477 }
478 GENERIC_WINDOW("RICOM").reset_min_max();
479 if (b_show_kernel)
480 {
481 ricom->kernel.draw_surfaces();
482 bind_tex(ricom->kernel.srf_kx, uiTextureIDs[9]);
483 bind_tex(ricom->kernel.srf_ky, uiTextureIDs[10]);
484 }
485 }
486 if (kernel_changed || b_nx_changed)
487 {
488 ricom->kernel.approximate_frequencies((size_t)ricom->nx);
489 }
490 if (b_show_kernel)
491 {
492 float sxk = (ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ItemSpacing.y * 3) / 2;
493 ImGui::Image((void *)(intptr_t)uiTextureIDs[9], ImVec2(sxk, sxk), ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f));
494 ImGui::SameLine();
495 ImGui::Image((void *)(intptr_t)uiTextureIDs[10], ImVec2(sxk, sxk), ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f));
496 }
497 if (b_show_frequencies)
498 {
499 ImGui::PlotLines("Frequencies", ricom->kernel.f_approx.data(), ricom->kernel.f_approx.size(), 0, NULL, 0.0f, 1.0f, ImVec2(0, 50));
500 }
501 }
502 if (ricom->b_vSTEM)
503 {
504 if (ImGui::CollapsingHeader("vSTEM Settings", ImGuiTreeNodeFlags_DefaultOpen))
505 {
506 bool inner_changed = ImGui::SliderFloat("Inner Radius", &ricom->detector.radius[0], 0.0f, 182.0f, "%.1f px");
507 bool outer_changed = ImGui::SliderFloat("Outer Radius", &ricom->detector.radius[1], 0.0f, 182.0f, "%.1f px");
508 if (inner_changed || outer_changed)
509 {
510 ricom->b_recompute_detector = true;
511 GENERIC_WINDOW("vSTEM").reset_min_max();
512 }
513 }
514 }
515
516 if (b_merlin_live_menu)
517 {
518 if (ImGui::CollapsingHeader("Merlin Live Mode", ImGuiTreeNodeFlags_DefaultOpen))
519 {
520
521 ImGui::InputInt("hvbias", &merlin_settings.hvbias, 1, 10);
522 ImGui::InputInt("threshold0", &merlin_settings.threshold0, 1, 8);
523 ImGui::InputInt("threshold1", &merlin_settings.threshold1, 1, 8);
524 ImGui::InputFloat("dwell time (us)", &merlin_settings.dwell_time, 0.01, 0.1);
525 ImGui::Checkbox("trigger", &merlin_settings.trigger);
526 ImGui::SameLine();
527 ImGui::Checkbox("headless", &merlin_settings.headless);
528 ImGui::Checkbox("continuousrw", &merlin_settings.continuousrw);
529 ImGui::SameLine();
530 ImGui::Checkbox("raw", &merlin_settings.raw);
531
532 if (merlin_settings.raw)
533 {
534 ImGui::Text("Depth");
535 ImGui::SameLine();
536 ImGui::BeginGroup();
537 ImGui::RadioButton("1", &ricom->camera.depth, 1);
538 ImGui::SameLine();
539 ImGui::RadioButton("6", &ricom->camera.depth, 6);
540 ImGui::SameLine();
541 ImGui::RadioButton("12", &ricom->camera.depth, 12);
542 ImGui::EndGroup();
543 }
544
545 ImGui::Checkbox("save file?", &merlin_settings.save);
546
547 if (ricom->socket.b_connected)
548 {
549 b_started = true;
550 b_restarted = true;
551 ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "Connected");
552 if (ricom->socket.connection_information.size() > 0)
553 {
554 ImGui::SameLine();
555 if (ImGui::Button("Show Acqusition Info", ImVec2(-1.0f, 0.0f)))
556 {
557 b_acq_open = true;
558 }
559 }
560 }
561 else
562 {
563 ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "Not Connected");
564 }
565
566 if (ImGui::Button("Start Acquisition", ImVec2(-1.0f, 0.0f)))
567 {
568
569 run_thread = std::thread(RICOM::run_ricom, ricom, RICOM::TCP);
570 std::this_thread::sleep_for(std::chrono::milliseconds(500));
571 py_thread = std::thread(RICOM::run_connection_script, ricom, &merlin_settings, python_path);
572 run_thread.detach();
573 py_thread.detach();
574 GENERIC_WINDOW("RICOM").set_data(ricom->nx, ricom->ny, &ricom->ricom_data);
575 }
576 }
577 }
578
579 if (ImGui::CollapsingHeader("File reconstruction", ImGuiTreeNodeFlags_DefaultOpen))
580 {
581
582 if (ImGui::Button("Open File", ImVec2(-1.0f, 0.0f)))
583 {
584 openFileDialog.Open();
585 }
586
587 openFileDialog.Display();
588 if (openFileDialog.HasSelected())
589 {
590 filename = openFileDialog.GetSelected().string();
591 b_file_selected = true;
592 openFileDialog.ClearSelected();
593 ricom->camera = hardware_configurations[ricom->select_mode_by_file(filename.c_str())];
594 }
595 if (b_file_selected)
596 {
597 ImGui::Text("File: %s", filename.c_str());
598
599 if (ricom->camera.model == CAMERA::MERLIN)
600 {
601 ImGui::BeginGroup();
602 ImGui::Text("Depth");
603 ImGui::RadioButton("1", &ricom->camera.depth, 1);
604 ImGui::SameLine();
605 ImGui::RadioButton("6", &ricom->camera.depth, 6);
606 ImGui::SameLine();
607 ImGui::RadioButton("12", &ricom->camera.depth, 12);
608 ImGui::EndGroup();
609 if (ImGui::IsItemHovered())
610 {
611 ImGui::SetTooltip("Only applicable for handling recorded files, \n recorded in raw mode.");
612 }
613 }
614 if (ricom->camera.model == CAMERA::TIMEPIX)
615 {
616 ImGui::DragInt("dwell time", &ricom->camera.dwell_time, 1, 1);
617 }
618
619 if (ImGui::Button("Run File", ImVec2(-1.0f, 0.0f)))
620 {
621 run_thread = std::thread(RICOM::run_ricom, ricom, RICOM::FILE);
622 b_started = true;
623 b_restarted = true;
624 run_thread.detach();
625 GENERIC_WINDOW("RICOM").set_data(ricom->nx, ricom->ny, &ricom->ricom_data);
626 }
627 }
628 }
629 ImGui::EndChild();
630
631 float panel_h_min = control_menu_size.y * 0.4;
632 float panel_h_max = control_menu_size.y - 32;
633 v_splitter(5, menu_split_v, panel_h_min, panel_h_max, pos.y + ImGui::GetStyle().ItemSpacing.y * 3);
634
635 ImGui::BeginChild("Progress", ImVec2(0, 0), true, ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoScrollbar);
636 ImGui::ProgressBar(ricom->fr_count / (ricom->fr_total), ImVec2(-1.0f, 0.0f));
637 ImGui::Text("Speed: %.2f kHz", ricom->fr_freq);
638 if (ImGui::Button("Quit", ImVec2(-1.0f, 0.0f)))
639 {
640 ricom->rc_quit = true;
641 b_redraw = true;
642 }
643
644 ImGui::Text("COM= %.2f, %.2f", ricom->com_public[0], ricom->com_public[1]);
645
646 // CBED Plot Area/DockSpace
647 ImGui::DockSpace(1319);
648 static auto first_time = true;
649 if (first_time)
650 {
651 first_time = false;
652 ImGui::DockBuilderRemoveNode(1319); // clear any previous layout
653 ImGui::DockBuilderAddNode(1319, ImGuiDockNodeFlags_DockSpace);
654 ImGui::DockBuilderDockWindow("CBED", 1319);
655 ImGui::DockBuilderFinish(1319);
656 }
657 ImGui::EndChild();
658 control_menu_size = ImGui::GetWindowSize();
659 ImGui::End();
660
661 main_dock.render(ImVec2(control_menu_size.x, pos.y), ImVec2(viewport->Size.x - control_menu_size.x, viewport->Size.y - menu_bar_size.y));
662
663 ImGui::Begin("CBED", nullptr, ImGuiWindowFlags_NoScrollbar);
664 ImGui::Checkbox("Plot CBED", &ricom->b_plot_cbed);
665 if (ricom->b_plot_cbed)
666 {
667 ImGui::SameLine();
668 ImGui::SetNextItemWidth(80);
669 ImGui::InputInt("Frames", &ricom->cbed_cmap_frames);
670 if (ImGui::IsItemHovered())
671 {
672 ImGui::SetTooltip("Number of frames to integrate for CBED image");
673 }
674 }
675 if (ricom->cbed_cmap_frames < 1)
676 ricom->cbed_cmap_frames = 1;
677 ImVec2 rem_space = ImGui::GetContentRegionAvail();
678 float tex_wh = (std::min)(rem_space.x, rem_space.y);
679 ImVec2 p = ImGui::GetCursorScreenPos();
680
681 float com_rel_x = p.x + tex_wh * (ricom->com_public[0] / ricom->camera.nx_cam);
682 float com_rel_y = p.y + tex_wh * (ricom->com_public[1] / ricom->camera.ny_cam);
683
684 float centre_x = p.x + tex_wh * (ricom->offset[0] / ricom->camera.nx_cam);
685 float centre_y = p.y + tex_wh * (ricom->offset[1] / ricom->camera.ny_cam);
686
687 com_rel_x = (std::max)(p.x, com_rel_x);
688 com_rel_y = (std::max)(p.y, com_rel_y);
689 com_rel_x = (std::min)(p.x + tex_wh, com_rel_x);
690 com_rel_y = (std::min)(p.y + tex_wh, com_rel_y);
691
692 float cross_width = tex_wh / 15.0f;
693 if (b_redraw)
694 {
695 if (ricom->srf_cbed != NULL)
696 {
697 bind_tex(ricom->srf_cbed, uiTextureIDs[0]);
698 }
699 }
700 ImGui::Image((ImTextureID)uiTextureIDs[0], ImVec2(tex_wh, tex_wh), uv_min, uv_max, tint_col, border_col);
701 ImGui::GetWindowDrawList()->AddCircle(ImVec2(centre_x, centre_y), tex_wh * 0.03, IM_COL32(255, 255, 255, 255), 256);
702 ImGui::GetWindowDrawList()->AddLine(ImVec2(com_rel_x - cross_width, com_rel_y), ImVec2(com_rel_x + cross_width, com_rel_y), IM_COL32(255, 0, 0, 255), 1.5f);
703 ImGui::GetWindowDrawList()->AddLine(ImVec2(com_rel_x, com_rel_y - cross_width), ImVec2(com_rel_x, com_rel_y + cross_width), IM_COL32(255, 0, 0, 255), 1.5f);
704 if (ricom->b_vSTEM)
705 {
706 ImGui::GetWindowDrawList()->AddCircle(ImVec2(centre_x, centre_y), tex_wh * (ricom->detector.radius[0] / ricom->camera.nx_cam), IM_COL32(255, 50, 0, 255), 256);
707 ImGui::GetWindowDrawList()->AddCircle(ImVec2(centre_x, centre_y), tex_wh * (ricom->detector.radius[1] / ricom->camera.nx_cam), IM_COL32(255, 150, 0, 255), 256);
708 }
709 ImGui::End();
710
711 if (b_acq_open)
712 {
713 ImVec2 pos_t = viewport->Pos;
714 pos_t[0] += control_menu_size[0] + 128;
715 pos_t[1] += menu_bar_size[1] + 128;
716 ImGui::SetNextWindowPos(pos_t, ImGuiCond_FirstUseEver);
717 ImVec2 size = {200, 400};
718 ImGui::SetNextWindowSize(size, ImGuiCond_FirstUseEver);
719
720 ImGui::Begin("Acquisition Header", &b_acq_open);
721 ImGui::BeginChild("Scrolling");
722 ImGui::TextWrapped(ricom->socket.connection_information.data());
723 ImGui::EndChild();
724 ImGui::End();
725 }
726
727 // Render all generic Image Windows
728 bool trigger = (b_trigger_update != ricom->b_busy) && (ricom->b_busy == false);
729 bool redraw_tick = (ricom->b_busy && b_redraw && b_started);
730 update_views(generic_windows_f, ricom, b_restarted, trigger, redraw_tick);
731 update_views(generic_windows_c, ricom, b_restarted, trigger, redraw_tick);
732
733 b_restarted = false;
734 b_trigger_update = ricom->b_busy;
735
736 // Rendering
737 ImGui::Render();
738 glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
739 glClear(GL_COLOR_BUFFER_BIT);
740 ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
741
742 if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
743 {
744 SDL_Window *backup_current_window = SDL_GL_GetCurrentWindow();
745 SDL_GLContext backup_current_context = SDL_GL_GetCurrentContext();
746 ImGui::UpdatePlatformWindows();
747 ImGui::RenderPlatformWindowsDefault();
748 SDL_GL_MakeCurrent(backup_current_window, backup_current_context);
749 }
750
751 SDL_GL_SwapWindow(window);
752
753 b_redraw = false;
754 }
755
756 if (run_thread.joinable())
757 run_thread.join();
758 if (py_thread.joinable())
759 py_thread.join();
760
761 ImGui_ImplOpenGL3_Shutdown();
762 ImGui_ImplSDL2_Shutdown();
763 ImGui::DestroyContext();
764
765 SDL_GL_DeleteContext(gl_context);
766 SDL_DestroyWindow(window);
767 SDL_Quit();
768
769 ini_file.write(ini_cfg, true);
770 return 0;
771}
void v_splitter(float thickness, float &size0, const float &min_h, const float &max_h, const float &offset)
Definition GuiUtils.cpp:41
GIM_Flags
@ ColormapSelector
void bind_tex(SDL_Surface *srf, GLuint tex_id)
Definition RunGUI.cpp:800
#define GENERIC_WINDOW_C(name)
Definition RunGUI.cpp:57
#define GENERIC_WINDOW(name)
Definition RunGUI.cpp:56
void update_views(std::map< std::string, ImGuiImageWindow< T > > &generic_windows_f, Ricom *ricom, bool b_restarted, bool trigger, bool b_redraw)
Definition RunGUI.cpp:774
SDL_Surface * srf_kx
Definition Ricom.h:66
void compute_kernel()
Definition Ricom.cpp:21
void draw_surfaces()
Definition Ricom.cpp:128
std::vector< float > f_approx
Definition Ricom.h:65
void approximate_frequencies(size_t n_im)
Definition Ricom.cpp:111
SDL_Surface * srf_ky
Definition Ricom.h:67
std::array< float, 2 > com_public
Definition Ricom.h:236
bool b_busy
Definition Ricom.h:224
int cbed_cmap
Definition Ricom.h:269
bool b_recompute_detector
Definition Ricom.h:231
std::vector< float > stem_data
Definition Ricom.h:240
int n_threads_max
Definition Ricom.h:254
float fr_count
Definition Ricom.h:257
int cbed_cmap_frames
Definition Ricom.h:229
std::vector< std::complex< float > > e_field_data
Definition Ricom.h:241
SDL_Surface * srf_cbed
Definition Ricom.h:268
int fr_total
Definition Ricom.h:248
std::vector< float > com_map_x
Definition Ricom.h:237
float fr_freq
Definition Ricom.h:256
bool b_recompute_kernel
Definition Ricom.h:232
std::vector< float > com_map_y
Definition Ricom.h:238
std::string connection_information
void check_ini_setting(mINI::INIStructure &ini_cfg, std::string section, std::string key, char *value)
Definition ImGuiINI.hpp:116
bool ShowFontSelector(const char *label, int &selectedFont, mINI::INIStructure &ini_cfg)
Definition ImGuiINI.hpp:57
bool ShowStyleSelector(const char *label, int &style_idx, mINI::INIStructure &ini_cfg)
Definition ImGuiINI.hpp:37
void set_font(int font_idx)
Definition ImGuiINI.hpp:81
void set_style(int style_idx)
Definition ImGuiINI.hpp:21
void run_connection_script(Ricom *r, MerlinSettings *merlin, const std::string &python_path)
Definition Ricom.cpp:1104
@ FILE
Definition Ricom.h:144