コード例 #1
0
gSystem.Load(hps_dst_path)

# import the modules used by HpsEvent i.e. HpsEvent,
# SvtTrack, EcalCluster ...
from ROOT import HpsEvent, SvtTrack

# Open the ROOT file
root_file = TFile(str(args.input))

# Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
# other colletions
tree = root_file.Get("HPS_Event")

# Create an HpsEvent object in order to read the TClonesArray
# collections
hps_event = HpsEvent()

# Get the HpsEvent branch from the TTree
b_hps_event = tree.GetBranch("Event")
b_hps_event.SetAddress(AddressOf(hps_event))

track_parameters = [0] * 5

# Loop over all events in the file
for entry in xrange(0, tree.GetEntries()):

    # Print the event number every 500 events
    if (entry + 1) % 500 == 0: print "Event " + str(entry + 1)

    # Read the ith entry from the tree.  This "fills" HpsEvent and allows
    # access to all collections
コード例 #2
0
def main():
    global beamEnergy
    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(description='PyRoot analysis demostrating the us of a DST.')
    parser.add_argument("dst_file",  help="ROOT DST file to process")
    parser.add_argument("-o", "--output",  help="Name of output pdf file")
    parser.add_argument("-m", "--mc",  help="is MonteCarlo")
    parser.add_argument("-p", "--pulser",  help="is Pulser")
    parser.add_argument("-e","--energy",help="beam energy")
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user 
    if args.output:
        output_file = args.output
    else: 
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to " 
        print output_file


    print "[ HPS ANALYSIS ]:  Output file is "+output_file
    isMC=False
    if args.mc:
        print  "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC=True


    isPulser=False
    if args.pulser:
        print  "[ HPS ANALYSIS ]: Setting to run from a pulser file"
        isPulser=True

    if args.energy : 
        print 'Setting beam energy to '+args.energy
        beamEnergy=float(args.energy)

    myhist=myHistograms(beamEnergy) 

#################################
#       Event Selection
################################
#clean up event first
#### nominal selection

    requireECalFiducial = False
    requireECalSuperFiducial = False # this is included as separate histograms now...leave false!
    positronMomentumFromPositionCut = False # this is included as separate histograms now...leave false!
    requireTopBottomCut = True
    requireLeftRightCut = True

    if isMC : 
        smearEnergy=False
        smearRes=0.05
        myhist.setSmearEnergy(smearEnergy,smearRes)


    L1Ele = True  # require L1 hit for Ele
    L1Pos = False # require L1 hit for Pos
    L6Ele = False  # require L1 hit for Ele
    L6Pos = False # require L1 hit for Pos
    trackKiller=True
    killInMomentum=False
    killInClusterPosition=False
    killInTrackSlope = True
#    effFileName='/u/br/mgraham/hps-analysis/TrackEfficiency/cop180_EfficiencyResults.root'
#    effDataName='h_Ecl_hps_005772_eleEff'
#    effMCName='h_Ecl_tritrig-NOSUMCUT_HPS-EngRun2015-Nominal-v5-0_eleEff'

    effFileName='/u/br/mgraham/hps-analysis/TrackEfficiency/cop180_midESum_TwoD-EfficiencyResults.root'
    effDataName='h_XvsY_hps_005772_eleEff'
    effMCName='h_XvsY_tritrig-NOSUMCUT_HPS-EngRun2015-Nominal-v5-0_eleEff'
    
    if isMC and trackKiller and killInClusterPosition : 
        effFile=ROOT.TFile(effFileName)
        print 'Getting data efficiency from '+effFileName 
        #    effData=getEffTH1(effFile,effDataName)
        #    effMC=getEffTH1(effFile,effMCName)
        effData=getEffTH2(effFile,effDataName)
        effMC=getEffTH2(effFile,effMCName)
        effData.Print("v")
        effMC.Print("v")
        effData.Divide(effMC)  # this will be the killing factor
        effData.Print("V")


    if isMC and trackKiller and killInTrackSlope: 
#        effSlopeFileName='/u/br/mgraham/hps-analysis/WABs/EmGamma-L1HitEfficiencyResults.root'
        effSlopeFileName='/u/home/mgraham/HPS-CODE/ANALYSIS/users/mgraham/TridentWABs2016/EmGamma-L1HitEfficiencyResults-2016.root'
        effRatioName='p2slopehps_007963.1GamEm_L1HitInefficiency'
        effSlopeFile=ROOT.TFile(effSlopeFileName)
        effSlopeFile.ls()
        effSlopeData=getEffTH1(effSlopeFile,effRatioName)
        effSlopeData.Print("v")
        print 'L1 Hit Efficiency vs Slope:  MC' 
        fixTH1EffBins(effSlopeData) 


     # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    #use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from "+args.dst_file
    tree=ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file)+"*")    
    # Create an HpsEvent object in order to read the TClonesArray 
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))

    #--- Analysis ---#
    #----------------#

    #counters
    nEvents=0
    nPassBasicCuts=0
    

    
#   //================ Time coincidence ======================================
    coincide_pars_mean = [0.289337,   -2.81998,   9.03475, -12.93,   8.71476,   -2.26969]
    coincide_pars_sigm = [4.3987,   -24.2371,   68.9567, -98.2586,   67.562,   -17.8987]
   
    formula_pol5 = "[0] + x*( [1] + x*( [2] + x*( [3] + x*( [4] + x*( [5] ) ) ) ) ) "
    f_coincide_clust_mean = ROOT.TF1("f_coincide_clust_mean", formula_pol5, 0., 1.4)
    f_coincide_clust_sigm = ROOT.TF1("f_coincide_clust_sigm", formula_pol5, 0., 1.4)
    f_coincide_clust_mean.SetParameters(np.array(coincide_pars_mean))
    f_coincide_clust_sigm.SetParameters(np.array(coincide_pars_sigm))
#   //The cut is            === mean - 3sigma < dt < mean + 3sigma ===

    clTimeMin = 30
    clTimeMax = 50

    if beamEnergy == 2.3 : 
        clTimeMin = 40
        clTimeMax = 65
    energyRatio=beamEnergy/1.05 #ratio of beam energies references to 1.05 GeV (2015 run)
        
    print("Total number of events in tree = "+str(tree.GetEntries()))
    seedCnt=0
    # Loop over all events in the file
    for entry in xrange(0, tree.GetEntries()) : 
                 
        # Print the event number every 500 events
        if (entry+1)%100 == 0 : print "Event " + str(entry+1)
        tree.GetEntry(entry)
        if not hps_event.isPair1Trigger() and not isMC and not isPulser: continue
        nEvents+=1
       
      
        nPassBasicCuts+=1
#        print "passed basic cuts"
        pairList=[]
        bestCandidate=-99
        pairsFound=0
        for  i in range(0,hps_event.getNumberOfEcalClusters()) :
            cl1=hps_event.getEcalCluster(i)
            cl1Position=cl1.getPosition()
            cl_xi=cl1Position[0]
            cl_yi=cl1Position[1]
            cl_zi=cl1Position[2]
            cl_ti=cl1.getClusterTime()
            cl_Ei=cl1.getEnergy()
            myhist.h_clTime1vsclE.Fill(cl_Ei,cl_ti)
            cl_di = math.sqrt( (cl_xi - phot_nom_x)*(cl_xi - phot_nom_x) + cl_yi*cl_yi )       
#            print 'looking at clusters' 
            #if(!fid_ECal(cl_xi,cl_yi))
            #        continue            
            if requireECalFiducial and not myhist.inFiducialRegion(cl_xi, cl_yi)  :
                continue
            if requireECalSuperFiducial and not myhist.inSuperFiducialRegion(cl_xi, cl_yi)  :
                continue
            if not (cl_ti > clTimeMin and cl_ti < clTimeMax ):
                continue
            if positronMomentumFromPositionCut and not myhist.momFromPositionEclUpperCut(cl_Ei,myhist.momFromECalPosition(cl_xi,cl_zi,beamAngle,myhist.BEff)) : 
                continue
#            print 'Found first good cluster'
            for  j in range(i+1,hps_event.getNumberOfEcalClusters()) :
                cl2=hps_event.getEcalCluster(j)
                cl2Position=cl2.getPosition()
                cl_xj=cl2Position[0]
                cl_yj=cl2Position[1]
                cl_zj=cl2Position[2]
                cl_tj=cl2.getClusterTime()
                cl_Ej=cl2.getEnergy()

                cl_dj =math.sqrt( (cl_xj - phot_nom_x)*(cl_xj - phot_nom_x) + cl_yj*cl_yj )
                Esum = cl_Ei + cl_Ej
                if  requireECalFiducial and not myhist.inFiducialRegion(cl_xj,cl_yj): 
                    continue
                if  requireECalSuperFiducial and not myhist.inSuperFiducialRegion(cl_xj,cl_yj): 
                    continue
                if not (cl_tj > clTimeMin and cl_tj < clTimeMax ):
                    continue
                if positronMomentumFromPositionCut and not myhist.momFromPositionEclUpperCut(cl_Ej,myhist.momFromECalPosition(cl_xj,cl_zj,beamAngle,myhist.BEff)) : 
                    continue
#                print 'Passed the probable positron cut'
                                
                myhist.h_clTime1vsclTime2.Fill(cl_ti,cl_tj)

                dt = cl_ti - cl_tj
#                delt_t_mean = f_coincide_clust_mean.Eval(Esum)
#                delt_t_sigm = f_coincide_clust_sigm.Eval(Esum) 
#      divide by 2 since these parameters were extracted from 1.05GeV Data (this is kludgy!)    
                delt_t_mean = f_coincide_clust_mean.Eval(Esum/energyRatio)
                delt_t_sigm = f_coincide_clust_sigm.Eval(Esum/energyRatio)         
                if not  (dt < delt_t_mean + 3*delt_t_sigm and dt > delt_t_mean - 3*delt_t_sigm) :
                    continue
#         //make sure they are top/bottom
#                print 'Passed the timing cut' 
#                print str(cl_yi)+"   " + str(cl_yj)
                if requireTopBottomCut and cl_yi*cl_yj>0 :
                    continue

                if requireLeftRightCut and cl_xi*cl_xj>0 :
                    continue

#                print 'Found a pair!!!!' 

                clpair=[cl1,cl2]
                pairList.append(clpair)
                                
        pairsFound+=len(pairList)
#        if len(pairList) >0 : print "found this many pairs "+str(len(pairList))

        fspList=[]
        for i in xrange(0, hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE)):
            fspList.append( hps_event.getParticle(HpsParticle.FINAL_STATE_PARTICLE,i))

      
        #########################        
        #   found some candidates...lets fill plots...
        #########################        
        removeL1HitEle=False
        removeL1HitPos=False
        for pair in pairList : 
            if pair[0].getPosition()[1] >0 :
                clTop=pair[0]
                clBottom=pair[1]
            else :
                clTop=pair[1]
                clBottom=pair[0]
            clTopPosition=clTop.getPosition()
            clBottomPosition=clBottom.getPosition()

            topX=clTopPosition[0]
            topY=clTopPosition[1]
            topZ=clTopPosition[2]
            botX=clBottomPosition[0]
            botY=clBottomPosition[1]
            botZ=clBottomPosition[2]
            topE=clTop.getEnergy()
            botE=clBottom.getEnergy()
            Esum=topE+botE
            Ediff=abs(topE-botE)
            cl_impact_angleTop = math.atan2(topY, topX - phot_nom_x)*radian
            cl_impact_angleBottom = math.atan2(botY,botX - phot_nom_x)*radian
            if cl_impact_angleTop < 0. :
                cl_impact_angleTop = cl_impact_angleTop + 360. 
            if cl_impact_angleBottom < 0. :
                cl_impact_angleBottom = cl_impact_angleBottom + 360.
            coplanarity=  cl_impact_angleBottom -  cl_impact_angleTop  
            myhist.h_coplan_Esum1.Fill(Esum,coplanarity)

                
#            cl_d_top= math.sqrt( (topX - phot_nom_x)*(topX - phot_nom_x) + topY*topY )- (60. + 100*(topE - 0.85)*(topE - 0.85) )       
#            cl_d_bottom= math.sqrt( (botX - phot_nom_x)*(botX - phot_nom_x) + botY*botY )- (60. + 100*(botE - 0.85)*(botE - 0.85) )       
            
            #do track matching
            trTop=ecalMatchTrack(fspList,clTop)
            trBottom=ecalMatchTrack(fspList,clBottom)
            #initial PDG assignments
            trEle=trTop
            trPos=trBottom
            clEle=clTop
            clPos=clBottom

            if topX > 0 : #assign the ele & pos with respect to the side of ECAL the cluster is on  
                trEle=trBottom
                clEle=clBottom
                trPos=trTop
                clPos=clTop
            
            if trEle is not None and trEle.getPDG() == -11 :# whoops, it's a positron
                trEle=trBottom
                trPos=trTop
                clEle=clBottom
                clPos=clTop
#            if trPos is not None and trPos.getPDG() == 11 : # whoops, it's an electron
#                trEle=trBottom
#                trPos=trTop
#                clEle=clBottom
#                clPos=clTop
                #for ++ or -- events, this will get flipped twice...live with it...
                

            if topY*botY >0 : 
                print "both clusters in same half?? How could this happen?"+str(topY)+" vs "+str(botY)

            if trackKiller and isMC: 
                if killInMomentum : 
                    p=clEle.getEnergy()
                    bin=effData.FindBin(p)                    
                    tkEff=effData.GetBinContent(bin)
                    print str(p)+ ' '+str(bin)+' '+str(tkEff)
                    if random.random()>tkEff  :  #high ratio of efficiencies, this hardly  kills...low, kills a lot
                        print "REJECTING THIS ELECTRON TRACK!!! "+str(p)
                        trEle=None 
                #### same thing for positron side
                    p=clPos.getEnergy()
                    bin=effData.FindBin(p)                    
                    tkEff=effData.GetBinContent(bin)
                    print str(p)+' '+str(bin)+' '+str(tkEff)
                    if random.random()>tkEff  :  #high ratio of efficiencies, this hardly  kills...low, kills a lot
                        print "REJECTING THIS ELECTRON TRACK!!! "+str(p)
                        trPos=None
                if killInClusterPosition:  
                    clX=clEle.getPosition()[0]
                    clY=clEle.getPosition()[1]
                    bin=effData.FindBin(clX,clY)
                    tkEff=effData.GetBinContent(bin)
                    if random.random()>tkEff  and tkEff!=0.0:  
                        print str(clX)+ ' '+str(clY)+' '+str(bin)+' '+str(tkEff)
                        print "REJECTING THIS ELECTRON TRACK!!! "+str(clX)
                        trEle=None
                    clX=clPos.getPosition()[0]
                    clY=clPos.getPosition()[1]
                    bin=effData.FindBin(-clX+80,clY) # flip sign +80mm for positron side (this isn't strictly correct)!!!
                    tkEff=effData.GetBinContent(bin)                    
                    if random.random()>tkEff and tkEff!=0.0  :  
                        print str(clX)+ ' '+str(clY)+' '+str(bin)+' '+str(tkEff)
                        print "REJECTING THIS POSITRON TRACK!!! "+str(clX)
                        trPos=None

                if killInTrackSlope: 
                    if trEle is not None and len(trEle.getTracks())>0: 
#                        print("found an electron...kill it!!!")
                        trk=trEle.getTracks()[0]
                        nHits=len(trk.getSvtHits())
                        slp=trk.getTanLambda()
                        rndm=random.random()            
                        ibin=effSlopeData.FindBin(slp)
                        eff=1-effSlopeData.GetBinContent(ibin) #the slope "efficiency" is actually an inefficiency                        
#                        print(str(rndm)+"    "+str(eff))
                        if rndm>eff: 
                            if nHits==5: 
                                print('Removing this electron  due to L1 inefficiency')
                                trEle=None
                            else :                            
                                print(' Removing this electron L1 hit due to inefficiency')
                                removeL1HitEle=True
                    if trPos is not None and  len(trPos.getTracks())>0: 
#                        print("found an positron...kill it!!!")
                        trk=trPos.getTracks()[0]
                        nHits=len(trk.getSvtHits())
                        slp=trk.getTanLambda()
                        rndm=random.random()            
                        ibin=effSlopeData.FindBin(slp)
                        eff=1-effSlopeData.GetBinContent(ibin) #the slope "efficiency" is actually an inefficiency                        
#                        print(str(rndm)+"    "+str(eff))
                        if rndm>eff: 
                            if nHits==5: 
                                print('Removing this positron due to L1 inefficiency')
                                trPos=None
                            else :                            
                                print('Removing this positron L1 hit due to inefficiency')
                                removeL1HitPos=True


#require layer 1
            if L1Ele and (not myhist.hasL1Hit(trEle) or removeL1HitEle):
                trEle=None
            if L1Pos and (not myhist.hasL1Hit(trPos) or removeL1HitPos):
                trPos=None
#require layer 6
            if L6Ele and not myhist.hasLXHit(trEle,6):
                trEle=None
            if L6Pos and not myhist.hasLXHit(trPos,6):
                trPos=None

            myhist.fillBand("_copAll_",trEle,clEle,trPos,clPos)
            
            if abs(coplanarity-180)<10 :                
                #  some debugging here...
                #  for events where there is a positron track and no electron track
                #  check to see if there maybe is a track that's could be associated with this clus
                if trEle is None and trPos is not None and trPos.getCharge()>0 : 
                    nMatchEle=0;
                    print 'found positron but not electron!  ele energy = '+str(clEle.getEnergy())+'; ele clX = '+str(clEle.getPosition()[0])+'; ele clY = '+str(clEle.getPosition()[1])
                    #loop through the electrons in event and check to see if on is in the same half
                    for fsp_n in xrange(0, hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE)) :            
                        fsp = hps_event.getParticle(HpsParticle.FINAL_STATE_PARTICLE,fsp_n)
                        if fsp.getType() !=0 : 
                            if  fsp.getType() > 32  : continue
                            track=fsp.getTracks()[0]
                            slope=track.getTanLambda()
                            if fsp.getCharge()<0 and slope*clEle.getPosition()[1]>0 and pMag(fsp.getMomentum())<0.8 : 
                                nMatchEle=nMatchEle+1
                                print 'found and electron in right half!!'
                                print 'track p = '+str(pMag(fsp.getMomentum())) 
                                trkAtEcal=track.getPositionAtEcal()
                                delX=trkAtEcal[0]-clEle.getPosition()[0]
                                delY=trkAtEcal[1]-clEle.getPosition()[1]
                                print 'trk-clEle delX = '+str(delX)+'; delY = '+str(delY)
                                myhist.h_misEle_delXvsdelY.Fill(delX,delY)
                                myhist.h_misEle_trkPvsclE.Fill(pMag(fsp.getMomentum()),clEle.getEnergy())
                                if len(fsp.getClusters())>0 : 
                                    clThisE=fsp.getClusters()[0]
                                    print '...this track matched to cluster with ele energy = '+str(clThisE.getEnergy())+'; ele clX = '+str(clThisE.getPosition()[0])+'; ele clY = '+str(clThisE.getPosition()[1])
########################                    
                    myhist.h_misEle_eleTrks.Fill(nMatchEle)
                myhist.fillBand("_cop180_",trEle,clEle,trPos,clPos)
                if Esum>myhist.midESumLow and Esum<myhist.midESumHigh :
                    myhist.fillBand("_cop180_midESum_",trEle,clEle,trPos,clPos)
                    if myhist.inSuperFiducialRegion(topX,topY) and myhist.inSuperFiducialRegion(botX,botY):
                        myhist.fillBand("_cop180_midESum_SuperFid",trEle,clEle,trPos,clPos)  
                    if not myhist.inSuperFiducialRegion(topX,topY) and not myhist.inSuperFiducialRegion(botX,botY):
                        myhist.fillBand("_cop180_midESum_AntiSuperFid",trEle,clEle,trPos,clPos)
                if myhist.inSuperFiducialRegion(topX,topY) and myhist.inSuperFiducialRegion(botX,botY):
                    myhist.fillBand("_cop180_SuperFid",trEle,clEle,trPos,clPos)  
                    if not myhist.inPhotonHole(topX,topY) and not myhist.inPhotonHole(botX,botY) : 
                        myhist.fillBand("_cop180_SuperFid_CutPhotons",trEle,clEle,trPos,clPos)  
                if not myhist.inSuperFiducialRegion(topX,topY) and not myhist.inSuperFiducialRegion(botX,botY):
                    myhist.fillBand("_cop180_AntiSuperFid",trEle,clEle,trPos,clPos)                      
                if Ediff<0.2 and len(pairList)==1: 
                    myhist.fillBand("_cop180_Holly_",trEle,clEle,trPos,clPos)
                if not myhist.inPhotonHole(topX,topY) and not myhist.inPhotonHole(botX,botY) : 
                    myhist.fillBand("_cop180_CutPhotons",trEle,clEle,trPos,clPos)  
            elif abs(coplanarity-160)<10 :                 
                myhist.fillBand("_cop160_",trEle,clEle,trPos,clPos)
                if Esum>myhist.midESumLow and Esum<myhist.midESumHigh :
                    myhist.fillBand("_cop160_midESum_",trEle,clEle,trPos,clPos)
                if myhist.inSuperFiducialRegion(topX,topY) and myhist.inSuperFiducialRegion(botX,botY):
                    myhist.fillBand("_cop160_SuperFid",trEle,clEle,trPos,clPos)  
#                    if  myhist.momFromPositionEclUpperCut(topE,myhist.momFromECalPosition(topX,topZ,beamAngle,myhist.BEff)) and myhist.momFromPositionEclUpperCut(botE,myhist.momFromECalPosition(botX,botZ,beamAngle,myhist.BEff)): 
                    if not myhist.inPhotonHole(topX,topY) and not myhist.inPhotonHole(botX,botY) : 
                        myhist.fillBand("_cop160_SuperFid_CutPhotons",trEle,clEle,trPos,clPos)  
#                if  myhist.momFromPositionEclUpperCut(topE,myhist.momFromECalPosition(topX,topZ,beamAngle,myhist.BEff)) and myhist.momFromPositionEclUpperCut(botE,myhist.momFromECalPosition(botX,botZ,beamAngle,myhist.BEff)): 
                if not myhist.inPhotonHole(topX,topY) and not myhist.inPhotonHole(botX,botY) : 
                    myhist.fillBand("_cop160_CutPhotons",trEle,clEle,trPos,clPos)  
            


#            particle = hps_event.getParticle(HpsParticle.TC_V0_CANDIDATE, candidateList[index])
#            myhist.fillCandidateHistograms(particle)
          
            

#    if(nPassTrkCuts>0): 
    print "******************************************************************************************"
    myhist.saveHistograms(output_file)   
#    sys.exit(0)
    print "***   Returning ****"
    return
コード例 #3
0
def main():

    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(
        description='PyRoot analysis demostrating the us of a DST.')
    parser.add_argument("dst_file", help="ROOT DST file to process")
    parser.add_argument("-o", "--output", help="Name of output pdf file")
    parser.add_argument("-m", "--mc", help="is MonteCarlo")
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user
    if args.output:
        output_file = args.output
    else:
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to "
        print output_file

    print "[ HPS ANALYSIS ]:  Output file is " + output_file
    isMC = False
    if args.mc:
        print "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC = True

    # Load the HpsEvent library.  In this example, this is done by finding the
    # path to the HpsEvent shared library via the environmental variable
    # HPS_DST_PATH.  The HPS_DST_PATH environmental variable points to the
    # location of the build directory containing all binaries and libraries.
    # In general, the location of the library can be anywhere a user wants it
    # to be as long as the proper path is specified.
    if os.getenv('HPS_DST_PATH') is None:
        print "[ HPS ANALYSIS ]: Error! Environmental variable HPS_DST_HOME is not set."
        print "\n[ HPS ANALYSIS ]: Exiting ..."
        sys.exit(2)

    hps_dst_path = os.environ['HPS_DST_PATH']
    hps_dst_path += "/build/lib/libHpsEvent.so"
    print "Loading HpsEvent Library from " + hps_dst_path
    # Load the library in ROOT
    import ROOT
    ROOT.gSystem.Load(hps_dst_path)

    # import the modules used by HpsEvent i.e. HpsEvent,
    # SvtTrack, EcalCluster ...
    from ROOT import HpsEvent, SvtTrack, GblTrack, EcalCluster, EcalHit, TChain, TTree, HpsParticle

    #################################
    #       Event Selection
    ################################
    ebeam = 1.05
    #clean up event first
    nTrkMax = 5
    nPosMax = 2
    # vertex quality cuts for vertexing
    v0Chi2 = 10.0
    v0PzMax = 1.2
    v0PzMin = 0.8
    v0PyMax = 0.2  #absolute value
    v0PxMax = 0.2  #absolute value
    v0VyMax = 1.0  # mm from target
    v0VxMax = 2.0  # mm from target
    #  track quality cuts
    trkChi2 = 20.0
    #    trkChi2=100.0
    beamCut = 0.8
    isoCut = 1.0
    minPCut = 0.25
    trkPyMax = 0.2
    trkPxMax = 0.2
    slopeCut = 0.0
    z0Cut = 0.5

    ##############
    #  ESum slices; upper limits
    nSlicesESum = 5
    esumMin = 0.55
    esumMax = 1.2
    sliceSizeESum = 0.1  #100MeV starting at esumMin
    ##############
    trackKiller = False
    tkEnergy = 0.3
    tkEff = 0.75

    ##############
    requireECalMatch = True
    useGBL = True

    # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    #use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from " + args.dst_file
    tree = ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file) + "*")

    # Create an HpsEvent object in order to read the TClonesArray
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))

    # Get the HpsEvent branch from the TTree
    #    b_hps_event = tree.GetBranch("Event")
    #    b_hps_event.SetAddress(ROOT.AddressOf(hps_event))

    #--- Analysis ---#
    #----------------#

    #counters
    nEvents = 0
    nPassBasicCuts = 0
    nPassESumCuts = 0
    nPassV0Cuts = 0
    nPassTrkCuts = 0
    nPassIsoCuts = 0
    nPassNCand = 0
    nPassECalMatch = 0
    myhist = myHistograms()
    for entry in xrange(0, tree.GetEntries()):
        # Print the event number every 500 events
        if (entry + 1) % 10000 == 0: print "Event " + str(entry + 1)
        tree.GetEntry(entry)
        if not hps_event.isPair1Trigger() and not isMC: continue
        nEvents += 1
        # Loop over all tracks in the event
        npositrons = 0
        n_tracks = 0
        for track_n in xrange(0, hps_event.getNumberOfTracks()):
            track = hps_event.getTrack(track_n)
            if track is None:
                continue
#            if not (useGBL ^ track.type<32)  : continue
            n_tracks += 1
            if track.getCharge() > 0:
                npositrons += 1

#        print "nTracks = "+str(n_tracks)+"; nPositrons = "+str(npositrons)
        if n_tracks > nTrkMax: continue
        if n_tracks < 2: continue
        if npositrons < 1 or npositrons > nPosMax: continue
        nPassBasicCuts += 1
        #        print "passed basic cuts"
        candidateList = []
        bestCandidate = -99
        nCandidate = 0
        # loop over all v0 candidates...
        for bsc_index in xrange(
                0,
                hps_event.getNumberOfParticles(HpsParticle.BSC_V0_CANDIDATE)):
            particle = hps_event.getParticle(HpsParticle.BSC_V0_CANDIDATE,
                                             bsc_index)
            if useGBL and particle.getType() < 32: continue
            if not useGBL and particle.getType() > 31: continue
            # Only look at particles that have two daugther particles...
            daughter_particles = particle.getParticles()
            if daughter_particles.GetSize() != 2: continue
            # Only look at particles that are composed of e+e- pairs
            if daughter_particles.At(0).getCharge() * daughter_particles.At(
                    1).getCharge() > 0:
                continue
            #            print "Passed daughter number cuts"

            electron = daughter_particles.At(0)
            positron = daughter_particles.At(1)

            if daughter_particles.At(0).getCharge() > 0:
                electron = daughter_particles.At(1)
                positron = daughter_particles.At(0)

            pEle = electron.getMomentum()
            pPos = positron.getMomentum()

            v0Sum = pMag(pSum(pEle, pPos))

            if v0Sum > v0PzMax: continue
            if v0Sum < v0PzMin: continue
            nPassESumCuts += 1

            vchi2 = particle.getVertexFitChi2()
            vposition = particle.getVertexPosition()
            vmomentum = particle.getMomentum()
            if vchi2 > v0Chi2: continue

            if abs(vposition[0]) > v0VxMax: continue
            if abs(vposition[1]) > v0VyMax: continue

            nPassV0Cuts += 1

            #            print "Passed v0 cuts"

            if pMag(pEle) > beamCut or pMag(pPos) > beamCut: continue
            if pMag(pEle) < minPCut or pMag(pPos) < minPCut: continue
            if pEle[1] * pPos[1] > 0: continue

            #            print particle.getTracks().At(0).GetEntries()

            #            eleTrk=GblTrack(particle.getTracks().At(0))
            #            posTrk=GblTrack(particle.getTracks().At(1))

            #            if eleTrk.getCharge()>0 :
            #                eleTrk=GblTrack(particle.getTracks().At(1))
            #                posTrk=GblTrack(particle.getTracks().At(0))

            eleTrk = electron.getTracks().At(0)
            posTrk = positron.getTracks().At(0)

            if eleTrk.getChi2() > trkChi2 or posTrk.getChi2() > trkChi2:
                continue

            if abs(eleTrk.getZ0()) > z0Cut or abs(posTrk.getZ0()) > z0Cut:
                continue


#            if abs(eleTrk.getTanLambda())<slopeCut or abs(posTrk.getTanLambda())<slopeCut :
#                continue

            if isMC and trackKiller:
                if pMag(pEle) < tkEnergy and random.random() > tkEff:
                    continue

            nPassTrkCuts += 1
            if requireECalMatch:
                if positron.getClusters().GetEntries() == 0:
                    continue
                if electron.getClusters().GetEntries() == 0:
                    continue
            nPassECalMatch += 1

            if abs(eleTrk.getIsolation(0)) < isoCut or abs(
                    eleTrk.getIsolation(1)) < isoCut:
                continue
            if abs(posTrk.getIsolation(0)) < isoCut or abs(
                    posTrk.getIsolation(1)) < isoCut:
                continue
            nPassIsoCuts += 1
            #Passed the cuts..append the candidate index
            candidateList.append(bsc_index)

        #########################
        #   found some candidates...lets fill plots...
        #########################
        for index in range(0, len(candidateList)):
            particle = hps_event.getParticle(HpsParticle.BSC_V0_CANDIDATE,
                                             candidateList[index])
            ucparticle = hps_event.getParticle(HpsParticle.UC_V0_CANDIDATE,
                                               candidateList[index])
            myhist.fillCandidateHistograms(particle, ucparticle)

    if nPassIsoCuts > 0:
        myhist.saveHistograms(output_file)

    print "\t\t\tTrident Selection Summary"
    print "******************************************************************************************"
    print "Number of Events:\t\t", nEvents, "\t\t\t", float(
        nEvents) / nEvents, "\t\t\t", float(nEvents) / nEvents
    print "N(particle) Cuts:\t\t", nPassBasicCuts, "\t\t\t", float(
        nPassBasicCuts) / nEvents, "\t\t\t", float(nPassBasicCuts) / nEvents
    print "ESum        Cuts:\t\t", nPassESumCuts, "\t\t\t", float(
        nPassESumCuts) / nPassBasicCuts, "\t\t\t", float(
            nPassESumCuts) / nEvents
    print "V0 Vertex   Cuts:\t\t", nPassV0Cuts, "\t\t\t", float(
        nPassV0Cuts) / nPassESumCuts, "\t\t\t", float(nPassV0Cuts) / nEvents
    print "Tracking    Cuts:\t\t", nPassTrkCuts, "\t\t\t", float(
        nPassTrkCuts) / nPassV0Cuts, "\t\t\t", float(nPassTrkCuts) / nEvents
    print "ECal Match  Cuts:\t\t", nPassECalMatch, "\t\t\t", float(
        nPassECalMatch) / nPassTrkCuts, "\t\t\t", float(
            nPassECalMatch) / nEvents
    print "Isolation    Cuts:\t\t", nPassIsoCuts, "\t\t\t", float(
        nPassIsoCuts) / nPassECalMatch, "\t\t\t", float(nPassIsoCuts) / nEvents
コード例 #4
0
ファイル: wabAnalysis.py プロジェクト: JeffersonLab/HPS-CODE
def main():
    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(description='PyRoot analysis demostrating the us of a DST.')
    parser.add_argument("dst_file",  help="ROOT DST file to process")
    parser.add_argument("-o", "--output",  help="Name of output pdf file")
    parser.add_argument("-m", "--mc",  help="is MonteCarlo")
    parser.add_argument("-p", "--pulser",  help="is Pulser")
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user 
    if args.output:
        output_file = args.output
    else: 
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to " 
        print output_file


    print "[ HPS ANALYSIS ]:  Output file is "+output_file
    isMC=False
    if args.mc:
        print  "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC=True


    isPulser=False
    if args.pulser:
        print  "[ HPS ANALYSIS ]: Setting to run from a pulser file"
        isPulser=True




#################################
#       Event Selection
################################
#clean up event first
#### nominal selection
    nTrkMax=10
    nTrkMin=2
    nPosMax=3
######  two tracks (e+/e-) exactly
#    nTrkMax=2
#    nTrkMin=2
#    nPosMax=1
###### more than 1 electron
#    nTrkMax=10
#    nTrkMin=3
#    nPosMax=1
###################
    #v0 cuts   
    v0Chi2=10
    #ESum -- full region
    v0PzMax=1.2
    v0PzMin=0.55
    #ESum -- Radiative region
#    v0PzMax=1.2
#    v0PzMin=0.80

    v0PyMax=0.2 #absolute value
    v0PxMax=0.2 #absolute value
    v0VzMax=25.0# mm from target
    v0VyMax=1.0# mm from target
    v0VxMax=2.0# mm from target
 #  track quality cuts
    trkChi2=10
    beamCut=0.8
    minPCut=0.05
    trkPyMax=0.2
    trkPxMax=0.2
#    slopeCut=0.03
    slopeCut=0.0
    trkDeltaT=4#ns
    cluDeltaT=2#ns
    cluTrkDeltaT=4#ns
##############
#  ESum slices; upper limits    
    nSlicesESum=5 
    esumMin=0.55
    esumMax=1.2
    sliceSizeESum=0.1 #100MeV starting at esumMin
