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
79#if defined(IMGUI_IMPL_OPENGL_ES2)
80
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
88 const char *glsl_version = "#version 150";
89 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
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
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
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);
114
115
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
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;
138 io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
139
140
141
142 ImVec2 uv_min = ImVec2(0.0f, 0.0f);
143 ImVec2 uv_max = ImVec2(1.0f, 1.0f);
144 ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
145 ImVec4 border_col = ImVec4(1.0f, 1.0f, 1.0f, 0.5f);
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
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
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
184 struct MerlinSettings merlin_settings;
185
186
187
188 int font_index = 0;
189 int style_index = 0;
197
198 std::string python_path;
199#ifdef _WIN32
200 python_path = "py";
201#else
202 python_path = "python3";
203#endif
207
215
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
226
227
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;
237 generic_windows_f.emplace(
"RICOM-FFT",
ImGuiImageWindow<float>(
"RICOM-FFT", &uiTextureIDs[2],
false, 4, common_flags, &ricom_fft));
239
241 generic_windows_f.emplace(
"vSTEM-FFT",
ImGuiImageWindow<float>(
"vSTEM-FFT", &uiTextureIDs[4],
false, 4, common_flags, &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
248 generic_windows_f.emplace(
"E-Field-FFT",
ImGuiImageWindow<float>(
"E-Field-FFT", &uiTextureIDs[8],
false, 4, common_flags, &e_field_fft));
250
251
255
256 ImGuiID dock_id = 3775;
258
259
260 while (!b_done)
261 {
262
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
274 ImGui_ImplOpenGL3_NewFrame();
275 ImGui_ImplSDL2_NewFrame();
276 ImGui::NewFrame();
277
278
279 if (ImGui::BeginMainMenuBar())
280 {
281 if (ImGui::BeginMenu("Appearance"))
282 {
283 ImGui::Combo(
"CBED Colormap", &ricom->
cbed_cmap, cmaps, IM_ARRAYSIZE(cmaps));
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");
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
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 {
360 }
361 else
362 {
364 }
365 }
366 if (ImGui::Checkbox("Show CoM-Y", &show_com_y))
367 {
368 if (show_com_y)
369 {
371 }
372 else
373 {
375 }
376 }
377 if (ImGui::Checkbox(
"Show E-Field", &ricom->
b_e_mag))
378 {
380 {
382 }
383 else
384 {
386 }
387 }
388 if (ImGui::Checkbox(
"View vSTEM Image", &ricom->
b_vSTEM))
389 {
391 {
393 }
394 else
395 {
397 }
398 }
399 ImGui::EndMenu();
400 }
401 menu_bar_size = ImGui::GetWindowSize();
402 ImGui::EndMainMenuBar();
403 }
404
405 const ImGuiViewport *viewport = ImGui::GetMainViewport();
407 {
409 {
410 b_redraw = true;
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");
448 bool offset_changed = ImGui::DragFloat2(
"Centre", &ricom->
offset[0], 0.1f, 0.0, (
float)*max_nx);
449 if (offset_changed)
450 {
453 }
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)
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);
467 if (init_kernel_img || rot_changed || kernel_changed || filter_changed || filter_changed2)
468 {
469 init_kernel_img = false;
471 {
473 }
474 else
475 {
477 }
479 if (b_show_kernel)
480 {
484 }
485 }
486 if (kernel_changed || b_nx_changed)
487 {
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 {
500 }
501 }
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 {
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();
538 ImGui::SameLine();
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
548 {
549 b_started = true;
550 b_restarted = true;
551 ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "Connected");
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
570 std::this_thread::sleep_for(std::chrono::milliseconds(500));
572 run_thread.detach();
573 py_thread.detach();
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();
594 }
595 if (b_file_selected)
596 {
597 ImGui::Text("File: %s", filename.c_str());
598
600 {
601 ImGui::BeginGroup();
602 ImGui::Text("Depth");
604 ImGui::SameLine();
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 }
615 {
617 }
618
619 if (ImGui::Button("Run File", ImVec2(-1.0f, 0.0f)))
620 {
622 b_started = true;
623 b_restarted = true;
624 run_thread.detach();
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 {
641 b_redraw = true;
642 }
643
645
646
647 ImGui::DockSpace(1319);
648 static auto first_time = true;
649 if (first_time)
650 {
651 first_time = false;
652 ImGui::DockBuilderRemoveNode(1319);
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);
666 {
667 ImGui::SameLine();
668 ImGui::SetNextItemWidth(80);
670 if (ImGui::IsItemHovered())
671 {
672 ImGui::SetTooltip("Number of frames to integrate for CBED image");
673 }
674 }
677 ImVec2 rem_space = ImGui::GetContentRegionAvail();
678 float tex_wh = (std::min)(rem_space.x, rem_space.y);
679 ImVec2 p = ImGui::GetCursorScreenPos();
680
683
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 {
696 {
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);
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");
723 ImGui::EndChild();
724 ImGui::End();
725 }
726
727
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
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)
void bind_tex(SDL_Surface *srf, GLuint tex_id)
#define GENERIC_WINDOW_C(name)
#define GENERIC_WINDOW(name)
void update_views(std::map< std::string, ImGuiImageWindow< T > > &generic_windows_f, Ricom *ricom, bool b_restarted, bool trigger, bool b_redraw)
std::atomic< bool > report_set_public
std::array< float, 2 > radius
std::vector< float > f_approx
void approximate_frequencies(size_t n_im)
std::array< int, 2 > kernel_filter_frequency
std::array< float, 2 > com_public
bool b_recompute_detector
std::vector< float > stem_data
std::vector< float > ricom_data
std::vector< std::complex< float > > e_field_data
std::vector< float > com_map_x
ProgressMonitor * p_prog_mon
enum CAMERA::Camera_model select_mode_by_file(const char *filename)
std::vector< float > com_map_y
CAMERA::Camera_BASE camera
std::array< float, 2 > offset
std::string connection_information
void check_ini_setting(mINI::INIStructure &ini_cfg, std::string section, std::string key, char *value)
bool ShowFontSelector(const char *label, int &selectedFont, mINI::INIStructure &ini_cfg)
bool ShowStyleSelector(const char *label, int &style_idx, mINI::INIStructure &ini_cfg)
void set_font(int font_idx)
void set_style(int style_idx)
void run_connection_script(Ricom *r, MerlinSettings *merlin, const std::string &python_path)
void run_ricom(Ricom *r, RICOM::modes mode)