1 from builtins
import range
12 """Adaptor class representing a collection of objects.
14 Concrete collection classes should inherit from this class.
17 def __init__(self, tree, sizeBranch, objclass):
22 sizeBranch -- Name of the branch to be used in size()
23 objclass -- Class to be used for the objects in __getitem__()
31 """Number of objects in the collection."""
35 """Number of objects in the collection."""
39 """Get object 'index' in the collection."""
43 """Returns generator for the objects."""
48 """Adaptor class representing a single object in a collection.
50 The member variables of the object are obtained from the branches
51 with common prefix and a given index.
53 Concrete object classes should inherit from this class.
60 index -- Index for this object
61 prefix -- Prefix of the branchs
69 """Return object member variable.
71 'attr' is translated as a branch in the TTree (<prefix>_<attr>).
78 """Raise an exception if the object index is not valid."""
80 raise Exception(
"%s is not valid" % self.__class__.__name__)
83 """Check if object index is valid."""
87 """Return object index."""
91 """Adaptor class for objects containgin DetId (hits)."""
93 super(_DetIdStrAdaptor, self).
__init__()
96 """Returns a string describing the layer of the hit."""
98 get =
lambda name: getattr(self._tree, self._prefix+
"_"+name)[self._index]
99 subdet = get(
"subdet")
101 isPhase2OTBarrel = (subdet == SubDet.TOB
and hasattr(self._tree, self._prefix+
"_isLower"))
102 if subdet
in [SubDet.FPix, SubDet.TID, SubDet.TEC]
or isPhase2OTBarrel:
103 sideNum = get(
"side")
108 elif isPhase2OTBarrel
and sideNum == 3:
112 return "%s%d%s" % (SubDet.toString(subdet),
113 getattr(self._tree, self._prefix+
"_layer")[self._index],
117 """Returns a string describing the DetId fields."""
119 get =
lambda name: getattr(self._tree, self._prefix+
"_"+name)[self._index]
120 isPhase2 = hasattr(self._tree, self._prefix+
"_isLower")
138 subdet = get(
"subdet")
139 if subdet == SubDet.BPix:
140 return "ladder {} module {}".
format(get(
"ladder"), get(
"module"))
141 if subdet == SubDet.FPix:
142 return "blade {} panel {} module {}".
format(get(
"blade"), get(
"panel"), get(
"module"))
143 if subdet == SubDet.TIB:
144 return "side {} order {} string {} module {}{}".
format(get(
"side"), get(
"order"), get(
"string"), get(
"module"), stereo())
145 if subdet == SubDet.TID:
146 return "ring {} order {} module {}{}".
format(get(
"ring"), get(
"order"), get(
"module"), stereo())
147 if subdet == SubDet.TOB:
149 return "rod {} module {}{}".
format(get(
"rod"), get(
"module"), stereo())
151 return "side {} rod {} module {}{}".
format(get(
"side"), get(
"rod"), get(
"module"), stereo())
152 if subdet == SubDet.TEC:
153 return "order {} petal {} ring {} module {}{}".
format(get(
"order"), get(
"petalNumber"), get(
"ring"), get(
"module"), stereo())
154 raise Exception(
"Unknown subdet %d" % subdet)
157 """Adaptor class for pixel/strip hit objects."""
163 index -- Index for this object
164 prefix -- Prefix of the branchs
168 super(_HitObject, self).
__init__(tree, index, prefix)
171 """Returns number of tracks containing this hit."""
176 """Returns generator for tracks containing this hit.
178 The generator returns Track objects
185 """Returns number of seeds containing this hit."""
190 """Returns generator for tracks containing this hit.
192 The generator returns Seed objects
199 return math.sqrt(self.x()**2 + self.y()**2)
202 return math.sqrt(self.x()**2 + self.y()**2 + self.z()**2)
205 """Adaptor class for objects containing hits (e.g. tracks)"""
207 super(_RecoHitAdaptor, self).
__init__()
210 """Internal method to generate pairs of hit index and type."""
211 for ihit, hitType
in zip(self.hitIdx(), self.hitType()):
212 yield (ihit, hitType)
215 """Returns generator for hits.
217 Generator returns PixelHit/StripHit/GluedHit/Phase2OT depending on the
221 for ihit, hitType
in self.
_hits():
233 raise Exception(
"Unknown hit type %d" % hitType)
236 """Returns generator for pixel hits."""
238 for ihit, hitType
in self.
_hits():
244 """Returns generator for strip hits."""
246 for ihit, hitType
in self.
_hits():
252 """Returns generator for matched strip hits."""
254 for ihit, hitType
in self.
_hits():
260 """Returns generator for invalid hits."""
262 for ihit, hitType
in self.
_hits():
268 """Returns generator for phase2 outer tracker hits."""
270 for ihit, hitType
in self.
_hits():
276 """Adaptor class for objects containing or matched to SimHits (e.g. reco hits)."""
278 super(_SimHitMatchAdaptor, self).
__init__()
281 """Internal method to get the number of matched SimHits."""
282 return getattr(self._tree, self._prefix+
"_simHitIdx")[self._index].
size()
285 """Returns the number of matched SimHits."""
290 """Returns a generator for matched SimHits.
292 The generator returns SimHitMatchInfo objects.
299 """Adaptor class for objects matched to TrackingParticles."""
301 super(_TrackingParticleMatchAdaptor, self).
__init__()
304 """Internal method to get the number of matched TrackingParticles."""
305 return getattr(self._tree, self._prefix+
"_simTrkIdx")[self._index].
size()
308 """Returns the number of matched TrackingParticles."""
313 """Returns a generator for matched TrackingParticles.
315 The generator returns TrackingParticleMatchInfo objects.
323 """Returns best-matching TrackingParticle, even for fake tracks, or None if there is no best-matching TrackingParticle.
325 Best-matching is defined as the one with largest number of
326 hits matched to the hits of a track (>= 3). If there are many
327 fulfilling the same number of hits, the one inducing the
328 innermost hit of the track is chosen.
330 idx = self.bestSimTrkIdx()
336 """Fraction of shared hits with reco hits as denominator for best-matching TrackingParticle."""
337 return self.bestSimTrkShareFrac()
340 """Fraction of shared hits with TrackingParticle::numberOfTrackerHits() as denominator for best-matching TrackingParticle."""
341 return self.bestSimTrkShareFracSimDenom()
344 """Fraction of shared hits with number of reco clusters associated to a TrackingParticle as denominator for best-matching TrackingParticle."""
345 return self.bestSimTrkShareFracSimClusterDenom()
348 """Normalized chi2 calculated from track parameters+covariance matrix and TrackingParticle parameters for best-matching TrackingParticle."""
349 return self.bestSimTrkNChi2()
352 """Returns best-matching TrackingParticle, even for fake tracks, or None if there is no best-matching TrackingParticle.
354 Best-matching is defined as the one with largest number of
355 hits matched to the hits of a track (>= 3) starting from the
356 beginning of the track. If there are many fulfilling the same
357 number of hits, "a first TP" is chosen (a bit arbitrary, but
360 idx = self.bestFromFirstHitSimTrkIdx()
366 """Fraction of shared hits with reco hits as denominator for best-matching TrackingParticle starting from the first hit of a track."""
367 return self.bestFromFirstHitSimTrkShareFrac()
370 """Fraction of shared hits with TrackingParticle::numberOfTrackerHits() as denominator for best-matching TrackingParticle starting from the first hit of a track."""
371 return self.bestFromFirstHitSimTrkShareFracSimDenom()
374 """Fraction of shared hits with number of reco clusters associated to a TrackingParticle as denominator for best-matching TrackingParticle starting from the first hit of a track."""
375 return self.bestFromFirstHitSimTrkShareFracSimClusterDenom()
378 """Normalized chi2 calculated from track parameters+covariance matrix and TrackingParticle parameters for best-matching TrackingParticle starting from the first hit of a track."""
379 return self.bestFromFirstHitSimTrkNChi2()
383 """Class abstracting the whole ntuple/TTree.
385 Main benefit is to provide nice interface for
386 - iterating over events
387 - querying whether hit/seed information exists
389 Note that to iteratate over the evets with zip(), you should use
390 itertools.izip() instead.
392 def __init__(self, fileName, tree="trackingNtuple/tree"):
396 fileName -- String for path to the ROOT file
397 tree -- Name of the TTree object inside the ROOT file (default: 'trackingNtuple/tree')
399 super(TrackingNtuple, self).
__init__()
400 self.
_file = ROOT.TFile.Open(fileName)
414 """Returns true if the ntuple has hit information."""
415 return hasattr(self.
_tree,
"pix_isBarrel")
418 """Returns true if the ntuple has seed information."""
419 return hasattr(self.
_tree,
"see_fitok")
422 """Returns generator for iterating over TTree entries (events)
424 Generator returns Event objects.
429 ientry = self.
_tree.LoadTree( jentry )
432 nb = self.
_tree.GetEntry( jentry )
438 """Returns Event for a given index"""
439 ientry = self.
_tree.LoadTree(index)
440 if ientry < 0:
return None
441 nb = self.
_tree.GetEntry(ientry)
448 """Class abstracting a single event.
450 Main benefit is to provide nice interface to get various objects
451 or collections of objects.
458 entry -- Entry number in the tree
468 """Returns event number."""
469 return self.
_tree.event
472 """Returns lumisection number."""
473 return self.
_tree.lumi
476 """Returns run number."""
477 return self.
_tree.run
480 """Returns (run, lumi, event) tuple."""
484 """Returns 'run:lumi:event' string."""
485 return "%d:%d:%d" % self.
eventId()
488 """Returns BeamSpot object."""
492 """Returns Tracks object."""
496 """Returns PixelHits object."""
500 """Returns StripHits object."""
504 """Returns GluedHits object."""
508 """Returns Phase2OTHits object."""
512 """Returns Seeds object."""
516 """Returns TrackingParticles object."""
520 """Returns Vertices object."""
524 """Returns TrackingVertices object."""
529 """Class representing the beam spot."""
541 """Return object member variable.
543 'attr' is translated as a branch in the TTree (bsp_<attr>).
550 """Class representing a match to a SimHit.
552 The point of this class is to provide, in addition to the matched
553 SimHit, also other information about the match (e.g. fraction of
554 charge from this SimHit).
561 index -- Index of the hit matched to SimHit
562 shindex -- Index of the SimHit match (second index in _simHitIdx branch)
563 prefix -- String for prefix of the object (track/seed/hit) matched to TrackingParticle
565 super(SimHitMatchInfo, self).
__init__(tree, index, prefix)
569 """Custom __getattr__ because of the second index needed to access the branch."""
574 """Returns matched SimHit."""
580 """Class representing a match to a TrackingParticle.
582 The point of this class is to provide, in addition to the matched
583 TrackingParticle, also other information about the match (e.g.
584 shared hit fraction for tracks/seeds).
591 index -- Index of the object (track/seed) matched to TrackingParticle
592 tpindex -- Index of the TrackingParticle match (second index in _simTrkIdx branch)
593 prefix -- String for prefix of the object (track/seed) matched to TrackingParticle
595 super(TrackingParticleMatchInfo, self).
__init__(tree, index, prefix)
599 """Custom __getattr__ because of the second index needed to access the branch.
601 Note that when mapping the 'attr' to a branch, a 'simTrk' is
602 prepended and the first letter of 'attr' is turned to upper
609 """Returns matched TrackingParticle."""
613 """Class representing a match to a Track.
615 The point of this class is to provide, in addition to the matched
616 Track, also other information about the match (e.g. shared hit fraction.
623 index -- Index of the object (TrackingParticle) matched to track
624 trkindex -- Index of the track match (second index in _trkIdx branch)
625 prefix -- String for prefix of the object (TrackingParticle) matched to track
627 super(TrackMatchInfo, self).
__init__(tree, index, prefix)
631 """Custom __getattr__ because of the second index needed to access the branch.
633 Note that when mapping the 'attr' to a branch, a 'trk' is
634 prepended and the first letter of 'attr' is turned to upper
641 """Returns matched Track."""
645 """Class representing a match to a Seed.
647 The point of this class is to provide an interface compatible with
648 all other "MatchInfo" classes
651 def __init__(self, tree, index, seedindex, prefix):
656 index -- Index of the object (TrackingParticle) matched to seed
657 seedindex -- Index of the seed match (second index in _trkIdx branch)
658 prefix -- String for prefix of the object (TrackingParticle) matched to seed
660 super(SeedMatchInfo, self).
__init__(tree, index, prefix)
664 """Returns matched Seed."""
670 """Class presenting a track."""
676 index -- Index of the track
678 super(Track, self).
__init__(tree, index,
"trk")
681 """Returns Seed of the track."""
686 """Returns Vertex that used this track in its fit."""
694 return (self.pt() - tp.pca_pt())/self.ptErr()
700 return (getattr(self,
"lambda")() - tp.pca_lambda())/self.lambdaErr()
706 return (self.phi() - tp.pca_phi())/self.phiErr()
712 return (self.dxy() - tp.pca_dxy())/self.dxyErr()
718 return (self.dz() - tp.pca_dz())/self.dzErr()
721 """Class presenting a collection of tracks."""
728 super(Tracks, self).
__init__(tree,
"trk_pt", Track)
732 """Class representing a pixel hit."""
738 index -- Index of the hit
740 super(PixelHit, self).
__init__(tree, index,
"pix")
746 """Class presenting a collection of pixel hits."""
753 super(PixelHits, self).
__init__(tree,
"pix_isBarrel", PixelHit)
757 """Class representing a strip hit."""
763 index -- Index of the hit
765 super(StripHit, self).
__init__(tree, index,
"str")
771 """Class presenting a collection of strip hits."""
778 super(StripHits, self).
__init__(tree,
"str_isBarrel", StripHit)
782 """Class representing a matched strip hit."""
788 index -- Index of the hit
790 super(GluedHit, self).
__init__(tree, index,
"glu")
796 """Returns a StripHit for the mono hit."""
801 """Returns a StripHit for the stereo hit."""
806 """Returns the number of seeds containing this hit."""
811 """Returns generator for seeds containing this hit.
813 The generator returns Seed objects
820 """Class presenting a collection of matched strip hits."""
827 super(GluedHits, self).
__init__(tree,
"glu_isBarrel", GluedHit)
840 """Class representing an invalid hit."""
846 index -- Index of the hit
848 super(InvalidHit, self).
__init__(tree, index,
"inv")
854 """Returns a string describing the layer of the hit."""
856 return super(InvalidHit, self).
layerStr() +
" (%s)"%InvalidHit.Type.toString(invalid_type)
860 """Class representing a phase2 OT hit."""
866 index -- Index of the hit
868 super(Phase2OTHit, self).
__init__(tree, index,
"ph2")
874 """Class presenting a collection of phase2 OT hits."""
881 super(Phase2OTHits, self).
__init__(tree,
"ph2_isBarrel", Phase2OTHit)
885 """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."""
886 for ioffset, offset
in enumerate(tree.see_offset):
887 if tree.see_algo[offset] == algo:
888 next_offset = tree.see_offset[ioffset+1]
if ioffset < tree.see_offset.size()-1
else tree.see_algo.size()
889 return (offset, next_offset)
893 """Class presenting a seed."""
899 index -- Index of the seed
901 super(Seed, self).
__init__(tree, index,
"see")
904 """Returns the seed index within the seeds of the same algo.
906 In case of errors, -1 is returned.
913 return self.
_index - offset
916 """Returns Track that was made from this seed."""
921 """Class presenting a collection of seeds."""
928 super(Seeds, self).
__init__(tree,
"see_pt", Seed)
931 """Returns the number of seeds for a given 'algo'."""
933 return next_offset - offset
936 """Returns generator iterating over the seeds of a given 'algo'.
938 Generator returns Seed object.
941 for isee
in range(offset, next_offset):
945 """Returns Seed of index 'iseed' for 'algo'."""
947 if iseed >= (next_offset-offset):
948 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)))
953 """Class representing a SimHit which has not induced a RecHit."""
959 index -- Index of the SimHit
961 super(SimHit, self).
__init__(tree, index,
"simhit")
973 """Class representing a TrackingParticle."""
979 index -- Index of the TrackingParticle
981 super(TrackingParticle, self).
__init__(tree, index,
"sim")
984 """Internal function to get the number of matched tracks."""
988 """Returns the number of matched tracks."""
993 """Returns a generator for matched tracks.
995 The generator returns TrackMatchInfo objects.
1002 """Returns best-matching track, even for non-reconstructed TrackingParticles, or None, if there is no best-matching track.
1004 Best-matching is defined as the one with largest number of
1005 hits matched to the hits of a TrackingParticle (>= 3). If
1006 there are many fulfilling the same number of hits, the one
1007 inducing the innermost hit of the TrackingParticle is chosen.
1013 tracks = collections.OrderedDict()
1015 for recHit
in hit.hits():
1016 for track
in recHit.tracks():
1017 if track.index()
in tracks:
1018 tracks[track.index()] += 1
1020 tracks[track.index()] = 1
1023 for trackIndex, nhits
in six.iteritems(tracks):
1025 best = (trackIndex, nhits)
1031 """Internal function to get the number of matched seeds."""
1035 """Returns the number of matched seeds."""
1040 """Returns a generator for matched tracks.
1042 The generator returns SeedMatchInfo objects.
1050 return self.simHitIdx().
size()
1053 """Returns generator for SimHits."""
1055 for ihit
in self.simHitIdx():
1059 """Returns the parent TrackingVertex."""
1064 """Returns a generator for decay vertices.
1066 The generator returns TrackingVertex objects.
1069 for ivtx
in self.
_tree.sim_decayVtxIdx[self.
_index]:
1073 """Returns True if this TrackingParticle is a looper.
1075 Note that the check involves looping over the SimHits, so it is not too cheap."""
1078 for ihit
in self.simHitIdx():
1088 """Class presenting a collection of TrackingParticles."""
1093 tree -- TTree object
1095 super(TrackingParticles, self).
__init__(tree,
"sim_pt", TrackingParticle)
1099 """Class presenting a primary vertex."""
1104 tree -- TTree object
1105 index -- Index of the vertex
1107 super(Vertex, self).
__init__(tree, index,
"vtx")
1110 """Returns the number of tracks used in the vertex fit."""
1115 """Returns a generator for the tracks used in the vertex fit.
1117 The generator returns Track object.
1124 """Class presenting a collection of vertices."""
1129 tree -- TTree object
1131 super(Vertices, self).
__init__(tree,
"vtx_valid", Vertex)
1135 """Class representing a TrackingVertex."""
1140 tree -- TTree object
1141 index -- Index of the TrackingVertex
1143 super(TrackingVertex, self).
__init__(tree, index,
"simvtx")
1146 """Returns the number of source TrackingParticles."""
1151 """Returns the number of daughter TrackingParticles."""
1156 """Returns a generator for the source TrackingParticles."""
1158 for isim
in self.
_tree.simvtx_sourceSimIdx[self.
_index]:
1162 """Returns a generator for the daughter TrackingParticles."""
1164 for isim
in self.
_tree.simvtx_daughterSimIdx[self.
_index]:
1168 """Class presenting a collection of TrackingVertices."""
1173 tree -- TTree object
1175 super(TrackingVertex, self).
__init__(tree,
"simvtx_x")