def write(self, setup): #Rescaling to efficiency normalisation = 1/self.histogram.GetBinContent(1) #Rescaling everything to have rates self.histogram.Scale(normalisation) efficiencyPlot = TGraphErrors(self.histogram) efficiencyPlot.SetName(self.cfg_ana.plot_name+"_errors") efficiencyPlot.SetTitle(self.cfg_ana.plot_title) for index in xrange(0, len(efficiencyPlot.GetX())): efficiencyPlot.SetPointError(index, efficiencyPlot.GetEX()[index], sqrt(efficiencyPlot.GetY()[index] * normalisation) ) c1 = TCanvas ("canvas_" + self.cfg_ana.plot_name, self.cfg_ana.plot_title, 600, 600) c1.SetGridx() c1.SetGridy() efficiencyPlot.Draw("AP") c1.Update() c1.Write() c1.Print(self.cfg_ana.plot_name + ".svg", "svg") efficiencyPlot.Write()
def _convert_tgrapherrors(root_obj: TGraphErrors) -> dict: """ Take the values from a TGraphErrors and add them to a series of arrays Parameters ---------- root_obj : TGraphError ROOT TGraphError Returns ------- dict Dictionary with x, y, xerr, yerr points """ xm, ym, x_errm, y_errm = (root_obj.GetX(), root_obj.GetY(), root_obj.GetEX(), root_obj.GetEY()) x, y, x_err, y_err = [], [], [], [] for n in range(0, root_obj.GetN()): x.append(xm[n]) y.append(ym[n]) x_err.append(x_errm[n]) y_err.append(y_errm[n]) return {'x': np.array(x), 'y': np.array(y), 'xerr': np.array(x_err), 'yerr': np.array(y_err)}
def testIthr(): lines = get_lines('DAC_scan_ithr_0x40to0xf0.dat') gr1 = TGraphErrors() gr2 = TGraphErrors() fUnit = 1000. / 0.7 yUnit = 'e^{-}' for line in lines: if len(line) == 0: continue if line[0] in ['#', '\n']: continue fs = line.rstrip().split() ix = int(fs[0]) gr1.SetPoint(ix, float(fs[1]), float(fs[2]) * fUnit) gr1.SetPointError(ix, 0, float(fs[3]) * fUnit) gr2.SetPoint(ix, float(fs[1]), float(fs[4]) * fUnit) gr2.SetPointError(ix, 0, float(fs[5]) * fUnit) useAtlasStyle() gStyle.SetMarkerStyle(20) gr1.SetMarkerStyle(20) gr1.Draw('AP') h1 = gr1.GetHistogram() h1.GetYaxis().SetTitle("Threshold [" + yUnit + "]") h1.GetXaxis().SetTitle("I_{Thre} code") # h1.GetYaxis().SetRangeUser(0,0.2) gPad.SetTicks(1, 0) gPad.SetRightMargin(0.16) y1b = 0 y2b = 15 x1 = h1.GetXaxis().GetXmax() y1 = h1.GetYaxis().GetXmin() y2 = h1.GetYaxis().GetXmax() raxis = TGaxis(x1, y1, x1, y2, y1b, y2b, 506, "+L") raxis.SetLineColor(2) raxis.SetLabelColor(2) raxis.SetTitleColor(2) raxis.SetTitle("ENC [" + yUnit + "]") raxis.Draw() nP = gr2.GetN() Ys = gr2.GetY() EYs = gr2.GetEY() Y = array( 'd', [y1 + (y2 - y1) / (y2b - y1b) * (Ys[i] - y1b) for i in range(nP)]) EY = array('d', [(y2 - y1) / (y2b - y1b) * EYs[i] for i in range(nP)]) gr2x = TGraphErrors(nP, gr2.GetX(), Y, gr2.GetEX(), EY) gr2x.SetMarkerStyle(24) gr2x.SetLineColor(2) gr2x.SetMarkerColor(2) gr2x.Draw('Psame') waitRootCmdX()
def ApplyBinShiftCorrectionGeneral(self, hist, fit): """ Alternative method for bin shift correction: - Apply user-default model for bin-shift correction - don't multiply by pt @param hist: Input spectrum for the bin shift correction @param fit: Model for the bin-shift correction @return: The bin-shift corrected spectrum as graph """ h = deepcopy(hist) hist.SetName("htemp") result = TGraphErrors(h) for i in range(0, result.GetN()): result.GetEX()[i] = 0. y = 0 #for now 10 iterations fixes for k in range(0, 10): for i in range(1, h.GetNbinsX() + 1): y = fit.Integral(h.GetBinLowEdge(i), h.GetBinUpEdge(i)) / h.GetBinWidth(i) x = self.FindX(y, fit, h.GetBinLowEdge(i), h.GetBinUpEdge(i)) result.GetX()[i - 1] = x # remove points that are 0 while result.GetY()[0] < 1.e-99: result.RemovePoint(0) mybin = 0 for biniter in range(0, result.GetN()): if result.GetY()[biniter] < 1.e-99: mybin = biniter break while result.RemovePoint(mybin) > 0: continue return result
def plotDistributionComparisonPlot(cfg): multiGraph = TMultiGraph() multiGraph.SetName("triggerRateMultiGraph") tfiles = [] histograms = [] canvas = TCanvas("canvas", "canvas", 800, 800) '''Contains the legend''' legend = TLegend(0.3, 0.7, 0.90, 0.9) '''Maximum value container, used to scale histograms''' maximumY = float("-inf") pad1 = TPad("pad1", "pad1", 0, 0.3, 1, 1.0) pad1.SetBottomMargin(0.05) # Upper and lower plot are joined #pad1.SetBottomMargin(0) # Upper and lower plot are joined pad1.SetGridx() # Vertical grid pad1.Draw() # Draw the upper pad: pad1 pad1.cd() # pad1 becomes the current pad for histogramFileNameAndTitle in cfg.plots: tfile = TFile(histogramFileNameAndTitle[0]) tfiles.append(tfile) histogram = tfile.Get(histogramFileNameAndTitle[1]) histograms.append(histogram) if histogram.ClassName() == "TH1F": histogram.SetStats(0) # No statistics on upper plot maximumY = histogram.GetMaximum( ) if histogram.GetMaximum() > maximumY else maximumY legend.AddEntry(histogram, histogramFileNameAndTitle[2], "l") # histograms[0] settings histograms[0].SetMarkerColor(4) histograms[0].SetLineColor(4) histograms[0].SetLineWidth(1) # Y axis histograms[0] plot settings histograms[0].GetYaxis().SetTitleSize(20) histograms[0].GetYaxis().SetTitleFont(43) histograms[0].GetYaxis().SetTitleOffset(1.55) #histograms[0].Scale(1./histograms[0].GetEntries()) if histograms[0].ClassName() == "TH1F": histograms[0].Draw( "SAME HIST") # Draw histograms[1] on top of histograms[0] else: histograms[0].Draw( "SAME APE") # Draw histograms[1] on top of histograms[0] #multiGraph.Add(histograms[0]) if getattr(cfg, "xRange", None) is not None: histograms[0].GetXaxis().SetRangeUser(cfg.xRange[0], cfg.xRange[1]) gPad.RedrawAxis() if getattr(cfg, "xAxisLabel", None) is not None: histograms[0].GetXaxis().SetTitle(cfg.xAxisLabel) gPad.RedrawAxis() if getattr(cfg, "yAxisLabel", None) is not None: histograms[0].GetYaxis().SetTitle(cfg.yAxisLabel) gPad.RedrawAxis() if getattr(cfg, "yRange", None) is not None: histograms[0].GetYaxis().SetRangeUser(cfg.yRange[0], cfg.yRange[1]) gPad.RedrawAxis() else: maximumY *= 1.1 histograms[0].GetYaxis().SetRangeUser(1e-6, maximumY) if getattr(cfg, "logY", False): canvas.SetLogy() # histograms[1] settings histograms[1].SetMarkerColor(2) histograms[1].SetLineColor(2) histograms[1].SetLineWidth(1) #histograms[1].Scale(1./histograms[1].GetEntries()) if histograms[1].ClassName() == "TH1F": histograms[1].Draw( "SAME HIST") # Draw histograms[1] on top of histograms[0] else: histograms[1].Draw( "SAME PE") # Draw histograms[1] on top of histograms[0] #multiGraph.Add(histograms[1]) #if multiGraph.GetListOfGraphs() != None: # multiGraph.Draw("SAME PE") # Do not draw the Y axis label on the upper plot and redraw a small # axis instead, in order to avoid the first label (0) to be clipped. #histograms[0].GetYaxis().SetLabelSize(0.) #axis = TGaxis( 0, 20, 0, maximumY, 20, maximumY, 510,"") #axis.SetLabelFont(43) # Absolute font size in pixel (precision 3) #axis.SetLabelSize(15) #axis.Draw() # Adding a small text with the chi-squared chiSquared = 0 if (histograms[0].ClassName() == "TGraph") or (histograms[0].ClassName() == "TGraphErrors"): numberOfBins = histograms[0].GetN() numberOfDegreesOfFreedom = numberOfBins else: numberOfBins = histograms[0].GetNbinsX() numberOfDegreesOfFreedom = numberOfBins for x in xrange( 1, numberOfBins + 1 ): # numberOfBins contains last bin, numberOfBins+1 contains the overflow (latter excluded), underflow also excluded if (histograms[0].ClassName() == "TGraph") or (histograms[0].ClassName() == "TGraphErrors"): binContent0 = histograms[0].GetY()[x - 1] else: binContent0 = histograms[0].GetBinContent(x) if (histograms[1].ClassName() == "TGraph") or (histograms[1].ClassName() == "TGraphErrors"): binContent1 = histograms[1].GetY()[x - 1] else: binContent1 = histograms[1].GetBinContent(x) bin0ErrorSquared = binContent0 bin1ErrorSquared = binContent1 #bin1ErrorSquared = 0 if (binContent0 == 0) and (binContent1 == 0): numberOfDegreesOfFreedom -= 1 #No data means one less degree of freedom else: binDifferenceSquared = (binContent0 - binContent1)**2 chiSquaredTerm = binDifferenceSquared / (bin0ErrorSquared + bin1ErrorSquared) chiSquared += chiSquaredTerm if chiSquaredTerm > chiSquaredWarningThreshold: if (histograms[0].ClassName() == "TGraph") or (histograms[0].ClassName() == "TGraphErrors"): print "Bin", x, "-", histograms[0].GetX()[ x - 1], "has a CS=", chiSquaredTerm else: print "Bin", x, "-", histograms[0].GetBinCenter( x), "has a CS=", chiSquaredTerm chiSquareLabel = TPaveText(0.7, 0.6, 0.9, 0.4) chiSquareLabel.AddText("#chi^{2}/ndf = " + str(chiSquared) + "/" + str(numberOfDegreesOfFreedom) + " = " + str(chiSquared / numberOfDegreesOfFreedom)) chiSquareLabel.Draw() print "FINAL CS IS", format( chiSquared, ".2f") + "/" + str(numberOfDegreesOfFreedom) + " = " + format( chiSquared / numberOfDegreesOfFreedom, ".2f") legend.SetHeader( "#chi^{2}/ndf = " + format(chiSquared, ".2f") + "/" + str(numberOfDegreesOfFreedom) + " = " + format(chiSquared / numberOfDegreesOfFreedom, ".2f"), "C") legend.Draw() # lower plot will be in pad canvas.cd() # Go back to the main canvas before defining pad2 pad2 = TPad("pad2", "pad2", 0, 0.05, 1, 0.3) pad2.SetTopMargin(0) pad2.SetBottomMargin(0.2) pad2.SetGridx() # vertical grid pad2.Draw() pad2.cd() # pad2 becomes the current pad pad2.SetGridy() # Define the ratio plot ratioPlot = TGraphErrors(histograms[0]) ratioPlot.SetName("ratioPlot") graph_histo0 = TGraphErrors(histograms[0]) graph_histo1 = TGraphErrors(histograms[1]) ratioPlot.SetLineColor(1) ratioPlot.SetMinimum(0.6) # Define Y .. ratioPlot.SetMaximum(1.5) # .. range #ratioPlot.Sumw2() #ratioPlot.SetStats(0) # No statistics on lower plot #Dividing point by point for index in xrange(0, ratioPlot.GetN()): if graph_histo1.GetY()[index] == 0: ratioPlot.GetY()[index] = 0 ratioPlot.GetEY()[index] = 0 else: ratioPlot.GetY()[index] /= graph_histo1.GetY()[index] ratioPlot.GetEY()[index] = sqrt( ((graph_histo1.GetY()[index])**2 * (graph_histo0.GetEY()[index])**2 + (graph_histo0.GetY()[index])**2 * (graph_histo1.GetEY()[index])**2) / (graph_histo1.GetY()[index])**4) ratioPlot.SetMarkerStyle(21) if getattr(cfg, "xRange", None) is not None: ratioPlot.GetXaxis().SetRangeUser(cfg.xRange[0], cfg.xRange[1]) gPad.RedrawAxis() if getattr(cfg, "yRangeRatio", None) is not None: ratioPlot.GetYaxis().SetRangeUser(cfg.yRangeRatio[0], cfg.yRangeRatio[1]) gPad.RedrawAxis() ratioPlot.Draw("APE") # Draw the ratio plot line0 = TLine(ratioPlot.GetXaxis().GetXmin(), 1, ratioPlot.GetXaxis().GetXmax(), 1) line0.SetLineColor(2) line0.SetLineWidth(2) line0.SetLineStyle(2) line0.Draw() # Ratio plot (ratioPlot) settings ratioPlot.SetTitle("") # Remove the ratio title # Y axis ratio plot settings ratioPlot.GetYaxis().SetTitle("Ratio #frac{blue}{red}") ratioPlot.GetYaxis().SetNdivisions(505) ratioPlot.GetYaxis().SetTitleSize(20) ratioPlot.GetYaxis().SetTitleFont(43) ratioPlot.GetYaxis().SetTitleOffset(1.55) ratioPlot.GetYaxis().SetLabelFont( 43) # Absolute font size in pixel (precision 3) ratioPlot.GetYaxis().SetLabelSize(15) # X axis ratio plot settings ratioPlot.GetXaxis().SetTitleSize(20) ratioPlot.GetXaxis().SetTitleFont(43) ratioPlot.GetXaxis().SetTitleOffset(4.) ratioPlot.GetXaxis().SetLabelFont( 43) # Absolute font size in pixel (precision 3) ratioPlot.GetXaxis().SetLabelSize(15) xRangeBinning = getattr(cfg, "simplifiedRatioPlotXRangeBinning", None) if xRangeBinning is not None: simplifiedRatioPlot = TGraphErrors(len(xRangeBinning) - 1) simplifiedRatioPlot.SetName("simplifiedRatioPlot") ratioPlotIndex = 0 for idx in xrange(0, simplifiedRatioPlot.GetN()): yAverage = 0. yMax = float("-inf") yMin = float("+inf") nPoints = 0. simplifiedRatioPlot.GetX()[idx] = (xRangeBinning[idx] + xRangeBinning[idx + 1]) / 2. simplifiedRatioPlot.GetEX()[idx] = (xRangeBinning[idx + 1] - xRangeBinning[idx]) / 2. while (ratioPlot.GetX()[ratioPlotIndex] < xRangeBinning[idx]): ratioPlotIndex += 1 while ((ratioPlotIndex < ratioPlot.GetN()) and (ratioPlot.GetX()[ratioPlotIndex] < xRangeBinning[idx + 1]) and (ratioPlot.GetX()[ratioPlotIndex] >= xRangeBinning[idx])): yAverage += ratioPlot.GetY()[ratioPlotIndex] if (yMax < ratioPlot.GetY()[ratioPlotIndex] + ratioPlot.GetEY()[ratioPlotIndex]): yMax = ratioPlot.GetY()[ratioPlotIndex] + ratioPlot.GetEY( )[ratioPlotIndex] if (yMin > ratioPlot.GetY()[ratioPlotIndex] - ratioPlot.GetEY()[ratioPlotIndex]): yMin = ratioPlot.GetY()[ratioPlotIndex] - ratioPlot.GetEY( )[ratioPlotIndex] nPoints += 1. ratioPlotIndex += 1 simplifiedRatioPlot.GetY()[idx] = yAverage / nPoints simplifiedRatioPlot.GetEY()[idx] = (yMax - yMin) / 2. saveFile = TFile(cfg.saveFileName, "RECREATE") saveFile.cd() canvas.Write() histograms[0].Write() histograms[1].Write() if multiGraph.GetListOfGraphs() != None: multiGraph.Write() ratioPlot.Write() if xRangeBinning is not None: simplifiedRatioPlot.Write() saveFile.Close() for tfile in tfiles: tfile.Close()
def ApplyBinShiftCorrection(self, hist): """ Apply bin-shift correction to the input spectrum using an iterative procedure @param hist: Input spectrum @return: Bin-shift corrected spectrum """ h = deepcopy(hist) h.SetName("htemp") # Bin shift correction performed in model specturm * pt for i in range(1, h.GetNbinsX() + 1): pt = h.GetBinCenter(i) h.SetBinContent(i, h.GetBinContent(i) * pt) h.SetBinError(i, h.GetBinError(i) * pt) result = TGraphErrors(h) for i in range(0, result.GetN()): result.GetEX()[i] = 0. fitfun = TF1("fitfun", "([0]*(1.+x/[1])^(-[2])*x)-[3]", 0.15, 100.0) fitfun.SetParameter(0, 1000) fitfun.SetParameter(1, 1) fitfun.SetParameter(2, 5) fitfun.FixParameter(3, 0) h.Fit(fitfun, "") self.__StableFit(h, fitfun, True) # Iterative approach: # - Use model to get the mean of the function inside the bin # - Get the X where the mean is found # - Use the new coordinate (x,y) for the next iteration of the fit # for now 10 iterations fixed for k in range(1, 11): for i in range(1, h.GetNbinsX() + 1): y = fitfun.Integral(h.GetBinLowEdge(i), h.GetBinUpEdge(i)) / h.GetBinWidth(i) result.GetX()[i - 1] = self.FindX(y, fitfun, h.GetBinLowEdge(i), h.GetBinUpEdge(i)) self.__StableFit(result, fitfun, False) # Undo multiplication with pt for i in range(0, result.GetN()): pt = result.GetX()[i] result.GetY()[i] /= pt result.GetEY()[i] /= pt #remove points that are 0 while result.GetY()[0] < 1.e-99: result.RemovePoint(0) bval = 0 for mybin in range(0, result.GetN() + 1): if result.GetY()[bin] < 1.e-99: bval = mybin break while result.RemovePoint(bval) > 0: continue return result
def build_tgraphs_from_data(df, keys=None, xkey='kT', skip_systematics=False, title_dict=None): """ """ from collections import defaultdict from ROOT import TGraphErrors if keys is None: keys = ("Ro", "Rs", "Rl") if title_dict is None: title_dict = { 'Ro': "R_{out}", 'Rs': "R_{side}", 'Rl': "R_{long}", 'lam': "#lambda", 'alpha': "#alpha", 'radius': 'R_{inv}' } missing_titles = set(keys) - set(title_dict.keys()) if missing_titles: raise ValueError(f"Title dict missing keys: {missing_titles}") def _merge_points(df, key): results = [] for kt, data in df.groupby(xkey): errs = np.array(data[key + '_err']) weights = errs**-2 val = (data[key] * weights).sum() / weights.sum() err = np.sqrt(1.0 / weights.sum()) results.append([kt, val, err]) return np.array(results).T graphs = defaultdict(dict) for cent, cdf in df.sort_values(xkey).groupby('cent'): for r in keys: x = [] y = [] ye = [] x, y, ye = _merge_points(cdf, r) xe = np.zeros_like(x) title = [r] gdata = TGraphErrors(x.size) np.frombuffer(gdata.GetX(), dtype=np.float64)[:] = x np.frombuffer(gdata.GetY(), dtype=np.float64)[:] = y np.frombuffer(gdata.GetEY(), dtype=np.float64)[:] = ye if skip_systematics: gsys = None else: sys_key = f"{r}_sys_err" sys_err = np.array(cdf[sys_key]) gsys = TGraphErrors(x.size) np.frombuffer(gsys.GetX(), dtype=np.float64)[:] = x # - 0.004 np.frombuffer(gsys.GetY(), dtype=np.float64)[:] = y np.frombuffer(gsys.GetEY(), dtype=np.float64)[:] = sys_err np.frombuffer(gsys.GetEX(), dtype=np.float64)[:] = 0.012 graphs[r][cent] = (gdata, gsys) return dict(graphs)