CMS 3D CMS Logo

ntupleDataFormat.py
Go to the documentation of this file.
1 import math
2 import collections
3 
4 import ROOT
5 
8 
10  """Adaptor class representing a collection of objects.
11 
12  Concrete collection classes should inherit from this class.
13 
14  """
15  def __init__(self, tree, sizeBranch, objclass):
16  """Constructor.
17 
18  Arguments:
19  tree -- TTree object
20  sizeBranch -- Name of the branch to be used in size()
21  objclass -- Class to be used for the objects in __getitem__()
22  """
23  super(_Collection, self).__init__()
24  self._tree = tree
25  self._sizeBranch = sizeBranch
26  self._objclass = objclass
27 
28  def size(self):
29  """Number of objects in the collection."""
30  return int(getattr(self._tree, self._sizeBranch).size())
31 
32  def __len__(self):
33  """Number of objects in the collection."""
34  return self.size()
35 
36  def __getitem__(self, index):
37  """Get object 'index' in the collection."""
38  return self._objclass(self._tree, index)
39 
40  def __iter__(self):
41  """Returns generator for the objects."""
42  for index in xrange(self.size()):
43  yield self._objclass(self._tree, index)
44 
45 class _Object(object):
46  """Adaptor class representing a single object in a collection.
47 
48  The member variables of the object are obtained from the branches
49  with common prefix and a given index.
50 
51  Concrete object classes should inherit from this class.
52  """
53  def __init__(self, tree, index, prefix):
54  """Constructor.
55 
56  Arguments:
57  tree -- TTree object
58  index -- Index for this object
59  prefix -- Prefix of the branchs
60  """
61  super(_Object, self).__init__()
62  self._tree = tree
63  self._index = index
64  self._prefix = prefix
65 
66  def __getattr__(self, attr):
67  """Return object member variable.
68 
69  'attr' is translated as a branch in the TTree (<prefix>_<attr>).
70  """
71  self._checkIsValid()
72  val = getattr(self._tree, self._prefix+"_"+attr)[self._index]
73  return lambda: val
74 
75  def _checkIsValid(self):
76  """Raise an exception if the object index is not valid."""
77  if not self.isValid():
78  raise Exception("%s is not valid" % self.__class__.__name__)
79 
80  def isValid(self):
81  """Check if object index is valid."""
82  return self._index != -1
83 
84  def index(self):
85  """Return object index."""
86  return self._index
87 
89  """Adaptor class for objects containgin DetId (hits)."""
90  def __init__(self):
91  super(_DetIdStrAdaptor, self).__init__()
92 
93  def layerStr(self):
94  """Returns a string describing the layer of the hit."""
95  self._checkIsValid()
96  get = lambda name: getattr(self._tree, self._prefix+"_"+name)[self._index]
97  subdet = get("subdet")
98  side = ""
99  isPhase2OTBarrel = (subdet == SubDet.TOB and hasattr(self._tree, self._prefix+"_isLower"))
100  if subdet in [SubDet.FPix, SubDet.TID, SubDet.TEC] or isPhase2OTBarrel:
101  sideNum = get("side")
102  if sideNum == 1:
103  side = "-"
104  elif sideNum == 2:
105  side = "+"
106  elif isPhase2OTBarrel and sideNum == 3:
107  side = ""
108  else:
109  side = "?"
110  return "%s%d%s" % (SubDet.toString(subdet),
111  getattr(self._tree, self._prefix+"_layer")[self._index],
112  side)
113 
114  def detIdStr(self):
115  """Returns a string describing the DetId fields."""
116  self._checkIsValid
117  get = lambda name: getattr(self._tree, self._prefix+"_"+name)[self._index]
118  isPhase2 = hasattr(self._tree, self._prefix+"_isLower")
119  def stereo():
120  if isPhase2:
121  if get("isLower"):
122  return " isLower"
123  if get("isUpper"):
124  return " isUpper"
125  if get("isStack"):
126  return " isStack"
127  else:
128  if get("isStereo"):
129  return " isStereo"
130  if get("isRPhi"):
131  return " isRPhi"
132  if get("isGlued"):
133  return " isGlued"
134  return ""
135 
136  subdet = get("subdet")
137  if subdet == SubDet.BPix:
138  return "ladder {} module {}".format(get("ladder"), get("module"))
139  if subdet == SubDet.FPix:
140  return "blade {} panel {} module {}".format(get("blade"), get("panel"), get("module"))
141  if subdet == SubDet.TIB:
142  return "side {} order {} string {} module {}{}".format(get("side"), get("order"), get("string"), get("module"), stereo())
143  if subdet == SubDet.TID:
144  return "ring {} order {} module {}{}".format(get("ring"), get("order"), get("module"), stereo())
145  if subdet == SubDet.TOB:
146  if isPhase2:
147  return "rod {} module {}{}".format(get("rod"), get("module"), stereo())
148  else:
149  return "side {} rod {} module {}{}".format(get("side"), get("rod"), get("module"), stereo())
150  if subdet == SubDet.TEC:
151  return "order {} petal {} ring {} module {}{}".format(get("order"), get("petalNumber"), get("ring"), get("module"), stereo())
152  raise Exception("Unknown subdet %d" % subdet)
153 
155  """Adaptor class for pixel/strip hit objects."""
156  def __init__(self, tree, index, prefix):
157  """Constructor.
158 
159  Arguments:
160  tree -- TTree object
161  index -- Index for this object
162  prefix -- Prefix of the branchs
163  """
164  """Constructor
165  """
166  super(_HitObject, self).__init__(tree, index, prefix)
167 
168  def ntracks(self):
169  """Returns number of tracks containing this hit."""
170  self._checkIsValid()
171  return getattr(self._tree, self._prefix+"_trkIdx")[self._index].size()
172 
173  def tracks(self):
174  """Returns generator for tracks containing this hit.
175 
176  The generator returns Track objects
177  """
178  self._checkIsValid()
179  for itrack in getattr(self._tree, self._prefix+"_trkIdx")[self._index]:
180  yield Track(self._tree, itrack)
181 
182  def nseeds(self):
183  """Returns number of seeds containing this hit."""
184  self._checkIsValid()
185  return getattr(self._tree, self._prefix+"_seeIdx")[self._index].size()
186 
187  def seeds(self):
188  """Returns generator for tracks containing this hit.
189 
190  The generator returns Seed objects
191  """
192  self._checkIsValid()
193  for iseed in getattr(self._tree, self._prefix+"_seeIdx")[self._index]:
194  yield Seed(self._tree, iseed)
195 
196  def r(self):
197  return math.sqrt(self.x()**2 + self.y()**2)
198 
199  def r3D(self):
200  return math.sqrt(self.x()**2 + self.y()**2 + self.z()**2)
201 
203  """Adaptor class for objects containing hits (e.g. tracks)"""
204  def __init__(self):
205  super(_RecoHitAdaptor, self).__init__()
206 
207  def _hits(self):
208  """Internal method to generate pairs of hit index and type."""
209  for ihit, hitType in zip(self.hitIdx(), self.hitType()):
210  yield (ihit, hitType)
211 
212  def hits(self):
213  """Returns generator for hits.
214 
215  Generator returns PixelHit/StripHit/GluedHit/Phase2OT depending on the
216  hit type.
217 
218  """
219  for ihit, hitType in self._hits():
220  if hitType == 0:
221  yield PixelHit(self._tree, ihit)
222  elif hitType == 1:
223  yield StripHit(self._tree, ihit)
224  elif hitType == 2:
225  yield GluedHit(self._tree, ihit)
226  elif hitType == 3:
227  yield InvalidHit(self._tree, ihit)
228  elif hitType == 4:
229  yield Phase2OTHit(self._tree, ihit)
230  else:
231  raise Exception("Unknown hit type %d" % hitType)
232 
233  def pixelHits(self):
234  """Returns generator for pixel hits."""
235  self._checkIsValid()
236  for ihit, hitType in self._hits():
237  if hitType != 0:
238  continue
239  yield PixelHit(self._tree, ihit)
240 
241  def stripHits(self):
242  """Returns generator for strip hits."""
243  self._checkIsValid()
244  for ihit, hitType in self._hits():
245  if hitType != 1:
246  continue
247  yield StripHit(self._tree, ihit)
248 
249  def gluedHits(self):
250  """Returns generator for matched strip hits."""
251  self._checkIsValid()
252  for ihit, hitType in self._hits():
253  if hitType != 2:
254  continue
255  yield GluedHit(self._tree, ihit)
256 
257  def invalidHits(self):
258  """Returns generator for invalid hits."""
259  self._checkIsValid()
260  for ihit, hitType in self._hits():
261  if hitType != 3:
262  continue
263  yield InvalidHit(self._tree, ihit)
264 
265  def phase2OTHits(self):
266  """Returns generator for phase2 outer tracker hits."""
267  self._checkIsValid()
268  for ihit, hitType in self._hits():
269  if hitType != 4:
270  continue
271  yield Phase2OTHit(self._tree, ihit)
272 
274  """Adaptor class for objects containing or matched to SimHits (e.g. reco hits)."""
275  def __init__(self):
276  super(_SimHitMatchAdaptor, self).__init__()
277 
278  def _nMatchedSimHits(self):
279  """Internal method to get the number of matched SimHits."""
280  return getattr(self._tree, self._prefix+"_simHitIdx")[self._index].size()
281 
282  def nMatchedSimHits(self):
283  """Returns the number of matched SimHits."""
284  self._checkIsValid()
285  return self._nMatchedSimHits()
286 
288  """Returns a generator for matched SimHits.
289 
290  The generator returns SimHitMatchInfo objects.
291  """
292  self._checkIsValid()
293  for imatch in xrange(self._nMatchedSimHits()):
294  yield SimHitMatchInfo(self._tree, self._index, imatch, self._prefix)
295 
297  """Adaptor class for objects matched to TrackingParticles."""
298  def __init__(self):
299  super(_TrackingParticleMatchAdaptor, self).__init__()
300 
302  """Internal method to get the number of matched TrackingParticles."""
303  return getattr(self._tree, self._prefix+"_simTrkIdx")[self._index].size()
304 
306  """Returns the number of matched TrackingParticles."""
307  self._checkIsValid()
308  return self._nMatchedTrackingParticles()
309 
311  """Returns a generator for matched TrackingParticles.
312 
313  The generator returns TrackingParticleMatchInfo objects.
314 
315  """
316  self._checkIsValid()
317  for imatch in xrange(self._nMatchedTrackingParticles()):
318  yield TrackingParticleMatchInfo(self._tree, self._index, imatch, self._prefix)
319 
321  """Returns best-matching TrackingParticle, even for fake tracks, or None if there is no best-matching TrackingParticle.
322 
323  Best-matching is defined as the one with largest number of
324  hits matched to the hits of a track (>= 3). If there are many
325  fulfilling the same number of hits, the one inducing the
326  innermost hit of the track is chosen.
327  """
328  self._checkIsValid()
329  if self._nMatchedTrackingParticles() == 1:
330  return next(self.matchedTrackingParticleInfos()).trackingParticle()
331 
332  tps = collections.OrderedDict()
333  for hit in self.hits():
334  if not isinstance(hit, _SimHitMatchAdaptor):
335  continue
336  for shInfo in hit.matchedSimHitInfos():
337  tp = shInfo.simHit().trackingParticle()
338  if tp.index() in tps:
339  tps[tp.index()] += 1
340  else:
341  tps[tp.index()] = 1
342 
343  best = (None, 2)
344  for tpIndex, nhits in tps.iteritems():
345  if nhits > best[1]:
346  best = (tpIndex, nhits)
347  if best[0] is None:
348  return None
349  return TrackingParticles(self._tree)[best[0]]
350 
351 ##########
353  """Class abstracting the whole ntuple/TTree.
354 
355  Main benefit is to provide nice interface for
356  - iterating over events
357  - querying whether hit/seed information exists
358 
359  Note that to iteratate over the evets with zip(), you should use
360  itertools.izip() instead.
361  """
362  def __init__(self, fileName, tree="trackingNtuple/tree"):
363  """Constructor.
364 
365  Arguments:
366  fileName -- String for path to the ROOT file
367  tree -- Name of the TTree object inside the ROOT file (default: 'trackingNtuple/tree')
368  """
369  super(TrackingNtuple, self).__init__()
370  self._file = ROOT.TFile.Open(fileName)
371  self._tree = self._file.Get(tree)
372  self._entries = self._tree.GetEntriesFast()
373 
374  def file(self):
375  return self._file
376 
377  def tree(self):
378  return self._tree
379 
380  def nevents(self):
381  return self._entries
382 
383  def hasHits(self):
384  """Returns true if the ntuple has hit information."""
385  return hasattr(self._tree, "pix_isBarrel")
386 
387  def hasSeeds(self):
388  """Returns true if the ntuple has seed information."""
389  return hasattr(self._tree, "see_fitok")
390 
391  def __iter__(self):
392  """Returns generator for iterating over TTree entries (events)
393 
394  Generator returns Event objects.
395 
396  """
397  for jentry in xrange(self._entries):
398  # get the next tree in the chain and verify
399  ientry = self._tree.LoadTree( jentry )
400  if ientry < 0: break
401  # copy next entry into memory and verify
402  nb = self._tree.GetEntry( jentry )
403  if nb <= 0: continue
404 
405  yield Event(self._tree, jentry)
406 
407  def getEvent(self, index):
408  """Returns Event for a given index"""
409  ientry = self._tree.LoadTree(index)
410  if ientry < 0: return None
411  nb = self._tree.GetEntry(ientry) # ientry or jentry?
412  if nb <= 0: None
413 
414  return Event(self._tree, ientry) # ientry of jentry?
415 
416 ##########
417 class Event(object):
418  """Class abstracting a single event.
419 
420  Main benefit is to provide nice interface to get various objects
421  or collections of objects.
422  """
423  def __init__(self, tree, entry):
424  """Constructor.
425 
426  Arguments:
427  tree -- TTree object
428  entry -- Entry number in the tree
429  """
430  super(Event, self).__init__()
431  self._tree = tree
432  self._entry = entry
433 
434  def entry(self):
435  return self._entry
436 
437  def event(self):
438  """Returns event number."""
439  return self._tree.event
440 
441  def lumi(self):
442  """Returns lumisection number."""
443  return self._tree.lumi
444 
445  def run(self):
446  """Returns run number."""
447  return self._tree.run
448 
449  def eventId(self):
450  """Returns (run, lumi, event) tuple."""
451  return (self._tree.run, self._tree.lumi, self._tree.event)
452 
453  def eventIdStr(self):
454  """Returns 'run:lumi:event' string."""
455  return "%d:%d:%d" % self.eventId()
456 
457  def beamspot(self):
458  """Returns BeamSpot object."""
459  return BeamSpot(self._tree)
460 
461  def tracks(self):
462  """Returns Tracks object."""
463  return Tracks(self._tree)
464 
465  def pixelHits(self):
466  """Returns PixelHits object."""
467  return PixelHits(self._tree)
468 
469  def stripHits(self):
470  """Returns StripHits object."""
471  return StripHits(self._tree)
472 
473  def gluedHits(self):
474  """Returns GluedHits object."""
475  return GluedHits(self._tree)
476 
477  def phase2OTHits(self):
478  """Returns Phase2OTHits object."""
479  return Phase2OTHits(self._tree)
480 
481  def seeds(self):
482  """Returns Seeds object."""
483  return Seeds(self._tree)
484 
485  def trackingParticles(self):
486  """Returns TrackingParticles object."""
487  return TrackingParticles(self._tree)
488 
489  def vertices(self):
490  """Returns Vertices object."""
491  return Vertices(self._tree)
492 
493  def trackingVertices(self):
494  """Returns TrackingVertices object."""
495  return TrackingVertices(self._tree)
496 
497 ##########
499  """Class representing the beam spot."""
500  def __init__(self, tree):
501  """Constructor.
502 
503  Arguments:
504  tree -- TTree object
505  """
506  super(BeamSpot, self).__init__()
507  self._tree = tree
508  self._prefix = "bsp"
509 
510  def __getattr__(self, attr):
511  """Return object member variable.
512 
513  'attr' is translated as a branch in the TTree (bsp_<attr>).
514  """
515  val = getattr(self._tree, self._prefix+"_"+attr)
516  return lambda: val
517 
518 ##########
520  """Class representing a match to a SimHit.
521 
522  The point of this class is to provide, in addition to the matched
523  SimHit, also other information about the match (e.g. fraction of
524  charge from this SimHit).
525  """
526  def __init__(self, tree, index, shindex, prefix):
527  """Constructor.
528 
529  Arguments:
530  tree -- TTree object
531  index -- Index of the hit matched to SimHit
532  shindex -- Index of the SimHit match (second index in _simHitIdx branch)
533  prefix -- String for prefix of the object (track/seed/hit) matched to TrackingParticle
534  """
535  super(SimHitMatchInfo, self).__init__(tree, index, prefix)
536  self._shindex = shindex
537 
538  def __getattr__(self, attr):
539  """Custom __getattr__ because of the second index needed to access the branch."""
540  val = super(SimHitMatchInfo, self).__getattr__(attr)()[self._shindex]
541  return lambda: val
542 
543  def simHit(self):
544  """Returns matched SimHit."""
545  self._checkIsValid()
546  return SimHit(self._tree, getattr(self._tree, self._prefix+"_simHitIdx")[self._index][self._shindex])
547 
549 
550  """Class representing a match to a TrackingParticle.
551 
552  The point of this class is to provide, in addition to the matched
553  TrackingParticle, also other information about the match (e.g.
554  shared hit fraction for tracks/seeds).
555  """
556  def __init__(self, tree, index, tpindex, prefix):
557  """Constructor.
558 
559  Arguments:
560  tree -- TTree object
561  index -- Index of the object (track/seed) matched to TrackingParticle
562  tpindex -- Index of the TrackingParticle match (second index in _simTrkIdx branch)
563  prefix -- String for prefix of the object (track/seed) matched to TrackingParticle
564  """
565  super(TrackingParticleMatchInfo, self).__init__(tree, index, prefix)
566  self._tpindex = tpindex
567 
568  def __getattr__(self, attr):
569  """Custom __getattr__ because of the second index needed to access the branch."""
570  val = super(TrackingParticleMatchInfo, self).__getattr__(attr)()[self._tpindex]
571  return lambda: val
572 
573  def trackingParticle(self):
574  """Returns matched TrackingParticle."""
575  self._checkIsValid()
576  return TrackingParticle(self._tree, getattr(self._tree, self._prefix+"_simTrkIdx")[self._index][self._tpindex])
577 
579  """Class representing a match to a Track.
580 
581  The point of this class is to provide, in addition to the matched
582  Track, also other information about the match (e.g. shared hit fraction.
583  """
584  def __init__(self, tree, index, trkindex, prefix):
585  """Constructor.
586 
587  Arguments:
588  tree -- TTree object
589  index -- Index of the object (TrackingParticle) matched to track
590  trkindex -- Index of the track match (second index in _trkIdx branch)
591  prefix -- String for prefix of the object (TrackingParticle) matched to track
592  """
593  super(TrackMatchInfo, self).__init__(tree, index, prefix)
594  self._trkindex = trkindex
595 
596  def track(self):
597  """Returns matched Track."""
598  self._checkIsValid()
599  return Track(self._tree, getattr(self._tree, self._prefix+"_trkIdx")[self._index][self._trkindex])
600 
602  """Class representing a match to a Seed.
603 
604  The point of this class is to provide an interface compatible with
605  all other "MatchInfo" classes
606 
607  """
608  def __init__(self, tree, index, seedindex, prefix):
609  """Constructor.
610 
611  Arguments:
612  tree -- TTree object
613  index -- Index of the object (TrackingParticle) matched to seed
614  seedindex -- Index of the seed match (second index in _trkIdx branch)
615  prefix -- String for prefix of the object (TrackingParticle) matched to seed
616  """
617  super(SeedMatchInfo, self).__init__(tree, index, prefix)
618  self._seedindex = seedindex
619 
620  def seed(self):
621  """Returns matched Seed."""
622  self._checkIsValid()
623  return Seed(self._tree, getattr(self._tree, self._prefix+"_seedIdx")[self._index][self._seedindex])
624 
625 ##########
627  """Class presenting a track."""
628  def __init__(self, tree, index):
629  """Constructor.
630 
631  Arguments:
632  tree -- TTree object
633  index -- Index of the track
634  """
635  super(Track, self).__init__(tree, index, "trk")
636 
637  def seed(self):
638  """Returns Seed of the track."""
639  self._checkIsValid()
640  return Seed(self._tree, self._tree.trk_seedIdx[self._index])
641 
642  def vertex(self):
643  """Returns Vertex that used this track in its fit."""
644  self._checkIsValid()
645  return Vertex(self._tree, self._tree.trk_vtxIdx[self._index])
646 
647  def ptPull(self):
648  tp = self.bestMatchingTrackingParticle()
649  if tp is None:
650  return None
651  return (self.pt() - tp.pca_pt())/self.ptErr()
652 
653  def thetaPull(self):
654  tp = self.bestMatchingTrackingParticle()
655  if tp is None:
656  return None
657  return (getattr(self, "lambda")() - tp.pca_lambda())/self.lambdaErr() # as in MTV
658 
659  def phiPull(self):
660  tp = self.bestMatchingTrackingParticle()
661  if tp is None:
662  return None
663  return (self.phi() - tp.pca_phi())/self.phiErr()
664 
665  def dxyPull(self):
666  tp = self.bestMatchingTrackingParticle()
667  if tp is None:
668  return None
669  return (self.dxy() - tp.pca_dxy())/self.dxyErr()
670 
671  def dzPull(self):
672  tp = self.bestMatchingTrackingParticle()
673  if tp is None:
674  return None
675  return (self.dz() - tp.pca_dz())/self.dzErr()
676 
678  """Class presenting a collection of tracks."""
679  def __init__(self, tree):
680  """Constructor.
681 
682  Arguments:
683  tree -- TTree object
684  """
685  super(Tracks, self).__init__(tree, "trk_pt", Track)
686 
687 ##########
689  """Class representing a pixel hit."""
690  def __init__(self, tree, index):
691  """Constructor.
692 
693  Arguments:
694  tree -- TTree object
695  index -- Index of the hit
696  """
697  super(PixelHit, self).__init__(tree, index, "pix")
698 
699  def isValidHit(self):
700  return True
701 
703  """Class presenting a collection of pixel hits."""
704  def __init__(self, tree):
705  """Constructor.
706 
707  Arguments:
708  tree -- TTree object
709  """
710  super(PixelHits, self).__init__(tree, "pix_isBarrel", PixelHit)
711 
712 ##########
714  """Class representing a strip hit."""
715  def __init__(self, tree, index):
716  """Constructor.
717 
718  Arguments:
719  tree -- TTree object
720  index -- Index of the hit
721  """
722  super(StripHit, self).__init__(tree, index, "str")
723 
724  def isValidHit(self):
725  return True
726 
728  """Class presenting a collection of strip hits."""
729  def __init__(self, tree):
730  """Constructor.
731 
732  Arguments:
733  tree -- TTree object
734  """
735  super(StripHits, self).__init__(tree, "str_isBarrel", StripHit)
736 
737 ##########
739  """Class representing a matched strip hit."""
740  def __init__(self, tree, index):
741  """Constructor.
742 
743  Arguments:
744  tree -- TTree object
745  index -- Index of the hit
746  """
747  super(GluedHit, self).__init__(tree, index, "glu")
748 
749  def isValidHit(self):
750  return True
751 
752  def monoHit(self):
753  """Returns a StripHit for the mono hit."""
754  self._checkIsValid()
755  return StripHit(self._tree, self._tree.glu_monoIdx[self._index])
756 
757  def stereoHit(self):
758  """Returns a StripHit for the stereo hit."""
759  self._checkIsValid()
760  return StripHit(self._tree, self._tree.glu_stereoIdx[self._index])
761 
762  def nseeds(self):
763  """Returns the number of seeds containing this hit."""
764  self._checkIsValid()
765  return self._tree.glu_seeIdx[self._index].size()
766 
767  def seeds(self):
768  """Returns generator for seeds containing this hit.
769 
770  The generator returns Seed objects
771  """
772  self._checkIsValid()
773  for iseed in self._tree.glu_seeIdx[self._index]:
774  yield Seed(self._tree, iseed)
775 
777  """Class presenting a collection of matched strip hits."""
778  def __init__(self, tree):
779  """Constructor.
780 
781  Arguments:
782  tree -- TTree object
783  """
784  super(GluedHits, self).__init__(tree, "glu_isBarrel", GluedHit)
785 
786 ##########
788  # repeating TrackingRecHit::Type
789  Type = _Enum(
790  missing = 1,
791  inactive = 2,
792  bad = 3,
793  missing_inner = 4,
794  missing_outer = 5
795  )
796 
797  """Class representing an invalid hit."""
798  def __init__(self, tree, index):
799  """Constructor.
800 
801  Arguments:
802  tree -- TTree object
803  index -- Index of the hit
804  """
805  super(InvalidHit, self).__init__(tree, index, "inv")
806 
807  def isValidHit(self):
808  return False
809 
810  def layerStr(self):
811  """Returns a string describing the layer of the hit."""
812  invalid_type = self._tree.inv_type[self._index]
813  return super(InvalidHit, self).layerStr() + " (%s)"%InvalidHit.Type.toString(invalid_type)
814 
815 ##########
817  """Class representing a phase2 OT hit."""
818  def __init__(self, tree, index):
819  """Constructor.
820 
821  Arguments:
822  tree -- TTree object
823  index -- Index of the hit
824  """
825  super(Phase2OTHit, self).__init__(tree, index, "ph2")
826 
827  def isValidHit(self):
828  return True
829 
831  """Class presenting a collection of phase2 OT hits."""
832  def __init__(self, tree):
833  """Constructor.
834 
835  Arguments:
836  tree -- TTree object
837  """
838  super(Phase2OTHits, self).__init__(tree, "ph2_isBarrel", Phase2OTHit)
839 
840 ##########
841 def _seedOffsetForAlgo(tree, algo):
842  """Internal function for returning a pair of indices for the beginning of seeds of a given 'algo', and the one-beyond-last index of the seeds."""
843  for ioffset, offset in enumerate(tree.see_offset):
844  if tree.see_algo[offset] == algo:
845  next_offset = tree.see_offset[ioffset+1] if ioffset < tree.see_offset.size()-1 else tree.see_algo.size()
846  return (offset, next_offset)
847  return (-1, -1)
848 
850  """Class presenting a seed."""
851  def __init__(self, tree, index):
852  """Constructor.
853 
854  Arguments:
855  tree -- TTree object
856  index -- Index of the seed
857  """
858  super(Seed, self).__init__(tree, index, "see")
859 
860  def indexWithinAlgo(self):
861  """Returns the seed index within the seeds of the same algo.
862 
863  In case of errors, -1 is returned.
864  """
865  self._checkIsValid()
866  algo = self._tree.see_algo[self._index]
867  (offset, next_offset) = _seedOffsetForAlgo(self._tree, algo)
868  if offset == -1: # algo not found
869  return -1
870  return self._index - offset
871 
872  def track(self):
873  """Returns Track that was made from this seed."""
874  self._checkIsValid()
875  return Track(self._tree, self._tree.see_trkIdx[self._index])
876 
878  """Class presenting a collection of seeds."""
879  def __init__(self, tree):
880  """Constructor.
881 
882  Arguments:
883  tree -- TTree object
884  """
885  super(Seeds, self).__init__(tree, "see_pt", Seed)
886 
887  def nSeedsForAlgo(self, algo):
888  """Returns the number of seeds for a given 'algo'."""
889  (offset, next_offset) = _seedOffsetForAlgo(self._tree, algo)
890  return next_offset - offset
891 
892  def seedsForAlgo(self, algo):
893  """Returns generator iterating over the seeds of a given 'algo'.
894 
895  Generator returns Seed object.
896  """
897  (offset, next_offset) = _seedOffsetForAlgo(self._tree, algo)
898  for isee in xrange(offset, next_offset):
899  yield Seed(self._tree, isee)
900 
901  def seedForAlgo(self, algo, iseed):
902  """Returns Seed of index 'iseed' for 'algo'."""
903  (offset, next_offset) = _seedOffsetForAlgo(self._tree, algo)
904  if iseed >= (next_offset-offset):
905  raise Exception("Seed index %d is larger than the number of seeds %d for algo %d (%s)" % (iseed, next_offset-offset, algo, Algo.toString(algo)))
906  return Seed(self._tree, offset+iseed)
907 
908 ##########
910  """Class representing a SimHit which has not induced a RecHit."""
911  def __init__(self, tree, index):
912  """Constructor.
913 
914  Arguments:
915  tree -- TTree object
916  index -- Index of the SimHit
917  """
918  super(SimHit, self).__init__(tree, index, "simhit")
919 
920  def nRecHits(self):
921  self._checkIsValid()
922  return self._tree.simhit_hitIdx[self._index].size()
923 
924  def trackingParticle(self):
925  self._checkIsValid()
926  return TrackingParticle(self._tree, getattr(self._tree, self._prefix+"_simTrkIdx")[self._index])
927 
928 ##########
930  """Class representing a TrackingParticle."""
931  def __init__(self, tree, index):
932  """Constructor.
933 
934  Arguments:
935  tree -- TTree object
936  index -- Index of the TrackingParticle
937  """
938  super(TrackingParticle, self).__init__(tree, index, "sim")
939 
940  def _nMatchedTracks(self):
941  """Internal function to get the number of matched tracks."""
942  return self._tree.sim_trkIdx[self._index].size()
943 
944  def nMatchedTracks(self):
945  """Returns the number of matched tracks."""
946  self._checkIsValid()
947  return self._nMatchedTracks()
948 
949  def matchedTrackInfos(self):
950  """Returns a generator for matched tracks.
951 
952  The generator returns TrackMatchInfo objects.
953  """
954  self._checkIsValid()
955  for imatch in xrange(self._nMatchedTracks()):
956  yield TrackMatchInfo(self._tree, self._index, imatch, self._prefix)
957 
958  def bestMatchingTrack(self):
959  """Returns best-matching track, even for non-reconstructed TrackingParticles, or None, if there is no best-matching track.
960 
961  Best-matching is defined as the one with largest number of
962  hits matched to the hits of a TrackingParticle (>= 3). If
963  there are many fulfilling the same number of hits, the one
964  inducing the innermost hit of the TrackingParticle is chosen.
965  """
966  self._checkIsValid()
967  if self._nMatchedTracks() == 1:
968  return next(self.matchedTrackInfos()).track()
969 
970  tracks = collections.OrderedDict()
971  for hit in self.simHits():
972  for recHit in hit.hits():
973  for track in recHit.tracks():
974  if track.index() in tracks:
975  tracks[track.index()] += 1
976  else:
977  tracks[track.index()] = 1
978 
979  best = (None, 2)
980  for trackIndex, nhits in tracks.iteritems():
981  if nhits > best[1]:
982  best = (trackIndex, nhits)
983  if best[0] is None:
984  return None
985  return Tracks(self._tree)[best[0]]
986 
987  def _nMatchedSeeds(self):
988  """Internal function to get the number of matched seeds."""
989  return self._tree.sim_seedIdx[self._index].size()
990 
991  def nMatchedSeeds(self):
992  """Returns the number of matched seeds."""
993  self._checkIsValid()
994  return self._nMatchedSeeds()
995 
996  def matchedSeedInfos(self):
997  """Returns a generator for matched tracks.
998 
999  The generator returns SeedMatchInfo objects.
1000  """
1001  self._checkIsValid()
1002  for imatch in xrange(self._nMatchedSeeds()):
1003  yield SeedMatchInfo(self._tree, self._index, imatch, self._prefix)
1004 
1005  def nSimHits(self):
1006  self._checkIsValid()
1007  return self.simHitIdx().size()
1008 
1009  def simHits(self):
1010  """Returns generator for SimHits."""
1011  self._checkIsValid()
1012  for ihit in self.simHitIdx():
1013  yield SimHit(self._tree, ihit)
1014 
1015  def parentVertex(self):
1016  """Returns the parent TrackingVertex."""
1017  self._checkIsValid()
1018  return TrackingVertex(self._tree, self._tree.sim_parentVtxIdx[self._index])
1019 
1020  def decayVertices(self):
1021  """Returns a generator for decay vertices.
1022 
1023  The generator returns TrackingVertex objects.
1024  """
1025  self._checkIsValid()
1026  for ivtx in self._tree.sim_decayVtxIdx[self._index]:
1027  yield TrackingVertex(self._tree, ivtx)
1028 
1029  def isLooper(self):
1030  """Returns True if this TrackingParticle is a looper.
1031 
1032  Note that the check involves looping over the SimHits, so it is not too cheap."""
1033  self._checkIsValid()
1034  prevr = 0
1035  for ihit in self.simHitIdx():
1036  hit = SimHit(self._tree, ihit)
1037  r = hit.x()**2 + hit.y()**2
1038  if r < prevr:
1039  return True
1040  prevr = r
1041  return False
1042 
1043 
1045  """Class presenting a collection of TrackingParticles."""
1046  def __init__(self, tree):
1047  """Constructor.
1048 
1049  Arguments:
1050  tree -- TTree object
1051  """
1052  super(TrackingParticles, self).__init__(tree, "sim_pt", TrackingParticle)
1053 
1054 ##########
1056  """Class presenting a primary vertex."""
1057  def __init__(self, tree, index):
1058  """Constructor.
1059 
1060  Arguments:
1061  tree -- TTree object
1062  index -- Index of the vertex
1063  """
1064  super(Vertex, self).__init__(tree, index, "vtx")
1065 
1066  def nTracks(self):
1067  """Returns the number of tracks used in the vertex fit."""
1068  self._checkIsValid()
1069  return self._tree.vtx_trkIdx[self._index].size()
1070 
1071  def tracks(self):
1072  """Returns a generator for the tracks used in the vertex fit.
1073 
1074  The generator returns Track object.
1075  """
1076  self._checkIsValid()
1077  for itrk in self._tree.vtx_trkIdx[self._index]:
1078  yield Track(self._tree, itrk)
1079 
1081  """Class presenting a collection of vertices."""
1082  def __init__(self, tree):
1083  """Constructor.
1084 
1085  Arguments:
1086  tree -- TTree object
1087  """
1088  super(Vertices, self).__init__(tree, "vtx_valid", Vertex)
1089 
1090 ##########
1092  """Class representing a TrackingVertex."""
1093  def __init__(self, tree, index):
1094  """Constructor.
1095 
1096  Arguments:
1097  tree -- TTree object
1098  index -- Index of the TrackingVertex
1099  """
1100  super(TrackingVertex, self).__init__(tree, index, "simvtx")
1101 
1103  """Returns the number of source TrackingParticles."""
1104  self._checkIsValid()
1105  return self._tree.simvtx_sourceSimIdx[self._index].size()
1106 
1108  """Returns the number of daughter TrackingParticles."""
1109  self._checkIsValid()
1110  return self._tree.simvtx_daughterSimIdx[self._index].size()
1111 
1113  """Returns a generator for the source TrackingParticles."""
1114  self._checkIsValid()
1115  for isim in self._tree.simvtx_sourceSimIdx[self._index]:
1116  yield TrackingParticle(self._tree, isim)
1117 
1119  """Returns a generator for the daughter TrackingParticles."""
1120  self._checkIsValid()
1121  for isim in self._tree.simvtx_daughterSimIdx[self._index]:
1122  yield TrackingParticle(self._tree, isim)
1123 
1125  """Class presenting a collection of TrackingVertices."""
1126  def __init__(self, tree):
1127  """Constructor.
1128 
1129  Arguments:
1130  tree -- TTree object
1131  """
1132  super(TrackingVertex, self).__init__(tree, "simvtx_x")
size
Write out results.
def __init__(self, tree, index, trkindex, prefix)
def __init__(self, tree, index)
def __init__(self, tree, index)
def __init__(self, tree)
def __init__(self, fileName, tree="trackingNtuple/tree")
def seedsForAlgo(self, algo)
def __init__(self, tree, index)
def __init__(self, tree, index, shindex, prefix)
def __init__(self, tree, entry)
def __init__(self, tree, index)
def __init__(self, tree, index, seedindex, prefix)
def seedForAlgo(self, algo, iseed)
def __init__(self, tree, index, tpindex, prefix)
OutputIterator zip(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp)
def __init__(self, tree, index)
def __init__(self, tree, index)
def __init__(self, tree, index)
def nSeedsForAlgo(self, algo)
def __init__(self, tree, index, prefix)
def __getattr__(self, attr)
def __init__(self, tree, index, prefix)
def __init__(self, tree, sizeBranch, objclass)
def __init__(self, tree, index)
def __init__(self, tree, index)
def __init__(self, tree, index)
def _seedOffsetForAlgo(tree, algo)
T get(const Candidate &c)
Definition: component.h:55