Python
FitTrackInfo.py
Go to the documentation of this file.
1 import ROOT,os,sys,getopt
2 import rootUtils as ut
3 import shipunit as u
4 
5 class FitTrackInfo(object):
6 
7  def __init__(self, tree, debug=0):
8  self.tree = tree
9  self.debug = debug
10  self.count = 0
11  self.Momentum = {}
12  self.Direction = {}
13  self.Position = {}
14  self.__info = {}
15  self.Vertex = None
16  self.Doca = None
17  # 0 orig, 1 refit, -1 failed refit
18  self.vertexEFlag = 0
19 
20  def clean(self):
21  self.count = 0
22  self.Momentum.clear()
23  self.Direction.clear()
24  self.Position.clear()
25  self.__info.clear()
26  self.Vertex = None
27  self.Doca = None
28 
29  def Print(self):
30  print "FitTrackInfo:"
31  for tid in self.__info:
32  print "\t", tid, "{:10.4f}".format(self.__info[tid]['Ndf']), "{:10.4f}".format(self.__info[tid]['Chi2']),
33  print " pos:", " ".join("{:10.4f}".format(self.Position[tid](ii)) for ii in range(0,3)),
34  print " mom:", " ".join("{:10.4f}".format(self.Direction[tid](ii)*self.Momentum[tid]) for ii in range(0,3)),
35  print " P:", "{:10.4f}".format(self.Momentum[tid])
36 
37  ## \brief returns list of keys #__info .
38  # \return list of MCtrackIDs of fitted tracks.
39  def getTrIDs(self):
40  trID = []
41  for tid in self.__info:
42  trID.append(tid)
43  return trID
44 
45  def getNtracks(self) :
46  return len(self.__info)
47 
48  def getChi2Ndf(self, tid):
49  return self.__info[tid]['Chi2']/self.__info[tid]['Ndf']
50 
51  def getNdf(self, tid):
52  return self.__info[tid]['Ndf']
53 
54  def compareTracks(self, tid, Pos, Dir, Pval):
55  false2 = (Pos==None or Dir==None or Pval==None)
56  false1 = (not tid in self.__info)
57  if (false2 and false1): return True
58  if (false2 or false1): return False
59  return ( (self.Direction[tid]==Dir) and (self.Position[tid]==Pos) and (self.Momentum[tid]==Pval) )
60 
61 
62  def getPosDirPval(self, tid):
63  if not tid in self.__info: return None, None, None
64  return self.Position[tid], self.Direction[tid], self.Momentum[tid]
65 
66  def getVertex(self) :
67  return self.Vertex
68 
69  def getDoca(self):
70  return self.Doca
71 
72  def myVertex2(self, t1,t2):
73  deltaPos =(self.Position[t1]-self.Position[t2]) # A1-A2
74  dotDir = self.Direction[t1].Dot(self.Direction[t2]) # a1.a2
75  crossDir = self.Direction[t1].Cross(self.Direction[t2]) # a1xa2
76  uPerpend = crossDir*(1./crossDir.Mag()) # (a1xa2)/|a1xa2| from a1 to a2
77 
78  minDist = deltaPos.Dot(uPerpend) # (A1-A2).(a1xa2)/|a1xa2|
79 
80  # A1 + a1*t1 + (minDist * uPerpend) is (A1 + a1*t1) projected to the plane:
81  # 1) A2+a2*t2 belons to the plane,
82  # 2) A1+a1*t1 is parallel to the plane
83  # cross at t1,t2: A1+a1*t1+(minDist*uPerpend) = A2+a2*t2
84  t2X = self.Direction[t2].X()
85  if (t2X == 0) : t2X = 0.00000000001
86  a2a = self.Direction[t2].Y()/t2X
87  alpha = deltaPos - minDist*uPerpend
88  nomin = alpha.Y() - a2a*alpha.X()
89  denom = a2a*self.Direction[t1].X() - self.Direction[t1].Y()
90  s1 = nomin/denom
91  s2 = ( alpha.X() + self.Direction[t1].X()*s1 ) / t2X#self.Direction[t2].X()
92  vec1 = self.Position[t1]+s1*self.Direction[t1]
93  vec2 = self.Position[t2]+s2*self.Direction[t2]
94  ave = (vec1+vec2)*0.5
95  dif = vec1-vec2
96  debugNeed = False
97  if(abs(abs(minDist)-dif.Mag())>0.00000001):
98  print "myVertex2 - problem:"
99  debugNeed = True
100  if(self.debug>2 or debugNeed):
101  for tid in (t1,t2):
102  print str(tid)+": Pos : ", "".join(str(self.Position[tid](ii)) +" " for ii in range(0,3)),
103  print "\t\tMom : ", "".join(str(self.Direction[tid](ii))+" " for ii in range(0,3))
104  print "uPerpend: ","".join(str(uPerpend(ii))+" " for ii in range(0,3))
105  if(self.debug>0 or debugNeed):
106  print "fit vertex: -> 1st poing : ", vec1.X(), vec1.Y(), vec1.Z()
107  print "fit vertex: -> 2nd point : ", vec2.X(), vec2.Y(), vec2.Z()
108  print "fit vertex: -> average : ", ave.X(), ave.Y(), ave.Z()
109  print "distance", abs(minDist), dif.Mag()
110  return ave, abs(minDist)
111 
112 
113  def readEvent(self):
114  self.clean()
115  indx = -1
116  for atrack in self.tree.FitTracks:
117  # kill tracks outside fiducial volume
118  # if not checkFiducialVolume(sTree,key,dy): continue
119  fitStatus = atrack.getFitStatus()
120  if not fitStatus.isFitConverged() : continue
121 
122  indx+=1
123  mcTrID = self.tree.fitTrack2MC[indx]
124 
125  self.__info[mcTrID] = {}
126  self.__info[mcTrID]['Ndf'] = fitStatus.getNdf()
127  self.__info[mcTrID]['Chi2'] = fitStatus.getChi2()
128 
129  fittedState = atrack.getFittedState()
130  self.Momentum[mcTrID] = fittedState.getMomMag()
131  self.Direction[mcTrID] = fittedState.getDir()
132  self.Position[mcTrID] = fittedState.getPos()
133 
134  if(indx>0):
135  if(indx==1):
136  self.createVertex(self.__info.keys()[0], self.__info.keys()[1])
137  else:
138  pass
139  #print "More than 2 fitterd tracks"
140  return len(self.__info)
141 
142  def createVertex(self, tid1, tid2, flag=0):
143  if( (tid1 in self.__info) and (tid2 in self.__info) ):
144  self.Vertex, self.Doca = self.myVertex2(tid1, tid2)
145  self.vertexEFlag = flag
146 
147  def addNewTrack(self, mcTrID, position, direction, Pval, ndf, chi2, verb = True):
148  if (verb and mcTrID in self.Momentum):
149  print "FotTrackInfo WARNING - trID ", mcTrID, "already filled! Will rewrite all records for this trID!"
150 
151  self.__info[mcTrID]={}
152  self.__info[mcTrID]['Ndf'] = ndf
153  self.__info[mcTrID]['Chi2'] = chi2
154 
155  self.Momentum[mcTrID] = Pval
156  self.Direction[mcTrID] = direction
157  self.Position[mcTrID] = position
158 
def getTrIDs
returns list of keys __info .
Definition: FitTrackInfo.py:39