##############
    trackKiller=False
    tkThreshold=0.5 #GeV, below this start killing tracks
    tkThreshEff=1.0
    tkLowPoint=0.20
    tkLowPointEff=0.40
#    tkSlope=2.6 
#    tkIntercept=-0.04
    #calculate tkSlope and Intercept   
    tkSlope=(tkThreshEff-tkLowPointEff)/(tkThreshold-tkLowPoint)
    tkIntercept=tkThreshEff-tkSlope*tkThreshold

##############
    requireECalMatch = True
    requireECalFiducial = False
    requireECalSuperFiducial = True
    useGBL=True


     # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    #use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from "+args.dst_file
    tree=ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file)+"*")    
    # Create an HpsEvent object in order to read the TClonesArray 
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))



    #--- Analysis ---#
    #----------------#

    #counters
    nEvents=0;
    nPassBasicCuts=0;
    nPassV0Cuts=0;
    nPassTrkCuts=0;
    nPassNCand=0
    nPassECalMatch=0;
    nFakeTri=0


    if 1==0 : 
        extraElectronProb=0.0
        dataNele=170.0;
        btNele=1.4;
        hf=ROOT.TFile("OutputHistograms/Data/hps_005772_pass6_useGBL_ECalMatch_SuperFiducialCut.root")
        hfMC=ROOT.TFile("OutputHistograms/MC/beam-tri_HPS-EngRun2015-Nominal-v4-4_pass6_useGBL_ECalMatch_SuperFiducialCut.root")
        pele=ROOT.RooRealVar("pele","pele",0,1)
        peleHist=hf.Get("raweleMom")
        peleMCHist=hfMC.Get("raweleMom")
        peleHist.Scale(1/dataNele)
        peleMCHist.Scale(1/btNele)
        peleHist.Add(peleMCHist,-1.0)  #subtract the MC from the data to get the distribution of extra tracks...this is cheating!
        for i in xrange(0,peleHist.GetNbinsX()) :
            print "Electron Momentum bin i = " +str( peleHist.GetBinContent(i) )
            if peleHist.GetBinContent(i) <0 :
                peleHist.SetBinContent(i,0)
        peleHist.Print("V")
        peleDH=RooDataHist("peleDH","peleDH",ROOT.RooArgList(pele),peleHist)
        peleDH.Print("V")
        extraElectronPdf=RooHistPdf("extraElectronPdf","extraElectronPdf",ROOT.RooArgSet(pele),peleDH)
        print 'pdf is made...printing info' 
        extraElectronPdf.Print("V")
        #    if isMC and random.random()<extraElectronProb : 
        #add an extra electron based on electron momentum
        print 'generating events' 
        newElePData=extraElectronPdf.generate(ROOT.RooArgSet(pele),1000000.0,True, False)
        newElePData.Print("V")
    
    seedCnt=0
    # Loop over all events in the file
    for entry in xrange(0, tree.GetEntries()) : 
                 
        # Print the event number every 500 events
        if (entry+1)%10000 == 0 : print "Event " + str(entry+1)
        tree.GetEntry(entry)
        if not hps_event.isPair1Trigger() and not isMC and not isPulser: continue
        nEvents+=1
        addFakeEle=False
        if 1==0 :
            if isMC and random.random()<extraElectronProb : 
        #add an extra electron based on electron momentum
                addFakeEle=True
                newEleP=newElePData.get(seedCnt).find("pele").getVal()
                seedCnt=seedCnt+1
                #            print 'Inserting an electron with momentum = '+str(newEleP)
                #            newEleCluster=hps_event.addEcalCluster();
                #            newEleTrack=hps_event.addTrack();
                #            print 'numbe of HpsParticles before = '+str(hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE))
                #            newEle=hps_event.addParticle(HpsParticle.FINAL_STATE_PARTICLE)
                #            print 'numbe of HpsParticles after = '+str(hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE))
                newEle=HpsParticle()
                newEle.setCharge(-1)
                newEle.setPDG(11)
                newEle.setEnergy(newEleP)
                sign=1
                if random.random()<0.5 : 
                    sign=-1
                newEleMom=[math.sin(0.03)*newEleP,sign*math.sin(0.04)*newEleP,math.cos(0.04)*newEleP]
                newEle.setMomentum(np.array(newEleMom))
            #fake track info
                newEleTrack=SvtTrack()
                newEleTrack.setTrackParameters(0.0,0.03,0.0001,sign*0.04,0.0)
                newEleTrack.setTrackTime(40.0)
                newEleTrack.setParticle(newEle)
                newEleTrack.setChi2(3.0)
                newEleTrack.setPositionAtEcal(np.array([300.0,sign*50.0,1350.0]))
            #fake cluster info
                newEleCluster=EcalCluster()
                newEleCluster.setEnergy(newEleP)
                foobar=[300.0,sign*50.0,1350.0]
                newEleCluster.setPosition(np.array(foobar,dtype='float32'))
                newEle.addTrack(newEleTrack)
                newEle.addCluster(newEleCluster)
#            print 'fake electron cluster x ' + str(newEle.getClusters().First().getPosition()[0])            
                                                                           

        # Loop over all tracks in the event
        npositrons=0
        n_tracks=0
        for track_n in xrange(0, hps_event.getNumberOfTracks()) :             
            track = hps_event.getTrack(track_n)
            if track is None : 
                continue
#            if useGBL and track.getParticle().getType()<32  : continue
#            if not useGBL and track.getParticle().getType()>31  : continue
            if trkMatchAndFiducial(track.getParticle()) and trkMomentum(track,minPCut,beamCut): # count only matched tracks in defined fiducial region
                n_tracks+=1
                if track.getCharge()>0 :
                    npositrons+=1
                    myhist.rawposMom.Fill(pMag(track.getMomentum()))
                else :
                    myhist.raweleMom.Fill(pMag(track.getMomentum()))
#                    findWABPair(track.getParticle(),hps_event)

        if addFakeEle :
            myhist.raweleMom.Fill(newEle.getEnergy())
            n_tracks=n_tracks+1
#        print "nTracks = "+str(n_tracks)+"; nPositrons = "+str(npositrons)
#        if n_tracks/2.0>nTrkMax : continue   #do this very dumb thing (divide by 2 to un-double count GBL tracks)
#        if n_tracks/2.0<2:  continue        
        myhist.nTrk.Fill(n_tracks);
        myhist.nPos.Fill(npositrons);
        myhist.nEle.Fill(n_tracks-npositrons);
        myhist.nClust.Fill(hps_event.getNumberOfEcalClusters())

        if n_tracks>nTrkMax : continue  
        if n_tracks<nTrkMin:  continue        
        if npositrons<1 or npositrons>nPosMax : continue
        nPassBasicCuts+=1
#        print "passed basic cuts"
        candidateList=[]
        bestCandidate=-99
        nCandidate=0
        # loop over all v0 candidates...
        for uc_index in xrange(0, hps_event.getNumberOfParticles(HpsParticle.UC_V0_CANDIDATE)):
            particle = hps_event.getParticle(HpsParticle.UC_V0_CANDIDATE, uc_index)
            if useGBL and  particle.getType()<32  : continue
            if not useGBL and  particle.getType()>31  : continue
#            print "found one..."
            vchi2=particle.getVertexFitChi2();
            vposition=particle.getVertexPosition();
            vmomentum=particle.getMomentum();
            if vchi2>v0Chi2 :  continue
            # use the measured sum of momentum 
#            if vmomentum[2]>v0PzMax : continue
#            if vmomentum[2]<v0PzMin : continue
             #recon'ed vertex position cuts
            if abs(vposition[0])>v0VxMax : continue
            if abs(vposition[1])>v0VyMax :continue

#            if abs(vposition[2])>v0VzMax :continue
            # Only look at particles that have two daugther particles...
            daughter_particles = particle.getParticles()
            if daughter_particles.GetSize() != 2 : continue
            # Only look at particles that are composed of e+e- pairs
            if daughter_particles.At(0).getCharge()*daughter_particles.At(1).getCharge() > 0 : continue
#            print "Passed daughter number cuts"

            electron =  daughter_particles.At(0)
            positron =  daughter_particles.At(1)
            
            if daughter_particles.At(0).getCharge()>0:
                electron =  daughter_particles.At(1)
                positron =  daughter_particles.At(0)

            pEle=electron.getMomentum()
            pPos=positron.getMomentum()

            v0Sum=pMag(pSum(pEle,pPos))
            #total momentum sum cuts
            if v0Sum>v0PzMax : continue
            if v0Sum<v0PzMin : continue
            nPassV0Cuts+=1
            print "Passed v0 cuts"
#############   tracking cuts
            #momentum cuts...get rid of very soft or very hard tracks
            if pMag(pEle)>beamCut or pMag(pPos)>beamCut : continue
            if pMag(pEle)<minPCut or pMag(pPos)<minPCut : continue   
            #top+bottom requirement
            if pEle[1]*pPos[1]>0 : continue

            print 'looking at tracks now' 
            print len(electron.getTracks())
            
            if  len(electron.getTracks()) == 0 or  len(positron.getTracks()) == 0: continue
            eleTrk=electron.getTracks().At(0)
            posTrk=positron.getTracks().At(0)
            if eleTrk is None or posTrk is None : continue
            eleTrk.Print("v")
            #track timing
            if eleTrk.getTrackTime() - posTrk.getTrackTime()> trkDeltaT :
                continue
            #track slope (if any cut)
            if abs(eleTrk.getTanLambda())<slopeCut or abs(posTrk.getTanLambda())<slopeCut :
                continue
            print 'satisfied timing cuts...'
            ##############
            # track killer part
            if isMC and trackKiller : 
                if pMag(pEle) <tkThreshold : #electron
                    tkEff=tkSlope*pMag(pEle)+tkIntercept 
                    if random.random()>tkEff  :
                        continue
                elif random.random()>tkThreshEff :  #allow for a flat killer above threshold
                    continue
                if pMag(pPos) <tkThreshold :   # positron
                    tkEff=tkSlope*pMag(pPos)+tkIntercept 
                    if random.random()>tkEff  :
                        continue
                elif random.random()>tkThreshEff : #allow for a flat killer above threshold
                    continue
            #  end of track killer
            ##############
            nPassTrkCuts+=1

            ##############
            #   ECAL matching and timing cuts...also fiducial region cuts...
            if requireECalMatch: 
                if positron.getClusters().GetEntries() == 0 :
                    continue
                if electron.getClusters().GetEntries() == 0 :
                    continue
                posCluster=positron.getClusters().First()
                eleCluster=electron.getClusters().First()
                
                if eleCluster.getClusterTime()- posCluster.getClusterTime() > cluDeltaT:
                    continue
                
                if eleTrk.getTrackTime() - eleCluster.getClusterTime()+43.5 > cluTrkDeltaT : 
                    continue

                if posTrk.getTrackTime() - posCluster.getClusterTime()+43.5 > cluTrkDeltaT : 
                    continue
                
                if requireECalFiducial:
                    #ANTI-fiducial cut
                    #                    if  myhist.inFiducialRegion(posCluster.getPosition()[0],posCluster.getPosition()[1]) :
                    #                        continue
                    #                    if  myhist.inFiducialRegion(eleCluster.getPosition()[0],eleCluster.getPosition()[1]) :
                    #                        continue
                    #Fiducial cut
                    if not myhist.inFiducialRegion(posCluster.getPosition()[0],posCluster.getPosition()[1]) :
                        continue
                    if not myhist.inFiducialRegion(eleCluster.getPosition()[0],eleCluster.getPosition()[1]) :
                        continue
                if requireECalSuperFiducial :
                    if not myhist.inSuperFiducialRegion(posCluster.getPosition()[0],posCluster.getPosition()[1]) :
                        continue
                    if not myhist.inSuperFiducialRegion(eleCluster.getPosition()[0],eleCluster.getPosition()[1]) :
                        continue
            nPassECalMatch+=1
            ##############
            #Passed the cuts..append the candidate index
            findWABPair(electron,hps_event)
            candidateList.append(uc_index)
      

        numCands=len(candidateList)
        if addFakeEle :
            for track_n in xrange(0, hps_event.getNumberOfTracks()) :             
                track = hps_event.getTrack(track_n)
                if track is None : 
                    continue
                if trkMatchAndFiducial(track.getParticle()) and trkMomentum(track,minPCut,beamCut) and track.getCharge>0 and newEle.getMomentum()[1]*track.getMomentum()[1]<0: # get positron in fudicial region; make sure it's in opposite quadrant
                    myhist.eSum.Fill(newEle.getEnergy()+pMag(track.getMomentum()))
                    numCands+=1
                    if len(candidateList) == 0 : 
                        print 'made a new trident event' 
                        nFakeTri+=1
                    
        myhist.nCand.Fill(numCands)
      
        #########################        
        #   found some candidates...lets fill plots...
        #########################        
        for index in range(0,len(candidateList)) :
            particle = hps_event.getParticle(HpsParticle.TC_V0_CANDIDATE, candidateList[index])
            myhist.fillCandidateHistograms(particle)
            myhist.nTrkCand.Fill(n_tracks);
            myhist.nPosCand.Fill(npositrons);
            myhist.nEleCand.Fill(n_tracks-npositrons);
            myhist.nClustCand.Fill(hps_event.getNumberOfEcalClusters())
            

#    if(nPassTrkCuts>0): 
    myhist.saveHistograms(output_file)   

    print "******************************************************************************************"
    print "Number of Events:\t\t",nEvents,"\t\t\t",float(nEvents)/nEvents,"\t\t\t",float(nEvents)/nEvents
    print "N(particle) Cuts:\t\t",nPassBasicCuts,"\t\t\t",float(nPassBasicCuts)/nEvents,"\t\t\t",float(nPassBasicCuts)/nEvents
    print "V0 Vertex   Cuts:\t\t",nPassV0Cuts,"\t\t\t",float(nPassV0Cuts)/nPassBasicCuts,"\t\t\t",float(nPassV0Cuts)/nEvents
    print "Tracking    Cuts:\t\t",nPassTrkCuts,"\t\t\t",float(nPassTrkCuts)/nPassV0Cuts,"\t\t\t",float(nPassTrkCuts)/nEvents
    print "ECal Match  Cuts:\t\t",nPassECalMatch,"\t\t\t",float(nPassECalMatch)/nPassTrkCuts,"\t\t\t",float(nPassECalMatch)/nEvents

    print "Number of Fake Events Added:  \t\t",nFakeTri,"\t\t\t",float(nFakeTri)/nPassECalMatch
コード例 #5
0
dst_file = TFile(str(args.input))
if not dst_file.IsOpen():
	print "\nDST file " + str(args.input) + " couldn't be opened!"
	sys.exit(2)

# Get the TTree
dst_tree = dst_file.Get("HPS_Event")

# Load the DST libraries
hps_dst_path = os.environ['HPS_DST_HOME']
hps_dst_path += "/build/lib/libHpsEvent.so"
gSystem.Load(hps_dst_path)

from ROOT import HpsEvent

hps_event = HpsEvent()
b_hps_event = dst_tree.GetBranch("Event")
b_hps_event.SetAddress(AddressOf(hps_event))

canvas = TCanvas("canvas", "Extrapolation Analysis", 800, 800)

h_track_d0 = TH1F("h_track_d0", "Track D0", 100, -1.5, 1.5)
h_track_d0.SetLineColor(kAzure+2)
h_track_d0.SetMarkerColor(kAzure+2)
h_gbl_track_d0 = TH1F("h_gbl_track_d0", "GBL Track D0", 100, -1.5, 1.5)
h_gbl_track_d0.SetLineColor(kRed+1)
h_gbl_track_d0.SetMarkerColor(kRed+1)

legend = TLegend(0.7, 0.8, 0.9, 0.9, "", "brNDC")
legend.SetBorderSize(0)
legend.SetFillStyle(0)
コード例 #6
0
dst_file = TFile(str(args.input))
if not dst_file.IsOpen():
    print "\nDST file " + str(args.input) + " couldn't be opened!"
    sys.exit(2)

# Get the TTree
dst_tree = dst_file.Get("HPS_Event")

# Load the DST libraries
hps_dst_path = os.environ['HPS_DST_HOME']
hps_dst_path += "/build/lib/libHpsEvent.so"
gSystem.Load(hps_dst_path)

from ROOT import HpsEvent

hps_event = HpsEvent()
b_hps_event = dst_tree.GetBranch("Event")
b_hps_event.SetAddress(AddressOf(hps_event))

canvas = TCanvas("canvas", "Extrapolation Analysis", 800, 800)

h_track_d0 = TH1F("h_track_d0", "Track D0", 100, -1.5, 1.5)
h_track_d0.SetLineColor(kAzure + 2)
h_track_d0.SetMarkerColor(kAzure + 2)
h_gbl_track_d0 = TH1F("h_gbl_track_d0", "GBL Track D0", 100, -1.5, 1.5)
h_gbl_track_d0.SetLineColor(kRed + 1)
h_gbl_track_d0.SetMarkerColor(kRed + 1)

legend = TLegend(0.7, 0.8, 0.9, 0.9, "", "brNDC")
legend.SetBorderSize(0)
legend.SetFillStyle(0)
コード例 #7
0
def main():
    global beamEnergy
    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(
        description='PyRoot analysis demostrating the us of a DST.')
    parser.add_argument("dst_file", help="ROOT DST file to process")
    parser.add_argument("-o", "--output", help="Name of output pdf file")
    parser.add_argument("-m", "--mc", help="is MonteCarlo")
    parser.add_argument("-p", "--pulser", help="is Pulser")
    parser.add_argument("-e", "--energy", help="beam energy")
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user
    if args.output:
        output_file = args.output
    else:
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to "
        print output_file

    print "[ HPS ANALYSIS ]:  Output file is " + output_file
    isMC = False
    if args.mc:
        print "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC = True

    isPulser = False
    if args.pulser:
        print "[ HPS ANALYSIS ]: Setting to run from a pulser file"
        isPulser = True

    if args.energy:
        print 'Setting beam energy to ' + args.energy
        beamEnergy = float(args.energy)
        myhist.setEnergyScales(beamEnergy)

#################################
#       Event Selection
################################
#clean up event first
#### nominal selection
    nTrkMax = 3
    nTrkMin = 3
    nPosMax = 1
    ######  two tracks (e+/e-) exactly
    #    nTrkMax=2
    #    nTrkMin=2
    #    nPosMax=1
    ###### more than 1 electron
    #    nTrkMax=10
    #    nTrkMin=3
    #    nPosMax=1
    ###################
    maxSharedHits = 2
    #v0 cuts
    #    v0Chi2=10
    v0Chi2 = 99999999.0
    #ESum -- full region
    v0PzMax = 1.2 * beamEnergy
    v0PzMin = 0.1 * beamEnergy
    #ESum -- Radiative region
    #    v0PzMax=1.2
    #    v0PzMin=0.80

    v0PyMax = 0.2  #absolute value
    v0PxMax = 0.2  #absolute value
    v0VzMax = 25.0  # mm from target
    #    v0VyMax=1.0# mm from target
    v0VyMax = 6666.0  # mm from target
    v0VxMax = 2.0  # mm from target
    #  track quality cuts
    trkChi2 = 10
    beamCut = 0.8 * beamEnergy
    minPCut = 0.05
    trkPyMax = 0.2
    trkPxMax = 0.2
    #    slopeCut=0.03
    slopeCut = 0.0
    trkDeltaT = 4  #ns
    cluDeltaT = 2  #ns
    cluTrkDeltaT = 4  #ns
    ##############
    #  ESum slices; upper limits
    nSlicesESum = 5
    esumMin = 0.55
    esumMax = 1.2
    sliceSizeESum = 0.1  #100MeV starting at esumMin
    ##############
    trackKiller = False
    tkThreshold = 0.5  #GeV, below this start killing tracks
    tkThreshEff = 1.0
    tkLowPoint = 0.20
    tkLowPointEff = 0.40
    #    tkSlope=2.6
    #    tkIntercept=-0.04
    #calculate tkSlope and Intercept
    tkSlope = (tkThreshEff - tkLowPointEff) / (tkThreshold - tkLowPoint)
    tkIntercept = tkThreshEff - tkSlope * tkThreshold

    ##############
    requireECalMatch = True
    requireECalFiducial = True
    requireECalSuperFiducial = False
    useGBL = True

    # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    #use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from " + args.dst_file
    tree = ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file) + "*")
    # Create an HpsEvent object in order to read the TClonesArray
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))

    #--- Analysis ---#
    #----------------#

    #counters
    nEvents = 0
    nPassBasicCuts = 0
    nPassV0Cuts = 0
    nPassTrkCuts = 0
    nPassNCand = 0
    nPassECalMatch = 0
    nFakeTri = 0
    nTwoCand = 0
    seedCnt = 0
    # Loop over all events in the file
    for entry in xrange(0, tree.GetEntries()):

        # Print the event number every 500 events
        if (entry + 1) % 10000 == 0: print "Event " + str(entry + 1)
        tree.GetEntry(entry)
        if not hps_event.isPair1Trigger() and not isMC and not isPulser:
            continue
        nEvents += 1
        addFakeEle = False

        # Loop over all tracks in the event
        npositrons = 0
        n_tracks = 0
        for track_n in xrange(0, hps_event.getNumberOfTracks()):
            track = hps_event.getGblTrack(track_n)
            if track is None:
                continue
#            print track.getParticle().getType()
            if trkMatchAndFiducial(
                    track.getParticle(),
                    requireECalSuperFiducial) and trkMomentum(
                        track, minPCut, beamCut
                    ):  # count only matched tracks in defined fiducial region
                n_tracks += 1
                if track.getCharge() > 0:
                    npositrons += 1
                    myhist.rawposMom.Fill(pMag(track.getMomentum()))
                else:
                    myhist.raweleMom.Fill(pMag(track.getMomentum()))
#                    findWABPair(track.getParticle(),hps_event)

#        print "nTracks = "+str(n_tracks)+"; nPositrons = "+str(npositrons)
#        if n_tracks/2.0>nTrkMax : continue   #do this very dumb thing (divide by 2 to un-double count GBL tracks)
#        if n_tracks/2.0<2:  continue
        myhist.nTrk.Fill(n_tracks)
        myhist.nPos.Fill(npositrons)
        myhist.nEle.Fill(n_tracks - npositrons)
        myhist.nClust.Fill(hps_event.getNumberOfEcalClusters())

        if n_tracks > nTrkMax: continue
        if n_tracks < nTrkMin: continue
        if npositrons < 1 or npositrons > nPosMax: continue
        nPassBasicCuts += 1
        #        print "passed basic cuts"
        candidateList = []
        bestCandidate = -99
        nCandidate = 0
        # loop over all v0 candidates...
        for uc_index in xrange(
                0,
                hps_event.getNumberOfParticles(HpsParticle.UC_V0_CANDIDATE)):
            particle = hps_event.getParticle(HpsParticle.UC_V0_CANDIDATE,
                                             uc_index)
            #            print "Particle Type = "+ str(particle.getType())
            if useGBL and particle.getType() < 32: continue
            if not useGBL and particle.getType() > 31: continue
            #            print "found one..."
            vchi2 = particle.getVertexFitChi2()
            vposition = particle.getVertexPosition()
            vmomentum = particle.getMomentum()
            if vchi2 > v0Chi2: continue
            # use the measured sum of momentum
            #            if vmomentum[2]>v0PzMax : continue
            #            if vmomentum[2]<v0PzMin : continue
            #recon'ed vertex position cuts
            if abs(vposition[0]) > v0VxMax: continue
            if abs(vposition[1]) > v0VyMax: continue

            #            if abs(vposition[2])>v0VzMax :continue
            # Only look at particles that have two daugther particles...
            daughter_particles = particle.getParticles()
            if daughter_particles.GetSize() != 2: continue
            # Only look at particles that are composed of e+e- pairs
            if daughter_particles.At(0).getCharge() * daughter_particles.At(
                    1).getCharge() > 0:
                continue
            #            print "Passed daughter number cuts"

            electron = daughter_particles.At(0)
            positron = daughter_particles.At(1)

            if daughter_particles.At(0).getCharge() > 0:
                electron = daughter_particles.At(1)
                positron = daughter_particles.At(0)

            pEle = electron.getMomentum()
            pPos = positron.getMomentum()

            v0Sum = pMag(pSum(pEle, pPos))
            #total momentum sum cuts
            if v0Sum > v0PzMax: continue
            if v0Sum < v0PzMin: continue
            nPassV0Cuts += 1
            #            print "Passed v0 cuts"
            #############   tracking cuts
            #momentum cuts...get rid of very soft or very hard tracks
            if pMag(pEle) > beamCut or pMag(pPos) > beamCut: continue
            if pMag(pEle) < minPCut or pMag(pPos) < minPCut: continue
            #top+bottom requirement
            if pEle[1] * pPos[1] > 0: continue

            #            print 'looking at tracks now'
            #            print len(electron.getTracks())

            if len(electron.getTracks()) == 0 or len(
                    positron.getTracks()) == 0:
                continue
            eleTrk = electron.getTracks().At(0)
            posTrk = positron.getTracks().At(0)
            if eleTrk is None or posTrk is None: continue
            #            eleTrk.Print("v")
            #track timing
            if eleTrk.getTrackTime() - posTrk.getTrackTime() > trkDeltaT:
                continue
            #track slope (if any cut)
            if abs(eleTrk.getTanLambda()) < slopeCut or abs(
                    posTrk.getTanLambda()) < slopeCut:
                continue
#            print 'satisfied timing cuts...'

##############
            nPassTrkCuts += 1

            ##############
            #   ECAL matching and timing cuts...also fiducial region cuts...
            if requireECalMatch:
                if positron.getClusters().GetEntries() == 0:
                    continue
                if electron.getClusters().GetEntries() == 0:
                    continue
                posCluster = positron.getClusters().First()
                eleCluster = electron.getClusters().First()

                if eleCluster.getClusterTime() - posCluster.getClusterTime(
                ) > cluDeltaT:
                    continue

                if eleTrk.getTrackTime() - eleCluster.getClusterTime(
                ) + 43.5 > cluTrkDeltaT:
                    continue

                if posTrk.getTrackTime() - posCluster.getClusterTime(
                ) + 43.5 > cluTrkDeltaT:
                    continue

                if requireECalFiducial:
                    #ANTI-fiducial cut
                    #                    if  myhist.inFiducialRegion(posCluster.getPosition()[0],posCluster.getPosition()[1]) :
                    #                        continue
                    #                    if  myhist.inFiducialRegion(eleCluster.getPosition()[0],eleCluster.getPosition()[1]) :
                    #                        continue
                    #Fiducial cut
                    if not myhist.inFiducialRegion(
                            posCluster.getPosition()[0],
                            posCluster.getPosition()[1]):
                        continue
                    if not myhist.inFiducialRegion(
                            eleCluster.getPosition()[0],
                            eleCluster.getPosition()[1]):
                        continue
                if requireECalSuperFiducial:
                    if not myhist.inSuperFiducialRegion(
                            posCluster.getPosition()[0],
                            posCluster.getPosition()[1]):
                        continue
                    if not myhist.inSuperFiducialRegion(
                            eleCluster.getPosition()[0],
                            eleCluster.getPosition()[1]):
                        continue
            nPassECalMatch += 1
            ##############
            #Passed the cuts..append the candidate index
            candidateList.append(particle)

        numCands = len(candidateList)

        myhist.nCand.Fill(numCands)
        if numCands != 2:
            continue  #require 2 candidates...probably have to rethink this.

        print 'found 2 candidates'

        cand0 = candidateList[0]  # take this as base candidate
        candpos = cand0.getParticles().At(0)
        candele = cand0.getParticles().At(1)
        if candpos.getCharge() < 0:
            candpos = cand0.getParticles().At(1)
            candele = cand0.getParticles().At(0)
#            print "swapping cand"
        cand1 = candidateList[1]  # get the recoil electron from this
        recoil = cand1.getParticles().At(0)
        recpos = cand1.getParticles().At(1)
        if recoil.getCharge() > 0:
            #            print "swapping recoil"
            recoil = cand1.getParticles().At(1)
            recpos = cand1.getParticles().At(0)
#        print 'Positron p' +str(pMag(candpos.getMomentum()))
#        print 'Electron p' +str(pMag(candele.getMomentum()))
#        print 'Recoil   p' +str(pMag(recoil.getMomentum()))
#        print 'Recoil Positron   p' +str(pMag(recpos.getMomentum()))

#        if candpos == recpos :
#            print "positrons are same"

        numSharedHits = myhist.getSharedHits(recoil.getTracks()[0],
                                             candele.getTracks()[0])
        print "Number of overlapping hits for electrons is : " + str(
            numSharedHits)

        if numSharedHits <= maxSharedHits:
            nTwoCand += 1
            myhist.fillCandidateHistograms(cand0, recoil)
            myhist.fillThreeTrackPlots(cand0, cand1)

#    if(nPassTrkCuts>0):
    myhist.saveHistograms(output_file)

    print "******************************************************************************************"
    print "Number of Events:\t\t", nEvents, "\t\t\t", float(
        nEvents) / nEvents, "\t\t\t", float(nEvents) / nEvents
    print "N(particle) Cuts:\t\t", nPassBasicCuts, "\t\t\t", float(
        nPassBasicCuts) / nEvents, "\t\t\t", float(nPassBasicCuts) / nEvents
    print "V0 Vertex   Cuts:\t\t", nPassV0Cuts, "\t\t\t", float(
        nPassV0Cuts) / nPassBasicCuts, "\t\t\t", float(nPassV0Cuts) / nEvents
    print "Tracking    Cuts:\t\t", nPassTrkCuts, "\t\t\t", float(
        nPassTrkCuts) / nPassV0Cuts, "\t\t\t", float(nPassTrkCuts) / nEvents
    print "ECal Match  Cuts:\t\t", nPassECalMatch, "\t\t\t", float(
        nPassECalMatch) / nPassTrkCuts, "\t\t\t", float(
            nPassECalMatch) / nEvents

    print "Number of Fake Events Added:  \t\t", nFakeTri, "\t\t\t", float(
        nFakeTri) / nPassECalMatch

    print "Number of events with 2 candidates (unshared) = ", nTwoCand
コード例 #8
0
def main():

    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(
        description='PyRoot analysis demostrating the us of a DST.')
    parser.add_argument("dst_file", help="ROOT DST file to process")
    parser.add_argument("-o", "--output", help="Name of output pdf file")
    parser.add_argument("-m", "--mc", help="is MonteCarlo")
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user
    if args.output:
        output_file = args.output
    else:
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to "
        print output_file

    print "[ HPS ANALYSIS ]:  Output file is " + output_file
    isMC = False
    if args.mc:
        print "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC = True

    # Load the HpsEvent library.  In this example, this is done by finding the
    # path to the HpsEvent shared library via the environmental variable
    # HPS_DST_PATH.  The HPS_DST_PATH environmental variable points to the
    # location of the build directory containing all binaries and libraries.
    # In general, the location of the library can be anywhere a user wants it
    # to be as long as the proper path is specified.
    if os.getenv('HPS_DST_PATH') is None:
        print "[ HPS ANALYSIS ]: Error! Environmental variable HPS_DST_HOME is not set."
        print "\n[ HPS ANALYSIS ]: Exiting ..."
        sys.exit(2)

    hps_dst_path = os.environ['HPS_DST_PATH']
    hps_dst_path += "/build/lib/libHpsEvent.so"
    print "Loading HpsEvent Library from " + hps_dst_path
    # Load the library in ROOT
    import ROOT
    ROOT.gSystem.Load(hps_dst_path)

    # import the modules used by HpsEvent i.e. HpsEvent,
    # SvtTrack, EcalCluster ...
    from ROOT import HpsEvent, SvtTrack, EcalCluster, EcalHit, TChain, TTree, HpsParticle

    #################################
    #       Event Selection
    ################################
    ebeam = 1.05
    #clean up event first
    nTrkMax = 5
    nPosMax = 2
    #v0 cuts
    v0Chi2 = 10
    v0PzMax = 1.25 * ebeam
    #   v0PzMax=0.8*ebeam
    #    v0PzMin=0.6
    v0PzMin = 0.3
    #    v0PzMin=0.8*ebeam
    v0PyMax = 0.2  #absolute value
    v0PxMax = 0.2  #absolute value
    v0VzMax = 25.0  # mm from target
    v0VyMax = 1.0  # mm from target
    v0VxMax = 2.0  # mm from target
    #  track quality cuts
    trkChi2 = 10
    #    beamCut=0.9
    beamCut = 0.8
    minPCut = 0.05
    trkPyMax = 0.2
    trkPxMax = 0.2
    #    slopeCut=0.02
    slopeCut = 0.00

    radCut = 0.8 * ebeam

    requireECalMatch = True
    useGBL = False
    #-----------------------------#
    #--- Setup ROOT histograms ---#
    #-----------------------------#

    # Create a canvas and set its characteristics
    #    canvas = ROOT.TCanvas("canvas", "Data Summary Tape Plots", 700, 700)
    #    setupCanvas(canvas)

    nCand = ROOT.TH1F("NCand", "Number of Candidates", 4, 0, 4)
    tridentMass = ROOT.TH1F("TridentMass", "Trident Mass (GeV)", 500, 0, 0.100)
    tridentMassVtxCut = ROOT.TH1F("TridentMassBeforeVertex",
                                  "Trident Mass (GeV): Before  VtxCut", 500, 0,
                                  0.100)
    tridentVx = ROOT.TH1F("Vx", "Trident Vx (mm)", 100, -4, 4)
    tridentVy = ROOT.TH1F("Vy", "Trident Vy (mm)", 100, -2, 2)
    tridentVz = ROOT.TH1F("Vz", "Trident Vz (mm)", 100, -50, 50)
    eSum = ROOT.TH1F("eSum", "Energy Sum", 100, 0.3, 1.2)
    eDiff = ROOT.TH1F("eDiffoverESum", "Energy Difference", 100, -0.8, 0.8)
    vertChi2 = ROOT.TH1F("vertChi2", "V0 Chi2", 100, 0, 10)
    ePosvseEle = ROOT.TH2F("ePosvseEle", "Positron vs Electron Energy", 100,
                           0.1, 0.9, 50, 0.1, 0.9)
    tanopenY = ROOT.TH1F("tanopenY", "tanopenY", 100, 0., 0.16)
    tanopenYThresh = ROOT.TH1F("tanopenYThresh", "tanopenYThresh", 100, 0.025,
                               0.06)
    minAngle = ROOT.TH1F("minAngle", "Minimum Track Angle", 100, 0.01, 0.03)
    coplan = ROOT.TH1F("coplanarity", "Coplanarity", 100, -0.004, 0.004)
    copVseSum = ROOT.TH2F("coplanarity vs eSum", "coplanarity vs eSum", 100,
                          0.3, 1.2, 100, -0.004, 0.004)

    eleMom = ROOT.TH1F("eleMom", "Electron Momentum (GeV)", 100, 0, 1.)
    posMom = ROOT.TH1F("posMom", "Positron Momentum (GeV)", 100, 0, 1.)

    eled0 = ROOT.TH1F("eled0", "Electron d0 (mm)", 100, -3, 3)
    posd0 = ROOT.TH1F("posd0", "Positron d0 (mm)", 100, -3, 3)

    elez0 = ROOT.TH1F("elez0", "Electron z0 (mm)", 100, -1.5, 1.5)
    posz0 = ROOT.TH1F("posz0", "Positron z0 (mm)", 100, -1.5, 1.5)

    elephi0 = ROOT.TH1F("elephi0", "Electron phi0", 100, -0.1, 0.1)
    posphi0 = ROOT.TH1F("posphi0", "Positron phi0", 100, -0.1, 0.1)

    eleslope = ROOT.TH1F("eleslope", "Electron slope", 100, -0.08, 0.08)
    posslope = ROOT.TH1F("posslope", "Positron slope", 100, -0.08, 0.08)

    trkTimeDiff = ROOT.TH1F("trkTimeDiff", "Ele-Pos Time Difference (ns)", 100,
                            -6, 6)
    cluTimeDiff = ROOT.TH1F("cluTimeDiff", "Cluster Time Difference (ns)", 100,
                            -2, 2)

    tHitTop = []
    tHitBot = []

    nlayers = 6
    pre = "time (ns) for layer "
    for i in range(1, nlayers):
        topName = pre + " " + str(i) + " Top"
        tHitTop.append(ROOT.TH1F(topName, topName, 100, -16, 16))
        botName = pre + " " + str(i) + " Bot"
        tHitBot.append(ROOT.TH1F(botName, botName, 100, -16, 16))

    # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    #use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from " + args.dst_file
    tree = ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file) + "*")

    # Create an HpsEvent object in order to read the TClonesArray
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))

    # Get the HpsEvent branch from the TTree
    #    b_hps_event = tree.GetBranch("Event")
    #    b_hps_event.SetAddress(ROOT.AddressOf(hps_event))

    #--- Analysis ---#
    #----------------#

    #counters
    nEvents = 0
    nPassBasicCuts = 0
    nPassV0Cuts = 0
    nPassTrkCuts = 0
    nPassNCand = 0
    # Loop over all events in the file
    for entry in xrange(0, tree.GetEntries()):
        # Print the event number every 500 events
        if (entry + 1) % 10000 == 0: print "Event " + str(entry + 1)

        # Read the ith entry from the tree.  This "fills" HpsEvent and allows
        # access to all collections
        #        entryNumber = tree.GetEntryNumber(entry);
        #        localEntry = fTree.LoadTree(entryNumber);
        #        print localEntry
        #        if localEntry < 0:
        #            continue
        #        tree.GetEntry(localEntry)
        tree.GetEntry(entry)
        #        print "checking trigger"
        if not hps_event.isPair1Trigger() and not isMC: continue
        nEvents += 1
        #        print "found a pair1 trigger"
        # Loop over all tracks in the event
        npositrons = 0
        n_tracks = 0
        #        print "Found "+str( hps_event.getNumberOfTracks()) +" tracks in event"
        #        if  hps_event.getNumberOfTracks() > 10 : continue
        for track_n in xrange(0, hps_event.getNumberOfTracks()):
            track = hps_event.getTrack(track_n)
            if track is None:
                continue
