def PlotROC(graphMap, saveDir, saveName, saveFormats): ''' Plot ROC curves (signal efficiency vs bkg efficiency) ''' ROOT.gStyle.SetOptStat(0) canvas = plot.CreateCanvas() canvas.cd() leg = plot.CreateLegend(0.25, 0.25, 0.60, 0.45) #0.50, 0.25, 0.85, 0.45 # For-loop: All graphs for i, k in enumerate(graphMap["graph"], 0): gr = graphMap["graph"][i] gr_name = graphMap["name"][i] plot.ApplyStyle(gr, i + 2) gr.GetXaxis().SetTitle("Signal Efficiency") gr.GetYaxis().SetTitle("Misidentification rate") if i == 0: gr.Draw("apl") else: gr.Draw("pl same") leg.AddEntry(gr, gr_name, "l") leg.Draw("same") plot.SavePlot(canvas, saveDir, saveName, saveFormats) canvas.Close() return
def PlotLossFunction(losses, nepochs, saveDir): ''' Plot the loss function vs the number of the epoch ''' def ApplyStyle(h, ymin, ymax, color): h.SetLineColor(color) h.SetMarkerColor(color) h.SetMarkerStyle(8) h.SetMarkerSize(0.6) h.SetMaximum(ymax) h.SetMinimum(ymin) h.GetXaxis().SetTitle("# epoch") h.GetYaxis().SetTitle("Loss") ROOT.gStyle.SetOptStat(0) canvas = ROOT.TCanvas() canvas.cd() leg=plot.CreateLegend(0.6, 0.75, 0.9, 0.85) xarr = [] for i in range(1, nepochs+1): xarr.append(i) if (opt.lam > 0): hLf = ROOT.TGraph(len(xarr), array('d', xarr), array('d', losses["L_f"])) hLr = ROOT.TGraph(len(xarr), array('d', xarr), array('d', losses["L_r"])) hLfr = ROOT.TGraph(len(xarr), array('d', xarr), array('d', losses["L_f - L_r"])) ymax = max(hLf.GetHistogram().GetMaximum(), hLr.GetHistogram().GetMaximum(), hLfr.GetHistogram().GetMaximum()) ymin = min(hLf.GetHistogram().GetMinimum(), hLr.GetHistogram().GetMinimum(), hLfr.GetHistogram().GetMinimum()) ymax = ymax + 1 ymin = ymin - 1 ApplyStyle(hLf, ymin, ymax, ROOT.kRed) ApplyStyle(hLr, ymin, ymax, ROOT.kBlue) ApplyStyle(hLfr, ymin, ymax, ROOT.kGreen+1) hLf.Draw("pa") hLr.Draw("p same") hLfr.Draw("p same") leg.AddEntry(hLf, "L_{c}","pl") leg.AddEntry(hLr,"L_{r}","pl") leg.AddEntry(hLfr,"L_{c} - L_{r}","pl") else: h_loss = ROOT.TGraph(len(xarr), array('d', xarr), array('d', losses["loss"])) ymax = h_loss.GetHistogram().GetMaximum() ymin = h_loss.GetHistogram().GetMinimum() ApplyStyle(h_loss, ymin, ymax, ROOT.kGreen +1) h_loss.Draw("pa") leg.AddEntry(h_loss, "L_{c}","pl") leg.Draw() saveName = "Loss_lam%s_opt%s" %(opt.lam, opt.opt) plot.SavePlot(canvas, saveDir, saveName) canvas.Close() return
def PlotOutput(Y_train, Y_test, saveDir, saveName, isSB, saveFormats): ROOT.gStyle.SetOptStat(0) # Create canvas canvas = plot.CreateCanvas() canvas.cd() canvas.SetLogy() # Create histograms h1 = ROOT.TH1F('train', '', 50, 0.0, 1.0) h2 = ROOT.TH1F('test', '', 50, 0.0, 1.0) # Fill histograms for r in Y_train: h1.Fill(r) for r in Y_test: h2.Fill(r) if 0: h1.Scale(1. / h1.Integral()) h2.Scale(1. / h2.Integral()) ymax = max(h1.GetMaximum(), h2.GetMaximum()) plot.ApplyStyle(h1, ROOT.kMagenta + 1) plot.ApplyStyle(h2, ROOT.kGreen + 2) for h in [h1, h2]: h.SetMinimum(100) h.SetMaximum(ymax * 1.1) h.GetXaxis().SetTitle("Output") h.GetYaxis().SetTitle("Entries") h.Draw("HIST SAME") # What is this for? Ask soti graph = plot.CreateGraph([0.5, 0.5], [0, ymax * 1.1]) graph.Draw("same") # Create legend leg = plot.CreateLegend(0.6, 0.75, 0.9, 0.85) if isSB: leg.AddEntry(h1, "signal", "l") leg.AddEntry(h2, "background", "l") else: leg.AddEntry(h1, "train", "l") leg.AddEntry(h2, "test", "l") leg.Draw() plot.SavePlot(canvas, saveDir, saveName, saveFormats) canvas.Close() return
def PlotTGraph(xVals, xErrs, yVals, yErrs, saveDir, saveName, jsonWr, saveFormats): # Create a TGraph object graph = plot.GetGraph(xVals, yVals, xErrs, xErrs, yErrs, yErrs) # Create a TCanvas object ROOT.gStyle.SetOptStat(0) canvas = plot.CreateCanvas() canvas.cd() #canvas.SetLogy() # Create the TGraph with asymmetric errors tgraph = ROOT.TGraphAsymmErrors(len(xVals), array.array("d", xVals), array.array("d", yVals), array.array("d", xErrs), array.array("d", xErrs), array.array("d", yErrs), array.array("d", yErrs)) tgraph.SetName(saveName) if "efficiency" in saveName.lower(): legName = "efficiency" if saveName.lower().endswith("sig"): plot.ApplyStyle(tgraph, ROOT.kBlue) else: plot.ApplyStyle(tgraph, ROOT.kRed) elif "significance" in saveName.lower(): legName = "significance" if saveName.lower().endswith("sig"): plot.ApplyStyle(tgraph, ROOT.kGreen) else: plot.ApplyStyle(tgraph, ROOT.kGreen + 3) else: plot.ApplyStyle(tgraph, ROOT.kOrange) # Draw the TGraph tgraph.GetXaxis().SetLimits(-0.05, 1.0) #tgraph.SetMaximum(1.1) #tgraph.SetMinimum(0) tgraph.Draw("AC") # Create legend leg = plot.CreateLegend(0.60, 0.70, 0.85, 0.80) leg.AddEntry(tgraph, legName, "l") leg.Draw() plot.SavePlot(canvas, saveDir, saveName, saveFormats) canvas.Close() # Write the Tgraph into the JSON file jsonWr.addGraph(saveName, tgraph) return
def PlotInputs(signal, bkg, var, saveDir, saveFormats): ROOT.gStyle.SetOptStat(0) # Create canvas canvas = plot.CreateCanvas() canvas.cd() info = plot.GetHistoInfo(var) # Create histograms hsignal = ROOT.TH1F('signal', '', info["nbins"], info["xmin"], info["xmax"]) hbkg = ROOT.TH1F('bkg', '', info["nbins"], info["xmin"], info["xmax"]) # Fill histograms for r in signal: hsignal.Fill(r) for r in bkg: hbkg.Fill(r) if 1: hsignal.Scale(1. / hsignal.Integral()) hbkg.Scale(1. / hbkg.Integral()) ymax = max(hsignal.GetMaximum(), hbkg.GetMaximum()) plot.ApplyStyle(hsignal, ROOT.kAzure - 3) hsignal.SetFillColor(ROOT.kAzure - 3) plot.ApplyStyle(hbkg, ROOT.kRed + 2) for h in [hsignal, hbkg]: h.SetMaximum(ymax * 1.2) h.GetXaxis().SetTitle(info["xlabel"]) h.GetYaxis().SetTitle(info["ylabel"]) hsignal.Draw("HIST") hbkg.Draw("HIST SAME") # Create legend leg = plot.CreateLegend(0.6, 0.75, 0.9, 0.85) leg.AddEntry(hsignal, "Truth-matched", "f") #"pl" leg.AddEntry(hbkg, "Unmatched", "l") #"pl" leg.Draw() plot.SavePlot(canvas, saveDir, var, saveFormats, True) canvas.Close() return
def PlotOvertrainingTest(Y_train_S, Y_test_S, Y_train_B, Y_test_B, saveDir, saveName, saveFormats): def ApplyStyle(histo): if "_s" in histo.GetName(): color = ROOT.kBlue else: color = ROOT.kRed plot.ApplyStyle(h, color) histo.SetMarkerSize(0.5) histo.GetXaxis().SetTitle("Output") histo.GetYaxis().SetTitle("Entries") histo.SetMinimum(10) return def GetLegendStyle(histoName): if "test" in histoName: legStyle = "f" if "_s" in histoName: legText = "signal (test)" else: legText = "background (test)" elif "train" in histoName: legStyle = "p" if "_s" in histoName: legText = "signal (train)" else: legText = "background (train)" return legText, legStyle def DrawStyle(histoName): if "train" in histoName: _style = "P" else: _style = "HIST" return _style ROOT.gStyle.SetOptStat(0) canvas = plot.CreateCanvas() canvas.cd() canvas.SetLogy() hList = [] DataList = [Y_train_S, Y_test_S, Y_train_B, Y_test_B] ymax = 0 nbins = 500 # Create the histograms htrain_s = ROOT.TH1F('train_s', '', nbins, 0.0, 1.0) htest_s = ROOT.TH1F('test_s', '', nbins, 0.0, 1.0) htrain_b = ROOT.TH1F('train_b', '', nbins, 0.0, 1.0) htest_b = ROOT.TH1F('test_b', '', nbins, 0.0, 1.0) # Append to list hList.append(htrain_s) hList.append(htest_s) hList.append(htrain_b) hList.append(htest_b) for i in range(len(DataList)): for r in DataList[i]: hList[i].Fill(r) # Clone the histograms htrain_s1 = htrain_s.Clone("train_s") htrain_b1 = htrain_b.Clone("train_b") htest_s1 = htest_s.Clone("test_s") htest_b1 = htest_b.Clone("test_b") drawStyle = "HIST SAME" leg = plot.CreateLegend(0.55, 0.68, 0.85, 0.88) for h in hList: h.Rebin(10) # Legend legText, legStyle = GetLegendStyle(h.GetName()) leg.AddEntry(h, legText, legStyle) ApplyStyle(h) ymax = max(htrain_s.GetMaximum(), htest_s.GetMaximum(), htrain_b.GetMaximum(), htest_b.GetMaximum()) for h in hList: h.SetMaximum(ymax * 2) h.Draw(DrawStyle(h.GetName()) + " SAME") #graph = plot.CreateGraph([0.5, 0.5], [0, ymax*2]) #graph.Draw("same") #leg.Draw() # Save & close canvas plot.SavePlot(canvas, saveDir, saveName, saveFormats) canvas.Close() return htrain_s1, htest_s1, htrain_b1, htest_b1
def PlotEfficiency(htest_s, htest_b, saveDir, saveName, saveFormats): ROOT.gStyle.SetOptStat(0) canvas = plot.CreateCanvas() canvas.cd() canvas.SetLeftMargin(0.145) canvas.SetRightMargin(0.11) # Calculate signal and background efficiency vs output xvalue, eff_s, eff_b, error = CalcEfficiency(htest_s, htest_b) graph_s = plot.GetGraph(xvalue, eff_s, error, error, error, error) graph_b = plot.GetGraph(xvalue, eff_b, error, error, error, error) plot.ApplyStyle(graph_s, ROOT.kBlue) plot.ApplyStyle(graph_b, ROOT.kRed) # Calculate significance vs output h_signif0, h_signif1 = CalcSignificance(htest_s, htest_b) plot.ApplyStyle(h_signif0, ROOT.kGreen) plot.ApplyStyle(h_signif1, ROOT.kGreen + 3) #=== Get maximum of significance maxSignif0 = h_signif0.GetMaximum() maxSignif1 = h_signif1.GetMaximum() maxSignif = max(maxSignif0, maxSignif1) # Normalize significance h_signifScaled0 = h_signif0.Clone("signif0") h_signifScaled0.Scale(1. / float(maxSignif)) h_signifScaled1 = h_signif1.Clone("signif1") h_signifScaled1.Scale(1. / float(maxSignif)) #Significance: Get new maximum ymax = max(h_signifScaled0.GetMaximum(), h_signifScaled1.GetMaximum()) for obj in [graph_s, graph_b, h_signifScaled0, h_signifScaled1]: obj.GetXaxis().SetTitle("Output") obj.GetYaxis().SetTitle("Efficiency") obj.SetMaximum(ymax * 1.1) obj.SetMinimum(0) #Draw h_signifScaled0.Draw("HIST") h_signifScaled1.Draw("HIST SAME") graph_s.Draw("PL SAME") graph_b.Draw("PL SAME") graph = plot.CreateGraph([0.5, 0.5], [0, ymax * 1.1]) graph.Draw("same") #Legend leg = plot.CreateLegend(0.50, 0.25, 0.85, 0.45) leg.AddEntry(graph_s, "Signal Efficiency", "l") leg.AddEntry(graph_b, "Bkg Efficiency", "l") leg.AddEntry(h_signifScaled0, "S/#sqrt{S+B}", "l") leg.AddEntry(h_signifScaled1, "2#times(#sqrt{S+B} - #sqrt{B})", "l") leg.Draw() # Define Right Axis (Significance) signifColor = ROOT.kGreen + 2 rightAxis = ROOT.TGaxis(1, 0, 1, 1.1, 0, 1.1 * maxSignif, 510, "+L") rightAxis.SetLineColor(signifColor) rightAxis.SetLabelColor(signifColor) rightAxis.SetTitleColor(signifColor) rightAxis.SetTitleOffset(1.25) rightAxis.SetLabelOffset(0.005) rightAxis.SetLabelSize(0.04) rightAxis.SetTitleSize(0.045) rightAxis.SetTitle("Significance") rightAxis.Draw() plot.SavePlot(canvas, saveDir, saveName, saveFormats) canvas.Close() return
def PlotAndWriteJSON(signal, bkg, saveDir, saveName, jsonWr, saveFormats, **kwargs): resultsDict = {} resultsDict["signal"] = signal resultsDict["background"] = bkg normalizeToOne = False if "normalizeToOne" in kwargs: normalizeToOne = kwargs["normalizeToOne"] # Create canvas ROOT.gStyle.SetOptStat(0) canvas = plot.CreateCanvas() canvas.cd() hList = [] gList = [] yMin = 100000 yMax = -1 xMin = 0.0 xMax = 1.0 nBins = 50 xTitle = "DNN output" yTitle = "Entries" log = True if "log" in kwargs: log = kwargs["log"] if "xTitle" in kwargs: xTitle = kwargs["xTitle"] if "yTitle" in kwargs: yTitle = kwargs["yTitle"] elif "output" in saveName.lower(): xTitle = "Entries" elif "efficiency" in saveName.lower(): xTitle = "Efficiency" elif "significance" in saveName.lower(): xTitle = "Significance" else: pass if "xMin" in kwargs: xMin = kwargs['xMin'] if "xMax" in kwargs: xMax = kwargs['xMax'] if "nBins" in kwargs: xBins = kwargs['nBins'] # For-loop: for i, key in enumerate(resultsDict.keys(), 0): h = ROOT.TH1F(key, '', nBins, xMin, xMax) for j, x in enumerate(resultsDict[key], 0): h.Fill(x) try: yMin = min(x[0], yMin) except: pass # Save maximum yMax = max(h.GetMaximum(), yMax) # Customise & append to list plot.ApplyStyle(h, i + 1) if normalizeToOne: if "ymax" in kwargs: yMax = kwargs["yMax"] else: yMax = 1.0 if "yMin" in kwargs: yMin = kwargs["yMin"] else: yMin = 1e-4 if h.Integral() > 0.0: h.Scale(1. / h.Integral()) hList.append(h) if yMin <= 0.0: yMin = 100 if log: canvas.SetLogy() # For-loop: All histograms for i, h in enumerate(hList, 0): h.SetMinimum(yMin * 0.85) h.SetMaximum(yMax * 1.15) h.GetXaxis().SetTitle(xTitle) h.GetYaxis().SetTitle(yTitle) if i == 0: h.Draw("HIST") else: h.Draw("HIST SAME") # Create legend leg = plot.CreateLegend(0.6, 0.75, 0.9, 0.85) for h in hList: leg.AddEntry(h, h.GetName(), "l") leg.Draw() plot.SavePlot(canvas, saveDir, saveName, saveFormats) canvas.Close() # Create TGraph for h in hList: gList.append(convertHistoToGaph(h)) # Write the Tgraph into the JSON file for gr in gList: gName = "%s_%s" % (saveName, gr.GetName()) jsonWr.addGraph(gName, gr) return
def main(): ROOT.gStyle.SetOptStat(0) # Apply tdr style style = tdrstyle.TDRStyle() style.setOptStat(False) style.setGridX(False) style.setGridY(False) # Definitions filename = opts.filename tfile = ROOT.TFile.Open(filename) dName = "" if ("TT" in filename): dName = "TT" elif ("QCD" in filename): dName = "QCD" #Signal and background branches signal = uproot.open(filename)["treeS"] background = uproot.open(filename)["treeB"] # Input list inputList = [] inputList.append("TrijetPtDR") inputList.append("TrijetDijetPtDR") inputList.append("TrijetBjetMass") inputList.append("TrijetLdgJetBDisc") inputList.append("TrijetSubldgJetBDisc") inputList.append("TrijetBJetLdgJetMass") inputList.append("TrijetBJetSubldgJetMass") inputList.append("TrijetMass") inputList.append("TrijetDijetMass") inputList.append("TrijetBJetBDisc") inputList.append("TrijetSoftDrop_n2") inputList.append("TrijetLdgJetCvsL") inputList.append("TrijetSubldgJetCvsL") inputList.append("TrijetLdgJetPtD") inputList.append("TrijetSubldgJetPtD") inputList.append("TrijetLdgJetAxis2") inputList.append("TrijetSubldgJetAxis2") inputList.append("TrijetLdgJetMult") inputList.append("TrijetSubldgJetMult") nInputs = len(inputList) #Signal and background dataframes df_signal = signal.pandas.df(inputList) df_background = background.pandas.df(inputList) # Number of events to predict the output and plot the top-quark mass if (opts.plotSignal): nEvts = len(df_signal.index) else: nEvts = len(df_background.index) # User few events for testing if (opts.test): nEvts = 1000 print "=== Number of events: ", nEvts #Signal and background datasets dset_signal = df_signal.values dset_background = df_background.values # Concat signal, background datasets df_list = [df_signal, df_background] df_all = pandas.concat(df_list) dataset = df_all.values # Target (top-quark mass) datasets dset_target_all = pandas.concat([ signal.pandas.df(["TrijetMass"]), background.pandas.df(["TrijetMass"]) ]).values dset_target_bkg = background.pandas.df(["TrijetMass"]).values dset_target_signal = signal.pandas.df(["TrijetMass"]).values # Signal and background inputs X_signal = dset_signal[:nEvts, 0:nInputs] X_background = dset_background[:nEvts, 0:nInputs] if (opts.plotSignal): X = dset_signal[:nEvts, 0:nInputs] target = dset_target_signal[:nEvts, :] else: X = dset_background[:nEvts, 0:nInputs] target = dset_target_bkg[:nEvts, :] #Load models lamValues = [0, 1, 5, 10, 20] #, 100, 500] # fixme! should be given as option colors = [ ROOT.kBlack, ROOT.kBlue, ROOT.kMagenta, ROOT.kOrange, ROOT.kRed, ROOT.kGreen, ROOT.kOrange + 7 ] canvas = plot.CreateCanvas() canvas.cd() ymaxFactor = 1.1 ymax = 0 histoList = [] if (opts.setLogY): canvas.SetLogy() ymaxFactor = 2 # load the models with different lambda for lam in lamValues: print "Lambda = ", lam if (lam == 0): # For labda = 0 load the simple classification (sequential) model loaded_model = load_model( 'models_16Nov/Model_relu_relu_relu_sigmoid.h5') else: loaded_model = load_model( 'models_16Nov/modelANN_32_Adam_0p0008_500_tanh_relu_msle_lam%s.h5' % (lam)) # Compile the model loaded_model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['acc']) Y = loaded_model.predict(X, verbose=1) # Concatenate Y (predicted output) and target (top-quark mass) # Ymass 0 column: output # Ymass 1st column: top-quark mass Ymass = numpy.concatenate((Y, target), axis=1) # Get selected top candidates (pass the output working point) Ymass_sel = Ymass[Ymass[:, 0] >= opts.wp] # Select samples with y > WP (col 0) massSel = Ymass_sel[:, 1] # Get the top-quark mass (col 1) for the selected samples. #Plot resutls nbins = 100 xmin = 0 xmax = 1000 # Change x-axis range when plotting the signal if (opts.plotSignal): nbins = 45 xmax = 450 width = float(xmax) / nbins histo = ROOT.TH1F('histo_lam%s' % (lam), '', nbins, xmin, xmax) mass_sel = [] print "selected entries:", len(massSel) for mass in massSel: histo.Fill(mass) histoList.append(histo.Clone("histoClone_lam%s" % lam)) del loaded_model # Create legend leg = plot.CreateLegend(0.6, 0.67, 0.9, 0.85) #Legend text dText = dName dText = dText.replace("TT", "t#bar{t}") # Loop over the histograms in the histoList for i in range(len(histoList)): leg.AddEntry(histoList[i], "%s (#lambda = %.0f)" % (dText, lamValues[i]), "f") # Normalize histograms to unity histoList[i].Scale(1. / (histoList[i].Integral())) ymax = max(ymax, histoList[i].GetMaximum()) histoList[i].GetXaxis().SetTitle("m_{top} (GeV)") histoList[i].GetYaxis().SetTitle("Arbitrary Units / %.0f GeV" % (width)) plot.ApplyStyle(histoList[i], colors[i]) histoList[i].Draw("HIST same") for i in range(len(histoList)): histoList[i].SetMaximum(ymax * ymaxFactor) leg.Draw("same") if (opts.plotSignal): sbText = "truth-matched" else: sbText = "unmatched" # Additional text tex1 = plot.Text(" %s top candidates" % sbText, 0.85, 0.5) tex2 = plot.Text(" with output value > %s" % (opts.wp), 0.82, 0.45) #Draw text tex1.Draw() tex2.Draw() # Draw line to indicate the real value of the top-quark mass graph = plot.CreateGraph([173., 173.], [0, ymax * ymaxFactor]) graph.Draw("same") # CMS extra text and lumi text #plot.CMSText("CMS Preliminary") #Fixme! cmsExtra doesn't work #cmsText.Draw() # Output directory dirName = plot.getDirName(opts.saveDir) # Save the plot saveName = opts.saveName if (opts.saveName == "TopMassANN"): saveName = "TopMassANN_%s_%s" % (dName, sbText.replace("-", "_")) # Save the histogram plot.SavePlot(canvas, dirName, saveName)
def PlotAndWriteJSON(signal, bkg, saveDir, saveName, jsonWr, saveFormats): resultsDict = {} resultsDict["signal"] = signal resultsDict["background"] = bkg # Create canvas ROOT.gStyle.SetOptStat(0) canvas = plot.CreateCanvas() canvas.cd() hList = [] gList = [] yMin = 100000 yMax = -1 # For-loop: for i, key in enumerate(resultsDict.keys(), 0): h = ROOT.TH1F(key, '', 50, 0.0, 1.0) for j, x in enumerate(resultsDict[key], 0): h.Fill(x) try: yMin = min(x[0], yMin) except: pass # Save maximum yMax = max(h.GetMaximum(), yMax) # Customise & append to list plot.ApplyStyle(h, i + 1) hList.append(h) if yMin <= 0.0: yMin = 100 canvas.SetLogy() # For-loop: All histograms for i, h in enumerate(hList, 0): h.SetMinimum(yMin * 0.85) h.SetMaximum(yMax * 1.15) h.GetXaxis().SetTitle("DNN output") if "output" in saveName.lower(): h.GetYaxis().SetTitle("Entries") elif "efficiency" in saveName.lower(): h.GetYaxis().SetTitle("Efficiency") elif "significance" in saveName.lower(): h.GetYaxis().SetTitle("Significance") else: pass if i == 0: h.Draw("HIST") else: h.Draw("HIST SAME") # Create legend leg = plot.CreateLegend(0.6, 0.75, 0.9, 0.85) for h in hList: leg.AddEntry(h, h.GetName(), "l") leg.Draw() plot.SavePlot(canvas, saveDir, saveName, saveFormats) canvas.Close() # Create TGraph for h in hList: gList.append(convertHistoToGaph(h)) # Write the Tgraph into the JSON file for gr in gList: gName = "%s_%s" % (saveName, gr.GetName()) jsonWr.addGraph(gName, gr) return