SND@LHC Software
Loading...
Searching...
No Matches
2dEventDisplay Namespace Reference

Functions

 pyExit ()
 
 goodEvent (event)
 
 userProcessing (event)
 
 bunchXtype ()
 
 getSciFiHitDensity (g, x_range=0.5)
 
 drawLegend (max_density, max_QDC, n_legend_points)
 
 drawSciFiHits (g, colour)
 
 loopEvents (start=0, save=False, goodEvents=False, withTrack=-1, withHoughTrack=-1, nTracks=0, minSipmMult=1, withTiming=False, option=None, Setup='TI18', verbose=0, auto=False, hitColour=None, FilterScifiHits=None)
 
 addTrack (OT, scifi=False)
 
 twoTrackEvent (sMin=10, dClMin=7, minDistance=1.5, sepDistance=0.5)
 
 drawDetectors ()
 
 zoom (xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None)
 
 dumpVeto ()
 
 MuFilter_PlaneBars (detID)
 
 checkOtherTriggers (event, deadTime=100, debug=False)
 
 cleanTracks ()
 
 timingOfEvent (makeCluster=False, debug=False)
 
 mufiNoise ()
 
 firstTimeStamp (event)
 
 dumpChannels (D='Digi_MuFilterHits')
 
 fillNode (node, color=None)
 
 drawInfo (pad, k, run, event, timestamp, moreEventInfo=[])
 
 drawCollisionAxis (pad, k)
 
 drawShowerAxis (pad, k, shower_start, ref_point, shower_direction)
 

Variables

 format
 
 level
 
 A
 
 B
 
dict eventComment = {}
 
dict h = {}
 
 parser = ArgumentParser()
 
 dest
 
 help
 
 type
 
 int
 
 required
 
 False
 
 default
 
 action
 
 options = parser.parse_args()
 
int resolution_factor = 1
 
 storePic
 
bool trans2local = False
 
bool runInfo = False
 
 fg = ROOT.TFile.Open(options.server+options.p+"RunInfodict.root")
 
 pkl = Unpickler(fg)
 
 geo = SndlhcGeo.GeoInterface(options.geoFile)
 
 lsOfGlobals = ROOT.gROOT.GetListOfGlobals()
 
dict detSize = {}
 
 em = geo.snd_geo.EmulsionDet
 
 si = geo.snd_geo.Scifi
 
 mi = geo.snd_geo.MuFilter
 
 vetoXdim
 
bool withDetector = True
 
bool with2Points = False
 
bool mc = False
 
int firstScifi_z = 300 * u.cm
 
 logger = ROOT.FairLogger.GetLogger()
 
 run = ROOT.FairRunAna()
 
 ioman = ROOT.FairRootManager.Instance()
 
 f = ROOT.TFile.Open(options.path+'sndsw_raw_'+str(options.runNumber).zfill(6)+'.root')
 
 eventTree = f.Get("cbmsim")
 
str runId = 'sim'
 
 outFile = ROOT.TMemFile('dummy','CREATE')
 
 source = ROOT.FairFileSource(f)
 
 sink = ROOT.FairRootFileSink(outFile)
 
dict HT_tasks
 
 trackTask = SndlhcTracking.Tracking()
 
 xrdb = ROOT.FairRuntimeDb.instance()
 
 OT = sink.GetOutTree()
 
 Digi_MuFilterHits
 
 nav = ROOT.gGeoManager.GetCurrentNavigator()
 
 runNumber = eventTree.EventHeader.GetRunId()
 
 FSdict = pkl.load('FSdict')
 
 fsdict = False
 
int Nlimit = 4
 
bool onlyScifi = False
 

Function Documentation

◆ addTrack()

2dEventDisplay.addTrack (   OT,
  scifi = False 
)

Definition at line 706 of file 2dEventDisplay.py.

706def addTrack(OT,scifi=False):
707 xax = h['xz'].GetXaxis()
708 nTrack = 0
709 for aTrack in OT.Reco_MuonTracks:
710 trackColor = ROOT.kRed
711 if aTrack.GetUniqueID()==1:
712 trackColor = ROOT.kBlue+2
713 flightDir = trackTask.trackDir(aTrack)
714 print('flight direction: %5.3F significance: %5.3F'%(flightDir[0],flightDir[1]))
715 if aTrack.GetUniqueID()==3: trackColor = ROOT.kBlack
716 if aTrack.GetUniqueID()==11: trackColor = ROOT.kAzure-2 # HT scifi track
717 if aTrack.GetUniqueID()==13: trackColor = ROOT.kGray+2 # HT ds track
718 # HT cross-system track fit
719 if aTrack.GetUniqueID()==15: trackColor = ROOT.kOrange+7
720 S = aTrack.getFitStatus()
721 if not S.isFitConverged() and (scifi or (aTrack.GetUniqueID()==1 or aTrack.GetUniqueID()==11) ):# scifi trk object ids are 1 or 11(Hough tracking)
722 print('not converge')
723 continue
724 for p in [0,1]:
725 h['aLine'+str(nTrack*10+p)] = ROOT.TGraph()
726
727 # draw the track line starting from the most upstream Veto plane
728 zEx = h['veto0_z']
729 mom = aTrack.getFittedState().getMom()
730 pos = aTrack.getFittedState().getPos()
731 lam = (zEx-pos.z())/mom.z()
732 Ex = [pos.x()+lam*mom.x(),pos.y()+lam*mom.y()]
733 for p in [0,1]: h['aLine'+str(nTrack*10+p)].SetPoint(0,zEx,Ex[p])
734
735 for i in range(aTrack.getNumPointsWithMeasurement()):
736 state = aTrack.getFittedState(i)
737 pos = state.getPos()
738 for p in [0,1]:
739 h['aLine'+str(nTrack*10+p)].SetPoint(i+1,pos[2],pos[p])
740
741 zEx = xax.GetBinCenter(xax.GetLast())
742 mom = aTrack.getFittedState().getMom()
743 pos = aTrack.getFittedState().getPos()
744 lam = (zEx-pos.z())/mom.z()
745 Ex = [pos.x()+lam*mom.x(),pos.y()+lam*mom.y()]
746 for p in [0,1]: h['aLine'+str(nTrack*10+p)].SetPoint(i+2,zEx,Ex[p])
747
748 for p in [0,1]:
749 tc = h[ 'simpleDisplay'].cd(p+1)
750 h['aLine'+str(nTrack*10+p)].SetLineColor(trackColor)
751 h['aLine'+str(nTrack*10+p)].SetLineWidth(2)
752 h['aLine'+str(nTrack*10+p)].Draw('same')
753 tc.Update()
754 h[ 'simpleDisplay'].Update()
755 nTrack+=1
756

◆ bunchXtype()

2dEventDisplay.bunchXtype ( )

Definition at line 226 of file 2dEventDisplay.py.

226def bunchXtype():
227# check for b1,b2,IP1,IP2
228 xing = {'all':True,'B1only':False,'B2noB1':False,'noBeam':False}
229 if fsdict:
230 T = eventTree.EventHeader.GetEventTime()
231 bunchNumber = int(T%(4*3564)/4+0.5)
232 nb1 = (3564 + bunchNumber - fsdict['phaseShift1'])%3564
233 nb2 = (3564 + bunchNumber - fsdict['phaseShift1']- fsdict['phaseShift2'])%3564
234 b1 = nb1 in fsdict['B1']
235 b2 = nb2 in fsdict['B2']
236 IP1 = False
237 IP2 = False
238 if b1:
239 IP1 = fsdict['B1'][nb1]['IP1']
240 if b2:
241 IP2 = fsdict['B2'][nb2]['IP2']
242 if b2 and not b1:
243 xing['B2noB1'] = True
244 if b1 and not b2 and not IP1:
245 xing['B1only'] = True
246 if not b1 and not b2: xing['noBeam'] = True
247 return xing
248

◆ checkOtherTriggers()

2dEventDisplay.checkOtherTriggers (   event,
  deadTime = 100,
  debug = False 
)

Definition at line 982 of file 2dEventDisplay.py.