#            if not (useGBL ^ track.type<32)  : continue
            n_tracks += 1
            if track.getCharge() > 0:
                npositrons += 1

#        print "nTracks = "+str(n_tracks)+"; nPositrons = "+str(npositrons)
        if n_tracks / 2.0 > nTrkMax:
            continue  #do this very dumb thing (divide by 2 to un-double count GBL tracks)
        if n_tracks / 2.0 < 2: continue
        if npositrons < 1 or npositrons > nPosMax: continue
        nPassBasicCuts += 1
        #        print "passed basic cuts"
        candidateList = []
        bestCandidate = -99
        nCandidate = 0
        # loop over all v0 candidates...
        for uc_index in xrange(
                0,
                hps_event.getNumberOfParticles(HpsParticle.UC_V0_CANDIDATE)):
            particle = hps_event.getParticle(HpsParticle.UC_V0_CANDIDATE,
                                             uc_index)
            if not (useGBL ^ particle.getType() < 32): continue
            vchi2 = particle.getVertexFitChi2()
            vposition = particle.getVertexPosition()
            vmomentum = particle.getMomentum()
            if vchi2 > v0Chi2: continue
            if vmomentum[2] > v0PzMax: continue
            if vmomentum[2] < v0PzMin: continue
            if abs(vposition[0]) > v0VxMax: continue
            if abs(vposition[1]) > v0VyMax: continue
            #            if abs(vposition[2])>v0VzMax :continue
            nPassV0Cuts += 1
            #            print "Passed v0 cuts"
            # Only look at particles that have two daugther particles...
            daughter_particles = particle.getParticles()
            if daughter_particles.GetSize() != 2: continue
            # Only look at particles that are composed of e+e- pairs
            if daughter_particles.At(0).getCharge() * daughter_particles.At(
                    1).getCharge() > 0:
                continue
            #            print "Passed daughter number cuts"

            electron = daughter_particles.At(0)
            positron = daughter_particles.At(1)

            if daughter_particles.At(0).getCharge() > 0:
                electron = daughter_particles.At(1)
                positron = daughter_particles.At(0)

            pEle = electron.getMomentum()
            pPos = positron.getMomentum()

            if pMag(pEle) > beamCut or pMag(pPos) > beamCut: continue
            if pMag(pEle) < minPCut or pMag(pPos) < minPCut: continue
            if pEle[1] * pPos[1] > 0: continue
            if requireECalMatch:
                if positron.getClusters().GetEntries() == 0:
                    continue
                if electron.getClusters().GetEntries() == 0:
                    continue
            eleTrk = electron.getTracks().At(0)
            posTrk = positron.getTracks().At(0)
            if abs(eleTrk.getTanLambda()) < slopeCut or abs(
                    posTrk.getTanLambda()) < slopeCut:
                continue

#            print "Passed track cuts"
            nPassTrkCuts += 1
            #Passed the cuts..append the candidate index
            candidateList.append(uc_index)

        #########################
        #   found some candidates...lets fill plots...
        #########################
        nCand.Fill(len(candidateList))
        for index in range(0, len(candidateList)):
            particle = hps_event.getParticle(HpsParticle.UC_V0_CANDIDATE,
                                             candidateList[index])
            vchi2 = particle.getVertexFitChi2()
            vposition = particle.getVertexPosition()
            vmomentum = particle.getMomentum()

            daughter_particles = particle.getParticles()
            electron = daughter_particles.At(0)
            positron = daughter_particles.At(1)

            if daughter_particles.At(0).getCharge() > 0:
                electron = daughter_particles.At(1)
                positron = daughter_particles.At(0)
            pEle = electron.getMomentum()
            pPos = positron.getMomentum()

            beam = [np.sin(0.0305), 0, np.cos(0.0305)]

            normEle = np.linalg.norm(pEle)
            normPos = np.linalg.norm(pPos)
            peleArray = np.asarray(pEle)
            pposArray = np.asarray(pPos)
            coplanarity = np.dot(
                beam, (np.cross(peleArray, pposArray))) / normEle / normPos
            coplan.Fill(coplanarity)
            #fill the plots
            tridentVx.Fill(vposition[0])
            tridentVy.Fill(vposition[1])
            tridentVz.Fill(vposition[2])

            ePosvseEle.Fill(pMag(pEle), pMag(pPos))
            #            eSum.Fill(pMag(pEle)+pMag(pPos))
            eSum.Fill(pMag(vmomentum))  #fill with the fitted momentum instead
            eDiff.Fill(pMag(pEle) - pMag(pPos)) / (pMag(pEle) + pMag(pPos))
            tridentMass.Fill(particle.Mass())
            copVseSum.Fill(pMag(vmomentum), coplanarity)
            eleMom.Fill(pMag(pEle))
            posMom.Fill(pMag(pPos))

            eleTrk = electron.getTracks().At(0)
            posTrk = positron.getTracks().At(0)

            eled0.Fill(eleTrk.getD0())
            elez0.Fill(eleTrk.getZ0())
            elephi0.Fill(math.sin(eleTrk.getPhi0()))
            eleslope.Fill(eleTrk.getTanLambda())

            posd0.Fill(posTrk.getD0())
            posz0.Fill(posTrk.getZ0())
            posphi0.Fill(math.sin(posTrk.getPhi0()))
            posslope.Fill(posTrk.getTanLambda())

            trkTimeDiff.Fill(eleTrk.getTrackTime() - posTrk.getTrackTime())
            vertChi2.Fill(particle.getVertexFitChi2())

            topenAngle = abs(eleTrk.getTanLambda()) + abs(
                posTrk.getTanLambda())

            tanopenY.Fill(topenAngle)
            tanopenYThresh.Fill(topenAngle)
            minAngle.Fill(
                min(abs(eleTrk.getTanLambda()), abs(posTrk.getTanLambda())))
            if requireECalMatch:
                pTime = positron.getClusters().At(0).getClusterTime()
                eTime = electron.getClusters().At(0).getClusterTime()
                cluTimeDiff.Fill(eTime - pTime)

    out = ROOT.TFile(output_file, "RECREATE")
    tridentMass.Write()
    tridentVx.Write()
    tridentVy.Write()
    tridentVz.Write()
    tridentMassVtxCut.Write()
    ePosvseEle.Write()
    vertChi2.Write()
    eSum.Write()
    eDiff.Write()
    eleMom.Write()
    eled0.Write()
    elez0.Write()
    elephi0.Write()
    eleslope.Write()
    copVseSum.Write()
    coplan.Write()
    posMom.Write()
    posd0.Write()
    posz0.Write()
    posphi0.Write()
    posslope.Write()
    trkTimeDiff.Write()
    cluTimeDiff.Write()
    tanopenYThresh.Write()
    tanopenY.Write()
    nCand.Write()
    minAngle.Write()
    out.Close()

    print "\t\t\tTrident Selection Summary"
    print "******************************************************************************************"
    print "Number of Events:\t\t", nEvents, "\t\t\t", float(
        nEvents) / nEvents, "\t\t\t", float(nEvents) / nEvents
    print "N(particle) Cuts:\t\t", nPassBasicCuts, "\t\t\t", float(
        nPassBasicCuts) / nEvents, "\t\t\t", float(nPassBasicCuts) / nEvents
    print "V0 Vertex   Cuts:\t\t", nPassV0Cuts, "\t\t\t", float(
        nPassV0Cuts) / nPassBasicCuts, "\t\t\t", float(nPassV0Cuts) / nEvents
    print "Tracking    Cuts:\t\t", nPassTrkCuts, "\t\t\t", float(
        nPassTrkCuts) / nPassV0Cuts, "\t\t\t", float(nPassTrkCuts) / nEvents
コード例 #9
0
def main():
    global beamEnergy
    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(
        description='PyRoot analysis demostrating the us of a DST.')
    parser.add_argument("dst_file", help="ROOT DST file to process")
    parser.add_argument("-o", "--output", help="Name of output pdf file")
    parser.add_argument("-m", "--mc", help="is MonteCarlo")
    parser.add_argument("-p", "--pulser", help="is Pulser")
    parser.add_argument("-e", "--energy", help="beam energy")
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user
    if args.output:
        output_file = args.output
    else:
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to "
        print output_file

    print "[ HPS ANALYSIS ]:  Output file is " + output_file
    isMC = False
    if args.mc:
        print "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC = True

    isPulser = False
    if args.pulser:
        print "[ HPS ANALYSIS ]: Setting to run from a pulser file"
        isPulser = True

    if args.energy:
        print 'Setting beam energy to ' + args.energy
        beamEnergy = float(args.energy)

    myhist = myHistograms(beamEnergy)

    #################################
    #       Event Selection
    ################################
    #clean up event first
    #### nominal selection

    requireECalFiducial = False
    requireECalSuperFiducial = False  # this is included as separate histograms now...leave false!
    positronMomentumFromPositionCut = False  # this is included as separate histograms now...leave false!
    requireTopBottomCut = True
    requireLeftRightCut = True

    if isMC:
        smearEnergy = False
        smearRes = 0.05
        myhist.setSmearEnergy(smearEnergy, smearRes)

    # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    #use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from " + args.dst_file
    tree = ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file) + "*")
    # Create an HpsEvent object in order to read the TClonesArray
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))

    #--- Analysis ---#
    #----------------#

    #counters
    nEvents = 0
    nPassBasicCuts = 0

    #   //================ Time coincidence ======================================
    coincide_pars_mean = [
        0.289337, -2.81998, 9.03475, -12.93, 8.71476, -2.26969
    ]
    coincide_pars_sigm = [
        4.3987, -24.2371, 68.9567, -98.2586, 67.562, -17.8987
    ]

    formula_pol5 = "[0] + x*( [1] + x*( [2] + x*( [3] + x*( [4] + x*( [5] ) ) ) ) ) "
    f_coincide_clust_mean = ROOT.TF1("f_coincide_clust_mean", formula_pol5, 0.,
                                     1.4)
    f_coincide_clust_sigm = ROOT.TF1("f_coincide_clust_sigm", formula_pol5, 0.,
                                     1.4)
    f_coincide_clust_mean.SetParameters(np.array(coincide_pars_mean))
    f_coincide_clust_sigm.SetParameters(np.array(coincide_pars_sigm))
    #   //The cut is            === mean - 3sigma < dt < mean + 3sigma ===

    clTimeMin = 30
    clTimeMax = 50

    if beamEnergy == 2.3:
        clTimeMin = 40
        clTimeMax = 65
    energyRatio = beamEnergy / 1.05  #ratio of beam energies references to 1.05 GeV (2015 run)

    seedCnt = 0
    # Loop over all events in the file
    for entry in xrange(0, tree.GetEntries()):

        # Print the event number every 500 events
        if (entry + 1) % 10000 == 0: print "Event " + str(entry + 1)
        tree.GetEntry(entry)
        if not hps_event.isPair1Trigger() and not isMC and not isPulser:
            continue
        nEvents += 1

        nPassBasicCuts += 1
        #        print "passed basic cuts"
        pairList = []
        bestCandidate = -99
        pairsFound = 0
        print 'looking at mcparticles'
        for i in range(0, hps_event.n_mc_particles):
            mcp = hps_event.getMCParticle(i)
            print type(mcp)
            if mcp is None: break
            if mcp.getEnergy() is None:
                print 'no PDGID'
                continue
            else:
                print mcp.getEnergy()

        print '....done'

        for i in range(0, hps_event.getNumberOfEcalClusters()):
            cl1 = hps_event.getEcalCluster(i)
            cl1Position = cl1.getPosition()
            cl_xi = cl1Position[0]
            cl_yi = cl1Position[1]
            cl_zi = cl1Position[2]
            cl_ti = cl1.getClusterTime()
            cl_Ei = cl1.getEnergy()
            myhist.h_clTime1vsclE.Fill(cl_Ei, cl_ti)
            cl_di = math.sqrt((cl_xi - phot_nom_x) * (cl_xi - phot_nom_x) +
                              cl_yi * cl_yi)
            #            print 'looking at clusters'
            #if(!fid_ECal(cl_xi,cl_yi))
            #        continue
            if requireECalFiducial and not myhist.inFiducialRegion(
                    cl_xi, cl_yi):
                continue
            if requireECalSuperFiducial and not myhist.inSuperFiducialRegion(
                    cl_xi, cl_yi):
                continue
            if not (cl_ti > clTimeMin and cl_ti < clTimeMax):
                continue
            if positronMomentumFromPositionCut and not myhist.momFromPositionEclUpperCut(
                    cl_Ei,
                    myhist.momFromECalPosition(cl_xi, cl_zi, beamAngle,
                                               myhist.BEff)):
                continue
#            print 'Found first good cluster'
            for j in range(i + 1, hps_event.getNumberOfEcalClusters()):
                cl2 = hps_event.getEcalCluster(j)
                cl2Position = cl2.getPosition()
                cl_xj = cl2Position[0]
                cl_yj = cl2Position[1]
                cl_zj = cl2Position[2]
                cl_tj = cl2.getClusterTime()
                cl_Ej = cl2.getEnergy()

                cl_dj = math.sqrt((cl_xj - phot_nom_x) * (cl_xj - phot_nom_x) +
                                  cl_yj * cl_yj)
                Esum = cl_Ei + cl_Ej
                #         //      if(!energySlopeCut(cl_xj,cl_d,cl_Ej))
                #         //        continue
                if requireECalFiducial and not myhist.inFiducialRegion(
                        cl_xj, cl_yj):
                    continue
                if requireECalSuperFiducial and not myhist.inSuperFiducialRegion(
                        cl_xj, cl_yj):
                    continue
                if not (cl_tj > clTimeMin and cl_tj < clTimeMax):
                    continue
#                print 'Found second good cluster'
#                //if(!fid_ECal(cl_x[j],cl_y[j]))
#         //  continue
#         //      if(!(energySlopeCut(cl_xi,cl_di,cl_Ei) || energySlopeCut(cl_xj,cl_dj,cl_Ej)))
#         //   continue
                if positronMomentumFromPositionCut and not myhist.momFromPositionEclUpperCut(
                        cl_Ej,
                        myhist.momFromECalPosition(cl_xj, cl_zj, beamAngle,
                                                   myhist.BEff)):
                    continue
#                print 'Passed the probable positron cut'

                myhist.h_clTime1vsclTime2.Fill(cl_ti, cl_tj)

                dt = cl_ti - cl_tj
                #                delt_t_mean = f_coincide_clust_mean.Eval(Esum)
                #                delt_t_sigm = f_coincide_clust_sigm.Eval(Esum)
                #      divide by 2 since these parameters were extracted from 1.05GeV Data (this is kludgy!)
                delt_t_mean = f_coincide_clust_mean.Eval(Esum / energyRatio)
                delt_t_sigm = f_coincide_clust_sigm.Eval(Esum / energyRatio)
                if not (dt < delt_t_mean + 3 * delt_t_sigm
                        and dt > delt_t_mean - 3 * delt_t_sigm):
                    continue
#         //make sure they are top/bottom
#                print 'Passed the timing cut'
#                print str(cl_yi)+"   " + str(cl_yj)
                if requireTopBottomCut and cl_yi * cl_yj > 0:
                    continue

                if requireLeftRightCut and cl_xi * cl_xj > 0:
                    continue

#                print 'Found a pair!!!!'

                clpair = [cl1, cl2]
                pairList.append(clpair)

        pairsFound += len(pairList)
        #        if len(pairList) >0 : print "found this many pairs "+str(len(pairList))

        fspList = []
        for i in xrange(
                0,
                hps_event.getNumberOfParticles(
                    HpsParticle.FINAL_STATE_PARTICLE)):
            fspList.append(
                hps_event.getParticle(HpsParticle.FINAL_STATE_PARTICLE, i))

        #########################
        #   found some candidates...lets fill plots...
        #########################
        for pair in pairList:
            if pair[0].getPosition()[1] > 0:
                clTop = pair[0]
                clBottom = pair[1]
            else:
                clTop = pair[1]
                clBottom = pair[0]
            clTopPosition = clTop.getPosition()
            clBottomPosition = clBottom.getPosition()

            topX = clTopPosition[0]
            topY = clTopPosition[1]
            topZ = clTopPosition[2]
            botX = clBottomPosition[0]
            botY = clBottomPosition[1]
            botZ = clBottomPosition[2]
            topE = clTop.getEnergy()
            botE = clBottom.getEnergy()
            Esum = topE + botE
            Ediff = abs(topE - botE)
            cl_impact_angleTop = math.atan2(topY, topX - phot_nom_x) * radian
            cl_impact_angleBottom = math.atan2(botY,
                                               botX - phot_nom_x) * radian
            if cl_impact_angleTop < 0.:
                cl_impact_angleTop = cl_impact_angleTop + 360.
            if cl_impact_angleBottom < 0.:
                cl_impact_angleBottom = cl_impact_angleBottom + 360.
            coplanarity = cl_impact_angleBottom - cl_impact_angleTop
            myhist.h_coplan_Esum1.Fill(Esum, coplanarity)

            #            cl_d_top= math.sqrt( (topX - phot_nom_x)*(topX - phot_nom_x) + topY*topY )- (60. + 100*(topE - 0.85)*(topE - 0.85) )
            #            cl_d_bottom= math.sqrt( (botX - phot_nom_x)*(botX - phot_nom_x) + botY*botY )- (60. + 100*(botE - 0.85)*(botE - 0.85) )

            #do track matching
            trTop = ecalMatchTrack(fspList, clTop)
            trBottom = ecalMatchTrack(fspList, clBottom)
            #initial PDG assignments
            trEle = trTop
            trPos = trBottom
            clEle = clTop
            clPos = clBottom

            if topX > 0:  #assign the ele & pos with respect to the side of ECAL the cluster is on
                trEle = trBottom
                clEle = clBottom
                trPos = trTop
                clPos = clTop

#            if trEle is not None and trEle.getPDG() == -11 :# whoops, it's a positron
#                trEle=trBottom
#                trPos=trTop
#                clEle=clBottom
#                clPos=clTop
#            if trPos is not None and trPos.getPDG() == 11 : # whoops, it's an electron
#                trEle=trBottom
#                trPos=trTop
#                clEle=clBottom
#                clPos=clTop
#for ++ or -- events, this will get flipped twice...live with it...

            if topY * botY > 0:
                print "both clusters in same half?? How could this happen?" + str(
                    topY) + " vs " + str(botY)

#            print coplanarity
            myhist.fillBand("_copAll_", trEle, clEle, trPos, clPos)

            if abs(coplanarity - 180) < 10:
                myhist.fillBand("_cop180_", trEle, clEle, trPos, clPos)
                if Esum > myhist.midESumLow and Esum < myhist.midESumHigh:
                    myhist.fillBand("_cop180_midESum_", trEle, clEle, trPos,
                                    clPos)
                if myhist.inSuperFiducialRegion(
                        topX, topY) and myhist.inSuperFiducialRegion(
                            botX, botY):
                    myhist.fillBand("_cop180_SuperFid", trEle, clEle, trPos,
                                    clPos)
                    #                    if  myhist.momFromPositionEclUpperCut(topE,myhist.momFromECalPosition(topX,topZ,beamAngle,myhist.BEff)) and myhist.momFromPositionEclUpperCut(botE,myhist.momFromECalPosition(botX,botZ,beamAngle,myhist.BEff)):
                    if not myhist.inPhotonHole(
                            topX, topY) and not myhist.inPhotonHole(
                                botX, botY):
                        myhist.fillBand("_cop180_SuperFid_CutPhotons", trEle,
                                        clEle, trPos, clPos)
                if Ediff < 0.2 and len(pairList) == 1:
                    myhist.fillBand("_cop180_Holly_", trEle, clEle, trPos,
                                    clPos)
#                if  myhist.momFromPositionEclUpperCut(topE,myhist.momFromECalPosition(topX,topZ,beamAngle,myhist.BEff)) and myhist.momFromPositionEclUpperCut(botE,myhist.momFromECalPosition(botX,botZ,beamAngle,myhist.BEff)):
                if not myhist.inPhotonHole(
                        topX, topY) and not myhist.inPhotonHole(botX, botY):
                    myhist.fillBand("_cop180_CutPhotons", trEle, clEle, trPos,
                                    clPos)
            elif abs(coplanarity - 160) < 10:
                myhist.fillBand("_cop160_", trEle, clEle, trPos, clPos)
                if Esum > myhist.midESumLow and Esum < myhist.midESumHigh:
                    myhist.fillBand("_cop160_midESum_", trEle, clEle, trPos,
                                    clPos)
                if myhist.inSuperFiducialRegion(
                        topX, topY) and myhist.inSuperFiducialRegion(
                            botX, botY):
                    myhist.fillBand("_cop160_SuperFid", trEle, clEle, trPos,
                                    clPos)
                    #                    if  myhist.momFromPositionEclUpperCut(topE,myhist.momFromECalPosition(topX,topZ,beamAngle,myhist.BEff)) and myhist.momFromPositionEclUpperCut(botE,myhist.momFromECalPosition(botX,botZ,beamAngle,myhist.BEff)):
                    if not myhist.inPhotonHole(
                            topX, topY) and not myhist.inPhotonHole(
                                botX, botY):
                        myhist.fillBand("_cop160_SuperFid_CutPhotons", trEle,
                                        clEle, trPos, clPos)
#                if  myhist.momFromPositionEclUpperCut(topE,myhist.momFromECalPosition(topX,topZ,beamAngle,myhist.BEff)) and myhist.momFromPositionEclUpperCut(botE,myhist.momFromECalPosition(botX,botZ,beamAngle,myhist.BEff)):
                if not myhist.inPhotonHole(
                        topX, topY) and not myhist.inPhotonHole(botX, botY):
                    myhist.fillBand("_cop160_CutPhotons", trEle, clEle, trPos,
                                    clPos)

#            particle = hps_event.getParticle(HpsParticle.TC_V0_CANDIDATE, candidateList[index])
#            myhist.fillCandidateHistograms(particle)

#    if(nPassTrkCuts>0):
    myhist.saveHistograms(output_file)
