Ejemplo n.º 1
0
    def __init__(self, leg1, leg2, pdgid, status=3, sort_by_pt=False, mass1=-1, mass2=-1): 
        '''
        Parameters (stored as attributes):
        leg1,2 : first and second leg.
        pdgid  : pdg code of the resonance
        status : status code of the resonance
        '''
        if isinstance(leg1.physObj, ROOT.pat.PackedCandidate): leg1 = PhysicsObject(ROOT.pat.PackedCandidate(leg1.physObj))
        if isinstance(leg2.physObj, ROOT.pat.PackedCandidate): leg2 = PhysicsObject(ROOT.pat.PackedCandidate(leg2.physObj))

        if sort_by_pt:
            self.leg1 = leg1 if leg1.pt() >= leg2.pt() else leg2 
            self.leg2 = leg2 if leg1.pt() >= leg2.pt() else leg1
        else:
            self.leg1 = leg1 
            self.leg2 = leg2 
        if mass1>0: self.leg1.setMass(mass1)
        if mass2>0: self.leg2.setMass(mass2)
        self._p4 = leg1.p4() + leg2.p4()
        self._charge = leg1.charge() + leg2.charge()
        self._pdgid = pdgid
        self._status = status
Ejemplo n.º 2
0
class Kst(object):
    '''
    Builds a K*(892) candidate out of two tracks.
    Assigns \pi and K mass hypothesis, find the assignment that returns the
    invariant mass closer to the nominal K*(892) mass.
    As an option, it can be required that the two tracks make a vertex.
    '''
    def __init__(self, tk1, tk2, requireVtx=False):
        self.tk1_ = tk1
        self.tk2_ = tk2

        self.arbitrate()

        self.vtx = None
        self.vtxprob = -99.

        if requireVtx:
            # stuff I need to instantiate only once
            self.vtxfit = VertexFitter()
            # create a std::vector<reco::Track> to be passed to the fitter
            self.tofit = ROOT.std.vector('reco::Track')()
            # fill the vector
            self.tofit.push_back(self.tk1_.physObj)
            self.tofit.push_back(self.tk2_.physObj)

            # fit the vertex and save the information
            self.makeVtx_()

    def makeVtx_(self):
        # fit it!
        svtree = self.vtxfit.Fit(self.tofit)  # actual vertex fitting
        # check that the vertex is good
        if not svtree.get().isEmpty() and svtree.get().isValid():
            svtree.movePointerToTheTop()
            sv = svtree.currentDecayVertex().get()
            recoSv = makeRecoVertex(
                sv, kinVtxTrkSize=2)  # need to do some gymastics
        self.vtx = recoSv
        self.vtxprob = ROOT.TMath.Prob(self.vtx.chi2(), int(self.vtx().ndof()))

    def arbitrate(self):
        pi1 = ROOT.Math.LorentzVector('<ROOT::Math::PxPyPzM4D<double> >')(
            self.tk1_.px(), self.tk1_.py(), self.tk1_.pz(), m_pi_ch)
        pi2 = ROOT.Math.LorentzVector('<ROOT::Math::PxPyPzM4D<double> >')(
            self.tk2_.px(), self.tk2_.py(), self.tk2_.pz(), m_pi_ch)
        k1 = ROOT.Math.LorentzVector('<ROOT::Math::PxPyPzM4D<double> >')(
            self.tk1_.px(), self.tk1_.py(), self.tk1_.pz(), m_k_ch)
        k2 = ROOT.Math.LorentzVector('<ROOT::Math::PxPyPzM4D<double> >')(
            self.tk2_.px(), self.tk2_.py(), self.tk2_.pz(), m_k_ch)

        # assign the mass hypotheses
        if abs((pi1 + k2).mass() - m_k_st_zero) < abs((pi2 + k1).mass() -
                                                      m_k_st_zero):
            self.pi_ = PhysicsObject(
                ROOT.pat.PackedCandidate(self.tk1_.physObj))
            self.k_ = PhysicsObject(ROOT.pat.PackedCandidate(
                self.tk2_.physObj))
        else:
            self.pi_ = PhysicsObject(
                ROOT.pat.PackedCandidate(self.tk2_.physObj))
            self.k_ = PhysicsObject(ROOT.pat.PackedCandidate(
                self.tk1_.physObj))

        self.pi_.setMass(m_pi_ch)
        self.k_.setMass(m_k_ch)

        self.pi_.setPdgId(self.pi_.charge() * 211)
        self.k_.setPdgId(self.k_.charge() * 321)

    def charge(self):
        return self.tk1_.charge() + self.tk2_.charge()

    def pi(self):
        return self.pi_

    def k(self):
        return self.k_

    def p4(self):
        return self.pi().p4() + self.k().p4()

    def mass(self):
        return self.p4().mass()

    def eta(self):
        return self.p4().eta()

    def phi(self):
        return self.p4().phi()

    def e(self):
        return self.p4().e()

    def pt(self):
        return self.p4().pt()

    def p(self):
        return math.sqrt(self.p4().px()**2 + self.p4().py()**2 +
                         self.p4().pz()**2)

    def px(self):
        return self.p4().px()

    def py(self):
        return self.p4().py()

    def pz(self):
        return self.p4().pz()

    def pdgId():
        # FIXME! get the correct pdgId based on the kaon an pion charges
        return 313 if self.k().charge() > 0 else -313