SND@LHC Software
Loading...
Searching...
No Matches
shipPid.py
Go to the documentation of this file.
1from __future__ import print_function
2from __future__ import division
3# pid deffiner
4import ROOT, sys
5import shipunit as u
6import rootUtils as ut
7import math as m
8import TrackExtrapolateTool
9import ctypes
10import shipDet_conf
11
12class Task:
13 "initialize"
14
15 def __init__(self,main):
16 print("****************************************")
17 print("*** You are using PID version 18.1.0 ***")
18 print("****************************************")
19 self.sTree = main.sTree
20 self.fpidArray = ROOT.TClonesArray("pid")
21 if not self.sTree.GetBranch("pid"):
22 self.pID = self.sTree.Branch("Pid", self.fpidArray,32000,-1)
23 else:
24 self.pID = self.sTree.pid
25 self.reps,self.states,self.newPosDir = {},{},{}
26 self.PDG = ROOT.TDatabasePDG.Instance()
27 fGeo = ROOT.gGeoManager
28 top = fGeo.GetTopVolume()
29 dv = top.GetNode('DecayVolume_1')
30 ns = dv.GetNodes()
31 T1Lid = ns.FindObject("T1Lid_1").GetMatrix()
32 self.z_start = T1Lid.GetTranslation()[2]
33 self.zpositions = {}
34 self.parallelToZ = ROOT.TVector3(0., 0., 1.)
35 hadron = top.GetNode("Hcal_1")
36 hvol = hadron.GetVolume()
37 self.zpositions['hcal'] = hadron.GetMatrix().GetTranslation()[2]
38 ecal = top.GetNode("Ecal_1")
39 evol = ecal.GetVolume()
40 self.zpositions['ecal'] = ecal.GetMatrix().GetTranslation()[2]
41 x = sys.modules['__main__']
42 ShipGeo = x.ShipGeo
43 for i in range(4):
44 muonDet = top.GetNode('MuonDetector_'+str(i+1))
45 if muonDet: self.zpositions['muon'+str(i)] = muonDet.GetMatrix().GetTranslation()[2]
46 else: self.zpositions['muon'+str(i)] = ShipGeo['MuonStation'+str(i)].z
47 self.hcal = sys.modules['__main__']. modules['Hcal']
48 self.pad_size_x = 5 #cm
49 self.pad_size_y = 5 #cm
50 self.dimensions_x = 300 #cm half witdth
51 self.dimensions_y = 600 #cm half witdth
52 self.rx=250
53 self.ry=500
54 self.muly_acceptance = 50.0
55 self.ncells_x=m.floor((2*self.dimensions_x)/self.pad_size_x)
56 self.ncells_y=m.floor((2*self.dimensions_y)/self.pad_size_y)
58 self.Ecal_dx = 15 #cm
59 self.Ecal_dy = 15 #cm
60 self.Ecal_EP_threshold_min = 0.92 #acceptence region for E over P in Ecal > self.Ecal_EP_threshold_min
62 self.Hit_number_threshold=3 #number of pad-hits around the extrapolated tracks in MuonDet
63 self.hitlimit_x,self.hitlimit_y=5,5 #x-y area to check the number of pad-hits
64 self.cutNdf = 25
65
66 self.P_min00,self.P_max00,self.dx00_min,self.dx00_max,self.dy00_min,self.dy00_max=-99,-99,-99,-99,-99,-99
67 self.P_min01,self.P_max01,self.dx01_min,self.dx01_max,self.dy01_min,self.dy01_max=-99,-99,-99,-99,-99,-99
68 self.P_min02,self.P_max02,self.dx02_min,self.dx02_max,self.dy02_min,self.dy02_max=-99,-99,-99,-99,-99,-99
69 self.P_min03,self.P_max03,self.dx03_min,self.dx03_max,self.dy03_min,self.dy03_max=-99,-99,-99,-99,-99,-99
70
71 self.P_min10,self.P_max10,self.dx10_min,self.dx10_max,self.dy10_min,self.dy10_max= 0, 8, -5, 5, -5, 5
72 self.P_min11,self.P_max11,self.dx11_min,self.dx11_max,self.dy11_min,self.dy11_max=-99,-99,-99,-99,-99,-99
73 self.P_min12,self.P_max12,self.dx12_min,self.dx12_max,self.dy12_min,self.dy12_max=-99,-99,-99,-99,-99,-99
74 self.P_min13,self.P_max13,self.dx13_min,self.dx13_max,self.dy13_min,self.dy13_max=-99,-99,-99,-99,-99,-99
75
76 self.P_min20,self.P_max20,self.dx20_min,self.dx20_max,self.dy20_min,self.dy20_max= 8, 13, -5, 5, -5, 5
77 self.P_min21,self.P_max21,self.dx21_min,self.dx21_max,self.dy21_min,self.dy21_max= 13, 20, -3, 3, -3, 3
78 self.P_min22,self.P_max22,self.dx22_min,self.dx22_max,self.dy22_min,self.dy22_max=-99,-99,-99,-99,-99,-99
79
80 self.P_min30,self.P_max30,self.dx30_min,self.dx30_max,self.dy30_min,self.dy30_max= 20,999, -4, 4, -4, 4
81 self.P_min31,self.P_max31,self.dx31_min,self.dx31_max,self.dy31_min,self.dy31_max=-99,-99,-99,-99,-99,-99
82
83 def execute(self):
84
85 self.PID()
86 self.pID.Fill()
87
88 def HcalHits(self):
89
90 self.hcal1 = []
91 self.hcal2 = []
92 self.new_hcal2 = []
93 if not hasattr(self.sTree,'HcalPointLite'): return
94 for chit in self.sTree.HcalPointLite:
95 if not chit.GetEnergyLoss()>0: continue
96 detID = chit.GetDetectorID()
97 x = ctypes.c_float()
98 y = ctypes.c_float()
99 section = ctypes.c_int()
100 self.hcal.GetCellCoordInf(detID,x,y,section)
101 ELoss = chit.GetEnergyLoss()/u.MeV
102 if ELoss>0: self.hcal1.append([x.value,y.value,section.value,ELoss])
103
104 def muonDigitHit(self):
105
106 self.list1 = []
107 self.list2 = []
108 self.new_list2 = []
109# print 'numer of hites = ', self.sTree.muonPoint.GetEntries()
110 for ahit in self.sTree.muonPoint:
111 if not ahit.GetEnergyLoss()>0: continue
112 detID = ahit.GetDetectorID()
113 if m.fabs(ahit.GetZ()-self.zpositions['muon0'])<self.muly_acceptance:
114 mul=0
115
116 X_hit_pos0=ahit.GetX()+self.dimensions_x
117 Y_hit_pos0=ahit.GetY()+self.dimensions_y
118 pos_hit_x0=m.floor(X_hit_pos0/self.pad_size_x)+1
119 pos_hit_y0=m.floor(Y_hit_pos0/self.pad_size_y)+1
120 if (pos_hit_x0<0 or pos_hit_x0>self.ncells_x) or (pos_hit_y0<0 or pos_hit_y0>self.ncells_y): continue
121 E = ahit.GetEnergyLoss()/u.MeV
122# print "--*--->> ", E,pos_hit_x0,pos_hit_y0, mul
123 if not E<self.threshold_pad_energy: self.list1.append([pos_hit_x0,pos_hit_y0,E,mul])
124 if m.fabs(ahit.GetZ()-self.zpositions['muon1'])<self.muly_acceptance:
125 mul1=1
126
127 X_hit_pos1=ahit.GetX()+self.dimensions_x
128 Y_hit_pos1=ahit.GetY()+self.dimensions_y
129 pos_hit_x1=m.floor(X_hit_pos1/self.pad_size_x)+1
130 pos_hit_y1=m.floor(Y_hit_pos1/self.pad_size_y)+1
131 if (pos_hit_x1<0 or pos_hit_x1>self.ncells_x) or (pos_hit_y1<0 or pos_hit_y1>self.ncells_y): continue
132 E1 = ahit.GetEnergyLoss()/u.MeV
133# print "--**--->> ", E1,pos_hit_x1,pos_hit_y1, mul1
134 if not E1<self.threshold_pad_energy: self.list1.append([pos_hit_x1,pos_hit_y1,E1,mul1])
135 if m.fabs(ahit.GetZ()-self.zpositions['muon2'])<self.muly_acceptance:
136 mul2=2
137
138 X_hit_pos2=ahit.GetX()+self.dimensions_x
139 Y_hit_pos2=ahit.GetY()+self.dimensions_y
140 pos_hit_x2=m.floor(X_hit_pos2/self.pad_size_x)+1
141 pos_hit_y2=m.floor(Y_hit_pos2/self.pad_size_y)+1
142 if (pos_hit_x2<0 or pos_hit_x2>self.ncells_x) or (pos_hit_y2<0 or pos_hit_y2>self.ncells_y): continue
143 E2 = ahit.GetEnergyLoss()/u.MeV
144# print "--***--->> ", E2,pos_hit_x2,pos_hit_y2, mul2
145 if not E2<self.threshold_pad_energy: self.list1.append([pos_hit_x2,pos_hit_y2,E2,mul2])
146 if m.fabs(ahit.GetZ()-self.zpositions['muon3'])<self.muly_acceptance:
147 mul3=3
148
149 X_hit_pos3=ahit.GetX()+self.dimensions_x
150 Y_hit_pos3=ahit.GetY()+self.dimensions_y
151 pos_hit_x3=m.floor(X_hit_pos3/self.pad_size_x)+1
152 pos_hit_y3=m.floor(Y_hit_pos3/self.pad_size_y)+1
153 if (pos_hit_x3<0 or pos_hit_x3>self.ncells_x) or (pos_hit_y3<0 or pos_hit_y3>self.ncells_y): continue
154 E3 = ahit.GetEnergyLoss()/u.MeV
155# print "--****--->> ", E3,pos_hit_x3,pos_hit_y3, mul3
156 if not E3<self.threshold_pad_energy: self.list1.append([pos_hit_x3,pos_hit_y3,E3,mul3])
157 for i in range(len(self.list1)):
158 E, E1, E2, E3, EE, E_tot=0,0,0,0,0,0
159 x,y, E, mull = self.list1[i][0], self.list1[i][1], self.list1[i][2], self.list1[i][3]
160 for j in range(len(self.list1)):
161 xx, yy, EE, mulll = self.list1[j][0], self.list1[j][1], self.list1[j][2], self.list1[j][3]
162 if x == xx and y == yy and mull == mulll: E_tot+=EE
163 j+=1
164 #print 'E_tot', E_tot
165 if not mull==0: self.list2.append([x,y,E_tot,mull])
166 i+=1
167 for elem in self.list2:
168 if elem not in self.new_list2: self.new_list2.append(elem)
169 self.list2 = self.new_list2
170 #if not self.list2==[]: print 'hits in each pad = ', self.list2
171
172 def PID(self):
173
174 self.muonDigitHit()
175 self.HcalHits()
176 self.fpidArray.Delete()
177 ppid = self.fpidArray
178
179 i=-1
180 for fT in self.sTree.FitTracks:
181 self.El,self.Hl,self.OverHit=False,False,False
182 self.pid00,self.pid01,self.pid02,self.pid03,self.pid10,self.pid11,self.pid12,self.pid13=False,False,False,False,False,False,False,False
183 self.pid20,self.pid21,self.pid22,self.pid30,self.pid31=False,False,False,False,False
184 self.pid_mu=False
185 self.vol_mu1,self.vol_ecal,self.vol_hcal=False,False,False
186 self.pos_pad_x0,self.pos_pad_y0,self.pos_pad_x1,self.pos_pad_y1,self.pos_pad_x2,self.pos_pad_y2,self.pos_pad_x3,self.pos_pad_y3=0,0,0,0,0,0,0,0
188 self.P=0.
189 i+=1
190 fst = fT.getFitStatus()
191 if not fst.isFitConverged() or fst.getNdf() < self.cutNdf:
192 pidObject=ROOT.pid()
193 pidObject.SetTrackID(i)
194 pidObject.SetTrackPID(-3)
195 nPID=ppid.GetEntries()
196 ppid[nPID]=pidObject
197 continue
198 fittedState = fT.getFittedState()
199 self.P = fittedState.getMomMag()
200 self.extrapStates = {}
201 for self.det in self.zpositions:
203# print rc
204 if rc>0:
205 self.extrapStates[self.det] = [pos.X(),pos.Y(),self.zpositions[self.det]]
206 self.hcal_ID()
207 self.muon_ID()
208 self.elec_ID()
209 pidObject=ROOT.pid()
210 pidObject.SetTrackID(i)
211 if not rc> 0:
212 pidObject.SetTrackPID(-1)
213 nPID=ppid.GetEntries()
214 ppid[nPID]=pidObject
215 continue
216 self.run_hcal_ID()
217 self.run_elec_ID()
218 self.run_muon_ID()
219 if self.El==True and self.vol_ecal==False:
220 pidObject.SetTrackPID(1)
221# print '==== Is Electron'
222 if (self.pid10==True or self.pid20==True or self.pid21==True or self.pid30==True or self.pid_mu==True) and self.El==False and self.vol_mu1==False:
223 pidObject.SetTrackPID(3)
224 self.Hl=False
225 # print '**** Is Muon'
226 if self.pid10==False and self.pid20==False and self.pid21==False and self.pid30==False and self.pid_mu==False and self.El==False and self.Hl==True and self.vol_hcal==False:
227 pidObject.SetTrackPID(2)
228 # print '$$$$ Is Hadron'
229 if self.vol_ecal==True or self.vol_mu1==True:
230 pidObject.SetTrackPID(-2)
231# print '==== It is out of the acceptance'
232 nPID=ppid.GetEntries()
233 ppid[nPID]=pidObject
234 # print "---------------- "
235
236 def muon_ID(self):
237 if self.det == 'muon0':
238 extrap_X_mu0 = self.extrapStates[self.det][0]
239 extrap_Y_mu0 = self.extrapStates[self.det][1]
240 extrap_Z_mu0 = self.extrapStates[self.det][2]
241 X_pos0=extrap_X_mu0+self.dimensions_x
242 Y_pos0=extrap_Y_mu0+self.dimensions_y
243 self.pos_pad_x0=m.floor(X_pos0/self.pad_size_x)+1
244 self.pos_pad_y0=m.floor(Y_pos0/self.pad_size_y)+1
245 if self.det == 'muon1':
246 self.extrap_X_mu1 = self.extrapStates[self.det][0]
247 self.extrap_Y_mu1 = self.extrapStates[self.det][1]
248 extrap_Z_mu1 = self.extrapStates[self.det][2]
249 X_pos1=self.extrap_X_mu1+self.dimensions_x
250 Y_pos1=self.extrap_Y_mu1+self.dimensions_y
251 self.pos_pad_x1=m.floor(X_pos1/self.pad_size_x)+1
252 self.pos_pad_y1=m.floor(Y_pos1/self.pad_size_y)+1
253 if self.det == 'muon2':
254 extrap_X_mu2 = self.extrapStates[self.det][0]
255 extrap_Y_mu2 = self.extrapStates[self.det][1]
256 extrap_Z_mu2 = self.extrapStates[self.det][2]
257 X_pos2=extrap_X_mu2+self.dimensions_x
258 Y_pos2=extrap_Y_mu2+self.dimensions_y
259 self.pos_pad_x2=m.floor(X_pos2/self.pad_size_x)+1
260 self.pos_pad_y2=m.floor(Y_pos2/self.pad_size_y)+1
261 if self.det == 'muon3':
262 extrap_X_mu3 = self.extrapStates[self.det][0]
263 extrap_Y_mu3 = self.extrapStates[self.det][1]
264 extrap_Z_mu3 = self.extrapStates[self.det][2]
265 X_pos3=extrap_X_mu3+self.dimensions_x
266 Y_pos3=extrap_Y_mu3+self.dimensions_y
267 self.pos_pad_x3=m.floor(X_pos3/self.pad_size_x)+1
268 self.pos_pad_y3=m.floor(Y_pos3/self.pad_size_y)+1
269
270 def run_muon_ID(self):
271 for i in range(len(self.list2)):
272 X,Y, e, Mull = self.list2[i][0], self.list2[i][1], self.list2[i][2], self.list2[i][3]
273 if Mull==0:
274 delta_x0 = X-self.pos_pad_x0
275 delta_y0 = Y-self.pos_pad_y0
276 if (self.P>self.P_min00 and self.P<self.P_max00) and (delta_x0>self.dx00_min and delta_x0<self.dx00_max) and (delta_y0>self.dy00_min and delta_y0<self.dy00_max):
277 self.pid00=True
278 if (self.P>self.P_min01 and self.P<self.P_max01) and (delta_x0>self.dx01_min and delta_x0<self.dx01_max) and (delta_y0>self.dy01_min and delta_y0<self.dy01_max):
279 self.pid01=True
280 if (self.P>self.P_min02 and self.P<self.P_max02) and (delta_x0>self.dx02_min and delta_x0<self.dx02_max) and (delta_y0>self.dy02_min and delta_y0<self.dy02_max):
281 self.pid02=True
282 if (self.P>self.P_min03 and self.P<self.P_max03) and (delta_x0>self.dx03_min and delta_x0<self.dx03_max) and (delta_y0>self.dy03_min and delta_y0<self.dy03_max):
283 self.pid03=True
284
285 # if (self.P>self.P_min00 and self.P<self.P_max00) and m.fabs(delta_x0)<self.hitlimit_x and m.fabs(delta_y0)<self.hitlimit_y: nhit0+=1
286# if nhit0>=self.Hit_number_threshold: overhit=True
287 if Mull==1:
288 delta_x1 = X-self.pos_pad_x1
289 delta_y1 = Y-self.pos_pad_y1
290 if (self.P>self.P_min10 and self.P<self.P_max10) and (delta_x1>self.dx10_min and delta_x1<self.dx10_max) and (delta_y1>self.dy10_min and delta_y1<self.dy10_max):
291 self.pid10=True
292 if (self.P>self.P_min11 and self.P<self.P_max11) and (delta_x1>self.dx11_min and delta_x1<self.dx11_max) and (delta_y1>self.dy11_min and delta_y1<self.dy11_max):
293 self.pid11=True
294 if (self.P>self.P_min12 and self.P<self.P_max12) and (delta_x1>self.dx12_min and delta_x1<self.dx12_max) and (delta_y1>self.dy12_min and delta_y1<self.dy12_max):
295 self.pid12=True
296 if (self.P>self.P_min13 and self.P<self.P_max13) and (delta_x1>self.dx13_min and delta_x1<self.dx13_max) and (delta_y1>self.dy13_min and delta_y1<self.dy13_max):
297 self.pid13=True
298 if Mull==2:
299 delta_x2 = X-self.pos_pad_x2
300 delta_y2 = Y-self.pos_pad_y2
301 if (self.P>self.P_min20 and self.P<self.P_max20) and (delta_x2>self.dx20_min and delta_x2<self.dx20_max) and (delta_y2>self.dy20_min and delta_y2<self.dy20_max):
302 self.pid20=True
303 if (self.P>self.P_min21 and self.P<self.P_max21) and (delta_x2>self.dx21_min and delta_x2<self.dx21_max) and (delta_y2>self.dy21_min and delta_y2<self.dy21_max):
304 self.pid21=True
305 if (self.P>self.P_min22 and self.P<self.P_max22) and (delta_x2>self.dx22_min and delta_x2<self.dx22_max) and (delta_y2>self.dy22_min and delta_y2<self.dy22_max):
306 self.pid22=True
307 if Mull==3:
308 delta_x3 = X-self.pos_pad_x3
309 delta_y3 = Y-self.pos_pad_y3
310 if (self.P>self.P_min30 and self.P<self.P_max30) and (delta_x3>self.dx30_min and delta_x3<self.dx30_max) and (delta_y3>self.dy30_min and delta_y3<self.dy30_max):
311 self.pid30=True
312 if (self.P>self.P_min31 and self.P<self.P_max31) and (delta_x3>self.dx31_min and delta_x3<self.dx31_max) and (delta_y3>self.dy31_min and delta_y3<self.dy31_max):
313 self.pid31=True
314
315 if not self.P>5 and (self.pid10==False and self.pid20==False and self.pid21==False and self.pid30==False):
316 chmu1=m.fabs((22.67-self.E_tot_h1)/22.67)
317 chmu2=m.fabs((55.75-self.E_tot_h2)/55.75)
318 if (chmu1<0.5 and chmu2<0.5):
319 self.pid_mu=True
320 check_vol_mu1=(m.pow(self.extrap_X_mu1,2)/m.pow(self.rx,2))+(m.pow(self.extrap_Y_mu1,2)/m.pow(self.ry,2))
321 if check_vol_mu1>1:
322 self.vol_mu1=True
323
324 def elec_ID(self):
325 if self.det == 'ecal':
326 self.extrap_X_ecal = self.extrapStates[self.det][0]
327 self.extrap_Y_ecal = self.extrapStates[self.det][1]
328 extrap_Z_ecal = self.extrapStates[self.det][2]
329
330 def run_elec_ID(self):
331 for aClus in self.sTree.EcalReconstructed:
332 x1_Clus, y1_Clus, Ene1_Clus = aClus.X(), aClus.Y(), aClus.RecoE()
333 Ecal_delta_x=x1_Clus - self.extrap_X_ecal
334 Ecal_delta_y=y1_Clus - self.extrap_Y_ecal
335 EP=Ene1_Clus/self.P
336 if (EP>self.Ecal_EP_threshold_min and EP<self.Ecal_EP_threshold_max) and m.fabs(Ecal_delta_x)<self.Ecal_dx and m.fabs(Ecal_delta_y)<self.Ecal_dy:
337 self.El=True
338 if self.pid10==False and self.pid20==False and self.pid21==False and self.pid30==False and self.El==False and self.pid_mu==False: self.Hl=True
339 check_vol_ecal=(m.pow(self.extrap_X_ecal,2)/m.pow(self.rx,2))+(m.pow(self.extrap_Y_ecal,2)/m.pow(self.ry,2))
340 if check_vol_ecal>1:
341 self.vol_ecal=True
342
343 def hcal_ID(self):
344 if self.det == 'hcal':
345 self.extrap_X_hcal = self.extrapStates[self.det][0]
346 self.extrap_Y_hcal = self.extrapStates[self.det][1]
347 extrap_Z_hcal = self.extrapStates[self.det][2]
348
349 def run_hcal_ID(self):
350 N1,N2,M,E_est,E_totale=0,0,0,0.,0.
351 self.E_tot_h1,self.E_tot_h2,self.E_tot=0.,0.,0.
352 for i in range(len(self.hcal1)):
353 x,y,s,E= self.hcal1[i][0], self.hcal1[i][1], self.hcal1[i][2], self.hcal1[i][3]
354 delta_x = x-self.extrap_X_hcal
355 delta_y = y-self.extrap_Y_hcal
356 if (m.pow(delta_x,2)+m.pow(delta_y,2))<2500 and s==0:
357 self.E_tot_h1+=E
358 if (m.pow(delta_x,2)+m.pow(delta_y,2))<2500 and s==1:
359 self.E_tot_h2+=E
360 E_totale+=E
361 self.E_tot = self.E_tot_h1+self.E_tot_h2
362 check_vol_hcal=(m.pow(self.extrap_X_hcal,2)/m.pow(self.rx,2))+(m.pow(self.extrap_Y_hcal,2)/m.pow(self.ry,2))
363 if check_vol_hcal>1:
364 self.vol_hcal=True
hcal_ID(self)
Definition shipPid.py:343
Hit_number_threshold
Definition shipPid.py:62
__init__(self, main)
Definition shipPid.py:15
HcalHits(self)
make particles persistent ##
Definition shipPid.py:88
elec_ID(self)
Definition shipPid.py:324
PID(self)
Definition shipPid.py:172
threshold_pad_energy
Definition shipPid.py:57
muonDigitHit(self)
Definition shipPid.py:104
run_hcal_ID(self)
Definition shipPid.py:349
muon_ID(self)
Definition shipPid.py:236
hcal1
hcalPoint hits ##
Definition shipPid.py:90
Ecal_EP_threshold_min
Definition shipPid.py:60
run_elec_ID(self)
Definition shipPid.py:330
Ecal_EP_threshold_max
Definition shipPid.py:61
list1
merging muonPoint hits inside each pad ##
Definition shipPid.py:106
run_muon_ID(self)
Definition shipPid.py:270
execute(self)
Definition shipPid.py:83