982def checkOtherTriggers(event,deadTime = 100,debug=False):
983 T0 = event.EventHeader.GetEventTime()
984 N = event.EventHeader.GetEventNumber()
985 Nprev = 1
986 rc = event.GetEvent(N-Nprev)
987 dt = T0 - event.EventHeader.GetEventTime()
988 otherFastTrigger = False
989 otherAdvTrigger = False
990 tightNoiseFilter = False
991 while dt < deadTime:
992 otherFastTrigger = False
993 for x in event.EventHeader.GetFastNoiseFilters():
994 if debug: print('fast:', x.first, x.second )
995 if x.second and not x.first == 'Veto_Total': otherFastTrigger = True
996 otherAdvTrigger = False
997 for x in event.EventHeader.GetAdvNoiseFilters():
998 if debug: print('adv:', x.first, x.second )
999 if x.second and not x.first == 'VETO_Planes': otherAdvTrigger = True
1000 if debug: print('pre event ',Nprev,dt,otherFastTrigger,otherAdvTrigger)
1001 if otherFastTrigger and otherAdvTrigger:
1002 rc = event.GetEvent(N)
1003 return otherFastTrigger, otherAdvTrigger, tightNoiseFilter, Nprev, dt
1004 Nprev+=1
1005 rc = event.GetEvent(N-Nprev)
1006 dt = T0 - event.EventHeader.GetEventTime()
1007 Nprev = 1
1008 rc = event.GetEvent(N-Nprev)
1009 dt = T0 - event.EventHeader.GetEventTime()
1010 while dt < deadTime:
1011 hits = {1:0,0:0}
1012 for aHit in event.Digi_MuFilterHits:
1013 Minfo = MuFilter_PlaneBars(aHit.GetDetectorID())
1014 s,l,bar = Minfo['station'],Minfo['plane'],Minfo['bar']
1015 if s>1: continue
1016 allChannels = aHit.GetAllSignals(False,False)
1017 hits[l]+=len(allChannels)
1018 noiseFilter0 = (hits[0]+hits[1])>4.5
1019 noiseFilter1 = hits[0]>0 and hits[1]>0
1020 if debug: print('veto hits:',hits)
1021 if noiseFilter0 and noiseFilter1:
1022 tightNoiseFilter = True
1023 rc = event.GetEvent(N)
1024 return otherFastTrigger, otherAdvTrigger, tightNoiseFilter, Nprev-1, dt
1025 Nprev+=1
1026 rc = event.GetEvent(N-Nprev)
1027 dt = T0 - event.EventHeader.GetEventTime()
1028 if Nprev>1:
1029 rc = event.GetEvent(N-Nprev+1)
1030 dt = T0 - event.EventHeader.GetEventTime()
1031 rc = event.GetEvent(N)
1032 return otherFastTrigger, otherAdvTrigger, tightNoiseFilter, Nprev-1, dt
1033

◆ cleanTracks()

2dEventDisplay.cleanTracks ( )

Definition at line 1034 of file 2dEventDisplay.py.