コード例 #10
0
def main():
    global beamEnergy
    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(description="PyRoot analysis demostrating the us of a DST.")
    parser.add_argument("dst_file", help="ROOT DST file to process")
    parser.add_argument("-o", "--output", help="Name of output pdf file")
    parser.add_argument("-m", "--mc", help="is MonteCarlo")
    parser.add_argument("-p", "--pulser", help="is Pulser")
    parser.add_argument("-e", "--energy", help="beam energy")
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user
    if args.output:
        output_file = args.output
    else:
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to "
        print output_file

    print "[ HPS ANALYSIS ]:  Output file is " + output_file
    isMC = False
    if args.mc:
        print "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC = True

    isPulser = False
    if args.pulser:
        print "[ HPS ANALYSIS ]: Setting to run from a pulser file"
        isPulser = True

    if args.energy:
        print "Setting beam energy to " + args.energy
        beamEnergy = float(args.energy)

    myhist = myHistograms(beamEnergy)

    #################################
    #       Event Selection
    ################################
    # clean up event first
    #### nominal selection

    requireECalFiducial = False
    requireECalSuperFiducial = False  # this is included as separate histograms now...leave false!
    positronMomentumFromPositionCut = False  # this is included as separate histograms now...leave false!
    requireTopBottomCut = True
    requireLeftRightCut = True

    if isMC:
        smearEnergy = False
        smearRes = 0.05
        myhist.setSmearEnergy(smearEnergy, smearRes)

    trackKiller = False
    killInMomentum = False
    killInClusterPosition = True
    #    effFileName='/u/br/mgraham/hps-analysis/TrackEfficiency/cop180_EfficiencyResults.root'
    #    effDataName='h_Ecl_hps_005772_eleEff'
    #    effMCName='h_Ecl_tritrig-NOSUMCUT_HPS-EngRun2015-Nominal-v5-0_eleEff'

    effFileName = "/u/br/mgraham/hps-analysis/TrackEfficiency/cop180_midESum_TwoD-EfficiencyResults.root"
    effDataName = "h_XvsY_hps_005772_eleEff"
    effMCName = "h_XvsY_tritrig-NOSUMCUT_HPS-EngRun2015-Nominal-v5-0_eleEff"

    if trackKiller:
        effFile = ROOT.TFile(effFileName)
        print "Getting data efficiency from " + effFileName
        #    effData=getEffTH1(effFile,effDataName)
        #    effMC=getEffTH1(effFile,effMCName)
        effData = getEffTH2(effFile, effDataName)
        effMC = getEffTH2(effFile, effMCName)
        effData.Print("v")
        effMC.Print("v")
        effData.Divide(effMC)  # this will be the killing factor
        effData.Print("V")

    # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    # use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from " + args.dst_file
    tree = ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file) + "*")
    # Create an HpsEvent object in order to read the TClonesArray
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))

    # --- Analysis ---#
    # ----------------#

    # counters
    nEvents = 0
    nPassBasicCuts = 0

    #   //================ Time coincidence ======================================
    coincide_pars_mean = [0.289337, -2.81998, 9.03475, -12.93, 8.71476, -2.26969]
    coincide_pars_sigm = [4.3987, -24.2371, 68.9567, -98.2586, 67.562, -17.8987]

    formula_pol5 = "[0] + x*( [1] + x*( [2] + x*( [3] + x*( [4] + x*( [5] ) ) ) ) ) "
    f_coincide_clust_mean = ROOT.TF1("f_coincide_clust_mean", formula_pol5, 0.0, 1.4)
    f_coincide_clust_sigm = ROOT.TF1("f_coincide_clust_sigm", formula_pol5, 0.0, 1.4)
    f_coincide_clust_mean.SetParameters(np.array(coincide_pars_mean))
    f_coincide_clust_sigm.SetParameters(np.array(coincide_pars_sigm))
    #   //The cut is            === mean - 3sigma < dt < mean + 3sigma ===

    clTimeMin = 30
    clTimeMax = 50

    if beamEnergy == 2.3:
        clTimeMin = 40
        clTimeMax = 65
    energyRatio = beamEnergy / 1.05  # ratio of beam energies references to 1.05 GeV (2015 run)

    seedCnt = 0
    # Loop over all events in the file
    for entry in xrange(0, tree.GetEntries()):

        # Print the event number every 500 events
        if (entry + 1) % 100 == 0:
            print "Event " + str(entry + 1)
        tree.GetEntry(entry)
        if not hps_event.isPair1Trigger() and not isMC and not isPulser:
            continue
        nEvents += 1

        nPassBasicCuts += 1
        #        print "passed basic cuts"
        pairList = []
        bestCandidate = -99
        pairsFound = 0
        for i in range(0, hps_event.getNumberOfEcalClusters()):
            cl1 = hps_event.getEcalCluster(i)
            cl1Position = cl1.getPosition()
            cl_xi = cl1Position[0]
            cl_yi = cl1Position[1]
            cl_zi = cl1Position[2]
            cl_ti = cl1.getClusterTime()
            cl_Ei = cl1.getEnergy()
            myhist.h_clTime1vsclE.Fill(cl_Ei, cl_ti)
            cl_di = math.sqrt((cl_xi - phot_nom_x) * (cl_xi - phot_nom_x) + cl_yi * cl_yi)
            #            print 'looking at clusters'
            # if(!fid_ECal(cl_xi,cl_yi))
            #        continue
            if requireECalFiducial and not myhist.inFiducialRegion(cl_xi, cl_yi):
                continue
            if requireECalSuperFiducial and not myhist.inSuperFiducialRegion(cl_xi, cl_yi):
                continue
            if not (cl_ti > clTimeMin and cl_ti < clTimeMax):
                continue
            if positronMomentumFromPositionCut and not myhist.momFromPositionEclUpperCut(
                cl_Ei, myhist.momFromECalPosition(cl_xi, cl_zi, beamAngle, myhist.BEff)
            ):
                continue
            #            print 'Found first good cluster'
            for j in range(i + 1, hps_event.getNumberOfEcalClusters()):
                cl2 = hps_event.getEcalCluster(j)
                cl2Position = cl2.getPosition()
                cl_xj = cl2Position[0]
                cl_yj = cl2Position[1]
                cl_zj = cl2Position[2]
                cl_tj = cl2.getClusterTime()
                cl_Ej = cl2.getEnergy()

                cl_dj = math.sqrt((cl_xj - phot_nom_x) * (cl_xj - phot_nom_x) + cl_yj * cl_yj)
                Esum = cl_Ei + cl_Ej
                if requireECalFiducial and not myhist.inFiducialRegion(cl_xj, cl_yj):
                    continue
                if requireECalSuperFiducial and not myhist.inSuperFiducialRegion(cl_xj, cl_yj):
                    continue
                if not (cl_tj > clTimeMin and cl_tj < clTimeMax):
                    continue
                if positronMomentumFromPositionCut and not myhist.momFromPositionEclUpperCut(
                    cl_Ej, myhist.momFromECalPosition(cl_xj, cl_zj, beamAngle, myhist.BEff)
                ):
                    continue
                #                print 'Passed the probable positron cut'

                myhist.h_clTime1vsclTime2.Fill(cl_ti, cl_tj)

                dt = cl_ti - cl_tj
                #                delt_t_mean = f_coincide_clust_mean.Eval(Esum)
                #                delt_t_sigm = f_coincide_clust_sigm.Eval(Esum)
                #      divide by 2 since these parameters were extracted from 1.05GeV Data (this is kludgy!)
                delt_t_mean = f_coincide_clust_mean.Eval(Esum / energyRatio)
                delt_t_sigm = f_coincide_clust_sigm.Eval(Esum / energyRatio)
                if not (dt < delt_t_mean + 3 * delt_t_sigm and dt > delt_t_mean - 3 * delt_t_sigm):
                    continue
                #         //make sure they are top/bottom
                #                print 'Passed the timing cut'
                #                print str(cl_yi)+"   " + str(cl_yj)
                if requireTopBottomCut and cl_yi * cl_yj > 0:
                    continue

                if requireLeftRightCut and cl_xi * cl_xj > 0:
                    continue

                #                print 'Found a pair!!!!'

                clpair = [cl1, cl2]
                pairList.append(clpair)

        pairsFound += len(pairList)
        #        if len(pairList) >0 : print "found this many pairs "+str(len(pairList))

        fspList = []
        for i in xrange(0, hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE)):
            fspList.append(hps_event.getParticle(HpsParticle.FINAL_STATE_PARTICLE, i))

        #########################
        #   found some candidates...lets fill plots...
        #########################
        for pair in pairList:
            if pair[0].getPosition()[1] > 0:
                clTop = pair[0]
                clBottom = pair[1]
            else:
                clTop = pair[1]
                clBottom = pair[0]
            clTopPosition = clTop.getPosition()
            clBottomPosition = clBottom.getPosition()

            topX = clTopPosition[0]
            topY = clTopPosition[1]
            topZ = clTopPosition[2]
            botX = clBottomPosition[0]
            botY = clBottomPosition[1]
            botZ = clBottomPosition[2]
            topE = clTop.getEnergy()
            botE = clBottom.getEnergy()
            Esum = topE + botE
            Ediff = abs(topE - botE)
            cl_impact_angleTop = math.atan2(topY, topX - phot_nom_x) * radian
            cl_impact_angleBottom = math.atan2(botY, botX - phot_nom_x) * radian
            if cl_impact_angleTop < 0.0:
                cl_impact_angleTop = cl_impact_angleTop + 360.0
            if cl_impact_angleBottom < 0.0:
                cl_impact_angleBottom = cl_impact_angleBottom + 360.0
            coplanarity = cl_impact_angleBottom - cl_impact_angleTop
            myhist.h_coplan_Esum1.Fill(Esum, coplanarity)

            #            cl_d_top= math.sqrt( (topX - phot_nom_x)*(topX - phot_nom_x) + topY*topY )- (60. + 100*(topE - 0.85)*(topE - 0.85) )
            #            cl_d_bottom= math.sqrt( (botX - phot_nom_x)*(botX - phot_nom_x) + botY*botY )- (60. + 100*(botE - 0.85)*(botE - 0.85) )

            # do track matching
            trTop = ecalMatchTrack(fspList, clTop)
            trBottom = ecalMatchTrack(fspList, clBottom)
            # initial PDG assignments
            trEle = trTop
            trPos = trBottom
            clEle = clTop
            clPos = clBottom

            if topX > 0:  # assign the ele & pos with respect to the side of ECAL the cluster is on
                trEle = trBottom
                clEle = clBottom
                trPos = trTop
                clPos = clTop

            if trEle is not None and trEle.getPDG() == -11:  # whoops, it's a positron
                trEle = trBottom
                trPos = trTop
                clEle = clBottom
                clPos = clTop
            #            if trPos is not None and trPos.getPDG() == 11 : # whoops, it's an electron
            #                trEle=trBottom
            #                trPos=trTop
            #                clEle=clBottom
            #                clPos=clTop
            # for ++ or -- events, this will get flipped twice...live with it...

            if topY * botY > 0:
                print "both clusters in same half?? How could this happen?" + str(topY) + " vs " + str(botY)

            if trackKiller and isMC:
                if killInMomentum:
                    p = clEle.getEnergy()
                    bin = effData.FindBin(p)
                    tkEff = effData.GetBinContent(bin)
                    print str(p) + " " + str(bin) + " " + str(tkEff)
                    if random.random() > tkEff:  # high ratio of efficiencies, this hardly  kills...low, kills a lot
                        print "REJECTING THIS ELECTRON TRACK!!! " + str(p)
                        trEle = None
                    #### same thing for positron side
                    p = clPos.getEnergy()
                    bin = effData.FindBin(p)
                    tkEff = effData.GetBinContent(bin)
                    print str(p) + " " + str(bin) + " " + str(tkEff)
                    if random.random() > tkEff:  # high ratio of efficiencies, this hardly  kills...low, kills a lot
                        print "REJECTING THIS ELECTRON TRACK!!! " + str(p)
                        trPos = None
                if killInClusterPosition:
                    clX = clEle.getPosition()[0]
                    clY = clEle.getPosition()[1]
                    bin = effData.FindBin(clX, clY)
                    tkEff = effData.GetBinContent(bin)
                    if random.random() > tkEff and tkEff != 0.0:
                        print str(clX) + " " + str(clY) + " " + str(bin) + " " + str(tkEff)
                        print "REJECTING THIS ELECTRON TRACK!!! " + str(clX)
                        trEle = None
                    clX = clPos.getPosition()[0]
                    clY = clPos.getPosition()[1]
                    bin = effData.FindBin(
                        -clX + 80, clY
                    )  # flip sign +80mm for positron side (this isn't strictly correct)!!!
                    tkEff = effData.GetBinContent(bin)
                    if random.random() > tkEff and tkEff != 0.0:
                        print str(clX) + " " + str(clY) + " " + str(bin) + " " + str(tkEff)
                        print "REJECTING THIS POSITRON TRACK!!! " + str(clX)
                        trPos = None

            myhist.fillBand("_copAll_", trEle, clEle, trPos, clPos)

            if abs(coplanarity - 180) < 10:
                #  some debugging here...
                #  for events where there is a positron track and no electron track
                #  check to see if there maybe is a track that's could be associated with this clus
                if trEle is None and trPos is not None and trPos.getCharge() > 0:
                    nMatchEle = 0
                    print "found positron but not electron!  ele energy = " + str(
                        clEle.getEnergy()
                    ) + "; ele clX = " + str(clEle.getPosition()[0]) + "; ele clY = " + str(clEle.getPosition()[1])
                    # loop through the electrons in event and check to see if on is in the same half
                    for fsp_n in xrange(0, hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE)):
                        fsp = hps_event.getParticle(HpsParticle.FINAL_STATE_PARTICLE, fsp_n)
                        if fsp.getType() != 0:
                            if fsp.getType() > 32:
                                continue
                            track = fsp.getTracks()[0]
                            slope = track.getTanLambda()
                            if (
                                fsp.getCharge() < 0
                                and slope * clEle.getPosition()[1] > 0
                                and pMag(fsp.getMomentum()) < 0.8
                            ):
                                nMatchEle = nMatchEle + 1
                                print "found and electron in right half!!"
                                print "track p = " + str(pMag(fsp.getMomentum()))
                                trkAtEcal = track.getPositionAtEcal()
                                delX = trkAtEcal[0] - clEle.getPosition()[0]
                                delY = trkAtEcal[1] - clEle.getPosition()[1]
                                print "trk-clEle delX = " + str(delX) + "; delY = " + str(delY)
                                myhist.h_misEle_delXvsdelY.Fill(delX, delY)
                                myhist.h_misEle_trkPvsclE.Fill(pMag(fsp.getMomentum()), clEle.getEnergy())
                                if len(fsp.getClusters()) > 0:
                                    clThisE = fsp.getClusters()[0]
                                    print "...this track matched to cluster with ele energy = " + str(
                                        clThisE.getEnergy()
                                    ) + "; ele clX = " + str(clThisE.getPosition()[0]) + "; ele clY = " + str(
                                        clThisE.getPosition()[1]
                                    )
                    ########################
                    myhist.h_misEle_eleTrks.Fill(nMatchEle)
                myhist.fillBand("_cop180_", trEle, clEle, trPos, clPos)
                if Esum > myhist.midESumLow and Esum < myhist.midESumHigh:
                    myhist.fillBand("_cop180_midESum_", trEle, clEle, trPos, clPos)
                    if myhist.inSuperFiducialRegion(topX, topY) and myhist.inSuperFiducialRegion(botX, botY):
                        myhist.fillBand("_cop180_midESum_SuperFid", trEle, clEle, trPos, clPos)
                    if not myhist.inSuperFiducialRegion(topX, topY) and not myhist.inSuperFiducialRegion(botX, botY):
                        myhist.fillBand("_cop180_midESum_AntiSuperFid", trEle, clEle, trPos, clPos)
                if myhist.inSuperFiducialRegion(topX, topY) and myhist.inSuperFiducialRegion(botX, botY):
                    myhist.fillBand("_cop180_SuperFid", trEle, clEle, trPos, clPos)
                    if not myhist.inPhotonHole(topX, topY) and not myhist.inPhotonHole(botX, botY):
                        myhist.fillBand("_cop180_SuperFid_CutPhotons", trEle, clEle, trPos, clPos)
                if not myhist.inSuperFiducialRegion(topX, topY) and not myhist.inSuperFiducialRegion(botX, botY):
                    myhist.fillBand("_cop180_AntiSuperFid", trEle, clEle, trPos, clPos)
                if Ediff < 0.2 and len(pairList) == 1:
                    myhist.fillBand("_cop180_Holly_", trEle, clEle, trPos, clPos)
                if not myhist.inPhotonHole(topX, topY) and not myhist.inPhotonHole(botX, botY):
                    myhist.fillBand("_cop180_CutPhotons", trEle, clEle, trPos, clPos)
            elif abs(coplanarity - 160) < 10:
                myhist.fillBand("_cop160_", trEle, clEle, trPos, clPos)
                if Esum > myhist.midESumLow and Esum < myhist.midESumHigh:
                    myhist.fillBand("_cop160_midESum_", trEle, clEle, trPos, clPos)
                if myhist.inSuperFiducialRegion(topX, topY) and myhist.inSuperFiducialRegion(botX, botY):
                    myhist.fillBand("_cop160_SuperFid", trEle, clEle, trPos, clPos)
                    #                    if  myhist.momFromPositionEclUpperCut(topE,myhist.momFromECalPosition(topX,topZ,beamAngle,myhist.BEff)) and myhist.momFromPositionEclUpperCut(botE,myhist.momFromECalPosition(botX,botZ,beamAngle,myhist.BEff)):
                    if not myhist.inPhotonHole(topX, topY) and not myhist.inPhotonHole(botX, botY):
                        myhist.fillBand("_cop160_SuperFid_CutPhotons", trEle, clEle, trPos, clPos)
                #                if  myhist.momFromPositionEclUpperCut(topE,myhist.momFromECalPosition(topX,topZ,beamAngle,myhist.BEff)) and myhist.momFromPositionEclUpperCut(botE,myhist.momFromECalPosition(botX,botZ,beamAngle,myhist.BEff)):
                if not myhist.inPhotonHole(topX, topY) and not myhist.inPhotonHole(botX, botY):
                    myhist.fillBand("_cop160_CutPhotons", trEle, clEle, trPos, clPos)

    #            particle = hps_event.getParticle(HpsParticle.TC_V0_CANDIDATE, candidateList[index])
    #            myhist.fillCandidateHistograms(particle)

    #    if(nPassTrkCuts>0):
    myhist.saveHistograms(output_file)
コード例 #11
0
ファイル: debugStuff.py プロジェクト: JeffersonLab/HPS-CODE
def main():
    global beamEnergy
    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(description="PyRoot analysis demostrating the us of a DST.")
    parser.add_argument("dst_file", help="ROOT DST file to process")
    parser.add_argument("-o", "--output", help="Name of output pdf file")
    parser.add_argument("-m", "--mc", help="is MonteCarlo")
    parser.add_argument("-p", "--pulser", help="is Pulser")
    parser.add_argument("-e", "--energy", help="beam energy")
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user
    if args.output:
        output_file = args.output
    else:
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to "
        print output_file

    print "[ HPS ANALYSIS ]:  Output file is " + output_file
    isMC = False
    if args.mc:
        print "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC = True

    isPulser = False
    if args.pulser:
        print "[ HPS ANALYSIS ]: Setting to run from a pulser file"
        isPulser = True

    if args.energy:
        print "Setting beam energy to " + args.energy
        beamEnergy = float(args.energy)

    myhist = myHistograms(beamEnergy)

    #################################
    #       Event Selection
    ################################
    # clean up event first
    #### nominal selection

    requireECalFiducial = False
    requireECalSuperFiducial = False  # this is included as separate histograms now...leave false!
    positronMomentumFromPositionCut = False  # this is included as separate histograms now...leave false!
    requireTopBottomCut = True
    requireLeftRightCut = True

    if isMC:
        smearEnergy = False
        smearRes = 0.05
        myhist.setSmearEnergy(smearEnergy, smearRes)

    # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    # use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from " + args.dst_file
    tree = ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file) + "*")
    # Create an HpsEvent object in order to read the TClonesArray
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))

    # --- Analysis ---#
    # ----------------#

    # counters
    nEvents = 0
    nPassBasicCuts = 0

    #   //================ Time coincidence ======================================
    coincide_pars_mean = [0.289337, -2.81998, 9.03475, -12.93, 8.71476, -2.26969]
    coincide_pars_sigm = [4.3987, -24.2371, 68.9567, -98.2586, 67.562, -17.8987]

    formula_pol5 = "[0] + x*( [1] + x*( [2] + x*( [3] + x*( [4] + x*( [5] ) ) ) ) ) "
    f_coincide_clust_mean = ROOT.TF1("f_coincide_clust_mean", formula_pol5, 0.0, 1.4)
    f_coincide_clust_sigm = ROOT.TF1("f_coincide_clust_sigm", formula_pol5, 0.0, 1.4)
    f_coincide_clust_mean.SetParameters(np.array(coincide_pars_mean))
    f_coincide_clust_sigm.SetParameters(np.array(coincide_pars_sigm))
    #   //The cut is            === mean - 3sigma < dt < mean + 3sigma ===

    clTimeMin = 30
    clTimeMax = 50

    if beamEnergy == 2.3:
        clTimeMin = 40
        clTimeMax = 65
    energyRatio = beamEnergy / 1.05  # ratio of beam energies references to 1.05 GeV (2015 run)

    seedCnt = 0
    # Loop over all events in the file
    for entry in xrange(0, tree.GetEntries()):

        # Print the event number every 500 events
        if (entry + 1) % 10000 == 0:
            print "Event " + str(entry + 1)
        tree.GetEntry(entry)
        if not hps_event.isPair1Trigger() and not isMC and not isPulser:
            continue
        nEvents += 1

        nPassBasicCuts += 1
        #        print "passed basic cuts"
        pairList = []
        bestCandidate = -99
        pairsFound = 0
        print "looking at mcparticles"
        for i in range(0, hps_event.n_mc_particles):
            mcp = hps_event.getMCParticle(i)
            print type(mcp)
            if mcp is None:
                break
            if mcp.getEnergy() is None:
                print "no PDGID"
                continue
            else:
                print mcp.getEnergy()

        print "....done"

        for i in range(0, hps_event.getNumberOfEcalClusters()):
            cl1 = hps_event.getEcalCluster(i)
            cl1Position = cl1.getPosition()
            cl_xi = cl1Position[0]
            cl_yi = cl1Position[1]
            cl_zi = cl1Position[2]
            cl_ti = cl1.getClusterTime()
            cl_Ei = cl1.getEnergy()
            myhist.h_clTime1vsclE.Fill(cl_Ei, cl_ti)
            cl_di = math.sqrt((cl_xi - phot_nom_x) * (cl_xi - phot_nom_x) + cl_yi * cl_yi)
            #            print 'looking at clusters'
            # if(!fid_ECal(cl_xi,cl_yi))
            #        continue
            if requireECalFiducial and not myhist.inFiducialRegion(cl_xi, cl_yi):
                continue
            if requireECalSuperFiducial and not myhist.inSuperFiducialRegion(cl_xi, cl_yi):
                continue
            if not (cl_ti > clTimeMin and cl_ti < clTimeMax):
                continue
            if positronMomentumFromPositionCut and not myhist.momFromPositionEclUpperCut(
                cl_Ei, myhist.momFromECalPosition(cl_xi, cl_zi, beamAngle, myhist.BEff)
            ):
                continue
            #            print 'Found first good cluster'
            for j in range(i + 1, hps_event.getNumberOfEcalClusters()):
                cl2 = hps_event.getEcalCluster(j)
                cl2Position = cl2.getPosition()
                cl_xj = cl2Position[0]
                cl_yj = cl2Position[1]
                cl_zj = cl2Position[2]
                cl_tj = cl2.getClusterTime()
                cl_Ej = cl2.getEnergy()

                cl_dj = math.sqrt((cl_xj - phot_nom_x) * (cl_xj - phot_nom_x) + cl_yj * cl_yj)
                Esum = cl_Ei + cl_Ej
                #         //      if(!energySlopeCut(cl_xj,cl_d,cl_Ej))
                #         //        continue
                if requireECalFiducial and not myhist.inFiducialRegion(cl_xj, cl_yj):
                    continue
                if requireECalSuperFiducial and not myhist.inSuperFiducialRegion(cl_xj, cl_yj):
                    continue
                if not (cl_tj > clTimeMin and cl_tj < clTimeMax):
                    continue
                #                print 'Found second good cluster'
                #                //if(!fid_ECal(cl_x[j],cl_y[j]))
                #         //  continue
                #         //      if(!(energySlopeCut(cl_xi,cl_di,cl_Ei) || energySlopeCut(cl_xj,cl_dj,cl_Ej)))
                #         //   continue
                if positronMomentumFromPositionCut and not myhist.momFromPositionEclUpperCut(
                    cl_Ej, myhist.momFromECalPosition(cl_xj, cl_zj, beamAngle, myhist.BEff)
                ):
                    continue
                #                print 'Passed the probable positron cut'

                myhist.h_clTime1vsclTime2.Fill(cl_ti, cl_tj)

                dt = cl_ti - cl_tj
                #                delt_t_mean = f_coincide_clust_mean.Eval(Esum)
                #                delt_t_sigm = f_coincide_clust_sigm.Eval(Esum)
                #      divide by 2 since these parameters were extracted from 1.05GeV Data (this is kludgy!)
                delt_t_mean = f_coincide_clust_mean.Eval(Esum / energyRatio)
                delt_t_sigm = f_coincide_clust_sigm.Eval(Esum / energyRatio)
                if not (dt < delt_t_mean + 3 * delt_t_sigm and dt > delt_t_mean - 3 * delt_t_sigm):
                    continue
                #         //make sure they are top/bottom
                #                print 'Passed the timing cut'
                #                print str(cl_yi)+"   " + str(cl_yj)
                if requireTopBottomCut and cl_yi * cl_yj > 0:
                    continue

                if requireLeftRightCut and cl_xi * cl_xj > 0:
                    continue

                #                print 'Found a pair!!!!'

                clpair = [cl1, cl2]
                pairList.append(clpair)

        pairsFound += len(pairList)
        #        if len(pairList) >0 : print "found this many pairs "+str(len(pairList))

        fspList = []
        for i in xrange(0, hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE)):
            fspList.append(hps_event.getParticle(HpsParticle.FINAL_STATE_PARTICLE, i))

        #########################
        #   found some candidates...lets fill plots...
        #########################
        for pair in pairList:
            if pair[0].getPosition()[1] > 0:
                clTop = pair[0]
                clBottom = pair[1]
            else:
                clTop = pair[1]
                clBottom = pair[0]
            clTopPosition = clTop.getPosition()
            clBottomPosition = clBottom.getPosition()

            topX = clTopPosition[0]
            topY = clTopPosition[1]
            topZ = clTopPosition[2]
            botX = clBottomPosition[0]
            botY = clBottomPosition[1]
            botZ = clBottomPosition[2]
            topE = clTop.getEnergy()
            botE = clBottom.getEnergy()
            Esum = topE + botE
            Ediff = abs(topE - botE)
            cl_impact_angleTop = math.atan2(topY, topX - phot_nom_x) * radian
            cl_impact_angleBottom = math.atan2(botY, botX - phot_nom_x) * radian
            if cl_impact_angleTop < 0.0:
                cl_impact_angleTop = cl_impact_angleTop + 360.0
            if cl_impact_angleBottom < 0.0:
                cl_impact_angleBottom = cl_impact_angleBottom + 360.0
            coplanarity = cl_impact_angleBottom - cl_impact_angleTop
            myhist.h_coplan_Esum1.Fill(Esum, coplanarity)

            #            cl_d_top= math.sqrt( (topX - phot_nom_x)*(topX - phot_nom_x) + topY*topY )- (60. + 100*(topE - 0.85)*(topE - 0.85) )
            #            cl_d_bottom= math.sqrt( (botX - phot_nom_x)*(botX - phot_nom_x) + botY*botY )- (60. + 100*(botE - 0.85)*(botE - 0.85) )

            # do track matching
            trTop = ecalMatchTrack(fspList, clTop)
            trBottom = ecalMatchTrack(fspList, clBottom)
            # initial PDG assignments
            trEle = trTop
            trPos = trBottom
            clEle = clTop
            clPos = clBottom

            if topX > 0:  # assign the ele & pos with respect to the side of ECAL the cluster is on
                trEle = trBottom
                clEle = clBottom
                trPos = trTop
                clPos = clTop

            #            if trEle is not None and trEle.getPDG() == -11 :# whoops, it's a positron
            #                trEle=trBottom
            #                trPos=trTop
            #                clEle=clBottom
            #                clPos=clTop
            #            if trPos is not None and trPos.getPDG() == 11 : # whoops, it's an electron
            #                trEle=trBottom
            #                trPos=trTop
            #                clEle=clBottom
            #                clPos=clTop
            # for ++ or -- events, this will get flipped twice...live with it...

            if topY * botY > 0:
                print "both clusters in same half?? How could this happen?" + str(topY) + " vs " + str(botY)

            #            print coplanarity
            myhist.fillBand("_copAll_", trEle, clEle, trPos, clPos)

            if abs(coplanarity - 180) < 10:
                myhist.fillBand("_cop180_", trEle, clEle, trPos, clPos)
                if Esum > myhist.midESumLow and Esum < myhist.midESumHigh:
                    myhist.fillBand("_cop180_midESum_", trEle, clEle, trPos, clPos)
                if myhist.inSuperFiducialRegion(topX, topY) and myhist.inSuperFiducialRegion(botX, botY):
                    myhist.fillBand("_cop180_SuperFid", trEle, clEle, trPos, clPos)
                    #                    if  myhist.momFromPositionEclUpperCut(topE,myhist.momFromECalPosition(topX,topZ,beamAngle,myhist.BEff)) and myhist.momFromPositionEclUpperCut(botE,myhist.momFromECalPosition(botX,botZ,beamAngle,myhist.BEff)):
                    if not myhist.inPhotonHole(topX, topY) and not myhist.inPhotonHole(botX, botY):
                        myhist.fillBand("_cop180_SuperFid_CutPhotons", trEle, clEle, trPos, clPos)
                if Ediff < 0.2 and len(pairList) == 1:
                    myhist.fillBand("_cop180_Holly_", trEle, clEle, trPos, clPos)
                #                if  myhist.momFromPositionEclUpperCut(topE,myhist.momFromECalPosition(topX,topZ,beamAngle,myhist.BEff)) and myhist.momFromPositionEclUpperCut(botE,myhist.momFromECalPosition(botX,botZ,beamAngle,myhist.BEff)):
                if not myhist.inPhotonHole(topX, topY) and not myhist.inPhotonHole(botX, botY):
                    myhist.fillBand("_cop180_CutPhotons", trEle, clEle, trPos, clPos)
            elif abs(coplanarity - 160) < 10:
                myhist.fillBand("_cop160_", trEle, clEle, trPos, clPos)
                if Esum > myhist.midESumLow and Esum < myhist.midESumHigh:
                    myhist.fillBand("_cop160_midESum_", trEle, clEle, trPos, clPos)
                if myhist.inSuperFiducialRegion(topX, topY) and myhist.inSuperFiducialRegion(botX, botY):
                    myhist.fillBand("_cop160_SuperFid", trEle, clEle, trPos, clPos)
                    #                    if  myhist.momFromPositionEclUpperCut(topE,myhist.momFromECalPosition(topX,topZ,beamAngle,myhist.BEff)) and myhist.momFromPositionEclUpperCut(botE,myhist.momFromECalPosition(botX,botZ,beamAngle,myhist.BEff)):
                    if not myhist.inPhotonHole(topX, topY) and not myhist.inPhotonHole(botX, botY):
                        myhist.fillBand("_cop160_SuperFid_CutPhotons", trEle, clEle, trPos, clPos)
                #                if  myhist.momFromPositionEclUpperCut(topE,myhist.momFromECalPosition(topX,topZ,beamAngle,myhist.BEff)) and myhist.momFromPositionEclUpperCut(botE,myhist.momFromECalPosition(botX,botZ,beamAngle,myhist.BEff)):
                if not myhist.inPhotonHole(topX, topY) and not myhist.inPhotonHole(botX, botY):
                    myhist.fillBand("_cop160_CutPhotons", trEle, clEle, trPos, clPos)

    #            particle = hps_event.getParticle(HpsParticle.TC_V0_CANDIDATE, candidateList[index])
    #            myhist.fillCandidateHistograms(particle)

    #    if(nPassTrkCuts>0):
    myhist.saveHistograms(output_file)
コード例 #12
0
def main():
    global beamEnergy
    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(description='PyRoot analysis demostrating the us of a DST.')
    parser.add_argument("dst_file",  help="ROOT DST file to process")
    parser.add_argument("-o", "--output",  help="Name of output pdf file")
    parser.add_argument("-m", "--mc",  help="is MonteCarlo")
    parser.add_argument("-p", "--pulser",  help="is Pulser")
    parser.add_argument("-e","--energy",help="beam energy")
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user 
    if args.output:
        output_file = args.output
    else: 
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to " 
        print output_file


    print "[ HPS ANALYSIS ]:  Output file is "+output_file
    isMC=False
    if args.mc:
        print  "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC=True


    isPulser=False
    if args.pulser:
        print  "[ HPS ANALYSIS ]: Setting to run from a pulser file"
        isPulser=True

#    if args.energy : 
#        print 'Setting beam energy to '+args.energy
#       beamEnergy=float(args.energy)
#        myhist.setEnergyScales(beamEnergy)


#################################
#       Event Selection
################################
#clean up event first
#### nominal selection
    nTrkMax=10
    nTrkMin=2
    nPosMax=3
######  two tracks (e+/e-) exactly
#    nTrkMax=2
#    nTrkMin=2
#    nPosMax=1
###### more than 1 electron
#    nTrkMax=10
#    nTrkMin=3
#    nPosMax=1
###################
    #v0 cuts   
    v0Chi2=10
    #ESum -- full region
    v0PzMax=1.2*beamEnergy
    v0PzMin=0.55*beamEnergy
    #ESum -- Radiative region
#    v0PzMax=1.2
#    v0PzMin=0.80

    v0PyMax=0.2 #absolute value
    v0PxMax=0.2 #absolute value
    v0VzMax=25.0# mm from target
    v0VyMax=1.0# mm from target
    v0VxMax=2.0# mm from target
 #  track quality cuts
    trkChi2=10
    beamCut=0.8*beamEnergy
    minPCut=0.05
    trkPyMax=0.2
    trkPxMax=0.2
#    slopeCut=0.03
    slopeCut=0.0
    trkDeltaT=4#ns
    cluDeltaT=2#ns
    cluTrkDeltaT=4#ns
##############
#  ESum slices; upper limits    
    nSlicesESum=5 
    esumMin=0.55
    esumMax=1.2
    sliceSizeESum=0.1 #100MeV starting at esumMin
##############
    trackKiller=True
    killInMomentum=False
    killInClusterPosition=True
#    tkThreshold=0.5 #GeV, below this start killing tracks
#    tkThreshEff=1.0
#    tkLowPoint=0.20
#    tkLowPointEff=0.40
#    tkSlope=2.6 
#    tkIntercept=-0.04
    #calculate tkSlope and Intercept   
#    tkSlope=(tkThreshEff-tkLowPointEff)/(tkThreshold-tkLowPoint)
#    tkIntercept=tkThreshEff-tkSlope*tkThreshold
#    effFileName='/u/br/mgraham/hps-analysis/TrackEfficiency/cop180_EfficiencyResults.root'
#    effDataName='h_Ecl_hps_005772_eleEff'
#    effMCName='h_Ecl_tritrig-NOSUMCUT_HPS-EngRun2015-Nominal-v5-0_eleEff'


    effFileName='/u/br/mgraham/hps-analysis/TrackEfficiency/cop180_midESum_TwoD-EfficiencyResults.root'
    effDataName='h_XvsY_hps_005772_eleEff'
    effMCName='h_XvsY_tritrig-NOSUMCUT_HPS-EngRun2015-Nominal-v5-0_eleEff'


    effFile=ROOT.TFile(effFileName)
    print 'Getting data efficiency' 
#    effData=getEffTH1(effFile,effDataName)
#    effMC=getEffTH1(effFile,effMCName)
    effData=getEffTH2(effFile,effDataName)
    effMC=getEffTH2(effFile,effMCName)
    effData.Print("v")
    effMC.Print("v")
    effData.Divide(effMC)  # this will be the killing factor
    effData.Print("V")
#    for i in range(0,effData.GetNbinsX()) : 
#        print 'efficiency ratio '+str(i)+'   '+str(effData.GetBinCenter(i))+' '+str(effData.GetBinContent(i))
##############
    requireECalMatch = True
    requireECalFiducial = False
    requireECalSuperFiducial = False
    requireECalTimingCoincidence = True
    useGBL=True


     # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    #use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from "+args.dst_file
    tree=ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file)+"*")    
    # Create an HpsEvent object in order to read the TClonesArray 
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))

    #--- Analysis ---#
    #----------------#

    #counters
    nEvents=0;
    nPassBasicCuts=0;
    nPassV0Cuts=0;
    nPassTrkCuts=0;
    nPassNCand=0
    nPassECalMatch=0;
    nFakeTri=0
    
    seedCnt=0
    # Loop over all events in the file
    for entry in xrange(0, tree.GetEntries()) : 
                 
        nEpEmTB=0
        nEpEpTB=0
        nEmEmTB=0
        nEpEmTT=0
        nEpEpTT=0
        nEmEmTT=0
        nEpEmBB=0
        nEpEpBB=0
        nEmEmBB=0
        nEpGamTB=0
        nEpGamTT=0
        nEpGamBB=0
        nEmGamTB=0
        nEmGamTT=0
        nEmGamBB=0    
#        print "Next event..."
        # Print the event number every 500 events
        if (entry+1)%100 == 0 : print "Event " + str(entry+1)
        tree.GetEntry(entry)
        if not hps_event.isPair1Trigger() and not isMC and not isPulser: continue
        nEvents+=1
      
    
        # Loop over all tracks in the event
        goodtrk=[]
        gamList=[]
        eleList=[]
        posList=[]
        for fsp_n in xrange(0, hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE)) :             
            fsp = hps_event.getParticle(HpsParticle.FINAL_STATE_PARTICLE,fsp_n)
            if fsp.getType() == 0 :  #might be good photon 
                if not checkClusterFiducialAndTiming(fsp,requireECalSuperFiducial) :                     continue
                gamList.append(fsp)
            else : #maybe a good track? 
                if useGBL and  fsp.getType()<32  : continue
                if not useGBL and  fsp.getType()>31  : continue
                track=fsp.getTracks()[0]
                if track is None : continue #this shouldn't happen
                if requireECalMatch and not trkMatchAndFiducial(track.getParticle(),requireECalSuperFiducial) : continue
                if not trkMomentum(track,minPCut,beamCut):  continue
                if trackKiller and isMC and requireECalMatch: # use the ECAL cluster to do this!!! 
                    if killInMomentum : 
#                    p=pMag(fsp.getMomentum())
                        p=fsp.getEnergy()
                        bin=effData.FindBin(p)                    
                        tkEff=effData.GetBinContent(bin)
                        print str(p)+ ' '+str(bin)+' '+str(tkEff)
                        if random.random()>tkEff  :  #high ratio of efficiencies, this hardly  kills...low, kills a lot
                            print "REJECTING THIS TRACK!!! "+str(p)
                            continue
                    if killInClusterPosition:  
                        clEle=fsp.getClusters()[0]
                        clX=clEle.getPosition()[0]
                        clY=clEle.getPosition()[1]
                        if fsp.getCharge()<0 : 
                            bin=effData.FindBin(clX,clY)
                        else: 
                            bin=effData.FindBin(-clX+80,clY) # flip sign +80mm for positron side (this isn't strictly correct)!!!
                        tkEff=effData.GetBinContent(bin)
                        if random.random()>tkEff  and tkEff!=0.0:  
                            print str(clX)+ ' '+str(clY)+' '+str(bin)+' '+str(tkEff)
                            print "REJECTING THIS ELECTRON TRACK!!! "+str(clX)
                            continue

            # check to see if we already found this track
                if myhist.checkIfShared(goodtrk,fsp): 
#                    print 'fromscratch::now goodtrk is '+str(len(goodtrk))+' tracks long'
#                    for trk in goodtrk: 
#                        print len(trk.getTracks()[0].getSvtHits())
                    continue
            #otherwise this is a new track
                else : 
                    goodtrk.append(fsp)


        if len(goodtrk) > nTrkMax: continue # too many tracks

        for fsp in goodtrk :
            if fsp.getCharge() < 0 : 
                eleList.append(fsp)
            else : 
                posList.append(fsp)
                
        if len(posList) > nPosMax: continue # too many positrons!

#        print 'found '+str(len(goodtrk))+' tracks in this event'
#        print '\t\t\t   # electrons = ' +str(len(eleList))
#        print '\t\t\t   # positrons = ' +str(len(posList))
#        print '\t\t\t   # photons = ' +str(len(gamList))

#do analysis for e+e- pairs
        for pos in posList : 
            for ele in eleList: 
                if  requireECalTimingCoincidence and not myhist.clusterCoincidence(ele,pos) :
                    continue
                if ele.getMomentum()[1]*pos.getMomentum()[1] <0:
                    myhist.fillTwoBody(ele,pos,'EpEm','TB')
                elif ele.getMomentum()[1]>0 and pos.getMomentum()[1]>0:
                    myhist.fillTwoBody(ele,pos,'EpEm','TT')
                elif ele.getMomentum()[1]<0 and pos.getMomentum()[1]<0:
                    myhist.fillTwoBody(ele,pos,'EpEm','BB')
#do analysis for e-e- pairs
        for i in range(0,len(eleList)) : 
            ele1=eleList[i]
            for k in range(i+1,len(eleList)):
                ele2=eleList[k]                
                if  requireECalTimingCoincidence and not myhist.clusterCoincidence(ele1,ele2) :
                    continue
                if ele1.getMomentum()[1]*ele2.getMomentum()[1] <0:
                    myhist.fillTwoBody(ele1,ele2,'EmEm','TB')#potentially comes from WABs
                elif ele1.getMomentum()[1]>0 and ele2.getMomentum()[1]>0:
                    myhist.fillTwoBody(ele1,ele2,'EmEm','TT')
                elif ele1.getMomentum()[1]<0 and ele2.getMomentum()[1]<0:
                    myhist.fillTwoBody(ele1,ele2,'EmEm','BB')
#do analysis for e+e+ pairs
        for i in range(0,len(posList)) : 
            pos1=posList[i]
            for k in range(i+1,len(posList)):
                pos2=posList[k]                
                if  requireECalTimingCoincidence and not myhist.clusterCoincidence(pos1,pos2) :
                    continue
                if pos1.getMomentum()[1]*pos2.getMomentum()[1] <0:
                    myhist.fillTwoBody(pos1,pos2,'EpEp','TB')
                elif pos1.getMomentum()[1]>0 and pos2.getMomentum()[1]>0:
                    myhist.fillTwoBody(pos1,pos2,'EpEp','TT')
                elif pos1.getMomentum()[1]<0 and pos2.getMomentum()[1]<0:
                    myhist.fillTwoBody(pos1,pos2,'EpEp','BB')

