FairShip
Loading...
Searching...
No Matches
eventDisplay.py
Go to the documentation of this file.
1#!/usr/bin/env python -i
2# SPDX-License-Identifier: LGPL-3.0-or-later
3# SPDX-FileCopyrightText: Copyright CERN for the benefit of the SHiP Collaboration
4
5import atexit
6import os
7import tkinter
8
9import ROOT
10
11ROOT.gROOT.ProcessLine('#include "FairEventHeader.h"')
12# only helps if class version in FairEventHeader.h is increased
13
14from argparse import ArgumentParser
15from array import array
16
17import decorators
18import shipRoot_conf
19import shipunit as u
20from ShipGeoConfig import load_from_root_file
21
24
25
26def _file_accessible(path: str) -> bool:
27 """Check whether a file exists (local or remote via XRootD)."""
28 if path.startswith("root://"):
29 from urllib.parse import urlparse
30
31 from XRootD import client as xrd_client
32
33 parsed = urlparse(path)
34 fs = xrd_client.FileSystem(f"{parsed.scheme}://{parsed.netloc}")
35 status, _ = fs.stat(parsed.path)
36 return status.ok
37 return os.path.exists(path)
38
39
40def evExit() -> None:
41 """Prevent double delete due to a FairRoot bug."""
42 # Check whether the Eve window was closed/destructed
43 if ROOT.addressof(ROOT.gEve) == 0:
44 # Prevent the FairEventManager destructor from being called
45 ROOT.SetOwnership(fMan, False)
46
47
48atexit.register(evExit)
49
50fMan = None
51fRun = None
52pdg = ROOT.TDatabasePDG.Instance()
53g = ROOT.gROOT
54gEnv = ROOT.gEnv
55gEnv.SetValue("Eve.Viewer.HideMenus", "off")
56
57mcEngine = "TGeant4"
58simEngine = "Pythia8"
59withGeo = False
60withMCTracks = True
61
62# muon shield strawtube decay vessel
63transparentMaterials = {
64 "iron": 80,
65 "aluminium": 80,
66 "mylar": 60,
67 "STTmix9010_2bar": 95,
68 "steel": 80,
69 "Aluminum": 80,
70 "Scintillator": 80,
71 # tau nu detector
72 "CoilCopper": 70,
73 "copper": 90,
74 "HPTgas": 70,
75 "Bakelite": 70,
76 "RPCgas": 70,
77 "TTmedium": 70,
78}
79#
80
81parser = ArgumentParser()
82
83parser.add_argument("-f", "--inputFile", dest="InputFile", help="Input file (MC simulation)", required=True)
84parser.add_argument(
85 "-r", "--recoFile", dest="recoFile", help="Reconstruction file (will be used as friend tree)", required=False
86)
87parser.add_argument("-g", "--geoFile", dest="geoFile", help="ROOT geofile", required=True)
88parser.add_argument(
89 "-p",
90 "--paramFile",
91 dest="ParFile",
92 help="FairRoot param file",
93 required=False,
94 default=None,
95)
96parser.add_argument(
97 "--Debug",
98 dest="Debug",
99 help="Switch on debugging",
100 required=False,
101 action="store_true",
102)
103parser.add_argument(
104 "-o",
105 "--outFile",
106 dest="OutputFile",
107 help="Output file",
108 required=False,
109 default=None,
110)
111parser.add_argument(
112 "-i",
113 dest="HiddenParticleID",
114 help="HiddenParticle ID",
115 required=False,
116 default=9900015,
117)
118
119options = parser.parse_args()
120if options.InputFile.find("_D") > 0:
121 withGeo = True
122
123# Determine reconstruction file
124if not options.recoFile:
125 # Default: replace .root with _rec.root, or if already _rec.root use as-is
126 if options.InputFile.find("_rec.root") > 0:
127 options.recoFile = options.InputFile
128 options.InputFile = options.InputFile.replace("_rec.root", ".root")
129 else:
130 candidate = options.InputFile.replace(".root", "_rec.root")
131 if _file_accessible(candidate):
132 options.recoFile = candidate
133
134
135def printMCTrack(n: int, MCTrack) -> None:
136 mcp = MCTrack[n]
137 print(
138 " %6i %7i %6.3F %6.3F %7.3F %7.3F %7.3F %7.3F %6i "
139 % (
140 n,
141 mcp.GetPdgCode(),
142 mcp.GetPx() / u.GeV,
143 mcp.GetPy() / u.GeV,
144 mcp.GetPz() / u.GeV,
145 mcp.GetStartX() / u.m,
146 mcp.GetStartY() / u.m,
147 mcp.GetStartZ() / u.m,
148 mcp.GetMotherId(),
149 )
150 )
151
152
153def dump(pcut: float = 0) -> None:
154 print(" # pid px py pz vx vy vz mid")
155 n = -1
156 for mcp in sTree.MCTrack:
157 n += 1
158 if mcp.GetP() / u.GeV < pcut:
159 continue
160 printMCTrack(n, sTree.MCTrack)
161
162
163def printFittedTracks() -> None:
164 print(" # converged Ndf chi2/Ndf P Pt MCid")
165 n = -1
166 for ft in sTree.FitTracks:
167 n += 1
168 fitStatus = ft.getFitStatus()
169 fitState = ft.getFittedState()
170 mom = fitState.getMom()
171 print(
172 "%3i %6i %4i %6.3F %6.3F %6.3F %6i "
173 % (
174 n,
175 fitStatus.isFitConverged(),
176 fitStatus.getNdf(),
177 fitStatus.getChi2() / fitStatus.getNdf(),
178 mom.Mag() / u.GeV,
179 mom.Pt() / u.GeV,
180 sTree.fitTrack2MC[n],
181 )
182 )
183
184
185def printParticles() -> None:
186 print(" # P Pt[GeV/c] DOCA[mm] Rsq Vz[m] d1 d2")
187 n = -1
188 for aP in sTree.Particles:
189 n += 1
190 doca = -1.0
191 if aP.GetMother(1) == 99: # DOCA is set
192 doca = aP.T()
193 Rsq = (aP.Vx() / (2.45 * u.m)) ** 2 + (aP.Vy() / ((10.0 / 2.0 - 0.05) * u.m)) ** 2
194 print(
195 "%3i %6.3F %6.3F %9.3F %6.3F %6.3F %4i %4i "
196 % (
197 n,
198 aP.P() / u.GeV,
199 aP.Pt() / u.GeV,
200 doca / u.mm,
201 Rsq,
202 aP.Vz() / u.m,
203 aP.GetDaughter(0),
204 aP.GetDaughter(1),
205 )
206 )
207
208
209class DrawVetoDigi(ROOT.FairTask):
210 "My Fair Task"
211
212 def InitTask(self) -> None:
213 self.comp = ROOT.TEveCompound("Veto Digis")
214 gEve.AddElement(self.comp)
215 sc = gEve.GetScenes()
216 self.evscene = sc.FindChild("Event scene")
217
218 def FinishEvent(self) -> None:
219 pass
220
221 def ExecuteTask(self, option: str = "") -> None:
222 self.comp.DestroyElements()
223 self.comp.OpenCompound()
224 nav = ROOT.gGeoManager.GetCurrentNavigator()
225 for digi in sTree.Digi_SBTHits:
226 if not digi.isValid():
227 continue
228 node = digi.GetNode()
229 shape = node.GetVolume().GetShape()
230 bx = ROOT.TEveBox(node.GetName())
231 bx.SetPickable(ROOT.kTRUE)
232 bx.SetTitle(digi.__repr__())
233 bx.SetMainColor(ROOT.kMagenta + 3)
234 dx, dy, dz = shape.GetDX(), shape.GetDY(), shape.GetDZ()
235 o = shape.GetOrigin()
236 master = array("d", [0, 0, 0])
237 n = 0
238 for edge in [
239 [-dx, -dy, -dz],
240 [-dx, +dy, -dz],
241 [+dx, +dy, -dz],
242 [+dx, -dy, -dz],
243 [-dx, -dy, dz],
244 [-dx, +dy, dz],
245 [+dx, +dy, dz],
246 [+dx, -dy, dz],
247 ]:
248 origin = array("d", [edge[0] + o[0], edge[1] + o[1], edge[2] + o[2]])
249 nav.LocalToMaster(origin, master)
250 bx.SetVertex(n, master[0], master[1], master[2])
251 n += 1
252 self.comp.AddElement(bx)
253 self.comp.CloseCompound()
254 gEve.ElementChanged(self.evscene, True, True)
255
256 def DrawParticle(self, n) -> None:
257 self.comp.OpenCompound()
258 DTrack = ROOT.TEveLine()
259 DTrack.SetPickable(ROOT.kTRUE)
260 DTrack.SetMainColor(ROOT.kCyan)
261 DTrack.SetLineWidth(4)
262 aP = sTree.Particles[n]
263 DTrack.SetTitle(aP.__repr__())
264 DTrack.SetName("Prtcle_" + str(n))
265 DTrack.SetNextPoint(aP.Vx(), aP.Vy(), aP.Vz())
266 lam = (self.Targetz - aP.Vz()) / aP.Pz()
267 DTrack.SetNextPoint(aP.Vx() + lam * aP.Px(), aP.Vy() + lam * aP.Py(), self.Targetz)
268 self.comp.AddElement(DTrack)
269 self.comp.CloseCompound()
270 gEve.ElementChanged(self.evscene, True, True)
271
272
273#
274class DrawTracks(ROOT.FairTask):
275 "My Fair Task"
276
277 def InitTask(self) -> None:
278 # prepare container for fitted tracks
279 self.comp = ROOT.TEveCompound("Tracks")
280 gEve.AddElement(self.comp)
281 self.trackColors = {
282 13: ROOT.kGreen,
283 211: ROOT.kRed,
284 11: ROOT.kOrange,
285 321: ROOT.kMagenta,
286 }
287 dv = top.GetNode("DecayVolume_1")
288 self.z_end = 500.0
289 if dv:
290 ns = dv.GetNodes()
291 try:
292 T1Lid = ns.FindObject("T1Lid_1").GetMatrix()
293 self.z_start = T1Lid.GetTranslation()[2]
294 except AttributeError:
295 self.z_start = 0
296 else:
297 self.z_start = 0
298 muonDet = top.GetNode("MuonDetector_1")
299 if muonDet:
300 self.z_end = muonDet.GetMatrix().GetTranslation()[2] + muonDet.GetVolume().GetShape().GetDZ()
301 elif hasattr(ShipGeo, "MuonStation3"):
302 self.z_end = ShipGeo["MuonStation3"].z
303 elif top.GetNode("VMuonBox_1"):
304 xx = top.GetNode("VMuonBox_1")
305 self.z_end = xx.GetMatrix().GetTranslation()[2] + xx.GetVolume().GetShape().GetDZ()
306 magNode = top.GetNode("MCoil_1")
307 if magNode:
308 self.z_mag = magNode.GetMatrix().GetTranslation()[2]
309 elif hasattr(ShipGeo, "Bfield"):
310 self.z_mag = ShipGeo["Bfield"].z
311 else:
312 self.z_mag = 0
313 self.niter = 100
314 self.dz = (self.z_end - self.z_start) / float(self.niter)
315 self.parallelToZ = ROOT.TVector3(0.0, 0.0, 1.0)
316 sc = gEve.GetScenes()
317 self.evscene = sc.FindChild("Event scene")
318 targetNode = top.GetNode("TargetArea_1")
319 if targetNode:
320 self.Targetz = targetNode.GetMatrix().GetTranslation()[2]
321 elif hasattr(ShipGeo, "target"):
322 self.Targetz = ShipGeo["target"].z0
323 else:
324 self.Targetz = 0
325
326 def FinishEvent(self) -> None:
327 pass
328
329 def ExecuteTask(self, option: str = "") -> None:
330 self.comp.DestroyElements()
331 self.comp.OpenCompound()
332 if (sTree.FindBranch("FitTracks") or sTree.FindBranch("FitTracks_PR")) and len(sTree.FitTracks) > 0:
333 self.DrawFittedTracks()
334 if not sTree.FindBranch("GeoTracks") and len(sTree.MCTrack) > 0 and globals()["withMCTracks"]:
335 if top.GetNode("Tunnel_1"):
336 DrawSimpleMCTracks() # for sndlhc, until more details are simulated
337 else:
338 self.DrawMCTracks()
339 self.comp.CloseCompound()
340 gEve.ElementChanged(self.evscene, True, True)
341
342 def DrawParticle(self, n) -> None:
343 self.comp.OpenCompound()
344 DTrack = ROOT.TEveLine()
345 DTrack.SetPickable(ROOT.kTRUE)
346 DTrack.SetMainColor(ROOT.kCyan)
347 DTrack.SetLineWidth(4)
348 aP = sTree.Particles[n]
349 DTrack.SetTitle(aP.__repr__())
350 DTrack.SetName("Prtcle_" + str(n))
351 DTrack.SetNextPoint(aP.Vx(), aP.Vy(), aP.Vz())
352 lam = (self.Targetz - aP.Vz()) / aP.Pz()
353 DTrack.SetNextPoint(aP.Vx() + lam * aP.Px(), aP.Vy() + lam * aP.Py(), self.Targetz)
354 self.comp.AddElement(DTrack)
355
356 def DrawMCTrack(self, n: int) -> None:
357 self.comp.OpenCompound()
358 fT = sTree.MCTrack[n]
359 DTrack = ROOT.TEveLine()
360 DTrack.SetPickable(ROOT.kTRUE)
361 DTrack.SetTitle(fT.__repr__())
362 p = pdg.GetParticle(fT.GetPdgCode())
363 if p:
364 pName = p.GetName()
365 else:
366 pName = str(fT.GetPdgCode())
367 DTrack.SetName("MCTrck_" + str(n) + "_" + pName)
368 fPos = ROOT.TVector3()
369 fMom = ROOT.TVector3()
370 fT.GetStartVertex(fPos)
371 fT.GetMomentum(fMom)
372 # check for end vertex
373 evVx = False
374 for da in sTree.MCTrack:
375 if da.GetMotherId() == n:
376 evVx = True
377 break
378 DTrack.SetNextPoint(fPos.X(), fPos.Y(), fPos.Z())
379 if evVx and abs(da.GetStartZ() - fPos.Z()) > 1 * u.cm:
380 DTrack.SetNextPoint(da.GetStartX(), da.GetStartY(), da.GetStartZ())
381 else:
382 zEx = 10 * u.m
383 if evVx:
384 zEx = -10 * u.m
385 lam = (zEx + fPos.Z()) / fMom.Z()
386 DTrack.SetNextPoint(fPos.X() + lam * fMom.X(), fPos.Y() + lam * fMom.Y(), zEx + fPos.Z())
387 c = ROOT.kYellow
388 DTrack.SetMainColor(c)
389 DTrack.SetLineWidth(3)
390 self.comp.AddElement(DTrack)
391 self.comp.CloseCompound()
392 gEve.ElementChanged(self.evscene, True, True)
393
394 def DrawMCTracks(self, option: str = "") -> None:
395 n = -1
396 ntot = 0
397 fPos = ROOT.TVector3()
398 fMom = ROOT.TVector3()
399 for fT in sTree.MCTrack:
400 n += 1
401 DTrack = ROOT.TEveLine()
402 DTrack.SetPickable(ROOT.kTRUE)
403 DTrack.SetTitle(fT.__repr__())
404 fT.GetStartVertex(fPos)
405 hitlist = {}
406 hitlist[fPos.Z()] = [fPos.X(), fPos.Y()]
407 # look for HNL
408 if abs(fT.GetPdgCode()) == options.HiddenParticleID:
409 for da in sTree.MCTrack:
410 if da.GetMotherId() == n:
411 break
412 # end vertex of HNL
413 da.GetStartVertex(fPos)
414 hitlist[fPos.Z()] = [fPos.X(), fPos.Y()]
415 # loop over all sensitive volumes to find hits
416 for P in [
417 "vetoPoint",
418 "strawtubesPoint",
419 "ShipRpcPoint",
420 "TargetPoint",
421 "MTCDetPoint",
422 "SiliconTargetPoint",
423 "TimeDetPoint",
424 ]:
425 if not sTree.GetBranch(P):
426 continue
427 c = eval("sTree." + P)
428 for p in c:
429 if p.GetTrackID() == n:
430 if hasattr(p, "LastPoint"):
431 lp = p.LastPoint()
432 if lp.x() == lp.y() and lp.x() == lp.z() and lp.x() == 0:
433 # must be old data, don't expect hit at 0,0,0
434 hitlist[p.GetZ()] = [p.GetX(), p.GetY()]
435 else:
436 hitlist[lp.z()] = [lp.x(), lp.y()]
437 hitlist[2.0 * p.GetZ() - lp.z()] = [
438 2.0 * p.GetX() - lp.x(),
439 2.0 * p.GetY() - lp.y(),
440 ]
441 else:
442 hitlist[p.GetZ()] = [p.GetX(), p.GetY()]
443 if len(hitlist) == 1:
444 if fT.GetMotherId() < 0:
445 continue
446 if abs(sTree.MCTrack[fT.GetMotherId()].GetPdgCode()) == options.HiddenParticleID:
447 # still would like to draw track stub
448 # check for end vertex
449 evVx = False
450 for da in sTree.MCTrack:
451 if da.GetMotherId() == n:
452 evVx = True
453 break
454 if evVx:
455 hitlist[da.GetStartZ()] = [da.GetStartX(), da.GetStartY()]
456 else:
457 zEx = 10 * u.m
458 fT.GetMomentum(fMom)
459 lam = (zEx + fPos.Z()) / fMom.Z()
460 hitlist[zEx + fPos.Z()] = [
461 fPos.X() + lam * fMom.X(),
462 fPos.Y() + lam * fMom.Y(),
463 ]
464 # sort in z
465 lz = list(hitlist.keys())
466 if len(lz) > 1:
467 lz.sort()
468 for z in lz:
469 DTrack.SetNextPoint(hitlist[z][0], hitlist[z][1], z)
470 p = pdg.GetParticle(fT.GetPdgCode())
471 if p:
472 pName = p.GetName()
473 else:
474 pName = str(fT.GetPdgCode())
475 DTrack.SetName("MCTrack_" + str(n) + "_" + pName)
476 c = ROOT.kYellow
477 if abs(fT.GetPdgCode()) == options.HiddenParticleID:
478 c = ROOT.kMagenta
479 DTrack.SetMainColor(c)
480 DTrack.SetLineWidth(3)
481 self.comp.AddElement(DTrack)
482 ntot += 1
483 print("draw ", ntot, " MC tracks")
484
485 def DrawFittedTracks(self, option: str = "") -> None:
486 n, ntot = -1, 0
487 for fT in sTree.FitTracks:
488 n += 1
489 fst = fT.getFitStatus()
490 if not fst.isFitConverged():
491 continue
492 if fst.getNdf() < 20:
493 continue
494 DTrack = ROOT.TEveLine()
495 DTrack.SetPickable(ROOT.kTRUE)
496 DTrack.SetTitle(fT.__repr__())
497 fstate = fT.getFittedState(0)
498 fPos = fstate.getPos()
499 fMom = fstate.getMom()
500 pos = fPos
501 mom = fMom
502 pid = fstate.getPDG()
503 zs = self.z_start
504 for i in range(self.niter):
505 rc, newpos, _newmom = TrackExtrapolateTool.extrapolateToPlane(fT, zs)
506 if rc:
507 DTrack.SetNextPoint(newpos.X(), newpos.Y(), newpos.Z())
508 else:
509 print("error with extrapolation: z=", zs)
510 # use linear extrapolation
511 px, py, pz = mom.X(), mom.Y(), mom.Z()
512 lam = (zs - pos.Z()) / pz
513 DTrack.SetNextPoint(pos.X() + lam * px, pos.Y() + lam * py, zs)
514 zs += self.dz
515 DTrack.SetName("FitTrack_" + str(n))
516 c = ROOT.kWhite
517 if abs(pid) in self.trackColors:
518 c = self.trackColors[abs(pid)]
519 DTrack.SetMainColor(c)
520 DTrack.SetLineWidth(3)
521 self.comp.AddElement(DTrack)
522 ntot += 1
523 print("draw ", ntot, " fitted tracks")
524 n = -1
525 for aP in sTree.Particles:
526 n += 1
527 # check fitted tracks
528 tracksOK = True
529 if aP.GetMother(1) == 99: # DOCA is set
530 if aP.T() > 3 * u.cm:
531 continue
532 for k in range(aP.GetNDaughters()):
533 if k > 1:
534 break # we don't have more than 2tracks/vertex yet, no idea why ROOT sometimes comes up with 4!
535 fT = sTree.FitTracks[aP.GetDaughter(k)]
536 fst = fT.getFitStatus()
537 if not fst.isFitConverged():
538 tracksOK = False
539 if fst.getNdf() < 20:
540 tracksOK = False
541 if not tracksOK:
542 continue
543 DTrack = ROOT.TEveLine()
544 DTrack.SetPickable(ROOT.kTRUE)
545 DTrack.SetMainColor(ROOT.kCyan)
546 DTrack.SetLineWidth(4)
547 DTrack.SetName("Particle_" + str(n))
548 DTrack.SetTitle(aP.__repr__())
549 DTrack.SetNextPoint(aP.Vx(), aP.Vy(), aP.Vz())
550 lam = (self.Targetz - aP.Vz()) / aP.Pz()
551 DTrack.SetNextPoint(aP.Vx() + lam * aP.Px(), aP.Vy() + lam * aP.Py(), self.Targetz)
552 self.comp.AddElement(DTrack)
553
554
555#
556import evd_fillEnergy
557
558
559class IO:
560 def __init__(self) -> None:
561 self.master = tkinter.Tk()
562 self.master.title("SHiP Event Display GUI")
563 self.master.geometry("320x580+165+820")
564 self.fram1 = tkinter.Frame(self.master)
565 b = tkinter.Button(self.fram1, text="Next Event", command=self.nextEvent)
566 b.pack(fill=tkinter.BOTH, expand=1)
567 label = tkinter.Label(self.fram1, text="Event number:")
568 label["relief"] = tkinter.RAISED
569 entry = tkinter.Entry(self.fram1)
570 entry["foreground"] = "blue"
571 label.pack(side=tkinter.LEFT)
572 entry.pack(side=tkinter.RIGHT)
573 self.contents = tkinter.IntVar()
574 # set it to some value
575 self.n = 0
576 self.contents.set(self.n)
577 # tell the entry widget to watch this variable
578 entry["textvariable"] = self.contents
579 # and here we get a callback when the user hits return.
580 # we will have the program print out the value of the
581 # application variable when the user hits return
582 entry.bind("<Key-Return>", self.nextEvent)
583 self.lbut = {}
584 x = "withMC"
585 a = tkinter.IntVar()
586 if globals()["withMCTracks"]:
587 a.set(1)
588 else:
589 a.set(0)
590 self.lbut[x] = tkinter.Checkbutton(self.master, text="with MC Tracks", compound=tkinter.LEFT, variable=a)
591 self.lbut[x].var = a
592 self.lbut[x]["command"] = self.toggleMCTracks
593 self.lbut[x].pack(side=tkinter.TOP)
594 self.geoscene = ROOT.gEve.GetScenes().FindChild("Geometry scene")
595 for v in top.GetNodes():
596 x = v.GetName()
597 a = tkinter.IntVar()
598 assembly = "Assembly" in v.GetVolume().__str__()
599 if v.IsVisible() or (assembly and v.IsVisDaughters()):
600 a.set(1)
601 else:
602 a.set(0)
603 self.lbut[x] = tkinter.Checkbutton(self.master, text=x.replace("_1", ""), compound=tkinter.LEFT, variable=a)
604 self.lbut[x].var = a
605 self.lbut[x]["command"] = lambda x=x: self.toggle(x)
606 self.lbut[x].pack(side=tkinter.BOTTOM)
607 self.fram1.pack()
608 # add ship actions to eve display
609 gEve = ROOT.gEve
610 slot = ROOT.TEveWindow.CreateWindowInTab(gEve.GetBrowser().GetTabLeft())
611 slot.SetShowTitleBar(ROOT.kFALSE)
612 packs = slot.MakePack()
613 packs.SetShowTitleBar(ROOT.kFALSE)
614 packs.SetElementName("SHiP actions")
615 packs.SetHorizontal()
616 slot = packs.NewSlot()
617 frame = slot.MakeFrame()
618 frame.SetElementName("commands")
619 frame.SetShowTitleBar(ROOT.kFALSE)
620 cf = frame.GetGUICompositeFrame()
621 hf = ROOT.TGVerticalFrame(cf)
622 hf.SetCleanup(ROOT.kLocalCleanup)
623 hf.SetWidth(150)
624 cf.AddFrame(hf)
625 guiFrame = ROOT.TGVerticalFrame(hf)
626 hf.AddFrame(guiFrame, ROOT.TGLayoutHints(ROOT.kLHintsExpandX))
627 guiFrame.SetCleanup(ROOT.kDeepCleanup)
628 b = ROOT.TGTextButton(guiFrame, "Add particle follower")
629 b.SetWidth(150)
630 b.SetToolTipText("start new window with top projection and energy loss")
631 b.SetCommand('TPython::ExecScript("' + os.environ["FAIRSHIP"] + '/macro/evd_addParticleFollower.py")')
632 guiFrame.AddFrame(b, ROOT.TGLayoutHints(ROOT.kLHintsExpandX))
633 bn = ROOT.TGTextButton(guiFrame, "fill histogram")
634 bn.SetWidth(150)
635 bn.SetToolTipText("Fill histogram with energy along flight path")
636 bn.SetCommand('TPython::ExecScript("' + os.environ["FAIRSHIP"] + '/macro/evd_fillEnergy.py")')
637 guiFrame.AddFrame(bn, ROOT.TGLayoutHints(ROOT.kLHintsExpandX))
638 bt = ROOT.TGTextButton(guiFrame, "switch transparent mode on/off")
639 bt.SetWidth(150)
640 bt.SetToolTipText("switch transparent mode on/off for better visibility of tracks")
641 bt.SetCommand('TPython::ExecScript("' + os.environ["FAIRSHIP"] + '/macro/evd_transparentMode.py")')
642 guiFrame.AddFrame(bt, ROOT.TGLayoutHints(ROOT.kLHintsExpandX))
643 bnx = ROOT.TGTextButton(guiFrame, "next event")
644 bnx.SetWidth(150)
645 bnx.SetToolTipText("click for next event")
646 bnx.SetCommand('TPython::ExecScript("' + os.environ["FAIRSHIP"] + '/macro/evd_nextEvent.py")')
647 guiFrame.AddFrame(bnx, ROOT.TGLayoutHints(ROOT.kLHintsExpandX))
648 #
649 cf.MapSubwindows()
650 cf.Layout()
651 cf.MapWindow()
652
653 def nextEvent(self, event=None) -> None:
654 i = int(self.contents.get())
655 if i == self.n:
656 self.n += 1
657 else:
658 self.n = i
659 self.contents.set(self.n)
660 SHiPDisplay.NextEvent(self.n)
661
662 def toggleMCTracks(self) -> None:
663 tl = fRun.GetMainTask().GetListOfTasks()
664 geoTask = tl.FindObject("GeoTracks")
665 if globals()["withMCTracks"]:
666 globals()["withMCTracks"] = False
667 self.lbut["withMC"].var.set(1)
668 if geoTask:
669 geoTask.SetActive(0)
670 else:
671 globals()["withMCTracks"] = True
672 self.lbut["withMC"].var.set(0)
673 if geoTask:
674 geoTask.SetActive(1)
675
676 def toggle(self, x) -> None:
677 v = top.GetNode(x)
678 assembly = "Assembly" in v.GetVolume().__str__()
679 if v.IsVisible() > 0 or (assembly and v.IsVisDaughters() > 0):
680 print("switch off ", x)
681 v.SetVisibility(0)
682 v.SetVisDaughters(0)
683 self.lbut[x].var.set(0)
684 else:
685 print("switch on ", x)
686 if assembly:
687 v.SetVisDaughters(1)
688 else:
689 v.SetVisibility(1)
690 self.lbut[x].var.set(1)
691 gEve.ElementChanged(self.geoscene, True, True)
692 for v in top.GetNodes():
693 x = v.GetName()
694 if x in self.lbut:
695 assembly = "Assembly" in v.GetVolume().__str__()
696 if v.IsVisible() > 0 or (assembly and v.IsVisDaughters() > 0):
697 self.lbut[x].var.set(1)
698 else:
699 self.lbut[x].var.set(0)
700
701
702#
703class EventLoop(ROOT.FairTask):
704 "My Fair Task"
705
706 def InitTask(self) -> None:
707 self.n = 0
708 self.first = True
709 if sGeo.GetVolume("volTarget"):
712 self.veto.InitTask()
714 self.tracks.InitTask()
715 # create SHiP GUI
716 self.ioBar = IO()
718 v1 = gEve.GetDefaultViewer()
719 v1.GetEveFrame().HideAllDecorations()
720 tr = gEve.GetBrowser().GetTabRight()
721 t0 = tr.GetTabTab(0)
722 t0.SetText(ROOT.TGString("3D"))
723
724 def NextEvent(self, i: int = -1) -> None:
725 if i < 0:
726 self.n += 1
727 else:
728 self.n = i
729 fRun.Run(self.n, self.n + 1) # go for first event
730 # check if tracks are made from real pattern recognition
731 if sTree.GetBranch("FitTracks_PR"):
732 sTree.FitTracks = sTree.FitTracks_PR
733 if sTree.GetBranch("fitTrack2MC_PR"):
734 sTree.fitTrack2MC = sTree.fitTrack2MC_PR
735 if sTree.GetBranch("Particles_PR"):
736 sTree.Particles = sTree.Particles_PR
737 if hasattr(self, "tracks"):
738 self.tracks.ExecuteTask()
739 if sTree.FindBranch("Digi_SBTHits"):
740 self.veto.ExecuteTask()
741 if ROOT.gROOT.FindObject("Root Canvas EnergyLoss"):
743 print("Event %i ready" % (self.n))
744 # make pointsets pickable
745 for x in mcHits:
746 p = ROOT.gEve.GetCurrentEvent().FindChild(mcHits[x].GetName())
747 if p:
748 p.SetPickable(ROOT.kTRUE)
749 p.SetTitle(p.__repr__())
750
751 def rotateView(self, hor: float | int = 0, ver: float | int = 0) -> None:
752 v = ROOT.gEve.GetDefaultGLViewer()
753 cam = v.CurrentCamera()
754 cam.Reset()
755 if hor != 0 or ver != 0:
756 cam.RotateRad(hor, ver)
757 v.DoDraw()
758
759 def topView(self) -> None:
760 self.rotateView(ROOT.TMath.Pi() / 2.0, 0.0) # rotation around z axis
761
762 def bottomView(self) -> None:
763 self.rotateView(-ROOT.TMath.Pi() / 2.0, 0.0) # rotation around z axis
764
765 def frontView(self) -> None:
766 self.rotateView(0.0, ROOT.TMath.Pi() / 2.0) # rotation around y or x axis
767
768 def backView(self) -> None:
769 self.rotateView(0.0, -ROOT.TMath.Pi() / 2.0) # rotation around y or x axis
770
771 def leftView(self) -> None:
772 self.rotateView(0.0, ROOT.TMath.Pi()) # rotation around y or x axis
773
774 def rightView(self) -> None:
775 self.rotateView(0.0, ROOT.TMath.Pi()) # rotation around y or x axis
776
777 def transparentMode(self, mode: str = "on") -> None:
778 for m in transparentMaterials:
779 mat = ROOT.gGeoManager.GetMaterial(m)
780 if not mat:
781 continue
782 if mode.lower() == "on" or mode == 1:
783 mat.SetTransparency(transparentMaterials[m])
784 self.TransparentMode = 1
785 else:
786 mat.SetTransparency("\x00")
787 self.TransparentMode = 0
788 sc = gEve.GetScenes()
789 geoscene = sc.FindChild("Geometry scene")
790 if geoscene:
791 gEve.ElementChanged(geoscene, True, True)
792
793
794# add projections DOES NOT WORK YET AS FORESEEN, under investigation. 30.11.2016
795def projection() -> None:
796 # if 1>0:
797 # camera
798 s = ROOT.gEve.SpawnNewScene("Projected Event")
799 ROOT.gEve.GetDefaultViewer().AddScene(s)
800 v = ROOT.gEve.GetDefaultGLViewer()
801 v.SetCurrentCamera(ROOT.TGLViewer.kCameraOrthoXOY)
802 cam = v.CurrentCamera()
803 cam.SetZoomMinMax(0.2, 20)
804 # projections
805 mng = ROOT.TEveProjectionManager(ROOT.TEveProjection.kPT_RPhi)
806 s.AddElement(mng)
807 axes = ROOT.TEveProjectionAxes(mng)
808 axes.SetTitle("TEveProjections demo")
809 s.AddElement(axes)
810 ROOT.gEve.AddToListTree(axes, ROOT.kTRUE)
811 ROOT.gEve.AddToListTree(mng, ROOT.kTRUE)
812
813
815 # if 1>0:
816 v = gEve.GetViewers()
817 vw = v.FindChild("Viewer 1")
818 if vw:
819 vw.SetName("3d")
820 sev = ROOT.gEve.SpawnNewViewer("Scaled 2D")
821 smng = ROOT.TEveProjectionManager(ROOT.TEveProjection.kPP_Plane)
822 sp = smng.GetProjection()
823 sp.SetUsePreScale(ROOT.kTRUE)
824 sp.AddPreScaleEntry(2, 100000000.0, 0.1)
825 ss = ROOT.gEve.SpawnNewScene("Scaled Geom")
826 sev.AddScene(ss)
827 ss.AddElement(smng)
828 N = sGeo.GetTopNode()
829 TNod = ROOT.TEveGeoTopNode(sGeo, N, 1, 3, 10)
830 ss.AddElement(TNod)
831 eventscene = ROOT.gEve.SpawnNewScene("Scaled event")
832 eventscene.AddElement(ROOT.FairEventManager.Instance())
833 sev.AddScene(eventscene)
834 eventscene.AddElement(smng)
835 ROOT.gEve.GetBrowser().GetTabRight().SetTab(1)
836 ROOT.gEve.FullRedraw3D(ROOT.kTRUE)
837
838
839def storeCameraSetting(fname: str = "camSetting.root") -> None:
840 f = ROOT.TFile.Open(fname, "RECREATE")
841 cam = ROOT.gEve.GetDefaultGLViewer().CurrentCamera()
842 cam.Write()
843 f.Close()
844
845
846def readCameraSetting(fname: str = "camSetting.root") -> None:
847 f = ROOT.TFile.Open(fname)
848 cam = ROOT.gEve.GetDefaultGLViewer().CurrentCamera()
849 f.GetKey(cam.ClassName()).Read(cam)
850 cam.IncTimeStamp()
851 gEve.GetDefaultGLViewer().RequestDraw()
852 f.Close()
853
854
855def speedUp() -> None:
856 for x in ["wire", "gas", "rockD", "rockS", "rockSFe"]:
857 xvol = sGeo.GetVolume(x)
858 if xvol:
859 xvol.SetVisibility(0)
860 for k in range(1, 7):
861 va = sGeo.GetVolume("T" + str(k))
862 if not va:
863 continue
864 for x in va.GetNodes():
865 nm = x.GetName()
866 if not nm.find("Inner") < 0 and k < 3:
867 x.SetVisDaughters(False)
868 x.SetVisibility(False)
869 if not nm.find("LiSc") < 0:
870 x.SetVisDaughters(False)
871 if not nm.find("RibPhi") < 0:
872 x.SetVisDaughters(False)
873
874
875# set display properties for tau nu target
876def DisplayNuDetector() -> None:
877 for x in ["Wall"]:
878 xvol = sGeo.GetVolume(x)
879 if not xvol:
880 continue
881 xvol.SetVisDaughters(0)
882 xvol.SetVisibility(1)
883 sc = gEve.GetScenes()
884 geoscene = sc.FindChild("Geometry scene")
885 gEve.ElementChanged(geoscene, True, True)
886
887
888def switchOff(tag) -> None:
889 sc = gEve.GetScenes()
890 geoscene = sc.FindChild("Geometry scene")
891 for v in top.GetNodes():
892 vname = v.GetName()
893 if not vname.find(tag) < 0:
894 v.SetVisibility(0)
895 v.SetVisDaughters(0)
896 gEve.ElementChanged(geoscene, True, True)
897
898
899def switchOn(tag) -> None:
900 sc = gEve.GetScenes()
901 geoscene = sc.FindChild("Geometry scene")
902 for v in top.GetNodes():
903 vname = v.GetName()
904 if not vname.find(tag) < 0:
905 print("switch on ", vname)
906 v.SetVisibility(1)
907 v.SetVisDaughters(1)
908 gEve.ElementChanged(geoscene, True, True)
909
910
912 sc = gEve.GetScenes()
913 geoscene = sc.FindChild("Geometry scene")
914 v = sGeo.FindVolumeFast("vleft")
915 v.SetVisibility(0)
916 v.SetVisDaughters(0)
917 for v in sGeo.GetListOfVolumes():
918 if v.GetName().find("wallVeto") > 0:
919 v.SetVisibility(0)
920 v.SetVisDaughters(0)
921 gEve.ElementChanged(geoscene, True, True)
922
923
924# switch off drawing of rock
925def switchOffRock() -> None:
926 sc = gEve.GetScenes()
927 geoscene = sc.FindChild("Geometry scene")
928 for x in ["rockD", "rockS"]:
929 v = sGeo.FindVolumeFast(x)
930 v.SetVisibility(0)
931 gEve.ElementChanged(geoscene, True, True)
932
933
934def switchOffAll(exc) -> None:
935 sc = gEve.GetScenes()
936 geoscene = sc.FindChild("Geometry scene")
937 for v in top.GetNodes():
938 vname = v.GetName()
939 if not vname.find("cave") < 0:
940 continue
941 todo = True
942 for tag in exc:
943 if not tag.find(vname) < 0:
944 todo = False
945 if todo:
946 v.SetVisibility(0)
947 v.SetVisDaughters(0)
948 gEve.ElementChanged(geoscene, True, True)
949
950
951def switchOnAll(exc) -> None:
952 sc = gEve.GetScenes()
953 geoscene = sc.FindChild("Geometry scene")
954 for v in top.GetNodes():
955 vname = v.GetName()
956 if not vname.find("cave") < 0:
957 continue
958 todo = True
959 for tag in exc:
960 if not tag.find(vname) < 0:
961 todo = False
962 if todo:
963 v.SetVisibility(1)
964 v.SetVisDaughters(1)
965 gEve.ElementChanged(geoscene, True, True)
966
967
968def select(pattern):
969 exc = []
970 for v in sGeo.GetListOfVolumes():
971 vname = v.GetName()
972 if not vname.find(pattern) < 0:
973 exc.append(vname)
974 return exc
975
976
977def search(lvdict, tag) -> None:
978 for x in lvdict:
979 if not x.find(tag) < 0:
980 print(x)
981
982
983def rename(name: str = "ship.TGeant4.root") -> None:
984 f = ROOT.TFile(name, "UPDATE")
985 t = f.Get("cbmsim")
986 for x in t.GetListOfBranches():
987 nm = x.GetName().replace("_1", "")
988 x.SetName(nm)
989 t.Write()
990 f.Close()
991
992
993class Rulers(ROOT.FairTask):
994 "add Ruler"
995
996 def __init__(self) -> None:
997 self.ruler = ROOT.TEveCompound("Rulers")
998 gEve.AddElement(self.ruler)
999
1000 def show(self, xy: int = 0, ticks: int = 5) -> None:
1001 self.ruler.DestroyElements()
1002 self.ruler.OpenCompound()
1003 xpos, ypos = -500.0, -1500.0
1004 zstart = ShipGeo.target.z0
1005 zlength = ShipGeo.MuonStation3.z - zstart + 10 * u.m
1006 a1 = ROOT.TEveLine()
1007 a1.SetNextPoint(xpos, ypos, zstart)
1008 a1.SetNextPoint(xpos, ypos, zstart + zlength)
1009 a1.SetMainColor(ROOT.kAzure - 9)
1010 a1.SetLineWidth(30)
1011 # self.ruler.AddElement(a1)
1012 z = zstart
1013 for i in range(int(zlength / 100 / ticks)):
1014 m = ROOT.TEveLine()
1015 m.SetNextPoint(xpos, ypos, z)
1016 m.SetNextPoint(xpos - 1 * u.m, ypos, z)
1017 m.SetMainColor(ROOT.kRed)
1018 m.SetLineWidth(5)
1019 self.ruler.AddElement(m)
1020 t1 = ROOT.TEveText(str(i * ticks) + "m")
1021 t1.SetMainColor(ROOT.kGray + 3)
1022 t1.SetFontSize(5)
1023 t1.RefMainTrans().SetPos(xpos - 0.1 * u.m, ypos + 0.2 * u.m, z)
1024 self.ruler.AddElement(t1)
1025 z += ticks * u.m
1026 xpos, ypos = 0.0, 0.0
1027 if xy == 0:
1028 z = ShipGeo.MuonStation3.z + 6 * u.m
1029 else:
1030 z = xy
1031 ylength = 7 * u.m
1032 a2 = ROOT.TEveLine()
1033 a2.SetNextPoint(xpos, -ylength, z)
1034 a2.SetNextPoint(xpos, ylength, z)
1035 a2.SetMainColor(ROOT.kAzure - 9)
1036 a2.SetLineWidth(30)
1037 # self.ruler.AddElement(a2)
1038 ypos = -ylength
1039 for i in range(-int(ylength / 100), int(ylength / 100), 1):
1040 m = ROOT.TEveLine()
1041 m.SetNextPoint(xpos, ypos, z)
1042 m.SetNextPoint(xpos + 0.05 * u.m, ypos, z)
1043 m.SetMainColor(ROOT.kRed)
1044 m.SetLineWidth(3)
1045 self.ruler.AddElement(m)
1046 t1 = ROOT.TEveText(str(i) + "m")
1047 t1.SetMainColor(ROOT.kGray + 3)
1048 t1.SetFontSize(5)
1049 t1.RefMainTrans().SetPos(xpos - 0.5 * u.m, ypos, z)
1050 self.ruler.AddElement(t1)
1051 ypos += 1 * u.m
1052 ty = ROOT.TEveText("y-axis")
1053 ty.SetFontSize(10)
1054 ty.RefMainTrans().SetPos(0.0, ypos + 1 * u.m, z)
1055 ty.SetMainColor(ROOT.kRed - 2)
1056 self.ruler.AddElement(ty)
1057 xpos, ypos = 0.0, 0.0
1058 if xy == 0:
1059 z = ShipGeo.MuonStation3.z + 10 * u.m
1060 xlength = 3 * u.m
1061 a3 = ROOT.TEveLine()
1062 a3.SetNextPoint(-xlength, 0, z)
1063 a3.SetNextPoint(xlength, 0, z)
1064 a3.SetMainColor(ROOT.kAzure - 9)
1065 a3.SetLineWidth(30)
1066 # self.ruler.AddElement(a3)
1067 xpos = -xlength
1068 for i in range(-int(xlength / 100), int(xlength / 100), 1):
1069 m = ROOT.TEveLine()
1070 m.SetNextPoint(xpos, ypos, z)
1071 m.SetNextPoint(xpos, ypos - 0.05 * u.m, z)
1072 m.SetMainColor(ROOT.kRed)
1073 m.SetLineWidth(3)
1074 self.ruler.AddElement(m)
1075 t1 = ROOT.TEveText(str(i) + "m")
1076 t1.SetMainColor(ROOT.kGray + 3)
1077 t1.SetFontSize(5)
1078 t1.RefMainTrans().SetPos(xpos, ypos - 0.1 * u.m, z)
1079 self.ruler.AddElement(t1)
1080 xpos += 1 * u.m
1081 tx = ROOT.TEveText("x-axis")
1082 tx.SetFontSize(10)
1083 tx.RefMainTrans().SetPos(xpos + 1 * u.m, 0.0, z)
1084 tx.SetMainColor(ROOT.kRed - 2)
1085 self.ruler.AddElement(tx)
1086 t1 = ROOT.TEveText("SHiP")
1087 t1.SetFontSize(200)
1088 t1.RefMainTrans().SetPos(0.0, 600.0, ShipGeo.TrackStation1.z - 10 * u.m)
1089 t1.PtrMainTrans().RotateLF(1, 3, ROOT.TMath.PiOver2())
1090 t1.SetMainColor(ROOT.kOrange - 2)
1091 t1.SetFontMode(ROOT.TGLFont.kExtrude)
1092 t1.SetLighting(ROOT.kTRUE)
1093 self.ruler.AddElement(t1)
1094 self.ruler.CloseCompound()
1095 sc = ROOT.gEve.GetScenes()
1096 geoscene = sc.FindChild("Geometry scene")
1097 ROOT.gEve.ElementChanged(geoscene, True, True)
1098
1099 def remove(self) -> None:
1100 self.ruler.DestroyElements()
1101
1102
1103def mydebug() -> None:
1104 t = g.FindObjectAny("cbmsim")
1105 nev = t.GetEntriesFast()
1106 t.GetEntry(0)
1107 # Loop over Geo tracks
1108 for i in range(min(5, nev)):
1109 t.GetEntry(i)
1110 for gTr in t.GeoTracks:
1111 gTr.Print()
1112 gTr.GetParticle()
1113 lorv = ROOT.TLorentzVector()
1114 print(
1115 "xyz E pxpypz",
1116 gTr.GetPoint(0)[0],
1117 gTr.GetPoint(0)[1],
1118 gTr.GetPoint(0)[2],
1119 lorv.E(),
1120 lorv.Px(),
1121 lorv.Py(),
1122 lorv.Pz(),
1123 )
1124 # Loop over MC tracks
1125 for i in range(min(5, nev)):
1126 t.GetEntry(i)
1127 for gMCTr in t.MCTrack:
1128 gMCTr.Print()
1129 print(gMCTr.GetPdgCode(), gMCTr.GetMass(), gMCTr.GetP())
1130 # MC event header
1131 for i in range(nev):
1132 t.GetEntry(i)
1133 print(
1134 t.MCEventHeader.GetEventID(),
1135 t.MCEventHeader.GetRunID(),
1136 t.MCEventHeader.GetZ(),
1137 )
1138 # Load geometry
1139 sGeo = ROOT.gGeoManager
1140 cave = sGeo.GetTopVolume()
1141 cave.Draw("ogl")
1142 # eve
1143 gEve = ROOT.gEve
1144 #
1145 sc = gEve.GetScenes()
1146 geoscene = sc.FindChild("Geometry scene")
1147 topnode = geoscene.FindChild("cave_1")
1148 topnode.SetVisLevel(4)
1149 gEve.ElementChanged(geoscene, True, True)
1150
1151
1152def debugStraw(n) -> None:
1153 sGeo = ROOT.gGeoManager
1154 vols = sGeo.GetListOfVolumes()
1155 sTree = g.FindObjectAny("cbmsim")
1156 sTree.GetEntry(n)
1157 for s in sTree.strawtubesPoint:
1158 print(vols[s.GetDetectorID() - 1].GetName())
1159
1160
1161# ----Load the default libraries------
1162ROOT.gSystem.Load("libEGPythia6.so")
1163ROOT.gSystem.Load("libPythia6.so")
1164ROOT.gSystem.Load("libpythia8.so")
1165
1166ROOT.gInterpreter.Declare('#include "VectorMCPointSource.h"')
1167
1168# ----- Reconstruction run -------------------------------------------
1169fRun = ROOT.FairRunAna()
1170if options.geoFile:
1171 fRun.SetGeomFile(options.geoFile)
1172
1173inFile = ROOT.FairFileSource(options.InputFile)
1174fRun.SetSource(inFile)
1175if options.OutputFile is None:
1176 options.OutputFile = ROOT.TMemFile("event_display_output", "recreate")
1177fRun.SetSink(ROOT.FairRootFileSink(options.OutputFile))
1178
1179if options.ParFile:
1180 rtdb = fRun.GetRuntimeDb()
1181 parInput1 = ROOT.FairParRootFileIo()
1182 parInput1.open(options.ParFile)
1183 rtdb.setFirstInput(parInput1)
1184
1185fMan = ROOT.FairEventManager()
1186fMan.SetMaxEnergy(400.0) # default is 25 GeV only !
1187fMan.SetMinEnergy(0.1) # 100 MeV
1188fMan.SetEvtMaxEnergy(400.0) # what is the difference between EvtMaxEnergy and MaxEnergy ?
1189fMan.SetPriOnly(False) # display everything
1190
1191# ----------------------Tracks and points -------------------------------------
1192verbose = 0 # 3 lot of output
1193if withGeo:
1194 Track = ROOT.FairMCTracksDraw("Monte-Carlo Tracks")
1195 GTrack = ROOT.FairGeoTracksDraw("GeoTracks")
1196 fMan.AddTask(GTrack)
1197 fMan.AddTask(Track)
1198
1199# Load Shipgeo dictionary written by run_simScript.py
1200ShipGeo = load_from_root_file(fRun.GetGeoFile(), "ShipGeo")
1201
1202# Check which MC point branches exist in the input file
1203_tmpFile = ROOT.TFile.Open(options.InputFile)
1204_tmpTree = _tmpFile.Get("cbmsim") if _tmpFile else None
1205
1206mcHits = {}
1207_candidates = {
1208 "VetoPoints": ("vetoPoint", ROOT.kBlue, ROOT.kFullDiamond),
1209 "TimeDetPoints": ("TimeDetPoint", ROOT.kBlue, ROOT.kFullDiamond),
1210 "StrawPoints": ("strawtubesPoint", ROOT.kGreen, ROOT.kFullCircle),
1211 "TargetPoints": ("TargetPoint", ROOT.kRed, ROOT.kFullSquare),
1212 "MTCDetPoint": ("MTCDetPoint", ROOT.kGreen, ROOT.kFullSquare),
1213 "SiliconTargetPoint": ("SiliconTargetPoint", ROOT.kCyan, ROOT.kFullSquare),
1214}
1215for key, (branch, colour, marker) in _candidates.items():
1216 if _tmpTree and _tmpTree.GetBranch(branch):
1217 source = ROOT.VectorMCPointSource[branch](branch)
1218 mcHits[key] = ROOT.FairMCPointDraw(branch, source, colour, marker)
1219
1220if _tmpFile:
1221 _tmpFile.Close()
1222
1223for x in mcHits:
1224 fMan.AddTask(mcHits[x])
1225
1226fMan.Init(1, 4, 10) # default Init(visopt=1, vislvl=3, maxvisnds=10000), ecal display requires vislvl=4
1227# visopt, set drawing mode :
1228# option=0 (default) all nodes drawn down to vislevel
1229# option=1 leaves and nodes at vislevel drawn
1230# option=2 path is drawn
1231# vislvl
1232#
1233fRman = ROOT.FairRootManager.Instance()
1234sTree = fRman.GetInChain()
1235if options.recoFile and _file_accessible(options.recoFile):
1236 sTree.AddFriend("ship_reco_sim", options.recoFile)
1237lsOfGlobals = ROOT.gROOT.GetListOfGlobals()
1238lsOfGlobals.Add(sTree)
1239sGeo = ROOT.gGeoManager
1240top = sGeo.GetTopVolume()
1241# manipulate colors and transparency before scene created
1242speedUp()
1243gEve = ROOT.gEve
1244
1245if hasattr(ShipGeo, "Bfield"):
1246 if hasattr(ShipGeo.Bfield, "fieldMap"):
1247 ROOT.gSystem.Load("libG4clhep.so")
1248 ROOT.gSystem.Load("libgeant4vmc.so")
1249 import geomGeant4
1250
1251 fieldMaker = geomGeant4.addVMCFields(ShipGeo, "", True, withVirtualMC=False)
1252 bfield = ROOT.genfit.FairShipFields()
1253 bfield.setField(fieldMaker.getGlobalField())
1254 else:
1255 bellField = ROOT.ShipBellField(
1256 "bellfield", ShipGeo.Bfield.max, ShipGeo.Bfield.z, 2, ShipGeo.Bfield.y / 2.0 * u.m
1257 )
1258 compField = ROOT.ShipCompField("compfield", bellField)
1259 bfield = ROOT.genfit.FairShipFields()
1260 bfield.setField(compField)
1261 geoMat = ROOT.genfit.TGeoMaterialInterface()
1262 ROOT.genfit.MaterialEffects.getInstance().init(geoMat)
1263 fM = ROOT.genfit.FieldManager.getInstance()
1264 fM.init(bfield)
1265
1266import TrackExtrapolateTool
1267
1268br = gEve.GetBrowser()
1269br.HideBottomTab() # make more space for graphics
1270br.SetWindowName("SHiP Eve Window")
1271
1272# switchOff('RockD')
1273if sGeo.FindVolumeFast("T2LiSc"):
1275rulers = Rulers()
1276SHiPDisplay = EventLoop()
1277import eveGlobal
1278
1279eveGlobal.SHiPDisplay = SHiPDisplay
1280SHiPDisplay.SetName("SHiP Displayer")
1281lsOfGlobals.Add(SHiPDisplay)
1282SHiPDisplay.InitTask()
1283
1284# SHiPDisplay.NextEvent(0)
1285
1286print("Help on GL viewer can be found by pressing Help button followed by help on GL viewer")
1287print("With the camera button, you can switch to different views.")
1288# short cuts
1289# w go to wire frame
1290# r smooth display
1291# t technical display
1292# e black<->white background
1293# j zoom in
1294# k zoom out
1295# d GL debug mode
1296
1297
1298# fGeo.SetNsegments(10) # can help a bit in case of performance problems
1299def DrawCharmTracks() -> None:
1300 i = -1
1301 for aTrack in sTree.MCTrack:
1302 i += 1
1303 if i < 2:
1304 continue
1305 if aTrack.GetMotherId() == 1:
1306 pa = pdg.GetParticle(sTree.MCTrack[i].GetPdgCode())
1307 if pa.Lifetime() > 1.0e-12:
1308 print(sTree.MCTrack[i])
1309 SHiPDisplay.tracks.DrawMCTrack(i)
1310
1311
1313 comp = SHiPDisplay.tracks.comp
1314 comp.OpenCompound()
1315 n = -1
1316 ntot = 0
1317 fPos = ROOT.TVector3()
1318 fMom = ROOT.TVector3()
1319 delZ = 10 * u.m
1320 for fT in sTree.MCTrack:
1321 n += 1
1322 DTrack = ROOT.TEveLine()
1323 DTrack.SetPickable(ROOT.kTRUE)
1324 DTrack.SetTitle(fT.__repr__())
1325 fT.GetStartVertex(fPos)
1326 fT.GetMomentum(fMom)
1327 hitlist = {}
1328 hitlist[fPos.Z()] = [fPos.X(), fPos.Y()]
1329 z = fPos.Z() + delZ
1330 slx, sly = fMom.X() / fMom.Z(), fMom.Y() / fMom.Z()
1331 hitlist[z] = [fPos.X() + slx * delZ, fPos.Y() + sly * delZ]
1332 for z in hitlist:
1333 DTrack.SetNextPoint(hitlist[z][0], hitlist[z][1], z)
1334 p = pdg.GetParticle(fT.GetPdgCode())
1335 if p:
1336 pName = p.GetName()
1337 else:
1338 pName = str(fT.GetPdgCode())
1339 DTrack.SetName("MCTrack_" + str(n) + "_" + pName)
1340 c = ROOT.kYellow
1341 DTrack.SetMainColor(c)
1342 DTrack.SetLineWidth(3)
1343 comp.AddElement(DTrack)
1344 ntot += 1
1345 comp.CloseCompound()
1346 gEve.ElementChanged(SHiPDisplay.tracks.evscene, True, True)
1347
1348
1350 r,
1351 x: float,
1352 y: float,
1353 z,
1354 angle,
1355 txt: str,
1356 size: int = 200,
1357 color=ROOT.kBlue,
1358 mode=ROOT.TGLFont.kExtrude,
1359 light=ROOT.kTRUE,
1360) -> None:
1361 tt = ROOT.TEveText(txt)
1362 tt.SetFontSize(size)
1363 tt.RefMainTrans().SetPos(x, y, z)
1364 tt.PtrMainTrans().RotateLF(1, 3, angle)
1365 tt.SetMainColor(color)
1366 tt.SetFontMode(mode)
1367 tt.SetLighting(light)
1368 r.AddElement(tt)
1369
1370
1371def PRVersion() -> None:
1373 for x in [
1374 "moreShieldingSide",
1375 "moreShieldingTopBot",
1376 "CoatWall",
1377 "CoatVol",
1378 "AbsorberVol",
1379 ]:
1380 vol = ROOT.gGeoManager.FindVolumeFast(x)
1381 vol.SetVisibility(0)
1382 ROOT.gGeoManager.GetMaterial("Concrete").SetTransparency(0)
1383 r = rulers.ruler
1384 ticks = 5
1385 r.DestroyElements()
1386 r.OpenCompound()
1387 xpos, ypos = -500.0, -1500.0
1388 zstart = ShipGeo.target.z0
1389 zlength = ShipGeo.MuonStation3.z - zstart + 10 * u.m
1390 z = zstart
1391 for i in range(int(zlength / 100 / ticks)):
1392 m = ROOT.TEveLine()
1393 m.SetNextPoint(xpos, ypos, z)
1394 m.SetNextPoint(xpos - 1 * u.m, ypos, z)
1395 m.SetMainColor(ROOT.kRed)
1396 m.SetLineWidth(5)
1397 r.AddElement(m)
1398 t1 = ROOT.TEveText(str(i * ticks) + "m")
1399 t1.SetMainColor(ROOT.kGray + 3)
1400 t1.SetFontSize(5)
1401 t1.RefMainTrans().SetPos(xpos - 0.1 * u.m, ypos + 0.2 * u.m, z)
1402 r.AddElement(t1)
1403 z += ticks * u.m
1404 xpos, ypos = 0.0, 0.0
1405 z = ShipGeo.MuonStation3.z + 6 * u.m
1406 ylength = 7 * u.m
1407 ypos = -ylength
1408 for i in range(-int(ylength / 100), int(ylength / 100), 1):
1409 m = ROOT.TEveLine()
1410 m.SetNextPoint(xpos, ypos, z)
1411 m.SetNextPoint(xpos + 0.05 * u.m, ypos, z)
1412 m.SetMainColor(ROOT.kRed)
1413 m.SetLineWidth(3)
1414 r.AddElement(m)
1415 t1 = ROOT.TEveText(str(i) + "m")
1416 t1.SetMainColor(ROOT.kGray + 3)
1417 t1.SetFontSize(5)
1418 t1.RefMainTrans().SetPos(xpos - 0.5 * u.m, ypos, z)
1419 r.AddElement(t1)
1420 ypos += 1 * u.m
1421 ty = ROOT.TEveText("y-axis")
1422 ty.SetFontSize(10)
1423 ty.RefMainTrans().SetPos(0.0, ypos + 1 * u.m, z)
1424 ty.SetMainColor(ROOT.kRed - 2)
1425 r.AddElement(ty)
1426 xpos, ypos = 0.0, 0.0
1427 z = ShipGeo.MuonStation3.z + 10 * u.m
1428 xlength = 3 * u.m
1429 xpos = -xlength
1430 for i in range(-int(xlength / 100), int(xlength / 100), 1):
1431 m = ROOT.TEveLine()
1432 m.SetNextPoint(xpos, ypos, z)
1433 m.SetNextPoint(xpos, ypos - 0.05 * u.m, z)
1434 m.SetMainColor(ROOT.kRed)
1435 m.SetLineWidth(3)
1436 r.AddElement(m)
1437 t1 = ROOT.TEveText(str(i) + "m")
1438 t1.SetMainColor(ROOT.kGray + 3)
1439 t1.SetFontSize(5)
1440 t1.RefMainTrans().SetPos(xpos, ypos - 0.1 * u.m, z)
1441 r.AddElement(t1)
1442 xpos += 1 * u.m
1443 tx = ROOT.TEveText("x-axis")
1444 tx.SetFontSize(10)
1445 tx.RefMainTrans().SetPos(xpos + 1 * u.m, 0.0, z)
1446 tx.SetMainColor(ROOT.kRed - 2)
1447 r.AddElement(tx)
1448 rotAngle = ROOT.TMath.Pi() + ROOT.TMath.PiOver2() * 5.0 / 2.0
1450 r,
1451 0.0,
1452 900.0,
1453 ShipGeo.TrackStation1.z - 20 * u.m,
1454 rotAngle,
1455 "SHiP",
1456 200,
1457 ROOT.kOrange - 2,
1458 )
1460 r,
1461 0.0,
1462 750.0,
1463 ShipGeo.TrackStation1.z - 40 * u.m,
1464 rotAngle,
1465 "Vacuum decay vessel",
1466 200,
1467 ROOT.kGray + 1,
1468 )
1469 positionText(r, 0.0, 100.0, ShipGeo.target.z - 6 * u.m, rotAngle, "Target", 200, ROOT.kBlue)
1471 r,
1472 0.0,
1473 600.0,
1474 ShipGeo.muShield.z - 10 * u.m,
1475 rotAngle,
1476 "Active muon shield",
1477 200,
1478 ROOT.kGreen - 2,
1479 )
1481 r,
1482 0.0,
1483 600.0,
1484 ShipGeo.tauMudet.zMudetC - 10 * u.m,
1485 rotAngle,
1486 "Tau neutrino detector",
1487 200,
1488 ROOT.kRed - 2,
1489 )
1491 r,
1492 0.0,
1493 900.0,
1494 ShipGeo.Bfield.z - 5 * u.m,
1495 rotAngle,
1496 "Dipole Magnet",
1497 200,
1498 ROOT.kBlue + 2,
1499 )
1501 r,
1502 -1500.0,
1503 -800.0,
1504 ShipGeo.TrackStation3.z - 2 * u.m,
1505 rotAngle,
1506 "Strawtracker",
1507 200,
1508 ROOT.kRed + 2,
1509 )
1510 positionText(r, 0.0, 700.0, ShipGeo.MuonFilter2.z, rotAngle, "Muon", 200, ROOT.kGreen + 2)
1511 r.CloseCompound()
1512 sc = gEve.GetScenes()
1513 geoscene = sc.FindChild("Geometry scene")
1514 gEve.ElementChanged(geoscene, True, True)
None ExecuteTask(self, str option="")
None DrawFittedTracks(self, str option="")
None DrawMCTrack(self, int n)
None DrawMCTracks(self, str option="")
None DrawParticle(self, n)
None ExecuteTask(self, str option="")
None DrawParticle(self, n)
None rotateView(self, float|int hor=0, float|int ver=0)
None transparentMode(self, str mode="on")
None NextEvent(self, int i=-1)
None toggleMCTracks(self)
None toggle(self, x)
None nextEvent(self, event=None)
None __init__(self)
None show(self, int xy=0, int ticks=5)
None apply_decorators()
Definition: decorators.py:99
None rename(str name="ship.TGeant4.root")
None storeCameraSetting(str fname="camSetting.root")
None dump(float pcut=0)
None DisplayNuDetector()
None PRVersion()
None projection_prescale()
None switchOffAll(exc)
bool _file_accessible(str path)
Definition: eventDisplay.py:26
None hidePlasticScintillator()
None switchOn(tag)
None debugStraw(n)
None readCameraSetting(str fname="camSetting.root")
None DrawCharmTracks()
None positionText(r, float x, float y, z, angle, str txt, int size=200, color=ROOT.kBlue, mode=ROOT.TGLFont.kExtrude, light=ROOT.kTRUE)
None switchOffRock()
None projection()
None printMCTrack(int n, MCTrack)
None DrawSimpleMCTracks()
None printParticles()
def select(pattern)
None speedUp()
None switchOnAll(exc)
None search(lvdict, tag)
None evExit()
Definition: eventDisplay.py:40
None switchOff(tag)
None printFittedTracks()
def addVMCFields(shipGeo, str controlFile="", bool verbose=False, bool withVirtualMC=True)
Definition: geomGeant4.py:165
None configure(darkphoton=None)