1034def cleanTracks():
1035 OT = sink.GetOutTree()
1036 listOfDetIDs = {}
1037 n = 0
1038 for aTrack in OT.Reco_MuonTracks:
1039 listOfDetIDs[n] = []
1040 for i in range(aTrack.getNumPointsWithMeasurement()):
1041 M = aTrack.getPointWithMeasurement(i)
1042 R = M.getRawMeasurement()
1043 listOfDetIDs[n].append(R.getDetId())
1044 if R.getDetId()>0: listOfDetIDs[n].append(R.getDetId()-1)
1045 listOfDetIDs[n].append(R.getDetId()+1)
1046 n+=1
1047 uniqueTracks = []
1048 for n1 in range( len(listOfDetIDs) ):
1049 unique = True
1050 for n2 in range( len(listOfDetIDs) ):
1051 if n1==n2: continue
1052 I = set(listOfDetIDs[n1]).intersection(listOfDetIDs[n2])
1053 if len(I)>0: unique = False
1054 if unique: uniqueTracks.append(n1)
1055 if len(uniqueTracks)>1:
1056 for n1 in range( len(listOfDetIDs) ): print(listOfDetIDs[n1])
1057 return uniqueTracks
1058
set(INCLUDE_DIRECTORIES ${SYSTEM_INCLUDE_DIRECTORIES} ${VMC_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/shipdata ${CMAKE_SOURCE_DIR}/shipLHC ${CMAKE_SOURCE_DIR}/analysis/cuts ${CMAKE_SOURCE_DIR}/analysis/tools ${FMT_INCLUDE_DIR}) include_directories($
Definition CMakeLists.txt:1

◆ drawCollisionAxis()

2dEventDisplay.drawCollisionAxis (   pad,
  k 
)

Definition at line 1265 of file 2dEventDisplay.py.

1265def drawCollisionAxis(pad, k):
1266 line_name = "collision_axis_line_" + str(k)
1267 h[line_name] = ROOT.TLine(h["zmin"], 0, h["zmax"], 0)
1268 h[line_name].SetLineColor(ROOT.kRed)
1269 h[line_name].SetLineStyle(2)
1270
1271 text_name = "collision_axis_text_" + str(k)
1272 h[text_name] = ROOT.TText(h["zmin"] + 8, 0 + 2, "Collision axis")
1273 h[text_name].SetTextAlign(12)
1274 h[text_name].SetTextFont(43)
1275 h[text_name].SetTextSize(13 * resolution_factor)
1276 h[text_name].SetTextColor(ROOT.kRed)
1277
1278 pad.cd(k)
1279 h[line_name].Draw()
1280 h[text_name].Draw()
1281

◆ drawDetectors()

2dEventDisplay.drawDetectors ( )

Definition at line 844 of file 2dEventDisplay.py.

844def drawDetectors():
845 nodes = {'volMuFilter_1/volFeBlockEnd_1':ROOT.kGreen-6}
846 for i in range(mi.NVetoPlanes):
847 nodes['volVeto_1/volVetoPlane_{}_{}'.format(i, i)]=ROOT.kRed
848 for j in range(mi.NVetoBars):
849 if i<2: nodes['volVeto_1/volVetoPlane_{}_{}/volVetoBar_1{}{:0>3d}'.format(i, i, i, j)]=ROOT.kRed
850 if i==2: nodes['volVeto_1/volVetoPlane_{}_{}/volVetoBar_ver_1{}{:0>3d}'.format(i, i, i, j)]=ROOT.kRed
851 if i<2: nodes['volVeto_1/subVetoBox_{}'.format(i)]=ROOT.kGray+1
852 if i==2: nodes['volVeto_1/subVeto3Box_{}'.format(i)]=ROOT.kGray+1
853 for i in range(si.nscifi): # number of scifi stations
854 nodes['volTarget_1/ScifiVolume{}_{}000000'.format(i+1, i+1)]=ROOT.kBlue+1
855 # iron blocks btw SciFi planes in the testbeam 2023-2024 det layout
856 nodes['volTarget_1/volFeTarget{}_1'.format(i+1)]=ROOT.kGreen-6
857 for i in range(em.wall): # number of target walls
858 nodes['volTarget_1/volWallborder_{}'.format(i)]=ROOT.kGray
859 for i in range(mi.NDownstreamPlanes):
860 nodes['volMuFilter_1/volMuDownstreamDet_{}_{}'.format(i, i+mi.NVetoPlanes+mi.NUpstreamPlanes)]=ROOT.kBlue+1
861 for j in range(mi.NDownstreamBars):
862 nodes['volMuFilter_1/volMuDownstreamDet_{}_{}/volMuDownstreamBar_ver_3{}{:0>3d}'.format(i, i+mi.NVetoPlanes+mi.NUpstreamPlanes, i, j+mi.NDownstreamBars)]=ROOT.kBlue+1
863 if i < 3:
864 nodes['volMuFilter_1/volMuDownstreamDet_{}_{}/volMuDownstreamBar_hor_3{}{:0>3d}'.format(i, i+mi.NVetoPlanes+mi.NUpstreamPlanes, i, j)]=ROOT.kBlue+1
865 for i in range(mi.NDownstreamPlanes):
866 nodes['volMuFilter_1/subDSBox_{}'.format(i+mi.NVetoPlanes+mi.NUpstreamPlanes)]=ROOT.kGray+1
867 for i in range(mi.NUpstreamPlanes):
868 nodes['volMuFilter_1/subUSBox_{}'.format(i+mi.NVetoPlanes)]=ROOT.kGray+1
869 nodes['volMuFilter_1/volMuUpstreamDet_{}_{}'.format(i, i+mi.NVetoPlanes)]=ROOT.kBlue+1
870 for j in range(mi.NUpstreamBars):
871 nodes['volMuFilter_1/volMuUpstreamDet_{}_{}/volMuUpstreamBar_2{}00{}'.format(i, i+mi.NVetoPlanes, i, j)]=ROOT.kBlue+1
872 nodes['volMuFilter_1/volFeBlock_{}'.format(i)]=ROOT.kGreen-6
873 for i in range(mi.NVetoPlanes+mi.NUpstreamPlanes,mi.NVetoPlanes+mi.NUpstreamPlanes+mi.NDownstreamPlanes):
874 nodes['volMuFilter_1/volFeBlock_{}'.format(i)]=ROOT.kGreen-6
875 passNodes = {'Block', 'Wall', 'FeTarget'}
876 xNodes = {'UpstreamBar', 'VetoBar', 'hor'}
877 proj = {'X':0,'Y':1}
878 for node_ in nodes:
879 node = '/cave_1/Detector_0/'+node_
880 for p in proj:
881 if node+p in h and any(passNode in node for passNode in passNodes):
882 X = h[node+p]
883 c = proj[p]
884 h['simpleDisplay'].cd(c+1)
885 X.Draw('f&&same')
886 X.Draw('same')
887 else:
888 # check if node exists
889 if not nav.CheckPath(node): continue
890 nav.cd(node)
891 N = nav.GetCurrentNode()
892 S = N.GetVolume().GetShape()
893 dx,dy,dz = S.GetDX(),S.GetDY(),S.GetDZ()
894 ox,oy,oz = S.GetOrigin()[0],S.GetOrigin()[1],S.GetOrigin()[2]
895 P = {}
896 M = {}
897 if p=='X' and (not any(xNode in node for xNode in xNodes) or 'VetoBar_ver' in node):
898 P['LeftBottom'] = array('d',[-dx+ox,oy,-dz+oz])
899 P['LeftTop'] = array('d',[dx+ox,oy,-dz+oz])
900 P['RightBottom'] = array('d',[-dx+ox,oy,dz+oz])
901 P['RightTop'] = array('d',[dx+ox,oy,dz+oz])
902 elif p=='Y' and 'ver' not in node:
903 P['LeftBottom'] = array('d',[ox,-dy+oy,-dz+oz])
904 P['LeftTop'] = array('d',[ox,dy+oy,-dz+oz])
905 P['RightBottom'] = array('d',[ox,-dy+oy,dz+oz])
906 P['RightTop'] = array('d',[ox,dy+oy,dz+oz])
907 else: continue
908 for C in P:
909 M[C] = array('d',[0,0,0])
910 nav.LocalToMaster(P[C],M[C])
911 if "volVetoPlane_0" in node:
912 h['veto0_z'] = M['LeftBottom'][2]
913 if "ScifiVolume" in node:
914 for st in range(1,si.nscifi+1):
915 if f"{st}_{st}000000" in node:
916 h[f"scifi{st}_z"] = M['LeftBottom'][2]
917 if "volMuUpstreamDet" in node:
918 for st in range(mi.NUpstreamPlanes):
919 if f"{st}_{st+mi.NVetoPlanes}" in node:
920 h[f"us{st+1}_z"] = M['LeftBottom'][2]
921
922 h[node+p] = ROOT.TPolyLine()
923 X = h[node+p]
924 c = proj[p]
925 X.SetPoint(0,M['LeftBottom'][2],M['LeftBottom'][c])
926 X.SetPoint(1,M['LeftTop'][2],M['LeftTop'][c])
927 X.SetPoint(2,M['RightTop'][2],M['RightTop'][c])
928 X.SetPoint(3,M['RightBottom'][2],M['RightBottom'][c])
929 X.SetPoint(4,M['LeftBottom'][2],M['LeftBottom'][c])
930 X.SetLineColor(nodes[node_])
931 X.SetLineWidth(1)
932 h['simpleDisplay'].cd(c+1)
933 if any(passNode in node for passNode in passNodes):
934 X.SetFillColorAlpha(nodes[node_], 0.5)
935 X.Draw('f&&same')
936 X.Draw('same')

◆ drawInfo()

2dEventDisplay.drawInfo (   pad,
  k,
  run,
  event,
  timestamp,
  moreEventInfo = [] 
)

Definition at line 1213 of file 2dEventDisplay.py.

1213def drawInfo(pad, k, run, event, timestamp,moreEventInfo=[]):
1214 drawLogo = True
1215 drawText = True
1216 if drawLogo:
1217 padLogo = ROOT.TPad("logo","logo",0.1,0.1,0.2,0.3)
1218 padLogo.SetFillStyle(4000)
1219 padLogo.SetFillColorAlpha(0, 0)
1220 padLogo.Draw()
1221 logo = ROOT.TImage.Open('$SNDSW_ROOT/shipLHC/Large__SND_Logo_black_cut.png')
1222 logo.SetConstRatio(True)
1223 padLogo.cd()
1224 logo.Draw()
1225 pad.cd(k)
1226
1227 if drawText:
1228 if k==1 or len(moreEventInfo)<5:
1229 runNumber = eventTree.EventHeader.GetRunId()
1230 timestamp_print = False
1231 if not mc and hasattr(eventTree.EventHeader, "GetUTCtimestamp"):
1232 timestamp_print = True
1233 time_event= datetime.utcfromtimestamp(eventTree.EventHeader.GetUTCtimestamp())
1234 padText = ROOT.TPad("info","info",0.19,0.1,0.6,0.3)
1235 padText.SetFillStyle(4000)
1236 padText.Draw()
1237 padText.cd()
1238 textInfo = ROOT.TLatex()
1239 textInfo.SetTextAlign(11)
1240 textInfo.SetTextFont(42)
1241 textInfo.SetTextSize(.15)
1242 textInfo.DrawLatex(0, 0.6, 'SND@LHC Experiment, CERN')
1243 if hasattr(eventTree.EventHeader,'GetEventNumber'): N = eventTree.EventHeader.GetEventNumber()
1244 else: N = event
1245 textInfo.DrawLatex(0, 0.4, 'Run / Event: '+str(run)+' / '+str(N))
1246 if timestamp_print:
1247 textInfo.DrawLatex(0, 0.2, 'Time (GMT): {}'.format(time_event))
1248 pad.cd(k)
1249 elif options.extraInfo:
1250 padText = ROOT.TPad("info","info",0.29,0.12,0.9,0.35)
1251 padText.SetFillStyle(4000)
1252 padText.Draw()
1253 padText.cd()
1254 textInfo = ROOT.TLatex()
1255 textInfo.SetTextAlign(11)
1256 textInfo.SetTextFont(42)
1257 textInfo.SetTextSize(.1)
1258 textInfo.SetTextColor(ROOT.kMagenta+2)
1259 dely = 0.12
1260 ystart = 0.85
1261 for i in range(7):
1262 textInfo.DrawLatex(0.4, 0.9-dely*i, moreEventInfo[i])
1263 pad.cd(k)
1264

◆ drawLegend()

2dEventDisplay.drawLegend (   max_density,
  max_QDC,
  n_legend_points 
)
Draws legend for hit colour

Definition at line 264 of file 2dEventDisplay.py.

264def drawLegend(max_density, max_QDC, n_legend_points):
265 """Draws legend for hit colour"""
266 h['simpleDisplay'].cd(1)
267 n_legend_points = 5
268 padLegScifi = ROOT.TPad("legend","legend",0.4,0.15,0.4+0.27, 0.15+0.25)
269 padLegScifi.SetFillStyle(4000)
270 padLegScifi.Draw()
271 padLegScifi.cd()
272 text_scifi_legend = ROOT.TLatex()
273 text_scifi_legend.SetTextAlign(11)
274 text_scifi_legend.SetTextFont(42)
275 text_scifi_legend.SetTextSize(.15)
276 for i in range(n_legend_points) :
277 if i < (n_legend_points - 1) :
278 text_scifi_legend.DrawLatex((i+0.3)*(1./(n_legend_points+2)), 0.2, "{:d}".format(int(i*max_density/(n_legend_points-1))))
279 text_scifi_legend.DrawLatex((i+0.3)*(1./(n_legend_points+2)), 0., "{:.0f}".format(int(i*max_QDC/(n_legend_points-1))))
280 else :
281 text_scifi_legend.DrawLatex((i+0.3)*(1./(n_legend_points+2)), 0.2, "{:d} SciFi hits/cm".format(int(i*max_density/(n_legend_points-1))))
282 text_scifi_legend.DrawLatex((i+0.3)*(1./(n_legend_points+2)), 0., "{:.0f} QDC units".format(int(i*max_QDC/(n_legend_points-1))))
283
284 h["markerCollection"].append(ROOT.TEllipse((i+0.15)*(1./(n_legend_points+2)), 0.26, 0.05/4, 0.05))
285 h["markerCollection"][-1].SetFillColor(ROOT.TColor.GetPalette()[int(float(i*max_density/(n_legend_points-1))/max_density*(len(ROOT.TColor.GetPalette())-1))])
286 h["markerCollection"][-1].Draw("SAME")
287
288 h["markerCollection"].append(ROOT.TBox((i+0.15)*(1./(n_legend_points+2))-0.05/4 , 0.06 - 0.05, (i+0.15)*(1./(n_legend_points+2))+0.05/4, 0.06 + 0.05))
289 h["markerCollection"][-1].SetFillColor(ROOT.TColor.GetPalette()[int(float(i*max_QDC/(n_legend_points-1))/max_QDC*(len(ROOT.TColor.GetPalette())-1))])
290 h["markerCollection"][-1].Draw("SAME")
291

◆ drawSciFiHits()

2dEventDisplay.drawSciFiHits (   g,
  colour 
)
Takes TGraph g and draws the graphs markers with the TColor given in list colour.

Definition at line 292 of file 2dEventDisplay.py.

292def drawSciFiHits(g, colour):
293 """Takes TGraph g and draws the graphs markers with the TColor given in list colour."""
294 n = g.GetN()
295 # Draw highest density points last
296 sorted_indices = np.argsort(colour)
297 for i_unsorted in range(0, n):
298 i = int(sorted_indices[i_unsorted])
299
300 x = g.GetPointX(i)
301 y = g.GetPointY(i)
302
303 h["markerCollection"].append(ROOT.TEllipse(x, y, 1.5, 1.5))
304 h["markerCollection"][-1].SetLineWidth(0)
305 h["markerCollection"][-1].SetFillColor(colour[i])
306 h["markerCollection"][-1].Draw("SAME")
307

◆ drawShowerAxis()

2dEventDisplay.drawShowerAxis (   pad,
  k,
  shower_start,
  ref_point,
  shower_direction 
)

Definition at line 1282 of file 2dEventDisplay.py.

1282def drawShowerAxis(pad, k, shower_start, ref_point, shower_direction):
1283 line_name= "shower_dir_" + str(k)
1284 if shower_start<100:
1285 zpos_name='scifi'+str(shower_start//10)
1286 else:
1287 zpos_name='us'+str(shower_start//100)
1288 h[line_name] = ROOT.TLine(h[zpos_name+'_z'],
1289 ref_point+shower_direction*h[zpos_name+'_z'],
1290 h['zmax'],
1291 ref_point+shower_direction*h['zmax'])
1292 h[line_name].SetLineColor(ROOT.kPink-6)
1293 h[line_name].SetLineStyle(3)
1294 h[line_name].SetLineWidth(5)
1295 pad.cd(k)
1296 h[line_name].Draw()

◆ dumpChannels()

2dEventDisplay.dumpChannels (   D = 'Digi_MuFilterHits')

Definition at line 1164 of file 2dEventDisplay.py.

1164def dumpChannels(D='Digi_MuFilterHits'):
1165 X = eval("eventTree."+D)
1166 text = {}
1167 for aHit in X:
1168 side = 'L'
1169 txt = "%8i"%(aHit.GetDetectorID())
1170 for k in range(aHit.GetnSiPMs()*aHit.GetnSides()):
1171 qdc = aHit.GetSignal(k)
1172 if qdc < -900: continue
1173 i = k
1174 if not k<aHit.GetnSiPMs():
1175 i = k-aHit.GetnSiPMs()
1176 if side == 'L':
1177 txt += " | "
1178 side = 'R'
1179 txt+= " %2i:%4.1F "%(i,qdc)
1180 text[aHit.GetDetectorID()] = txt
1181 keys = list(text.keys())
1182 keys.sort()
1183 for k in keys: print(text[k])
1184

◆ dumpVeto()

2dEventDisplay.dumpVeto ( )

Definition at line 952 of file 2dEventDisplay.py.

952def dumpVeto():
953 muHits = {10:[],11:[]}
954 for aHit in eventTree.Digi_MuFilterHits:
955 if not aHit.isValid(): continue
956 s = aHit.GetDetectorID()//10000
957 if s>1: continue
958 p = (aHit.GetDetectorID()//1000)%10
959 bar = (aHit.GetDetectorID()%1000)%60
960 plane = s*10+p
961 muHits[plane].append(aHit)
962 for plane in [10,11]:
963 for aHit in muHits[plane]:
964 S =aHit.GetAllSignals(False,False)
965 txt = ""
966 for x in S:
967 if x[1]>0: txt+=str(x[1])+" "
968 print(plane, (aHit.GetDetectorID()%1000)%60, txt)
969
970# decode MuFilter detID

◆ fillNode()

2dEventDisplay.fillNode (   node,
  color = None 
)

Definition at line 1185 of file 2dEventDisplay.py.

1185def fillNode(node, color=None):
1186 xNodes = {'UpstreamBar', 'VetoBar', 'hor'}
1187 proj = {'X':0,'Y':1}
1188 if color == None :
1189 hcal_color = ROOT.kBlack
1190 veto_color = ROOT.kRed+1
1191 else :
1192 hcal_color = color
1193 veto_color = color
1194 thick = 5
1195 for p in proj:
1196 if node+p in h:
1197 X = h[node+p]
1198 if 'Veto' in node:
1199 color = veto_color
1200 else :
1201 color = hcal_color
1202
1203 if 'Downstream' in node:
1204 thick = 5
1205 c = proj[p]
1206 h[ 'simpleDisplay'].cd(c+1)
1207 X.SetFillColor(color)
1208 X.SetLineColor(color)
1209 X.SetLineWidth(thick)
1210 X.Draw('f&&same')
1211 X.Draw('same')
1212

◆ firstTimeStamp()

2dEventDisplay.firstTimeStamp (   event)

Definition at line 1148 of file 2dEventDisplay.py.

1148def firstTimeStamp(event):
1149 tmin = [1E9,'']
1150 digis = [event.Digi_MuFilterHits,event.Digi_ScifiHits]
1151 for digi in event.Digi_ScifiHits:
1152 dt = digi.GetTime()
1153 if dt<tmin[0]:
1154 tmin[0]=dt
1155 tmin[1]=digi
1156 for digi in event.Digi_MuFilterHits:
1157 for t in digi.GetAllTimes(): # will not give time if QDC<0!
1158 dt = t.second
1159 if dt<tmin[0]:
1160 tmin[0]=dt
1161 tmin[1]=digi
1162 return tmin
1163

◆ getSciFiHitDensity()

2dEventDisplay.getSciFiHitDensity (   g,
  x_range = 0.5 
)
Takes ROOT TGraph g and returns array with number of hits within x_range cm of each hit.

Definition at line 249 of file 2dEventDisplay.py.

249def getSciFiHitDensity(g, x_range=0.5):
250 """Takes ROOT TGraph g and returns array with number of hits within x_range cm of each hit."""
251 ret = []
252 for i in range(g.GetN()):
253 x_i = g.GetPointX(i)
254 y_i = g.GetPointY(i)
255 density = 0
256 for j in range(g.GetN()):
257 x_j = g.GetPointX(j)
258 y_j = g.GetPointY(j)
259 if ((x_i - x_j)**2 + (y_i - y_j)**2) <= x_range**2:
260 density += 1
261 ret.append(density)
262 return ret
263

◆ goodEvent()

2dEventDisplay.goodEvent (   event)

Definition at line 182 of file 2dEventDisplay.py.

182def goodEvent(event):
183# can be replaced by any user selection
184 stations = {'Scifi':{},'Mufi':{}}
185 if event.Digi_ScifiHits.GetEntries()>25: return False
186 for d in event.Digi_ScifiHits:
187 stations['Scifi'][d.GetDetectorID()//1000000] = 1
188 for d in event.Digi_MuFilterHits:
189 plane = d.GetDetectorID()//1000
190 stations['Mufi'][plane] = 1
191 totalN = len(stations['Mufi'])+len(stations['Scifi'])
192 if len(stations['Scifi'])>4 and len(stations['Mufi'])>6: return True
193 else: False
194 if onlyScifi and len(stations['Scifi'])>Nlimit: return True
195 elif not onlyScifi and totalN > Nlimit: return True
196 else: return False
197

◆ loopEvents()

2dEventDisplay.loopEvents (   start = 0,
  save = False,
  goodEvents = False,
  withTrack = -1,
  withHoughTrack = -1,
  nTracks = 0,
  minSipmMult = 1,
  withTiming = False,
  option = None,
  Setup = 'TI18',
  verbose = 0,
  auto = False,
  hitColour = None,
  FilterScifiHits = None 
)

Definition at line 308 of file 2dEventDisplay.py.

323 ):
324
325 # check the format of FilterScifiHits if set
326 if FilterScifiHits:
327 important_keys = {"bins_x", "min_x", "max_x", "time_lower_range", "time_upper_range"}
328 all_keys = important_keys.copy()
329 all_keys.add("method")
330 filter_parameters = {"bins_x":52., "min_x":0., "max_x":26.,
331 "time_lower_range":1E9/(2*u.snd_freq/u.hertz),
332 "time_upper_range":2E9/(u.snd_freq/u.hertz),
333 "method":0}
334 if FilterScifiHits!="default" and not important_keys.issubset(FilterScifiHits):
335 logging.fatal("Invalid FilterScifiHits format. Two options are supported:\n"
336 "#1 FilterScifiHits = 'default'\nwhich sets the default parameters:\n"+
337 str(filter_parameters)+" or\n"
338 "#2 FilterScifiHits = filter_dictionary \nwhere filter_dictionary has all of the following keys\n"+
339 str(important_keys)+"\nAn additional key 'method' exists: its single supported value, also default, is 0.")
340 return
341 if FilterScifiHits!="default" and any(k not in all_keys for k in FilterScifiHits):
342 logging.warning("Ignoring provided keys other than "+str(all_keys))
343
344 if 'simpleDisplay' not in h:
345 ut.bookCanvas(h,key='simpleDisplay',title='simple event display',nx=1200,ny=1016,cx=1,cy=2)
346
347 h['simpleDisplay'].cd(1)
348 # TI18 coordinate system
349 zStart = 250.
350 zEnd = 600.
351 xStart = -100.
352 yStart = -30.
353 if Setup == 'H6': zStart = 60.
354 if Setup == 'TP': zStart = -50. # old coordinate system with origin in middle of target
355 if Setup == 'H4':
356 xStart = -110.
357 yStart = -10.
358 zStart = 300.
359 zEnd = 430.
360 if 'xz' in h:
361 h.pop('xz').Delete()
362 h.pop('yz').Delete()
363 else:
364 h['xmin'],h['xmax'] = xStart,xStart+110.
365 h['ymin'],h['ymax'] = yStart,yStart+110.
366 h['zmin'],h['zmax'] = zStart,zEnd
367 for d in ['xmin','xmax','ymin','ymax','zmin','zmax']: h['c'+d]=h[d]
368 ut.bookHist(h,'xz','; z [cm]; x [cm]',500,h['czmin'],h['czmax'],100,h['cxmin'],h['cxmax'])
369 ut.bookHist(h,'yz','; z [cm]; y [cm]',500,h['czmin'],h['czmax'],100,h['cymin'],h['cymax'])
370
371 proj = {1:'xz',2:'yz'}
372 h['xz'].SetStats(0)
373 h['yz'].SetStats(0)
374
375 N = -1
376 Tprev = -1
377 A,B = ROOT.TVector3(),ROOT.TVector3()
378 ptext={0:' Y projection',1:' X projection'}
379 text = ROOT.TLatex()
380 event = eventTree
381 OT = sink.GetOutTree()
382 if withTrack==0 or withHoughTrack==0: OT = eventTree
383 if type(start) == type(1):
384 s = start
385 e = event.GetEntries()
386 else:
387 s = 0
388 e = len(start)
389 for N in range(s,e):
390 if type(start) == type(1): rc = event.GetEvent(N)
391 else: rc = event.GetEvent(start[N])
392 if goodEvents and not goodEvent(event): continue
393 nHoughtracks = 0
394 OT.Reco_MuonTracks = ROOT.TObjArray(10)
395 if withHoughTrack > 0:
396 rc = source.GetInTree().GetEvent(N)
397 # Delete SndlhcMuonReco kalman tracks container
398 for ht_task in HT_tasks.values():
399 ht_task.kalman_tracks.Delete()
400 if withHoughTrack==1:
401 HT_tasks['muon_reco_task_Sf'].Exec(0)
402 HT_tasks['muon_reco_task_DS'].Exec(0)
403 elif withHoughTrack==2:
404 HT_tasks['muon_reco_task_Sf'].Exec(0)
405 elif withHoughTrack==3:
406 HT_tasks['muon_reco_task_DS'].Exec(0)
407 elif withHoughTrack==4:
408 HT_tasks['muon_reco_task_nuInt'].Exec(0)
409 # Save the tracks in OT.Reco_MuonTracks object
410 for ht_task in HT_tasks.values():
411 for trk in ht_task.kalman_tracks:
412 OT.Reco_MuonTracks.Add(trk)
413 nHoughtracks = OT.Reco_MuonTracks.GetEntries()
414 if nHoughtracks>0: print('number of tracks by HT:', nHoughtracks)
415
416 if withTrack > 0:
417 # Delete SndlhcTracking fitted tracks container
418 trackTask.fittedTracks.Delete()
419 if withTrack==1:
420 trackTask.ExecuteTask("ScifiDS")
421 elif withTrack==2:
422 trackTask.ExecuteTask("Scifi")
423 elif withTrack==3:
424 trackTask.ExecuteTask("DS")
425 # Save found tracks
426 for trk in trackTask.fittedTracks:
427 OT.Reco_MuonTracks.Add(trk)
428 ntracks = len(OT.Reco_MuonTracks) - nHoughtracks
429 if ntracks>0: print('number of tracks by ST:', ntracks)
430 nAlltracks = len(OT.Reco_MuonTracks)
431 if nAlltracks<nTracks: continue
432
433 if verbose>0:
434 for aTrack in OT.Reco_MuonTracks:
435 print(aTrack.__repr__())
436 mom = aTrack.getFittedState().getMom()
437 pos = aTrack.getFittedState().getPos()
438 mom.Print()
439 pos.Print()
440 T,dT = 0,0
441 T = event.EventHeader.GetEventTime()
442 runId = eventTree.EventHeader.GetRunId()
443 if Tprev >0: dT = T-Tprev
444 Tprev = T
445 if nAlltracks > 0: print('total number of tracks: ', nAlltracks)
446
447 digis = []
448 if event.FindBranch("Digi_ScifiHits"):
449 scifi_digis = event.Digi_ScifiHits
450 method = 0
451 if FilterScifiHits!=None and FilterScifiHits!="default":
452 filter_parameters = {k: FilterScifiHits[k] for k in important_keys if k in FilterScifiHits}
453 method = FilterScifiHits.get("method", 0) # set to the default 0, if item is not provided
454 if FilterScifiHits and (Setup=="TI18" or Setup=="H8" or Setup=="H4"):
455 setup = Setup
456 # Only H8 is explicitly supported in the SciFi tools. However, the same baby SciFi
457 # system was reused in H4. It is then safe to use the SciFi tools for H4 as well.
458 if Setup =="H4":
459 setup ="H8"
460 # Convert the filter_parameters to the needed std.map format
461 selection_parameters = ROOT.std.map('string', 'float')()
462 selection_parameters["bins_x"] = float(filter_parameters["bins_x"])
463 selection_parameters["min_x"] = float(filter_parameters["min_x"])
464 selection_parameters["max_x"] = float(filter_parameters["max_x"])
465 selection_parameters["time_lower_range"] = float(filter_parameters["time_lower_range"])
466 selection_parameters["time_upper_range"] = float(filter_parameters["time_upper_range"])
467 scifi_digis = ROOT.snd.analysis_tools.filterScifiHits(event.Digi_ScifiHits,selection_parameters,method,setup,mc)
468 else:
469 if FilterScifiHits:
470 logging.warning(Setup+" is not supported for the time-filtering of SciFi hits, using all hits instead.")
471 digis.append(scifi_digis)
472 run_conf = ROOT.snd.Configuration.Option.ti18_2022_2023
473 if Setup=='TI18' or Setup=="H6":
474 run_conf = ROOT.snd.Configuration.Option.ti18_2022_2023
475 elif Setup == "H8":
476 ROOT.snd.Configuration.Option.test_beam_2023
477 elif Setup == "H4":
478 ROOT.snd.Configuration.Option.test_beam_2024
479 else:
480 print("Going for default setup TI18")
481 configuration = ROOT.snd.Configuration(run_conf, geo.modules['Scifi'], geo.modules['MuFilter'])
482 scifi_planes = ROOT.snd.analysis_tools.FillScifi(configuration, scifi_digis, geo.modules['Scifi'])
483 us_planes = ROOT.snd.analysis_tools.FillUS(configuration, event.Digi_MuFilterHits, geo.modules['MuFilter'], mc)
484 if event.FindBranch("Digi_MuFilterHits"): digis.append(event.Digi_MuFilterHits)
485 if event.FindBranch("Digi_MuFilterHit"): digis.append(event.Digi_MuFilterHit)
486 empty = True
487 for x in digis:
488 if x.GetEntries()>0:
489 if empty: print( "event -> %i"%N)
490 empty = False
491 if empty: continue
492 h['hitCollectionX']= {'Veto':[0,ROOT.TGraphErrors()],'Scifi':[0,ROOT.TGraphErrors()],'DS':[0,ROOT.TGraphErrors()]}
493 h['hitCollectionY']= {'Veto':[0,ROOT.TGraphErrors()],'Scifi':[0,ROOT.TGraphErrors()],'US':[0,ROOT.TGraphErrors()],'DS':[0,ROOT.TGraphErrors()]}
494 if hitColour:
495 h['hitColourX'] = {'Veto': [], 'Scifi': [], 'DS' : []}
496 h['hitColourY'] = {'Veto': [], 'Scifi' : [], 'US' : [], 'DS' : []}
497 h["markerCollection"] = []
498
499 h['firedChannelsX']= {'Veto':[0,0,0,0],'Scifi':[0,0,0],'DS':[0,0,0]}
500 h['firedChannelsY']= {'Veto':[0,0,0,0],'Scifi':[0,0,0],'US':[0,0,0,0],'DS':[0,0,0,0]}
501 systems = {1:'Veto',2:'US',3:'DS',0:'Scifi'}
502 for collection in ['hitCollectionX','hitCollectionY']:
503 for c in h[collection]:
504 rc=h[collection][c][1].SetName(c)
505 rc=h[collection][c][1].Set(0)
506
507 if hitColour:
508 h["markerCollection"] = []
509
510 #Do we still use these lines? Seems no.
511 #And for events having all negative QDCs minT[1] is returned empty and the display crashes.
512 #dTs = "%5.2Fns"%(dT/u.snd_freq*1E9)
513 # find detector which triggered
514 #minT = firstTimeStamp(event)
515 #dTs+= " " + str(minT[1].GetDetectorID())
516 for p in proj:
517 rc = h[ 'simpleDisplay'].cd(p)
518 h[proj[p]].Draw('b')
519
520 if options.drawCollAxis:
521 for k in proj:
522 drawCollisionAxis(h['simpleDisplay'], k)
523
524 if withDetector:
525 drawDetectors()
526 for D in digis:
527 for digi in D:
528 detID = digi.GetDetectorID()
529 sipmMult = 1
530 if digi.GetName() == 'MuFilterHit':
531 system = digi.GetSystem()
532 geo.modules['MuFilter'].GetPosition(detID,A,B)
533 sipmMult = len(digi.GetAllSignals(False,False))
534 if sipmMult<minSipmMult and (system==1 or system==2): continue
535 else:
536 geo.modules['Scifi'].GetSiPMPosition(detID,A,B)
537 system = 0
538 curPath = nav.GetPath()
539 tmp = curPath.rfind('/')
540 nav.cd(curPath[:tmp])
541 first = True
542 for X in [A, B]:
543 if not first and not with2Points:
544 continue
545 first = False
546 globA, locA = array('d', [X[0], X[1], X[2]]), array('d', [X[0], X[1], X[2]])
547 if trans2local:
548 nav.MasterToLocal(globA, locA)
549 Z = X[2]
550 if digi.isVertical():
551 # only using hits with positive qdc for centroids, so only show such
552 if options.drawShowerDir and system==0 and digi.GetSignal(0)<0:
553 continue
554 collection = 'hitCollectionX'
555 Y = locA[0]
556 sY = detSize[system][0]
557 else:
558 # only using hits with positive qdc for centroids, so only show such
559 if options.drawShowerDir and system==0 and digi.GetSignal(0)<0:
560 continue
561 collection = 'hitCollectionY'
562 Y = locA[1]
563 sY = detSize[system][1]
564 c = h[collection][systems[system]]
565 rc = c[1].SetPoint(c[0], Z, Y)
566 rc = c[1].SetPointError(c[0], detSize[system][2], sY)
567 c[0] += 1
568 if hitColour == "q" :
569 max_QDC = 200 * 16
570 this_qdc = 0
571 ns = max(1,digi.GetnSides())
572 for side in range(ns):
573 for m in range(digi.GetnSiPMs()):
574 qdc = digi.GetSignal(m+side*digi.GetnSiPMs())
575 if not qdc < 0 :
576 this_qdc += qdc
577 if this_qdc > max_QDC :
578 this_qdc = max_QDC
579 fillNode(curPath, ROOT.TColor.GetPalette()[int(this_qdc/max_QDC*(len(ROOT.TColor.GetPalette())-1))])
580 else :
581 fillNode(curPath)
582
583 if digi.isVertical(): F = 'firedChannelsX'
584 else: F = 'firedChannelsY'
585 ns = max(1,digi.GetnSides())
586 for side in range(ns):
587 for m in range(digi.GetnSiPMs()):
588 qdc = digi.GetSignal(m+side*digi.GetnSiPMs())
589 if qdc < 0 and qdc > -900: h[F][systems[system]][1]+=1
590 elif not qdc<0:
591 h[F][systems[system]][0]+=1
592 if len(h[F][systems[system]]) < 2+side: continue
593 h[F][systems[system]][2+side]+=qdc
594 h['hitCollectionY']['Scifi'][1].SetMarkerColor(ROOT.kBlue+2)
595 h['hitCollectionX']['Scifi'][1].SetMarkerColor(ROOT.kBlue+2)
596
597 if hitColour == "q" :
598 for orientation in ['X', 'Y']:
599 max_density = 40
600 density = np.clip(0, max_density, getSciFiHitDensity(h['hitCollection'+orientation]['Scifi'][1]))
601 for i in range(h['hitCollection'+orientation]['Scifi'][1].GetN()) :
602 h['hitColour'+orientation]['Scifi'].append(ROOT.TColor.GetPalette()[int(float(density[i])/max_density*(len(ROOT.TColor.GetPalette())-1))])
603
604 drawLegend(max_density, max_QDC, 5)
605
606 k = 1
607 moreEventInfo = []
608
609
610 for collection in ['hitCollectionX','hitCollectionY']:
611 h['simpleDisplay'].cd(k)
612 drawInfo(h['simpleDisplay'], k, runId, N, T)
613 k+=1
614 for c in h[collection]:
615 F = collection.replace('hitCollection','firedChannels')
616 pj = collection.split('ion')[1]
617 if pj =="X" or c=="Scifi":
618 atext = "%1s %5s %3i +:%3i -:%3i qdc :%5.1F"%(pj,c,h[collection][c][1].GetN(),h[F][c][0],h[F][c][1],h[F][c][2])
619 else:
620 atext = "%1s %5s %3i +:%3i -:%3i qdcL:%5.1F qdcR:%5.1F"%(pj,c,h[collection][c][1].GetN(),h[F][c][0],h[F][c][1],h[F][c][2],h[F][c][3])
621 moreEventInfo.append(atext)
622 print(atext)
623 if h[collection][c][1].GetN()<1: continue
624 if c=='Scifi':
625 if hitColour not in ["q"] :
626 h[collection][c][1].SetMarkerStyle(20)
627 h[collection][c][1].SetMarkerSize(1.5)
628 rc=h[collection][c][1].Draw('sameP')
629 h['display:'+c]=h[collection][c][1]
630 elif hitColour == "q" :
631 drawSciFiHits(h[collection][c][1], h['hitColour'+collection[-1]][c])
632
633 T0 = eventTree.EventHeader.GetEventTime()
634 if type(start) == type(1): rc = event.GetEvent(N-1)
635 else: rc = event.GetEvent(start[N]-1)
636 delTM1 = eventTree.EventHeader.GetEventTime() - T0
637 if type(start) == type(1): rc = event.GetEvent(N+1)
638 else: rc = event.GetEvent(start[N]+1)
639 delTP1 = eventTree.EventHeader.GetEventTime() - T0
640 atext = "timing info, prev event: %6i cc next event: %6i cc"%(delTM1,delTP1)
641 moreEventInfo.append(atext)
642 if type(start) == type(1): rc = event.GetEvent(N)
643 else: rc = event.GetEvent(start[N])
644
645 k = 1
646 for collection in ['hitCollectionX','hitCollectionY']:
647 h['simpleDisplay'].cd(k)
648 drawInfo(h['simpleDisplay'], k, runId, N, T,moreEventInfo)
649 k+=1
650
651 h['simpleDisplay'].Update()
652 if withTiming: timingOfEvent()
653 addTrack(OT)
654
655 # try finding shower direction and intercept
656 if options.drawShowerDir:
657 sh_scifi_planes, sh_us_planes = ROOT.snd.analysis_tools.GetShoweringPlanes(scifi_planes, us_planes)
658 ref_point, shower_direction = ROOT.snd.analysis_tools.GetShowerInterceptAndDirection(configuration, sh_scifi_planes, sh_us_planes)
659 is_nan = np.isnan([ref_point.X(), ref_point.Y(), ref_point.Z(), shower_direction.X(), shower_direction.Y(), shower_direction.Z()]).any()
660 if is_nan:
661 print("Found shower direction and/or intercept contain NaN value")
662 # try finding the shower origin
663 else:
664 shower_start = 10*ROOT.snd.analysis_tools.GetScifiShowerStart(scifi_planes)
665 if shower_start<0:
666 print("Could not find shower start in SciFi, going for US")
667 shower_start = 100*ROOT.snd.analysis_tools.GetUSShowerStart(us_planes)
668 if shower_start<0:
669 print("Could not find shower start in SciFi or in US")
670 else:
671 for k in proj:
672 if k==1:
673 drawShowerAxis(h['simpleDisplay'], k, shower_start, ref_point.X(),
674 shower_direction.X()/shower_direction.Z())
675 else:
676 drawShowerAxis(h['simpleDisplay'], k, shower_start, ref_point.Y(),
677 shower_direction.Y()/shower_direction.Z())
678 h['simpleDisplay'].Update()
679
680 if option == "2tracks":
681 rc = twoTrackEvent(sMin=10,dClMin=7,minDistance=0.5,sepDistance=0.5)
682 if not rc: rc = twoTrackEvent(sMin=10,dClMin=7,minDistance=0.5,sepDistance=0.75)
683 if not rc: rc = twoTrackEvent(sMin=10,dClMin=7,minDistance=0.5,sepDistance=1.0)
684 if not rc: rc = twoTrackEvent(sMin=10,dClMin=7,minDistance=0.5,sepDistance=1.75)
685 if not rc: rc = twoTrackEvent(sMin=10,dClMin=7,minDistance=0.5,sepDistance=2.5)
686 if not rc: rc = twoTrackEvent(sMin=10,dClMin=7,minDistance=0.5,sepDistance=3.0)
687
688 if verbose>0: dumpChannels()
689 userProcessing(event)
690
691 if save:
692 h['simpleDisplay'].Print('{:0>2d}-event_{:04d}'.format(runId, N) + '.' + options.extension)
693 if auto:
694 h['simpleDisplay'].Print(options.storePic + str(runId) + '-event_' + str(event.EventHeader.GetEventNumber()) + '.' + options.extension)
695 if not auto:
696 rc = input("hit return for next event or p for print or q for quit: ")
697 if rc=='p':
698 h['simpleDisplay'].Print(options.storePic + str(runId) + '-event_' + str(event.EventHeader.GetEventNumber()) + '.' + options.extension)
699 elif rc == 'q':
700 break
701 else:
702 eventComment[f"{runId}-event_{event.EventHeader.GetEventNumber()}"] = rc
703 if save:
704 os.system("convert -delay 60 -loop 0 event*." + options.extension + " animated.gif")
705

◆ MuFilter_PlaneBars()

2dEventDisplay.MuFilter_PlaneBars (   detID)

Definition at line 971 of file 2dEventDisplay.py.

971def MuFilter_PlaneBars(detID):
972 s = detID//10000
973 l = (detID%10000)//1000 # plane number
974 bar = (detID%1000)
975 if s>2:
976 l=2*l
977 if bar>59:
978 bar=bar-60
979 if l<6: l+=1
980 return {'station':s,'plane':l,'bar':bar}
981

◆ mufiNoise()

2dEventDisplay.mufiNoise ( )

Definition at line 1105 of file 2dEventDisplay.py.

1105def mufiNoise():
1106 for s in range(1,4):
1107 ut.bookHist(h,'mult'+str(s),'hit mult for system '+str(s),100,-0.5,99.5)
1108 ut.bookHist(h,'multb'+str(s),'hit mult per bar for system '+str(s),20,-0.5,19.5)
1109 ut.bookHist(h,'res'+str(s),'residual system '+str(s),20,-10.,10.)
1110 OT = sink.GetOutTree()
1111 N=0
1112 for event in eventTree:
1113 N+=1
1114 if N%1000==0: print(N)
1115 OT.Reco_MuonTracks.Delete()
1116 rc = trackTask.ExecuteTask("Scifi")
1117 for aTrack in OT.Reco_MuonTracks:
1118 mom = aTrack.getFittedState().getMom()
1119 pos = aTrack.getFittedState().getPos()
1120 if not aTrack.getFitStatus().isFitConverged(): continue
1121 mult = {1:0,2:0,3:0}
1122 for aHit in eventTree.Digi_MuFilterHits:
1123 if not aHit.isValid(): continue
1124 s = aHit.GetDetectorID()//10000
1125 S = aHit.GetAllSignals(False,False)
1126 rc = h['multb'+str(s)].Fill(len(S))
1127 mult[s]+=len(S)
1128 if s==2 or s==1:
1129 geo.modules['MuFilter'].GetPosition(aHit.GetDetectorID(),A,B)
1130 y = (A[1]+B[1])/2.
1131 zEx = (A[2]+B[2])/2.
1132 lam = (zEx-pos.z())/mom.z()
1133 Ey = pos.y()+lam*mom.y()
1134 rc = h['res'+str(s)].Fill(Ey-y)
1135 for s in mult: rc = h['mult'+str(s)].Fill(mult[s])
1136 ut.bookCanvas(h,'noise','',1200,1200,2,3)
1137 for s in range(1,4):
1138 tc = h['noise'].cd(s*2-1)
1139 tc.SetLogy(1)
1140 h['mult'+str(s)].Draw()
1141 h['noise'].cd(s*2)
1142 h['multb'+str(s)].Draw()
1143 ut.bookCanvas(h,'res','',600,1200,1,3)
1144 for s in range(1,4):
1145 tc = h['res'].cd(s)
1146 h['res'+str(s)].Draw()
1147

◆ pyExit()

2dEventDisplay.pyExit ( )

Definition at line 24 of file 2dEventDisplay.py.

24def pyExit():
25 "unfortunately need as bypassing an issue related to use xrootd"
26 os.system('kill '+str(os.getpid()))

◆ timingOfEvent()

2dEventDisplay.timingOfEvent (   makeCluster = False,
  debug = False 
)

Definition at line 1059 of file 2dEventDisplay.py.

1059def timingOfEvent(makeCluster=False,debug=False):
1060 ut.bookHist(h,'evTimeDS','cor time of hits;[ns]',70,-5.,30)
1061 ut.bookHist(h,'evTimeScifi','cor time of hits blue DS red Scifi;[ns]',70,-5.,30)
1062 ut.bookCanvas(h,'tevTime','cor time of hits',1024,768,1,1)
1063 h['evTimeScifi'].SetLineColor(ROOT.kRed)
1064 h['evTimeDS'].SetLineColor(ROOT.kBlue)
1065 h['evTimeScifi'].SetStats(0)
1066 h['evTimeDS'].SetStats(0)
1067 h['evTimeScifi'].SetLineWidth(2)
1068 h['evTimeDS'].SetLineWidth(2)
1069 if makeCluster: trackTask.scifiCluster()
1070 meanXY = {}
1071 for siCl in trackTask.clusScifi:
1072 detID = siCl.GetFirst()
1073 s = detID//1000000
1074 isVertical = detID%1000000//100000
1075 siCl.GetPosition(A,B)
1076 z=(A[2]+B[2])/2.
1077 pos = (A[1]+B[1])/2.
1078 L = abs(A[0]-B[0])/2.
1079 if isVertical:
1080 pos = (A[0]+B[0])/2.
1081 L = abs(A[1]-B[1])/2.
1082 corTime = geo.modules['Scifi'].GetCorrectedTime(detID, siCl.GetTime(), 0) - (z-firstScifi_z)/u.speedOfLight
1083 h['evTimeScifi'].Fill(corTime)
1084 if debug: print(detID,corTime,pos)
1085 for aHit in eventTree.Digi_MuFilterHits:
1086 detID = aHit.GetDetectorID()
1087 if not detID//10000==3: continue
1088 if aHit.isVertical(): nmax = 1
1089 else: nmax=2
1090 geo.modules['MuFilter'].GetPosition(detID,A,B)
1091 z=(A[2]+B[2])/2.
1092 pos = (A[1]+B[1])/2.
1093 L = abs(A[0]-B[0])/2.
1094 if isVertical:
1095 pos = (A[0]+B[0])/2.
1096 L = abs(A[1]-B[1])/2.
1097 for i in range(nmax):
1098 corTime = geo.modules['MuFilter'].GetCorrectedTime(detID, i, aHit.GetTime(i)*u.snd_TDC2ns, 0)- (z-firstScifi_z)/u.speedOfLight
1099 h['evTimeDS'].Fill(corTime)
1100 if debug: print(detID,i,corTime,pos)
1101 tc=h['tevTime'].cd()
1102 h['evTimeScifi'].Draw()
1103 h['evTimeDS'].Draw('same')
1104 tc.Update()

◆ twoTrackEvent()

2dEventDisplay.twoTrackEvent (   sMin = 10,
  dClMin = 7,
  minDistance = 1.5,
  sepDistance = 0.5 
)

Definition at line 757 of file 2dEventDisplay.py.

757def twoTrackEvent(sMin=10,dClMin=7,minDistance=1.5,sepDistance=0.5):
758 trackTask.clusScifi.Clear()
759 trackTask.scifiCluster()
760 clusters = trackTask.clusScifi
761 sortedClusters={}
762 for aCl in clusters:
763 so = aCl.GetFirst()//100000
764 if not so in sortedClusters: sortedClusters[so]=[]
765 sortedClusters[so].append(aCl)
766 if len(sortedClusters)<sMin: return False
767 M=0
768 for x in sortedClusters:
769 if len(sortedClusters[x]) == 2: M+=1
770 if M < dClMin: return False
771 seeds = {}
772 S = [-1,-1]
773 for o in range(0,2):
774# same procedure for both projections
775# take seeds from from first station with 2 clusters
776 for s in range(1,6):
777 x = 10*s+o
778 if x in sortedClusters:
779 if len(sortedClusters[x])==2:
780 sortedClusters[x][0].GetPosition(A,B)
781 if o%2==1: pos0 = (A[0]+B[0])/2
782 else: pos0 = (A[1]+B[1])/2
783 sortedClusters[x][1].GetPosition(A,B)
784 if o%2==1: pos1 = (A[0]+B[0])/2
785 else: pos1 = (A[1]+B[1])/2
786 if abs(pos0-pos1) > minDistance:
787 S[o] = s
788 break
789 if S[o]<0: break # no seed found
790 seeds[o]={}
791 k = -1
792 for c in sortedClusters[S[o]*10+o]:
793 k += 1
794 c.GetPosition(A,B)
795 if o%2==1: pos = (A[0]+B[0])/2
796 else: pos = (A[1]+B[1])/2
797 seeds[o][k] = [[c,pos]]
798 if k!=1: continue
799 if abs(seeds[o][0][0][1] - seeds[o][1][0][1]) < sepDistance: continue
800 for s in range(1,6):
801 if s==S[o]: continue
802 for c in sortedClusters[s*10+o]:
803 c.GetPosition(A,B)
804 if o%2==1: pos = (A[0]+B[0])/2
805 else: pos = (A[1]+B[1])/2
806 for k in range(2):
807 if abs(seeds[o][k][0][1] - pos) < sepDistance:
808 seeds[o][k].append([c,pos])
809 if S[0]<0 or S[1]<0:
810 passed = False
811 else:
812 passed = True
813 for o in range(0,2):
814 for k in range(2):
815 if len(seeds[o][k])<3:
816 passed = False
817 break
818 print(passed)
819 if passed:
820 tracks = []
821 for k in range(2):
822 # arbitrarly combine X and Y of combination 0
823 n = 0
824 hitlist = {}
825 for o in range(0,2):
826 for X in seeds[o][k]:
827 hitlist[n] = X[0]
828 n+=1
829 theTrack = trackTask.fitTrack(hitlist)
830 if not hasattr(theTrack,"getFittedState"):
831 validTrack = False
832 continue
833 fitStatus = theTrack.getFitStatus()
834 if not fitStatus.isFitConverged():
835 theTrack.Delete()
836 else:
837 tracks.append(theTrack)
838 if len(tracks)==2:
839 OT = sink.GetOutTree()
840 OT.Reco_MuonTracks = tracks
841 addTrack(OT,True)
842 return passed
843

◆ userProcessing()

2dEventDisplay.userProcessing (   event)
User hook to add action after event is plotted.

Useful for adding special objects to the display for example.
An example for display of 3-track events with external reco:

```python
trackTask.multipleTrackCandidates(
    nMaxCl=8, dGap=0.2, dMax=0.8, dMax3=0.8, ovMax=1, doublet=True, debug=False
)
n3D = [0, 0]
for p in range(2):
    tc = h['simpleDisplay'].cd(-p + 2)
    for trackId in trackTask.multipleTrackStore['trackCand'][p]:
        if trackId < 100000 and not trackTask.multipleTrackStore['doublet']:
            continue
        if trackId in trackTask.multipleTrackStore['cloneCand'][p]:
            continue
        n3D[p] += 1
        rc = trackTask.multipleTrackStore['trackCand'][p][trackId].Fit('pol1', 'SQ')
        trackTask.multipleTrackStore['trackCand'][p][trackId].Draw('same')
    tc.Update()
print('Number of full tracks', n3D)
return True
```

Definition at line 198 of file 2dEventDisplay.py.

198def userProcessing(event):
199 '''User hook to add action after event is plotted.
200
201 Useful for adding special objects to the display for example.
202 An example for display of 3-track events with external reco:
203
204 ```python
205 trackTask.multipleTrackCandidates(
206 nMaxCl=8, dGap=0.2, dMax=0.8, dMax3=0.8, ovMax=1, doublet=True, debug=False
207 )
208 n3D = [0, 0]
209 for p in range(2):
210 tc = h['simpleDisplay'].cd(-p + 2)
211 for trackId in trackTask.multipleTrackStore['trackCand'][p]:
212 if trackId < 100000 and not trackTask.multipleTrackStore['doublet']:
213 continue
214 if trackId in trackTask.multipleTrackStore['cloneCand'][p]:
215 continue
216 n3D[p] += 1
217 rc = trackTask.multipleTrackStore['trackCand'][p][trackId].Fit('pol1', 'SQ')
218 trackTask.multipleTrackStore['trackCand'][p][trackId].Draw('same')
219 tc.Update()
220 print('Number of full tracks', n3D)
221 return True
222 ```
223 '''
224 return
225

◆ zoom()

2dEventDisplay.zoom (   xmin = None,
  xmax = None,
  ymin = None,
  ymax = None,
  zmin = None,
  zmax = None 
)

Definition at line 937 of file 2dEventDisplay.py.

937def zoom(xmin=None,xmax=None,ymin=None,ymax=None,zmin=None,zmax=None):
938# zoom() will reset to default setting
939 for d in ['xmin','xmax','ymin','ymax','zmin','zmax']:
940 if eval(d): h['c'+d]=eval(d)
941 else: h['c'+d]=h[d]
942 h['xz'].GetXaxis().SetRangeUser(h['czmin'],h['czmax'])
943 h['yz'].GetXaxis().SetRangeUser(h['czmin'],h['czmax'])
944 h['xz'].GetYaxis().SetRangeUser(h['cxmin'],h['cxmax'])
945 h['yz'].GetYaxis().SetRangeUser(h['cymin'],h['cymax'])
946 tc = h['simpleDisplay'].cd(1)
947 tc.Update()
948 tc = h['simpleDisplay'].cd(2)
949 tc.Update()
950 h['simpleDisplay'].Update()
951

Variable Documentation

◆ A

2dEventDisplay.A

Definition at line 30 of file 2dEventDisplay.py.

◆ action

2dEventDisplay.action

Definition at line 43 of file 2dEventDisplay.py.

◆ B

2dEventDisplay.B

Definition at line 30 of file 2dEventDisplay.py.

◆ default

2dEventDisplay.default

Definition at line 38 of file 2dEventDisplay.py.

◆ dest

2dEventDisplay.dest

Definition at line 37 of file 2dEventDisplay.py.

◆ detSize

dict 2dEventDisplay.detSize = {}

Definition at line 80 of file 2dEventDisplay.py.

◆ Digi_MuFilterHits

2dEventDisplay.Digi_MuFilterHits

Definition at line 162 of file 2dEventDisplay.py.

◆ em

2dEventDisplay.em = geo.snd_geo.EmulsionDet

Definition at line 81 of file 2dEventDisplay.py.

◆ eventComment

dict 2dEventDisplay.eventComment = {}

Definition at line 32 of file 2dEventDisplay.py.

◆ eventTree

2dEventDisplay.eventTree = f.Get("cbmsim")

Definition at line 111 of file 2dEventDisplay.py.

◆ f

2dEventDisplay.f = ROOT.TFile.Open(options.path+'sndsw_raw_'+str(options.runNumber).zfill(6)+'.root')

Definition at line 106 of file 2dEventDisplay.py.

◆ False

2dEventDisplay.False

Definition at line 38 of file 2dEventDisplay.py.

◆ fg

2dEventDisplay.fg = ROOT.TFile.Open(options.server+options.p+"RunInfodict.root")

Definition at line 67 of file 2dEventDisplay.py.

◆ firstScifi_z

int 2dEventDisplay.firstScifi_z = 300 * u.cm

Definition at line 94 of file 2dEventDisplay.py.

◆ format

2dEventDisplay.format

Definition at line 18 of file 2dEventDisplay.py.

◆ FSdict

2dEventDisplay.FSdict = pkl.load('FSdict')

Definition at line 171 of file 2dEventDisplay.py.

◆ fsdict

bool 2dEventDisplay.fsdict = False

Definition at line 173 of file 2dEventDisplay.py.

◆ geo

2dEventDisplay.geo = SndlhcGeo.GeoInterface(options.geoFile)

Definition at line 74 of file 2dEventDisplay.py.

◆ h

dict 2dEventDisplay.h = {}

Definition at line 34 of file 2dEventDisplay.py.

◆ help

2dEventDisplay.help

Definition at line 37 of file 2dEventDisplay.py.

◆ HT_tasks

dict 2dEventDisplay.HT_tasks
Initial value:
1= {'muon_reco_task_Sf':SndlhcMuonReco.MuonReco(),
2 'muon_reco_task_DS':SndlhcMuonReco.MuonReco(),
3 'muon_reco_task_nuInt':SndlhcMuonReco.MuonReco()}

Definition at line 124 of file 2dEventDisplay.py.

◆ int

2dEventDisplay.int

Definition at line 37 of file 2dEventDisplay.py.

◆ ioman

2dEventDisplay.ioman = ROOT.FairRootManager.Instance()

Definition at line 103 of file 2dEventDisplay.py.

◆ level

2dEventDisplay.level

Definition at line 18 of file 2dEventDisplay.py.

◆ logger

2dEventDisplay.logger = ROOT.FairLogger.GetLogger()

Definition at line 96 of file 2dEventDisplay.py.

◆ lsOfGlobals

2dEventDisplay.lsOfGlobals = ROOT.gROOT.GetListOfGlobals()

Definition at line 76 of file 2dEventDisplay.py.

◆ mc

2dEventDisplay.mc = False

Definition at line 92 of file 2dEventDisplay.py.

◆ mi

2dEventDisplay.mi = geo.snd_geo.MuFilter

Definition at line 84 of file 2dEventDisplay.py.

◆ nav

2dEventDisplay.nav = ROOT.gGeoManager.GetCurrentNavigator()

Definition at line 164 of file 2dEventDisplay.py.

◆ Nlimit

int 2dEventDisplay.Nlimit = 4

Definition at line 179 of file 2dEventDisplay.py.

◆ onlyScifi

bool 2dEventDisplay.onlyScifi = False

Definition at line 180 of file 2dEventDisplay.py.

◆ options

2dEventDisplay.options = parser.parse_args()

Definition at line 55 of file 2dEventDisplay.py.

◆ OT

2dEventDisplay.OT = sink.GetOutTree()

Definition at line 151 of file 2dEventDisplay.py.

◆ outFile

2dEventDisplay.outFile = ROOT.TMemFile('dummy','CREATE')

Definition at line 118 of file 2dEventDisplay.py.

◆ parser

2dEventDisplay.parser = ArgumentParser()

Definition at line 36 of file 2dEventDisplay.py.

◆ pkl

2dEventDisplay.pkl = Unpickler(fg)

Definition at line 68 of file 2dEventDisplay.py.

◆ required

2dEventDisplay.required

Definition at line 37 of file 2dEventDisplay.py.

◆ resolution_factor

int 2dEventDisplay.resolution_factor = 1

Definition at line 57 of file 2dEventDisplay.py.

◆ run

2dEventDisplay.run = ROOT.FairRunAna()

Definition at line 102 of file 2dEventDisplay.py.

◆ runId

str 2dEventDisplay.runId = 'sim'

Definition at line 112 of file 2dEventDisplay.py.

◆ runInfo

2dEventDisplay.runInfo = False

Definition at line 65 of file 2dEventDisplay.py.

◆ runNumber

2dEventDisplay.runNumber = eventTree.EventHeader.GetRunId()

Definition at line 168 of file 2dEventDisplay.py.

◆ si

2dEventDisplay.si = geo.snd_geo.Scifi

Definition at line 82 of file 2dEventDisplay.py.

◆ sink

2dEventDisplay.sink = ROOT.FairRootFileSink(outFile)

Definition at line 121 of file 2dEventDisplay.py.

◆ source

2dEventDisplay.source = ROOT.FairFileSource(f)

Definition at line 119 of file 2dEventDisplay.py.

◆ storePic

2dEventDisplay.storePic

Definition at line 63 of file 2dEventDisplay.py.

◆ trackTask

2dEventDisplay.trackTask = SndlhcTracking.Tracking()

Definition at line 131 of file 2dEventDisplay.py.

◆ trans2local

bool 2dEventDisplay.trans2local = False

Definition at line 64 of file 2dEventDisplay.py.

◆ type

2dEventDisplay.type

Definition at line 37 of file 2dEventDisplay.py.

◆ vetoXdim

2dEventDisplay.vetoXdim

Definition at line 85 of file 2dEventDisplay.py.

◆ with2Points

bool 2dEventDisplay.with2Points = False

Definition at line 91 of file 2dEventDisplay.py.

◆ withDetector

bool 2dEventDisplay.withDetector = True

Definition at line 90 of file 2dEventDisplay.py.

◆ xrdb

2dEventDisplay.xrdb = ROOT.FairRuntimeDb.instance()

Definition at line 136 of file 2dEventDisplay.py.