#do analysis for e-gamma pairs 
        for ele in eleList : 
            for gam in gamList: 
                gamY=gam.getClusters().First().getPosition()[1]
                if  requireECalTimingCoincidence and not myhist.clusterCoincidence(ele,gam) :
                    continue
                if ele.getMomentum()[1]*gamY<0 : #(these could be WABS!)
                    myhist.fillTwoBody(ele,gam,'EmGam','TB')
                elif  ele.getMomentum()[1] >0 : 
                    myhist.fillTwoBody(ele,gam,'EmGam','TT')
                elif  ele.getMomentum()[1] <0 : 
                    myhist.fillTwoBody(ele,gam,'EmGam','BB')

#do analysis for e+gamma pairs ... these could be ???  
        for pos in posList : 
            for gam in gamList: 
                gamY=gam.getClusters().First().getPosition()[1]
                if  requireECalTimingCoincidence and not myhist.clusterCoincidence(pos,gam) :
                    continue
                if pos.getMomentum()[1]*gamY<0 : 
                    myhist.fillTwoBody(pos,gam,'EpGam','TB')
                elif  pos.getMomentum()[1] >0 : 
                    myhist.fillTwoBody(pos,gam,'EpGam','TT')
                elif  pos.getMomentum()[1] <0 : 
                    myhist.fillTwoBody(pos,gam,'EpGam','BB')

#do analysis for e+e-e- triplets...
        for pos in posList: 
            for i in range(0,len(eleList)) : 
                ele1=eleList[i]
                if  requireECalTimingCoincidence and not myhist.clusterCoincidence(ele1,pos) :
                    continue
                for k in range(i+1,len(eleList)):
                    ele2=eleList[k]                
                    if  requireECalTimingCoincidence and not myhist.clusterCoincidence(ele2,pos) :
                        continue
                    if pos.getMomentum()[1]>0 and ele1.getMomentum()[1]>0 and ele2.getMomentum()[1]>0  : 
                        myhist.fillThreeBody(pos,ele1,ele2,'EpEmEm','TTT')#all top?
                    elif ((pos.getMomentum()[1]>0 and ele1.getMomentum()[1]>0 and ele2.getMomentum()[1]<0)  or 
                          (pos.getMomentum()[1]<0 and ele1.getMomentum()[1]<0 and ele2.getMomentum()[1]>0)  or
                          (pos.getMomentum()[1]<0 and ele1.getMomentum()[1]>0 and ele2.getMomentum()[1]<0)  or
                          (pos.getMomentum()[1]>0 and ele1.getMomentum()[1]<0 and ele2.getMomentum()[1]>0) ): 
                        myhist.fillThreeBody(pos,ele1,ele2,'EpEmEm','TTB')#electrons on opposite halves...possible trident or WAB
                    elif ( (pos.getMomentum()[1]>0 and ele1.getMomentum()[1]<0 and ele2.getMomentum()[1]<0)  or 
                           (pos.getMomentum()[1]<0 and ele1.getMomentum()[1]>0 and ele2.getMomentum()[1]>0) ): 
                        myhist.fillThreeBody(pos,ele1,ele2,'EpEmEm','TBB')#electrons on same halves....possible trident (not WAB)
                    elif pos.getMomentum()[1]<0 and ele1.getMomentum()[1]<0 and ele2.getMomentum()[1]<0  : 
                        myhist.fillThreeBody(pos,ele1,ele2,'EpEmEm','BBB')#all bottom?

    myhist.saveHistograms(output_file)   
コード例 #13
0
def main():


    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(description='PyRoot analysis demostrating the use of a DST.')
    parser.add_argument("dst_file",  help="ROOT DST file to process")
    parser.add_argument("-o", "--output",  help="Name of output pdf file")
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user 
    if args.output:
        output_file = args.output
    else: 
        output_file = "analysis_output.pdf"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to " 
        print output_file

    # Load the HpsEvent library.  In this example, this is done by finding the
    # path to the HpsEvent shared library via the environmental variable
    # HPS_DST_PATH.  The HPS_DST_PATH environmental variable points to the
    # location of the build directory containing all binaries and libraries.
    # In general, the location of the library can be anywhere a user wants it
    # to be as long as the proper path is specified. 
    if os.getenv('HPS_DST_PATH') is None: 
        print "[ HPS ANALYSIS ]: Error! Environmental variable HPS_DST_HOME is not set."
        print "\n[ HPS ANALYSIS ]: Exiting ..."
        sys.exit(2)

    hps_dst_path = os.environ['HPS_DST_PATH']
    hps_dst_path += "/build/lib/libHpsEvent.so"
   
    # Load the library in ROOT
    import ROOT
    ROOT.gSystem.Load(hps_dst_path)

    # import the modules used by HpsEvent i.e. HpsEvent, 
    # SvtTrack, EcalCluster ...
    from ROOT import HpsEvent, SvtTrack, EcalCluster, EcalHit, HpsParticle

    #-----------------------------#
    #--- Setup ROOT histograms ---#
    #-----------------------------#

    # Create a canvas and set its characteristics
    canvas = ROOT.TCanvas("canvas", "Data Summary Tape Plots", 700, 700)
    setupCanvas(canvas)

    #
    # Ecal
    #
    h_hit_pos = ROOT.TH2F("cluster_pos", "ECal cluster position", 47, -23, 24, 12, -6, 6)
    setup2DHistogram(h_hit_pos, "Ecal Crystal Index - x", "Ecal Crystal Index - y")
    
    h_cluster_energy = ROOT.TH1F("cluster_energy", "Ecal Cluster Energy", 100, 0, 5.5)
    setup1DHistogram(h_cluster_energy, "Ecal Cluster Energy [GeV]")

    #
    # Track parameters and momentum
    #
    h_d0 = ROOT.TH1F("d0",  "Track D0", 80, -10, 10);
    setup1DHistogram(h_d0, "D0 [mm]")
    
    h_z0 = ROOT.TH1F("z0", "Track Z0", 80, -2, 2);
    setup1DHistogram(h_z0, "Z0 [mm]")
    
    h_sinphi0 = ROOT.TH1F("sin(phi0)", "Track sin(#phi_{0})", 40, -0.2, 0.2)
    setup1DHistogram(h_sinphi0, "sin(#phi_{0})")

    h_curvature = ROOT.TH1F("curvature", "Track Curvature", 50, -0.001, 0.001)
    setup1DHistogram(h_curvature, "Curvature")
    
    h_tlambda = ROOT.TH1F("tlambda",  "Track Tan(#lambda)", 64, -0.08, 0.08);
    setup1DHistogram(h_tlambda, "Tan #lambda")
    
    h_p = ROOT.TH1F("p", "Particle Momentum", 64, 0, 2.2);
    setup1DHistogram(h_p, "Momentum [GeV]")  
    
    h_chi2 = ROOT.TH1F("chi2", "Track #chi^{2}", 25, 0, 25);
    setup1DHistogram(h_chi2, "#chi^{2}")

    #
    # Particles
    #
    h_invariant_mass = ROOT.TH1F("invariant mass", "Invariant Mass", 100, 0, 0.200)
    setup1DHistogram(h_invariant_mass, "Invariant Mass [GeV]")

    h_vertex_z = ROOT.TH1F("h_vertex_z", "Particle Vertex - Z", 150, -150, 150); 
    setup1DHistogram(h_vertex_z, "Vertex z [mm]")

    h_epem = ROOT.TH2F("p[e+] v p[e-]", "p[e+] v p[e-]", 50, 0, 2.0, 50, 0, 2.0)
    setup2DHistogram(h_epem, "p[e-]", "p[e+]")

    #-----------------------------#

    # Open the ROOT file
    root_file = ROOT.TFile(str(args.dst_file))

    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    tree = root_file.Get("HPS_Event")

    # Create an HpsEvent object in order to read the TClonesArray 
    # collections
    hps_event = HpsEvent()

    # Get the HpsEvent branch from the TTree 
    b_hps_event = tree.GetBranch("Event")
    b_hps_event.SetAddress(ROOT.AddressOf(hps_event))

    #--- Analysis ---#
    #----------------#

    # Loop over all events in the file
    for entry in xrange(0, tree.GetEntries()) : 

        # Print the event number every 500 events
        if (entry+1)%500 == 0 : print "Event " + str(entry+1)

        # Read the ith entry from the tree.  This "fills" HpsEvent and allows 
        # access to all collections
        tree.GetEntry(entry)

        # Loop over all of the Ecal clusters in the event
        for cluster_n in xrange(0, hps_event.getNumberOfEcalClusters()):

            # Get an Ecal cluster from the event
            ecal_cluster = hps_event.getEcalCluster(cluster_n)

            # Get the Ecal cluster energy
            cluster_energy = ecal_cluster.getEnergy()

            # Fill the cluster energy plot
            h_cluster_energy.Fill(cluster_energy)

            # Get the seed hit of the cluster
            ecal_cluster_seed_hit = ecal_cluster.getSeed()

            # Get the crystal index of the ecal hit
            index_x = ecal_cluster_seed_hit.getXCrystalIndex()
            index_y = ecal_cluster_seed_hit.getYCrystalIndex()

            # Fill the Ecal hit position plot
            h_hit_pos.Fill(index_x, index_y, 1)

        # Loop over all tracks in the event
        for track_n in xrange(0, hps_event.getNumberOfTracks()) : 

            # Get the track from the event
            track = hps_event.getTrack(track_n)

            # Get the track parameters 
            d0 = track.getD0()
            z0 = track.getZ0()
            sinphi0 = math.sin(track.getPhi0())
            curvature = track.getOmega()
            tan_lambda = track.getTanLambda()
            chi2 = track.getChi2()

            # Fill the plots
            h_d0.Fill(d0)
            h_z0.Fill(z0)
            h_sinphi0.Fill(sinphi0)
            h_curvature.Fill(curvature)
            h_tlambda.Fill(tan_lambda)
            h_chi2.Fill(chi2)

            # Get the track momentum and fill the plots.  The track momentum
            # is retrieved from the associated HpsParticle.
            p = track.getMomentum()
            h_p.Fill(math.sqrt(p[0]*p[0] + p[1]*p[1] + p[2]*p[2]))

        # Loop over all unconstrained vertexed particles in the event
        for particle_n in xrange(0, hps_event.getNumberOfParticles(HpsParticle.UC_V0_CANDIDATE)):

            # Get a vertexed particle from the event
            particle = hps_event.getParticle(HpsParticle.UC_V0_CANDIDATE, particle_n)
           
            # Only look at particles that have two daugther particles
            daughter_particles = particle.getParticles()
            if daughter_particles.GetSize() != 2 : continue

            # Only look at particles that are composed of e+e- pairs
            if daughter_particles.At(0).getCharge()*daughter_particles.At(1).getCharge() > 0 : continue

            # Get the vertex position of the particle and plot it
            vertex_z = particle.getVertexPosition()[2]
            h_vertex_z.Fill(vertex_z)

            # Get the invariant mass of the particle and plot it
            mass = particle.getMass()
            h_invariant_mass.Fill(mass)

            # Get the momentum of both the daughter particles and plot them
            p1 = daughter_particles.At(0).getMomentum()
            p_mag_1 = math.sqrt(p1[0]*p1[0] + p1[1]*p1[1] + p1[2]*p1[2])

            p2 = daughter_particles.At(1).getMomentum()
            p_mag_2 = math.sqrt(p2[0]*p2[0] + p2[1]*p2[1] + p2[2]*p2[2])

            if daughter_particles.At(0).getCharge() < 0 :
                h_epem.Fill(p_mag_1, p_mag_2)
            else :
                h_epem.Fill(p_mag_2, p_mag_1)

    # Save all the plots to a single pdf file
    h_hit_pos.Draw("colz")
    canvas.Print(output_file + "(")
    h_cluster_energy.Draw()
    canvas.Print(output_file + "(")
    h_d0.Draw("");
    canvas.Print(output_file + "(");
    h_z0.Draw("");
    canvas.Print(output_file + "(");
    h_sinphi0.Draw("");
    canvas.Print(output_file + "(");
    h_curvature.Draw("");
    canvas.Print(output_file + "(");
    h_tlambda.Draw(""); 
    canvas.Print(output_file + "(");
    h_chi2.Draw("");
    canvas.Print(output_file + "(");
    h_p.Draw(""); 
    canvas.Print(output_file + "(");
    h_vertex_z.Draw("");
    canvas.Print(output_file + "(");
    h_invariant_mass.Draw(""); 
    canvas.Print(output_file + "(");
    h_epem.Draw("colz"); 
    canvas.Print(output_file + ")")
コード例 #14
0
def main():
    global beamEnergy
    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(description='PyRoot analysis demostrating the us of a DST.')
    parser.add_argument("dst_file",  help="ROOT DST file to process")
    parser.add_argument("-o", "--output",  help="Name of output pdf file")
    parser.add_argument("-m", "--mc",  help="is MonteCarlo")
    parser.add_argument("-p", "--pulser",  help="is Pulser")
    parser.add_argument("-e","--energy",help="beam energy")
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user 
    if args.output:
        output_file = args.output
    else: 
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to " 
        print output_file


    print "[ HPS ANALYSIS ]:  Output file is "+output_file
    isMC=False
    if args.mc:
        print  "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC=True


    isPulser=False
    if args.pulser:
        print  "[ HPS ANALYSIS ]: Setting to run from a pulser file"
        isPulser=True

    if args.energy : 
        print 'Setting beam energy to '+args.energy
        beamEnergy=float(args.energy)
        myhist.setEnergyScales(beamEnergy)


#################################
#       Event Selection
################################
#clean up event first
#### nominal selection
    nTrkMax=3
    nTrkMin=3
    nPosMax=1
######  two tracks (e+/e-) exactly
#    nTrkMax=2
#    nTrkMin=2
#    nPosMax=1
###### more than 1 electron
#    nTrkMax=10
#    nTrkMin=3
#    nPosMax=1
###################
    maxSharedHits=2
    #v0 cuts   
#    v0Chi2=10
    v0Chi2=99999999.0
    #ESum -- full region
    v0PzMax=1.2*beamEnergy
    v0PzMin=0.1*beamEnergy
    #ESum -- Radiative region
#    v0PzMax=1.2
#    v0PzMin=0.80

    v0PyMax=0.2 #absolute value
    v0PxMax=0.2 #absolute value
    v0VzMax=25.0# mm from target
#    v0VyMax=1.0# mm from target    
    v0VyMax=6666.0# mm from target
    v0VxMax=2.0# mm from target
 #  track quality cuts
    trkChi2=10
    beamCut=0.8*beamEnergy
    minPCut=0.05
    trkPyMax=0.2
    trkPxMax=0.2
#    slopeCut=0.03
    slopeCut=0.0
    trkDeltaT=4#ns
    cluDeltaT=2#ns
    cluTrkDeltaT=4#ns
##############
#  ESum slices; upper limits    
    nSlicesESum=5 
    esumMin=0.55
    esumMax=1.2
    sliceSizeESum=0.1 #100MeV starting at esumMin
##############
    trackKiller=False
    tkThreshold=0.5 #GeV, below this start killing tracks
    tkThreshEff=1.0
    tkLowPoint=0.20
    tkLowPointEff=0.40
#    tkSlope=2.6 
#    tkIntercept=-0.04
    #calculate tkSlope and Intercept   
    tkSlope=(tkThreshEff-tkLowPointEff)/(tkThreshold-tkLowPoint)
    tkIntercept=tkThreshEff-tkSlope*tkThreshold

##############
    requireECalMatch = True
    requireECalFiducial = True
    requireECalSuperFiducial = False
    useGBL=True


     # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    #use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from "+args.dst_file
    tree=ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file)+"*")    
    # Create an HpsEvent object in order to read the TClonesArray 
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))

    #--- Analysis ---#
    #----------------#

    #counters
    nEvents=0;
    nPassBasicCuts=0;
    nPassV0Cuts=0;
    nPassTrkCuts=0;
    nPassNCand=0
    nPassECalMatch=0;
    nFakeTri=0
    nTwoCand=0
    seedCnt=0
    # Loop over all events in the file
    for entry in xrange(0, tree.GetEntries()) : 
                 
        # Print the event number every 500 events
        if (entry+1)%10000 == 0 : print "Event " + str(entry+1)
        tree.GetEntry(entry)
        if not hps_event.isPair1Trigger() and not isMC and not isPulser: continue
        nEvents+=1
        addFakeEle=False
                                         

        # Loop over all tracks in the event
        npositrons=0
        n_tracks=0
        for track_n in xrange(0, hps_event.getNumberOfTracks()) :             
            track = hps_event.getGblTrack(track_n)
            if track is None : 
                continue
#            print track.getParticle().getType()
            if trkMatchAndFiducial(track.getParticle(),requireECalSuperFiducial) and trkMomentum(track,minPCut,beamCut): # count only matched tracks in defined fiducial region
                n_tracks+=1
                if track.getCharge()>0 :
                    npositrons+=1
                    myhist.rawposMom.Fill(pMag(track.getMomentum()))
                else :
                    myhist.raweleMom.Fill(pMag(track.getMomentum()))
#                    findWABPair(track.getParticle(),hps_event)

#        print "nTracks = "+str(n_tracks)+"; nPositrons = "+str(npositrons)
#        if n_tracks/2.0>nTrkMax : continue   #do this very dumb thing (divide by 2 to un-double count GBL tracks)
#        if n_tracks/2.0<2:  continue        
        myhist.nTrk.Fill(n_tracks);
        myhist.nPos.Fill(npositrons);
        myhist.nEle.Fill(n_tracks-npositrons);
        myhist.nClust.Fill(hps_event.getNumberOfEcalClusters())

        if n_tracks>nTrkMax : continue  
        if n_tracks<nTrkMin:  continue        
        if npositrons<1 or npositrons>nPosMax : continue
        nPassBasicCuts+=1
#        print "passed basic cuts"
        candidateList=[]
        bestCandidate=-99
        nCandidate=0
        # loop over all v0 candidates...
        for uc_index in xrange(0, hps_event.getNumberOfParticles(HpsParticle.UC_V0_CANDIDATE)):
            particle = hps_event.getParticle(HpsParticle.UC_V0_CANDIDATE, uc_index)
#            print "Particle Type = "+ str(particle.getType())
            if useGBL and  particle.getType()<32  : continue
            if not useGBL and  particle.getType()>31  : continue
#            print "found one..."
            vchi2=particle.getVertexFitChi2();
            vposition=particle.getVertexPosition();
            vmomentum=particle.getMomentum();
            if vchi2>v0Chi2 :  continue
            # use the measured sum of momentum 
#            if vmomentum[2]>v0PzMax : continue
#            if vmomentum[2]<v0PzMin : continue
             #recon'ed vertex position cuts
            if abs(vposition[0])>v0VxMax : continue
            if abs(vposition[1])>v0VyMax :continue

#            if abs(vposition[2])>v0VzMax :continue
            # Only look at particles that have two daugther particles...
            daughter_particles = particle.getParticles()
            if daughter_particles.GetSize() != 2 : continue
            # Only look at particles that are composed of e+e- pairs
            if daughter_particles.At(0).getCharge()*daughter_particles.At(1).getCharge() > 0 : continue
#            print "Passed daughter number cuts"

            electron =  daughter_particles.At(0)
            positron =  daughter_particles.At(1)
            
            if daughter_particles.At(0).getCharge()>0:
                electron =  daughter_particles.At(1)
                positron =  daughter_particles.At(0)

            pEle=electron.getMomentum()
            pPos=positron.getMomentum()

            v0Sum=pMag(pSum(pEle,pPos))
            #total momentum sum cuts
            if v0Sum>v0PzMax : continue
            if v0Sum<v0PzMin : continue
            nPassV0Cuts+=1
#            print "Passed v0 cuts"
#############   tracking cuts
            #momentum cuts...get rid of very soft or very hard tracks
            if pMag(pEle)>beamCut or pMag(pPos)>beamCut : continue
            if pMag(pEle)<minPCut or pMag(pPos)<minPCut : continue   
            #top+bottom requirement
            if pEle[1]*pPos[1]>0 : continue

#            print 'looking at tracks now' 
#            print len(electron.getTracks())
            
            if  len(electron.getTracks()) == 0 or  len(positron.getTracks()) == 0: continue
            eleTrk=electron.getTracks().At(0)
            posTrk=positron.getTracks().At(0)
            if eleTrk is None or posTrk is None : continue
#            eleTrk.Print("v")
            #track timing
            if eleTrk.getTrackTime() - posTrk.getTrackTime()> trkDeltaT :
                continue
            #track slope (if any cut)
            if abs(eleTrk.getTanLambda())<slopeCut or abs(posTrk.getTanLambda())<slopeCut :
                continue
#            print 'satisfied timing cuts...'

            ##############
            nPassTrkCuts+=1

            ##############
            #   ECAL matching and timing cuts...also fiducial region cuts...
            if requireECalMatch: 
                if positron.getClusters().GetEntries() == 0 :
                    continue
                if electron.getClusters().GetEntries() == 0 :
                    continue
                posCluster=positron.getClusters().First()
                eleCluster=electron.getClusters().First()
                
                if eleCluster.getClusterTime()- posCluster.getClusterTime() > cluDeltaT:
                    continue
                
                if eleTrk.getTrackTime() - eleCluster.getClusterTime()+43.5 > cluTrkDeltaT : 
                    continue

                if posTrk.getTrackTime() - posCluster.getClusterTime()+43.5 > cluTrkDeltaT : 
                    continue
                
                if requireECalFiducial:
                    #ANTI-fiducial cut
                    #                    if  myhist.inFiducialRegion(posCluster.getPosition()[0],posCluster.getPosition()[1]) :
                    #                        continue
                    #                    if  myhist.inFiducialRegion(eleCluster.getPosition()[0],eleCluster.getPosition()[1]) :
                    #                        continue
                    #Fiducial cut
                    if not myhist.inFiducialRegion(posCluster.getPosition()[0],posCluster.getPosition()[1]) :
                        continue
                    if not myhist.inFiducialRegion(eleCluster.getPosition()[0],eleCluster.getPosition()[1]) :
                        continue
                if requireECalSuperFiducial :
                    if not myhist.inSuperFiducialRegion(posCluster.getPosition()[0],posCluster.getPosition()[1]) :
                        continue
                    if not myhist.inSuperFiducialRegion(eleCluster.getPosition()[0],eleCluster.getPosition()[1]) :
                        continue
            nPassECalMatch+=1
            ##############
            #Passed the cuts..append the candidate index
            candidateList.append(particle)
      

        numCands=len(candidateList)
                    
        myhist.nCand.Fill(numCands)
        if numCands != 2 : continue  #require 2 candidates...probably have to rethink this.  
        
        print 'found 2 candidates' 
        
        cand0=candidateList[0]  # take this as base candidate
        candpos=cand0.getParticles().At(0)
        candele=cand0.getParticles().At(1)
        if candpos.getCharge()<0 : 
            candpos=cand0.getParticles().At(1)
            candele=cand0.getParticles().At(0)    
#            print "swapping cand"
        cand1=candidateList[1]  # get the recoil electron from this
        recoil= cand1.getParticles().At(0)
        recpos= cand1.getParticles().At(1)
        if recoil.getCharge()> 0 :
#            print "swapping recoil"
            recoil= cand1.getParticles().At(1)
            recpos= cand1.getParticles().At(0)
#        print 'Positron p' +str(pMag(candpos.getMomentum()))
#        print 'Electron p' +str(pMag(candele.getMomentum()))
#        print 'Recoil   p' +str(pMag(recoil.getMomentum()))
#        print 'Recoil Positron   p' +str(pMag(recpos.getMomentum()))

#        if candpos == recpos : 
#            print "positrons are same" 

        numSharedHits=myhist.getSharedHits(recoil.getTracks()[0],candele.getTracks()[0])
        print "Number of overlapping hits for electrons is : "+str(numSharedHits)

        
        if numSharedHits <= maxSharedHits : 
            nTwoCand+=1
            myhist.fillCandidateHistograms(cand0,recoil)
            myhist.fillThreeTrackPlots(cand0,cand1)
            

#    if(nPassTrkCuts>0): 
    myhist.saveHistograms(output_file)   

    print "******************************************************************************************"
    print "Number of Events:\t\t",nEvents,"\t\t\t",float(nEvents)/nEvents,"\t\t\t",float(nEvents)/nEvents
    print "N(particle) Cuts:\t\t",nPassBasicCuts,"\t\t\t",float(nPassBasicCuts)/nEvents,"\t\t\t",float(nPassBasicCuts)/nEvents
    print "V0 Vertex   Cuts:\t\t",nPassV0Cuts,"\t\t\t",float(nPassV0Cuts)/nPassBasicCuts,"\t\t\t",float(nPassV0Cuts)/nEvents
    print "Tracking    Cuts:\t\t",nPassTrkCuts,"\t\t\t",float(nPassTrkCuts)/nPassV0Cuts,"\t\t\t",float(nPassTrkCuts)/nEvents
    print "ECal Match  Cuts:\t\t",nPassECalMatch,"\t\t\t",float(nPassECalMatch)/nPassTrkCuts,"\t\t\t",float(nPassECalMatch)/nEvents

    print "Number of Fake Events Added:  \t\t",nFakeTri,"\t\t\t",float(nFakeTri)/nPassECalMatch
                      
    print "Number of events with 2 candidates (unshared) = ",nTwoCand
コード例 #15
0
def main():


    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(description='PyRoot analysis demostrating the us of a DST.')
    parser.add_argument("dst_file",  help="ROOT DST file to process")
    parser.add_argument("-o", "--output",  help="Name of output pdf file")
    parser.add_argument("-m", "--mc",  help="is MonteCarlo")
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user 
    if args.output:
        output_file = args.output
    else: 
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to " 
        print output_file


    print "[ HPS ANALYSIS ]:  Output file is "+output_file
    isMC=False
    if args.mc:
        print  "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC=True

    # Load the HpsEvent library.  In this example, this is done by finding the
    # path to the HpsEvent shared library via the environmental variable
    # HPS_DST_PATH.  The HPS_DST_PATH environmental variable points to the
    # location of the build directory containing all binaries and libraries.
    # In general, the location of the library can be anywhere a user wants it
    # to be as long as the proper path is specified. 
    if os.getenv('HPS_DST_PATH') is None: 
        print "[ HPS ANALYSIS ]: Error! Environmental variable HPS_DST_HOME is not set."
        print "\n[ HPS ANALYSIS ]: Exiting ..."
        sys.exit(2)

    hps_dst_path = os.environ['HPS_DST_PATH']
    hps_dst_path += "/build/lib/libHpsEvent.so"
    print "Loading HpsEvent Library from "+hps_dst_path
    # Load the library in ROOT
    import ROOT
    ROOT.gSystem.Load(hps_dst_path)

    # import the modules used by HpsEvent i.e. HpsEvent, 
    # SvtTrack, EcalCluster ...
    from ROOT import HpsEvent, SvtTrack, EcalCluster, EcalHit, TChain, TTree, HpsParticle




#################################
#       Event Selection
################################
    ebeam=1.05
#clean up event first
    nTrkMax=5
    nPosMax=2
 #v0 cuts   
    v0Chi2=10
    v0PzMax=1.25*ebeam
 #   v0PzMax=0.8*ebeam
    v0PzMin=0.6
#    v0PzMin=0.8*ebeam
    v0PyMax=0.2 #absolute value
    v0PxMax=0.2 #absolute value
    v0VzMax=25.0# mm from target
    v0VyMax=1.0# mm from target
    v0VxMax=2.0# mm from target
 #  track quality cuts
    trkChi2=10
#    beamCut=0.9
    beamCut=0.8
    minPCut=0.05
    trkPyMax=0.2
    trkPxMax=0.2
    slopeCut=0.02

    radCut=0.8*ebeam

    requireECalMatch = True
    useGBL=True
    #-----------------------------#
    #--- Setup ROOT histograms ---#
    #-----------------------------#

    # Create a canvas and set its characteristics
    #    canvas = ROOT.TCanvas("canvas", "Data Summary Tape Plots", 700, 700)
    #    setupCanvas(canvas)
  
    nCand = ROOT.TH1F("NCand","Number of Candidates", 4, 0, 4 );
    tridentMass = ROOT.TH1F("TridentMass","Trident Mass (GeV)", 500, 0, 0.100);
    tridentMassVtxCut = ROOT.TH1F( "TridentMassBeforeVertex", "Trident Mass (GeV): Before  VtxCut", 500, 0, 0.100);
    tridentVx = ROOT.TH1F("Vx", "Trident Vx (mm)", 100, -4, 4);
    tridentVy = ROOT.TH1F("Vy","Trident Vy (mm)", 100, -2, 2);
    tridentVz =  ROOT.TH1F("Vz", "Trident Vz (mm)", 100, -50, 50);
    eSum =  ROOT.TH1F("eSum", "Energy Sum", 100, 0.3, 1.2);
    eDiff =  ROOT.TH1F("eDiffoverESum", "Energy Difference", 100, -0.8, 0.8);    
    vertChi2 =  ROOT.TH1F("vertChi2", "V0 Chi2", 100, 0, 10);    
    ePosvseEle=ROOT.TH2F("ePosvseEle","Positron vs Electron Energy",100,0.1,0.9,50,0.1,0.9);
    tanopenY =  ROOT.TH1F("tanopenY", "tanopenY", 100, 0., 0.16);
    tanopenYThresh =  ROOT.TH1F("tanopenYThresh", "tanopenYThresh", 100, 0.025, 0.06);
    minAngle = ROOT.TH1F("minAngle","Minimum Track Angle",100,0.01,0.03)
    
    
    eleMom = ROOT.TH1F("eleMom","Electron Momentum (GeV)", 100, 0, 1.);
    posMom = ROOT.TH1F("posMom","Positron Momentum (GeV)", 100, 0, 1.);
    
    eled0 = ROOT.TH1F("eled0","Electron d0 (mm)", 100, -3, 3);
    posd0 = ROOT.TH1F("posd0","Positron d0 (mm)", 100, -3, 3);
    
    elez0 = ROOT.TH1F("elez0","Electron z0 (mm)", 100, -1.5, 1.5);
    posz0 = ROOT.TH1F("posz0","Positron z0 (mm)", 100, -1.5, 1.5);


    elephi0 = ROOT.TH1F("elephi0","Electron phi0", 100, -0.1, 0.1);
    posphi0 = ROOT.TH1F("posphi0","Positron phi0", 100, -0.1, 0.1);

    eleslope = ROOT.TH1F("eleslope","Electron slope", 100, -0.08, 0.08);
    posslope = ROOT.TH1F("posslope","Positron slope", 100, -0.08, 0.08);

    trkTimeDiff = ROOT.TH1F("trkTimeDiff","Ele-Pos Time Difference (ns)", 100, -6, 6);

    tHitTop=[]
    tHitBot=[]
    
    nlayers=6
    pre="time (ns) for layer ";
    for  i in range(1, nlayers) :
        topName=pre+" "+str(i)+" Top"
        tHitTop.append(ROOT.TH1F(topName,topName,100,-16,16))
        botName=pre+" "+str(i)+" Bot"
        tHitBot.append(ROOT.TH1F(botName,botName,100,-16,16))
   
   


    # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    #use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from "+args.dst_file
    tree=ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file)+"*")    


    # Create an HpsEvent object in order to read the TClonesArray 
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))

    # Get the HpsEvent branch from the TTree 
#    b_hps_event = tree.GetBranch("Event")
#    b_hps_event.SetAddress(ROOT.AddressOf(hps_event))

    #--- Analysis ---#
    #----------------#

    #counters
    nEvents=0;
    nPassBasicCuts=0;
    nPassV0Cuts=0;
    nPassTrkCuts=0;
    nPassNCand=0
    # Loop over all events in the file
    for entry in xrange(0, tree.GetEntries()) : 
        # Print the event number every 500 events
        if (entry+1)%10000 == 0 : print "Event " + str(entry+1)

        # Read the ith entry from the tree.  This "fills" HpsEvent and allows 
        # access to all collections
#        entryNumber = tree.GetEntryNumber(entry);
#        localEntry = fTree.LoadTree(entryNumber);
#        print localEntry
#        if localEntry < 0: 
#            continue
#        tree.GetEntry(localEntry)
        tree.GetEntry(entry)
#        print "checking trigger"
        if not hps_event.isPair1Trigger() and not isMC : continue
        nEvents+=1
#        print "found a pair1 trigger"
        # Loop over all tracks in the event
        npositrons=0
        n_tracks=0
#        print "Found "+str( hps_event.getNumberOfTracks()) +" tracks in event"
#        if  hps_event.getNumberOfTracks() > 10 : continue
        for track_n in xrange(0, hps_event.getNumberOfTracks()) :             
            track = hps_event.getTrack(track_n)
            if track is None : 
                continue
#            if not (useGBL ^ track.type<32)  : continue
            n_tracks+=1
            if track.getCharge()>0 :
                npositrons+=1

#        print "nTracks = "+str(n_tracks)+"; nPositrons = "+str(npositrons)
        if n_tracks/2.0>nTrkMax : continue   #do this very dumb thing (divide by 2 to un-double count GBL tracks)
        if n_tracks/2.0<2:  continue        
        if npositrons<1 or npositrons>nPosMax : continue
        nPassBasicCuts+=1
#        print "passed basic cuts"
        candidateList=[]
        bestCandidate=-99
        nCandidate=0
        # loop over all v0 candidates...
        for uc_index in xrange(0, hps_event.getNumberOfParticles(HpsParticle.UC_V0_CANDIDATE)):
            particle = hps_event.getParticle(HpsParticle.UC_V0_CANDIDATE, uc_index)
            if not (useGBL ^ particle.getType()<32)  : continue
            vchi2=particle.getVertexFitChi2();
            vposition=particle.getVertexPosition();
            vmomentum=particle.getMomentum();
            if vchi2>v0Chi2 :  continue
            if vmomentum[2]>v0PzMax : continue
            if vmomentum[2]<v0PzMin : continue
            if abs(vposition[0])>v0VxMax : continue
            if abs(vposition[1])>v0VyMax :continue
#            if abs(vposition[2])>v0VzMax :continue
            nPassV0Cuts+=1
