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
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 "******************************************************************************************"
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
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
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 "******************************************************************************************"
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
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)
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)
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)
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 + ")")
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