startpars = totalPdf.getParameters(fitter.ws.set('obsSet')) fitter.ws.defineSet("params", startpars) fitter.ws.saveSnapshot("initPars", startpars) if opts.toy: #generate toy dataset print 'Generated parameters' fitter.ws.set('params').Print('v') fitter.ws.saveSnapshot("genPars", startpars) data = totalPdf.generate(fitter.ws.set('obsSet'), RooFit.Name('data_obs'), RooFit.Extended()) if fitter.pars.binData: data = RooDataHist('data_obs', 'data_obs', fitter.ws.set('obsSet'), data) data.Print('v') getattr(fitter.ws, 'import')(data) else: data = fitter.loadData() fitter.setMultijetYield() data.Print() startpars.IsA().Destructor(startpars) print 'Time elapsed: %.1f sec' % timer.RealTime() print 'CPU time used: %.1f sec' % timer.CpuTime() print 'starting fitting routine' timer.Continue() #fitter.ws.var('top_nrm').setConstant() fr = None fr = fitter.fit()
class MjjFit: def __init__(self, mass_range=[0., 2000.]): self.data_histogram_ = None self.data_roohistogram_ = None self.luminosity_ = 0. self.collision_energy_ = 8000. self.signal_histograms_ = {} self.signal_roohistograms_ = {} self.signal_names_ = [] # Fit storage self.simple_fit_ = None self.mjj_ = RooRealVar('mjj','mjj',float(mass_range[0]),float(mass_range[1])) self.workspace_ = None def add_data(self, data_histogram): print "[MjFit.add_data] INFO : Adding data histogram" # Add a data histogram self.data_histogram_ = data_histogram.Clone() self.data_histogram_.SetDirectory(0) self.data_roohistogram_ = RooDataHist('data_roohistogram','data_roohistogram',RooArgList(self.mjj_),self.data_histogram_) self.data_roohistogram_.Print() def add_signal(self, signal_name, signal_histogram): print "[MjjFit.add_signal] INFO : Adding signal histogram " + signal_name # Add a signal histogram. # Scale to sigma=1 (in whatever units the data luminosity is given in), so the 'r' parameter corresponds to the limit on the cross section. if self.luminosity_ == 0: print "[MjjFit.add_signal] ERROR : Please set luminosity first (MjjFit.set_luminosity(###))." sys.exit(1) self.signal_names_.append(signal_name) self.signal_histograms_[signal_name] = signal_histogram.Clone() self.signal_histograms_[signal_name].SetDirectory(0) self.signal_histograms_[signal_name].Scale(1. * self.luminosity_ / self.signal_histograms_[signal_name].Integral()) self.signal_roohistograms_[signal_name] = RooDataHist(signal_histogram.GetName() + "_rdh", signal_histogram.GetName() + "_rdh", RooArgList(self.mjj_), signal_histograms[signal_name]) self.signal_roohistograms_[signal_name].Print() def simple_fit_B(self, fit_range=None): # Run a simple ROOT fit (B only) # - No S+B equivalent. This is done with RooFit. if fit_range: fit_min = fit_range[0] fit_max = fit_range[1] else: fit_min = data_histogram.GetXaxis().GetXmin() fit_max = data_histogram.GetXaxis().GetXmax() fit = TF1(data_histogram.GetName() + "_fit_B", BackgroundFit, fit_min, fit_max, 4) fit.SetParameter(0, 2.e-4) fit.SetParameter(1, 3) fit.SetParameter(2, 10) fit.SetParameter(3, 1) fit.SetParLimits(0, 1.e-6, 1.e2) fit.SetParLimits(1, -25., 25.) fit.SetParLimits(2, -25., 25.) fit.SetParLimits(3, -5., 5.) data_histogram.Fit(fit, "ER0I") fit_ratio = self.make_fit_pull_histogram(data_histogram, fit) print "Fit chi2/ndf = " + str(fit.GetChisquare()) + " / " + str(fit.GetNDF()) + " = " + str(fit.GetChisquare() / fit.GetNDF()) self.simple_fit_ = {"fit":fit, "fit_ratio":fit_ratio} return self.simple_fit_ def make_fit_pull_histogram(self, hist, fit): #print "Fit xmin = " + str(fit.GetXmin()) hist_ratio = hist.Clone() hist_ratio.SetName(hist.GetName() + "_fit_ratio") for bin in xrange(1, hist_ratio.GetNbinsX() + 1): xmin = hist_ratio.GetXaxis().GetBinLowEdge(bin) xmax = hist_ratio.GetXaxis().GetBinUpEdge(bin) if xmax < fit.GetXmin() or xmin > fit.GetXmax(): hist_ratio.SetBinContent(bin, 0.) hist_ratio.SetBinError(bin, 0.) continue fit_integral = fit.Integral(xmin, xmax) if hist.GetBinError(bin) > 0: hist_ratio.SetBinContent(bin, (hist.GetBinContent(bin) * hist.GetBinWidth(bin) - fit_integral) / (hist.GetBinError(bin) * hist.GetBinWidth(bin))) hist_ratio.SetBinError(bin, 0.) else: hist_ratio.SetBinContent(bin, 0.) hist_ratio.SetBinError(bin, 0.) return hist_ratio def fit(self, save_to, signal_name=None, fix_p3=False, fit_range=[300., 1200.], fit_strategy=1): # Run a RooFit fit # Create background PDF p1 = RooRealVar('p1','p1',args.p1,0.,100.) p2 = RooRealVar('p2','p2',args.p2,0.,60.) p3 = RooRealVar('p3','p3',args.p3,-10.,10.) if args.fix_p3: p3.setConstant() background_pdf = RooGenericPdf('background_pdf','(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))'%(self.collision_energy,self.collision_energy,self.collision_energy),RooArgList(self.mjj_,p1,p2,p3)) background_pdf.Print() data_integral = data_histogram.Integral(data_histogram.GetXaxis().FindBin(float(fit_range[0])),data_histogram.GetXaxis().FindBin(float(fit_range[1]))) background_norm = RooRealVar('background_norm','background_norm',data_integral,0.,1e+08) background_norm.Print() # Create signal PDF and fit model if signal_name: signal_pdf = RooHistPdf('signal_pdf', 'signal_pdf', RooArgSet(self.mjj_), self.signal_roohistograms_[signal_name]) signal_pdf.Print() signal_norm = RooRealVar('signal_norm','signal_norm',0,-1e+05,1e+05) signal_norm.Print() model = RooAddPdf("model","s+b",RooArgList(background_pdf,signal_pdf),RooArgList(background_norm,signal_norm)) else: model = RooAddPdf("model","b",RooArgList(background_pdf),RooArgList(background_norm)) # Run fit res = model.fitTo(data_, RooFit.Save(kTRUE), RooFit.Strategy(fit_strategy)) # Save to workspace self.workspace_ = RooWorkspace('w','workspace') #getattr(w,'import')(background,ROOT.RooCmdArg()) getattr(self.workspace_,'import')(background_pdf,RooFit.Rename("background")) getattr(self.workspace_,'import')(background_norm,ROOT.RooCmdArg()) getattr(self.workspace_,'import')(self.data_roohistogram_,RooFit.Rename("data_obs")) getattr(self.workspace_, 'import')(model, RooFit.Rename("model")) if signal_name: getattr(self.workspace_,'import')(signal_roohistogram,RooFit.Rename("signal")) getattr(self.workspace_,'import')(signal_pdf,RooFit.Rename("signal_pdf")) getattr(self.workspace_,'import')(signal_norm,ROOT.RooCmdArg()) self.workspace_.Print() self.workspace_.writeToFile(save_to) if signal_name: roofit_results[signal_name] = save_to else: roofit_results["background"] = save_to # fitted_signal_shapes = list of fitted S(+B) shapes to plot. # expected_signal_shapes = list of S shapes to plot, scaled to cross sections taken from configuration file def plot(self, save_tag, fitted_signal_shapes=None, expected_signal_shapes=None, log=False, x_range=None): c = TCanvas("c_" + save_tag, "c_" + save_tag, 800, 1600) l = TLegend(0.55, 0.6, 0.88, 0.88) l.SetFillColor(0) l.SetBorderSize(0) top = TPad("top", "top", 0., 0.5, 1., 1.) top.SetBottomMargin(0.03) top.Draw() if log: top.SetLogy() c.cd() bottom = TPad("bottom", "bottom", 0., 0., 1., 0.5) bottom.SetTopMargin(0.02) bottom.SetBottomMargin(0.2) bottom.Draw() ROOT.SetOwnership(c, False) ROOT.SetOwnership(top, False) ROOT.SetOwnership(bottom, False) top.cd() # Frame from background fit if not roofit_results.has_key("background"): print "[MjjFit.plot] ERROR : Please run background-only fit before plotting (e.g. MjjFit.plot(\"bkgd_file.root\"))" f_background = TFile(roofit_results["background"], "READ") w_background = f_background.Get("w") data_rdh = w_background.data("data_obs") if x_range: x_min = x_range[0] x_max = x_range[1] else: x_min = self.mjj_.GetMin() x_max = self.mjj_.GetMax() frame_top = self.mjj_.frame(x_min, x_max) frame_top.GetYaxis().SetTitle("Events / " + str(int(data_histogram.GetXaxis().GetBinWidth(1))) + " GeV") frame_top.GetXaxis().SetTitleSize(0) frame_top.GetXaxis().SetLabelSize(0) #if log: # frame_top.SetMaximum(y_max * 10.) # frame_top.SetMinimum(y_min / 100.) #else: # frame_top.SetMaximum(y_max * 1.3) # frame_top.SetMinimum(0.) frame_top.Draw() data_rdh.plotOn(frame_top, RooFit.Name("Data")) l.AddEntry(frame_top.findObject("Data"), "Data", "pl") background_pdf = w_background.pdf("background") background_pdf.plotOn(frame_top, RooFit.Name("Background Fit"), RooFit.LineColor(seaborn.GetColorRoot("default", 0)), RooFit.LineStyle(1), RooFit.LineWidth(2)) style_counter = 1 if fitted_signal_shapes: for signal_name in fitted_signal_shapes: # Load from workspace if not roofit_results.has_key(signal_name): print "[MjjFit.plot] ERROR : Signal name " + signal_name + " does not exist in roofit_results. Did you run the fit first?" sys.exit(1) f_in = TFile(roofit_results[signal_name], "READ") w = f_in.Get("workspace") fit_pdf = w.pdf("model") fit_pdf_name = "Fit (" + signal_name + ")" fit_pdf.SetName(fit_pdf_name) fit_pdf.plotOn(frame_top, RooFit.Name(fit_pdf_name), RooFit.LineColor(seaborn.GetColorRoot("default", style_counter)), RooFit.LineStyle(1), RooFit.LineWidth(2)) l.AddEntry(frame_top.findObject(signal_name), signal_name, "l") style_counter += 1 f_in.Close() if expected_signal_shapes: for signal_name in expected_signal_shapes: self.signal_roohistograms_[signal_name].plotOn(frame_top, RooFit.Name(signal_name), RooFit.Rescale(cross_section * self.luminosity_ / self.signal_roohistograms_[signal_name].sum()), RooFit.LineColor(seaborn.GetColorRoot("pastel", style_counter)), RooFit.LineStyle(2), RooFit.LineWidth(2)) l.AddEntry(frame_top.findObject(signal_name), signal_name, "l") style_counter += 1 frame_top.Draw() l.Draw() # Pull histogram c.cd() bottom.cd() pull_histogram = frame_top.pullHist("Data", "Background Fit") frame_bottom = self.mjj_.frame(x_min, x_max) pull_histogram.plotOn(frame_bottom, RooFit.Name(fit_pdf_name)) frame_bottom.GetXaxis().SetTitle("m_{jj} [GeV]") frame_bottom.GetYaxis().SetTitle("#frac{Data - Fit}{#sigma(Fit)}") frame_bottom.Draw() c.cd() c.SaveAs("/uscms/home/dryu/Dijets/data/EightTeeEeVeeBee/Results/figures/c_" + save_tag + ".pdf")
bkg = RooGenericPdf('bkg', '1/(exp(pow(@0/@1,@2))+1)', RooArgList(x, x0, p)) fsig = RooRealVar('fsig', 'fsig', 0.5, 0., 1.) signal = RooAddPdf('signal', 'signal', sig, bkg, fsig) # ----------------------------------------- # fit signal canSname = 'can_Mjj' + str(mass) canS = TCanvas(canSname, canSname, 900, 600) gPad.SetLogy() roohistSig = RooDataHist('roohist', 'roohist', RooArgList(x), hSig) roohistSig.Print() res_sig = signal.fitTo(roohistSig, RooFit.Save(ROOT.kTRUE)) res_sig.Print() frame = x.frame() roohistSig.plotOn(frame, RooFit.Binning(166)) signal.plotOn(frame) signal.plotOn(frame, RooFit.Components('bkg'), RooFit.LineColor(ROOT.kRed), RooFit.LineWidth(2), RooFit.LineStyle(ROOT.kDashed)) #frame.GetXaxis().SetRangeUser(1118,6099) frame.GetXaxis().SetRangeUser(minX_mass, maxX_mass) frame.GetXaxis().SetTitle('m_{jj} (GeV)') frame.Draw() parsSig = signal.getParameters(roohistSig) parsSig.setAttribAll('Constant', True)
print ">> Creating datacard and workspace for %s resonance with m = %i GeV..." % ( args.signal_model, int(mass)) # get signal shape hSig = signal_shapes_file.Get("h_" + args.signal_model + "_" + str(int(mass))) # normalize signal shape to the expected event yield (works even if input shapes are not normalized to unity) hSig.Scale( signalCrossSection * lumi / hSig.Integral() ) # divide by a number that provides roughly an r value of 1-10 print "[debug] hSig.Integral() = " + str(hSig.Integral()) print "[debug] hSig.GetMean() = " + str(hSig.GetMean()) print "[debug] hSig.GetRMS() = " + str(hSig.GetRMS()) rooSigHist = RooDataHist('rooSigHist', 'rooSigHist', RooArgList(mjj), hSig) rooSigHist.Print() signal = RooHistPdf('signal', 'signal', RooArgSet(mjj), rooSigHist) signal.Print() signal_norm = RooRealVar('signal_norm', 'signal_norm', 0, -1e+05, 1e+05) if args.fitBonly: signal_norm.setConstant() signal_norm.Print() p1 = RooRealVar('p1', 'p1', args.p1, 0., 100.) p2 = RooRealVar('p2', 'p2', args.p2, 0., 60.) p3 = RooRealVar('p3', 'p3', args.p3, -10., 10.) if args.fixP3: p3.setConstant() background = RooGenericPdf( 'background', '(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))' %
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 shapeCards( process, isData, datahistosFile, histosFile, signalHistosFile, signalSample, hist, signalMass, minMass, maxMass, jesValue, jerValue, lumiUnc, outputName ): """function to run Roofit and save workspace for RooStats""" warnings.filterwarnings( action='ignore', category=RuntimeWarning, message='.*class stack<RooAbsArg\*,deque<RooAbsArg\*> >' ) hSignal = signalHistosFile.Get(hist+'_'+signalSample) hSignal.Rebin(10) htmpSignal = hSignal.Clone() #htmpSignal.Scale(100) signalXS = search(dictXS, 'RPVStopStopToJets_UDD312_M-'+str(signalMass) ) #hSignal.Scale( lumi*signalXS / hSignal.Integral()) massAve = RooRealVar( 'massAve', 'massAve', minMass, maxMass ) rooSigHist = RooDataHist( 'rooSigHist', 'rooSigHist', RooArgList(massAve), hSignal ) rooSigHist.Print() signal = RooHistPdf('signal','signal',RooArgSet(massAve),rooSigHist) signal.Print() signal_norm = RooRealVar('signal_norm','signal_norm',0,-1e+04,1e+04) #if args.fitBonly: signal_norm.setConstant() signal_norm.Print() hBkg = datahistosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj') #hBkg = histosFile.Get(hist+'_QCDPtAll_BCD') bkgAcc = round(hBkg.Integral( hBkg.GetXaxis().FindBin( minMass ), hBkg.GetXaxis().FindBin( maxMass ))) #hBkg.Scale(1/hBkg.Integral()) hPseudo = hBkg.Clone() hPseudo.Reset() #background_norm = RooRealVar('background_norm','background_norm',bkgAcc,0.,1e+07) background_norm = RooRealVar('background_norm','background_norm',1.,0.,1e+07) background_norm.Print() if 'template' in process: rooBkgHist = RooDataHist( 'rooBkgHist', 'rooBkgHist', RooArgList(massAve), hBkg ) rooBkgHist.Print() background = RooHistPdf('background','background',RooArgSet(massAve),rooBkgHist) background.Print() else: p1 = RooRealVar('p1','p1', 1 ,0.,100.) p2 = RooRealVar('p2','p2', 1 ,0.,60.) p3 = RooRealVar('p3','p3', 1 , -10.,10.) background = RooGenericPdf('background','(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))'%(1300,1300,1300),RooArgList(massAve,p1,p2,p3)) background.Print() ### S+B model if not isData: newNumEvents = random.randint( bkgAcc-round(TMath.Sqrt(bkgAcc)), bkgAcc+round(TMath.Sqrt(bkgAcc)) ) print 'Events in MC:', bkgAcc, ', in PseudoExperiment:', newNumEvents hPseudo.FillRandom( hBkg, newNumEvents ) #hPseudo.Scale(1/hPseudo.Integral()) #hData = histosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_ABCDProj') hData = datahistosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj') #hData = histosFile.Get(hist+'_QCDPtAll_A') #hData.Add(htmpSignal) #hData.Scale(1/hData.Integral()) rooDataHist = RooDataHist('rooDatahist','rooDatahist',RooArgList(massAve), hData if isData else hPseudo ) rooDataHist.Print() #model = RooAddPdf("model","s+b",RooArgList(background,signal),RooArgList(background_norm,signal_norm)) #res = model.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(0)) #res.Print() ############# JES and JER uncertainties hSigSyst = {} hSigSystDataHist = {} signalCDF = TGraph(hSignal.GetNbinsX()+1) # JES and JER uncertainties if args.jesUnc or args.jerUnc: signalCDF.SetPoint(0,0.,0.) integral = 0. for i in range(1, hSignal.GetNbinsX()+1): x = hSignal.GetXaxis().GetBinLowEdge(i+1) integral = integral + hSignal.GetBinContent(i) signalCDF.SetPoint(i,x,integral) if args.jesUnc: print ' |---> Adding JES' hSigSyst['JESUp'] = hSignal.Clone() hSigSyst['JESDown'] = hSignal.Clone() if args.jerUnc: print ' |---> Adding JER' hSigSyst['JERUp'] = hSignal.Clone() hSigSyst['JERDown'] = hSignal.Clone() # reset signal histograms for key in hSigSyst: hSigSyst[key].Reset() hSigSyst[key].SetName(hSigSyst[key].GetName() + '_' + key) # produce JES signal shapes if args.jesUnc: for q in range(1, hSignal.GetNbinsX()+1): xLow = hSignal.GetXaxis().GetBinLowEdge(q) xUp = hSignal.GetXaxis().GetBinLowEdge(q+1) jes = 1. - jesValue xLowPrime = jes*xLow xUpPrime = jes*xUp hSigSyst['JESUp'].SetBinContent(q, signalCDF.Eval(xUpPrime) - signalCDF.Eval(xLowPrime)) jes = 1. + jesValue xLowPrime = jes*xLow xUpPrime = jes*xUp hSigSyst['JESDown'].SetBinContent(q, signalCDF.Eval(xUpPrime) - signalCDF.Eval(xLowPrime)) hSigSystDataHist['JESUp'] = RooDataHist('hSignalJESUp','hSignalJESUp',RooArgList(massAve),hSigSyst['JESUp']) hSigSystDataHist['JESDown'] = RooDataHist('hSignalJESDown','hSignalJESDown',RooArgList(massAve),hSigSyst['JESDown']) # produce JER signal shapes if args.jerUnc: for i in range(1, hSignal.GetNbinsX()+1): xLow = hSignal.GetXaxis().GetBinLowEdge(i) xUp = hSignal.GetXaxis().GetBinLowEdge(i+1) jer = 1. - jerValue xLowPrime = jer*(xLow-float(signalMass))+float(signalMass) xUpPrime = jer*(xUp-float(signalMass))+float(signalMass) hSigSyst['JERUp'].SetBinContent(i, signalCDF.Eval(xUpPrime) - signalCDF.Eval(xLowPrime)) jer = 1. + jerValue xLowPrime = jer*(xLow-float(signalMass))+float(signalMass) xUpPrime = jer*(xUp-float(signalMass))+float(signalMass) hSigSyst['JERDown'].SetBinContent(i, signalCDF.Eval(xUpPrime) - signalCDF.Eval(xLowPrime)) hSigSystDataHist['JERUp'] = RooDataHist('hSignalJERUp','hSignalJERUp',RooArgList(massAve),hSigSyst['JERUp']) hSigSystDataHist['JERDown'] = RooDataHist('hSignalJERDown','hSignalJERDown',RooArgList(massAve),hSigSyst['JERDown']) myWS = RooWorkspace("myWS") getattr(myWS,'import')(rooSigHist,RooFit.Rename("signal")) getattr(myWS,'import')(rooBkgHist,RooFit.Rename("background")) #getattr(myWS,'import')(signal_norm) getattr(myWS,'import')(background_norm) if args.jesUnc: getattr(myWS,'import')(hSigSystDataHist['JESUp'],RooFit.Rename("signal__JESUp")) getattr(myWS,'import')(hSigSystDataHist['JESDown'],RooFit.Rename("signal__JESDown")) if args.jerUnc: getattr(myWS,'import')(hSigSystDataHist['JERUp'],RooFit.Rename("signal__JERUp")) getattr(myWS,'import')(hSigSystDataHist['JERDown'],RooFit.Rename("signal__JERDown")) getattr(myWS,'import')(rooDataHist,RooFit.Rename("data_obs")) myWS.Print() outputRootFile = currentDir+'/Rootfiles/workspace_'+outputName+'.root' myWS.writeToFile(outputRootFile, True) print ' |----> Workspace created in root file:\n', outputRootFile # ----------------------------------------- # write a datacard dataCardName = currentDir+'/Datacards/datacard_'+outputName+'.txt' datacard = open( dataCardName ,'w') datacard.write('imax 1\n') datacard.write('jmax 1\n') datacard.write('kmax *\n') datacard.write('---------------\n') if args.jesUnc or args.jerUnc or args.lumiUnc or args.normUnc or args.unc: datacard.write('shapes * * '+outputRootFile+' myWS:$PROCESS myWS:$PROCESS__$SYSTEMATIC\n') else: datacard.write("shapes * * "+outputRootFile+" myWS:$PROCESS \n") datacard.write('---------------\n') datacard.write('bin 1\n') datacard.write('observation -1\n') datacard.write('------------------------------\n') datacard.write('bin 1 1\n') datacard.write('process signal background\n') datacard.write('process 0 1\n') datacard.write('rate -1 -1\n') datacard.write('------------------------------\n') if args.lumiUnc: datacard.write('lumi lnN %f -\n'%(lumiUnc)) if args.jesUnc: datacard.write('JES shape 1 -\n') if args.jerUnc: datacard.write('JER shape 1 -\n') #flat parameters --- flat prior if args.normUnc: datacard.write('background_norm flatParam\n') #datacard.write('p1 flatParam\n') datacard.close() print ' |----> Datacard created:\n', dataCardName
def shapeCards(datahistosFile, histosFile, signalFile, signalSample, hist, signalMass, minMass, maxMass, outputName, outputFileTheta): """function to run Roofit and save workspace for RooStats""" warnings.filterwarnings( action='ignore', category=RuntimeWarning, message='.*class stack<RooAbsArg\*,deque<RooAbsArg\*> >') ############################################################# DATA #hData = histosFile.Get('massAve_deltaEtaDijet_QCDPtAll') #hData = datahistosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj') dataFile = TFile(datahistosFile) hData = dataFile.Get(hist + '_DATA') hData.Rebin(args.reBin) #hData = hData.Rebin( len( boostedMassAveBins )-1, hData.GetName(), boostedMassAveBins ) #hData = histosFile.Get(hist+'_QCDPtAll_A') #hData.Add(htmpSignal) #hData.Scale(1/hData.Integral()) #maxMass = boostedMassAveBins[ hData.FindLastBinAbove( 0, 1) ] #minMass = signalMass-30 #maxMass = signalMass+30 massAve = RooRealVar('massAve', 'massAve', minMass, maxMass) #massAveData = RooRealVar( 'massAveData', 'massAveData', minMass, maxMass ) rooDataHist = RooDataHist('rooDatahist', 'rooDatahist', RooArgList(massAve), hData) # if isData else hPseudo ) rooDataHist.Print() ############################################################################################ ####################### Signal if 'gaus' in args.job: hSignal = TH1F('massAve_RPVStop', 'massAve_RPVStop', maxMass / args.reBin, minMass, maxMass) for q in range(hSignal.GetNbinsX() + 1): gausEval = signalFile.Eval(hSignal.GetXaxis().GetBinCenter(q)) hSignal.SetBinContent(q, gausEval) #meanSig = RooRealVar( 'meanSig', 'mean of signal', sigGaus.GetParameter( 1 ) ) #sigmaSig = RooRealVar( 'sigmaSig', 'sigma of signal', sigGaus.GetParameter( 2 ) ) #signalPdf = RooGaussian( 'signal', 'signal', massAve, meanSig, sigmaSig ) #signalPdf.Print() else: signalHistosFile = TFile(signalFile) hSignal = signalHistosFile.Get(hist + '_' + signalSample) hSignal.Rebin(args.reBin) hSignal.Scale(twoProngSF) signalXS = search(dictXS, 'RPVStopStopToJets_UDD312_M-' + str(signalMass)) rooSigHist = RooDataHist('rooSigHist', 'rooSigHist', RooArgList(massAve), hSignal) sigAcc = rooSigHist.sumEntries( ) #round(hSignal.Integral( hSignal.GetXaxis().FindBin( minMass ), hSignal.GetXaxis().FindBin( maxMass )), 2) rooSigHist.Print() #signal = RooHistPdf('signal','signal',RooArgSet(massAve),rooSigHist) #signal.Print() #signal_norm = RooRealVar('signal_norm','signal_norm',0,-1e+04,1e+04) #if args.fitBonly: signal_norm.setConstant() #signal_norm.Print() ##################################################################### hSigSyst = signalUnc(hSignal, signalMass) hSigSystDataHist = {} if args.jesUnc: hSigSystDataHist['JESUp'] = RooDataHist('hSignalJESUp', 'hSignalJESUp', RooArgList(massAve), hSigSyst['JESUp']) hSigSystDataHist['JESDown'] = RooDataHist('hSignalJESDown', 'hSignalJESDown', RooArgList(massAve), hSigSyst['JESDown']) if args.jerUnc: hSigSystDataHist['JERUp'] = RooDataHist('hSignalJERUp', 'hSignalJERUp', RooArgList(massAve), hSigSyst['JERUp']) hSigSystDataHist['JERDown'] = RooDataHist('hSignalJERDown', 'hSignalJERDown', RooArgList(massAve), hSigSyst['JERDown']) #################################### Background if args.altBkg: newBkgHistoFile = datahistosFile.replace('DATA', 'DATA_ABCDBkg') newBkgFile = TFile(newBkgHistoFile) htmpBkg = newBkgFile.Get( 'massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj') if (htmpBkg.GetBinWidth(1) != args.reBin): print '|----- Bin size in DATA_C histogram is different than rest.' sys.exit(0) else: htmpBkg = dataFile.Get( 'massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj') htmpBkg.Rebin(args.reBin) #hBkg = histosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_QCDPtAll_ABCDProj') #hBkg = histosFile.Get(hist+'_QCDPtAll_BCD') #htmpBkg = htmpBkg.Rebin( len( boostedMassAveBins )-1, htmpBkg.GetName(), boostedMassAveBins ) hBkg = htmpBkg.Clone() hBkg.Reset() for ibin in range(htmpBkg.GetNbinsX()): binCont = htmpBkg.GetBinContent(ibin) binErr = htmpBkg.GetBinError(ibin) if binCont == 0: hBkg.SetBinContent(ibin, 0) hBkg.SetBinError(ibin, 1.8) else: hBkg.SetBinContent(ibin, binCont) hBkg.SetBinError(ibin, binErr) #hBkg.Scale(1/hBkg.Integral()) hPseudo = createPseudoExperiment(hBkg, bkgAcc) ###### Adding statistical uncertanty hBkgStatUncUp = hBkg.Clone() hBkgStatUncUp.Reset() hBkgStatUncDown = hBkg.Clone() hBkgStatUncDown.Reset() for i in range(hBkg.GetNbinsX() + 1): cont = hBkg.GetBinContent(i) contErr = hBkg.GetBinError(i) hBkgStatUncUp.SetBinContent(i, cont + (1 * contErr)) hBkgStatUncDown.SetBinContent(i, cont - (1 * contErr)) hBkgStatUncUpDataHist = RooDataHist('hBkgStatUncUp', 'hBkgStatUncUp', RooArgList(massAve), hBkgStatUncUp) hBkgStatUncDownDataHist = RooDataHist('hBkgStatUncDown', 'hBkgStatUncDown', RooArgList(massAve), hBkgStatUncDown) if 'template' in args.job: rooBkgHist = RooDataHist('rooBkgHist', 'rooBkgHist', RooArgList(massAve), hBkg) bkgAcc = rooBkgHist.sumEntries() rooBkgHist.Print() background = RooHistPdf('background', 'background', RooArgSet(massAve), rooBkgHist) background.Print() else: massAveBkg = RooRealVar('massAveBkg', 'massAveBkg', minMass, maxMass) p1 = RooRealVar('p1', 'p1', 1, 0., 100.) p2 = RooRealVar('p2', 'p2', 1, 0., 60.) p3 = RooRealVar('p3', 'p3', 1, -10., 10.) bkgAcc = round( hBkg.Integral(hBkg.GetXaxis().FindBin(minMass), hBkg.GetXaxis().FindBin(maxMass)), 2) background = RooGenericPdf( 'background', '(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))' % (1300, 1300, 1300), RooArgList(massAveBkg, p1, p2, p3)) background.Print() hBkgSyst = {} hBkgSystDataHist = {} if args.bkgUnc: print ' |---> Adding bkg unc' hBkgSyst['BkgUncUp'] = hBkg.Clone() hBkgSyst['BkgUncDown'] = hBkg.Clone() for key in hBkgSyst: hBkgSyst[key].Reset() hBkgSyst[key].SetName(hBkgSyst[key].GetName() + '_' + key) for q in range(0, hBkg.GetNbinsX()): binCont = hBkg.GetBinContent(q) bkgUncUp = 1. + (args.bkgUncValue / 100.) hBkgSyst['BkgUncUp'].SetBinContent(q, binCont * bkgUncUp) bkgUncDown = 1. - (args.bkgUncValue / 100.) hBkgSyst['BkgUncDown'].SetBinContent(q, binCont * bkgUncDown) hBkgSystDataHist['BkgUncUp'] = RooDataHist('hBkgBkgUncUp', 'hBkgBkgUncUp', RooArgList(massAve), hBkgSyst['BkgUncUp']) hBkgSystDataHist['BkgUncDown'] = RooDataHist('hBkgBkgUncDown', 'hBkgBkgUncDown', RooArgList(massAve), hBkgSyst['BkgUncDown']) ############################################################################################ #model = RooAddPdf("model","s+b",RooArgList(background,signal),RooArgList(background_norm,signal_norm)) #res = model.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(0)) #res.Print() ############################ Create Workspace myWS = RooWorkspace("myWS") getattr(myWS, 'import')(rooBkgHist, RooFit.Rename("background")) #getattr(myWS,'import')(background,RooFit.Rename("background")) #getattr(myWS,'import')(signal_norm) #getattr(myWS,'import')(background_norm) ''' if 'gaus' in args.job: getattr(myWS,'import')(signalPdf,RooFit.Rename("signal")) if args.jesUnc: getattr(myWS,'import')(signalPdfJESUp,RooFit.Rename("signal__JESUp")) getattr(myWS,'import')(signalPdfJESDown,RooFit.Rename("signal__JESDown")) else: ''' getattr(myWS, 'import')(rooSigHist, RooFit.Rename("signal")) if args.jesUnc: getattr(myWS, 'import')(hSigSystDataHist['JESUp'], RooFit.Rename("signal__JESUp")) getattr(myWS, 'import')(hSigSystDataHist['JESDown'], RooFit.Rename("signal__JESDown")) if args.jerUnc: getattr(myWS, 'import')(hSigSystDataHist['JERUp'], RooFit.Rename("signal__JERUp")) getattr(myWS, 'import')(hSigSystDataHist['JERDown'], RooFit.Rename("signal__JERDown")) if args.bkgUnc: getattr(myWS, 'import')(hBkgSystDataHist['BkgUncUp'], RooFit.Rename("background__BkgUncUp")) getattr(myWS, 'import')(hBkgSystDataHist['BkgUncDown'], RooFit.Rename("background__BkgUncDown")) getattr(myWS, 'import')(hBkgStatUncUpDataHist, RooFit.Rename("background__BkgStatUncUp")) getattr(myWS, 'import')(hBkgStatUncDownDataHist, RooFit.Rename("background__BkgStatUncDown")) getattr(myWS, 'import')(rooDataHist, RooFit.Rename("data_obs")) myWS.Print() outputRootFile = currentDir + '/Rootfiles/workspace_' + outputName + '.root' myWS.writeToFile(outputRootFile, True) print ' |----> Workspace created in root file:\n', outputRootFile ''' c1 = TCanvas('c1', 'c1', 10, 10, 750, 500 ) # c1.SetLogy() xframe = myWS.var("massAve").frame() signalPdf.plotOn( xframe ) xframe.Draw() c1.SaveAs('test.png') del c1 ''' ############################################################################################ ######################### write a datacard dataCardName = currentDir + '/Datacards/datacard_' + outputName + '.txt' datacard = open(dataCardName, 'w') datacard.write('imax 1\n') datacard.write('jmax 1\n') datacard.write('kmax *\n') datacard.write('---------------\n') if args.jesUnc or args.jerUnc or args.lumiUnc or args.bkgUnc or args.unc: datacard.write('shapes * * ' + outputRootFile + ' myWS:$PROCESS myWS:$PROCESS__$SYSTEMATIC\n') else: datacard.write("shapes * * " + outputRootFile + " myWS:$PROCESS \n") datacard.write('---------------\n') datacard.write('bin ' + signalSample + '\n') datacard.write('observation -1\n') datacard.write('------------------------------\n') datacard.write('bin ' + signalSample + ' ' + signalSample + '\n') datacard.write('process signal background\n') datacard.write('process 0 1\n') #datacard.write('rate -1 -1\n') datacard.write('rate ' + str(sigAcc) + ' ' + str(bkgAcc) + '\n') datacard.write('------------------------------\n') if args.lumiUnc: datacard.write('lumi lnN %f -\n' % (lumiValue)) if args.puUnc: datacard.write('pu lnN %f -\n' % (puValue)) if args.jesUnc: datacard.write('JES shape 1 -\n') if args.jerUnc: datacard.write('JER shape 1 -\n') #flat parameters --- flat prior #if args.bkgUnc: datacard.write('BkgUnc shape - '+str( round( 1/ (args.bkgUncValue/34.1), 2 ) )+'\n') if args.bkgUnc: datacard.write('BkgUnc shape - 1 \n') #NcombineUnc = ( 1 / TMath.Sqrt( args.bkgUncValue / 100. ) ) - 1 #datacard.write('background_norm gmN '+str(int(round(NcombineUnc)))+' - '+str( round(bkgAcc/NcombineUnc,2) )+'\n') #datacard.write('p1 flatParam\n') datacard.write('BkgStatUnc shape - 1 \n') datacard.close() print ' |----> Datacard created:\n', dataCardName ############################################################################################ ########## Theta if args.theta: print ' |----> Creating Theta file\n', outputFileTheta outFile = TFile(outputFileTheta, 'update') tmpName = 'rpvstopjj' + str(signalMass) hSignal.SetName('massAve__' + tmpName) hSignal.Write() hSigSyst['JESDown'].SetName('massAve__' + tmpName + '__jes__down') hSigSyst['JESDown'].Write() hSigSyst['JESUp'].SetName('massAve__' + tmpName + '__jes__up') hSigSyst['JESUp'].Write() hSigSyst['JERDown'].SetName('massAve__' + tmpName + '__jer__down') hSigSyst['JERDown'].Write() hSigSyst['JERUp'].SetName('massAve__' + tmpName + '__jer__up') hSigSyst['JERUp'].Write() if (signalMass == 100): #or (signalMass == 170): hBkg.SetName('massAve__background') hBkg.Write() hBkgSyst['BkgUncDown'].SetName('massAve__background__unc__down') hBkgSyst['BkgUncDown'].Write() hBkgSyst['BkgUncUp'].SetName('massAve__background__unc__up') hBkgSyst['BkgUncUp'].Write() hData.SetName('massAve__DATA') hData.Write() outFile.Close()
def expectedPlcLimit(obs_, poi_, model, ws, ntoys=30, CL=0.95, binData=False): # obs : observable variable or RooArgSet of observables # poi : parameter of interest or RooArgSet of parameters # model : RooAbsPdf of model to consider including any constraints # the parameters should have the values corresponding to the # background-only hypothesis which will be used to estimate the # expected limit. # ntoys : number of toy datsets to generate to get expected limit # CL : confidence level for interval # returns a dictionary containing the expected limits and their 1 sigma # errors for the first/only parameter in poi_ and a list of the results # from the individual toys. from math import sqrt obs = RooArgSet(obs_) obs.setName('observables') mPars = model.getParameters(obs) genPars = mPars.snapshot() print "parameters for generating toy datasets" genPars.Print("v") limits = [] upperLimits = TH1F("upperLimits_%s" % poi_.GetName(), "", 100, poi_.getMin(), poi_.getMax()) lowerLimits = TH1F("lowerLimits_%s" % poi_.GetName(), "", 100, poi_.getMin(), poi_.getMax()) probs = array('d', [0.022, 0.16, 0.5, 0.84, 0.978]) upperQs = array('d', [0.] * len(probs)) lowerQs = array('d', [0.] * len(probs)) for i in range(0, ntoys): print 'generate limit of toy %i of %i' % (i + 1, ntoys) mPars.assignFast(genPars) toyData = model.generate(obs, RooFit.Extended()) if binData: toyData = RooDataHist('data_obs_%i' % i, 'data_obs_%i' % i, obs, toyData) toyData.SetName('data_obs_%i' % i) toyData.Print() limits.append(plcLimit(obs_, poi_, model, ws, toyData, CL)) #print limits[-1] if limits[-1][poi_.GetName()]['ok'] and \ ((poi_.getMax()-limits[-1][poi_.GetName()]['upper']) > 0.001*poi_.getMax()): upperLimits.Fill(limits[-1][poi_.GetName()]['upper']) if limits[-1][poi_.GetName()]['ok'] and \ ((limits[-1][poi_.GetName()]['lower']-poi_.getMin()) > 0.001*abs(poi_.getMin())): lowerLimits.Fill(limits[-1][poi_.GetName()]['lower']) toyData.IsA().Destructor(toyData) upperLimits.GetQuantiles(len(probs), upperQs, probs) # upperLimits.Print() print 'expected upper limit quantiles using %i toys: [' % ( upperLimits.GetEntries()), for q in upperQs: print '%0.4f' % q, print ']' lowerLimits.GetQuantiles(len(probs), lowerQs, probs) # lowerLimits.Print() print 'expected lower limit quantiles using %i toys: [' % ( lowerLimits.GetEntries()), for q in lowerQs: print '%0.4f' % q, print ']' expLimits = { 'upper': upperQs[2], 'upperErr': sqrt( (upperQs[2] - upperQs[1]) * (upperQs[3] - upperQs[2])), 'lower': lowerQs[2], 'lowerErr': sqrt( (lowerQs[2] - lowerQs[1]) * (lowerQs[3] - lowerQs[2])), 'ntoys': upperLimits.GetEntries(), 'upperQuantiles': upperQs, 'lowerQuantiles': lowerQs, 'quantiles': probs } return (expLimits, limits)
dspihist = dspi_data.fillHistogram(dspihist, RooArgList(time)) dskhist = dsk_data.fillHistogram(dskhist, RooArgList(time)) ratiohist.Divide(dskhist, dspihist) # relative normalisation fintegral = ratio.createIntegral(RooArgSet(time), 'fullrange').getVal() hintegral = ratiohist.Integral('width') # has weights, use width norm = fintegral / hintegral print '=' * 5, ' Integrals ', '=' * 5 print 'Function integral / histogram integral = %g / %g = %g' % ( fintegral, hintegral, norm) ratiohist.Scale(norm) # make dataset from histogram ratiodset = RooDataHist('ratiodset', '', RooArgList(time), ratiohist) ratiodset.Print('v') ## Plot tframe = time.frame(RooFit.Title('Time acceptance ratio')) paramset = RooArgSet(rturnon, roffset, rbeta) ratio.plotOn(tframe, RooFit.VisualizeError(fitresult, paramset, 1, False)) ratio.plotOn(tframe) ratiodset.plotOn(tframe, RooFit.MarkerStyle(kFullDotMedium)) tframe.Draw() # Print if doPrint: print 'Plotting to file: plots/DsK_ratio_%s.{png,pdf}' % timestamp gPad.Print('plots/DsK_ratio_%s.png' % timestamp)
PDF = RooGenericPdf('PDF', '%s ? 0 : %s' % (acc_cond, expr), RooArgList(time, turnon, offset)) elif accfn == 'erf': acc_cond = '(@1<0.0002)' expr = '(0.5*(TMath::Erf((@1-@2)/@0)+1))' PDF = RooGenericPdf('PDF', '%s ? 0 : %s' % (acc_cond, expr), RooArgList(turnon, time, offset)) else: print 'Unknown acceptance type. Aborting' assert(False) # Dataset to fit to datahist = RooDataHist('datahist', 'Dataset from a histogram', RooArgList(time), RooFit.Import(timehist2, False)) # Debug datahist.Print('v') # Fit PDF.fitTo(datahist, RooFit.SumW2Error(True), RooFit.NumCPU(1), RooFit.Range(epsilon, 0.005), RooFit.Optimize(False), RooFit.Verbose(True), RooFit.Strategy(2)) # Plot tframe1 = time.frame(RooFit.Name('ptime'), RooFit.Title('Lifetime acceptance fitted to %s' % accfn)) datahist.plotOn(tframe1, RooFit.MarkerStyle(kFullTriangleUp)) PDF.plotOn(tframe1, RooFit.LineColor(kGreen)) # canvas2 = TCanvas('canvas2', 'Acceptance', 800, 600) tframe1.Draw() canvas1.Print(fname)