def getClone(tfile, root_dir, name): th1 = getHist(tfile, root_dir, name) cloned = th1.Clone() cloned.SetDirectory(0) cloned.Sumw2() ROOT.SetOwnership(cloned, 1) return cloned
def getTemplate(infile, config, section): # so far we need only one template per sample, we do not differentiate plus/minus etc. if config.has_option(section, 'template_hist'): if config.has_option(section, 'template_file'): # we have to open some external file extrafile = ROOT.TFile( config.get(section, 'input_folder') + '/' + config.get(section, 'template_file'), 'READONLY') if extrafile.IsZombie(): raise RuntimeError, 'No file %s in %s' % \ (config.get(section,'template_file'), config.get(section,'input_folder')) template = getClone(extrafile, '', '', config.get(section, 'template_hist')) template.SetDirectory(infile.GetDirectory('')) extrafile.Close() else: # read the template from input_file template = getClone(infile, '', '', config.get(section, 'template_hist')) template.Scale(1.0 / template.Integral()) return template else: return None
def dumpOutput(filename, outputPrefix, usePreQCD = False, combineWJets = False): # TODO fix this inputFile = filename outputFile = "%s_split.root" % inputFile templateFile = inputFile + "_templates.root" metaFile = inputFile + "_meta.json" temp = TFile(templateFile) output = TFile(outputFile, "RECREATE") output.cd() meta = json.loads(open(metaFile).read()) dataHist = temp.Get('newdata;1') mcHists = {'Data':dataHist} for key in temp.GetListOfKeys(): keyString = key.GetName() if keyString.endswith('_updated'): mcHists[keyString.split('_')[0]] = temp.Get(keyString) reverseIndex = dict((v, k) for (k, v) in meta['groupIndexMap'].items()) lowerEdgeIdx = 0 for (binName, binIndex) in meta['groupIndexMap'].items(): newBins = meta['numBinsVec'][binIndex] lowerBin = meta['lowerEdgeBinVec'][binIndex] upperBin = meta['upperEdgeBinVec'][binIndex] binVec = [float(x) for x in meta['binLowerEdges'][lowerBin - 1:upperBin]] binArray = array.array('f', binVec) for mc in mcHists: newName = "%s%s" % (mc, binName) # TODO propagate xmin/xmax from the fit newHist = ROOT.TH1F(newName, newName, newBins - 1, binArray) for histIndex in range(newBins): oldContent = mcHists[mc].GetBinContent(lowerBin + histIndex) oldError = mcHists[mc].GetBinError(lowerBin + histIndex) newHist.SetBinContent(histIndex, oldContent) newHist.SetBinError(histIndex, oldError) newHist.Write() lowerEdgeIdx += newBins output.Write() temp.Close() temp = output discList = [] for key in temp.GetListOfKeys(): keyString = key.GetName() keySplit = keyString.split('_') currDisc = "_".join(keySplit[2:]) if currDisc == 'svm': continue if not currDisc in discList: discList.append(currDisc) discList.sort() # split the histograms out, so plot them now defaultColors = {'SingleTop' : ROOT.kCyan, 'SingleTT' : ROOT.kCyan - 3, 'SingleTS' : ROOT.kCyan - 2, 'SingleTTW' : ROOT.kCyan - 1, 'SingleTbarT' : ROOT.kCyan + 1, 'SingleTbarS' : ROOT.kCyan + 2, 'SingleTbarTW' : ROOT.kCyan + 3, 'WJets' : ROOT.kGreen, 'Wqq' : ROOT.kGreen + 1, 'Wcx' : ROOT.kGreen + 2, 'Wbx' : ROOT.kGreen + 3, 'WZ' : ROOT.kYellow +3, 'WW' : ROOT.kYellow -6, 'DiBoson' : ROOT.kOrange, 'EWK' : ROOT.kOrange, 'Top' : ROOT.kRed, 'Zinv' : ROOT.kBlue-3, 'ZJets' : ROOT.kBlue, 'ZZ' : ROOT.kPink -6, 'Stop450' : ROOT.kYellow, 'QCDpre' : ROOT.kMagenta, 'QCD' : ROOT.kMagenta} xlabelsPerDisc = {'lepPt' : 'GeV/c', 'MET' : 'GeV', 'hT' : 'GeV', 'std' : 'GeV/c', 'stdt' : 'GeV/c', 'sumEt' : 'GeV', 'wrp' : 'rad', 'wMT' : 'GeV/c^{2}', 'hT' : 'GeV', } sampleToCategory = { 'WZ' : 'Diboson', 'WW' : 'Diboson', 'ZZ' : 'Diboson', 'SingleTT' : 'SingleTop', 'SingleTS' : 'SingleTop', 'SingleTTW' : 'SingleTop', 'SingleTbarT' : 'SingleTop', 'SingleTbarS' : 'SingleTop', 'SingleTbarTW' : 'SingleTop', 'Zinv' : 'ZJets', 'ZJets' : 'ZJets' } def iterateJetBottomTau(): return itertools.product((0,1,2,3,4,5),(0,1,2),(0,1)) integralLookup = [] inputKeyLookup = [] for key in temp.GetListOfKeys(): keyString = key.GetName() if not keyString in inputKeyLookup: inputKeyLookup.append(keyString) integralLookup.append((keyString, temp.Get(keyString).Integral())) htmlTarget = "%s.html" % outputPrefix relBase = os.path.dirname(htmlTarget) relSuffix = os.path.basename(outputPrefix) with open(htmlTarget,'w+') as idx: idx.write("<html><head><title>Fit Results</title></head><body><h1>SHyFT Fit Results</h1>") sampleCounts = {} # FIXME: This should really really be automagic for njet, nbjet, ntau in iterateJetBottomTau(): if (nbjet + ntau) > njet: continue if not njet in sampleCounts: sampleCounts[njet] = {} if not nbjet in sampleCounts[njet]: sampleCounts[njet][nbjet] = {} if not ntau in sampleCounts[njet][nbjet]: sampleCounts[njet][nbjet][ntau] = {} plot = StackedPlot() # FIXME should have serialization/deserialization fixed by now targetSuffix = "_%sj_%sb_%st" % (njet, nbjet, ntau) shouldSave = False sizeListing = [] def customCompare(val): return -1*val[1] foundBin = False for keyString,_ in sorted(integralLookup, key=customCompare, reverse=True): sampleString = keyString.split('_')[0] if keyString.endswith(targetSuffix): foundBin = True hist = temp.Get(keyString) if hist.Integral() != 0: shouldSave = True color = defaultColors.get(sampleString, None) currSample = keyString.split('_')[0] plot.addQuantity(currSample, temp.Get(keyString), color = color) tableCategory = sampleToCategory.get(sampleString, sampleString) sampleCounts[njet][nbjet][ntau][tableCategory] = \ sampleCounts[njet][nbjet][ntau].get(tableCategory, 0) + \ temp.Get(keyString).Integral() disc = keyString.split('_')[1] if not foundBin: print "Got nothing for %s? (probably okay)" % targetSuffix continue if disc in xlabelsPerDisc: plot.xAxisTitle = xlabelsPerDisc[disc] plot.title = "%s (%sj, %sb, %st)" % (disc, njet, nbjet, ntau) if shouldSave: target = os.path.join(relBase,'%sfit%s' % (relSuffix, targetSuffix)) plot.draw(target + ".svg") plot.draw(target + ".pdf") plot.draw(target + ".png") idx.write('<img src="%sfit%s.svg" alt="%s" />' % (relSuffix, targetSuffix, plot.title)) idx.write('<table><tr><th>Bin</th><th>Data</th><th>Total Pred</th><th>SF</th>') headers = {} totalPred = {} sampleSum = {} allPredictions = 0 for njet in sampleCounts: totalPred[njet] = {} for nbjet in sampleCounts[njet]: totalPred[njet][nbjet] = {} for ntau in sampleCounts[njet][nbjet]: totalPred[njet][nbjet][ntau] = 0 for sample in sampleCounts[njet][nbjet][ntau]: sampleSum[sample] = sampleSum.get(sample, 0) + sampleCounts[njet][nbjet][ntau][sample] if sample != 'Data': headers[sample] = 1 totalPred[njet][nbjet][ntau] += sampleCounts[njet][nbjet][ntau][sample] allPredictions += sampleCounts[njet][nbjet][ntau][sample] headerList = sorted(headers.keys()) for header in headerList: idx.write('<th>%s</th>' % header) idx.write('</tr>\n') for njet in sorted(sampleCounts): for nbjet in sorted(sampleCounts[njet]): for ntau in sorted(sampleCounts[njet][nbjet]): if sampleCounts[njet][nbjet][ntau] == {}: continue if totalPred[njet][nbjet][ntau] > 0: frac = (sampleCounts[njet][nbjet][ntau]['Data']/totalPred[njet][nbjet][ntau]) else: frac = 0.0 idx.write('<tr><th>%sj_%sb_%st</th><td>%.2e</td><td>%.2e</td><td>%.2f</td>' %\ (njet, nbjet, ntau, sampleCounts[njet][nbjet][ntau]['Data'], totalPred[njet][nbjet][ntau], frac)) for sample in headerList: idx.write('<td>%.2e</td>' % sampleCounts[njet][nbjet][ntau].get(sample, 0)) idx.write('</tr>\n') if allPredictions > 0.0: idx.write('<tr><th>Total</th><th>%.2e</th><th>%.2e</th><th>%.2f</th>' % (sampleSum['Data'], allPredictions, sampleSum['Data']/allPredictions)) else: idx.write('<tr><th>Total</th><th>%.2e</th><th>%.2e</th><th>INF</th>' % (sampleSum['Data'], allPredictions)) for header in headerList: idx.write('<th>%.2e</th>' % sampleSum[header]) idx.write('</tr></table>') idx.write("</body></html>")
def draw(self, filename, nostack=False, dropPattern=""): """ Draw the current image """ if not nostack: drawOpt = "HIST" else: drawOpt = "nostack,HIST" myCanvas = ROOT.TCanvas("c1", "stacked hists", 10, 10, 900, 700) oldPad = ROOT.gPad myCanvas.cd() hs = ROOT.THStack('hs', self.title) r = 0 if nostack: for shape in self.getFilteredShapes(dropPattern): integral = shape['shape'].Integral() shape['oldshape'] = shape['shape'] shape['shape'] = shape['shape'].Clone() if integral: shape['shape'].Scale(1 / integral) for shape in self.getFilteredShapes(dropPattern): shape['shape'].SetOption('') if self.isData(shape): continue # 2 is red. Go figure. if 'color' in shape: if nostack: shape['shape'].SetLineColor(shape['color']) shape['shape'].SetFillColor(ROOT.kWhite) shape['shape'].SetLineWidth(4) else: shape['shape'].SetLineColor(ROOT.kBlack) shape['shape'].SetFillColor(shape['color']) #shape['shape'].SetLineWidth(1.0) else: shape['shape'].SetFillColor(2 + r) if nostack: shape['shape'].SetLineColor(2 + r) else: shape['shape'].SetLineColor(ROOT.kBlack) r += 1 hs.Add(shape['shape']) #if not nostack: # hs.Draw(drawOpt) #else: # first = True # for shape in self.shapes: # if first: # shape['shape'].Draw() # else: # shape['shape'].Draw('same') hs.SetDrawOption(drawOpt) hs.Draw(drawOpt) hs.SetDrawOption(drawOpt) for shape in self.getFilteredShapes(dropPattern): if self.isData(shape): if shape['shape'].GetMaximum() > hs.GetMaximum(): hs.SetMaximum(shape['shape'].GetMaximum()) pass if not nostack: shape['shape'].Draw('esame') else: shape['shape'].Draw('HIST,same') if self.xAxisTitle: axis = hs.GetXaxis() axis.SetTitle(self.xAxisTitle) myCanvas.RedrawAxis() leg = ROOT.TLegend(0.65, 0.7, 0.99, 0.99) #leg = ROOT.TLegend() for shape in reversed([x for x in self.getFilteredShapes(dropPattern)]): if self.isData(shape): #shape['shape'].SetLineColor(ROOT.kBlack) if not nostack: leg.AddEntry(shape['shape'], shape['name'], "pl") else: leg.AddEntry(shape['shape'], shape['name'], "l") for shape in reversed([x for x in self.getFilteredShapes(dropPattern)]): if not self.isData(shape): #shape['shape'].SetLineColor(ROOT.kBlack) if not nostack: leg.AddEntry(shape['shape'], shape['name'], 'f') else: leg.AddEntry(shape['shape'], shape['name'], 'l') leg.Draw() myCanvas.SaveAs(filename) myCanvas.Close() ROOT.gPad = oldPad if nostack: for shape in self.getFilteredShapes(dropPattern): shape['shape'] = shape['oldshape']
reverseIndex = dict((v, k) for (k, v) in meta['groupIndexMap'].items()) lowerEdgeIdx = 0 for (binName, binIndex) in meta['groupIndexMap'].items(): newBins = meta['numBinsVec'][binIndex] lowerBin = meta['lowerEdgeBinVec'][binIndex] - 1 upperBin = meta['upperEdgeBinVec'][binIndex] - 1 binVec = [float(x) for x in meta['binLowerEdges'][lowerBin:upperBin + 1]] binVec.append( float(binVec[-1] + meta['binLowerEdges'][lowerBin + 1] - meta['binLowerEdges'][lowerBin])) binArray = array.array('f', binVec) for mc in mcHists: newName = "%s%s" % (mc, binName) # TODO propagate xmin/xmax from the fit newHist = ROOT.TH1F(newName, newName, newBins, binArray) for histIndex in range(newBins): # Stupid zero-based indices oldBin = lowerBin + histIndex + 1 newBin = histIndex + 1 oldContent = mcHists[mc].GetBinContent(oldBin) oldError = mcHists[mc].GetBinError(oldBin) newHist.SetBinContent(newBin, oldContent) newHist.SetBinError(newBin, oldError) newHist.Write() lowerEdgeIdx += newBins output.Write() temp.Close() temp = output discList = [] for key in temp.GetListOfKeys():
from array import array import math from SHyFT.ROOTWrap import ROOT import sys xvals = [] yvals = [] with open(sys.argv[1]) as f: for line in f: line = line.rstrip('\n') splitted = line.split(' ') if (len(splitted) == 2): xvals.append(float(splitted[0])) yvals.append(float(splitted[1])) c = ROOT.TCanvas("c", "Log likelihood scan", 200, 10, 700, 500) g = ROOT.TGraph(len(xvals), array('d', xvals), array('d', yvals)) f = ROOT.TF1("fun", "[2] * x * x + [1] * x + [0]") h = ROOT.TF1("fun", "[2] * (x - [0])^2 / ([1] ^ 2)") g.Fit(f) g.Draw("AL") g.Fit(h) g.Draw("A") c.Update() c.Print("fitpara.pdf") print len(xvals) print len(yvals) peak = f.GetMinimum(xvals[0], xvals[-1], 1E-10, 100000) maxx = f.GetMinimumX(xvals[0], xvals[-1], 1E-10, 100000) print "f(%.4f) = %.4f" % (maxx, peak) derivative2 = f.Derivative2(maxx)
# strong reference the TFile to keep ROOT from reaping it fileRefs = [] for arg in args: argSplit = arg.split(':') if len(argSplit) == 1: fileGlob = arg plotRegex = '.*' elif len(argSplit) == 2: fileGlob = argSplit[0] plotRegex = argSplit[1] fileList = glob.glob(fileGlob) plotRegex = re.compile(plotRegex) for oneFile in fileList: if debug: print "Examining %s" % oneFile rootFile = ROOT.TFile(oneFile, 'READONLY') ROOT.gDirectory.Cd("") fileRefs.append(rootFile) for key in rootFile.GetListOfKeys(): keyString = key.GetName() if plotRegex.search(keyString) != None: if debug: print " Examining %s" % keyString plotsToPrint.append((keyString, rootFile.Get(keyString))) totalSum = 0.0 maxKeyLen = 0 for key, _ in plotsToPrint: maxKeyLen = max(maxKeyLen, len(key))
def getHist(tfile, root_dir, name): readname = '' if root_dir != '': readname = root_dir + '/' readname += name #print 'getting ',readname th1 = tfile.Get(readname) try: if th1.IsZombie(): print 'no such histogram!' return None except ReferenceError, e: print "Failed to read %s" % readname return None ROOT.SetOwnership(th1, 1) return th1 # get a clone of the histogram, considering its location def getClone(tfile, root_dir, name): th1 = getHist(tfile, root_dir, name) cloned = th1.Clone() cloned.SetDirectory(0) cloned.Sumw2() ROOT.SetOwnership(cloned, 1) return cloned # substitute the leading part of the name (Top, WJets, etc) by user-defined prefix # will help to deal with multiple single top templates, for example