SND@LHC Software
Loading...
Searching...
No Matches
ShipAna.py
Go to the documentation of this file.
1from __future__ import print_function
2from __future__ import division
3# example for accessing smeared hits and fitted tracks
4import ROOT,os,sys,getopt
5import ctypes
6import rootUtils as ut
7import shipunit as u
8from ShipGeoConfig import ConfigRegistry
9from rootpyPickler import Unpickler
10from decorators import *
11import shipRoot_conf
12from argparse import ArgumentParser
13
15PDG = ROOT.TDatabasePDG.Instance()
16
17chi2CutOff = 4.
18fiducialCut = False
19measCutFK = 25
20measCutPR = 22
21docaCut = 2.
22
23parser = ArgumentParser()
24
25parser.add_argument("-f", "--inputFile", dest="inputFile", help="Input file", required=True)
26parser.add_argument("-n", "--nEvents", dest="nEvents", help="Number of events to analyze", required=False, default=999999,type=int)
27parser.add_argument("-g", "--geoFile", dest="geoFile", help="ROOT geofile", required=True)
28parser.add_argument("--Debug", dest="Debug", help="Switch on debugging", required=False, action="store_true")
29options = parser.parse_args()
30
31eosship = ROOT.gSystem.Getenv("EOSSHIP")
32if not options.inputFile.find(',')<0 :
33 sTree = ROOT.TChain("cbmsim")
34 for x in options.inputFile.split(','):
35 if x[0:4] == "/eos":
36 sTree.AddFile(eosship+x)
37 else: sTree.AddFile(x)
38elif options.inputFile[0:4] == "/eos":
39 eospath = eosship+options.inputFile
40 f = ROOT.TFile.Open(eospath)
41 sTree = f.cbmsim
42else:
43 f = ROOT.TFile(options.inputFile)
44 sTree = f.cbmsim
45
46# try to figure out which ecal geo to load
47if not options.geoFile:
48 options.geoFile = options.inputFile.replace('ship.','geofile_full.').replace('_rec.','.')
49if options.geoFile[0:4] == "/eos":
50 eospath = eosship+options.geoFile
51 fgeo = ROOT.TFile.Open(eospath)
52else:
53 fgeo = ROOT.TFile(options.geoFile)
54
55# new geofile, load Shipgeo dictionary written by run_simScript.py
56upkl = Unpickler(fgeo)
57ShipGeo = upkl.load('ShipGeo')
58ecalGeoFile = ShipGeo.ecal.File
59dy = ShipGeo.Yheight/u.m
60
61# -----Create geometry----------------------------------------------
62import shipDet_conf
63run = ROOT.FairRunSim()
64run.SetName("TGeant4") # Transport engine
65run.SetOutputFile(ROOT.TMemFile('output', 'recreate')) # Output file
66run.SetUserConfig("g4Config_basic.C") # geant4 transport not used, only needed for the mag field
67rtdb = run.GetRuntimeDb()
68# -----Create geometry----------------------------------------------
69modules = shipDet_conf.configure(run,ShipGeo)
70
71import geomGeant4
72if hasattr(ShipGeo.Bfield,"fieldMap"):
73 fieldMaker = geomGeant4.addVMCFields(ShipGeo, '', True, withVirtualMC = False)
74else:
75 print("no fieldmap given, geofile too old, not anymore support")
76 exit(-1)
77sGeo = fgeo.FAIRGeom
78geoMat = ROOT.genfit.TGeoMaterialInterface()
79ROOT.genfit.MaterialEffects.getInstance().init(geoMat)
80bfield = ROOT.genfit.FairShipFields()
81bfield.setField(fieldMaker.getGlobalField())
82fM = ROOT.genfit.FieldManager.getInstance()
83fM.init(bfield)
84
85volDict = {}
86i=0
87for x in ROOT.gGeoManager.GetListOfVolumes():
88 volDict[i]=x.GetName()
89 i+=1
90
91# prepare veto decisions
92import shipVeto
93veto = shipVeto.Task(sTree)
94vetoDets={}
95log={}
96h = {}
97ut.bookHist(h,'delPOverP','delP / P',400,0.,200.,100,-0.5,0.5)
98ut.bookHist(h,'pullPOverPx','delPx / sigma',400,0.,200.,100,-3.,3.)
99ut.bookHist(h,'pullPOverPy','delPy / sigma',400,0.,200.,100,-3.,3.)
100ut.bookHist(h,'pullPOverPz','delPz / sigma',400,0.,200.,100,-3.,3.)
101ut.bookHist(h,'delPOverP2','delP / P chi2/nmeas<'+str(chi2CutOff),400,0.,200.,100,-0.5,0.5)
102ut.bookHist(h,'delPOverPz','delPz / Pz',400,0.,200.,100,-0.5,0.5)
103ut.bookHist(h,'delPOverP2z','delPz / Pz chi2/nmeas<'+str(chi2CutOff),400,0.,200.,100,-0.5,0.5)
104ut.bookHist(h,'chi2','chi2/nmeas after trackfit',100,0.,10.)
105ut.bookHist(h,'prob','prob(chi2)',100,0.,1.)
106ut.bookHist(h,'IP','Impact Parameter',100,0.,10.)
107ut.bookHist(h,'Vzresol','Vz reco - true [cm]',100,-50.,50.)
108ut.bookHist(h,'Vxresol','Vx reco - true [cm]',100,-10.,10.)
109ut.bookHist(h,'Vyresol','Vy reco - true [cm]',100,-10.,10.)
110ut.bookHist(h,'Vzpull','Vz pull',100,-5.,5.)
111ut.bookHist(h,'Vxpull','Vx pull',100,-5.,5.)
112ut.bookHist(h,'Vypull','Vy pull',100,-5.,5.)
113ut.bookHist(h,'Doca','Doca between two tracks',100,0.,10.)
114for x in ['','_pi0']:
115 ut.bookHist(h,'IP0'+x,'Impact Parameter to target',100,0.,100.)
116 ut.bookHist(h,'IP0/mass'+x,'Impact Parameter to target vs mass',100,0.,2.,100,0.,100.)
117 ut.bookHist(h,'HNL'+x,'reconstructed Mass',500,0.,2.)
118ut.bookHist(h,'HNLw','reconstructed Mass with weights',500,0.,2.)
119ut.bookHist(h,'meas','number of measurements',40,-0.5,39.5)
120ut.bookHist(h,'meas2','number of measurements, fitted track',40,-0.5,39.5)
121ut.bookHist(h,'measVSchi2','number of measurements vs chi2/meas',40,-0.5,39.5,100,0.,10.)
122ut.bookHist(h,'distu','distance to wire',100,0.,1.)
123ut.bookHist(h,'distv','distance to wire',100,0.,1.)
124ut.bookHist(h,'disty','distance to wire',100,0.,1.)
125ut.bookHist(h,'meanhits','mean number of hits / track',50,-0.5,49.5)
126ut.bookHist(h,'ecalClusters','x/y and energy',50,-3.,3.,50,-6.,6.)
127
128ut.bookHist(h,'extrapTimeDetX','extrapolation to TimeDet X',100,-10.,10.)
129ut.bookHist(h,'extrapTimeDetY','extrapolation to TimeDet Y',100,-10.,10.)
130
131ut.bookHist(h,'oa','cos opening angle',100,0.999,1.)
132# potential Veto detectors
133ut.bookHist(h,'nrtracks','nr of tracks in signal selected',10,-0.5,9.5)
134ut.bookHist(h,'nrSVT','nr of hits in SVT',10,-0.5,9.5)
135ut.bookHist(h,'nrSBT','nr of hits in SBT',100,-0.5,99.5)
136ut.bookHist(h,'nrRPC','nr of hits in RPC',100,-0.5,99.5)
137
138import TrackExtrapolateTool
139
140def VertexError(t1,t2,PosDir,CovMat,scalFac):
141# with improved Vx x,y resolution
142 a,u = PosDir[t1]['position'],PosDir[t1]['direction']
143 c,v = PosDir[t2]['position'],PosDir[t2]['direction']
144 Vsq = v.Dot(v)
145 Usq = u.Dot(u)
146 UV = u.Dot(v)
147 ca = c-a
148 denom = Usq*Vsq-UV**2
149 tmp2 = Vsq*u-UV*v
150 Va = ca.Dot(tmp2)/denom
151 tmp2 = UV*u-Usq*v
152 Vb = ca.Dot(tmp2)/denom
153 X = (a+c+Va*u+Vb*v) * 0.5
154 l1 = a - X + u*Va # l2 = c - X + v*Vb
155 dist = 2. * ROOT.TMath.Sqrt( l1.Dot(l1) )
156 T = ROOT.TMatrixD(3,12)
157 for i in range(3):
158 for k in range(4):
159 for j in range(3):
160 KD = 0
161 if i==j: KD = 1
162 if k==0 or k==2:
163 # cova and covc
164 temp = ( u[j]*Vsq - v[j]*UV )*u[i] + (u[j]*UV-v[j]*Usq)*v[i]
165 sign = -1
166 if k==2 : sign = +1
167 T[i][3*k+j] = 0.5*( KD + sign*temp/denom )
168 elif k==1:
169 # covu
170 aNAZ = denom*( ca[j]*Vsq-v.Dot(ca)*v[j] )
171 aZAN = ( ca.Dot(u)*Vsq-ca.Dot(v)*UV )*2*( u[j]*Vsq-v[j]*UV )
172 bNAZ = denom*( ca[j]*UV+(u.Dot(ca)*v[j]) - 2*ca.Dot(v)*u[j] )
173 bZAN = ( ca.Dot(u)*UV-ca.Dot(v)*Usq )*2*( u[j]*Vsq-v[j]*UV )
174 T[i][3*k+j] = 0.5*( Va*KD + u[i]/denom**2*(aNAZ-aZAN) + v[i]/denom**2*(bNAZ-bZAN) )
175 elif k==3:
176 # covv
177 aNAZ = denom*( 2*ca.Dot(u)*v[j] - ca.Dot(v)*u[j] - ca[j]*UV )
178 aZAN = ( ca.Dot(u)*Vsq-ca.Dot(v)*UV )*2*( v[j]*Usq-u[j]*UV )
179 bNAZ = denom*( ca.Dot(u)*u[j]-ca[j]*Usq )
180 bZAN = ( ca.Dot(u)*UV-ca.Dot(v)*Usq )*2*( v[j]*Usq-u[j]*UV )
181 T[i][3*k+j] = 0.5*(Vb*KD + u[i]/denom**2*(aNAZ-aZAN) + v[i]/denom**2*(bNAZ-bZAN) )
182 transT = ROOT.TMatrixD(12,3)
183 transT.Transpose(T)
184 CovTracks = ROOT.TMatrixD(12,12)
185 tlist = [t1,t2]
186 for k in range(2):
187 for i in range(6):
188 for j in range(6):
189 xfac = 1.
190 if i>2: xfac = scalFac[tlist[k]]
191 if j>2: xfac = xfac * scalFac[tlist[k]]
192 CovTracks[i+k*6][j+k*6] = CovMat[tlist[k]][i][j] * xfac
193 # if i==5 or j==5 : CovMat[tlist[k]][i][j] = 0 # ignore error on z-direction
194 tmp = ROOT.TMatrixD(3,12)
195 tmp.Mult(T,CovTracks)
196 covX = ROOT.TMatrixD(3,3)
197 covX.Mult(tmp,transT)
198 return X,covX,dist
199
200from array import array
201def dist2InnerWall(X,Y,Z):
202 dist = 0
203 # return distance to inner wall perpendicular to z-axis, if outside decayVolume return 0.
204 node = sGeo.FindNode(X,Y,Z)
205 if ShipGeo.tankDesign < 5:
206 if not 'cave' in node.GetName(): return dist # TP
207 else:
208 if not 'DecayVacuum' in node.GetName(): return dist
209 start = array('d',[X,Y,Z])
210 nsteps = 8
211 dalpha = 2*ROOT.TMath.Pi()/nsteps
212 rsq = X**2+Y**2
213 minDistance = 100 *u.m
214 for n in range(nsteps):
215 alpha = n * dalpha
216 sdir = array('d',[ROOT.TMath.Sin(alpha),ROOT.TMath.Cos(alpha),0.])
217 node = sGeo.InitTrack(start, sdir)
218 nxt = sGeo.FindNextBoundary()
219 if ShipGeo.tankDesign < 5 and nxt.GetName().find('I')<0: return 0
220 distance = sGeo.GetStep()
221 if distance < minDistance : minDistance = distance
222 return minDistance
223
224def isInFiducial(X,Y,Z):
225 if not fiducialCut: return True
226 if Z > ShipGeo.TrackStation1.z : return False
227 if Z < ShipGeo.vetoStation.z+100.*u.cm : return False
228 # typical x,y Vx resolution for exclusive HNL decays 0.3cm,0.15cm (gaussian width)
229 if dist2InnerWall(X,Y,Z)<5*u.cm: return False
230 return True
231#
232def ImpactParameter(point,tPos,tMom):
233 t = 0
234 if hasattr(tMom,'P'): P = tMom.P()
235 else: P = tMom.Mag()
236 for i in range(3): t += tMom(i)/P*(point(i)-tPos(i))
237 dist = 0
238 for i in range(3): dist += (point(i)-tPos(i)-t*tMom(i)/P)**2
239 dist = ROOT.TMath.Sqrt(dist)
240 return dist
241#
242def checkHNLorigin(sTree):
243 flag = True
244 if not fiducialCut: return flag
245 flag = False
246# only makes sense for signal == HNL
247 hnlkey = -1
248 for n in range(sTree.MCTrack.GetEntries()):
249 mo = sTree.MCTrack[n].GetMotherId()
250 if mo <0: continue
251 if abs(sTree.MCTrack[mo].GetPdgCode()) == 9900015:
252 hnlkey = n
253 break
254 if hnlkey<0 :
255 ut.reportError("ShipAna: checkHNLorigin, no HNL found")
256 else:
257 # MCTrack after HNL should be first daughter
258 theHNLVx = sTree.MCTrack[hnlkey]
259 X,Y,Z = theHNLVx.GetStartX(),theHNLVx.GetStartY(),theHNLVx.GetStartZ()
260 if isInFiducial(X,Y,Z): flag = True
261 return flag
262
263def checkFiducialVolume(sTree,tkey,dy):
264# extrapolate track to middle of magnet and check if in decay volume
265 inside = True
266 if not fiducialCut: return True
267 fT = sTree.FitTracks[tkey]
268 rc,pos,mom = TrackExtrapolateTool.extrapolateToPlane(fT,ShipGeo.Bfield.z)
269 if not rc: return False
270 if not dist2InnerWall(pos.X(),pos.Y(),pos.Z())>0: return False
271 return inside
272def getPtruthFirst(sTree,mcPartKey):
273 Ptruth,Ptruthx,Ptruthy,Ptruthz = -1.,-1.,-1.,-1.
274 for ahit in sTree.strawtubesPoint:
275 if ahit.GetTrackID() == mcPartKey:
276 Ptruthx,Ptruthy,Ptruthz = ahit.GetPx(),ahit.GetPy(),ahit.GetPz()
277 Ptruth = ROOT.TMath.Sqrt(Ptruthx**2+Ptruthy**2+Ptruthz**2)
278 break
279 return Ptruth,Ptruthx,Ptruthy,Ptruthz
280
282 key = 0
283 for ahit in ev.SmearedHits.GetObject():
284 print(ahit[0],ahit[1],ahit[2],ahit[3],ahit[4],ahit[5],ahit[6])
285 # follow link to true MCHit
286 mchit = TrackingHits[key]
287 mctrack = MCTracks[mchit.GetTrackID()]
288 print(mchit.GetZ(),mctrack.GetP(),mctrack.GetPdgCode())
289 key+=1
290
291def myVertex(t1,t2,PosDir):
292 # closest distance between two tracks
293 # d = |pq . u x v|/|u x v|
294 a = ROOT.TVector3(PosDir[t1][0](0) ,PosDir[t1][0](1), PosDir[t1][0](2))
295 u = ROOT.TVector3(PosDir[t1][1](0),PosDir[t1][1](1),PosDir[t1][1](2))
296 c = ROOT.TVector3(PosDir[t2][0](0) ,PosDir[t2][0](1), PosDir[t2][0](2))
297 v = ROOT.TVector3(PosDir[t2][1](0),PosDir[t2][1](1),PosDir[t2][1](2))
298 pq = a-c
299 uCrossv = u.Cross(v)
300 dist = pq.Dot(uCrossv)/(uCrossv.Mag()+1E-8)
301 # u.a - u.c + s*|u|**2 - u.v*t = 0
302 # v.a - v.c + s*v.u - t*|v|**2 = 0
303 E = u.Dot(a) - u.Dot(c)
304 F = v.Dot(a) - v.Dot(c)
305 A,B = u.Mag2(), -u.Dot(v)
306 C,D = u.Dot(v), -v.Mag2()
307 t = -(C*E-A*F)/(B*C-A*D)
308 X = c.x()+v.x()*t
309 Y = c.y()+v.y()*t
310 Z = c.z()+v.z()*t
311 return X,Y,Z,abs(dist)
312def RedoVertexing(t1,t2):
313 PosDir = {}
314 for tr in [t1,t2]:
315 xx = sTree.FitTracks[tr].getFittedState()
316 PosDir[tr] = [xx.getPos(),xx.getDir()]
317 xv,yv,zv,doca = myVertex(t1,t2,PosDir)
318# as we have learned, need iterative procedure
319 dz = 99999.
320 reps,states,newPosDir = {},{},{}
321 parallelToZ = ROOT.TVector3(0., 0., 1.)
322 rc = True
323 step = 0
324 while dz > 0.1:
325 zBefore = zv
326 newPos = ROOT.TVector3(xv,yv,zv)
327 # make a new rep for track 1,2
328 for tr in [t1,t2]:
329 xx = sTree.FitTracks[tr].getFittedState()
330 reps[tr] = ROOT.genfit.RKTrackRep(xx.getPDG())
331 states[tr] = ROOT.genfit.StateOnPlane(reps[tr])
332 reps[tr].setPosMom(states[tr],xx.getPos(),xx.getMom())
333 try:
334 reps[tr].extrapolateToPoint(states[tr], newPos, False)
335 except:
336 print('SHiPAna: extrapolation did not worked')
337 rc = False
338 break
339 newPosDir[tr] = [reps[tr].getPos(states[tr]),reps[tr].getDir(states[tr])]
340 if not rc: break
341 xv,yv,zv,doca = myVertex(t1,t2,newPosDir)
342 dz = abs(zBefore-zv)
343 step+=1
344 if step > 10:
345 print('abort iteration, too many steps, pos=',xv,yv,zv,' doca=',doca,'z before and dz',zBefore,dz)
346 rc = False
347 break
348 if not rc: return xv,yv,zv,doca,-1 # extrapolation failed, makes no sense to continue
349 LV={}
350 for tr in [t1,t2]:
351 mom = reps[tr].getMom(states[tr])
352 pid = abs(states[tr].getPDG())
353 if pid == 2212: pid = 211
354 mass = PDG.GetParticle(pid).Mass()
355 E = ROOT.TMath.Sqrt( mass*mass + mom.Mag2() )
356 LV[tr] = ROOT.TLorentzVector()
357 LV[tr].SetPxPyPzE(mom.x(),mom.y(),mom.z(),E)
358 HNLMom = LV[t1]+LV[t2]
359 return xv,yv,zv,doca,HNLMom
360def fitSingleGauss(x,ba=None,be=None):
361 name = 'myGauss_'+x
362 myGauss = h[x].GetListOfFunctions().FindObject(name)
363 if not myGauss:
364 if not ba : ba = h[x].GetBinCenter(1)
365 if not be : be = h[x].GetBinCenter(h[x].GetNbinsX())
366 bw = h[x].GetBinWidth(1)
367 mean = h[x].GetMean()
368 sigma = h[x].GetRMS()
369 norm = h[x].GetEntries()*0.3
370 myGauss = ROOT.TF1(name,'[0]*'+str(bw)+'/([2]*sqrt(2*pi))*exp(-0.5*((x-[1])/[2])**2)+[3]',4)
371 myGauss.SetParameter(0,norm)
372 myGauss.SetParameter(1,mean)
373 myGauss.SetParameter(2,sigma)
374 myGauss.SetParameter(3,1.)
375 myGauss.SetParName(0,'Signal')
376 myGauss.SetParName(1,'Mean')
377 myGauss.SetParName(2,'Sigma')
378 myGauss.SetParName(3,'bckgr')
379 h[x].Fit(myGauss,'','',ba,be)
380
382 matched = False
383 hnlKey = []
384 for t in [p.GetDaughter(0),p.GetDaughter(1)]:
385 mcp = sTree.fitTrack2MC[t]
386 while mcp > -0.5:
387 mo = sTree.MCTrack[mcp]
388 if abs(mo.GetPdgCode()) == 9900015:
389 hnlKey.append(mcp)
390 break
391 mcp = mo.GetMotherId()
392 if len(hnlKey) == 2:
393 if hnlKey[0]==hnlKey[1]: matched = True
394 return matched
395def ecalCluster2MC(aClus):
396 # return MC track most contributing, and its fraction of energy
397 trackid = ctypes.c_int()
398 energy_dep = ctypes.c_double()
399 mcLink = {}
400 for i in range( aClus.Size() ):
401 mccell = ecalStructure.GetHitCell(aClus.CellNum(i)) # Get i'th cell of the cluster.
402 for n in range( mccell.TrackEnergySize()):
403 mccell.GetTrackEnergySlow(n, trackid, energy_dep)
404 if not abs(trackid.value)<sTree.MCTrack.GetEntries(): tid = -1
405 else: tid = trackid.value
406 if tid not in mcLink: mcLink[tid]=0
407 mcLink[tid]+=energy_dep.value
408# find trackid most contributing
409 eMax,mMax = 0,-1
410 for m in mcLink:
411 if mcLink[m]>eMax:
412 eMax = mcLink[m]
413 mMax = m
414 return mMax,eMax/aClus.Energy()
415
417 ut.bookCanvas(h,key='ecalanalysis',title='cluster map',nx=800,ny=600,cx=1,cy=1)
418 cv = h['ecalanalysis'].cd(1)
419 h['ecalClusters'].Draw('colz')
420 ut.bookCanvas(h,key='ecalCluster2Track',title='Ecal cluster distances to track impact',nx=1600,ny=800,cx=4,cy=2)
421 if "ecalReconstructed_dist_mu+" in h:
422 cv = h['ecalCluster2Track'].cd(1)
423 h['ecalReconstructed_distx_mu+'].Draw()
424 cv = h['ecalCluster2Track'].cd(2)
425 h['ecalReconstructed_disty_mu+'].Draw()
426 if "ecalReconstructed_dist_pi+" in h:
427 cv = h['ecalCluster2Track'].cd(3)
428 h['ecalReconstructed_distx_pi+'].Draw()
429 cv = h['ecalCluster2Track'].cd(4)
430 h['ecalReconstructed_disty_pi+'].Draw()
431 if "ecalReconstructed_dist_mu-" in h:
432 cv = h['ecalCluster2Track'].cd(5)
433 h['ecalReconstructed_distx_mu-'].Draw()
434 cv = h['ecalCluster2Track'].cd(6)
435 h['ecalReconstructed_disty_mu-'].Draw()
436 if "ecalReconstructed_dist_pi-" in h:
437 cv = h['ecalCluster2Track'].cd(7)
438 h['ecalReconstructed_distx_pi-'].Draw()
439 cv = h['ecalCluster2Track'].cd(8)
440 h['ecalReconstructed_disty_pi-'].Draw()
441
442 ut.bookCanvas(h,key='strawanalysis',title='Distance to wire and mean nr of hits',nx=1200,ny=600,cx=3,cy=1)
443 cv = h['strawanalysis'].cd(1)
444 h['disty'].Draw()
445 h['distu'].Draw('same')
446 h['distv'].Draw('same')
447 cv = h['strawanalysis'].cd(2)
448 h['meanhits'].Draw()
449 cv = h['strawanalysis'].cd(3)
450 h['meas2'].Draw()
451 ut.bookCanvas(h,key='fitresults',title='Fit Results',nx=1600,ny=1200,cx=2,cy=2)
452 cv = h['fitresults'].cd(1)
453 h['delPOverPz'].Draw('box')
454 cv = h['fitresults'].cd(2)
455 cv.SetLogy(1)
456 h['prob'].Draw()
457 cv = h['fitresults'].cd(3)
458 h['delPOverPz_proj'] = h['delPOverPz'].ProjectionY()
459 ROOT.gStyle.SetOptFit(11111)
460 h['delPOverPz_proj'].Draw()
461 h['delPOverPz_proj'].Fit('gaus')
462 cv = h['fitresults'].cd(4)
463 h['delPOverP2z_proj'] = h['delPOverP2z'].ProjectionY()
464 h['delPOverP2z_proj'].Draw()
465 fitSingleGauss('delPOverP2z_proj')
466 h['fitresults'].Print('fitresults.gif')
467 for x in ['','_pi0']:
468 ut.bookCanvas(h,key='fitresults2'+x,title='Fit Results '+x,nx=1600,ny=1200,cx=2,cy=2)
469 cv = h['fitresults2'+x].cd(1)
470 if x=='':
471 h['Doca'].SetXTitle('closest distance between 2 tracks [cm]')
472 h['Doca'].SetYTitle('N/1mm')
473 h['Doca'].Draw()
474 else:
475 h['pi0Mass'].SetXTitle('#gamma #gamma invariant mass [GeV/c^{2}]')
476 h['pi0Mass'].SetYTitle('N/'+str(int(h['pi0Mass'].GetBinWidth(1)*1000))+'MeV')
477 h['pi0Mass'].Draw()
478 fitResult = h['pi0Mass'].Fit('gaus','S','',0.08,0.19)
479 cv = h['fitresults2'+x].cd(2)
480 h['IP0'+x].SetXTitle('impact parameter to p-target [cm]')
481 h['IP0'+x].SetYTitle('N/1cm')
482 h['IP0'+x].Draw()
483 cv = h['fitresults2'+x].cd(3)
484 h['HNL'+x].SetXTitle('inv. mass [GeV/c^{2}]')
485 h['HNL'+x].SetYTitle('N/4MeV/c2')
486 h['HNL'+x].Draw()
487 fitSingleGauss('HNL'+x,0.9,1.1)
488 cv = h['fitresults2'+x].cd(4)
489 h['IP0/mass'+x].SetXTitle('inv. mass [GeV/c^{2}]')
490 h['IP0/mass'+x].SetYTitle('IP [cm]')
491 h['IP0/mass'+x].Draw('colz')
492 h['fitresults2'+x].Print('fitresults2'+x+'.gif')
493 ut.bookCanvas(h,key='vxpulls',title='Vertex resol and pulls',nx=1600,ny=1200,cx=3,cy=2)
494 cv = h['vxpulls'].cd(4)
495 h['Vxpull'].Draw()
496 cv = h['vxpulls'].cd(5)
497 h['Vypull'].Draw()
498 cv = h['vxpulls'].cd(6)
499 h['Vzpull'].Draw()
500 cv = h['vxpulls'].cd(1)
501 h['Vxresol'].Draw()
502 cv = h['vxpulls'].cd(2)
503 h['Vyresol'].Draw()
504 cv = h['vxpulls'].cd(3)
505 h['Vzresol'].Draw()
506 ut.bookCanvas(h,key='trpulls',title='momentum pulls',nx=1600,ny=600,cx=3,cy=1)
507 cv = h['trpulls'].cd(1)
508 h['pullPOverPx_proj']=h['pullPOverPx'].ProjectionY()
509 h['pullPOverPx_proj'].Draw()
510 cv = h['trpulls'].cd(2)
511 h['pullPOverPy_proj']=h['pullPOverPy'].ProjectionY()
512 h['pullPOverPy_proj'].Draw()
513 cv = h['trpulls'].cd(3)
514 h['pullPOverPz_proj']=h['pullPOverPz'].ProjectionY()
515 h['pullPOverPz_proj'].Draw()
516 ut.bookCanvas(h,key='vetodecisions',title='Veto Detectors',nx=1600,ny=600,cx=4,cy=1)
517 cv = h['vetodecisions'].cd(1)
518 cv.SetLogy(1)
519 h['nrtracks'].Draw()
520 cv = h['vetodecisions'].cd(2)
521 cv.SetLogy(1)
522 h['nrSVT'].Draw()
523 cv = h['vetodecisions'].cd(3)
524 cv.SetLogy(1)
525 h['nrSBT'].Draw()
526 cv = h['vetodecisions'].cd(4)
527 cv.SetLogy(1)
528 h['nrRPC'].Draw()
529#
530 print('finished making plots')
531# calculate z front face of ecal, needed later
532top = ROOT.gGeoManager.GetTopVolume()
533ecal = None
534if top.GetNode('Ecal_1'):
535 ecal = top.GetNode('Ecal_1')
536 z_ecal = ecal.GetMatrix().GetTranslation()[2]
537elif top.GetNode('SplitCalDetector_1'):
538 ecal = top.GetNode('SplitCalDetector_1')
539 z_ecal = ecal.GetMatrix().GetTranslation()[2]
540
541# start event loop
543 global ecalReconstructed
544 rc = sTree.GetEntry(n)
545# check if tracks are made from real pattern recognition
546 measCut = measCutFK
547 if sTree.GetBranch("FitTracks_PR"):
548 sTree.FitTracks = sTree.FitTracks_PR
549 measCut = measCutPR
550 if sTree.GetBranch("fitTrack2MC_PR"): sTree.fitTrack2MC = sTree.fitTrack2MC_PR
551 if sTree.GetBranch("Particles_PR"): sTree.Particles = sTree.Particles_PR
552 if not checkHNLorigin(sTree): return
553 if not sTree.MCTrack.GetEntries()>1: wg = 1.
554 else: wg = sTree.MCTrack[1].GetWeight()
555 if not wg>0.: wg=1.
556
557# make some ecal cluster analysis if exist
558 if hasattr(sTree,"EcalClusters"):
559 if calReco: ecalReconstructed.Delete()
560 else: ecalReconstructed = sTree.EcalReconstructed
561 for x in caloTasks:
562 if x.GetName() == 'ecalFiller': x.Exec('start',sTree.EcalPointLite)
563 elif x.GetName() == 'ecalMatch': x.Exec('start',ecalReconstructed,sTree.MCTrack)
564 else : x.Exec('start')
565 for aClus in ecalReconstructed:
566 mMax = aClus.MCTrack()
567 if mMax <0 or mMax > sTree.MCTrack.GetEntries():
568 aP = None # this should never happen, otherwise the ECAL MC matching has a bug
569 else: aP = sTree.MCTrack[mMax]
570 if aP:
571 tmp = PDG.GetParticle(aP.GetPdgCode())
572 if tmp: pName = 'ecalReconstructed_'+tmp.GetName()
573 else: pName = 'ecalReconstructed_'+str(aP.GetPdgCode())
574 else:
575 pName = 'ecalReconstructed_unknown'
576 if pName not in h:
577 ut.bookHist(h,pName,'x/y and energy for '+pName.split('_')[1],50,-3.,3.,50,-6.,6.)
578 rc = h[pName].Fill(aClus.X()/u.m,aClus.Y()/u.m,aClus.RecoE()/u.GeV)
579# look at distance to tracks
580 for fT in sTree.FitTracks:
581 rc,pos,mom = TrackExtrapolateTool.extrapolateToPlane(fT,z_ecal)
582 if rc:
583 pdgcode = fT.getFittedState().getPDG()
584 tmp = PDG.GetParticle(pdgcode)
585 if tmp: tName = 'ecalReconstructed_dist_'+tmp.GetName()
586 else: tName = 'ecalReconstructed_dist_'+str(aP.GetPdgCode())
587 if tName not in h:
588 p = tName.split('dist_')[1]
589 ut.bookHist(h,tName,'Ecal cluster distance t0 '+p,100,0.,100.*u.cm)
590 ut.bookHist(h,tName.replace('dist','distx'),'Ecal cluster distance to '+p+' in X ',100,-50.*u.cm,50.*u.cm)
591 ut.bookHist(h,tName.replace('dist','disty'),'Ecal cluster distance to '+p+' in Y ',100,-50.*u.cm,50.*u.cm)
592 dist = ROOT.TMath.Sqrt( (aClus.X()-pos.X())**2+(aClus.Y()-pos.Y())**2 )
593 rc = h[tName].Fill(dist)
594 rc = h[tName.replace('dist','distx')].Fill( aClus.X()-pos.X() )
595 rc = h[tName.replace('dist','disty')].Fill( aClus.Y()-pos.Y() )
596# compare with old method
597 for aClus in sTree.EcalClusters:
598 rc = h['ecalClusters'].Fill(aClus.X()/u.m,aClus.Y()/u.m,aClus.Energy()/u.GeV)
599 mMax,frac = ecalCluster2MC(aClus)
600# return MC track most contributing, and its fraction of energy
601 if mMax>0:
602 aP = sTree.MCTrack[mMax]
603 tmp = PDG.GetParticle(aP.GetPdgCode())
604 if tmp: pName = 'ecalClusters_'+tmp.GetName()
605 else: pName = 'ecalClusters_'+str(aP.GetPdgCode())
606 else:
607 pName = 'ecalClusters_unknown'
608 if pName not in h: ut.bookHist(h,pName,'x/y and energy for '+pName.split('_')[1],50,-3.,3.,50,-6.,6.)
609 rc = h[pName].Fill(aClus.X()/u.m,aClus.Y()/u.m,aClus.Energy()/u.GeV)
610
611# make some straw hit analysis
612 hitlist = {}
613 for ahit in sTree.strawtubesPoint:
614 detID = ahit.GetDetectorID()
615 top = ROOT.TVector3()
616 bot = ROOT.TVector3()
617 modules["Strawtubes"].StrawEndPoints(detID,bot,top)
618 dw = ahit.dist2Wire()
619 if detID < 50000000 :
620 if abs(top.y())==abs(bot.y()): h['disty'].Fill(dw)
621 if abs(top.y())>abs(bot.y()): h['distu'].Fill(dw)
622 if abs(top.y())<abs(bot.y()): h['distv'].Fill(dw)
623#
624 trID = ahit.GetTrackID()
625 if not trID < 0 :
626 if trID in hitlist: hitlist[trID]+=1
627 else: hitlist[trID]=1
628 for tr in hitlist: h['meanhits'].Fill(hitlist[tr])
629 key = -1
630 fittedTracks = {}
631 for atrack in sTree.FitTracks:
632 key+=1
633# kill tracks outside fiducial volume
634 if not checkFiducialVolume(sTree,key,dy): continue
635 fitStatus = atrack.getFitStatus()
636 nmeas = fitStatus.getNdf()
637 h['meas'].Fill(nmeas)
638 if not fitStatus.isFitConverged() : continue
639 h['meas2'].Fill(nmeas)
640 if nmeas < measCut: continue
641 fittedTracks[key] = atrack
642# needs different study why fit has not converged, continue with fitted tracks
643 rchi2 = fitStatus.getChi2()
644 prob = ROOT.TMath.Prob(rchi2,int(nmeas))
645 h['prob'].Fill(prob)
646 chi2 = rchi2/nmeas
647 fittedState = atrack.getFittedState()
648 h['chi2'].Fill(chi2,wg)
649 h['measVSchi2'].Fill(atrack.getNumPoints(),chi2)
650 P = fittedState.getMomMag()
651 Px,Py,Pz = fittedState.getMom().x(),fittedState.getMom().y(),fittedState.getMom().z()
652 cov = fittedState.get6DCov()
653 if len(sTree.fitTrack2MC)-1<key: continue
654 mcPartKey = sTree.fitTrack2MC[key]
655 mcPart = sTree.MCTrack[mcPartKey]
656 if not mcPart : continue
657 Ptruth_start = mcPart.GetP()
658 Ptruthz_start = mcPart.GetPz()
659 # get p truth from first strawpoint
660 Ptruth,Ptruthx,Ptruthy,Ptruthz = getPtruthFirst(sTree,mcPartKey)
661 delPOverP = (Ptruth - P)/Ptruth
662 h['delPOverP'].Fill(Ptruth,delPOverP)
663 delPOverPz = (1./Ptruthz - 1./Pz) * Ptruthz
664 h['pullPOverPx'].Fill( Ptruth,(Ptruthx-Px)/ROOT.TMath.Sqrt(cov[3][3]) )
665 h['pullPOverPy'].Fill( Ptruth,(Ptruthy-Py)/ROOT.TMath.Sqrt(cov[4][4]) )
666 h['pullPOverPz'].Fill( Ptruth,(Ptruthz-Pz)/ROOT.TMath.Sqrt(cov[5][5]) )
667 h['delPOverPz'].Fill(Ptruthz,delPOverPz)
668 if chi2>chi2CutOff: continue
669 h['delPOverP2'].Fill(Ptruth,delPOverP)
670 h['delPOverP2z'].Fill(Ptruth,delPOverPz)
671# try measure impact parameter
672 trackDir = fittedState.getDir()
673 trackPos = fittedState.getPos()
674 vx = ROOT.TVector3()
675 mcPart.GetStartVertex(vx)
676 t = 0
677 for i in range(3): t += trackDir(i)*(vx(i)-trackPos(i))
678 dist = 0
679 for i in range(3): dist += (vx(i)-trackPos(i)-t*trackDir(i))**2
680 dist = ROOT.TMath.Sqrt(dist)
681 h['IP'].Fill(dist)
682# ---
683# loop over particles, 2-track combinations
684 for HNL in sTree.Particles:
685 t1,t2 = HNL.GetDaughter(0),HNL.GetDaughter(1)
686# kill tracks outside fiducial volume, if enabled
687 if not checkFiducialVolume(sTree,t1,dy) or not checkFiducialVolume(sTree,t2,dy) : continue
688 checkMeasurements = True
689# cut on nDOF
690 for tr in [t1,t2]:
691 fitStatus = sTree.FitTracks[tr].getFitStatus()
692 nmeas = fitStatus.getNdf()
693 if nmeas < measCut: checkMeasurements = False
694 if not checkMeasurements: continue
695# check mc matching
696 if not match2HNL(HNL): continue
697 HNLPos = ROOT.TLorentzVector()
698 HNL.ProductionVertex(HNLPos)
699 HNLMom = ROOT.TLorentzVector()
700 HNL.Momentum(HNLMom)
701 doca = HNL.GetDoca()
702# redo doca calculation
703 # xv,yv,zv,doca,HNLMom = RedoVertexing(t1,t2)
704 # if HNLMom == -1: continue
705 # check if decay inside decay volume
706 if not isInFiducial(HNLPos.X(),HNLPos.Y(),HNLPos.Z()): continue
707 h['Doca'].Fill(doca)
708 if doca > docaCut : continue
709 tr = ROOT.TVector3(0,0,ShipGeo.target.z0)
710
711# look for pi0
712 for pi0 in pi0Reco.findPi0(sTree,HNLPos):
713 rc = h['pi0Mass'].Fill(pi0.M())
714 if abs(pi0.M()-0.135)>0.02: continue
715# could also be used for eta, by changing cut
716 HNLwithPi0 = HNLMom + pi0
717 dist = ImpactParameter(tr,HNLPos,HNLwithPi0)
718 mass = HNLwithPi0.M()
719 h['IP0_pi0'].Fill(dist)
720 h['IP0/mass_pi0'].Fill(mass,dist)
721 h['HNL_pi0'].Fill(mass)
722
723 dist = ImpactParameter(tr,HNLPos,HNLMom)
724 mass = HNLMom.M()
725 h['IP0'].Fill(dist)
726 h['IP0/mass'].Fill(mass,dist)
727 h['HNL'].Fill(mass)
728 h['HNLw'].Fill(mass,wg)
729#
730 vetoDets['SBT'] = veto.SBT_decision()
731 vetoDets['SVT'] = veto.SVT_decision()
732 vetoDets['RPC'] = veto.RPC_decision()
733 vetoDets['TRA'] = veto.Track_decision()
734 h['nrtracks'].Fill(vetoDets['TRA'][2])
735 h['nrSVT'].Fill(vetoDets['SVT'][2])
736 h['nrSBT'].Fill(vetoDets['SBT'][2])
737 h['nrRPC'].Fill(vetoDets['RPC'][2])
738# HNL true
739 mctrack = sTree.MCTrack[sTree.fitTrack2MC[t1]]
740 h['Vzresol'].Fill( (mctrack.GetStartZ()-HNLPos.Z())/u.cm )
741 h['Vxresol'].Fill( (mctrack.GetStartX()-HNLPos.X())/u.cm )
742 h['Vyresol'].Fill( (mctrack.GetStartY()-HNLPos.Y())/u.cm )
743 PosDir,newPosDir,CovMat,scalFac = {},{},{},{}
744# opening angle at vertex
745 newPos = ROOT.TVector3(HNLPos.X(),HNLPos.Y(),HNLPos.Z())
746 st1,st2 = sTree.FitTracks[t1].getFittedState(),sTree.FitTracks[t2].getFittedState()
747 PosDir[t1] = {'position':st1.getPos(),'direction':st1.getDir(),'momentum':st1.getMom()}
748 PosDir[t2] = {'position':st2.getPos(),'direction':st2.getDir(),'momentum':st2.getMom()}
749 CovMat[t1] = st1.get6DCov()
750 CovMat[t2] = st2.get6DCov()
751 rep1,rep2 = ROOT.genfit.RKTrackRep(st1.getPDG()),ROOT.genfit.RKTrackRep(st2.getPDG())
752 state1,state2 = ROOT.genfit.StateOnPlane(rep1),ROOT.genfit.StateOnPlane(rep2)
753 rep1.setPosMom(state1,st1.getPos(),st1.getMom())
754 rep2.setPosMom(state2,st2.getPos(),st2.getMom())
755 try:
756 rep1.extrapolateToPoint(state1, newPos, False)
757 rep2.extrapolateToPoint(state2, newPos, False)
758 mom1,mom2 = rep1.getMom(state1),rep2.getMom(state2)
759 except:
760 mom1,mom2 = st1.getMom(),st2.getMom()
761 newPosDir[t1] = {'position':rep1.getPos(state1),'direction':rep1.getDir(state1),'momentum':mom1}
762 newPosDir[t2] = {'position':rep2.getPos(state2),'direction':rep2.getDir(state2),'momentum':mom2}
763 oa = mom1.Dot(mom2)/(mom1.Mag()*mom2.Mag())
764 h['oa'].Fill(oa)
765#
766 covX = HNL.GetCovV()
767 dist = HNL.GetDoca()
768 h['Vzpull'].Fill( (mctrack.GetStartZ()-HNLPos.Z())/ROOT.TMath.Sqrt(covX[2][2]) )
769 h['Vxpull'].Fill( (mctrack.GetStartX()-HNLPos.X())/ROOT.TMath.Sqrt(covX[0][0]) )
770 h['Vypull'].Fill( (mctrack.GetStartY()-HNLPos.Y())/ROOT.TMath.Sqrt(covX[1][1]) )
771
772# check extrapolation to TimeDet if exists
773 if hasattr(ShipGeo,"TimeDet"):
774 for fT in sTree.FitTracks:
775 rc,pos,mom = TrackExtrapolateTool.extrapolateToPlane(fT,ShipGeo.TimeDet.z)
776 if rc:
777 for aPoint in sTree.TimeDetPoint:
778 h['extrapTimeDetX'].Fill(pos.X()-aPoint.GetX())
779 h['extrapTimeDetY'].Fill(pos.Y()-aPoint.GetY())
780#
782 HNLorigin={}
783 ut.bookHist(h,'HNLmomNoW','momentum unweighted',100,0.,300.)
784 ut.bookHist(h,'HNLmom','momentum',100,0.,300.)
785 ut.bookHist(h,'HNLPtNoW','Pt unweighted',100,0.,10.)
786 ut.bookHist(h,'HNLPt','Pt',100,0.,10.)
787 ut.bookHist(h,'HNLmom_recTracks','momentum',100,0.,300.)
788 ut.bookHist(h,'HNLmomNoW_recTracks','momentum unweighted',100,0.,300.)
789 for n in range(sTree.GetEntries()):
790 rc = sTree.GetEntry(n)
791 for hnlkey in [1,2]:
792 if abs(sTree.MCTrack[hnlkey].GetPdgCode()) == 9900015:
793 theHNL = sTree.MCTrack[hnlkey]
794 wg = theHNL.GetWeight()
795 if not wg>0.: wg=1.
796 idMother = abs(sTree.MCTrack[hnlkey-1].GetPdgCode())
797 if idMother not in HNLorigin: HNLorigin[idMother]=0
798 HNLorigin[idMother]+=wg
799 P = theHNL.GetP()
800 Pt = theHNL.GetPt()
801 h['HNLmom'].Fill(P,wg)
802 h['HNLmomNoW'].Fill(P)
803 h['HNLPt'].Fill(Pt,wg)
804 h['HNLPtNoW'].Fill(Pt)
805 for HNL in sTree.Particles:
806 t1,t2 = HNL.GetDaughter(0),HNL.GetDaughter(1)
807 for tr in [t1,t2]:
808 xx = sTree.FitTracks[tr].getFittedState()
809 Prec = xx.getMom().Mag()
810 h['HNLmom_recTracks'].Fill(Prec,wg)
811 h['HNLmomNoW_recTracks'].Fill(Prec)
812 theSum = 0
813 for x in HNLorigin: theSum+=HNLorigin[x]
814 for x in HNLorigin: print("%4i : %5.4F relative fraction: %5.4F "%(x,HNLorigin[x],HNLorigin[x]/theSum))
815#
816# initialize ecalStructure
817caloTasks = []
818calReco = False
819sTree.GetEvent(0)
820if ecal:
821 ecalGeo = ecalGeoFile+'z'+str(ShipGeo.ecal.z)+".geo"
822 if not ecalGeo in os.listdir(os.environ["FAIRSHIP"]+"/geometry"): shipDet_conf.makeEcalGeoFile(ShipGeo.ecal.z,ShipGeo.ecal.File)
823 ecalFiller = ROOT.ecalStructureFiller("ecalFiller", 0,ecalGeo)
824 ecalFiller.SetUseMCPoints(ROOT.kTRUE)
825 ecalFiller.StoreTrackInformation()
826 ecalStructure = ecalFiller.InitPython(sTree.EcalPointLite)
827 caloTasks.append(ecalFiller)
828
829 if hasattr(sTree,"EcalReconstructed"):
830 calReco = False
831 ecalReconstructed = sTree.EcalReconstructed
832 else:
833 calReco = True
834 print("setup calo reconstruction of ecalReconstructed objects")
835# Calorimeter reconstruction
836 #GeV -> ADC conversion
837 ecalDigi=ROOT.ecalDigi("ecalDigi",0)
838 ecalPrepare=ROOT.ecalPrepare("ecalPrepare",0)
839 ecalStructure = ecalFiller.InitPython(sTree.EcalPointLite)
840 ecalDigi.InitPython(ecalStructure)
841 caloTasks.append(ecalDigi)
842 ecalPrepare.InitPython(ecalStructure)
843 caloTasks.append(ecalPrepare)
844 # Cluster calibration
845 ecalClusterCalib=ROOT.ecalClusterCalibration("ecalClusterCalibration", 0)
846 #4x4 cm cells
847 ecalCl3PhS=ROOT.TFormula("ecalCl3PhS", "[0]+x*([1]+x*([2]+x*[3]))")
848 ecalCl3PhS.SetParameters(6.77797e-04, 5.75385e+00, 3.42690e-03, -1.16383e-04)
849 ecalClusterCalib.SetStraightCalibration(3, ecalCl3PhS)
850 ecalCl3Ph=ROOT.TFormula("ecalCl3Ph", "[0]+x*([1]+x*([2]+x*[3]))+[4]*x*y+[5]*x*y*y")
851 ecalCl3Ph.SetParameters(0.000750975, 5.7552, 0.00282783, -8.0025e-05, -0.000823651, 0.000111561)
852 ecalClusterCalib.SetCalibration(3, ecalCl3Ph)
853#6x6 cm cells
854 ecalCl2PhS=ROOT.TFormula("ecalCl2PhS", "[0]+x*([1]+x*([2]+x*[3]))")
855 ecalCl2PhS.SetParameters(8.14724e-04, 5.67428e+00, 3.39030e-03, -1.28388e-04)
856 ecalClusterCalib.SetStraightCalibration(2, ecalCl2PhS)
857 ecalCl2Ph=ROOT.TFormula("ecalCl2Ph", "[0]+x*([1]+x*([2]+x*[3]))+[4]*x*y+[5]*x*y*y")
858 ecalCl2Ph.SetParameters(0.000948095, 5.67471, 0.00339177, -0.000122629, -0.000169109, 8.33448e-06)
859 ecalClusterCalib.SetCalibration(2, ecalCl2Ph)
860 caloTasks.append(ecalClusterCalib)
861 ecalReco=ROOT.ecalReco('ecalReco',0)
862 caloTasks.append(ecalReco)
863# Match reco to MC
864 ecalMatch=ROOT.ecalMatch('ecalMatch',0)
865 caloTasks.append(ecalMatch)
866 ecalCalib = ecalClusterCalib.InitPython()
867 ecalReconstructed = ecalReco.InitPython(sTree.EcalClusters, ecalStructure, ecalCalib)
868 ecalMatch.InitPython(ecalStructure, ecalReconstructed, sTree.MCTrack)
869
870options.nEvents = min(sTree.GetEntries(),options.nEvents)
871
872import pi0Reco
873ut.bookHist(h,'pi0Mass','gamma gamma inv mass',100,0.,0.5)
874
875for n in range(options.nEvents):
876 myEventLoop(n)
877 sTree.FitTracks.Delete()
878makePlots()
879# output histograms
880hfile = options.inputFile.split(',')[0].replace('_rec','_ana')
881if hfile[0:4] == "/eos" or not options.inputFile.find(',')<0:
882# do not write to eos, write to local directory
883 tmp = hfile.split('/')
884 hfile = tmp[len(tmp)-1]
885ROOT.gROOT.cd()
886ut.writeHists(h,hfile)
887
888
void InitPython(ecalStructure *structure)
Definition ecalDigi.cxx:85
void InitPython(ecalStructure *str, TClonesArray *reconstructed, TClonesArray *mctracks)
void InitPython(ecalStructure *structure)
TClonesArray * InitPython(TClonesArray *clusters, ecalStructure *str, ecalClusterCalibration *calib)
Definition ecalReco.cxx:294
ecalCell * GetHitCell(const Int_t hitId) const
VertexError(t1, t2, PosDir, CovMat, scalFac)
Definition ShipAna.py:140
access2SmearedHits()
Definition ShipAna.py:281
RedoVertexing(t1, t2)
Definition ShipAna.py:312
isInFiducial(X, Y, Z)
Definition ShipAna.py:224
getPtruthFirst(sTree, mcPartKey)
Definition ShipAna.py:272
dist2InnerWall(X, Y, Z)
Definition ShipAna.py:201
ecalCluster2MC(aClus)
Definition ShipAna.py:395
makePlots()
Definition ShipAna.py:416
ImpactParameter(point, tPos, tMom)
Definition ShipAna.py:232
checkHNLorigin(sTree)
Definition ShipAna.py:242
myVertex(t1, t2, PosDir)
Definition ShipAna.py:291
match2HNL(p)
Definition ShipAna.py:381
HNLKinematics()
Definition ShipAna.py:781
myEventLoop(n)
Definition ShipAna.py:542
fitSingleGauss(x, ba=None, be=None)
Definition ShipAna.py:360
checkFiducialVolume(sTree, tkey, dy)
Definition ShipAna.py:263
addVMCFields(shipGeo, controlFile='', verbose=False, withVirtualMC=True)
findPi0(sTree, secVertex)
Definition pi0Reco.py:13
configure(run, ship_geo)
makeEcalGeoFile(z, efile)
configure(darkphoton=None)