5#ifdef GEMC_HAS_QTCHARTS
6#include "gAnalysisView.h"
10#include "G4UImanager.hh"
18void resetSceneBeforeGeometryReload(G4UImanager* g4uim) {
19 if (!g4uim) {
return; }
21 g4uim->ApplyCommand(
"/vis/viewer/set/autoRefresh false");
22 g4uim->ApplyCommand(
"/vis/scene/endOfEventAction accumulate 0");
23 g4uim->ApplyCommand(
"/vis/scene/endOfRunAction refresh");
24 g4uim->ApplyCommand(
"/vis/scene/removeModel all");
25 g4uim->ApplyCommand(
"/vis/viewer/clearTransients");
26 g4uim->ApplyCommand(
"/vis/viewer/clear");
27 g4uim->ApplyCommand(
"/vis/viewer/set/autoRefresh true");
28 g4uim->ApplyCommand(
"/vis/viewer/flush");
29 g4uim->ApplyCommand(
"/vis/viewer/clearTransients");
32void resetEventDrawingBeforeRun(G4UImanager* g4uim) {
33 if (!g4uim) {
return; }
35 g4uim->ApplyCommand(
"/vis/viewer/set/autoRefresh false");
36 g4uim->ApplyCommand(
"/vis/scene/endOfEventAction accumulate 0");
37 g4uim->ApplyCommand(
"/vis/scene/endOfRunAction refresh");
38 g4uim->ApplyCommand(
"/vis/viewer/clearTransients");
39 g4uim->ApplyCommand(
"/vis/viewer/clear");
40 g4uim->ApplyCommand(
"/vis/viewer/flush");
41 g4uim->ApplyCommand(
"/vis/viewer/clearTransients");
44void restoreSceneModels(G4UImanager* g4uim,
const std::shared_ptr<GOptions>& gopts,
bool includeEventModels) {
45 if (!g4uim) {
return; }
50 g4uim->ApplyCommand(
"/vis/viewer/set/autoRefresh false");
51 g4uim->ApplyCommand(
"/vis/scene/removeModel all");
52 g4uim->ApplyCommand(
"/vis/viewer/clearTransients");
53 g4uim->ApplyCommand(
"/vis/viewer/clear");
54 g4uim->ApplyCommand(
"/vis/drawVolume");
55 g4uim->ApplyCommand(
"/vis/viewer/set/background " + g4view.background);
56 g4uim->ApplyCommand(
"/vis/viewer/set/numberOfCloudPoints " + std::to_string(g4view.cloudPoints));
57 for (
const auto& command : g4SceneProperties.addSceneDecorations(gopts)) { g4uim->ApplyCommand(command); }
58 for (
const auto& command : g4SceneProperties.addSceneTexts(gopts)) { g4uim->ApplyCommand(command); }
59 if (includeEventModels) {
61 g4uim->ApplyCommand(
"/vis/scene/add/trajectories smooth");
62 g4uim->ApplyCommand(
"/vis/modeling/trajectories/create/drawByCharge");
63 g4uim->ApplyCommand(
"/vis/modeling/trajectories/drawByCharge-0/default/setDrawStepPts true");
64 g4uim->ApplyCommand(
"/vis/modeling/trajectories/drawByCharge-0/default/setStepPtsSize 2");
65 g4uim->ApplyCommand(
"/vis/scene/add/hits");
66 g4uim->ApplyCommand(
"/vis/scene/endOfEventAction accumulate 10000");
67 if (decorations.eventID) {
68 g4uim->ApplyCommand(
"/vis/scene/add/eventID " + std::to_string(decorations.eventIDSize));
71 g4uim->ApplyCommand(
"/vis/viewer/set/autoRefresh true");
72 g4uim->ApplyCommand(
"/vis/viewer/flush");
78 std::shared_ptr<EventDispenser> ed,
80 std::shared_ptr<GAnalysisAccumulator> analyzer,
81 bool viewerAlreadyInitialized,
85 analysisAccumulator(std::move(analyzer)),
87 detectorConstruction(dc),
88 viewerInitialized(viewerAlreadyInitialized) {
97 guiSession = std::make_unique<GUI_Session>(gopts,
gboard);
100 createRightContent(gopts, dc,
gboard);
103 auto* topLayout =
new QHBoxLayout;
104 createTopButtons(topLayout);
107 auto* bottomLayout =
new QHBoxLayout;
108 bottomLayout->setContentsMargins(0, 0, 0, 0);
109 bottomLayout->setSpacing(6);
111 bottomLayout->addWidget(leftButtons, 1);
112 bottomLayout->addWidget(rightContent, 10);
115 auto* mainLayout =
new QVBoxLayout;
116 mainLayout->setContentsMargins(6, 6, 6, 6);
117 mainLayout->setSpacing(6);
118 mainLayout->addLayout(topLayout);
119 mainLayout->addLayout(bottomLayout, 1);
120 mainLayout->addWidget(
gboard, 0);
122 setLayout(mainLayout);
123 setWindowTitle(tr(
"GEMC: Geant4 Monte-Carlo"));
124 setMinimumWidth(1000);
125 setMinimumHeight(760);
126 resize(1000, std::max(sizeHint().height(), 760));
127 QTimer::singleShot(0,
this, [
this]() {
129 const int preferredHeight = std::max(sizeHint().height(), 760);
130 setMinimumHeight(preferredHeight);
131 resize(std::max(1000, sizeHint().width()), preferredHeight);
135 gtimer =
new QTimer(
this);
136 connect(gtimer, SIGNAL(timeout()),
this, SLOT(cycleBeamOn()));
139 connect(leftButtons->buttonsWidget,
140 SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem*)),
141 this, SLOT(change_page(QListWidgetItem *, QListWidgetItem*)));
145void GemcGUI::updateGui() {
147 displayedEventCount += nEvents->text().toULongLong();
148 eventNumberLabel->setText(tr(
"Event Number: %1").arg(displayedEventCount));
152void GemcGUI::resetVisualizationBeforeGeometryReload() {
153#ifdef GEMC_HAS_QTCHARTS
154 if (analysisView !=
nullptr) { analysisView->clearForGeometryReload(); }
156 resetSceneBeforeGeometryReload(G4UImanager::GetUIpointer());
159void GemcGUI::refreshVisualizationFromOptions() {
160 if (!detectorConstruction || !detectorConstruction->has_built_geometry()) {
return; }
162 auto* g4uim = G4UImanager::GetUIpointer();
163 if (!g4uim) {
return; }
165 restoreSceneModels(g4uim, guiOptions,
false);
166 visualizationNeedsRunRestore =
true;
169void GemcGUI::refreshGeometryTree() {
170 if (!rightContent || !detectorConstruction || !guiOptions || !geometryTree) {
return; }
172 geometryReloadedSinceRun =
true;
174 const int treeIndex = rightContent->indexOf(geometryTree);
175 if (treeIndex < 0) {
return; }
177 const int currentIndex = rightContent->currentIndex();
178 auto* g4uim = G4UImanager::GetUIpointer();
179 if (!g4uim) {
return; }
181 const auto g4volumes = detectorConstruction->has_built_geometry()
182 ? detectorConstruction->get_g4volumes_map()
183 : std::unordered_map<std::string, G4Volume*>{};
184 const auto gvolumes = detectorConstruction->has_built_geometry()
185 ? detectorConstruction->get_gvolumes_flat_map()
186 : std::unordered_map<std::string, const GVolume*>{};
187 const auto gmirrors = detectorConstruction->has_built_geometry()
188 ? detectorConstruction->get_gmirrors_flat_map()
189 : std::unordered_map<std::string, const GMirror*>{};
190 auto* refreshedTree =
new GTree(guiOptions, g4volumes, gvolumes,
nullptr, gmirrors);
192 rightContent->removeWidget(geometryTree);
193 geometryTree->deleteLater();
194 geometryTree = refreshedTree;
195 rightContent->insertWidget(treeIndex, geometryTree);
196 rightContent->setCurrentIndex(currentIndex == treeIndex ? treeIndex : currentIndex);
198 if (g4volumes.size() > 1) {
199 if (!viewerInitialized) {
201 G4SceneProperties g4SceneProperties(guiOptions);
202 auto commands = g4SceneProperties.scene_commands(guiOptions);
203 for (
const auto& command : commands) { g4uim->ApplyCommand(command); }
204 viewerInitialized =
true;
207 restoreSceneModels(g4uim, guiOptions,
false);
211void GemcGUI::prepareGeometryForBeamOn() {
212 if ((!geometryReloadedSinceRun && !visualizationNeedsRunRestore) || !detectorConstruction) {
return; }
213 if (!detectorConstruction->has_built_geometry()) {
return; }
215 auto* g4uim = G4UImanager::GetUIpointer();
216 resetEventDrawingBeforeRun(g4uim);
218 if (geometryReloadedSinceRun) {
219 detectorConstruction->prepare_geometry_for_run();
220 if (eventDispenser) {
221 eventDispenser->resetRunContext();
228 restoreSceneModels(g4uim, guiOptions,
true);
230 geometryReloadedSinceRun =
false;
231 visualizationNeedsRunRestore =
false;
241void GemcGUI::change_page(QListWidgetItem* current, QListWidgetItem* previous) {
249 rightContent->setCurrentIndex(thisIndex);
GemcGUI(std::shared_ptr< GOptions > gopts, std::shared_ptr< EventDispenser > ed, GDetectorConstruction *dc, std::shared_ptr< GAnalysisAccumulator > analysisAccumulator, bool viewerAlreadyInitialized=false, QWidget *parent=nullptr)
Construct the main GUI widget.
~GemcGUI() override
Destroy the GUI widget and release explicitly owned resources.
G4View getG4View(const std::shared_ptr< GOptions > &gopts)
G4Decorations getG4Decorations(const std::shared_ptr< GOptions > &gopts)