REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestGeant4EventViewer.cxx
1
14
15#include "TRestGeant4EventViewer.h"
16
17#include <TRestStringOutput.h>
18
19using namespace std;
20
22
23TRestGeant4EventViewer::TRestGeant4EventViewer() { Initialize(); }
24
25TRestGeant4EventViewer::~TRestGeant4EventViewer() {
26 // TRestGeant4EventViewer destructor
27}
28
29void TRestGeant4EventViewer::Initialize() {
30 fG4Event = new TRestGeant4Event();
31 fEvent = fG4Event;
32
33 fHitConnectors.clear();
34 fHitConnectors.push_back(nullptr);
35}
36
37void TRestGeant4EventViewer::DeleteCurrentEvent() {
38 TRestEveEventViewer::DeleteCurrentEvent();
39 fG4Metadata = nullptr;
40
41 fHitConnectors.clear();
42 fHitConnectors.push_back(nullptr);
43}
44
46 Color_t fColor = kWhite;
47 Style_t fLineStyle = 1;
48 Width_t fLineWidth = 4.0;
49};
50
51TrackVisualConfiguration GetTrackVisualConfiguration(const TRestGeant4Track& track) {
52 auto config = TrackVisualConfiguration();
53 // special particles
54 const auto particleName = track.GetParticleName();
55 if (particleName == "geantino") {
56 config.fColor = kRed;
57 config.fLineStyle = 9;
58 config.fLineWidth = 2;
59 return config;
60 }
61 // color based on charge
62 if (particleName.Contains('-')) {
63 config.fColor = kMagenta; // red
64 } else if (particleName.Contains('+')) {
65 config.fColor = kAzure;
66 }
67 // color based on particle (overrides charge color)
68 if (particleName == "neutron") {
69 config.fColor = kOrange; // white
70 } else if (particleName == "gamma") {
71 config.fColor = kGreen; // green
72 } else if (particleName == "e-") {
73 config.fColor = kRed; // red
74 } else if (particleName == "mu-") {
75 config.fColor = kGray; // red
76 } else if (particleName == "alpha") {
77 config.fColor = kYellow; // red
78 }
79
80 // width
81 Width_t width = TMath::Log10(track.GetInitialKineticEnergy() / 100);
82 width = (width > 10 ? 10 : width);
83 width = (width < 1 ? 1 : width);
84 config.fLineWidth = TMath::Log10(track.GetInitialKineticEnergy() / 10);
85
86 // line style
87
88 if (track.GetCreatorProcess() == "nCapture") {
89 config.fLineStyle = 2;
90 }
91
92 return config;
93}
94
95TEveStraightLineSet* TRestGeant4EventViewer::GetTrackEveDrawable(const TRestGeant4Track& track) {
96 auto lineSet = new TEveStraightLineSet(
97 TString::Format("ID %d | %s | Created by %s | KE: %s", //
98 track.GetTrackID(), track.GetParticleName().Data(), track.GetCreatorProcess().Data(),
99 ToEnergyString(track.GetInitialKineticEnergy()).c_str()));
100
101 const auto& hits = track.GetHits();
102 for (unsigned int i = 0; i < hits.GetNumberOfHits() - 1; i++) {
103 lineSet->AddLine({static_cast<float>(fGeomScale * hits.GetPosition(i).x()),
104 static_cast<float>(fGeomScale * hits.GetPosition(i).y()),
105 static_cast<float>(fGeomScale * hits.GetPosition(i).z())}, //
106 {static_cast<float>(fGeomScale * hits.GetPosition(i + 1).x()),
107 static_cast<float>(fGeomScale * hits.GetPosition(i + 1).y()),
108 static_cast<float>(fGeomScale * hits.GetPosition(i + 1).z())});
109
110 const auto config = GetTrackVisualConfiguration(track);
111 lineSet->SetMainColor(config.fColor);
112 lineSet->SetLineColor(config.fColor);
113 lineSet->SetLineStyle(config.fLineStyle);
114 lineSet->SetLineWidth(config.fLineWidth);
115 }
116
117 return lineSet;
118}
119
121 Color_t fColor = kBlack;
122 Style_t fMarkerStyle = 1;
123 Size_t fMarkerSize = 1.0;
124};
125
126HitsVisualConfiguration GetHitsVisualConfiguration(const TString& processNameOrType) {
127 auto config = HitsVisualConfiguration();
128 // based on particle type
129 if (processNameOrType.EqualTo("Electromagnetic")) {
130 config.fColor = kRed;
131 } else if (processNameOrType.EqualTo("Init")) {
132 // custom process (not Geant4)
133 config.fColor = kWhite;
134 }
135
136 // based on particle name
137 if (processNameOrType.EqualTo("Transportation")) {
138 config.fColor = kWhite;
139 } else if (processNameOrType.EqualTo("Init")) {
140 // custom process (not Geant4)
141 config.fColor = kWhite;
142 } else if (processNameOrType.EqualTo("hadElastic")) {
143 config.fColor = kOrange;
144 } else if (processNameOrType.EqualTo("neutronInelastic")) {
145 config.fColor = kGreen;
146 config.fMarkerStyle = 4;
147 } else if (processNameOrType.EqualTo("nCapture")) {
148 config.fColor = kBlue;
149 config.fMarkerStyle = 2;
150 config.fMarkerSize = 4.0;
151 }
152 return config;
153}
154
155void TRestGeant4EventViewer::AddEvent(TRestEvent* event) {
156 DeleteCurrentEvent();
157
158 fG4Event = (TRestGeant4Event*)event;
159 fG4Metadata = fG4Event->GetGeant4Metadata();
160 if (fG4Metadata == nullptr) {
161 cerr << "TRestGeant4EventViewer::Initialize. No TRestGeant4Metadata found in TRestGeant4Event"
162 << endl;
163 exit(1);
164 }
165
166 size_t trackCounter = 0;
167 size_t hitsCounter = 0;
168
169 map<Int_t, TEveStraightLineSet*> linesSet;
170 map<TString, TEvePointSet*> hitsPoints;
171 map<TString, TEveElementList*> hitsType;
172
173 auto trackList = new TEveElementList("Tracks");
174 gEve->AddElement(trackList);
175 auto hitsList = new TEveElementList("Hits");
176 gEve->AddElement(hitsList);
177
178 const auto& physicsInfo = fG4Metadata->GetGeant4PhysicsInfo();
179
180 for (const auto& track : fG4Event->GetTracks()) {
181 if (track.GetInitialKineticEnergy() < 1.0 || track.GetLength() < 0.1) {
182 continue;
183 }
184
185 auto line = GetTrackEveDrawable(track);
186 linesSet[track.GetTrackID()] = line;
187 TEveElement* parentLine = trackList;
188 if (linesSet.count(track.GetParentID())) {
189 parentLine = linesSet.at(track.GetParentID());
190 }
191 gEve->AddElement(line, parentLine);
192 trackCounter++;
193
194 const auto& hits = track.GetHits();
195 for (unsigned int i = 0; i < hits.GetNumberOfHits(); i++) {
196 const auto& processName = physicsInfo.GetProcessName(hits.GetProcess(i));
197 const auto& processType = physicsInfo.GetProcessType(processName);
198 const auto& position = hits.GetPosition(i);
199
200 if (hitsType.count(processType) == 0) {
201 hitsType[processType] = new TEveElementList(processType);
202 gEve->AddElement(hitsType[processType], hitsList);
203 }
204 if (hitsPoints.count(processName) == 0) {
205 hitsPoints[processName] = new TEvePointSet(processName);
206 auto hitPoints = hitsPoints.at(processName);
207 auto hitsVisualConfig = GetHitsVisualConfiguration(processName);
208 hitPoints->SetMarkerColor(hitsVisualConfig.fColor);
209 hitPoints->SetMarkerStyle(hitsVisualConfig.fMarkerStyle);
210 hitPoints->SetMarkerSize(hitsVisualConfig.fMarkerSize);
211
212 gEve->AddElement(hitPoints, hitsType[processType]);
213 }
214 hitsPoints.at(processName)
215 ->SetNextPoint(fGeomScale * position.X(), fGeomScale * position.Y(),
216 fGeomScale * position.Z());
217 hitsCounter++;
218 }
219 }
220
221 // Add event text
222 const auto& firstTrack = fG4Event->GetTracks().front();
223 TVector3 position = {firstTrack.GetInitialPosition().X(), firstTrack.GetInitialPosition().Y(),
224 firstTrack.GetInitialPosition().Z()};
225 AddText(
226 TString::Format(
227 "Event ID: %d%s | Primary origin: (%4.2lf, %4.2lf, %4.2lf) mm", fG4Event->GetID(),
228 (fG4Event->GetSubID() > 0 ? TString::Format(" (SubID: %d)", fG4Event->GetSubID()) : "").Data(),
229 position.X(), position.Y(), position.Z()),
230 position);
231
232 Update();
233}
234
235void TRestGeant4EventViewer::AddText(TString text, TVector3 at) {
236 TEveText* evText = new TEveText(text);
237 evText->SetName("Event title");
238 evText->SetFontSize(12);
239 evText->RefMainTrans().SetPos((at.X() + 15) * fGeomScale, (at.Y() + 15) * fGeomScale,
240 (at.Z() + 15) * fGeomScale);
241
242 gEve->AddElement(evText);
243}
244
245void TRestGeant4EventViewer::AddMarker(Int_t trkID, TVector3 at, TString name) {
246 TEvePointSet* marker = new TEvePointSet(1);
247 marker->SetName(name);
248 marker->SetMarkerColor(kMagenta);
249 marker->SetMarkerStyle(3);
250 marker->SetPoint(0, at.X() * fGeomScale, at.Y() * fGeomScale, at.Z() * fGeomScale);
251 marker->SetMarkerSize(0.4);
252 fHitConnectors[trkID]->AddElement(marker);
253}
254
255void TRestGeant4EventViewer::NextTrackVertex(Int_t trkID, TVector3 to) {
256 fHitConnectors[trkID]->SetNextPoint(to.X() * fGeomScale, to.Y() * fGeomScale, to.Z() * fGeomScale);
257}
258
259void TRestGeant4EventViewer::AddTrack(Int_t trkID, Int_t parentID, TVector3 from, TString name) {
260 TEveLine* evLine = new TEveLine();
261 evLine->SetName(name);
262 fHitConnectors.push_back(evLine);
263
264 fHitConnectors[trkID]->SetMainColor(kWhite);
265 fHitConnectors[trkID]->SetLineWidth(4);
266
267 if (name.Contains("gamma")) fHitConnectors[trkID]->SetMainColor(kGreen);
268 if (name.Contains("e-")) fHitConnectors[trkID]->SetMainColor(kRed);
269 if (name.Contains("mu-")) fHitConnectors[trkID]->SetMainColor(kGray);
270 if (name.Contains("alpha")) fHitConnectors[trkID]->SetMainColor(kYellow);
271 if (name.Contains("neutron")) fHitConnectors[trkID]->SetMainColor(kBlue);
272
273 fHitConnectors[trkID]->SetNextPoint(from.X() * fGeomScale, from.Y() * fGeomScale, from.Z() * fGeomScale);
274
275 if (parentID >= 0 && fHitConnectors.size() > (unsigned int)parentID)
276 fHitConnectors[parentID]->AddElement(fHitConnectors[trkID]);
277 else {
278 RESTWarning << "Parent ID: " << parentID << " of track " << trkID << " was not found!" << RESTendl;
279 RESTWarning << "This might be solved by enabling TRestGeant4Metadata::fRegisterEmptyTracks"
280 << RESTendl;
281 }
282}
283
284void TRestGeant4EventViewer::AddParentTrack(Int_t trkID, TVector3 from, TString name) {
285 TEveLine* evLine = new TEveLine();
286 evLine->SetName(name);
287 fHitConnectors.push_back(evLine);
288
289 fHitConnectors[trkID]->SetMainColor(kWhite);
290 fHitConnectors[trkID]->SetLineWidth(4);
291 fHitConnectors[trkID]->SetNextPoint(from.X() * fGeomScale, from.Y() * fGeomScale, from.Z() * fGeomScale);
292
293 gEve->AddElement(fHitConnectors[trkID]);
294}
A base class for any REST event.
Definition: TRestEvent.h:38
An event class to store geant4 generated event information.
const TRestGeant4PhysicsInfo & GetGeant4PhysicsInfo() const
Returns an immutable reference to the physics info.