#            print "Passed v0 cuts"
            # Only look at particles that have two daugther particles...
            daughter_particles = particle.getParticles()
            if daughter_particles.GetSize() != 2 : continue
            # Only look at particles that are composed of e+e- pairs
            if daughter_particles.At(0).getCharge()*daughter_particles.At(1).getCharge() > 0 : continue
#            print "Passed daughter number cuts"

            electron =  daughter_particles.At(0)
            positron =  daughter_particles.At(1)
            
            if daughter_particles.At(0).getCharge()>0:
                electron =  daughter_particles.At(1)
                positron =  daughter_particles.At(0)

            pEle=electron.getMomentum()
            pPos=positron.getMomentum()

            if pMag(pEle)>beamCut or pMag(pPos)>beamCut : continue
            if pMag(pEle)<minPCut or pMag(pPos)<minPCut : continue            
            if pEle[1]*pPos[1]>0 : continue
            if requireECalMatch: 
                if positron.getClusters().GetEntries() == 0 :
                    continue
                if electron.getClusters().GetEntries() == 0 :
                    continue
            eleTrk=electron.getTracks().At(0)
            posTrk=positron.getTracks().At(0)
            if abs(eleTrk.getTanLambda())<slopeCut or abs(posTrk.getTanLambda())<slopeCut :
                continue
                
            
#            print "Passed track cuts"
            nPassTrkCuts+=1
            #Passed the cuts..append the candidate index
            candidateList.append(uc_index)

        #########################        
        #   found some candidates...lets fill plots...
        #########################        
        nCand.Fill(len(candidateList))
        for index in range(0,len(candidateList)) :
            particle = hps_event.getParticle(HpsParticle.UC_V0_CANDIDATE, candidateList[index])
            vchi2=particle.getVertexFitChi2();
            vposition=particle.getVertexPosition();
            vmomentum=particle.getMomentum();

            daughter_particles = particle.getParticles()
            electron =  daughter_particles.At(0)
            positron =  daughter_particles.At(1)
            
            if daughter_particles.At(0).getCharge()>0:
                electron =  daughter_particles.At(1)
                positron =  daughter_particles.At(0)
            pEle=electron.getMomentum()
            pPos=positron.getMomentum()

            #fill the plots
            tridentVx.Fill(vposition[0])
            tridentVy.Fill(vposition[1])
            tridentVz.Fill(vposition[2])

            ePosvseEle.Fill(pMag(pEle),pMag(pPos))
#            eSum.Fill(pMag(pEle)+pMag(pPos))
            eSum.Fill(pMag(vmomentum)) #fill with the fitted momentum instead
            eDiff.Fill(pMag(pEle)-pMag(pPos))/(pMag(pEle)+pMag(pPos))
            tridentMass.Fill(particle.Mass());

            eleMom.Fill(pMag(pEle));
            posMom.Fill(pMag(pPos));
      
     
            eleTrk=electron.getTracks().At(0)
            posTrk=positron.getTracks().At(0)

            eled0.Fill(eleTrk.getD0())
            elez0.Fill(eleTrk.getZ0())
            elephi0.Fill(math.sin(eleTrk.getPhi0()))
            eleslope.Fill(eleTrk.getTanLambda())

            posd0.Fill(posTrk.getD0())
            posz0.Fill(posTrk.getZ0())
            posphi0.Fill(math.sin(posTrk.getPhi0()))
            posslope.Fill(posTrk.getTanLambda())
            
            trkTimeDiff.Fill(eleTrk.getTrackTime()-posTrk.getTrackTime())
            vertChi2.Fill(particle.getVertexFitChi2())
      
            topenAngle=abs(eleTrk.getTanLambda()) +abs(posTrk.getTanLambda())

            tanopenY.Fill(topenAngle);
            tanopenYThresh.Fill(topenAngle);
            minAngle.Fill(min(abs(eleTrk.getTanLambda()),abs(posTrk.getTanLambda())))
            
    out=ROOT.TFile(output_file,"RECREATE");
    tridentMass.Write()
    tridentVx.Write()
    tridentVy.Write()
    tridentVz.Write()
    tridentMassVtxCut.Write()
    ePosvseEle.Write()
    vertChi2.Write()
    eSum.Write()
    eDiff.Write()
    eleMom.Write() 
    eled0.Write() 
    elez0.Write()
    elephi0.Write()
    eleslope.Write()
    posMom.Write() 
    posd0.Write() 
    posz0.Write()
    posphi0.Write()
    posslope.Write()
    trkTimeDiff.Write()
    tanopenYThresh.Write()
    tanopenY.Write()
    nCand.Write()
    minAngle.Write()
    out.Close()

    print "\t\t\tTrident Selection Summary"
    print "******************************************************************************************"
    print "Number of Events:\t\t",nEvents,"\t\t\t",float(nEvents)/nEvents,"\t\t\t",float(nEvents)/nEvents
    print "N(particle) Cuts:\t\t",nPassBasicCuts,"\t\t\t",float(nPassBasicCuts)/nEvents,"\t\t\t",float(nPassBasicCuts)/nEvents
    print "V0 Vertex   Cuts:\t\t",nPassV0Cuts,"\t\t\t",float(nPassV0Cuts)/nPassBasicCuts,"\t\t\t",float(nPassV0Cuts)/nEvents
    print "Tracking    Cuts:\t\t",nPassTrkCuts,"\t\t\t",float(nPassTrkCuts)/nPassV0Cuts,"\t\t\t",float(nPassTrkCuts)/nEvents
コード例 #16
0
    def preprocess(self, dst_file):

        chain = r.TChain("HPS_Event")
        chain.Add(dst_file)
        tree = chain.GetTree()

        from ROOT import HpsEvent

        hps_event = HpsEvent()
        branch = chain.SetBranchAddress("Event", r.AddressOf(hps_event))

        # Create the file name for the preprocessed ROOT file
        #output_file_name = root_file.GetName()[str(root_file.GetName()).rindex("/") + 1:-5]
        output_file_name = "beam_tri_preprocessed_signal.root"

        # Add variables to the ntuple
        ft_maker = ft.FlatTupleMaker(output_file_name)
        ft_maker.add_variable("cluster_0_energy")
        ft_maker.add_variable("cluster_1_energy")
        ft_maker.add_variable("cluster_0_x")
        ft_maker.add_variable("cluster_1_x")
        ft_maker.add_variable("cluster_0_y")
        ft_maker.add_variable("cluster_1_y")
        ft_maker.add_variable("track_0_p")
        ft_maker.add_variable("track_0_px")
        ft_maker.add_variable("track_0_py")
        ft_maker.add_variable("track_0_pz")
        ft_maker.add_variable("track_0_tanlambda")
        ft_maker.add_variable("track_0_phi0")
        ft_maker.add_variable("track_0_omega")
        ft_maker.add_variable("track_0_d0")
        ft_maker.add_variable("track_0_z0")
        ft_maker.add_variable("track_0_charge")
        ft_maker.add_variable("track_1_p")
        ft_maker.add_variable("track_1_px")
        ft_maker.add_variable("track_1_py")
        ft_maker.add_variable("track_1_pz")
        ft_maker.add_variable("track_1_tanlambda")
        ft_maker.add_variable("track_1_phi0")
        ft_maker.add_variable("track_1_omega")
        ft_maker.add_variable("track_1_d0")
        ft_maker.add_variable("track_1_z0")
        ft_maker.add_variable("track_1_charge")

        matcher = tcm.TrackClusterMatcher()

        for entry in xrange(0, chain.GetEntries()):

            if (entry + 1) % 1000 == 0: print "Event " + str(entry + 1)

            chain.GetEntry(entry)

            #if not au.is_good_data_event(hps_event) : continue

            # Loop through all clusters in the event and find a 'good' pair.
            # For now, a 'good' pair is defined as two clusters whose cluster
            # time difference is less than 1.7 ns and greater than -1.6 ns
            cluster_pair = au.get_good_cluster_pair(hps_event)

            if not self.is_good_cluster_pair(cluster_pair): continue

            matcher.find_all_matches(hps_event)
            tracks = [
                matcher.get_track(cluster_pair[0]),
                matcher.get_track(cluster_pair[1])
            ]

            if (tracks[0] is None) or (tracks[1] is None): continue

            ft_maker.set_variable_value("cluster_0_energy",
                                        cluster_pair[0].getEnergy())
            ft_maker.set_variable_value("cluster_1_energy",
                                        cluster_pair[1].getEnergy())
            ft_maker.set_variable_value("cluster_0_x",
                                        cluster_pair[0].getPosition()[0])
            ft_maker.set_variable_value("cluster_1_x",
                                        cluster_pair[1].getPosition()[0])
            ft_maker.set_variable_value("cluster_0_y",
                                        cluster_pair[0].getPosition()[1])
            ft_maker.set_variable_value("cluster_1_y",
                                        cluster_pair[1].getPosition()[1])
            ft_maker.set_variable_value(
                "track_0_p",
                np.linalg.norm(np.asarray(tracks[0].getMomentum())))
            ft_maker.set_variable_value("track_0_px",
                                        tracks[0].getMomentum()[0])
            ft_maker.set_variable_value("track_0_py",
                                        tracks[0].getMomentum()[1])
            ft_maker.set_variable_value("track_0_pz",
                                        tracks[0].getMomentum()[2])
            ft_maker.set_variable_value("track_0_tanlambda",
                                        tracks[0].getTanLambda())
            ft_maker.set_variable_value("track_0_phi0", tracks[0].getPhi0())
            ft_maker.set_variable_value("track_0_omega", tracks[0].getOmega())
            ft_maker.set_variable_value("track_0_d0", tracks[0].getD0())
            ft_maker.set_variable_value("track_0_z0", tracks[0].getZ0())
            ft_maker.set_variable_value("track_0_charge",
                                        tracks[0].getCharge())
            ft_maker.set_variable_value(
                "track_1_p",
                np.linalg.norm(np.asarray(tracks[1].getMomentum())))
            ft_maker.set_variable_value("track_1_px",
                                        tracks[1].getMomentum()[0])
            ft_maker.set_variable_value("track_1_py",
                                        tracks[1].getMomentum()[1])
            ft_maker.set_variable_value("track_1_pz",
                                        tracks[1].getMomentum()[2])
            ft_maker.set_variable_value("track_1_tanlambda",
                                        tracks[1].getTanLambda())
            ft_maker.set_variable_value("track_1_phi0", tracks[1].getPhi0())
            ft_maker.set_variable_value("track_1_omega", tracks[1].getOmega())
            ft_maker.set_variable_value("track_1_d0", tracks[1].getD0())
            ft_maker.set_variable_value("track_1_z0", tracks[1].getZ0())
            ft_maker.set_variable_value("track_1_charge",
                                        tracks[1].getCharge())

            ft_maker.fill()

        ft_maker.close()
コード例 #17
0
def main():
    global beamEnergy
    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(
        description='PyRoot analysis demostrating the us of a DST.')
    parser.add_argument("dst_file", help="ROOT DST file to process")
    parser.add_argument("-o", "--output", help="Name of output pdf file")
    parser.add_argument("-m", "--mc", help="is MonteCarlo")
    parser.add_argument("-p", "--pulser", help="is Pulser")
    parser.add_argument("-e", "--energy", help="beam energy")
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user
    if args.output:
        output_file = args.output
    else:
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to "
        print output_file

    print "[ HPS ANALYSIS ]:  Output file is " + output_file
    isMC = False
    if args.mc:
        print "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC = True

    isPulser = False
    if args.pulser:
        print "[ HPS ANALYSIS ]: Setting to run from a pulser file"
        isPulser = True

    if args.energy:
        print 'Setting beam energy to ' + args.energy
        beamEnergy = float(args.energy)
        myhist.setEnergyScales(beamEnergy)

#################################
#       Event Selection
################################
#clean up event first
#### nominal selection
    nTrkMax = 10
    nTrkMin = 2
    nPosMax = 3
    ######  two tracks (e+/e-) exactly
    #    nTrkMax=2
    #    nTrkMin=2
    #    nPosMax=1
    ###### more than 1 electron
    #    nTrkMax=10
    #    nTrkMin=3
    #    nPosMax=1
    ###################
    #v0 cuts
    v0Chi2 = 10
    #ESum -- full region
    v0PzMax = 1.2 * beamEnergy
    v0PzMin = 0.55 * beamEnergy
    #ESum -- Radiative region
    #    v0PzMax=1.2
    #    v0PzMin=0.80

    v0PyMax = 0.2  #absolute value
    v0PxMax = 0.2  #absolute value
    v0VzMax = 25.0  # mm from target
    v0VyMax = 1.0  # mm from target
    v0VxMax = 2.0  # mm from target
    #  track quality cuts
    trkChi2 = 10
    beamCut = 0.8 * beamEnergy
    minPCut = 0.05
    trkPyMax = 0.2
    trkPxMax = 0.2
    #    slopeCut=0.03
    slopeCut = 0.0
    trkDeltaT = 4  #ns
    cluDeltaT = 2  #ns
    cluTrkDeltaT = 4  #ns
    ##############
    #  ESum slices; upper limits
    nSlicesESum = 5
    esumMin = 0.55
    esumMax = 1.2
    sliceSizeESum = 0.1  #100MeV starting at esumMin
    ##############
    trackKiller = False
    tkThreshold = 0.5  #GeV, below this start killing tracks
    tkThreshEff = 1.0
    tkLowPoint = 0.20
    tkLowPointEff = 0.40
    #    tkSlope=2.6
    #    tkIntercept=-0.04
    #calculate tkSlope and Intercept
    tkSlope = (tkThreshEff - tkLowPointEff) / (tkThreshold - tkLowPoint)
    tkIntercept = tkThreshEff - tkSlope * tkThreshold

    ##############
    requireECalMatch = True
    requireECalFiducial = False
    requireECalSuperFiducial = False
    useGBL = True

    # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    #use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from " + args.dst_file
    tree = ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file) + "*")
    # Create an HpsEvent object in order to read the TClonesArray
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))

    #--- Analysis ---#
    #----------------#

    #counters
    nEvents = 0
    nPassBasicCuts = 0
    nPassV0Cuts = 0
    nPassTrkCuts = 0
    nPassNCand = 0
    nPassECalMatch = 0
    nFakeTri = 0

    if 1 == 0:
        extraElectronProb = 0.0
        dataNele = 170.0
        btNele = 1.4
        hf = ROOT.TFile(
            "OutputHistograms/Data/hps_005772_pass6_useGBL_ECalMatch_SuperFiducialCut.root"
        )
        hfMC = ROOT.TFile(
            "OutputHistograms/MC/beam-tri_HPS-EngRun2015-Nominal-v4-4_pass6_useGBL_ECalMatch_SuperFiducialCut.root"
        )
        pele = ROOT.RooRealVar("pele", "pele", 0, 1)
        peleHist = hf.Get("raweleMom")
        peleMCHist = hfMC.Get("raweleMom")
        peleHist.Scale(1 / dataNele)
        peleMCHist.Scale(1 / btNele)
        peleHist.Add(
            peleMCHist, -1.0
        )  #subtract the MC from the data to get the distribution of extra tracks...this is cheating!
        for i in xrange(0, peleHist.GetNbinsX()):
            print "Electron Momentum bin i = " + str(peleHist.GetBinContent(i))
            if peleHist.GetBinContent(i) < 0:
                peleHist.SetBinContent(i, 0)
        peleHist.Print("V")
        peleDH = RooDataHist("peleDH", "peleDH", ROOT.RooArgList(pele),
                             peleHist)
        peleDH.Print("V")
        extraElectronPdf = RooHistPdf("extraElectronPdf", "extraElectronPdf",
                                      ROOT.RooArgSet(pele), peleDH)
        print 'pdf is made...printing info'
        extraElectronPdf.Print("V")
        #    if isMC and random.random()<extraElectronProb :
        #add an extra electron based on electron momentum
        print 'generating events'
        newElePData = extraElectronPdf.generate(ROOT.RooArgSet(pele),
                                                1000000.0, True, False)
        newElePData.Print("V")

    seedCnt = 0
    # Loop over all events in the file
    for entry in xrange(0, tree.GetEntries()):

        # Print the event number every 500 events
        if (entry + 1) % 10000 == 0: print "Event " + str(entry + 1)
        tree.GetEntry(entry)
        if not hps_event.isPair1Trigger() and not isMC and not isPulser:
            continue
        nEvents += 1
        addFakeEle = False
        if 1 == 0:
            if isMC and random.random() < extraElectronProb:
                #add an extra electron based on electron momentum
                addFakeEle = True
                newEleP = newElePData.get(seedCnt).find("pele").getVal()
                seedCnt = seedCnt + 1
                #            print 'Inserting an electron with momentum = '+str(newEleP)
                #            newEleCluster=hps_event.addEcalCluster();
                #            newEleTrack=hps_event.addTrack();
                #            print 'numbe of HpsParticles before = '+str(hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE))
                #            newEle=hps_event.addParticle(HpsParticle.FINAL_STATE_PARTICLE)
                #            print 'numbe of HpsParticles after = '+str(hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE))
                newEle = HpsParticle()
                newEle.setCharge(-1)
                newEle.setPDG(11)
                newEle.setEnergy(newEleP)
                sign = 1
                if random.random() < 0.5:
                    sign = -1
                newEleMom = [
                    math.sin(0.03) * newEleP, sign * math.sin(0.04) * newEleP,
                    math.cos(0.04) * newEleP
                ]
                newEle.setMomentum(np.array(newEleMom))
                #fake track info
                newEleTrack = SvtTrack()
                newEleTrack.setTrackParameters(0.0, 0.03, 0.0001, sign * 0.04,
                                               0.0)
                newEleTrack.setTrackTime(40.0)
                newEleTrack.setParticle(newEle)
                newEleTrack.setChi2(3.0)
                newEleTrack.setPositionAtEcal(
                    np.array([300.0, sign * 50.0, 1350.0]))
                #fake cluster info
                newEleCluster = EcalCluster()
                newEleCluster.setEnergy(newEleP)
                foobar = [300.0, sign * 50.0, 1350.0]
                newEleCluster.setPosition(np.array(foobar, dtype='float32'))
                newEle.addTrack(newEleTrack)
                newEle.addCluster(newEleCluster)
#            print 'fake electron cluster x ' + str(newEle.getClusters().First().getPosition()[0])

# Loop over all tracks in the event
        npositrons = 0
        n_tracks = 0
        for track_n in xrange(0, hps_event.getNumberOfTracks()):
            track = hps_event.getTrack(track_n)
            if track is None:
                continue
#            if useGBL and track.getParticle().getType()<32  : continue
#            if not useGBL and track.getParticle().getType()>31  : continue
            if trkMatchAndFiducial(
                    track.getParticle(),
                    requireECalSuperFiducial) and trkMomentum(
                        track, minPCut, beamCut
                    ):  # count only matched tracks in defined fiducial region
                n_tracks += 1
                if track.getCharge() > 0:
                    npositrons += 1
                    myhist.rawposMom.Fill(pMag(track.getMomentum()))
                else:
                    myhist.raweleMom.Fill(pMag(track.getMomentum()))
#                    findWABPair(track.getParticle(),hps_event)

        if addFakeEle:
            myhist.raweleMom.Fill(newEle.getEnergy())
            n_tracks = n_tracks + 1
#        print "nTracks = "+str(n_tracks)+"; nPositrons = "+str(npositrons)
#        if n_tracks/2.0>nTrkMax : continue   #do this very dumb thing (divide by 2 to un-double count GBL tracks)
#        if n_tracks/2.0<2:  continue
        myhist.nTrk.Fill(n_tracks)
        myhist.nPos.Fill(npositrons)
        myhist.nEle.Fill(n_tracks - npositrons)
        myhist.nClust.Fill(hps_event.getNumberOfEcalClusters())

        if n_tracks > nTrkMax: continue
        if n_tracks < nTrkMin: continue
        if npositrons < 1 or npositrons > nPosMax: continue
        nPassBasicCuts += 1
        #        print "passed basic cuts"
        candidateList = []
        bestCandidate = -99
        nCandidate = 0
        # loop over all v0 candidates...
        for uc_index in xrange(
                0,
                hps_event.getNumberOfParticles(HpsParticle.UC_V0_CANDIDATE)):
            particle = hps_event.getParticle(HpsParticle.UC_V0_CANDIDATE,
                                             uc_index)
            if useGBL and particle.getType() < 32: continue
            if not useGBL and particle.getType() > 31: continue
            #            print "found one..."
            vchi2 = particle.getVertexFitChi2()
            vposition = particle.getVertexPosition()
            vmomentum = particle.getMomentum()
            if vchi2 > v0Chi2: continue
            # use the measured sum of momentum
            #            if vmomentum[2]>v0PzMax : continue
            #            if vmomentum[2]<v0PzMin : continue
            #recon'ed vertex position cuts
            if abs(vposition[0]) > v0VxMax: continue
            if abs(vposition[1]) > v0VyMax: continue

            #            if abs(vposition[2])>v0VzMax :continue
            # Only look at particles that have two daugther particles...
            daughter_particles = particle.getParticles()
            if daughter_particles.GetSize() != 2: continue
            # Only look at particles that are composed of e+e- pairs
            if daughter_particles.At(0).getCharge() * daughter_particles.At(
                    1).getCharge() > 0:
                continue
            #            print "Passed daughter number cuts"

            electron = daughter_particles.At(0)
            positron = daughter_particles.At(1)

            if daughter_particles.At(0).getCharge() > 0:
                electron = daughter_particles.At(1)
                positron = daughter_particles.At(0)

            pEle = electron.getMomentum()
            pPos = positron.getMomentum()

            v0Sum = pMag(pSum(pEle, pPos))
            #total momentum sum cuts
            if v0Sum > v0PzMax: continue
            if v0Sum < v0PzMin: continue
            nPassV0Cuts += 1
            #            print "Passed v0 cuts"
            #############   tracking cuts
            #momentum cuts...get rid of very soft or very hard tracks
            if pMag(pEle) > beamCut or pMag(pPos) > beamCut: continue
            if pMag(pEle) < minPCut or pMag(pPos) < minPCut: continue
            #top+bottom requirement
            if pEle[1] * pPos[1] > 0: continue

            #            print 'looking at tracks now'
            #            print len(electron.getTracks())

            if len(electron.getTracks()) == 0 or len(
                    positron.getTracks()) == 0:
                continue
            eleTrk = electron.getTracks().At(0)
            posTrk = positron.getTracks().At(0)
            if eleTrk is None or posTrk is None: continue
            #            eleTrk.Print("v")
            #track timing
            if eleTrk.getTrackTime() - posTrk.getTrackTime() > trkDeltaT:
                continue
            #track slope (if any cut)
            if abs(eleTrk.getTanLambda()) < slopeCut or abs(
                    posTrk.getTanLambda()) < slopeCut:
                continue
#            print 'satisfied timing cuts...'
##############
# track killer part
            if isMC and trackKiller:
                if pMag(pEle) < tkThreshold:  #electron
                    tkEff = tkSlope * pMag(pEle) + tkIntercept
                    if random.random() > tkEff:
                        continue
                elif random.random(
                ) > tkThreshEff:  #allow for a flat killer above threshold
                    continue
                if pMag(pPos) < tkThreshold:  # positron
                    tkEff = tkSlope * pMag(pPos) + tkIntercept
                    if random.random() > tkEff:
                        continue
                elif random.random(
                ) > tkThreshEff:  #allow for a flat killer above threshold
                    continue
            #  end of track killer
            ##############
            nPassTrkCuts += 1

            ##############
            #   ECAL matching and timing cuts...also fiducial region cuts...
            if requireECalMatch:
                if positron.getClusters().GetEntries() == 0:
                    continue
                if electron.getClusters().GetEntries() == 0:
                    continue
                posCluster = positron.getClusters().First()
                eleCluster = electron.getClusters().First()

                if eleCluster.getClusterTime() - posCluster.getClusterTime(
                ) > cluDeltaT:
                    continue

                if eleTrk.getTrackTime() - eleCluster.getClusterTime(
                ) + 43.5 > cluTrkDeltaT:
                    continue

                if posTrk.getTrackTime() - posCluster.getClusterTime(
                ) + 43.5 > cluTrkDeltaT:
                    continue

                if requireECalFiducial:
                    #ANTI-fiducial cut
                    #                    if  myhist.inFiducialRegion(posCluster.getPosition()[0],posCluster.getPosition()[1]) :
                    #                        continue
                    #                    if  myhist.inFiducialRegion(eleCluster.getPosition()[0],eleCluster.getPosition()[1]) :
                    #                        continue
                    #Fiducial cut
                    if not myhist.inFiducialRegion(
                            posCluster.getPosition()[0],
                            posCluster.getPosition()[1]):
                        continue
                    if not myhist.inFiducialRegion(
                            eleCluster.getPosition()[0],
                            eleCluster.getPosition()[1]):
                        continue
                if requireECalSuperFiducial:
                    if not myhist.inSuperFiducialRegion(
                            posCluster.getPosition()[0],
                            posCluster.getPosition()[1]):
                        continue
                    if not myhist.inSuperFiducialRegion(
                            eleCluster.getPosition()[0],
                            eleCluster.getPosition()[1]):
                        continue
            nPassECalMatch += 1
            ##############
            #Passed the cuts..append the candidate index
            findWABPair(electron, hps_event)
            candidateList.append(uc_index)

        numCands = len(candidateList)
        if addFakeEle:
            for track_n in xrange(0, hps_event.getNumberOfTracks()):
                track = hps_event.getTrack(track_n)
                if track is None:
                    continue
                if trkMatchAndFiducial(track.getParticle()) and trkMomentum(
                        track, minPCut, beamCut
                ) and track.getCharge > 0 and newEle.getMomentum(
                )[1] * track.getMomentum(
                )[1] < 0:  # get positron in fudicial region; make sure it's in opposite quadrant
                    myhist.eSum.Fill(newEle.getEnergy() +
                                     pMag(track.getMomentum()))
                    numCands += 1
                    if len(candidateList) == 0:
                        #                        print 'made a new trident event'
                        nFakeTri += 1

        myhist.nCand.Fill(numCands)

        #########################
        #   found some candidates...lets fill plots...
        #########################
        for index in range(0, len(candidateList)):
            particle = hps_event.getParticle(HpsParticle.TC_V0_CANDIDATE,
                                             candidateList[index])
            myhist.fillCandidateHistograms(particle)
            myhist.nTrkCand.Fill(n_tracks)
            myhist.nPosCand.Fill(npositrons)
            myhist.nEleCand.Fill(n_tracks - npositrons)
            myhist.nClustCand.Fill(hps_event.getNumberOfEcalClusters())

#    if(nPassTrkCuts>0):
    myhist.saveHistograms(output_file)

    print "******************************************************************************************"
    print "Number of Events:\t\t", nEvents, "\t\t\t", float(
        nEvents) / nEvents, "\t\t\t", float(nEvents) / nEvents
    print "N(particle) Cuts:\t\t", nPassBasicCuts, "\t\t\t", float(
        nPassBasicCuts) / nEvents, "\t\t\t", float(nPassBasicCuts) / nEvents
    print "V0 Vertex   Cuts:\t\t", nPassV0Cuts, "\t\t\t", float(
        nPassV0Cuts) / nPassBasicCuts, "\t\t\t", float(nPassV0Cuts) / nEvents
    print "Tracking    Cuts:\t\t", nPassTrkCuts, "\t\t\t", float(
        nPassTrkCuts) / nPassV0Cuts, "\t\t\t", float(nPassTrkCuts) / nEvents
    print "ECal Match  Cuts:\t\t", nPassECalMatch, "\t\t\t", float(
        nPassECalMatch) / nPassTrkCuts, "\t\t\t", float(
            nPassECalMatch) / nEvents

    print "Number of Fake Events Added:  \t\t", nFakeTri, "\t\t\t", float(
        nFakeTri) / nPassECalMatch
コード例 #18
0
gSystem.Load(hps_dst_path)

# import the modules used by HpsEvent i.e. HpsEvent, 
# SvtTrack, EcalCluster ...
from ROOT import HpsEvent, SvtTrack

# Open the ROOT file
root_file = TFile(str(args.input))

# Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
# other colletions
tree = root_file.Get("HPS_Event")

# Create an HpsEvent object in order to read the TClonesArray 
# collections
hps_event = HpsEvent()

# Get the HpsEvent branch from the TTree 
b_hps_event = tree.GetBranch("Event")
b_hps_event.SetAddress(AddressOf(hps_event))

track_parameters = [0]*5

# Loop over all events in the file
for entry in xrange(0, tree.GetEntries()) : 
    
    # Print the event number every 500 events
    if (entry+1)%500 == 0 : print "Event " + str(entry+1)

    # Read the ith entry from the tree.  This "fills" HpsEvent and allows 
    # access to all collections
コード例 #19
0
def main():


    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(description='PyRoot analysis demostrating the us of a DST.')
    parser.add_argument("dst_file",  help="ROOT DST file to process")
    parser.add_argument("-o", "--output",  help="Name of output pdf file")
    parser.add_argument("-m", "--mc",  help="is MonteCarlo")
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user 
    if args.output:
        output_file = args.output
    else: 
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to " 
        print output_file


    print "[ HPS ANALYSIS ]:  Output file is "+output_file
    isMC=False
    if args.mc:
        print  "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC=True

    # Load the HpsEvent library.  In this example, this is done by finding the
    # path to the HpsEvent shared library via the environmental variable
    # HPS_DST_PATH.  The HPS_DST_PATH environmental variable points to the
    # location of the build directory containing all binaries and libraries.
    # In general, the location of the library can be anywhere a user wants it
    # to be as long as the proper path is specified. 
    if os.getenv('HPS_DST_PATH') is None: 
        print "[ HPS ANALYSIS ]: Error! Environmental variable HPS_DST_HOME is not set."
        print "\n[ HPS ANALYSIS ]: Exiting ..."
        sys.exit(2)

    hps_dst_path = os.environ['HPS_DST_PATH']
    hps_dst_path += "/build/lib/libHpsEvent.so"
    print "Loading HpsEvent Library from "+hps_dst_path
    # Load the library in ROOT
    import ROOT
    ROOT.gSystem.Load(hps_dst_path)

    # import the modules used by HpsEvent i.e. HpsEvent, 
    # SvtTrack, EcalCluster ...
    from ROOT import HpsEvent, SvtTrack, GblTrack, EcalCluster, EcalHit, TChain, TTree, HpsParticle

#################################
#       Event Selection
################################
    ebeam=1.05
#clean up event first
    nTrkMax=5
    nPosMax=2
# vertex quality cuts for vertexing 
    v0Chi2=10.0
    v0PzMax=1.2
    v0PzMin=0.8
    v0PyMax=0.2 #absolute value
    v0PxMax=0.2 #absolute value
    v0VyMax=1.0# mm from target
    v0VxMax=2.0# mm from target
 #  track quality cuts    
    trkChi2=20.0
#    trkChi2=100.0
    beamCut=0.8
    isoCut=1.0
    minPCut=0.25
    trkPyMax=0.2
    trkPxMax=0.2
    slopeCut=0.0
    z0Cut=0.5

##############
#  ESum slices; upper limits    
    nSlicesESum=5 
    esumMin=0.55
    esumMax=1.2
    sliceSizeESum=0.1 #100MeV starting at esumMin
##############
    trackKiller=False
    tkEnergy=0.3
    tkEff=0.75 

##############
    requireECalMatch = True
    useGBL=True
 
  # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    #use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from "+args.dst_file
    tree=ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file)+"*")    


    # Create an HpsEvent object in order to read the TClonesArray 
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))

    # Get the HpsEvent branch from the TTree 
#    b_hps_event = tree.GetBranch("Event")
#    b_hps_event.SetAddress(ROOT.AddressOf(hps_event))

    #--- Analysis ---#
    #----------------#

    #counters
    nEvents=0;
    nPassBasicCuts=0;
    nPassESumCuts=0;
    nPassV0Cuts=0;
    nPassTrkCuts=0;
    nPassIsoCuts=0;
    nPassNCand=0
    nPassECalMatch=0;
    myhist=myHistograms()
    for entry in xrange(0, tree.GetEntries()) : 
        # Print the event number every 500 events
        if (entry+1)%10000 == 0 : print "Event " + str(entry+1)
        tree.GetEntry(entry)
        if not hps_event.isPair1Trigger() and not isMC : continue
        nEvents+=1
        # Loop over all tracks in the event
        npositrons=0
        n_tracks=0
        for track_n in xrange(0, hps_event.getNumberOfTracks()) :             
            track = hps_event.getTrack(track_n)
            if track is None : 
                continue
#            if not (useGBL ^ track.type<32)  : continue
            n_tracks+=1
            if track.getCharge()>0 :
                npositrons+=1

#        print "nTracks = "+str(n_tracks)+"; nPositrons = "+str(npositrons)
        if n_tracks>nTrkMax : continue  
        if n_tracks<2:  continue        
        if npositrons<1 or npositrons>nPosMax : continue
        nPassBasicCuts+=1
#        print "passed basic cuts"
        candidateList=[]
        bestCandidate=-99
        nCandidate=0
        # loop over all v0 candidates...
        for bsc_index in xrange(0, hps_event.getNumberOfParticles(HpsParticle.BSC_V0_CANDIDATE)):
            particle = hps_event.getParticle(HpsParticle.BSC_V0_CANDIDATE, bsc_index)
            if useGBL and  particle.getType()<32  : continue
            if not useGBL and  particle.getType()>31  : continue
            # Only look at particles that have two daugther particles...
            daughter_particles = particle.getParticles()
            if daughter_particles.GetSize() != 2 : continue
            # Only look at particles that are composed of e+e- pairs
            if daughter_particles.At(0).getCharge()*daughter_particles.At(1).getCharge() > 0 : continue
#            print "Passed daughter number cuts"

            electron =  daughter_particles.At(0)
            positron =  daughter_particles.At(1)
            
            if daughter_particles.At(0).getCharge()>0:
                electron =  daughter_particles.At(1)
                positron =  daughter_particles.At(0)
                
            pEle=electron.getMomentum()
            pPos=positron.getMomentum()

            v0Sum=pMag(pSum(pEle,pPos))
            
            if v0Sum>v0PzMax : continue
            if v0Sum<v0PzMin : continue
            nPassESumCuts+=1

            vchi2=particle.getVertexFitChi2();
            vposition=particle.getVertexPosition();
            vmomentum=particle.getMomentum();
            if vchi2>v0Chi2 :  continue

            if abs(vposition[0])>v0VxMax : continue
            if abs(vposition[1])>v0VyMax :continue

            nPassV0Cuts+=1

