Example #1
0
def checkHNLorigin(sTree):
 flag = True
 if not fiducialCut: return flag
 flag = False
# only makes sense for signal == HNL
 hnlkey = -1
 for n in range(sTree.MCTrack.GetEntries()):
   mo = sTree.MCTrack[n].GetMotherId()
   if mo <0: continue
   if abs(sTree.MCTrack[mo].GetPdgCode()) == 9900015: 
       hnlkey = n
       break
 if hnlkey<0 : 
  ut.reportError("ShipAna: checkHNLorigin, no HNL found")
 else:
  # MCTrack after HNL should be first daughter
  theHNLVx = sTree.MCTrack[hnlkey]
  X,Y,Z =  theHNLVx.GetStartX(),theHNLVx.GetStartY(),theHNLVx.GetStartZ()
  if isInFiducial(X,Y,Z): flag = True
 return flag 
Example #2
0
def checkHNLorigin(sTree):
    flag = True
    if not fiducialCut: return flag
    flag = False
    # only makes sense for signal == HNL
    hnlkey = -1
    for n in range(sTree.MCTrack.GetEntries()):
        mo = sTree.MCTrack[n].GetMotherId()
        if mo < 0: continue
        if abs(sTree.MCTrack[mo].GetPdgCode()) == 9900015:
            hnlkey = n
            break
    if hnlkey < 0:
        ut.reportError("ShipAna: checkHNLorigin, no HNL found")
    else:
        # MCTrack after HNL should be first daughter
        theHNLVx = sTree.MCTrack[hnlkey]
        X, Y, Z = theHNLVx.GetStartX(), theHNLVx.GetStartY(
        ), theHNLVx.GetStartZ()
        if isInFiducial(X, Y, Z): flag = True
    return flag
Example #3
0
 def findVetoHitOnTrack(self, track):
     distMin = 99999.
     vetoHitOnTrack = ROOT.vetoHitOnTrack()
     xx = track.getFittedState()
     rep = ROOT.genfit.RKTrackRep(xx.getPDG())
     state = ROOT.genfit.StateOnPlane(rep)
     rep.setPosMom(state, xx.getPos(), xx.getMom())
     for i, vetoHit in enumerate(self.digiSBT):
         vetoHitPos = vetoHit.GetXYZ()
         try:
             rep.extrapolateToPoint(state, vetoHitPos, False)
         except:
             error = "shipDigiReco::findVetoHitOnTrack extrapolation did not worked"
             ut.reportError(error)
             if debug: print error
             continue
         dist = (rep.getPos(state) - vetoHitPos).Mag()
         if dist < distMin:
             distMin = dist
             vetoHitOnTrack.SetDist(distMin)
             vetoHitOnTrack.SetHitID(i)
     return vetoHitOnTrack
Example #4
0
 def findVetoHitOnTrack(self,track):
   distMin = 99999.
   vetoHitOnTrack = ROOT.vetoHitOnTrack()
   xx  = track.getFittedState()
   rep   = ROOT.genfit.RKTrackRep(xx.getPDG())
   state = ROOT.genfit.StateOnPlane(rep)
   rep.setPosMom(state,xx.getPos(),xx.getMom())
   for i,vetoHit in enumerate(self.digiSBT):
     vetoHitPos = vetoHit.GetXYZ()
     try:
      rep.extrapolateToPoint(state,vetoHitPos,False)
     except:
      error =  "shipDigiReco::findVetoHitOnTrack extrapolation did not worked"
      ut.reportError(error)
      if debug: print error
      continue
     dist = (rep.getPos(state) - vetoHitPos).Mag()
     if dist < distMin:
       distMin = dist
       vetoHitOnTrack.SetDist(distMin)
       vetoHitOnTrack.SetHitID(i)
   return vetoHitOnTrack
Example #5
0
    def findTracks(self):
        hitPosLists = {}
        stationCrossed = {}
        fittedtrackids = []
        self.fGenFitArray.Delete()
        self.fitTrack2MC.clear()
        #
        if withT0:
            self.SmearedHits = self.withT0Estimate()
            # old procedure, not including estimation of t0
        else:
            self.SmearedHits = self.smearHits(withNoStrawSmearing)

        nTrack = -1
        trackCandidates = []
        if realPR:
            fittedtrackids = shipPatRec.execute(
                self.SmearedHits, self.sTree,
                shipPatRec.ReconstructibleMCTracks)
            if fittedtrackids:
                tracknbr = 0
                for ids in fittedtrackids:
                    trackCandidates.append(
                        [shipPatRec.theTracks[tracknbr], ids])
                    tracknbr += 1
        else:  # do fake pattern reco
            for sm in self.SmearedHits:
                detID = self.digiStraw[sm['digiHit']].GetDetectorID()
                station = int(detID / 10000000)
                trID = self.sTree.strawtubesPoint[sm['digiHit']].GetTrackID()
                if not hitPosLists.has_key(trID):
                    hitPosLists[trID] = ROOT.std.vector('TVectorD')()
                    stationCrossed[trID] = {}
                m = array('d', [
                    sm['xtop'], sm['ytop'], sm['z'], sm['xbot'], sm['ybot'],
                    sm['z'], sm['dist']
                ])
                hitPosLists[trID].push_back(ROOT.TVectorD(7, m))
                if not stationCrossed[trID].has_key(station):
                    stationCrossed[trID][station] = 0
                stationCrossed[trID][station] += 1
            for atrack in hitPosLists:
                if atrack < 0:
                    continue  # these are hits not assigned to MC track because low E cut
                pdg = self.sTree.MCTrack[atrack].GetPdgCode()
                if not self.PDG.GetParticle(pdg): continue  # unknown particle
                meas = hitPosLists[atrack]
                nM = meas.size()
                if nM < 25: continue  # not enough hits to make a good trackfit
                if len(stationCrossed[atrack]) < 3:
                    continue  # not enough stations crossed to make a good trackfit
                if debug:
                    mctrack = self.sTree.MCTrack[atrack]
                charge = self.PDG.GetParticle(pdg).Charge() / (3.)
                posM = ROOT.TVector3(0, 0, 0)
                momM = ROOT.TVector3(0, 0, 3. * u.GeV)
                # approximate covariance
                covM = ROOT.TMatrixDSym(6)
                resolution = self.sigma_spatial
                if withT0:
                    resolution = resolution * 1.4  # worse resolution due to t0 estimate
                for i in range(3):
                    covM[i][i] = resolution * resolution
                covM[0][0] = resolution * resolution * 100.
                for i in range(3, 6):
                    covM[i][i] = ROOT.TMath.Power(
                        resolution / nM / ROOT.TMath.Sqrt(3), 2)
                # trackrep
                rep = ROOT.genfit.RKTrackRep(pdg)
                # smeared start state
                stateSmeared = ROOT.genfit.MeasuredStateOnPlane(rep)
                rep.setPosMomCov(stateSmeared, posM, momM, covM)
                # create track
                seedState = ROOT.TVectorD(6)
                seedCov = ROOT.TMatrixDSym(6)
                rep.get6DStateCov(stateSmeared, seedState, seedCov)
                theTrack = ROOT.genfit.Track(rep, seedState, seedCov)
                hitCov = ROOT.TMatrixDSym(7)
                hitCov[6][6] = resolution * resolution
                for m in meas:
                    tp = ROOT.genfit.TrackPoint(
                        theTrack
                    )  # note how the point is told which track it belongs to
                    measurement = ROOT.genfit.WireMeasurement(
                        m, hitCov, 1, 6, tp
                    )  # the measurement is told which trackpoint it belongs to
                    # print measurement.getMaxDistance()
                    measurement.setMaxDistance(0.5 * u.cm)
                    # measurement.setLeftRightResolution(-1)
                    tp.addRawMeasurement(
                        measurement)  # package measurement in the TrackPoint
                    theTrack.insertPoint(tp)  # add point to Track
            # print "debug meas",atrack,nM,stationCrossed[atrack],self.sTree.MCTrack[atrack],pdg
                trackCandidates.append([theTrack, atrack])
        for entry in trackCandidates:
            #check
            atrack = entry[1]
            theTrack = entry[0]
            if not theTrack.checkConsistency():
                print 'Problem with track before fit, not consistent', atrack, theTrack
                continue
# do the fit
            try:
                self.fitter.processTrack(
                    theTrack)  # processTrackWithRep(theTrack,rep,True)
            except:
                if debug: print "genfit failed to fit track"
                error = "genfit failed to fit track"
                ut.reportError(error)
                continue


#check
            if not theTrack.checkConsistency():
                if debug:
                    print 'Problem with track after fit, not consistent', atrack, theTrack
                error = "Problem with track after fit, not consistent"
                ut.reportError(error)
                continue
            fitStatus = theTrack.getFitStatus()
            nmeas = fitStatus.getNdf()
            chi2 = fitStatus.getChi2() / nmeas
            h['chi2'].Fill(chi2)
            # make track persistent
            nTrack = self.fGenFitArray.GetEntries()
            if not debug:
                theTrack.prune(
                    "CFL"
                )  #  http://sourceforge.net/p/genfit/code/HEAD/tree/trunk/core/include/Track.h#l280
            self.fGenFitArray[nTrack] = theTrack
            self.fitTrack2MC.push_back(atrack)
            if debug:
                print 'save track', theTrack, chi2, nmeas, fitStatus.isFitConverged(
                )
        self.fitTracks.Fill()
        self.mcLink.Fill()
        return nTrack + 1
