def getEfficiency(datasets, numerator="Numerator", denominator="Denominator"): # statOption = ROOT.TEfficiency.kFNormal statOption = ROOT.TEfficiency.kFCP # Clopper-Pearson # statOption = ROOT.TEfficiency.kFFC # Feldman-Cousins first = True isData = False teff = ROOT.TEfficiency() for dataset in datasets: n = dataset.getDatasetRootHisto(numerator).getHistogram() d = dataset.getDatasetRootHisto(denominator).getHistogram() if d.GetEntries() == 0: continue checkNegatives(n, d) # removeNegatives(n) # removeNegatives(d) print dataset.getName(), "entries", n.GetEntries(), d.GetEntries() print " bins", n.GetNbinsX(), d.GetNbinsX() print " lowedge", n.GetBinLowEdge(1), d.GetBinLowEdge(1) eff = ROOT.TEfficiency(n, d) eff.SetStatisticOption(statOption) weight = 1 if dataset.isMC(): weight = dataset.getCrossSection() / d.GetEntries() for i in range(1, d.GetNbinsX() + 1): print " bin", i, d.GetBinLowEdge(i), n.GetBinContent( i), d.GetBinContent(i) eff.SetWeight(weight) if first: teff = eff if dataset.isData(): tn = n td = d first = False else: teff.Add(eff) if dataset.isData(): tn.Add(n) td.Add(d) if isData: teff = ROOT.TEfficiency(tn, td) teff.SetStatisticOption(self.statOption) return teff
def getEfficiency(datasets,numerator="Numerator",denominator="Denominator"): # statOption = ROOT.TEfficiency.kFNormal statOption = ROOT.TEfficiency.kFCP # Clopper-Pearson # statOption = ROOT.TEfficiency.kFFC # Feldman-Cousins first = True isData = False teff = ROOT.TEfficiency() for dataset in datasets: n = dataset.getDatasetRootHisto(numerator).getHistogram() d = dataset.getDatasetRootHisto(denominator).getHistogram() if d.GetEntries() == 0: continue checkNegatives(n,d) # removeNegatives(n) # removeNegatives(d) print dataset.getName(),"entries",n.GetEntries(),d.GetEntries() print " bins",n.GetNbinsX(),d.GetNbinsX() print " lowedge",n.GetBinLowEdge(1),d.GetBinLowEdge(1) eff = ROOT.TEfficiency(n,d) eff.SetStatisticOption(statOption) weight = 1 if dataset.isMC(): weight = dataset.getCrossSection()/d.GetEntries() for i in range(1,d.GetNbinsX()+1): print " bin",i,d.GetBinLowEdge(i),n.GetBinContent(i),d.GetBinContent(i) eff.SetWeight(weight) if first: teff = eff if dataset.isData(): tn = n td = d first = False else: teff.Add(eff) if dataset.isData(): tn.Add(n) td.Add(d) if isData: teff = ROOT.TEfficiency(tn, td) teff.SetStatisticOption(self.statOption) return teff
def GetCutEfficiencyHisto(dataset, histoName, statOpt, **kwargs): ''' See https://root.cern.ch/doc/master/classTEfficiency.html ''' HasKeys(["verbose", "normalizeTo", "cutDirection"], **kwargs) verbose = kwargs.get("verbose") normalizeTo = kwargs.get("normalizeTo") cutDirection = kwargs.get("cutDirection") Verbose("Calculating the cut-efficiency (%s) for histo with name %s" % (cutDirection, histoName)) # Choose statistics options statOpts = [ "kFCP", "kFNormal", "KFWilson", "kFAC", "kFFC", "kBJeffrey", "kBUniform", "kBayesian" ] if statOpt not in statOpts: raise Exception( "Invalid statistics option \"%s\". Please choose one from the following:\n\t%s" % (statOpt, "\n\t".join(statOpts))) if statOpt == "kFCP": statOption = ROOT.TEfficiency.kFCP # Clopper-Pearson elif statOpt == "kFNormal": statOption = ROOT.TEfficiency.kFNormal # Normal Approximation elif statOpt == "kFWilson": statOption = ROOT.TEfficiency.kFWilson # Wilson elif statOpt == "kFAC": statOption = ROOT.TEfficiency.kFAC # Agresti-Coull elif statOpt == "kFFC": statOption = ROOT.TEfficiency.kFFC # Feldman-Cousins elif statOpt == "kBJeffrey": statOption = ROOT.TEfficiency.kBJeffrey # Jeffrey elif statOpt == "kBUniform": statOption = ROOT.TEfficiency.kBUniform # Uniform Prior elif statOpt == "kBayesian": statOption = ROOT.TEfficiency.kBayesian # Custom Prior else: raise Exception("This should never be reached") # Declare variables & options first = True isData = False teff = ROOT.TEfficiency() # Get the ROOT histogram rootHisto = dataset.getDatasetRootHisto(histoName) # Normalise the histogram NormalizeRootHisto(datasetsMgr, rootHisto, dataset.isMC(), normalizeTo) #NormalizeRootHisto(datasetsMgr, rootHisto, d.isMC(), normalizeTo) ## Get a clone of the wrapped histogram normalized as requested. h = rootHisto.getHistogram() titleX = h.GetXaxis().GetTitle() binWidth = h.GetXaxis().GetBinWidth(0) titleY = "efficiency (%s) / %s" % (cutDirection, GetBinwidthDecimals(binWidth) % (binWidth)) # If empty return if h.GetEntries() == 0: return # Create the numerator/denominator histograms numerator = h.Clone("Numerator") denominator = h.Clone("Denominator") # Reset the numerator/denominator histograms numerator.Reset() denominator.Reset() # Calculate the instances passing a given cut (all bins) nBinsX = h.GetNbinsX() + 1 for iBin in range(1, nBinsX): nTotal = h.Integral(0, nBinsX) if cutDirection == ">": nPass = h.Integral(iBin + 1, nBinsX) elif cutDirection == "<": nPass = nTotal - h.Integral(iBin + 1, nBinsX) else: raise Exception( "Invalid cut direction \"%s\". Please choose either \">\" or \"<\"" % (cutDirection)) # Sanity check if nPass < 0: nPass = 0 # Fill the numerator/denominator histograms # print "iBin = %s, nPass = %s, nTotal = %s" % (iBin, nPass, nTotal) numerator.SetBinContent(iBin, nPass) numerator.SetBinError(iBin, math.sqrt(nPass) / 10) # denominator.SetBinContent(iBin, nTotal) denominator.SetBinError(iBin, math.sqrt(nTotal) / 10) # Check for negative values CheckNegatives(numerator, denominator) # Create TEfficiency object using the two histos eff = ROOT.TEfficiency(numerator, denominator) eff.SetStatisticOption(statOption) Verbose("The statistic option was set to %s" % (eff.GetStatisticOption())) # Save info in a table (debugging) table = [] hLine = "=" * 70 msgAlign = '{:<5} {:<20} {:<20} {:<20}' title = msgAlign.format("Bin", "Efficiency", "Error-Low", "Error-Up") table.append("\n" + hLine) table.append(title) table.append(hLine) for iBin in range(1, nBinsX): e = eff.GetEfficiency(iBin) errLow = eff.GetEfficiencyErrorLow(iBin) errUp = eff.GetEfficiencyErrorUp(iBin) values = msgAlign.format(iBin, e, errLow, errUp) table.append(values) table.append(hLine) # Verbose mode if verbose: for l in table: print l weight = 1 if dataset.isMC(): weight = dataset.getCrossSection() eff.SetWeight(weight) if first: teff = eff if dataset.isData(): tn = numerator td = denominator first = False else: teff.Add(eff) if dataset.isData(): tn.Add(numerator) td.Add(denominator) if isData: teff = ROOT.TEfficiency(tn, td) teff.SetStatisticOption(self.statOption) style = styleDict[dataset.getName()] return Convert2TGraph(teff, dataset, style, titleX, titleY)
def PlotEfficiency(datasetsMgr, numPath, denPath, intLumi): # Definitions myList = [] index = 0 _kwargs = GetHistoKwargs(numPath, opts) # For-loop: All datasets for dataset in datasetsMgr.getAllDatasets(): #if "Fake" in numPath and "TT" in dataset.getName(): # continue # Get the histograms #num = dataset.getDatasetRootHisto(numPath).getHistogram() #den = dataset.getDatasetRootHisto(denPath).getHistogram() n = dataset.getDatasetRootHisto(numPath) n.normalizeToLuminosity(intLumi) num = n.getHistogram() d = dataset.getDatasetRootHisto(denPath) d.normalizeToLuminosity(intLumi) den = d.getHistogram() if "binList" in _kwargs: xBins = _kwargs["binList"] nx = len(xBins) - 1 num = num.Rebin(nx, "", xBins) den = den.Rebin(nx, "", xBins) # Sanity checks if den.GetEntries() == 0 or num.GetEntries() == 0: continue if num.GetEntries() > den.GetEntries(): continue # Remove negative bins and ensure numerator bin <= denominator bin CheckNegatives(num, den, True) # RemoveNegatives(num) # RemoveNegatives(den) # Sanity check (Histograms are valid and consistent) - Always false! # if not ROOT.TEfficiency.CheckConsistency(num, den): # continue # Create Efficiency plots with Clopper-Pearson stats eff = ROOT.TEfficiency(num, den) # fixme: investigate warnings eff.SetStatisticOption(ROOT.TEfficiency.kFCP) # # Set the weights - Why is this needed? if 0: weight = 1 if dataset.isMC(): weight = dataset.getCrossSection() eff.SetWeight(weight) # Convert to TGraph eff = convert2TGraph(eff) # Apply default style (according to dataset name) plots._plotStyles[dataset.getName()].apply(eff) # Append in list myList.append( histograms.HistoGraph(eff, plots._legendLabels[dataset.getName()], "lp", "P")) # Define save name saveName = "Eff_" + numPath.split("/")[-1] + "Over" + denPath.split( "/")[-1] # Plot the efficiency p = plots.PlotBase(datasetRootHistos=myList, saveFormats=[]) plots.drawPlot(p, saveName, **_kwargs) # Save plot in all formats savePath = os.path.join(opts.saveDir, "HplusMasses", numPath.split("/")[0], opts.optMode) #savePath = os.path.join(opts.saveDir, numPath.split("/")[0], opts.optMode) save_path = savePath + opts.MVAcut SavePlot(p, saveName, save_path, saveFormats=[".png", ".pdf", ".C"]) return
def GetCutEfficiencyHisto(dataset, histoName, statOpt, **kwargs): ''' See https://root.cern.ch/doc/master/classTEfficiency.html ''' HasKeys(["verbose", "normalizeTo", "cutDirection"], **kwargs) verbose = kwargs.get("verbose") normalizeTo = kwargs.get("normalizeTo") cutDirection= kwargs.get("cutDirection") Verbose("Calculating the cut-efficiency (%s) for histo with name %s" % (cutDirection, histoName) ) # Choose statistics options statOpts = ["kFCP", "kFNormal", "KFWilson", "kFAC", "kFFC", "kBJeffrey", "kBUniform", "kBayesian"] if statOpt not in statOpts: raise Exception("Invalid statistics option \"%s\". Please choose one from the following:\n\t%s" % (statOpt, "\n\t".join(statOpts))) if statOpt == "kFCP": statOption = ROOT.TEfficiency.kFCP # Clopper-Pearson elif statOpt == "kFNormal": statOption = ROOT.TEfficiency.kFNormal # Normal Approximation elif statOpt == "kFWilson": statOption = ROOT.TEfficiency.kFWilson # Wilson elif statOpt == "kFAC": statOption = ROOT.TEfficiency.kFAC # Agresti-Coull elif statOpt == "kFFC": statOption = ROOT.TEfficiency.kFFC # Feldman-Cousins elif statOpt == "kBJeffrey": statOption = ROOT.TEfficiency.kBJeffrey # Jeffrey elif statOpt == "kBUniform": statOption = ROOT.TEfficiency.kBUniform # Uniform Prior elif statOpt == "kBayesian": statOption = ROOT.TEfficiency.kBayesian # Custom Prior else: raise Exception("This should never be reached") # Declare variables & options first = True isData = False teff = ROOT.TEfficiency() # Get the ROOT histogram rootHisto = dataset.getDatasetRootHisto(histoName) # Normalise the histogram NormalizeRootHisto(datasetsMgr, rootHisto, dataset.isMC(), normalizeTo) #NormalizeRootHisto(datasetsMgr, rootHisto, d.isMC(), normalizeTo) ## Get a clone of the wrapped histogram normalized as requested. h = rootHisto.getHistogram() titleX = h.GetXaxis().GetTitle() binWidth = h.GetXaxis().GetBinWidth(0) titleY = "efficiency (%s) / %s" % (cutDirection, GetBinwidthDecimals(binWidth) % (binWidth) ) # If empty return if h.GetEntries() == 0: return # Create the numerator/denominator histograms numerator = h.Clone("Numerator") denominator = h.Clone("Denominator") # Reset the numerator/denominator histograms numerator.Reset() denominator.Reset() # Calculate the instances passing a given cut (all bins) nBinsX = h.GetNbinsX()+1 for iBin in range(1, nBinsX): nTotal = h.Integral(0, nBinsX) if cutDirection == ">": nPass = h.Integral(iBin+1, nBinsX) elif cutDirection == "<": nPass = nTotal - h.Integral(iBin+1, nBinsX) else: raise Exception("Invalid cut direction \"%s\". Please choose either \">\" or \"<\"" % (cutDirection)) # Sanity check if nPass < 0: nPass = 0 # Fill the numerator/denominator histograms # print "iBin = %s, nPass = %s, nTotal = %s" % (iBin, nPass, nTotal) numerator.SetBinContent(iBin, nPass) numerator.SetBinError(iBin, math.sqrt(nPass)/10) # denominator.SetBinContent(iBin, nTotal) denominator.SetBinError(iBin, math.sqrt(nTotal)/10) # Check for negative values CheckNegatives(numerator, denominator) # Create TEfficiency object using the two histos eff = ROOT.TEfficiency(numerator, denominator) eff.SetStatisticOption(statOption) Verbose("The statistic option was set to %s" % (eff.GetStatisticOption()) ) # Save info in a table (debugging) table = [] hLine = "="*70 msgAlign = '{:<5} {:<20} {:<20} {:<20}' title = msgAlign.format("Bin", "Efficiency", "Error-Low", "Error-Up") table.append("\n" + hLine) table.append(title) table.append(hLine) for iBin in range(1, nBinsX): e = eff.GetEfficiency(iBin) errLow = eff.GetEfficiencyErrorLow(iBin) errUp = eff.GetEfficiencyErrorUp(iBin) values = msgAlign.format(iBin, e, errLow, errUp) table.append(values) table.append(hLine) # Verbose mode if verbose: for l in table: print l weight = 1 if dataset.isMC(): weight = dataset.getCrossSection() eff.SetWeight(weight) if first: teff = eff if dataset.isData(): tn = numerator td = denominator first = False else: teff.Add(eff) if dataset.isData(): tn.Add(numerator) td.Add(denominator) if isData: teff = ROOT.TEfficiency(tn, td) teff.SetStatisticOption(self.statOption) style = styleDict[dataset.getName()] return Convert2TGraph(teff, dataset, style, titleX, titleY)
def GetEfficiency(datasetsMgr, datasets, numerator="Numerator",denominator="Denominator", **kwargs): ''' TEfficiency method: See https://root.cern.ch/doc/master/classTEfficiency.html ''' lumi = GetLumi(datasetsMgr) # Select Statistic Options statOption = ROOT.TEfficiency.kFCP ''' statOption = ROOT.TEfficiency.kFCP # Clopper-Pearson statOption = ROOT.TEfficiency.kFNormal # Normal Approximation statOption = ROOT.TEfficiency.kFWilson # Wilson statOption = ROOT.TEfficiency.kFAC # Agresti-Coull statOption = ROOT.TEfficiency.kFFC # Feldman-Cousins statOption = ROOT.TEfficiency.kBBJeffrey # Jeffrey statOption = ROOT.TEfficiency.kBBUniform # Uniform Prior statOption = ROOT.TEfficiency.kBBayesian # Custom Prior ''' first = True teff = ROOT.TEfficiency() # teff.SetStatisticOption(statOption) # For-loop: All datasets for dataset in datasets: num = dataset.getDatasetRootHisto(numerator) den = dataset.getDatasetRootHisto(denominator) # if dataset.isMC(): num.normalizeToLuminosity(lumi) den.normalizeToLuminosity(lumi) # Get Numerator and Denominator n = num.getHistogram() d = den.getHistogram() if d.GetEntries() == 0 or n.GetEntries() == 0: msg = "Denominator Or Numerator has no entries" Print(ErrorStyle() + msg + NormalStyle(), True) continue # Check Negatives CheckNegatives(n, d, True) # Remove Negatives RemoveNegatives(n) #RemoveNegatives(d) NumeratorBins = n.GetNbinsX() DenominatorBins = d.GetNbinsX() # Sanity Check if (NumeratorBins != DenominatorBins) : raise Exception("Numerator and Denominator Bins are NOT equal!") nBins = d.GetNbinsX() xMin = d.GetXaxis().GetXmin() xMax = d.GetXaxis().GetXmax() # ----------------------------------------------------------------------------------------- # # Ugly hack to ignore EMPTY (in the wanted range) histograms with overflows/underflows # ----------------------------------------------------------------------------------------- # if 0: print "\n" print "=========== getEfficiency:" print "Dataset = ", dataset.getName() print "Numerator :", n.GetName(), " entries=", n.GetEntries(), " Bins=", n.GetNbinsX(), " Low edge=", n.GetBinLowEdge(1) print "Denominator:", d.GetName(), " entries=", d.GetEntries(), " Bins=", d.GetNbinsX(), " Low edge=", d.GetBinLowEdge(1) print "\n" print ">>>>>> Sanity Check: <<<<<<" print "Numerator Mean = ", n.GetMean() print "Numerator RMS = ", n.GetRMS() print "Numerator Integral = ", n.Integral(1, nBins) print "Denominator Mean = ", d.GetMean() print "Denominator RMS = ", d.GetRMS() print "Denominator Integral = ", d.Integral(1, nBins) if (n.GetMean() == 0 or d.GetMean() == 0): continue if (n.GetRMS() == 0 or d.GetRMS() == 0): continue if (n.Integral(1,nBins) == 0 or d.Integral(1,nBins) == 0): continue Verbose("Passed the sanity check", True) eff = ROOT.TEfficiency(n, d) eff.SetStatisticOption(statOption) # For-loop: All bins if 0: for iBin in range(1, nBins+1): print iBin, "x=", n.GetBinLowEdge(iBin), " Num=", n.GetBinContent(iBin), " Den=", d.GetBinContent(iBin)," Eff=", eff.GetEfficiency(iBin) weight = 1 if dataset.isMC(): weight = dataset.getCrossSection() eff.SetWeight(weight) if first: teff = eff first = False if dataset.isData(): tn = n td = d else: teff.Add(eff) if dataset.isData(): tn.Add(n) td.Add(d) if dataset.isData(): teff = ROOT.TEfficiency(tn, td) teff.SetStatisticOption(statOption) Verbose("Final tEff", True) if 0: for iBin in range(1,nBins+1): print iBin, "x=", n.GetBinLowEdge(iBin)," Efficiency=", teff.GetEfficiency(iBin), " Weight = ", teff.GetWeight() return convert2TGraph(teff)
def PlotEfficiency(datasetsMgr, numPath, denPath, intLumi): # Definitions myList = [] index = 0 _kwargs = GetHistoKwargs(numPath, opts) # For-loop: All datasets for dataset in datasetsMgr.getAllDatasets(): if "Fake" in numPath and "TT" in dataset.getName(): continue # Get the histograms #num = dataset.getDatasetRootHisto(numPath).getHistogram() #den = dataset.getDatasetRootHisto(denPath).getHistogram() n = dataset.getDatasetRootHisto(numPath) n.normalizeToLuminosity(intLumi) num = n.getHistogram() d = dataset.getDatasetRootHisto(denPath) d.normalizeToLuminosity(intLumi) den = d.getHistogram() if "binList" in _kwargs: xBins = _kwargs["binList"] nx = len(xBins)-1 num = num.Rebin(nx, "", xBins) den = den.Rebin(nx, "", xBins) # Sanity checks if den.GetEntries() == 0 or num.GetEntries() == 0: continue if num.GetEntries() > den.GetEntries(): continue # Remove negative bins and ensure numerator bin <= denominator bin CheckNegatives(num, den, True) # RemoveNegatives(num) # RemoveNegatives(den) # Sanity check (Histograms are valid and consistent) - Always false! # if not ROOT.TEfficiency.CheckConsistency(num, den): # continue # Create Efficiency plots with Clopper-Pearson stats eff = ROOT.TEfficiency(num, den) # fixme: investigate warnings eff.SetStatisticOption(ROOT.TEfficiency.kFCP) # # Set the weights - Why is this needed? if 0: weight = 1 if dataset.isMC(): weight = dataset.getCrossSection() eff.SetWeight(weight) # Convert to TGraph eff = convert2TGraph(eff) # Apply default style (according to dataset name) plots._plotStyles[dataset.getName()].apply(eff) # Append in list myList.append(histograms.HistoGraph(eff, plots._legendLabels[dataset.getName()], "lp", "P")) # Define save name saveName = "Eff_" + numPath.split("/")[-1] + "Over" + denPath.split("/")[-1] # Plot the efficiency p = plots.PlotBase(datasetRootHistos=myList, saveFormats=[]) plots.drawPlot(p, saveName, **_kwargs) # Save plot in all formats savePath = os.path.join(opts.saveDir, numPath.split("/")[0], opts.optMode) #savePath = os.path.join(opts.saveDir, numPath.split("/")[0], opts.optMode) save_path = savePath + opts.MVAcut SavePlot(p, saveName, save_path, saveFormats = [".png", ".pdf", ".C"]) return
def getEfficiency2D(datasetsMgr, datasets, numerator="Numerator", denominator="Denominator", **kwargs): ''' TEfficiency method: See https://root.cern.ch/doc/master/classTEfficiency.html ''' HasKeys(["verbose"], **kwargs) verbose = True #kwargs.get("verbose") lumi = GetLumi(datasetsMgr) # Select Statistic Options statOption = ROOT.TEfficiency.kFCP ''' statOption = ROOT.TEfficiency.kFCP # Clopper-Pearson statOption = ROOT.TEfficiency.kFNormal # Normal Approximation statOption = ROOT.TEfficiency.kFWilson # Wilson statOption = ROOT.TEfficiency.kFAC # Agresti-Coull statOption = ROOT.TEfficiency.kFFC # Feldman-Cousins statOption = ROOT.TEfficiency.kBBJeffrey # Jeffrey statOption = ROOT.TEfficiency.kBBUniform # Uniform Prior statOption = ROOT.TEfficiency.kBBayesian # Custom Prior ''' print "getEfficiency function" first = True teff = ROOT.TEfficiency() # teff.SetStatisticOption(statOption) print "Loop over Datasets" for dataset in datasets: print "Datasets" #datasets.normalizeMCByLuminosity() for dataset in datasets: num = dataset.getDatasetRootHisto(numerator) den = dataset.getDatasetRootHisto(denominator) if dataset.isMC(): num.normalizeToLuminosity(lumi) den.normalizeToLuminosity(lumi) #num.normalizeMCByLuminosity() #den.normalizeMCByLuminosity() # Get Numerator and Denominator n = num.getHistogram() d = den.getHistogram() #tn = None #td = None #n.normalizeMCByLuminosity() #d.normalizeMCByLuminosity() #n = dataset.getDatasetRootHisto(numerator).getHistogram() #d = dataset.getDatasetRootHisto(denominator).getHistogram() if d.GetEntries() == 0 or n.GetEntries() == 0: print "Denominator Or Numerator has no entries" continue # Check Negatives CheckNegatives(n, d, True) # Remove Negatives RemoveNegatives(n) #RemoveNegatives(d) NumeratorBins = n.GetNbinsX() DenominatorBins = d.GetNbinsX() # Sanity Check if (NumeratorBins != DenominatorBins): raise Exception("Numerator and Denominator Bins are NOT equal!") nBinsX = d.GetNbinsX() xMin = d.GetXaxis().GetXmin() xMax = d.GetXaxis().GetXmax() nBinsY = d.GetNbinsY() #yMin = d.GetYaxis().GetYmin() #yMax = d.GetYaxis().GetYmax() print("NoProblem till here asdasd...") # ----------------------------------------------------------------------------------------- # # Ugly hack to ignore EMPTY (in the wanted range) histograms with overflows/underflows # ----------------------------------------------------------------------------------------- # print "\n" print "=========== getEfficiency:" print "Dataset = ", dataset.getName() #print "Numerator :", n.GetName(), " entries=", n.GetEntries(), " Bins=", n.GetNbinsX(), " Low edge=", n.GetBinLowEdge(1) #print "Denominator:", d.GetName(), " entries=", d.GetEntries(), " Bins=", d.GetNbinsX(), " Low edge=", d.GetBinLowEdge(1) print "\n" print ">>>>>> Sanity Check: <<<<<<" print "Numerator Mean = ", n.GetMean() print "Numerator RMS = ", n.GetRMS() print "Numerator Integral = ", n.Integral() print "Denominator Mean = ", d.GetMean() print "Denominator RMS = ", d.GetRMS() print "Denominator Integral = ", d.Integral() if (n.GetMean() == 0 or d.GetMean() == 0): continue if (n.GetRMS() == 0 or d.GetRMS() == 0): continue if (n.Integral() == 0 or d.Integral() == 0): continue print "Passed the sanity check" eff = ROOT.TEfficiency(n, d) eff.SetStatisticOption(statOption) # if "TT" in dataset.getName(): # print " " # print " TT sample" #for iBin in range(1, nBins+1): # print iBin, "x=", n.GetBinLowEdge(iBin), " Num=", n.GetBinContent(iBin), " Den=", d.GetBinContent(iBin)," Eff=", eff.GetEfficiency(iBin) # "Contrib. =", d.GetBinContent(iBin)/d.Integral(1, nBins)*100.0, "Contrib. = ", n.GetBinContent(iBin)/n.Integral(1, nBins)*100.0, ''' #if (verbose): print "\n" for iBin in range(1,nBins+1): #print iBin, "x=", n.GetBinLowEdge(iBin), " Numerator=", n.GetBinContent(iBin), " Denominator=", d.GetBinContent(iBin), " Efficiency=", eff.GetEfficiency(iBin\ ), " Weight=", eff.GetWeight() print "\n" ''' weight = 1 if dataset.isMC(): weight = dataset.getCrossSection() eff.SetWeight(weight) #print "dataset=", dataset.getName(), "has weight=", weight #print " Efficiency plot has weight=", eff.GetWeight() if first: teff = eff first = False if dataset.isData(): tn = n td = d else: teff.Add(eff) #print " " #print "Adding eff to TEfficiency=" #for iBin in range(1, nBins+1): # print iBin, "x=", n.GetBinLowEdge(iBin), " Numerator=", n.GetBinContent(iBin), "Contrib. = ", n.GetBinContent(iBin)/n.Integral(1, nBins)*100.0, " Denominator=", d.GetBinContent(iBin), "Contrib. =", d.GetBinContent(iBin)/d.Integral(1, nBins)*100.0, " Efficiency=", teff.GetEfficiency(iBin), " Weight=", teff.GetWeight() if dataset.isData(): tn.Add(n) td.Add(d) if dataset.isData(): teff = ROOT.TEfficiency(tn, td) teff.SetStatisticOption(statOption) ''' print " ------------------------- Final Data Plot ------------------------- " print "Integral = ", tn.Integral(1, nBins) print "Numerator:" for iBin in range(1, nBins+1): print iBin, "x=", tn.GetBinLowEdge(iBin), " Bin Content = ", tn.GetBinContent(iBin), " Percentage=", tn.GetBinContent(iBin)/tn.Integral(1, nBins)*100.0 print "Denominator: " print "Integral = ", td.Integral(1,nBins) for iBin in range(1, nBins+1): print iBin, "x=", td.GetBinLowEdge(iBin), " Bin Content = ", td.GetBinContent(iBin), " Percentage=", td.GetBinContent(iBin)/td.Integral(1, nBins)*100 print "-------------------------------------------------------------------- " ''' print " -----------------> Final tEff" #for iBin in range(1,nBins+1): # print iBin, "x=", n.GetBinLowEdge(iBin)," Efficiency=", teff.GetEfficiency(iBin), " Weight = ", teff.GetWeight() return teff
def PlotProb(datasets, numPath, denPath): EfficiencyList = [] index = 0 for dataset in datasets: datasetName = dataset.getName() print "Dataset = ", datasetName statOption = ROOT.TEfficiency.kFNormal ## n = dataset.getDatasetRootHisto(numPath).getHistogram() # n.normalizeToOne() ## d = dataset.getDatasetRootHisto(denPath).getHistogram() nn = dataset.getDatasetRootHisto(numPath) nn.normalizeToLuminosity(35.8 * (10**3)) n = nn.getHistogram() dd = dataset.getDatasetRootHisto(denPath) # dd.normalizeToOne() # dd.normalizeToLuminosity(36.3*(10**3)) dd.normalizeToLuminosity(35.8 * (10**3)) # dd.normalizeByCrossSection() d = dd.getHistogram() # if "TT" in datasetName and ("Higgs" in numPath or "LdgBjetPt_isLdgFreeBjet" in numPath): # continue # elif "M_" in datasetName and not ("Higgs" in numPath or "LdgBjetPt_isLdgFreeBjet" in numPath): # continue if "Event" in numPath: n.Rebin(10) d.Rebin(10) else: n.Rebin(5) d.Rebin(5) if d.GetEntries() == 0 or n.GetEntries() == 0: continue if n.GetEntries() > d.GetEntries(): continue # Check Negatives CheckNegatives(n, d, True) # Remove Negatives RemoveNegatives(n) nBins = d.GetNbinsX() xMin = d.GetXaxis().GetXmin() xMax = d.GetXaxis().GetXmax() binwidth = int(n.GetBinWidth(0)) # ----------------------------------------------------------------------------------------- # # Ugly hack to ignore EMPTY (in the wanted range) histograms with overflows/underflows # ----------------------------------------------------------------------------------------- # if (0): print "\n" print "=========== getEfficiency:" print "Dataset = ", dataset.getName() print "Numerator: entries=", n.GetEntries( ), " Bins=", n.GetNbinsX(), " Low edge=", n.GetBinLowEdge(1) print "Denominator: entries=", d.GetEntries( ), " Bins=", d.GetNbinsX(), " Low edge=", d.GetBinLowEdge(1) print "\n" print ">>>>>> Sanity Check: <<<<<<" print "Numerator Mean = ", n.GetMean() print "Numerator RMS = ", n.GetRMS() print "Numerator Integral = ", n.Integral(1, nBins) print "Denominator Mean = ", d.GetMean() print "Denominator RMS = ", d.GetRMS() print "Denominator Integral = ", d.Integral(1, nBins) if (n.GetMean() == 0 or d.GetMean() == 0): continue if (n.GetRMS() == 0 or d.GetRMS() == 0): continue if (n.Integral(1, nBins) == 0 or d.Integral(1, nBins) == 0): continue # if not (ROOT.TEfficiency.CheckConsistency(n,d)): continue; effic = ROOT.TEfficiency(n, d) effic.SetStatisticOption(statOption) weight = 1 if dataset.isMC(): weight = dataset.getCrossSection() effic.SetWeight(weight) eff = convert2TGraph(effic) # Apply Styles if "TT" in datasetName: if index == 0: styles.signalStyleHToTB500.apply(eff) # styles.ttStyle.apply(eff) eff.SetLineStyle(1) eff.SetLineWidth(3) eff.SetLineColor(619) legend = "Default: t#bar{t}" index = 1 else: styles.signalStyleHToTB500.apply(eff) # styles.ttStyle.apply(eff) eff.SetLineStyle(1) eff.SetLineWidth(3) eff.SetLineColor(417) legend = "#Delta R(q,q')>0.8: t#bar{t}" elif "M_500" in datasetName: styles.signalStyleHToTB500.apply(eff) legend = "H^{+} m_{H^{+}} = 500 GeV" elif "M_300" in datasetName: styles.signalStyleHToTB300.apply(eff) legend = "H^{+} m_{H^{+}} = 300 GeV" elif "M_1000" in datasetName: styles.signalStyleHToTB1000.apply(eff) legend = "H^{+} m_{H^{+}} = 1000 GeV" elif "M_800" in datasetName: styles.signalStyleHToTB800.apply(eff) legend = "H^{+} m_{H^{+}} = 800 GeV" elif "M_200" in datasetName: styles.signalStyleHToTB200.apply(eff) legend = "H^{+} m_{H^{+}} = 200 GeV" else: styles.ttStyle.apply(eff) legend = "other" EfficiencyList.append(histograms.HistoGraph(eff, legend, "lp", "P")) saveName = "Eff_" + numPath.split("/")[-1] + "Over" + denPath.split( "/")[-1] if "Pt" in numPath: xMin = 0.0 # rebinX = 2 xMax = 805.0 # xMax = 555.0 # For topPt < 500GeV xTitle = "p_{T} (GeV/c)" units = "GeV/c" _format = "%0.1f" + units yTitle = "Efficiency / " + str(binwidth) + " " + units yMin = 0.0 yMax = 1.1 elif "_Eta" in numPath: xMin = -3.0 xMax = +3.0 xTitle = "#eta" yTitle = "Efficiency" yMin = 0.0 yMax = 1.1 elif "_Mass" in numPath: xMin = 50.0 xMax = 300 xTitle = "M (GeV/c^{2})" yTitle = "Efficiency" yMin = 0.0 yMax = 1.1 elif "_Phi" in numPath: xMin = -3 xMax = +3 xTitle = "#phi" yTitle = "Efficiency" yMin = 0.0 yMax = 1.1 else: xMin = 0.0 xMax = 250.0 xTitle = "xTitle" yTitle = "yTitle" yMin = 0.0 yMax = 1.1 if "Fake" in numPath: # xMin = 95.0 # rebinX = 4 xMax = 805.0 xTitle = "candidate p_{T} (GeV/c)" units = "GeV/c" _format = "%0.1f" + units yTitle = "Misid rate / " + str(binwidth) + " " + units yMin = 0.0 yMax = 0.11 if "Event" in numPath: rebinX = 2 # xMin = 95.0 xMax = 805.0 xTitle = "candidate p_{T} (GeV/c)" units = "GeV/c" _format = "%0.1f" + units yTitle = "Efficiency / " + str(binwidth) + " " + units yMin = 0.0 yMax = 1.1 if "NonMatched" in numPath: xMin = 90.0 rebinX = 4 xMax = 700.0 xMax = 555.0 # For topPt < 500GeV xTitle = "p_{T} (GeV)" yTitle = "Efficiency" yMin = 0.0 yMax = 0.15 if "AllTopQuarkPt_MatchedBDT" in numPath and "TopQuarkPt" in denPath: xMin = 0.0 # rebinX = 4 xMax = 805.0 #705 units = "GeV/c" xTitle = "generated top p_{T} (GeV/c)" yTitle = "Efficiency / " + str(binwidth) + " " + units yMin = 0.0 yMax = 1.1 if "SameFake" in numPath: xMin = 95.0 rebinX = 4 xMax = 705.0 xMax = 555.0 # For topPt < 500GeV xTitle = "p_{T} [GeV]" yTitle = "Efficiency" yMin = 0.0 yMax = 1.1 options = {"ymin": yMin, "ymax": yMax, "xmin": xMin, "xMax": xMax} # if "TT" in datasetName and ("Higgs" in numPath or "LdgBjetPt_isLdgFreeBjet" in numPath): # return # if "M_" in datasetName and not ("Higgs" in numPath or "LdgBjetPt_isLdgFreeBjet" in numPath): # return p = plots.PlotBase(datasetRootHistos=EfficiencyList, saveFormats=kwargs.get("saveFormats")) #p = plots.ComparisonManyPlot(refEff, EfficiencyList, saveFormats=[]) p.createFrame(saveName, opts=options) # p.histoMgr.forEachHisto(lambda h: h.getRootHisto().RebinX(kwargs.get("rebinX"))) # Set Titles # p.getFrame().GetYaxis().SetTitle(kwargs.get("ylabel")) #"ylabel" p.getFrame().GetXaxis().SetTitle(xTitle) p.getFrame().GetYaxis().SetTitle(yTitle) # Set range p.getFrame().GetXaxis().SetRangeUser(xMin, xMax) moveLegend = {"dx": -0.55, "dy": -0.02, "dh": -0.2} # moveLegend = {"dx": -0.55, "dy": -0.01, "dh": -0.1} p.setLegend(histograms.moveLegend(histograms.createLegend(), **moveLegend)) # Add Standard Texts to plot histograms.addStandardTexts() p.draw() # Save plot in all formats savePath = os.path.join(opts.saveDir, "HplusMasses", numPath.split("/")[0], opts.optMode) save_path = savePath + opts.MVAcut # SavePlot(p, saveName, savePath) SavePlot(p, saveName, save_path) return
def PlotProb(datasets, numPath, denPath): EfficiencyList = [] index = 0 for dataset in datasets: datasetName = dataset.getName() print "Dataset = ", datasetName statOption = ROOT.TEfficiency.kFNormal ## n = dataset.getDatasetRootHisto(numPath).getHistogram() # n.normalizeToOne() ## d = dataset.getDatasetRootHisto(denPath).getHistogram() nn = dataset.getDatasetRootHisto(numPath) nn.normalizeToLuminosity(35.8*(10**3)) n = nn.getHistogram() dd = dataset.getDatasetRootHisto(denPath) # dd.normalizeToOne() # dd.normalizeToLuminosity(36.3*(10**3)) dd.normalizeToLuminosity(35.8*(10**3)) # dd.normalizeByCrossSection() d = dd.getHistogram() # if "TT" in datasetName and ("Higgs" in numPath or "LdgBjetPt_isLdgFreeBjet" in numPath): # continue # elif "M_" in datasetName and not ("Higgs" in numPath or "LdgBjetPt_isLdgFreeBjet" in numPath): # continue if "Event" in numPath: n.Rebin(10) d.Rebin(10) else: n.Rebin(5) d.Rebin(5) if d.GetEntries() == 0 or n.GetEntries() == 0: continue if n.GetEntries() > d.GetEntries(): continue # Check Negatives CheckNegatives(n, d, True) # Remove Negatives RemoveNegatives(n) nBins = d.GetNbinsX() xMin = d.GetXaxis().GetXmin() xMax = d.GetXaxis().GetXmax() binwidth = int(n.GetBinWidth(0)) # ----------------------------------------------------------------------------------------- # # Ugly hack to ignore EMPTY (in the wanted range) histograms with overflows/underflows # ----------------------------------------------------------------------------------------- # if (0): print "\n" print "=========== getEfficiency:" print "Dataset = ", dataset.getName() print "Numerator: entries=", n.GetEntries(), " Bins=", n.GetNbinsX(), " Low edge=", n.GetBinLowEdge(1) print "Denominator: entries=", d.GetEntries(), " Bins=", d.GetNbinsX(), " Low edge=", d.GetBinLowEdge(1) print "\n" print ">>>>>> Sanity Check: <<<<<<" print "Numerator Mean = ", n.GetMean() print "Numerator RMS = ", n.GetRMS() print "Numerator Integral = ", n.Integral(1, nBins) print "Denominator Mean = ", d.GetMean() print "Denominator RMS = ", d.GetRMS() print "Denominator Integral = ", d.Integral(1, nBins) if (n.GetMean() == 0 or d.GetMean() == 0): continue if (n.GetRMS() == 0 or d.GetRMS() == 0): continue if (n.Integral(1,nBins) == 0 or d.Integral(1,nBins) == 0): continue # if not (ROOT.TEfficiency.CheckConsistency(n,d)): continue; effic = ROOT.TEfficiency(n,d) effic.SetStatisticOption(statOption) weight = 1 if dataset.isMC(): weight = dataset.getCrossSection() effic.SetWeight(weight) eff = convert2TGraph(effic) # Apply Styles if "TT" in datasetName: if index == 0: styles.signalStyleHToTB500.apply(eff) # styles.ttStyle.apply(eff) eff.SetLineStyle(1) eff.SetLineWidth(3) eff.SetLineColor(619) legend = "Default: t#bar{t}" index = 1 else: styles.signalStyleHToTB500.apply(eff) # styles.ttStyle.apply(eff) eff.SetLineStyle(1) eff.SetLineWidth(3) eff.SetLineColor(417) legend = "#Delta R(q,q')>0.8: t#bar{t}" elif "M_500" in datasetName: styles.signalStyleHToTB500.apply(eff) legend = "H^{+} m_{H^{+}} = 500 GeV" elif "M_300" in datasetName: styles.signalStyleHToTB300.apply(eff) legend = "H^{+} m_{H^{+}} = 300 GeV" elif "M_1000" in datasetName: styles.signalStyleHToTB1000.apply(eff) legend = "H^{+} m_{H^{+}} = 1000 GeV" elif "M_800" in datasetName: styles.signalStyleHToTB800.apply(eff) legend = "H^{+} m_{H^{+}} = 800 GeV" elif "M_200" in datasetName: styles.signalStyleHToTB200.apply(eff) legend = "H^{+} m_{H^{+}} = 200 GeV" else: styles.ttStyle.apply(eff) legend = "other" EfficiencyList.append(histograms.HistoGraph(eff, legend, "lp", "P")) saveName = "Eff_"+numPath.split("/")[-1]+"Over"+denPath.split("/")[-1] if "Pt" in numPath: xMin = 0.0 # rebinX = 2 xMax = 805.0 # xMax = 555.0 # For topPt < 500GeV xTitle = "p_{T} (GeV/c)" units = "GeV/c" _format = "%0.1f" + units yTitle = "Efficiency / " + str(binwidth) + " "+units yMin = 0.0 yMax = 1.1 elif "_Eta" in numPath: xMin = -3.0 xMax = +3.0 xTitle = "#eta" yTitle = "Efficiency" yMin = 0.0 yMax = 1.1 elif "_Mass" in numPath: xMin = 50.0 xMax = 300 xTitle = "M (GeV/c^{2})" yTitle = "Efficiency" yMin = 0.0 yMax = 1.1 elif "_Phi" in numPath: xMin = -3 xMax = +3 xTitle = "#phi" yTitle = "Efficiency" yMin = 0.0 yMax = 1.1 else: xMin = 0.0 xMax = 250.0 xTitle = "xTitle" yTitle = "yTitle" yMin = 0.0 yMax = 1.1 if "Fake" in numPath: # xMin = 95.0 # rebinX = 4 xMax = 805.0 xTitle = "candidate p_{T} (GeV/c)" units = "GeV/c" _format = "%0.1f" + units yTitle = "Misid rate / " + str(binwidth) + " " +units yMin = 0.0 yMax = 0.11 if "Event" in numPath: rebinX = 2 # xMin = 95.0 xMax = 805.0 xTitle = "candidate p_{T} (GeV/c)" units = "GeV/c" _format = "%0.1f" + units yTitle = "Efficiency / " + str(binwidth) + " "+ units yMin = 0.0 yMax = 1.1 if "NonMatched" in numPath: xMin = 90.0 rebinX = 4 xMax = 700.0 xMax = 555.0 # For topPt < 500GeV xTitle = "p_{T} (GeV)" yTitle = "Efficiency" yMin = 0.0 yMax = 0.15 if "AllTopQuarkPt_MatchedBDT" in numPath and "TopQuarkPt" in denPath: xMin = 0.0 # rebinX = 4 xMax = 805.0 #705 units = "GeV/c" xTitle = "generated top p_{T} (GeV/c)" yTitle = "Efficiency / " + str(binwidth) + " " + units yMin = 0.0 yMax = 1.1 if "SameFake" in numPath: xMin = 95.0 rebinX = 4 xMax = 705.0 xMax = 555.0 # For topPt < 500GeV xTitle = "p_{T} [GeV]" yTitle = "Efficiency" yMin = 0.0 yMax = 1.1 options = {"ymin": yMin , "ymax": yMax, "xmin":xMin, "xMax":xMax} # if "TT" in datasetName and ("Higgs" in numPath or "LdgBjetPt_isLdgFreeBjet" in numPath): # return # if "M_" in datasetName and not ("Higgs" in numPath or "LdgBjetPt_isLdgFreeBjet" in numPath): # return p = plots.PlotBase(datasetRootHistos=EfficiencyList, saveFormats=kwargs.get("saveFormats")) #p = plots.ComparisonManyPlot(refEff, EfficiencyList, saveFormats=[]) p.createFrame(saveName, opts=options) # p.histoMgr.forEachHisto(lambda h: h.getRootHisto().RebinX(kwargs.get("rebinX"))) # Set Titles # p.getFrame().GetYaxis().SetTitle(kwargs.get("ylabel")) #"ylabel" p.getFrame().GetXaxis().SetTitle(xTitle) p.getFrame().GetYaxis().SetTitle(yTitle) # Set range p.getFrame().GetXaxis().SetRangeUser(xMin, xMax) moveLegend = {"dx": -0.55, "dy": -0.02, "dh": -0.2} # moveLegend = {"dx": -0.55, "dy": -0.01, "dh": -0.1} p.setLegend(histograms.moveLegend(histograms.createLegend(), **moveLegend)) # Add Standard Texts to plot histograms.addStandardTexts() p.draw() # Save plot in all formats savePath = os.path.join(opts.saveDir, "HplusMasses", numPath.split("/")[0], opts.optMode) save_path = savePath + opts.MVAcut # SavePlot(p, saveName, savePath) SavePlot(p, saveName, save_path) return
def PlotEfficiency(datasetsMgr, numPath, denPath, intLumi): # Definitions myList = [] myBckList = [] index = 0 _kwargs = GetHistoKwargs(denPath, opts) counter = 0 # For-loop: All datasets for dataset in datasetsMgr.getAllDatasets(): name_N = numPath name_D = denPath # Get the histograms #num = dataset.getDatasetRootHisto(numPath).getHistogram() #den = dataset.getDatasetRootHisto(denPath).getHistogram() #if "TT" in dataset.getName(): # numPath = numPath.replace("HiggsTop", "AllTop") # denPath = denPath.replace("HiggsTop", "AllTop") # numPath = numPath.replace("AssocTop", "AllTop") # denPath = denPath.replace("AssocTop", "AllTop") n = dataset.getDatasetRootHisto(numPath) n.normalizeToLuminosity(intLumi) num = n.getHistogram() d = dataset.getDatasetRootHisto(denPath) d.normalizeToLuminosity(intLumi) den = d.getHistogram() if "binList" in _kwargs: xBins = _kwargs["binList"] nx = len(xBins)-1 num = num.Rebin(nx, "", xBins) den = den.Rebin(nx, "", xBins) for i in range(1, num.GetNbinsX()+1): nbin = num.GetBinContent(i) dbin = den.GetBinContent(i) #print dataset.getName(), nbin, dbin if (nbin > dbin): print "error" # Sanity checks if den.GetEntries() == 0 or num.GetEntries() == 0: continue if num.GetEntries() > den.GetEntries(): continue # Remove negative bins and ensure numerator bin <= denominator bin #CheckNegatives(num, den, False) #CheckNegatives(num, den, True) #RemoveNegatives(num) #RemoveNegatives(den) # Sanity check (Histograms are valid and consistent) - Always false! # if not ROOT.TEfficiency.CheckConsistency(num, den): # continue # Create Efficiency plots with Clopper-Pearson stats eff = ROOT.TEfficiency(num, den) # fixme: investigate warnings eff.SetStatisticOption(ROOT.TEfficiency.kFCP) # # Set the weights - Why is this needed? if 0: weight = 1 if dataset.isMC(): weight = dataset.getCrossSection() eff.SetWeight(weight) # Convert to TGraph eff = convert2TGraph(eff) # Apply default style (according to dataset name) plots._plotStyles[dataset.getName()].apply(eff) # Apply random histo styles and append if "charged" in dataset.getName().lower(): counter +=1 mass = dataset.getName().split("M_")[-1] styles.markerStyles[counter].apply(eff) if "300" in mass or "650" in mass: s = styles.getSignalStyleHToTB_M(mass) s.apply(eff) eff.SetLineStyle(ROOT.kSolid) eff.SetLineWidth(3) eff.SetMarkerSize(1.2) ''' mass = dataset.getName().split("M_")[-1] mass = mass.replace("650", "1000") s = styles.getSignalStyleHToTB_M(mass) s.apply(eff) ''' ''' ttStyle = styles.getEWKLineStyle() if "tt" in dataset.getName().lower(): ttStyle.apply(eff) ''' # Append in list #if "charged" in dataset.getName().lower(): # if "m_500" in dataset.getName().lower(): if 1: #if "tt" in dataset.getName().lower(): if "m_500" in dataset.getName().lower(): eff_ref = histograms.HistoGraph(eff, plots._legendLabels[dataset.getName()], "lp", "P") else: myList.append(histograms.HistoGraph(eff, plots._legendLabels[dataset.getName()], "lp", "P")) #elif "tt" in dataset.getName().lower(): # eff_ref = histograms.HistoGraph(eff, plots._legendLabels[dataset.getName()], "lp", "P") # Define save name saveName = "Eff_" + name_N.split("/")[-1] + "Over"+ name_D.split("/")[-1] # Plot the efficiency #p = plots.PlotBase(datasetRootHistos=myList, saveFormats=[]) p = plots.ComparisonManyPlot(eff_ref, myList, saveFormats=[]) plots.drawPlot(p, saveName, **_kwargs) # Save plot in all formats savePath = os.path.join(opts.saveDir, name_N.split("/")[0], opts.optMode) SavePlot(p, saveName, savePath, saveFormats = [".png", ".C", ".pdf"])#, ".pdf"]) return