#            print "Passed v0 cuts"

            if pMag(pEle)>beamCut or pMag(pPos)>beamCut : continue
            if pMag(pEle)<minPCut or pMag(pPos)<minPCut : continue            
            if pEle[1]*pPos[1]>0 : continue
           
#            print particle.getTracks().At(0).GetEntries()

#            eleTrk=GblTrack(particle.getTracks().At(0))
#            posTrk=GblTrack(particle.getTracks().At(1))

#            if eleTrk.getCharge()>0 :
#                eleTrk=GblTrack(particle.getTracks().At(1))
#                posTrk=GblTrack(particle.getTracks().At(0))

            eleTrk=electron.getTracks().At(0)
            posTrk=positron.getTracks().At(0)

            if eleTrk.getChi2()>trkChi2 or posTrk.getChi2()>trkChi2 :
                continue

            
            if abs(eleTrk.getZ0())>z0Cut or abs(posTrk.getZ0())>z0Cut :
                continue
#            if abs(eleTrk.getTanLambda())<slopeCut or abs(posTrk.getTanLambda())<slopeCut :
#                continue

            if isMC and trackKiller : 
                if pMag(pEle) <tkEnergy and random.random()>tkEff  :
                    continue
            
            nPassTrkCuts+=1
            if requireECalMatch: 
                if positron.getClusters().GetEntries() == 0 :
                    continue
                if electron.getClusters().GetEntries() == 0 :
                    continue
            nPassECalMatch+=1

            if abs(eleTrk.getIsolation(0))<isoCut or abs(eleTrk.getIsolation(1))< isoCut :
                continue
            if abs(posTrk.getIsolation(0))<isoCut or abs(posTrk.getIsolation(1))< isoCut :
                continue
            nPassIsoCuts+=1
            #Passed the cuts..append the candidate index
            candidateList.append(bsc_index)

        #########################        
        #   found some candidates...lets fill plots...
        #########################        
        for index in range(0,len(candidateList)) :
            particle = hps_event.getParticle(HpsParticle.BSC_V0_CANDIDATE, candidateList[index])
            ucparticle= hps_event.getParticle(HpsParticle.UC_V0_CANDIDATE, candidateList[index])
            myhist.fillCandidateHistograms(particle,ucparticle)
         
    if nPassIsoCuts > 0 :
        myhist.saveHistograms(output_file)   
 

    print "\t\t\tTrident Selection Summary"
    print "******************************************************************************************"
    print "Number of Events:\t\t",nEvents,"\t\t\t",float(nEvents)/nEvents,"\t\t\t",float(nEvents)/nEvents
    print "N(particle) Cuts:\t\t",nPassBasicCuts,"\t\t\t",float(nPassBasicCuts)/nEvents,"\t\t\t",float(nPassBasicCuts)/nEvents
    print "ESum        Cuts:\t\t",nPassESumCuts,"\t\t\t",float(nPassESumCuts)/nPassBasicCuts,"\t\t\t",float(nPassESumCuts)/nEvents
    print "V0 Vertex   Cuts:\t\t",nPassV0Cuts,"\t\t\t",float(nPassV0Cuts)/nPassESumCuts,"\t\t\t",float(nPassV0Cuts)/nEvents
    print "Tracking    Cuts:\t\t",nPassTrkCuts,"\t\t\t",float(nPassTrkCuts)/nPassV0Cuts,"\t\t\t",float(nPassTrkCuts)/nEvents
    print "ECal Match  Cuts:\t\t",nPassECalMatch,"\t\t\t",float(nPassECalMatch)/nPassTrkCuts,"\t\t\t",float(nPassECalMatch)/nEvents
    print "Isolation    Cuts:\t\t",nPassIsoCuts,"\t\t\t",float(nPassIsoCuts)/nPassECalMatch,"\t\t\t",float(nPassIsoCuts)/nEvents
コード例 #20
0
def main():


    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(description='PyRoot analysis demostrating the us of a DST.')
    parser.add_argument("dst_file",  help="ROOT DST file to process")
    parser.add_argument("-o", "--output",  help="Name of output pdf file")
    parser.add_argument("-m", "--mc",  help="is MonteCarlo")
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user 
    if args.output:
        output_file = args.output
    else: 
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to " 
        print output_file


    print "[ HPS ANALYSIS ]:  Output file is "+output_file
    isMC=False
    if args.mc:
        print  "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC=True




#################################
#       Event Selection
################################
#clean up event first
#### nominal selection
    nTrkMax=10
    nTrkMin=2
    nPosMax=3
######  two tracks (e+/e-) exactly
#    nTrkMax=2
#    nTrkMin=2
#    nPosMax=1
###### more than 1 electron
#    nTrkMax=10
#    nTrkMin=3
#    nPosMax=1
###################
    #v0 cuts   
    v0Chi2=10
    #ESum -- full region
    v0PzMax=1.2
    v0PzMin=0.55
    #ESum -- Radiative region
#    v0PzMax=1.2
#    v0PzMin=0.80

    v0PyMax=0.2 #absolute value
    v0PxMax=0.2 #absolute value
    v0VzMax=25.0# mm from target
    v0VyMax=1.0# mm from target
    v0VxMax=2.0# mm from target
 #  track quality cuts
    trkChi2=10
    beamCut=0.8
    minPCut=0.05
    trkPyMax=0.2
    trkPxMax=0.2
#    slopeCut=0.03
    slopeCut=0.0
    trkDeltaT=4#ns
    cluDeltaT=2#ns
    cluTrkDeltaT=4#ns
##############
#  ESum slices; upper limits    
    nSlicesESum=5 
    esumMin=0.55
    esumMax=1.2
    sliceSizeESum=0.1 #100MeV starting at esumMin
##############
    trackKiller=False
    tkThreshold=0.5 #GeV, below this start killing tracks
    tkThreshEff=1.0
    tkLowPoint=0.20
    tkLowPointEff=0.40
#    tkSlope=2.6 
#    tkIntercept=-0.04
    #calculate tkSlope and Intercept   
    tkSlope=(tkThreshEff-tkLowPointEff)/(tkThreshold-tkLowPoint)
    tkIntercept=tkThreshEff-tkSlope*tkThreshold

##############
    requireECalMatch = True
    requireECalFiducial = False
    requireECalSuperFiducial = True
    useGBL=True


     # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    #use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from "+args.dst_file
    tree=ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file)+"*")    
    # Create an HpsEvent object in order to read the TClonesArray 
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))



    #--- Analysis ---#
    #----------------#

    #counters
    nEvents=0;
    nPassBasicCuts=0;
    nPassV0Cuts=0;
    nPassTrkCuts=0;
    nPassNCand=0
    nPassECalMatch=0;
  

    # Loop over all events in the file
    for entry in xrange(0, tree.GetEntries()) : 
        # Print the event number every 500 events
        if (entry+1)%10000 == 0 : print "Event " + str(entry+1)
        tree.GetEntry(entry)
#        print str(hps_event.isPulserTrigger())+ ' ' +str(hps_event.isSingle1Trigger())
        if hps_event.isPulserTrigger() :
            print 'found pulser event' 
                
#        if not hps_event.isPair1Trigger() and not isMC: continue
#        if not hps_event.isPulserTrigger() and not isMC: continue
        nEvents+=1
        # Loop over all tracks in the event
        npositrons=0
        n_tracks=0
        for track_n in xrange(0, hps_event.getNumberOfTracks()) :             
            track = hps_event.getTrack(track_n)
            if track is None : 
                continue
#            if useGBL and track.getParticle().getType()<32  : continue
#            if not useGBL and track.getParticle().getType()>31  : continue
            if trkMatchAndFiducial(track.getParticle()) and trkMomentum(track,minPCut,beamCut): # count only matched tracks in defined fiducial region
                n_tracks+=1
                if track.getCharge()>0 :
                    npositrons+=1
                    myhist.rawposMom.Fill(pMag(track.getMomentum()))
                else :
                    myhist.raweleMom.Fill(pMag(track.getMomentum()))

        print "nTracks = "+str(n_tracks)+"; nPositrons = "+str(npositrons)
#        if n_tracks/2.0>nTrkMax : continue   #do this very dumb thing (divide by 2 to un-double count GBL tracks)
#        if n_tracks/2.0<2:  continue        
        myhist.nTrk.Fill(n_tracks);
        myhist.nPos.Fill(npositrons);
        myhist.nEle.Fill(n_tracks-npositrons);
        myhist.nClust.Fill(hps_event.getNumberOfEcalClusters())

        if n_tracks>nTrkMax : continue  
        if n_tracks<nTrkMin:  continue        
        if npositrons<1 or npositrons>nPosMax : continue
        nPassBasicCuts+=1


    myhist.saveHistograms(output_file)   

    print "******************************************************************************************"
コード例 #21
0
ファイル: wabAnalysis.py プロジェクト: JeffersonLab/HPS-CODE
def main():
    global beamEnergy
    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(
        description='PyRoot analysis demostrating the us of a DST.')
    parser.add_argument("dst_file", help="ROOT DST file to process")
    parser.add_argument("-o", "--output", help="Name of output pdf file")
    parser.add_argument("-m", "--mc", help="is MonteCarlo")
    parser.add_argument("-p", "--pulser", help="is Pulser")
    parser.add_argument("-e", "--energy", help="beam energy")
    parser.add_argument("-r", "--rad", help="radiative cut")
    parser.add_argument("-w", "--weigh", help="track efficiency weighing")
    parser.add_argument("-n", "--newfile", help="Name of skim output file")

    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user
    if args.output:
        output_file = args.output
    else:
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to "
        print output_file

    print "[ HPS ANALYSIS ]:  Output file is " + output_file
    isMC = False
    if args.mc:
        print "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC = True

    isPulser = False
    if args.pulser:
        print "[ HPS ANALYSIS ]: Setting to run from a pulser file"
        isPulser = True

    doRadRegion = False
    if args.rad:
        print "[ HPS ANALYSIS ]: Setting to run with Radiative Region Cut"
        doRadRegion = True

    weightTracks = False
    if args.weigh:
        print "[ HPS ANALYSIS ]: Setting to run with track efficiency weighing"
        weightTracks = True

    if args.energy:
        print 'Setting beam energy to ' + args.energy
        beamEnergy = float(args.energy)
        myhist.setEnergyScales(beamEnergy)

    doSkim = False
    if args.newfile:
        print 'skimming into ' + args.newfile
        newfile = args.newfile
        doSkim = True

    doTB = True
    doTT = False  #or BB
    doEpEm = True
    doEmEm = False
    doEpEp = False
    doEpGam = True
    doEmGam = True
    doGamGam = False
    do3Body = False

    #################################
    #       Event Selection
    ################################
    # Define cuts
    #  mg...these cuts are from Omar's bump hunt selection (as of 1/10/17)
    #  he has already selected events with top/bottom e+e- tracks with track momentum <0.8 GeV
    # Accidentals
    #    radiative_cut = v0_p > 0.8*1.056
    #    v0_p_cut = v0_p < 1.2*1.056
    #    chi2_cut = (electron_chi2 < 40) & (positron_chi2 < 40)

    #    top_track_cluster_dt = top_cluster_time - top_time
    #    bot_track_cluster_dt = bot_cluster_time - bot_time
    #    track_cluster_dt_cut = ((np.absolute(top_track_cluster_dt - 43) < 4.5)
    #                            & (np.absolute(bot_track_cluster_dt - 43) < 4.5))
    #    cluster_time_diff_cut = np.absolute(cluster_time_diff) < 2
    #
    #    base_selection = radiative_cut & v0_p_cut & chi2_cut & track_cluster_dt_cut & cluster_time_diff_cut

    # e+ converted WABS
    #    l1_cut      = (positron_has_l1 == 1)
    #    l2_cut      = (positron_has_l2 == 1)
    #    positron_d0_cut = positron_d0 < 1.1
    #    asym = (electron_pt - positron_pt)/(electron_pt + positron_pt)
    #    asym_cut = asym < .47
    #
    #    wab_cuts = l1_cut & l2_cut & positron_d0_cut & asym_cut
    #
    #    selection = base_selection & wab_cuts
    ###########################################

    #### nominal selection
    nTrkMax = 10
    nTrkMin = 2
    nPosMax = 3
    ######  two tracks (e+/e-) exactly
    #    nTrkMax=2
    #    nTrkMin=2
    #    nPosMax=1
    ###### more than 1 electron
    #    nTrkMax=10
    #    nTrkMin=3
    #    nPosMax=1
    ###################
    #v0 cuts
    v0Chi2 = 10
    #ESum -- full region
    v0PzMax = 1.1 * beamEnergy
    v0PzMin = 0.5 * beamEnergy
    if doRadRegion:
        v0PzMin = 0.8 * beamEnergy
#  track quality cuts
    trkChi2 = 40
    beamCut = 0.8 * beamEnergy
    minPCut = 0.05 * beamEnergy
    slopeCut = 0.0
    #    if isMC:
    #        cluDeltaT=4
    #    else:
    cluDeltaT = 2  #ns
    #    cluDeltaT=10#ns
    cluTrkDeltaT = 4.5  #ns
    cluTrkOffset = 43  #ns

    # non-converted WAB coplanarity cut:
    wabCoplanMean = 150  #degrees
    wabCoplanCut = 15  #degrees

    trackKiller = False
    killInMomentum = False
    killInClusterPosition = False
    killInTrackSlope = False
    weighInEclVsY = True

    effMomFileName = '/u/br/mgraham/hps-analysis/TrackEfficiency/cop180_EfficiencyResults.root'
    effRatioName = 'h_Ecl_hps_005772_eleEff_ratio'
    effMomFile = ROOT.TFile(effMomFileName)
    effMomData = getEffRatio(effMomFile, effRatioName)
    effMomData.Print("v")
    print 'Efficiency vs Momentum:  MC'
    fixTH1EffBins(effMomData)
    for i in range(0, effMomData.GetNbinsX()):
        print 'efficiency ratio ' + str(i) + '   ' + str(
            effMomData.GetBinCenter(i)) + ' ' + str(
                effMomData.GetBinContent(i))

    effEclVsYFileName = '/u/br/mgraham/hps-analysis/TrackEfficiency/cop180_TwoD-EfficiencyResults.root'
    effEclVsYFile = ROOT.TFile(effEclVsYFileName)
    eff2DEleRatioName = 'data_over_wab_plus_tritig_eleEffRatio'
    eff2DEleRatio = getEffTH2(effEclVsYFile, eff2DEleRatioName)
    eff2DEleRatio.Print("V")
    fixTH2EffBins(eff2DEleRatio)

    eff2DPosRatioName = 'data_over_wab_plus_tritig_posEffRatio'
    #    eff2DPosRatio=getEffTH2(effEclVsYFile,eff2DPosRatioName)
    eff2DPosRatio = getEffTH2(effEclVsYFile, eff2DEleRatioName)
    eff2DPosRatio.Print("V")
    fixTH2EffBins(eff2DPosRatio)

    ###############
    requireECalMatch = True
    requireECalFiducial = False
    requireECalSuperFiducial = False
    requireECalTimingCoincidence = False
    requireECalTrackTiming = False
    requireWABCoplanarity = False
    useGBL = True

    # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    #use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from " + args.dst_file
    tree = ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file) + "*")
    # Create an HpsEvent object in order to read the TClonesArray
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))
    #--- Analysis ---#
    #----------------#

    #counters
    nEvents = 0
    nPassBasicCuts = 0
    nPassV0Cuts = 0
    nPassTrkCuts = 0
    nPassNCand = 0
    nPassECalMatch = 0
    nFakeTri = 0

    seedCnt = 0
    split = 0
    bsize = 64000
    nKilled = 0
    nTrks = 0
    nevnts = tree.GetEntries()
    tree.Print("V")
    #Create a new file + a clone of old tree in new file
    if doSkim:
        print 'creating skim file at ' + newfile
        newRootFile = ROOT.TFile(newfile, "recreate")
        print 'done making new file!'
        newtree = ROOT.TTree("HPS_Event", "HPS event tree")
        print 'Made New Tree'
        newtree.Print('V')
        #        new_hps_event = HpsEvent()
        b_new_hps_event = newtree.Branch("Event", "HpsEvent",
                                         ROOT.AddressOf(hps_event), 32000, 3)
        #        newtree = tree.CloneTree();
        print 'done making new tree!'

    # Loop over all events in the file
    for entry in xrange(0, tree.GetEntries()):

        nEpEmTB = 0
        nEmEmTB = 0
        nEmGamTB = 0
        #        print "Next event..."
        # Print the event number every 500 events
        if (entry + 1) % 100 == 0: print "Event " + str(entry + 1)
        tree.GetEntry(entry)
        if not hps_event.isPair1Trigger() and not isMC and not isPulser:
            continue
        nEvents += 1

        #kill tracks by killing L1 hits (and then checking if they have enough hits)
        survivingFSP = []
        for fsp_n in xrange(
                0,
                hps_event.getNumberOfParticles(
                    HpsParticle.FINAL_STATE_PARTICLE)):
            fsp = hps_event.getParticle(HpsParticle.FINAL_STATE_PARTICLE,
                                        fsp_n)
            if fsp.getType() == 0:  # is a photon...
                survivingFSP.append(fsp)
                continue
            if useGBL and fsp.getType() < 32: continue
            if not useGBL and fsp.getType() > 31: continue
            trk = fsp.getTracks()[0]
            yesL1Hit = myhist.hasL1Hit(trk)
            nHits = len(trk.getSvtHits())
            slp = trk.getTanLambda()
            #            print "This track has #nhits = "+str(nHits)
            if not yesL1Hit:
                survivingFSP.append(fsp)
                continue  #this track doesn't have an L1 hit to kill
            if nHits > 5:
                survivingFSP.append(fsp)
                continue  #even if we kill L1 hit, this track will survive
#            bin=effSlopeData.FindBin(slp)
#            eff=1-effSlopeData.GetBinContent(bin) #the slope "efficiecny" is actually an inefficiency
#            rndm=random.random()
#            print 'found a 5 hit track with slope = '+str(slp)+'; eff = '+str(eff)+"; rndm = "+str(rndm)
#            if isMC and trackKiller and killInTrackSlope and rndm>eff :
#            if rndm>eff :
# L1 hit got killed!  Since we already checked nHits==5, this track is dead
#                print 'killing track with slope = ' +str(slp)
#                continue
#            else :
            survivingFSP.append(fsp)

#        print "number of surviving particles = "+str(len(survivingFSP))
# Loop over all tracks in the event
        goodtrk = []
        gamList = []
        eleList = []
        posList = []
        #        for fsp_n in xrange(0, hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE)) :
        #            fsp = hps_event.getParticle(HpsParticle.FINAL_STATE_PARTICLE,fsp_n)
        for fsp in survivingFSP:
            if fsp.getType() == 0:  #might be good photon
                if not checkClusterFiducialAndTiming(fsp,
                                                     requireECalSuperFiducial):
                    continue
                gamList.append(fsp)
            else:  #maybe a good track?
                if useGBL and fsp.getType() < 32: continue
                if not useGBL and fsp.getType() > 31: continue
                track = fsp.getTracks()[0]
                if track is None: continue  #this shouldn't happen
                if requireECalMatch and not trkMatchAndFiducial(
                        track.getParticle(), requireECalSuperFiducial):
                    continue
                if not trkMomentum(track, minPCut, beamCut): continue
                if myhist.checkIfShared(goodtrk, fsp):
                    #                    print 'fromscratch::now goodtrk is '+str(len(goodtrk))+' tracks long'
                    #                    for trk in goodtrk:
                    #                        print len(trk.getTracks()[0].getSvtHits())
                    continue
                nTrks += 1  # check to see if we already found this track
                if trackKiller and isMC and requireECalMatch:  # use the ECAL cluster to do this!!!
                    if killInMomentum:
                        #                        p=pMag(fsp.getMomentum())
                        p = fsp.getEnergy()
                        bin = effMomData.FindBin(p)
                        tkEff = effMomData.GetBinContent(bin)
                        #                        print str(p)+ ' '+str(bin)+' '+str(tkEff)
                        if random.random(
                        ) > tkEff and tkEff != 0.0:  #high ratio of efficiencies, this hardly  kills...low, kills a lot
                            print "REJECTING THIS TRACK!!! " + str(p)
                            nKilled += 1
                            continue
#                    if killInClusterPosition:
#                        clEle=fsp.getClusters()[0]
#                        clX=clEle.getPosition()[0]
#                        clY=clEle.getPosition()[1]
#                        if fsp.getCharge()<0 :
#                            bin=effData.FindBin(clX,clY)
#                        else:
#                            bin=effData.FindBin(-clX+42.55,clY) # flip sign +42.55mm for positron side (this isn't strictly correct)!!!
#                        tkEff=effData.GetBinContent(bin)
#                        if random.random()>tkEff  and tkEff!=0.0:
#                            print str(clX)+ ' '+str(clY)+' '+str(bin)+' '+str(tkEff)
#                            print "REJECTING THIS ELECTRON TRACK!!! "+str(clX)
#                            continue

#otherwise this is a new track
                goodtrk.append(fsp)

        if len(goodtrk) > nTrkMax: continue  # too many tracks

        for fsp in goodtrk:
            if fsp.getCharge() < 0:
                eleList.append(fsp)
            else:
                posList.append(fsp)

        if len(posList) > nPosMax: continue  # too many positrons!

        # we found a good event...fill the new tree so that we can save for later
        if doSkim:
            print "adding this event to the skim"
            newtree.Fill()

#        print 'found '+str(len(goodtrk))+' tracks in this event'
#        print '\t\t\t   # electrons = ' +str(len(eleList))
#        print '\t\t\t   # positrons = ' +str(len(posList))
#        print '\t\t\t   # photons = ' +str(len(gamList))

#do analysis for e+e- pairs
        if doEpEm:
            for pos in posList:
                if (requireECalTrackTiming
                        and not myhist.clusterTrackCoincidence(
                            pos, cluTrkDeltaT, cluTrkOffset)):
                    continue
                for ele in eleList:
                    if (requireECalTrackTiming
                            and not myhist.clusterTrackCoincidence(
                                ele, cluTrkDeltaT, cluTrkOffset)):
                        continue
                    if (requireECalTimingCoincidence
                            and not myhist.simpleClusterCoincidence(
                                ele, pos, cluDeltaT)) or pMag(
                                    pSum(ele.getMomentum(),
                                         pos.getMomentum())) < v0PzMin:
                        continue
                    eleHitInL1 = myhist.hasL1Hit(ele.getTracks()[0])
                    posHitInL1 = myhist.hasL1Hit(pos.getTracks()[0])
                    eleHitInL2 = myhist.hasLXHit(ele.getTracks()[0], 2)
                    posHitInL2 = myhist.hasLXHit(pos.getTracks()[0], 2)
                    eleWgt = 1.0
                    posWgt = 1.0
                    if weightTracks and isMC and requireECalMatch:
                        clEle = ele.getClusters()[0]
                        clEcl = clEle.getEnergy()
                        clY = clEle.getPosition()[1]
                        eleWgt = eff2DEleRatio.GetBinContent(
                            eff2DEleRatio.FindBin(clEcl, clY))
                        clPos = pos.getClusters()[0]
                        clEcl = clPos.getEnergy()
                        clY = clPos.getPosition()[1]
                        posWgt = eff2DPosRatio.GetBinContent(
                            eff2DPosRatio.FindBin(clEcl, clY))
                    if doTB and ele.getMomentum()[1] * pos.getMomentum()[1] < 0:
                        myhist.fillTwoBody(pos, ele, 'EpEm', 'TB',
                                           eleWgt * posWgt)
                        if eleHitInL1 and posHitInL1:
                            myhist.fillTwoBody(pos, ele, 'EpEmL1L1', 'TB',
                                               eleWgt * posWgt)
#                            if not eleHitInL2 and not posHitInL2:
#                                myhist.fillTwoBody(pos,ele,'EpEmL1NoL2L1NoL2','TB')
#                            elif not eleHitInL2 :
#                                myhist.fillTwoBody(pos,ele,'EpEmL1NoL2L1L2','TB')
#                            elif not posHitInL2 :
#                                myhist.fillTwoBody(pos,ele,'EpEmL1L2L1NoL2','TB')
#                            else:
#                                myhist.fillTwoBody(pos,ele,'EpEmL1L2L1L2','TB')
                        elif eleHitInL1:
                            myhist.fillTwoBody(pos, ele, 'EpEmL2L1', 'TB',
                                               eleWgt * posWgt)
#                           if not eleHitInL2 :
#                               myhist.fillTwoBody(pos,ele,'EpEmNoL1L2L1NoL2','TB')
#                           else:
#                               myhist.fillTwoBody(pos,ele,'EpEmNoL1L2L1L2','TB')
                        elif posHitInL1:
                            myhist.fillTwoBody(pos, ele, 'EpEmL1L2', 'TB',
                                               eleWgt * posWgt)
#                           if not posHitInL2 :
#                               myhist.fillTwoBody(pos,ele,'EpEmL1NoL2NoL1L2','TB')
#                           else:
#                               myhist.fillTwoBody(pos,ele,'EpEmL1L2NoL1L2','TB')
                        else:
                            myhist.fillTwoBody(pos, ele, 'EpEmL2L2', 'TB',
                                               eleWgt * posWgt)
#do analysis for e-e- pairs
        if doEmEm:
            for i in range(0, len(eleList)):
                ele1 = eleList[i]
                if (requireECalTrackTiming
                        and not myhist.clusterTrackCoincidence(
                            ele1, cluTrkDeltaT, cluTrkOffset)):
                    continue
                for k in range(i + 1, len(eleList)):
                    ele2 = eleList[k]
                    if (requireECalTrackTiming
                            and not myhist.clusterTrackCoincidence(
                                ele2, cluTrkDeltaT, cluTrkOffset)):
                        continue
                    if (requireECalTimingCoincidence
                            and not myhist.simpleClusterCoincidence(
                                ele1, ele2, cluDeltaT)) or pMag(
                                    pSum(ele1.getMomentum(),
                                         ele2.getMomentum())) < v0PzMin:
                        continue
                    ele1HitInL1 = myhist.hasL1Hit(ele1.getTracks()[0])
                    ele2HitInL1 = myhist.hasL1Hit(ele2.getTracks()[0])
                    if doTB and ele1.getMomentum()[1] * ele2.getMomentum(
                    )[1] < 0:
                        myhist.fillTwoBody(ele1, ele2, 'EmEm',
                                           'TB')  #potentially comes from WABs
                        if ele1HitInL1 and ele2HitInL1:
                            myhist.fillTwoBody(ele1, ele2, 'EmEmL1L1', 'TB')
                        elif ele1HitInL1:
                            myhist.fillTwoBody(ele1, ele2, 'EmEmL2L1', 'TB')
                        elif ele2HitInL1:
                            myhist.fillTwoBody(ele1, ele2, 'EmEmL1L2', 'TB')
                        else:
                            myhist.fillTwoBody(ele1, ele2, 'EmEmL2L2', 'TB')
#do analysis for e-gamma pairs
        if doEmGam:
            for ele in eleList:
                if (requireECalTrackTiming
                        and not myhist.clusterTrackCoincidence(
                            ele, cluTrkDeltaT, cluTrkOffset)):
                    continue
                for gam in gamList:
                    gamY = gam.getClusters().First().getPosition()[1]
                    if requireECalTimingCoincidence and not myhist.clusterCoincidence(
                            ele, gam):
                        continue
                    if requireWABCoplanarity and not myhist.cutCoplanarity(
                            ele, gam, wabCoplanCut, wabCoplanMean):
                        continue
                    if pMag(pSum(ele.getMomentum(),
                                 gam.getMomentum())) < v0PzMin:
                        continue
                    eleHitInL1 = myhist.hasL1Hit(ele.getTracks()[0])
                    eleHitInL2 = myhist.hasLXHit(ele.getTracks()[0], 2)
                    eleHitInL3 = myhist.hasLXHit(ele.getTracks()[0], 3)
                    eleWgt = 1.0
                    if weightTracks and isMC and requireECalMatch:
                        clEle = ele.getClusters()[0]
                        clEcl = clEle.getEnergy()
                        clY = clEle.getPosition()[1]
                        eleWgt = eff2DEleRatio.GetBinContent(
                            eff2DEleRatio.FindBin(clEcl, clY))
                    if doTB and ele.getMomentum(
                    )[1] * gamY < 0:  #(these could be WABS!)
                        myhist.fillTwoBody(gam, ele, 'GamEm', 'TB', eleWgt)
                        if eleHitInL1:
                            myhist.fillTwoBody(gam, ele, 'GamEmL1', 'TB',
                                               eleWgt)
                            if not eleHitInL2:
                                myhist.fillTwoBody(gam, ele, 'GamEmL1NoL2',
                                                   'TB', eleWgt)
                            else:
                                myhist.fillTwoBody(gam, ele, 'GamEmL1L2', 'TB',
                                                   eleWgt)
                        else:
                            myhist.fillTwoBody(gam, ele, 'GamEmL2', 'TB',
                                               eleWgt)
                    elif doTT and ele.getMomentum()[1] > 0:
                        myhist.fillTwoBody(gam, ele, 'GamEm', 'TT', eleWgt)
                    elif doTT and ele.getMomentum()[1] < 0:
                        myhist.fillTwoBody(gam, ele, 'GamEm', 'BB', eleWgt)

#do analysis for e-gamma pairs
        if doEpGam:
            for pos in posList:
                if (requireECalTrackTiming
                        and not myhist.clusterTrackCoincidence(
                            pos, cluTrkDeltaT, cluTrkOffset)):
                    continue
                for gam in gamList:
                    gamY = gam.getClusters().First().getPosition()[1]
                    if requireECalTimingCoincidence and not myhist.clusterCoincidence(
                            pos, gam):
                        continue
                    if requireWABCoplanarity and not myhist.cutCoplanarity(
                            pos, gam, wabCoplanCut, wabCoplanMean):
                        continue
                    if pMag(pSum(pos.getMomentum(),
                                 gam.getMomentum())) < v0PzMin:
                        continue
                    posHitInL1 = myhist.hasL1Hit(pos.getTracks()[0])
                    posHitInL2 = myhist.hasLXHit(pos.getTracks()[0], 2)
                    posHitInL3 = myhist.hasLXHit(pos.getTracks()[0], 3)
                    posWgt = 1.0
                    if weightTracks and isMC and requireECalMatch:
                        clPos = pos.getClusters()[0]
                        clEcl = clPos.getEnergy()
                        clY = clPos.getPosition()[1]
                        posWgt = eff2DPosRatio.GetBinContent(
                            eff2DPosRatio.FindBin(clEcl, clY))
                    if doTB and pos.getMomentum(
                    )[1] * gamY < 0:  #(these could be WABS!)
                        myhist.fillTwoBody(gam, pos, 'GamEp', 'TB', posWgt)
                        if posHitInL1:
                            myhist.fillTwoBody(gam, pos, 'GamEpL1', 'TB',
                                               posWgt)
                            if not posHitInL2:
                                myhist.fillTwoBody(gam, pos, 'GamEpL1NoL2',
                                                   'TB', posWgt)
                            else:
                                myhist.fillTwoBody(gam, pos, 'GamEpL1L2', 'TB',
                                                   posWgt)
                        else:
                            myhist.fillTwoBody(gam, pos, 'GamEpL2', 'TB',
                                               posWgt)
                    elif doTT and pos.getMomentum()[1] > 0:
                        myhist.fillTwoBody(gam, pos, 'GamEp', 'TT', posWgt)
                    elif doTT and pos.getMomentum()[1] < 0:
                        myhist.fillTwoBody(gam, pos, 'GamEp', 'BB', posWgt)

    myhist.saveHistograms(output_file)
    if doSkim:
        newtree.Print()
        newtree.AutoSave()

    print "******************************************************************************************"
    print "Number of tracks killed = " + str(nKilled) + " out of " + str(
        nTrks) + " total = " + str(float(nKilled) / nTrks)
コード例 #22
0
def main():
    global beamEnergy
    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(description='PyRoot analysis demostrating the us of a DST.')
    parser.add_argument("dst_file",  help="ROOT DST file to process")
    parser.add_argument("-o", "--output",  help="Name of output pdf file")
    parser.add_argument("-m", "--mc",  help="is MonteCarlo")
    parser.add_argument("-p", "--pulser",  help="is Pulser")
    parser.add_argument("-e","--energy",help="beam energy")
    parser.add_argument("-r","--rad",help="radiative cut")
    parser.add_argument("-w","--weigh",help="track efficiency weighing")
    parser.add_argument("-n", "--newfile",  help="Name of skim output file")
    
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user 
    if args.output:
        output_file = args.output
    else: 
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to " 
        print output_file


    print "[ HPS ANALYSIS ]:  Output file is "+output_file
    isMC=False
    if args.mc:
        print  "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC=True


    isPulser=False
    if args.pulser:
        print  "[ HPS ANALYSIS ]: Setting to run from a pulser file"
        isPulser=True

    doRadRegion=False
    if args.rad: 
        print "[ HPS ANALYSIS ]: Setting to run with Radiative Region Cut" 
        doRadRegion=True

    weightTracks=False
    if args.weigh: 
        print "[ HPS ANALYSIS ]: Setting to run with track efficiency weighing" 
        weightTracks=True

    if args.energy : 
        print 'Setting beam energy to '+args.energy
        beamEnergy=float(args.energy)
        myhist.setEnergyScales(beamEnergy)

    doSkim=False
    if args.newfile :
        print 'skimming into '+args.newfile
        newfile=args.newfile
        doSkim=True

    doTB=True
    doTT=False #or BB
    doEpEm=True
    doEmEm=False
    doEpEp=False
    doEpGam=True
    doEmGam=True
    doGamGam=False
    do3Body=False
    


#################################
#       Event Selection
################################
# Define cuts
#  mg...these cuts are from Omar's bump hunt selection (as of 1/10/17)
#  he has already selected events with top/bottom e+e- tracks with track momentum <0.8 GeV
# Accidentals
#    radiative_cut = v0_p > 0.8*1.056
#    v0_p_cut = v0_p < 1.2*1.056
#    chi2_cut = (electron_chi2 < 40) & (positron_chi2 < 40)