Example #6
0
    def TwoTrackVertex(self):
        self.fPartArray.Delete()
        fittedTracks = getattr(self.sTree, self.fitTrackLoc)
        goodTracks = getattr(self.sTree, self.goodTracksLoc)
        if goodTracks.size() < 2: return
        particles = self.fPartArray
        PosDirCharge, CovMat, scalFac = {}, {}, {}
        for tr in goodTracks:
            fitStatus = fittedTracks[tr].getFitStatus()
            xx = fittedTracks[tr].getFittedState()
            pid = xx.getPDG()
            if not pidProton and abs(pid) == 2212:
                pid = int(math.copysign(211, pid))
            rep = ROOT.genfit.RKTrackRep(xx.getPDG())
            state = ROOT.genfit.StateOnPlane(rep)
            rep.setPosMom(state, xx.getPos(), xx.getMom())
            PosDirCharge[tr] = {'position':xx.getPos(),'direction':xx.getDir(),\
                                   'momentum':xx.getMom(),'charge':xx.getCharge(),'pdgCode':pid,'state':xx,'rep':rep,'newstate':state}
            CovMat[tr] = xx.get6DCov()
#
        if len(PosDirCharge) < 2: return
        if len(PosDirCharge) > 4: return  # abort too busy events
        for t1 in PosDirCharge:
            c1 = PosDirCharge[t1]['charge']
            for t2 in PosDirCharge:
                if not t2 > t1: continue
                # ignore this for background studies
                if PosDirCharge[t2]['charge'] == c1: continue
                newPos, doca = self.VertexError(t1, t2, PosDirCharge)
                # as we have learned, need iterative procedure
                dz = 99999.
                rc = True
                step = 0
                while dz > 0.01:
                    zBefore = newPos[2]
                    # make a new rep for track 1,2
                    for tr in [t1, t2]:
                        try:
                            PosDirCharge[tr]['rep'].extrapolateToPoint(
                                PosDirCharge[tr]['newstate'], newPos, False)
                        except:
                            ut.reportError(
                                'shipVertex: extrapolation did not worked')
                            rc = False
                            break
                        self.newPosDir[tr] = {'position':PosDirCharge[tr]['rep'].getPos(PosDirCharge[tr]['newstate']),\
                                              'direction':PosDirCharge[tr]['rep'].getDir(PosDirCharge[tr]['newstate']),\
                                              'momentum':PosDirCharge[tr]['rep'].getMom(PosDirCharge[tr]['newstate'])}
                    if not rc: break
                    newPos, doca = self.VertexError(t1, t2, self.newPosDir)
                    dz = abs(zBefore - newPos[2])
                    step += 1
                    if step > 10:
                        ut.reportError(
                            "shipVertex::abort iteration, too many steps")
                        if debug:
                            print 'abort iteration, too many steps, pos=', newPos[
                                0], newPos[1], newPos[
                                    2], ' doca=', doca, 'z before and dz', zBefore, dz
                        rc = False
                        break
