REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestGeant4EventViewer.cxx
1 
15 #include "TRestGeant4EventViewer.h"
16 
17 #include <TRestStringOutput.h>
18 
19 using namespace std;
20 
21 ClassImp(TRestGeant4EventViewer);
22 
23 TRestGeant4EventViewer::TRestGeant4EventViewer() { Initialize(); }
24 
25 TRestGeant4EventViewer::~TRestGeant4EventViewer() {
26  // TRestGeant4EventViewer destructor
27 }
28 
29 void TRestGeant4EventViewer::Initialize() {
30  fG4Event = new TRestGeant4Event();
31  fEvent = fG4Event;
32 
33  fHitConnectors.clear();
34  fHitConnectors.push_back(nullptr);
35 }
36 
37 void 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 
51 TrackVisualConfiguration 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 
95 TEveStraightLineSet* 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 
126 HitsVisualConfiguration 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 
155 void 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 
235 void 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 
245 void 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 
255 void TRestGeant4EventViewer::NextTrackVertex(Int_t trkID, TVector3 to) {
256  fHitConnectors[trkID]->SetNextPoint(to.X() * fGeomScale, to.Y() * fGeomScale, to.Z() * fGeomScale);
257 }
258 
259 void 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 
284 void 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.