#    top_track_cluster_dt = top_cluster_time - top_time
#    bot_track_cluster_dt = bot_cluster_time - bot_time
#    track_cluster_dt_cut = ((np.absolute(top_track_cluster_dt - 43) < 4.5) 
#                            & (np.absolute(bot_track_cluster_dt - 43) < 4.5))
#    cluster_time_diff_cut = np.absolute(cluster_time_diff) < 2
#    
#    base_selection = radiative_cut & v0_p_cut & chi2_cut & track_cluster_dt_cut & cluster_time_diff_cut

    # e+ converted WABS
#    l1_cut      = (positron_has_l1 == 1)
#    l2_cut      = (positron_has_l2 == 1)
#    positron_d0_cut = positron_d0 < 1.1
#    asym = (electron_pt - positron_pt)/(electron_pt + positron_pt)
#    asym_cut = asym < .47
#
#    wab_cuts = l1_cut & l2_cut & positron_d0_cut & asym_cut
#
#    selection = base_selection & wab_cuts
###########################################


#### nominal selection
    nTrkMax=10
    nTrkMin=2
    nPosMax=3
######  two tracks (e+/e-) exactly
#    nTrkMax=2
#    nTrkMin=2
#    nPosMax=1
###### more than 1 electron
#    nTrkMax=10
#    nTrkMin=3
#    nPosMax=1
###################
    #v0 cuts   
    v0Chi2=75
    #ESum -- full region
    v0PzMax=1.1*beamEnergy    
    v0PzMin=0.5*beamEnergy
    if doRadRegion: 
        v0PzMin=0.8*beamEnergy
 #  track quality cuts
    trkChi2=40
    beamCut=0.8*beamEnergy
    minPCut=0.05*beamEnergy    
    slopeCut=0.0
#    if isMC: 
#        cluDeltaT=4
#    else:
    cluDeltaT=2#ns
#    cluDeltaT=10#ns
#    cluTrkDeltaT=4.5#ns
    cluTrkDeltaT=5.8#ns
    cluTrkOffset=43#ns

    # non-converted WAB coplanarity cut: 
    wabCoplanMean=150 #degrees
    wabCoplanCut=15  #degrees
    wabD0Cut=1.1  #mm, accept less than
    wabPtCut=0.47 #pt asymmetry, accept less than

###############
    requireWABCoplanarity = False
    requireECalMatch = True
    requireECalFiducial = False
    requireECalSuperFiducial = True
    requireECalTimingCoincidence = True
    requireECalTrackTiming = True
###   require the track and v0 chi^2 for "omars base"
    requireTrkChiSq=True
    requireV0ChiSq=True
####  these two are wab supression
    requireWABD0Cut=True
    requireWABPtCut=True
####
    useGBL=True
#################

    trackKiller=True
    killInMomentum=False
    killInClusterPosition=False
    killInTrackSlope= True
    weighInEclVsY=True

    effMomFileName='/u/br/mgraham/hps-analysis/TrackEfficiency/cop180_EfficiencyResults.root'
    effRatioName='h_Ecl_hps_005772_eleEff_ratio'
    effMomFile=ROOT.TFile(effMomFileName)
    effMomData=getEffRatio(effMomFile,effRatioName)
    effMomData.Print("v")
    print 'Efficiency vs Momentum:  MC' 
    fixTH1EffBins(effMomData) 
    for i in range(0,effMomData.GetNbinsX()) : 
        print 'efficiency ratio '+str(i)+'   '+str(effMomData.GetBinCenter(i))+' '+str(effMomData.GetBinContent(i))

    effEclVsYFileName='/u/br/mgraham/hps-analysis/TrackEfficiency/cop180_TwoD-EfficiencyResults.root'
    effEclVsYFile=ROOT.TFile(effEclVsYFileName)
    eff2DEleRatioName='data_over_wab_plus_tritig_eleEffRatio'
    eff2DEleRatio=getEffTH2(effEclVsYFile,eff2DEleRatioName)
    eff2DEleRatio.Print("V")
    fixTH2EffBins(eff2DEleRatio)

    eff2DPosRatioName='data_over_wab_plus_tritig_posEffRatio'
#    eff2DPosRatio=getEffTH2(effEclVsYFile,eff2DPosRatioName)
    eff2DPosRatio=getEffTH2(effEclVsYFile,eff2DEleRatioName)
    eff2DPosRatio.Print("V")
    fixTH2EffBins(eff2DPosRatio)


    effSlopeFileName='/u/br/mgraham/hps-analysis/WABs/EmGamma-L1HitEfficiencyResults.root'
    effRatioName='p2slopehps_005772.1GamEm_L1HitInefficiency'
    effSlopeFile=ROOT.TFile(effSlopeFileName)
    effSlopeFile.ls()
    effSlopeData=getEffTH1(effSlopeFile,effRatioName)
    effSlopeData.Print("v")
    print 'L1 Hit Efficiency vs Slope:  MC' 
    fixTH1EffBins(effSlopeData) 

     # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    #use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from "+args.dst_file
    tree=ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file)+"*")    
    # Create an HpsEvent object in order to read the TClonesArray 
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))
    #--- Analysis ---#
    #----------------#

    #counters
    nEvents=0;
    nPassBasicCuts=0;
    nPassV0Cuts=0;
    nPassTrkCuts=0;
    nPassNCand=0
    nPassECalMatch=0;
    nFakeTri=0
    
    seedCnt=0
    split = 0;
    bsize = 64000;
    nKilled=0
    nTrks=0
    nevnts=tree.GetEntries()
    tree.Print("V")
  #Create a new file + a clone of old tree in new file
    if doSkim:
        print 'creating skim file at '+newfile
        newRootFile = ROOT.TFile(newfile,"recreate");
        print 'done making new file!'
        newtree=ROOT.TTree("HPS_Event", "HPS event tree"); 
        print 'Made New Tree'
        newtree.Print('V')
#        new_hps_event = HpsEvent()
        b_new_hps_event = newtree.Branch("Event","HpsEvent", ROOT.AddressOf(hps_event),32000,3)
#        newtree = tree.CloneTree();
        print 'done making new tree!'

    print 'Number of entries in Tree = '+str(tree.GetEntries())

    # Loop over all events in the file
    for entry in xrange(0, tree.GetEntries()) :                  
        nEpEmTB=0
        nEmEmTB=0
        nEmGamTB=0
#        print "Next event..."
        # Print the event number every 500 events
        if (entry+1)%100 == 0 : print "Event " + str(entry+1)
        tree.GetEntry(entry)
        if not hps_event.isPair1Trigger() and not isMC and not isPulser: continue
        nEvents+=1
      
        #kill tracks by killing L1 hits (and then checking if they have enough hits)
        survivingFSP=[]
        removedL1Hit={}
        for fsp_n in xrange(0, hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE)) :             
            fsp = hps_event.getParticle(HpsParticle.FINAL_STATE_PARTICLE,fsp_n)
            if fsp.getType()==0 : # is a photon...            
                survivingFSP.append(fsp)
                continue
            if useGBL and  fsp.getType()<32 : continue
            if not useGBL and  fsp.getType()>31  : continue
            trk=fsp.getTracks()[0]
            yesL1Hit=myhist.hasL1Hit(trk)
            nHits=len(trk.getSvtHits())
            slp=trk.getTanLambda()
            bin=effSlopeData.FindBin(slp)
            eff=1-effSlopeData.GetBinContent(bin) #the slope "efficiecny" is actually an inefficiency
            rndm=random.random()            
            if isMC and trackKiller and killInTrackSlope and rndm>eff : 
                if nHits==5: 
                    print 'Removing this track due to L1 inefficiency'
                    continue
                else :
                    print 'removing hit due to L1 inefficiency'
                    survivingFSP.append(fsp)
                    removedL1Hit[fsp]=True
            else: 
                survivingFSP.append(fsp)
                removedL1Hit[fsp]=False

#            print "This track has #nhits = "+str(nHits)
#            if not yesL1Hit : 
#                survivingFSP.append(fsp)
#                continue #this track doesn't have an L1 hit to kill
#            if nHits>5 : 
#                survivingFSP.append(fsp)
#                continue #even if we kill L1 hit, this track will survive
#            bin=effSlopeData.FindBin(slp)
#            eff=1-effSlopeData.GetBinContent(bin) #the slope "efficiecny" is actually an inefficiency
#            rndm=random.random()
#            print 'found a 5 hit track with slope = '+str(slp)+'; eff = '+str(eff)+"; rndm = "+str(rndm)
#            if isMC and trackKiller and killInTrackSlope and rndm>eff : 
#                if rndm>eff : 
                    # L1 hit got killed!  Since we already checked nHits==5, this track is dead
#                    print 'killing track with slope = ' +str(slp)
#                    continue
#            else : 
#                survivingFSP.append(fsp)


#        print "number of surviving particles = "+str(len(survivingFSP))
        # Loop over all tracks in the event
        goodtrk=[]
        gamList=[]
        eleList=[]
        posList=[]
#        for fsp_n in xrange(0, hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE)) :             
#            fsp = hps_event.getParticle(HpsParticle.FINAL_STATE_PARTICLE,fsp_n)
        for fsp in survivingFSP: 
            if fsp.getType() == 0 :  #might be good photon 
                if not checkClusterFiducialAndTiming(fsp,requireECalSuperFiducial) :  continue
                gamList.append(fsp)
            else : #maybe a good track? 
                if useGBL and  fsp.getType()<32  : continue
                if not useGBL and  fsp.getType()>31  : continue
                track=fsp.getTracks()[0]
                if track is None : continue #this shouldn't happen
                if requireECalMatch and not trkMatchAndFiducial(track.getParticle(),requireECalSuperFiducial) : continue
                if not trkMomentum(track,minPCut,beamCut):  continue
                if requireTrkChiSq and track.getChi2()>trkChi2: continue
                if myhist.checkIfShared(goodtrk,fsp): 
#                    print 'fromscratch::now goodtrk is '+str(len(goodtrk))+' tracks long'
#                    for trk in goodtrk: 
                    #                        print len(trk.getTracks()[0].getSvtHits())
                    continue
                nTrks+=1            # check to see if we already found this track
                if trackKiller and isMC and requireECalMatch: # use the ECAL cluster to do this!!! 
                    if killInMomentum : 
#                        p=pMag(fsp.getMomentum())
                        p=fsp.getEnergy()
                        bin=effMomData.FindBin(p)                    
                        tkEff=effMomData.GetBinContent(bin)
#                        print str(p)+ ' '+str(bin)+' '+str(tkEff)
                        if random.random()>tkEff and tkEff!=0.0  :  #high ratio of efficiencies, this hardly  kills...low, kills a lot
                            print "REJECTING THIS TRACK!!! "+str(p)
                            nKilled+=1
                            continue
#                    if killInClusterPosition:  
#                        clEle=fsp.getClusters()[0]
#                        clX=clEle.getPosition()[0]
#                        clY=clEle.getPosition()[1]
#                        if fsp.getCharge()<0 : 
#                            bin=effData.FindBin(clX,clY)
#                        else: 
#                            bin=effData.FindBin(-clX+42.55,clY) # flip sign +42.55mm for positron side (this isn't strictly correct)!!!
#                        tkEff=effData.Get0BinContent(bin)
#                        if random.random()>tkEff  and tkEff!=0.0:  
#                            print str(clX)+ ' '+str(clY)+' '+str(bin)+' '+str(tkEff)
#                            print "REJECTING THIS ELECTRON TRACK!!! "+str(clX)
#                            continue
                    

            #otherwise this is a new track
                goodtrk.append(fsp)


        if len(goodtrk) > nTrkMax: continue # too many tracks

        for fsp in goodtrk :
            if fsp.getCharge() < 0 : 
                eleList.append(fsp)
            else : 
                posList.append(fsp)
                
        if len(posList) > nPosMax: continue # too many positrons!

        # we found a good event...fill the new tree so that we can save for later
        if doSkim and (len(posList)>0 or len(gamList)>0) and len(eleList)>0:
            print "adding this event to the skim" 
            newtree.Fill()

#        print 'found '+str(len(goodtrk))+' tracks in this event'
#        print '\t\t\t   # electrons = ' +str(len(eleList))
#        print '\t\t\t   # positrons = ' +str(len(posList))
#        print '\t\t\t   # photons = ' +str(len(gamList))

#do analysis for e+e- pairs
        if doEpEm : 
            for pos in posList : 
                if (requireECalTrackTiming and not myhist.clusterTrackCoincidence(pos,cluTrkDeltaT,cluTrkOffset) ):  
                    continue                
                for ele in eleList: 
                    v0=V0Match(ele,pos,hps_event)
                    if (requireECalTrackTiming and not myhist.clusterTrackCoincidence(ele,cluTrkDeltaT,cluTrkOffset) ):  
                        continue
                    if  (requireECalTimingCoincidence and not myhist.simpleClusterCoincidence(ele,pos,cluDeltaT)) or pMag(pSum(ele.getMomentum(),pos.getMomentum()))<v0PzMin :
                        continue
                    if requireV0ChiSq: 
                        if v0 is not None and v0.getVertexFitChi2()>v0Chi2:
                            continue                            
                    if requireWABD0Cut and pos.getTracks()[0].getD0()>wabD0Cut: 
                        continue
                    if requireWABPtCut: 
                        ptEle=pT(ele.getMomentum())
                        ptPos=pT(pos.getMomentum())
                        asym=(ptEle-ptPos)/(ptEle+ptPos)
                        if asym>wabPtCut : 
                            continue

                    eleHitInL1=myhist.hasL1Hit(ele.getTracks()[0])
                    posHitInL1=myhist.hasL1Hit(pos.getTracks()[0])
                    eleHitInL2=myhist.hasLXHit(ele.getTracks()[0],2)
                    posHitInL2=myhist.hasLXHit(pos.getTracks()[0],2)
                    if isMC and trackKiller and killInTrackSlope and removedL1Hit[ele]:
                        eleHitInL1 = False
                        print 'Electron L1 hit to false due to slope inefficiency' 
                    if isMC and trackKiller and killInTrackSlope and removedL1Hit[pos]: 
                        posHitInL1 = False
                        print 'Positron L1 hit to false due to slope inefficiency' 
                    
                    eleWgt=1.0
                    posWgt=1.0
                    if weightTracks and isMC and requireECalMatch: 
                        clEle=ele.getClusters()[0]
                        clEcl=clEle.getEnergy()
                        clY=clEle.getPosition()[1]                
                        eleWgt=eff2DEleRatio.GetBinContent(eff2DEleRatio.FindBin(clEcl,clY))
                        clPos=pos.getClusters()[0]
                        clEcl=clPos.getEnergy()
                        clY=clPos.getPosition()[1]                
                        posWgt=eff2DPosRatio.GetBinContent(eff2DPosRatio.FindBin(clEcl,clY))
                    if doTB and ele.getMomentum()[1]*pos.getMomentum()[1] <0 : 
                        myhist.fillTwoBody(pos,ele,v0,'EpEm','TB',eleWgt*posWgt)
                        if eleHitInL1 and posHitInL1 :  
                            myhist.fillTwoBody(pos,ele,v0,'EpEmL1L1','TB',eleWgt*posWgt) 
                            if eleHitInL2 and posHitInL2 : 
                                myhist.fillTwoBody(pos,ele,v0,'EpEmL1L2L1L2','TB',eleWgt*posWgt) 
#                            if not eleHitInL2 and not posHitInL2:
#                                myhist.fillTwoBody(pos,ele,v0,'EpEmL1NoL2L1NoL2','TB',eleWgt*posWgt) 
#                            elif not eleHitInL2 : 
#                                myhist.fillTwoBody(pos,ele,v0,'EpEmL1NoL2L1L2','TB',eleWgt*posWgt) 
#                            elif not posHitInL2 : 
#                                myhist.fillTwoBody(pos,ele,v0,'EpEmL1L2L1NoL2','TB',eleWgt*posWgt) 
#                            else: 
#                                myhist.fillTwoBody(pos,ele,v0,'EpEmL1L2L1L2','TB',eleWgt*posWgt) 
                        elif eleHitInL1 : 
                            myhist.fillTwoBody(pos,ele,v0,'EpEmL2L1','TB',eleWgt*posWgt)
 #                           if not eleHitInL2 :
 #                               myhist.fillTwoBody(pos,ele,v0,'EpEmNoL1L2L1NoL2','TB',eleWgt*posWgt) 
 #                           else:
 #                               myhist.fillTwoBody(pos,ele,v0,'EpEmNoL1L2L1L2','TB',eleWgt*posWgt)                                 
                        elif posHitInL1 : 
                            myhist.fillTwoBody(pos,ele,v0,'EpEmL1L2','TB',eleWgt*posWgt)
 #                           if not posHitInL2 :
 #                               myhist.fillTwoBody(pos,ele,v0,'EpEmL1NoL2NoL1L2','TB') 
 #                           else:
 #                               myhist.fillTwoBody(pos,ele,v0,'EpEmL1L2NoL1L2','TB')                                 
                        else: 
                            myhist.fillTwoBody(pos,ele,v0,'EpEmL2L2','TB',eleWgt*posWgt)                
#do analysis for e-e- pairs
        if doEmEm : 
            for i in range(0,len(eleList)) : 
                ele1=eleList[i]
                if (requireECalTrackTiming and not myhist.clusterTrackCoincidence(ele1,cluTrkDeltaT,cluTrkOffset) ):  
                    continue
                for k in range(i+1,len(eleList)):
                    v0=None
                    ele2=eleList[k]
                    if (requireECalTrackTiming and not myhist.clusterTrackCoincidence(ele2,cluTrkDeltaT,cluTrkOffset) ):  
                        continue
                    if  (requireECalTimingCoincidence and not myhist.simpleClusterCoincidence(ele1,ele2,cluDeltaT)) or pMag(pSum(ele1.getMomentum(),ele2.getMomentum()))<v0PzMin :
                        continue                     
                    ele1HitInL1=myhist.hasL1Hit(ele1.getTracks()[0])
                    ele2HitInL1=myhist.hasL1Hit(ele2.getTracks()[0])
                    if doTB and ele1.getMomentum()[1]*ele2.getMomentum()[1] <0:
                        myhist.fillTwoBody(ele1,ele2,v0,'EmEm','TB')#potentially comes from WABs
                        if ele1HitInL1 and ele2HitInL1 :  
                            myhist.fillTwoBody(ele1,ele2,v0,'EmEmL1L1','TB') 
                        elif ele1HitInL1 : 
                            myhist.fillTwoBody(ele1,ele2,v0,'EmEmL2L1','TB')
                        elif ele2HitInL1 : 
                            myhist.fillTwoBody(ele1,ele2,v0,'EmEmL1L2','TB')
                        else: 
                            myhist.fillTwoBody(ele1,ele2,v0,'EmEmL2L2','TB')                    
#do analysis for e-gamma pairs 
        if doEmGam: 
            for ele in eleList : 
                if (requireECalTrackTiming and not myhist.clusterTrackCoincidence(ele,cluTrkDeltaT,cluTrkOffset) ):  
                    continue
                for gam in gamList: 
                    v0=None
                    gamY=gam.getClusters().First().getPosition()[1]
                    if  requireECalTimingCoincidence and not myhist.clusterCoincidence(ele,gam) :
                        continue
                    if requireWABCoplanarity and not myhist.cutCoplanarity(ele,gam,wabCoplanCut,wabCoplanMean): 
                        continue
                    if pMag(pSum(ele.getMomentum(),gam.getMomentum()))<v0PzMin: 
                        continue
                    eleHitInL1=myhist.hasL1Hit(ele.getTracks()[0])
                    eleHitInL2=myhist.hasLXHit(ele.getTracks()[0],2)
                    eleHitInL3=myhist.hasLXHit(ele.getTracks()[0],3)
                    if isMC and trackKiller and killInTrackSlope and removedL1Hit[ele]:  eleHitInL1 = False
                    eleWgt=1.0
                    if weightTracks and isMC and requireECalMatch: 
                        clEle=ele.getClusters()[0]
                        clEcl=clEle.getEnergy()
                        clY=clEle.getPosition()[1]                
                        eleWgt=eff2DEleRatio.GetBinContent(eff2DEleRatio.FindBin(clEcl,clY))
                    if doTB and ele.getMomentum()[1]*gamY<0 : #(these could be WABS!)
                        myhist.fillTwoBody(gam,ele,v0,'GamEm','TB',eleWgt)
                        if eleHitInL1:  
                            myhist.fillTwoBody(gam,ele,v0,'GamEmL1','TB',eleWgt) 
                            if not eleHitInL2 : 
                                myhist.fillTwoBody(gam,ele,v0,'GamEmL1NoL2','TB',eleWgt)
                            else:
                                myhist.fillTwoBody(gam,ele,v0,'GamEmL1L2','TB',eleWgt) 
                        else: 
                            myhist.fillTwoBody(gam,ele,v0,'GamEmL2','TB',eleWgt)  
                    elif  doTT and ele.getMomentum()[1] >0 : 
                        myhist.fillTwoBody(gam,ele,v0,'GamEm','TT',eleWgt)
                    elif  doTT and ele.getMomentum()[1] <0 : 
                        myhist.fillTwoBody(gam,ele,v0,'GamEm','BB',eleWgt)

#do analysis for e-gamma pairs 
        if doEpGam: 
            for pos in posList : 
                if (requireECalTrackTiming and not myhist.clusterTrackCoincidence(pos,cluTrkDeltaT,cluTrkOffset) ):  
                    continue
                for gam in gamList: 
                    v0=None
                    gamY=gam.getClusters().First().getPosition()[1]
                    if  requireECalTimingCoincidence and not myhist.clusterCoincidence(pos,gam) :
                        continue
                    if requireWABCoplanarity and not myhist.cutCoplanarity(pos,gam,wabCoplanCut,wabCoplanMean): 
                        continue
                    if pMag(pSum(pos.getMomentum(),gam.getMomentum()))<v0PzMin: 
                        continue
                    posHitInL1=myhist.hasL1Hit(pos.getTracks()[0])
                    posHitInL2=myhist.hasLXHit(pos.getTracks()[0],2)
                    posHitInL3=myhist.hasLXHit(pos.getTracks()[0],3)
                    posWgt=1.0
                    if weightTracks and isMC and requireECalMatch: 
                        clPos=pos.getClusters()[0]
                        clEcl=clPos.getEnergy()
                        clY=clPos.getPosition()[1]                
                        posWgt=eff2DPosRatio.GetBinContent(eff2DPosRatio.FindBin(clEcl,clY))
                    if doTB and pos.getMomentum()[1]*gamY<0 : #(these could be WABS!)
                        myhist.fillTwoBody(gam,pos,v0,'GamEp','TB',posWgt)
                        if posHitInL1:  
                            myhist.fillTwoBody(gam,pos,v0,'GamEpL1','TB',posWgt) 
                            if not posHitInL2 : 
                                myhist.fillTwoBody(gam,pos,v0,'GamEpL1NoL2','TB',posWgt)
                            else:
                                myhist.fillTwoBody(gam,pos,v0,'GamEpL1L2','TB',posWgt) 
                        else: 
                            myhist.fillTwoBody(gam,pos,v0,'GamEpL2','TB',posWgt)  
                    elif  doTT and pos.getMomentum()[1] >0 : 
                        myhist.fillTwoBody(gam,pos,v0,'GamEp','TT',posWgt)
                    elif  doTT and pos.getMomentum()[1] <0 : 
                        myhist.fillTwoBody(gam,pos,v0,'GamEp','BB',posWgt)


    myhist.saveHistograms(output_file)   
    if doSkim:
        newtree.Print();
        newtree.AutoSave();

    print "******************************************************************************************"
    if(nTrks>0): 
        print "Number of tracks killed = "+str(nKilled)+" out of "+str(nTrks)+" total = "+str(float(nKilled)/nTrks)
コード例 #23
0
def main():

    # Parse all command line arguments using the argparse module.
    parser = argparse.ArgumentParser(
        description='PyRoot analysis demostrating the us of a DST.')
    parser.add_argument("dst_file", help="ROOT DST file to process")
    parser.add_argument("-o", "--output", help="Name of output pdf file")
    parser.add_argument("-m", "--mc", help="is MonteCarlo")
    args = parser.parse_args()

    # If an output file name was not specified, set a default name and warn
    # the user
    if args.output:
        output_file = args.output
    else:
        output_file = "analysis_output.root"
        print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to "
        print output_file

    print "[ HPS ANALYSIS ]:  Output file is " + output_file
    isMC = False
    if args.mc:
        print "[ HPS ANALYSIS ]: Setting to run as MC"
        isMC = True

#################################
#       Event Selection
################################
#clean up event first
#### nominal selection
    nTrkMax = 10
    nTrkMin = 2
    nPosMax = 3
    ######  two tracks (e+/e-) exactly
    #    nTrkMax=2
    #    nTrkMin=2
    #    nPosMax=1
    ###### more than 1 electron
    #    nTrkMax=10
    #    nTrkMin=3
    #    nPosMax=1
    ###################
    #v0 cuts
    v0Chi2 = 10
    #ESum -- full region
    v0PzMax = 1.2
    v0PzMin = 0.55
    #ESum -- Radiative region
    #    v0PzMax=1.2
    #    v0PzMin=0.80

    v0PyMax = 0.2  #absolute value
    v0PxMax = 0.2  #absolute value
    v0VzMax = 25.0  # mm from target
    v0VyMax = 1.0  # mm from target
    v0VxMax = 2.0  # mm from target
    #  track quality cuts
    trkChi2 = 10
    beamCut = 0.8
    minPCut = 0.05
    trkPyMax = 0.2
    trkPxMax = 0.2
    #    slopeCut=0.03
    slopeCut = 0.0
    trkDeltaT = 4  #ns
    cluDeltaT = 2  #ns
    cluTrkDeltaT = 4  #ns
    ##############
    #  ESum slices; upper limits
    nSlicesESum = 5
    esumMin = 0.55
    esumMax = 1.2
    sliceSizeESum = 0.1  #100MeV starting at esumMin
    ##############
    trackKiller = False
    tkThreshold = 0.5  #GeV, below this start killing tracks
    tkThreshEff = 1.0
    tkLowPoint = 0.20
    tkLowPointEff = 0.40
    #    tkSlope=2.6
    #    tkIntercept=-0.04
    #calculate tkSlope and Intercept
    tkSlope = (tkThreshEff - tkLowPointEff) / (tkThreshold - tkLowPoint)
    tkIntercept = tkThreshEff - tkSlope * tkThreshold

    ##############
    requireECalMatch = True
    requireECalFiducial = False
    requireECalSuperFiducial = True
    useGBL = True

    # Open the ROOT file
    #    root_file = ROOT.TFile(str(args.dst_file))
    # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all
    # other colletions
    #    tree = root_file.Get("HPS_Event")
    #use a TChain
    print "[ HPS ANALYSIS ]: Reading in root chain from " + args.dst_file
    tree = ROOT.TChain("HPS_Event")
    tree.Add(str(args.dst_file) + "*")
    # Create an HpsEvent object in order to read the TClonesArray
    # collections
    hps_event = HpsEvent()

    b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event))

    #--- Analysis ---#
    #----------------#

    #counters
    nEvents = 0
    nPassBasicCuts = 0
    nPassV0Cuts = 0
    nPassTrkCuts = 0
    nPassNCand = 0
    nPassECalMatch = 0

    # Loop over all events in the file
    for entry in xrange(0, tree.GetEntries()):
        # Print the event number every 500 events
        if (entry + 1) % 10000 == 0: print "Event " + str(entry + 1)
        tree.GetEntry(entry)
        #        print str(hps_event.isPulserTrigger())+ ' ' +str(hps_event.isSingle1Trigger())
        if hps_event.isPulserTrigger():
            print 'found pulser event'

#        if not hps_event.isPair1Trigger() and not isMC: continue
#        if not hps_event.isPulserTrigger() and not isMC: continue
        nEvents += 1
        # Loop over all tracks in the event
        npositrons = 0
        n_tracks = 0
        for track_n in xrange(0, hps_event.getNumberOfTracks()):
            track = hps_event.getTrack(track_n)
            if track is None:
                continue
#            if useGBL and track.getParticle().getType()<32  : continue
#            if not useGBL and track.getParticle().getType()>31  : continue
            if trkMatchAndFiducial(track.getParticle()) and trkMomentum(
                    track, minPCut, beamCut
            ):  # count only matched tracks in defined fiducial region
                n_tracks += 1
                if track.getCharge() > 0:
                    npositrons += 1
                    myhist.rawposMom.Fill(pMag(track.getMomentum()))
                else:
                    myhist.raweleMom.Fill(pMag(track.getMomentum()))

        print "nTracks = " + str(n_tracks) + "; nPositrons = " + str(
            npositrons)
        #        if n_tracks/2.0>nTrkMax : continue   #do this very dumb thing (divide by 2 to un-double count GBL tracks)
        #        if n_tracks/2.0<2:  continue
        myhist.nTrk.Fill(n_tracks)
        myhist.nPos.Fill(npositrons)
        myhist.nEle.Fill(n_tracks - npositrons)
        myhist.nClust.Fill(hps_event.getNumberOfEcalClusters())

        if n_tracks > nTrkMax: continue
        if n_tracks < nTrkMin: continue
        if npositrons < 1 or npositrons > nPosMax: continue
        nPassBasicCuts += 1

    myhist.saveHistograms(output_file)

    print "******************************************************************************************"
コード例 #24
0
    def preprocess(self, dst_file):

        chain = r.TChain("HPS_Event")
        chain.Add(dst_file)
        tree = chain.GetTree()

        from ROOT import HpsEvent

        hps_event = HpsEvent()
        branch = chain.SetBranchAddress("Event", r.AddressOf(hps_event))

        # Add variables to the ntuple
        ft_maker = ft.FlatTupleMaker(self.output_file_name)
        ft_maker.add_variable("cluster_0_energy")
        ft_maker.add_variable("cluster_1_energy")
        ft_maker.add_variable("cluster_0_x")
        ft_maker.add_variable("cluster_1_x")
        ft_maker.add_variable("cluster_0_y")
        ft_maker.add_variable("cluster_1_y")
        ft_maker.add_variable("track_0_p")
        ft_maker.add_variable("track_0_px")
        ft_maker.add_variable("track_0_py")
        ft_maker.add_variable("track_0_pz")
        ft_maker.add_variable("track_0_theta")
        ft_maker.add_variable("track_0_phi0")
        ft_maker.add_variable("track_0_omega")
        ft_maker.add_variable("track_0_d0")
        ft_maker.add_variable("track_0_z0")
        ft_maker.add_variable("track_1_p")
        ft_maker.add_variable("track_1_px")
        ft_maker.add_variable("track_1_py")
        ft_maker.add_variable("track_1_pz")
        ft_maker.add_variable("track_1_theta")
        ft_maker.add_variable("track_1_phi0")
        ft_maker.add_variable("track_1_omega")
        ft_maker.add_variable("track_1_d0")
        ft_maker.add_variable("track_1_z0")
        ft_maker.add_variable("track_pair_p_sum")

        matcher = tcm.TrackClusterMatcher()

        for entry in xrange(0, chain.GetEntries()):

            if (entry + 1) % 1000 == 0: print "Event " + str(entry + 1)

            chain.GetEntry(entry)

            # Loop through all clusters in the event and find a 'good' pair.
            # For now, a 'good' pair is defined as two clusters whose cluster
            # time difference is less than 1.6 ns and greater than -1.6 ns
            cluster_pair = au.get_good_cluster_pair(hps_event)

            if len(cluster_pair) != 2: continue

            matcher.find_all_matches(hps_event)
            tracks = [
                matcher.get_track(cluster_pair[0]),
                matcher.get_track(cluster_pair[1])
            ]

            if (tracks[0] is None) or (tracks[1] is None): continue

            ft_maker.set_variable_value("cluster_0_energy",
                                        cluster_pair[0].getEnergy())
            ft_maker.set_variable_value("cluster_1_energy",
                                        cluster_pair[1].getEnergy())
            ft_maker.set_variable_value("cluster_0_x",
                                        cluster_pair[0].getPosition()[0])
            ft_maker.set_variable_value("cluster_1_x",
                                        cluster_pair[1].getPosition()[0])
            ft_maker.set_variable_value("cluster_0_y",
                                        cluster_pair[0].getPosition()[1])
            ft_maker.set_variable_value("cluster_1_y",
                                        cluster_pair[1].getPosition()[1])
            ft_maker.set_variable_value(
                "track_0_p",
                np.linalg.norm(np.asarray(tracks[0].getMomentum())))
            ft_maker.set_variable_value("track_0_px",
                                        tracks[0].getMomentum()[0])
            ft_maker.set_variable_value("track_0_py",
                                        tracks[0].getMomentum()[1])
            ft_maker.set_variable_value("track_0_pz",
                                        tracks[0].getMomentum()[2])
            track_0_theta = math.fabs(math.pi / 2 -
                                      math.acos(te.get_cos_theta(tracks[0])))
            ft_maker.set_variable_value("track_0_theta", track_0_theta)
            ft_maker.set_variable_value("track_0_phi0", tracks[0].getPhi0())
            ft_maker.set_variable_value("track_0_omega", tracks[0].getOmega())
            ft_maker.set_variable_value("track_0_d0", tracks[0].getD0())
            ft_maker.set_variable_value("track_0_z0", tracks[0].getZ0())
            ft_maker.set_variable_value(
                "track_1_p",
                np.linalg.norm(np.asarray(tracks[1].getMomentum())))
            ft_maker.set_variable_value("track_1_px",
                                        tracks[1].getMomentum()[0])
            ft_maker.set_variable_value("track_1_py",
                                        tracks[1].getMomentum()[1])
            ft_maker.set_variable_value("track_1_pz",
                                        tracks[1].getMomentum()[2])
            track_1_theta = math.fabs(math.pi / 2 -
                                      math.acos(te.get_cos_theta(tracks[1])))
            ft_maker.set_variable_value("track_1_theta", track_1_theta)
            ft_maker.set_variable_value("track_1_phi0", tracks[1].getPhi0())
            ft_maker.set_variable_value("track_1_omega", tracks[1].getOmega())
            ft_maker.set_variable_value("track_1_d0", tracks[1].getD0())
            ft_maker.set_variable_value("track_1_z0", tracks[1].getZ0())
            p_sum = np.linalg.norm(np.asarray(
                tracks[0].getMomentum())) + np.linalg.norm(
                    np.asarray(tracks[1].getMomentum()))
            ft_maker.set_variable_value("track_pair_p_sum", p_sum)

            ft_maker.fill()

        ft_maker.close()