#
                if not rc:
                    continue  # extrapolation failed, makes no sense to continue
                # now go for the last step and vertex error
                scalFac[t1] = (PosDirCharge[t1]['position'][2] -
                               newPos[2]) / PosDirCharge[t1]['direction'][
                                   2] / PosDirCharge[t1]['momentum'].Mag()
                scalFac[t2] = (PosDirCharge[t2]['position'][2] -
                               newPos[2]) / PosDirCharge[t2]['direction'][
                                   2] / PosDirCharge[t2]['momentum'].Mag()
                HNLPos, covX, dist = self.VertexError(t1, t2, self.newPosDir,
                                                      CovMat, scalFac)
                # monitor Vx resolution and pulls
                #print "DEBUG",HNLPos[0],HNLPos[1],HNLPos[2],dist,covX[0][0],covX[1][1],covX[2][2]
                #print "     ",mctrack.GetStartX(),mctrack.GetStartY(),mctrack.GetStartZ()
                #   HNL true
                if self.sTree.GetBranch("fitTrack2MC"):
                    mctrack = self.sTree.MCTrack[self.sTree.fitTrack2MC[t1]]
                    mctrack2 = self.sTree.MCTrack[self.sTree.fitTrack2MC[t2]]
                    mcHNL = self.sTree.MCTrack[mctrack.GetMotherId()]
                    #print "true vtx: ",mctrack.GetStartX(),mctrack.GetStartY(),mctrack.GetStartZ()
                    #print "reco vtx: ",HNLPos[0],HNLPos[1],HNLPos[2]
                    #self.h['Vzpull'].Fill( (mctrack.GetStartZ()-HNLPos[2])/ROOT.TMath.Sqrt(covX[2][2]) )
                    #self.h['Vxpull'].Fill( (mctrack.GetStartX()-HNLPos[0])/ROOT.TMath.Sqrt(covX[0][0]) )
                    #self.h['Vypull'].Fill( (mctrack.GetStartY()-HNLPos[1])/ROOT.TMath.Sqrt(covX[1][1]) )
                    #self.h['dVx'].Fill( (mctrack.GetStartX()-HNLPos[0]) )
                    #self.h['dVy'].Fill( (mctrack.GetStartY()-HNLPos[1]) )
                    #self.h['dVz'].Fill( (mctrack.GetStartZ()-HNLPos[2]) )

                #print "*********************************** vertex fit precise   ******************************************** "

                detPlane = ROOT.genfit.DetPlane(ROOT.TVector3(0, 0, HNLPos[2]),
                                                ROOT.TVector3(1, 0, 0),
                                                ROOT.TVector3(0, 1, 0))
                plane = ROOT.genfit.RKTrackRep().makePlane(
                    ROOT.TVector3(0, 0, HNLPos[2]), ROOT.TVector3(1, 0, 0),
                    ROOT.TVector3(0, 1, 0))
                st1 = fittedTracks[t1].getFittedState()
                st2 = fittedTracks[t2].getFittedState()
                try:
                    st1.extrapolateToPlane(plane)
                except:
                    ut.reportError(
                        "shipVertex::TwoTrackVertex: extrapolation does not worked"
                    )
                    continue
                try:
                    st2.extrapolateToPlane(plane)
                except:
                    ut.reportError(
                        "shipVertex::TwoTrackVertex: extrapolation does not worked"
                    )
                    continue
                mom1 = st1.getMom()
                mom2 = st2.getMom()
                cov1 = st1.getCov()
                cov2 = st2.getCov()
                cov = ROOT.TMatrixDSym(10)
                for i in range(10):
                    for j in range(10):
                        if i < 5 and j < 5: cov[i][j] = cov1[i][j]
                        if i > 4 and j > 4: cov[i][j] = cov2[i - 5][j - 5]
                covInv = ROOT.TMatrixDSym()
                ROOT.genfit.tools.invertMatrix(cov, covInv)

                self.y_data = np.array(
                    [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
                stVal1 = st1.getState()
                stVal2 = st2.getState()
                for i in range(5):
                    self.y_data[i] = stVal1[i]
                    self.y_data[i + 5] = stVal2[i]
                self.z0 = HNLPos[2]
                self.Vy = np.zeros(100)
                for i in range(100):
                    self.Vy[i] = covInv[i / 10][i % 10]

                f = np.array([0.])
                gMinuit = ROOT.TMinuit(9)
                gMinuit.SetFCN(self.fcn)
                gMinuit.SetPrintLevel(-1)  #minute quiet mode
                rc = gMinuit.DefineParameter(0, 'X pos', HNLPos[0], 0.1, 0, 0)
                rc = gMinuit.DefineParameter(1, 'Y pos', HNLPos[1], 0.1, 0, 0)
                rc = gMinuit.DefineParameter(2, 'Z pos', HNLPos[2], 0.1, 0, 0)
                rc = gMinuit.DefineParameter(3, 'tan1X', mom1[0] / mom1[2],
                                             0.1, 0, 0)
                rc = gMinuit.DefineParameter(4, 'tan1Y', mom1[1] / mom1[2],
                                             0.1, 0, 0)
                rc = gMinuit.DefineParameter(5, '1/mom1', 1. / mom1.Mag(), 0.1,
                                             0, 0)
                rc = gMinuit.DefineParameter(6, 'tan2X', mom2[0] / mom2[2],
                                             0.1, 0, 0)
                rc = gMinuit.DefineParameter(7, 'tan2Y', mom2[1] / mom2[2],
                                             0.1, 0, 0)
                rc = gMinuit.DefineParameter(8, '1/mom2', 1. / mom2.Mag(), 0.1,
                                             0, 0)
                gMinuit.Clear()
                gMinuit.Migrad()
                try:
                    tmp = array('d', [0])
                    err = array('i', [0])
                    gMinuit.mnexcm("HESSE", tmp, -1, err)
                    #gMinuit.mnexcm( "MINOS", tmp, -1, err )
                except:
                    ut.reportError("shipVertex::minos does not work")
                    continue
                #get results from TMinuit:
                emat = array('d', [
                    0,
                ] * 81)
                gMinuit.mnemat(emat, 9)
                values = array('d', [
                    0,
                ] * 9)
                errors = array('d', [
                    0,
                ] * 9)
                dValue = ROOT.Double()
                dError = ROOT.Double()
                rc = gMinuit.GetParameter(0, dValue, dError)
                values[0] = dValue
                errors[0] = dError
                rc = gMinuit.GetParameter(1, dValue, dError)
                values[1] = dValue
                errors[1] = dError
                rc = gMinuit.GetParameter(2, dValue, dError)
                values[2] = dValue
                errors[2] = dError
                rc = gMinuit.GetParameter(3, dValue, dError)
                values[3] = dValue
                errors[3] = dError
                rc = gMinuit.GetParameter(4, dValue, dError)
                values[4] = dValue
                errors[4] = dError
                rc = gMinuit.GetParameter(5, dValue, dError)
                values[5] = dValue
                errors[5] = dError
                rc = gMinuit.GetParameter(6, dValue, dError)
                values[6] = dValue
                errors[6] = dError
                rc = gMinuit.GetParameter(7, dValue, dError)
                values[7] = dValue
                errors[7] = dError
                rc = gMinuit.GetParameter(8, dValue, dError)
                values[8] = dValue
                errors[8] = dError

                xFit = values[0]
                yFit = values[1]
                zFit = values[2]
                HNLPosFit = ROOT.TVector3(xFit, yFit, zFit)
                xFitErr = errors[0]
                yFitErr = errors[1]
                zFitErr = errors[2]

                #fixme: mass from track reconstraction needed
                m1 = self.PDG.GetParticle(PosDirCharge[t1]['pdgCode']).Mass()
                m2 = self.PDG.GetParticle(PosDirCharge[t2]['pdgCode']).Mass()

                #self.h['VxpullFit'].Fill( (mctrack.GetStartX()-xFit)/xFitErr )
                #self.h['VypullFit'].Fill( (mctrack.GetStartY()-yFit)/yFitErr )
                #self.h['VzpullFit'].Fill( (mctrack.GetStartZ()-zFit)/zFitErr )
                #self.h['dVxFit'].Fill( (mctrack.GetStartX()-xFit) )
                #self.h['dVyFit'].Fill( (mctrack.GetStartY()-yFit) )
                #self.h['dVzFit'].Fill( (mctrack.GetStartZ()-zFit) )

                def getP(fitValues, cov, m1, m2):
                    a3 = fitValues[3]
                    a4 = fitValues[4]
                    a5 = fitValues[5]
                    a6 = fitValues[6]
                    a7 = fitValues[7]
                    a8 = fitValues[8]
                    px1 = a3 / (a5 * ROOT.TMath.Sqrt(1 + a3**2 + a4**2))
                    py1 = a4 / (a5 * ROOT.TMath.Sqrt(1 + a3**2 + a4**2))
                    pz1 = 1 / (a5 * ROOT.TMath.Sqrt(1 + a3**2 + a4**2))
                    px2 = a6 / (a8 * ROOT.TMath.Sqrt(1 + a6**2 + a7**2))
                    py2 = a7 / (a8 * ROOT.TMath.Sqrt(1 + a6**2 + a7**2))
                    pz2 = 1 / (a8 * ROOT.TMath.Sqrt(1 + a6**2 + a7**2))
                    Px = px1 + px2
                    Py = py1 + py2
                    Pz = pz1 + pz2
                    E1 = ROOT.TMath.Sqrt(px1**2 + py1**2 + pz1**2 + m1**2)
                    E2 = ROOT.TMath.Sqrt(px2**2 + py2**2 + pz2**2 + m2**2)
                    M = ROOT.TMath.Sqrt(2 * E1 * E2 + m1**2 + m2**2 -
                                        2 * pz1 * pz2 *
                                        (1 + a3 * a6 + a4 * a7))
                    MM = 2 * M
                    A5 = 1 + a3**2 + a4**2
                    A8 = 1 + a6**2 + a7**2
                    M_AtoP = ROOT.TMatrixD(4, 6)
                    MT_AtoP = ROOT.TMatrixD(6, 4)
                    covA = ROOT.TMatrixD(6, 6)
                    M_AtoP[0][0] = (1. - a3 * a3 / A5) / (a5 *
                                                          ROOT.TMath.Sqrt(A5))
                    M_AtoP[0][1] = (-a3 * a4 / A5) / (a5 * ROOT.TMath.Sqrt(A5))
                    M_AtoP[0][2] = (-a3) / (a5 * a5 * ROOT.TMath.Sqrt(A5))
                    M_AtoP[0][3] = (1. - a6 * a6 / A8) / (a8 *
                                                          ROOT.TMath.Sqrt(A8))
                    M_AtoP[0][4] = (-a6 * a7 / A8) / (a8 * ROOT.TMath.Sqrt(A8))
                    M_AtoP[0][5] = (-a6) / (a8 * a8 * ROOT.TMath.Sqrt(A8))

                    M_AtoP[1][0] = (-a3 * a4 / A5) / (a5 * ROOT.TMath.Sqrt(A5))
                    M_AtoP[1][1] = (1. - a4 * a4 / A5) / (a5 *
                                                          ROOT.TMath.Sqrt(A5))
                    M_AtoP[1][2] = (-a4) / (a5 * a5 * ROOT.TMath.Sqrt(A5))
                    M_AtoP[1][3] = (-a6 * a7 / A8) / (a8 * ROOT.TMath.Sqrt(A8))
                    M_AtoP[1][4] = (1. - a7 * a7 / A8) / (a8 *
                                                          ROOT.TMath.Sqrt(A8))
                    M_AtoP[1][5] = (-a7) / (a8 * a8 * ROOT.TMath.Sqrt(A8))

                    M_AtoP[2][0] = (-a3 / A5) / (a5 * ROOT.TMath.Sqrt(A5))
                    M_AtoP[2][1] = (-a4 / A5) / (a5 * ROOT.TMath.Sqrt(A5))
                    M_AtoP[2][2] = (-1.) / (a5 * a5 * ROOT.TMath.Sqrt(A5))
                    M_AtoP[2][3] = (-a6 / A8) / (a8 * ROOT.TMath.Sqrt(A8))
                    M_AtoP[2][4] = (-a7 / A8) / (a8 * ROOT.TMath.Sqrt(A8))
                    M_AtoP[2][5] = (-1.) / (a8 * a8 * ROOT.TMath.Sqrt(A8))

                    a5a8 = a5 * a8 * ROOT.TMath.Sqrt(A5) * ROOT.TMath.Sqrt(A8)

                    M_AtoP[3][0] = (-2 * a6 / a5a8 + 2 * a3 * E2 /
                                    (a5 * a5 * A5 * E1)) / MM
                    M_AtoP[3][1] = (-2 * a7 / a5a8 + 2 * a4 * E2 /
                                    (a5 * a5 * A5 * E1)) / MM
                    M_AtoP[3][2] = (2 * (1 + a3 * a6 + a4 * a7) /
                                    (a5 * a5a8) - 2 *
                                    (1. + a3 * a3 + a4 * a4) * E2 /
                                    (a5 * a5 * a5 * A5 * E1)) / MM
                    M_AtoP[3][3] = (-2 * a3 / a5a8 + 2 * a6 * E1 /
                                    (a8 * a8 * A8 * E2)) / MM
                    M_AtoP[3][4] = (-2 * a4 / a5a8 + 2 * a7 * E1 /
                                    (a8 * a8 * A8 * E2)) / MM
                    M_AtoP[3][5] = (2 * (1 + a3 * a6 + a4 * a7) /
                                    (a8 * a5a8) - 2 *
                                    (1. + a6 * a6 + a7 * a7) * E1 /
                                    (a8 * a8 * a8 * A8 * E2)) / MM

                    for i in range(4):
                        for j in range(6):
                            MT_AtoP[j][i] = M_AtoP[i][j]

                    for i in range(36):
                        covA[i / 6][i % 6] = cov[i / 6 + 3 + (i % 6 + 3) * 9]

                    tmp = ROOT.TMatrixD(4, 6)
                    tmp.Mult(M_AtoP, covA)
                    covP = ROOT.TMatrixD(4, 4)
                    covP.Mult(tmp, MT_AtoP)
                    P = ROOT.TLorentzVector()
                    P.SetXYZM(Px, Py, Pz, M)
                    return P, covP

                P, covP = getP(values, emat, m1, m2)
                #print "******************************************************************************* "

                #create ship particle
                #notes:
                #P-TLorentzVector of fitted HNL prticle
                #covP - covariance matrix of HNL four-vector (Px,Py,Pz,M)
                #HNLPosFit - fited position of HNL
                #covV - comariance matrix of the vtx position
                covV = array('d', [
                    emat[0], emat[1], emat[2], emat[1 + 9], emat[2 + 9],
                    emat[2 + 2 * 9]
                ])
                covP = array('d', [
                    covP[0][0], covP[0][1], covP[0][2], covP[0][3], covP[1][1],
                    covP[1][2], covP[1][3], covP[2][2], covP[2][3], covP[3][3]
                ])

                # try to make it persistent
                vx = ROOT.TLorentzVector(
                    HNLPosFit, 0
                )  # time at vertex still needs to be evaluated from time of tracks and time of flight
                particle = ROOT.ShipParticle(9900015, 0, -1, -1, t1, t2, P, vx)
                particle.SetCovV(covV)
                particle.SetCovP(covP)
                particle.SetDoca(doca)
                nParts = particles.GetEntries()
                particles[nParts] = particle
Example #7
0
 def findTracks(self):
  hitPosLists    = {}
  stationCrossed = {}
  fittedtrackids=[]
  listOfIndices  = {}
  self.fGenFitArray.Clear()
  self.fTrackletsArray.Delete()
  self.fitTrack2MC.clear()

#   
  if global_variables.withT0:
    self.SmearedHits = self.withT0Estimate()
  # old procedure, not including estimation of t0 
  else:
    self.SmearedHits = self.smearHits(global_variables.withNoStrawSmearing)

  nTrack = -1
  trackCandidates = []
  
  if global_variables.realPR:
    # Do real PatRec
    track_hits = shipPatRec.execute(self.SmearedHits, global_variables.ShipGeo, global_variables.realPR)
    # Create hitPosLists for track fit
    for i_track in track_hits.keys():
      atrack = track_hits[i_track]
      atrack_y12 = atrack['y12']
      atrack_stereo12 = atrack['stereo12']
      atrack_y34 = atrack['y34']
      atrack_stereo34 = atrack['stereo34']
      atrack_smeared_hits = list(atrack_y12) + list(atrack_stereo12) + list(atrack_y34) + list(atrack_stereo34)
      for sm in atrack_smeared_hits:
        detID = sm['detID']
        station = int(detID//10000000)
        trID = i_track
        # Collect hits for track fit
        if trID not in hitPosLists:
          hitPosLists[trID] = ROOT.std.vector('TVectorD')()
          listOfIndices[trID] = []
          stationCrossed[trID]  = {}
        m = array('d',[sm['xtop'],sm['ytop'],sm['z'],sm['xbot'],sm['ybot'],sm['z'],sm['dist']])
        hitPosLists[trID].push_back(ROOT.TVectorD(7,m))
        listOfIndices[trID].append(sm['digiHit'])
        if station not in stationCrossed[trID]:
          stationCrossed[trID][station] = 0
        stationCrossed[trID][station] += 1
  else: # do fake pattern recognition
   for sm in self.SmearedHits:
    detID = self.digiStraw[sm['digiHit']].GetDetectorID()
    station = int(detID//10000000)
    trID = self.sTree.strawtubesPoint[sm['digiHit']].GetTrackID()
    if trID not in hitPosLists:   
      hitPosLists[trID]     = ROOT.std.vector('TVectorD')()
      listOfIndices[trID] = [] 
      stationCrossed[trID]  = {}
    m = array('d',[sm['xtop'],sm['ytop'],sm['z'],sm['xbot'],sm['ybot'],sm['z'],sm['dist']])
    hitPosLists[trID].push_back(ROOT.TVectorD(7,m))
    listOfIndices[trID].append(sm['digiHit'])
    if station not in stationCrossed[trID]: stationCrossed[trID][station]=0
    stationCrossed[trID][station]+=1
#
   # for atrack in listOfIndices:
   #   # make tracklets out of trackCandidates, just for testing, should be output of proper pattern recognition
   #  nTracks   = self.fTrackletsArray.GetEntries()
   #  aTracklet  = self.fTrackletsArray.ConstructedAt(nTracks)
   #  listOfHits = aTracklet.getList()
   #  aTracklet.setType(3)
   #  for index in listOfIndices[atrack]:
   #    listOfHits.push_back(index)
#  
  for atrack in hitPosLists:
    if atrack < 0: continue # these are hits not assigned to MC track because low E cut
    pdg    = self.sTree.MCTrack[atrack].GetPdgCode()
    if not self.PDG.GetParticle(pdg): continue # unknown particle
    # pdg = 13
    meas = hitPosLists[atrack]
    nM = meas.size()
    if nM < 25 : continue                          # not enough hits to make a good trackfit 
    if len(stationCrossed[atrack]) < 3 : continue  # not enough stations crossed to make a good trackfit 
    if global_variables.debug:
       mctrack = self.sTree.MCTrack[atrack]
    # charge = self.PDG.GetParticle(pdg).Charge()/(3.)
    posM = ROOT.TVector3(0, 0, 0)
    momM = ROOT.TVector3(0,0,3.*u.GeV)
# approximate covariance
    covM = ROOT.TMatrixDSym(6)
    resolution = self.sigma_spatial
    if global_variables.withT0:
      resolution *= 1.4 # worse resolution due to t0 estimate
    for  i in range(3):   covM[i][i] = resolution*resolution
    covM[0][0]=resolution*resolution*100.
    for  i in range(3,6): covM[i][i] = ROOT.TMath.Power(resolution / nM / ROOT.TMath.Sqrt(3), 2)
# trackrep
    rep = ROOT.genfit.RKTrackRep(pdg)
# smeared start state
    stateSmeared = ROOT.genfit.MeasuredStateOnPlane(rep)
    rep.setPosMomCov(stateSmeared, posM, momM, covM)
# create track
    seedState = ROOT.TVectorD(6)
    seedCov   = ROOT.TMatrixDSym(6)
    rep.get6DStateCov(stateSmeared, seedState, seedCov)
    theTrack = ROOT.genfit.Track(rep, seedState, seedCov)
    hitCov = ROOT.TMatrixDSym(7)
    hitCov[6][6] = resolution*resolution
    for m in meas:
      tp = ROOT.genfit.TrackPoint(theTrack) # note how the point is told which track it belongs to 
      measurement = ROOT.genfit.WireMeasurement(m,hitCov,1,6,tp) # the measurement is told which trackpoint it belongs to
      # print measurement.getMaxDistance()
      measurement.setMaxDistance(global_variables.ShipGeo.strawtubes.InnerStrawDiameter / 2.)
      # measurement.setLeftRightResolution(-1)
      tp.addRawMeasurement(measurement) # package measurement in the TrackPoint                                          
      theTrack.insertPoint(tp)  # add point to Track
   # print "debug meas",atrack,nM,stationCrossed[atrack],self.sTree.MCTrack[atrack],pdg
    trackCandidates.append([theTrack,atrack])
  
  for entry in trackCandidates:
#check
    atrack = entry[1]
    theTrack = entry[0]
    if not theTrack.checkConsistency():
     print('Problem with track before fit, not consistent',atrack,theTrack)
     continue
# do the fit
    try:  self.fitter.processTrack(theTrack) # processTrackWithRep(theTrack,rep,True)
    except: 
      if global_variables.debug:
        print("genfit failed to fit track")
      error = "genfit failed to fit track"
      ut.reportError(error)
      continue
#check
    if not theTrack.checkConsistency():
     if global_variables.debug:
       print('Problem with track after fit, not consistent', atrack, theTrack)
     error = "Problem with track after fit, not consistent"
     ut.reportError(error)
     continue
    try:
      fittedState = theTrack.getFittedState()
      fittedMom = fittedState.getMomMag()
    except:
      error = "Problem with fittedstate"
      ut.reportError(error)
      continue
    fitStatus   = theTrack.getFitStatus()
    nmeas = fitStatus.getNdf()   
    chi2        = fitStatus.getChi2()/nmeas   
    global_variables.h['chi2'].Fill(chi2)
# make track persistent
    nTrack   = self.fGenFitArray.GetEntries()
    if not global_variables.debug:
      theTrack.prune("CFL")  # http://sourceforge.net/p/genfit/code/HEAD/tree/trunk/core/include/Track.h#l280
    self.fGenFitArray[nTrack] = theTrack
    # self.fitTrack2MC.push_back(atrack)
    if global_variables.debug:
     print('save track',theTrack,chi2,nmeas,fitStatus.isFitConverged())
    # Save MC link
    track_ids = []
    for index in listOfIndices[atrack]:
      ahit = self.sTree.strawtubesPoint[index]
      track_ids += [ahit.GetTrackID()]
    frac, tmax = self.fracMCsame(track_ids)
    self.fitTrack2MC.push_back(tmax)
    # Save hits indexes of the the fitted tracks
    nTracks   = self.fTrackletsArray.GetEntries()
    aTracklet  = self.fTrackletsArray.ConstructedAt(nTracks)
    listOfHits = aTracklet.getList()
    aTracklet.setType(1)
    for index in listOfIndices[atrack]:
      listOfHits.push_back(index)
  self.Tracklets.Fill()
  self.fitTracks.Fill()
  self.mcLink.Fill()
# debug 
  if global_variables.debug:
   print('save tracklets:') 
   for x in self.sTree.Tracklets:
    print(x.getType(),x.getList().size())
  return nTrack+1
Example #8
0
 def TwoTrackVertex(self):
  self.fPartArray.Delete()
  fittedTracks = getattr(self.sTree,self.fitTrackLoc)
  goodTracks = getattr(self.sTree,self.goodTracksLoc)
  if goodTracks.size() < 2: return
  particles    = self.fPartArray
  PosDirCharge,CovMat,scalFac = {},{},{}
  for tr in goodTracks:
   fitStatus = fittedTracks[tr].getFitStatus()
   xx  = fittedTracks[tr].getFittedState()
   pid   = xx.getPDG()
   if not pidProton and abs(pid) == 2212:
     pid = int(ROOT.TMath.Sign(211,pid))
   rep   = ROOT.genfit.RKTrackRep(xx.getPDG())  
   state = ROOT.genfit.StateOnPlane(rep)
   rep.setPosMom(state,xx.getPos(),xx.getMom())
   PosDirCharge[tr] = {'position':xx.getPos(),'direction':xx.getDir(),\
                          'momentum':xx.getMom(),'charge':xx.getCharge(),'pdgCode':pid,'state':xx,'rep':rep,'newstate':state}
   CovMat[tr] = xx.get6DCov() 
#
  if len(PosDirCharge) < 2: return
  if len(PosDirCharge) > 4: return # abort too busy events
  for t1 in PosDirCharge:
   c1  = PosDirCharge[t1]['charge'] 
   for t2 in PosDirCharge:
     if not t2>t1: continue
     # ignore this for background studies 
     if PosDirCharge[t2]['charge'] == c1 : continue
     newPos,doca    = self.VertexError(t1,t2,PosDirCharge)
# as we have learned, need iterative procedure
     dz = 99999.
     rc = True 
     step = 0
     while dz > 0.01:
      zBefore = newPos[2]
     # make a new rep for track 1,2
      for tr in [t1,t2]:     
       try:
        PosDirCharge[tr]['rep'].extrapolateToPoint(PosDirCharge[tr]['newstate'], newPos, False)
       except:
        ut.reportError('shipVertex: extrapolation did not worked')
        rc = False  
        break
       self.newPosDir[tr] = {'position':PosDirCharge[tr]['rep'].getPos(PosDirCharge[tr]['newstate']),\
                             'direction':PosDirCharge[tr]['rep'].getDir(PosDirCharge[tr]['newstate']),\
                             'momentum':PosDirCharge[tr]['rep'].getMom(PosDirCharge[tr]['newstate'])}
      if not rc: break
      newPos,doca = self.VertexError(t1,t2,self.newPosDir)
      dz = abs(zBefore-newPos[2])
      step+=1
      if step > 10:  
         ut.reportError("shipVertex::abort iteration, too many steps")
         if debug: 
          print 'abort iteration, too many steps, pos=',newPos[0],newPos[1],newPos[2],' doca=',doca,'z before and dz',zBefore,dz
         rc = False
         break 
#       
     if not rc: continue # extrapolation failed, makes no sense to continue
# now go for the last step and vertex error
     scalFac[t1] = (PosDirCharge[t1]['position'][2]-newPos[2])/PosDirCharge[t1]['direction'][2]/PosDirCharge[t1]['momentum'].Mag()
     scalFac[t2] = (PosDirCharge[t2]['position'][2]-newPos[2])/PosDirCharge[t2]['direction'][2]/PosDirCharge[t2]['momentum'].Mag()
     HNLPos,covX,dist = self.VertexError(t1,t2,self.newPosDir,CovMat,scalFac)
# monitor Vx resolution and pulls
     #print "DEBUG",HNLPos[0],HNLPos[1],HNLPos[2],dist,covX[0][0],covX[1][1],covX[2][2]
     #print "     ",mctrack.GetStartX(),mctrack.GetStartY(),mctrack.GetStartZ()
#   HNL true
     if  self.sTree.GetBranch("fitTrack2MC"):
      mctrack = self.sTree.MCTrack[self.sTree.fitTrack2MC[t1]]
      mctrack2 = self.sTree.MCTrack[self.sTree.fitTrack2MC[t2]]
      mcHNL = self.sTree.MCTrack[mctrack.GetMotherId()]
      #print "true vtx: ",mctrack.GetStartX(),mctrack.GetStartY(),mctrack.GetStartZ()
      #print "reco vtx: ",HNLPos[0],HNLPos[1],HNLPos[2]
      #self.h['Vzpull'].Fill( (mctrack.GetStartZ()-HNLPos[2])/ROOT.TMath.Sqrt(covX[2][2]) )
      #self.h['Vxpull'].Fill( (mctrack.GetStartX()-HNLPos[0])/ROOT.TMath.Sqrt(covX[0][0]) )
      #self.h['Vypull'].Fill( (mctrack.GetStartY()-HNLPos[1])/ROOT.TMath.Sqrt(covX[1][1]) )
      #self.h['dVx'].Fill( (mctrack.GetStartX()-HNLPos[0]) )
      #self.h['dVy'].Fill( (mctrack.GetStartY()-HNLPos[1]) )
      #self.h['dVz'].Fill( (mctrack.GetStartZ()-HNLPos[2]) )
      
     
     #print "*********************************** vertex fit precise   ******************************************** "
     
     detPlane = ROOT.genfit.DetPlane(ROOT.TVector3(0,0,HNLPos[2]),ROOT.TVector3(1,0,0),ROOT.TVector3(0,1,0))
     plane = ROOT.genfit.RKTrackRep().makePlane(ROOT.TVector3(0,0,HNLPos[2]),ROOT.TVector3(1,0,0),ROOT.TVector3(0,1,0))
     st1  = fittedTracks[t1].getFittedState()
     st2  = fittedTracks[t2].getFittedState()
     try:
      st1.extrapolateToPlane(plane)
     except:
      ut.reportError("shipVertex::TwoTrackVertex: extrapolation does not worked")
      continue
     try:
      st2.extrapolateToPlane(plane)
     except:
      ut.reportError("shipVertex::TwoTrackVertex: extrapolation does not worked")
      continue
     mom1 = st1.getMom()
     mom2 = st2.getMom()
     cov1 = st1.getCov()
     cov2 = st2.getCov()
     cov = ROOT.TMatrixDSym(10)
     for i in range(10):
       for j in range(10):
	 if i<5 and j<5: cov[i][j]=cov1[i][j]
	 if i>4 and j>4: cov[i][j]=cov2[i-5][j-5]
     covInv = ROOT.TMatrixDSym()
     ROOT.genfit.tools.invertMatrix(cov,covInv)
     
     self.y_data = np.array([0.,0.,0.,0.,0.,0.,0.,0.,0.,0.])
     stVal1 = st1.getState()
     stVal2 = st2.getState()
     for i in range(5):
      self.y_data[i]=stVal1[i]
      self.y_data[i+5]=stVal2[i]
     self.z0 = HNLPos[2]
     self.Vy = np.zeros(100)
     for i in range(100):	
       self.Vy[i] = covInv[i/10][i%10]
     
     f=np.array([0.])
     gMinuit = ROOT.TMinuit(9)
     gMinuit.SetFCN(self.fcn)
     gMinuit.SetPrintLevel(-1)#minute quiet mode
     rc = gMinuit.DefineParameter(0, 'X pos',HNLPos[0], 0.1,0,0)
     rc = gMinuit.DefineParameter(1, 'Y pos',HNLPos[1], 0.1,0,0)
     rc = gMinuit.DefineParameter(2, 'Z pos',HNLPos[2], 0.1,0,0)
     rc = gMinuit.DefineParameter(3, 'tan1X',mom1[0]/mom1[2], 0.1,0,0)
     rc = gMinuit.DefineParameter(4, 'tan1Y',mom1[1]/mom1[2], 0.1,0,0)
     rc = gMinuit.DefineParameter(5, '1/mom1',1./mom1.Mag(), 0.1,0,0)
     rc = gMinuit.DefineParameter(6, 'tan2X',mom2[0]/mom2[2], 0.1,0,0)
     rc = gMinuit.DefineParameter(7, 'tan2Y',mom2[1]/mom2[2], 0.1,0,0)
     rc = gMinuit.DefineParameter(8, '1/mom2',1./mom2.Mag(), 0.1,0,0)
     gMinuit.Clear()
     gMinuit.Migrad()
     try:
      tmp = array('d',[0])
      err = array('i',[0])
      gMinuit.mnexcm( "HESSE", tmp, -1, err )
      #gMinuit.mnexcm( "MINOS", tmp, -1, err )
     except:
       ut.reportError("shipVertex::minos does not work")
       continue
     #get results from TMinuit:
     emat = array('d',[0,]*81)
     gMinuit.mnemat(emat,9)
     values = array('d',[0,]*9)
     errors = array('d',[0,]*9)
     dValue = ROOT.Double()
     dError = ROOT.Double()
     rc = gMinuit.GetParameter(0, dValue, dError)
     values[0]=dValue
     errors[0]=dError
     rc = gMinuit.GetParameter(1, dValue, dError)
     values[1]=dValue
     errors[1]=dError
     rc = gMinuit.GetParameter(2, dValue, dError)
     values[2]=dValue
     errors[2]=dError
     rc = gMinuit.GetParameter(3, dValue, dError)
     values[3]=dValue
     errors[3]=dError
     rc = gMinuit.GetParameter(4, dValue, dError)
     values[4]=dValue
     errors[4]=dError
     rc = gMinuit.GetParameter(5, dValue, dError)
     values[5]=dValue
     errors[5]=dError
     rc = gMinuit.GetParameter(6, dValue, dError)
     values[6]=dValue
     errors[6]=dError
     rc = gMinuit.GetParameter(7, dValue, dError)
     values[7]=dValue
     errors[7]=dError
     rc = gMinuit.GetParameter(8, dValue, dError)
     values[8]=dValue
     errors[8]=dError

     xFit = values[0]
     yFit = values[1]
     zFit = values[2]
     HNLPosFit =  ROOT.TVector3(xFit,yFit,zFit)
     xFitErr = errors[0]
     yFitErr = errors[1]
     zFitErr = errors[2]
     
     #fixme: mass from track reconstraction needed 
     m1 = self.PDG.GetParticle(PosDirCharge[t1]['pdgCode']).Mass()
     m2 = self.PDG.GetParticle(PosDirCharge[t2]['pdgCode']).Mass()
     
     #self.h['VxpullFit'].Fill( (mctrack.GetStartX()-xFit)/xFitErr )
     #self.h['VypullFit'].Fill( (mctrack.GetStartY()-yFit)/yFitErr )
     #self.h['VzpullFit'].Fill( (mctrack.GetStartZ()-zFit)/zFitErr )
     #self.h['dVxFit'].Fill( (mctrack.GetStartX()-xFit) )
     #self.h['dVyFit'].Fill( (mctrack.GetStartY()-yFit) )
     #self.h['dVzFit'].Fill( (mctrack.GetStartZ()-zFit) )
     
     def getP(fitValues,cov,m1,m2):
       a3=fitValues[3]
       a4=fitValues[4]
       a5=fitValues[5]
       a6=fitValues[6]
       a7=fitValues[7]
       a8=fitValues[8]
       px1 = a3/(a5*ROOT.TMath.Sqrt(1 + a3**2 + a4**2))
       py1 = a4/(a5*ROOT.TMath.Sqrt(1 + a3**2 + a4**2))
       pz1 = 1/(a5*ROOT.TMath.Sqrt(1 + a3**2 + a4**2))
       px2 = a6/(a8*ROOT.TMath.Sqrt(1 + a6**2 + a7**2))
       py2 = a7/(a8*ROOT.TMath.Sqrt(1 + a6**2 + a7**2))
       pz2 = 1/(a8*ROOT.TMath.Sqrt(1 + a6**2 + a7**2))
       Px = px1 + px2
       Py = py1 + py2
       Pz = pz1 + pz2
       E1 = ROOT.TMath.Sqrt(px1**2 + py1**2 + pz1**2 + m1**2)
       E2 = ROOT.TMath.Sqrt(px2**2 + py2**2 + pz2**2 + m2**2)
       M = ROOT.TMath.Sqrt(2*E1*E2+m1**2+m2**2-2*pz1*pz2*(1+a3*a6+a4*a7))
       MM = 2*M
       A5 = 1 + a3**2 + a4**2
       A8 = 1 + a6**2 + a7**2
       M_AtoP = ROOT.TMatrixD(4,6)
       MT_AtoP = ROOT.TMatrixD(6,4)
       covA = ROOT.TMatrixD(6,6)
       M_AtoP[0][0] = (1.-a3*a3/A5)/(a5*ROOT.TMath.Sqrt(A5))
       M_AtoP[0][1] = (-a3*a4/A5)/(a5*ROOT.TMath.Sqrt(A5))
       M_AtoP[0][2] = (-a3)/(a5*a5*ROOT.TMath.Sqrt(A5))
       M_AtoP[0][3] = (1.-a6*a6/A8)/(a8*ROOT.TMath.Sqrt(A8))
       M_AtoP[0][4] = (-a6*a7/A8)/(a8*ROOT.TMath.Sqrt(A8))
       M_AtoP[0][5] = (-a6)/(a8*a8*ROOT.TMath.Sqrt(A8))
       
       M_AtoP[1][0] = (-a3*a4/A5)/(a5*ROOT.TMath.Sqrt(A5))
       M_AtoP[1][1] = (1.-a4*a4/A5)/(a5*ROOT.TMath.Sqrt(A5))
       M_AtoP[1][2] = (-a4)/(a5*a5*ROOT.TMath.Sqrt(A5))
       M_AtoP[1][3] = (-a6*a7/A8)/(a8*ROOT.TMath.Sqrt(A8))
       M_AtoP[1][4] = (1.-a7*a7/A8)/(a8*ROOT.TMath.Sqrt(A8))
       M_AtoP[1][5] = (-a7)/(a8*a8*ROOT.TMath.Sqrt(A8))
       
       M_AtoP[2][0] = (-a3/A5)/(a5*ROOT.TMath.Sqrt(A5))
       M_AtoP[2][1] = (-a4/A5)/(a5*ROOT.TMath.Sqrt(A5))
       M_AtoP[2][2] = (-1.)/(a5*a5*ROOT.TMath.Sqrt(A5))
       M_AtoP[2][3] = (-a6/A8)/(a8*ROOT.TMath.Sqrt(A8))
       M_AtoP[2][4] = (-a7/A8)/(a8*ROOT.TMath.Sqrt(A8))
       M_AtoP[2][5] = (-1.)/(a8*a8*ROOT.TMath.Sqrt(A8))
       
       a5a8 = a5*a8*ROOT.TMath.Sqrt(A5)*ROOT.TMath.Sqrt(A8)
       
       M_AtoP[3][0] = (-2*a6/a5a8 + 2*a3*E2/(a5*a5*A5*E1))/MM
       M_AtoP[3][1] = (-2*a7/a5a8 + 2*a4*E2/(a5*a5*A5*E1))/MM
       M_AtoP[3][2] = (2*(1+a3*a6+a4*a7)/(a5*a5a8) - 2*(1.+a3*a3+a4*a4)*E2/(a5*a5*a5*A5*E1))/MM
       M_AtoP[3][3] = (-2*a3/a5a8 + 2*a6*E1/(a8*a8*A8*E2))/MM
       M_AtoP[3][4] = (-2*a4/a5a8 + 2*a7*E1/(a8*a8*A8*E2))/MM
       M_AtoP[3][5] = (2*(1+a3*a6+a4*a7)/(a8*a5a8) - 2*(1.+a6*a6+a7*a7)*E1/(a8*a8*a8*A8*E2))/MM
       
       for i in range(4):
	 for j in range(6):
	   MT_AtoP[j][i] = M_AtoP[i][j]
       
       for i in range(36):
	 covA[i/6][i%6] = cov[i/6+3+(i%6+3)*9]
       
       tmp   = ROOT.TMatrixD(4,6)
       tmp.Mult(M_AtoP,covA)
       covP  = ROOT.TMatrixD(4,4)
       covP.Mult(tmp,MT_AtoP)
       P = ROOT.TLorentzVector()
       P.SetXYZM(Px,Py,Pz,M)
       return P,covP
      
     P,covP = getP(values,emat,m1,m2)
     #print "******************************************************************************* "
     
     #create ship particle
     #notes:
     #P-TLorentzVector of fitted HNL prticle
     #covP - covariance matrix of HNL four-vector (Px,Py,Pz,M)
     #HNLPosFit - fited position of HNL
     #covV - comariance matrix of the vtx position
     covV = array('d',[emat[0],emat[1],emat[2],emat[1+9],emat[2+9],emat[2+2*9]])
     covP = array('d',[covP[0][0],covP[0][1],covP[0][2],covP[0][3],covP[1][1],covP[1][2],covP[1][3],covP[2][2],covP[2][3],covP[3][3]])
          
# try to make it persistent
     vx = ROOT.TLorentzVector(HNLPosFit,0)  # time at vertex still needs to be evaluated from time of tracks and time of flight
     particle = ROOT.ShipParticle(9900015,0,-1,-1,t1,t2,P,vx)
     particle.SetCovV(covV)
     particle.SetCovP(covP)
     particle.SetDoca(doca)
     nParts   = particles.GetEntries()
     particles[nParts] = particle
Example #9
0
 def TwoTrackVertex(self):
  self.fPartArray.Delete()
  fittedTracks = getattr(self.sTree,self.fitTrackLoc)
  if fittedTracks.GetEntries() < 2: return 
  particles    = self.fPartArray
  PosDirCharge,CovMat,scalFac = {},{},{}
  for tr in range(fittedTracks.GetEntries()):
   fitStatus = fittedTracks[tr].getFitStatus()
   if not fitStatus.isFitConverged(): continue
   nmeas = fitStatus.getNdf()
   chi2  = fitStatus.getChi2()/nmeas
   if chi2<50 and not chi2<0: 
      xx  = fittedTracks[tr].getFittedState()
      pid   = xx.getPDG()
      if not pidProton and abs(pid) == 2212:
        pid = int(ROOT.TMath.Sign(211,pid))
      rep   = ROOT.genfit.RKTrackRep(xx.getPDG())  
      state = ROOT.genfit.StateOnPlane(rep)
      rep.setPosMom(state,xx.getPos(),xx.getMom())
      PosDirCharge[tr] = {'position':xx.getPos(),'direction':xx.getDir(),\
                          'momentum':xx.getMom(),'charge':xx.getCharge(),'pdgCode':pid,'state':xx,'rep':rep,'newstate':state}
      CovMat[tr] = xx.get6DCov() 
#
  if len(PosDirCharge) < 2: return
  if len(PosDirCharge) > 4: return # abort too busy events
  for t1 in PosDirCharge:
   c1  = PosDirCharge[t1]['charge'] 
   for t2 in PosDirCharge:
     if not t2>t1: continue
     # ignore this for background studies 
     if PosDirCharge[t2]['charge'] == c1 : continue
     newPos,doca    = self.VertexError(t1,t2,PosDirCharge)
# as we have learned, need iterative procedure
# as we have learned, need iterative procedure
     dz = 99999.
     rc = True 
     step = 0
     while dz > 0.01:
      zBefore = newPos[2]
     # make a new rep for track 1,2
      for tr in [t1,t2]:     
       try:
        PosDirCharge[tr]['rep'].extrapolateToPoint(PosDirCharge[tr]['newstate'], newPos, False)
       except:
        # print 'SHiPReco: extrapolation did not worked'
        ut.reportError('SHiPReco: extrapolation did not worked')
        rc = False  
        break
       self.newPosDir[tr] = {'position':PosDirCharge[tr]['rep'].getPos(PosDirCharge[tr]['newstate']),\
                             'direction':PosDirCharge[tr]['rep'].getDir(PosDirCharge[tr]['newstate']),\
                             'momentum':PosDirCharge[tr]['rep'].getMom(PosDirCharge[tr]['newstate'])}
      if not rc: break
      newPos,doca = self.VertexError(t1,t2,self.newPosDir)
      dz = abs(zBefore-newPos[2])
      step+=1
      if step > 10:  
         print 'abort iteration, too many steps, pos=',newPos[0],newPos[1],newPos[2],' doca=',doca,'z before and dz',zBefore,dz
         rc = False
         break 
#       
     if not rc: continue # extrapolation failed, makes no sense to continue
# now go for the last step and vertex error
     scalFac[t1] = (PosDirCharge[t1]['position'][2]-newPos[2])/PosDirCharge[t1]['direction'][2]/PosDirCharge[t1]['momentum'].Mag()
     scalFac[t2] = (PosDirCharge[t2]['position'][2]-newPos[2])/PosDirCharge[t2]['direction'][2]/PosDirCharge[t2]['momentum'].Mag()
     HNLPos,covX,dist = self.VertexError(t1,t2,self.newPosDir,CovMat,scalFac)
# monitor Vx resolution and pulls
     #print "DEBUG",HNLPos[0],HNLPos[1],HNLPos[2],dist,covX[0][0],covX[1][1],covX[2][2]
     #print "     ",mctrack.GetStartX(),mctrack.GetStartY(),mctrack.GetStartZ()
#   HNL true
     if  self.sTree.GetBranch("fitTrack2MC"):
      mctrack = self.sTree.MCTrack[self.sTree.fitTrack2MC[t1]]
      self.h['Vzpull'].Fill( (mctrack.GetStartZ()-HNLPos[2])/ROOT.TMath.Sqrt(covX[2][2]) )
      self.h['Vxpull'].Fill( (mctrack.GetStartX()-HNLPos[0])/ROOT.TMath.Sqrt(covX[0][0]) )
      self.h['Vypull'].Fill( (mctrack.GetStartY()-HNLPos[1])/ROOT.TMath.Sqrt(covX[1][1]) )
#
     pid = PosDirCharge[t1]['pdgCode']
     mass = self.PDG.GetParticle(pid).Mass()
     mom  = self.newPosDir[t1]['momentum']
     E = ROOT.TMath.Sqrt( mass*mass + mom.Mag2() )
     self.LV[1].SetPxPyPzE(mom.x(),mom.y(),mom.z(),E)
     pid = PosDirCharge[t2]['pdgCode']
     mass = self.PDG.GetParticle(pid).Mass()
     mom  = self.newPosDir[t2]['momentum']
     E = ROOT.TMath.Sqrt( mass*mass + mom.Mag2() )
     self.LV[2].SetPxPyPzE(mom.x(),mom.y(),mom.z(),E)
     HNL = self.LV[1]+self.LV[2]
# try to make it persistent
     vx = ROOT.TLorentzVector(HNLPos,doca)  # misuse time as DOCA  
     particle = ROOT.TParticle(9900015,0,-1,-1,t1,t2,HNL,vx)
     particle.SetMother(1,99) # as marker to remember doca is set
     nParts   = particles.GetEntries()
     particles[nParts] = particle
Example #10
0
    def TwoTrackVertex(self):
        self.fPartArray.Delete()
        fittedTracks = getattr(self.sTree, self.fitTrackLoc)
        if fittedTracks.GetEntries() < 2: return
        particles = self.fPartArray
        PosDirCharge, CovMat, scalFac = {}, {}, {}
        for tr in range(fittedTracks.GetEntries()):
            fitStatus = fittedTracks[tr].getFitStatus()
            if not fitStatus.isFitConverged(): continue
            nmeas = fitStatus.getNdf()
            chi2 = fitStatus.getChi2() / nmeas
            if chi2 < 50 and not chi2 < 0:
                xx = fittedTracks[tr].getFittedState()
                pid = xx.getPDG()
                if not pidProton and abs(pid) == 2212:
                    pid = int(ROOT.TMath.Sign(211, pid))
                rep = ROOT.genfit.RKTrackRep(xx.getPDG())
                state = ROOT.genfit.StateOnPlane(rep)
                rep.setPosMom(state, xx.getPos(), xx.getMom())
                PosDirCharge[tr] = {'position':xx.getPos(),'direction':xx.getDir(),\
                                    'momentum':xx.getMom(),'charge':xx.getCharge(),'pdgCode':pid,'state':xx,'rep':rep,'newstate':state}
                CovMat[tr] = xx.get6DCov()
#
        if len(PosDirCharge) < 2: return
        if len(PosDirCharge) > 4: return  # abort too busy events
        for t1 in PosDirCharge:
            c1 = PosDirCharge[t1]['charge']
            for t2 in PosDirCharge:
                if not t2 > t1: continue
                # ignore this for background studies
                if PosDirCharge[t2]['charge'] == c1: continue
                newPos, doca = self.VertexError(t1, t2, PosDirCharge)
                # as we have learned, need iterative procedure
                # as we have learned, need iterative procedure
                dz = 99999.
                rc = True
                step = 0
                while dz > 0.01:
                    zBefore = newPos[2]
                    # make a new rep for track 1,2
                    for tr in [t1, t2]:
                        try:
                            PosDirCharge[tr]['rep'].extrapolateToPoint(
                                PosDirCharge[tr]['newstate'], newPos, False)
                        except:
                            # print 'SHiPReco: extrapolation did not worked'
                            ut.reportError(
                                'SHiPReco: extrapolation did not worked')
                            rc = False
                            break
                        self.newPosDir[tr] = {'position':PosDirCharge[tr]['rep'].getPos(PosDirCharge[tr]['newstate']),\
                                              'direction':PosDirCharge[tr]['rep'].getDir(PosDirCharge[tr]['newstate']),\
                                              'momentum':PosDirCharge[tr]['rep'].getMom(PosDirCharge[tr]['newstate'])}
                    if not rc: break
                    newPos, doca = self.VertexError(t1, t2, self.newPosDir)
                    dz = abs(zBefore - newPos[2])
                    step += 1
                    if step > 10:
                        print 'abort iteration, too many steps, pos=', newPos[
                            0], newPos[1], newPos[
                                2], ' doca=', doca, 'z before and dz', zBefore, dz
                        rc = False
                        break
#
                if not rc:
                    continue  # extrapolation failed, makes no sense to continue
                # now go for the last step and vertex error
                scalFac[t1] = (PosDirCharge[t1]['position'][2] -
                               newPos[2]) / PosDirCharge[t1]['direction'][
                                   2] / PosDirCharge[t1]['momentum'].Mag()
                scalFac[t2] = (PosDirCharge[t2]['position'][2] -
                               newPos[2]) / PosDirCharge[t2]['direction'][
                                   2] / PosDirCharge[t2]['momentum'].Mag()
                HNLPos, covX, dist = self.VertexError(t1, t2, self.newPosDir,
                                                      CovMat, scalFac)
                # monitor Vx resolution and pulls
                #print "DEBUG",HNLPos[0],HNLPos[1],HNLPos[2],dist,covX[0][0],covX[1][1],covX[2][2]
                #print "     ",mctrack.GetStartX(),mctrack.GetStartY(),mctrack.GetStartZ()
                #   HNL true
                if self.sTree.GetBranch("fitTrack2MC"):
                    mctrack = self.sTree.MCTrack[self.sTree.fitTrack2MC[t1]]
                    self.h['Vzpull'].Fill((mctrack.GetStartZ() - HNLPos[2]) /
                                          ROOT.TMath.Sqrt(covX[2][2]))
                    self.h['Vxpull'].Fill((mctrack.GetStartX() - HNLPos[0]) /
                                          ROOT.TMath.Sqrt(covX[0][0]))
                    self.h['Vypull'].Fill((mctrack.GetStartY() - HNLPos[1]) /
                                          ROOT.TMath.Sqrt(covX[1][1]))
#
                pid = PosDirCharge[t1]['pdgCode']
                mass = self.PDG.GetParticle(pid).Mass()
                mom = self.newPosDir[t1]['momentum']
                E = ROOT.TMath.Sqrt(mass * mass + mom.Mag2())
                self.LV[1].SetPxPyPzE(mom.x(), mom.y(), mom.z(), E)
                pid = PosDirCharge[t2]['pdgCode']
                mass = self.PDG.GetParticle(pid).Mass()
                mom = self.newPosDir[t2]['momentum']
                E = ROOT.TMath.Sqrt(mass * mass + mom.Mag2())
                self.LV[2].SetPxPyPzE(mom.x(), mom.y(), mom.z(), E)
                HNL = self.LV[1] + self.LV[2]
                # try to make it persistent
                vx = ROOT.TLorentzVector(HNLPos, doca)  # misuse time as DOCA
                particle = ROOT.TParticle(9900015, 0, -1, -1, t1, t2, HNL, vx)
                particle.SetMother(1, 99)  # as marker to remember doca is set
                nParts = particles.GetEntries()
                particles[nParts] = particle
Example #11
0
 def findTracks(self):
  hitPosLists    = {}
  stationCrossed = {}
  fittedtrackids=[]
  listOfIndices  = {}
  self.fGenFitArray.Clear()
  self.fTrackletsArray.Delete()
  self.fitTrack2MC.clear()

#   
  if withT0:  self.SmearedHits = self.withT0Estimate()
  # old procedure, not including estimation of t0 
  else:       self.SmearedHits = self.smearHits(withNoStrawSmearing)

  nTrack = -1
  trackCandidates = []
  
  if realPR:
    # Do real PatRec
    track_hits = shipPatRec.execute(self.SmearedHits, ShipGeo, realPR)
    # Create hitPosLists for track fit
    for i_track in track_hits.keys():
      atrack = track_hits[i_track]
      atrack_y12 = atrack['y12']
      atrack_stereo12 = atrack['stereo12']
      atrack_y34 = atrack['y34']
      atrack_stereo34 = atrack['stereo34']
      atrack_smeared_hits = list(atrack_y12) + list(atrack_stereo12) + list(atrack_y34) + list(atrack_stereo34)
      for sm in atrack_smeared_hits:
        detID = sm['detID']
        station = int(detID/10000000)
        trID = i_track
        # Collect hits for track fit
        if not hitPosLists.has_key(trID):
          hitPosLists[trID] = ROOT.std.vector('TVectorD')()
          listOfIndices[trID] = []
          stationCrossed[trID]  = {}
        m = array('d',[sm['xtop'],sm['ytop'],sm['z'],sm['xbot'],sm['ybot'],sm['z'],sm['dist']])
        hitPosLists[trID].push_back(ROOT.TVectorD(7,m))
        listOfIndices[trID].append(sm['digiHit'])
        if not stationCrossed[trID].has_key(station):
          stationCrossed[trID][station] = 0
        stationCrossed[trID][station] += 1
  else: # do fake pattern recognition
   for sm in self.SmearedHits:
    detID = self.digiStraw[sm['digiHit']].GetDetectorID()
    station = int(detID/10000000)
    trID = self.sTree.strawtubesPoint[sm['digiHit']].GetTrackID()
    if not hitPosLists.has_key(trID):   
      hitPosLists[trID]     = ROOT.std.vector('TVectorD')()
      listOfIndices[trID] = [] 
      stationCrossed[trID]  = {}
    m = array('d',[sm['xtop'],sm['ytop'],sm['z'],sm['xbot'],sm['ybot'],sm['z'],sm['dist']])
    hitPosLists[trID].push_back(ROOT.TVectorD(7,m))
    listOfIndices[trID].append(sm['digiHit'])
    if not stationCrossed[trID].has_key(station): stationCrossed[trID][station]=0
    stationCrossed[trID][station]+=1
#
   # for atrack in listOfIndices:
   #   # make tracklets out of trackCandidates, just for testing, should be output of proper pattern recognition
   #  nTracks   = self.fTrackletsArray.GetEntries()
   #  aTracklet  = self.fTrackletsArray.ConstructedAt(nTracks)
   #  listOfHits = aTracklet.getList()
   #  aTracklet.setType(3)
   #  for index in listOfIndices[atrack]:
   #    listOfHits.push_back(index)
#  
  for atrack in hitPosLists:
    if atrack < 0: continue # these are hits not assigned to MC track because low E cut
    pdg    = self.sTree.MCTrack[atrack].GetPdgCode()
    if not self.PDG.GetParticle(pdg): continue # unknown particle
    # pdg = 13
    meas = hitPosLists[atrack]
    nM = meas.size()
    if nM < 25 : continue                          # not enough hits to make a good trackfit 
    if len(stationCrossed[atrack]) < 3 : continue  # not enough stations crossed to make a good trackfit 
    if debug: 
       mctrack = self.sTree.MCTrack[atrack]
    # charge = self.PDG.GetParticle(pdg).Charge()/(3.)
    posM = ROOT.TVector3(0, 0, 0)
    momM = ROOT.TVector3(0,0,3.*u.GeV)
# approximate covariance
    covM = ROOT.TMatrixDSym(6)
    resolution = self.sigma_spatial
    if withT0: resolution = resolution*1.4 # worse resolution due to t0 estimate
    for  i in range(3):   covM[i][i] = resolution*resolution
    covM[0][0]=resolution*resolution*100.
    for  i in range(3,6): covM[i][i] = ROOT.TMath.Power(resolution / nM / ROOT.TMath.Sqrt(3), 2)
# trackrep
    rep = ROOT.genfit.RKTrackRep(pdg)
# smeared start state
    stateSmeared = ROOT.genfit.MeasuredStateOnPlane(rep)
    rep.setPosMomCov(stateSmeared, posM, momM, covM)
# create track
    seedState = ROOT.TVectorD(6)
    seedCov   = ROOT.TMatrixDSym(6)
    rep.get6DStateCov(stateSmeared, seedState, seedCov)
    theTrack = ROOT.genfit.Track(rep, seedState, seedCov)
    hitCov = ROOT.TMatrixDSym(7)
    hitCov[6][6] = resolution*resolution
    for m in meas:
      tp = ROOT.genfit.TrackPoint(theTrack) # note how the point is told which track it belongs to 
      measurement = ROOT.genfit.WireMeasurement(m,hitCov,1,6,tp) # the measurement is told which trackpoint it belongs to
      # print measurement.getMaxDistance()
      measurement.setMaxDistance(ShipGeo.strawtubes.InnerStrawDiameter/2.)
      # measurement.setLeftRightResolution(-1)
      tp.addRawMeasurement(measurement) # package measurement in the TrackPoint                                          
      theTrack.insertPoint(tp)  # add point to Track
   # print "debug meas",atrack,nM,stationCrossed[atrack],self.sTree.MCTrack[atrack],pdg
    trackCandidates.append([theTrack,atrack])
  
  for entry in trackCandidates:
#check
    atrack = entry[1]
    theTrack = entry[0]
    if not theTrack.checkConsistency():
     print 'Problem with track before fit, not consistent',atrack,theTrack
     continue
# do the fit
    try:  self.fitter.processTrack(theTrack) # processTrackWithRep(theTrack,rep,True)
    except: 
      if debug: print "genfit failed to fit track"
      error = "genfit failed to fit track"
      ut.reportError(error)
      continue
#check
    if not theTrack.checkConsistency():
     if debug: print 'Problem with track after fit, not consistent',atrack,theTrack
     error = "Problem with track after fit, not consistent"
     ut.reportError(error)
     continue
    try:
      fittedState = theTrack.getFittedState()
      fittedMom = fittedState.getMomMag()
    except:
      error = "Problem with fittedstate"
      ut.reportError(error)
      continue
    fitStatus   = theTrack.getFitStatus()
    nmeas = fitStatus.getNdf()   
    chi2        = fitStatus.getChi2()/nmeas   
    h['chi2'].Fill(chi2)
# make track persistent
    nTrack   = self.fGenFitArray.GetEntries()
    if not debug: theTrack.prune("CFL")  #  http://sourceforge.net/p/genfit/code/HEAD/tree/trunk/core/include/Track.h#l280 
    self.fGenFitArray[nTrack] = theTrack
    # self.fitTrack2MC.push_back(atrack)
    if debug: 
     print 'save track',theTrack,chi2,nmeas,fitStatus.isFitConverged()
    # Save MC link
    track_ids = []
    for index in listOfIndices[atrack]:
      ahit = self.sTree.strawtubesPoint[index]
      track_ids += [ahit.GetTrackID()]
    frac, tmax = self.fracMCsame(track_ids)
    self.fitTrack2MC.push_back(tmax)
    # Save hits indexes of the the fitted tracks
    nTracks   = self.fTrackletsArray.GetEntries()
    aTracklet  = self.fTrackletsArray.ConstructedAt(nTracks)
    listOfHits = aTracklet.getList()
    aTracklet.setType(1)
    for index in listOfIndices[atrack]:
      listOfHits.push_back(index)
  self.Tracklets.Fill()
  self.fitTracks.Fill()
  self.mcLink.Fill()
# debug 
  if debug:
   print 'save tracklets:' 
   for x in self.sTree.Tracklets:
    print x.getType(),x.getList().size()
  return nTrack+1