class TrendPlot: def __init__(self, section, config, cache = None): from ROOT import MakeNullPointer, TH1, TFile,TObject from array import array self.__config = config self.__section = section self.__cache = cache #self.__allReferenceRunNrs = sorted([int(i) for i in self.__config.get("reference","runs").split(",")]) #self.__reference = None self.__threshold = int(self.__config.get("styleDefaults","histoThreshold")) if self.__config.has_option(self.__section,"threshold"): self.__threshold = int(self.__config.get(self.__section,"threshold")) metricString = "metrics."+self.__config.get(self.__section,"metric") metrics =__import__(".".join(metricString.split("(")[0].split(".")[:-1])) self.__metric = eval( metricString) self.__metric.setThreshold( self.__threshold ) self.__metric.setCache( self.__cache ) self.__title = self.__section.split("plot:")[1] if self.__config.has_option(self.__section,"title"): self.__title = self.__config.get(self.__section,"title") self.__xTitle ="" # this is automatically generated later self.__yTitle = metricString #.split("(")[0].split(".")[-1].split("(")[0] self.__saveHistos = metricString #.split("(")[0].split(".")[-1].split("(")[0] if self.__config.has_option(self.__section,"yTitle"): self.__yTitle = self.__config.get(self.__section,"yTitle") if self.__config.has_option(self.__section,"saveHistos"): self.__saveHistos = self.__config.get(self.__section,"saveHistos") self.__x = array("d") self.__y = array("d") self.__yErrHigh = array("d") self.__yErrLow = array("d") self.__ySysErrHigh = array("d") self.__ySysErrLow = array("d") self.__count = 0 self.__runs = [] self.__histoSum = MakeNullPointer(TH1) self.__FileHisto=MakeNullPointer(TFile) self.__labels = [] def __addAnnotaion(self,run, x, y, yErr): from math import sqrt, fabs #(refY, refYErr) = self.__metric(self.__reference[1]) #err = sqrt(yErr[0]**2+refYErr[1]**2) #if refY > y: # err = sqrt(yErr[1]**2+refYErr[0]**2) #significance = fabs(y-refY)/err if not err == 0 else 0. err=0 significance=0 if significance > float(self.__config.get("styleDefaults","significanceThreshold")): self.__labels.append((x,y," %s %.2f#sigma"%(run,significance))) if y < float(self.__config.get("styleDefaults","ksThreshold")) and 'Kolmogorov' in self.__yTitle: self.__labels.append((x,y," %s ks=%.2f"%(run,y))) if self.__config.has_option(self.__section,"yMin") and self.__config.has_option(self.__section,"yMax") : yMin = float(self.__config.get(self.__section,"yMin")) yMax = float(self.__config.get(self.__section,"yMax")) yDelta = yMax-yMin #TOMAS - COMMENTED OUT the vertical out-of-range labels #if y < yMin : self.__labels.append((x,yMin+0.05*yDelta,"run %s, value=%.2f"%(run,y))) #if y > yMax : self.__labels.append((x,yMax-0.40*yDelta,"run %s, value=%.2f"%(run,y))) def drawAnnotation(self): from ROOT import TLatex latex = TLatex() latex.SetTextSize(float(self.__config.get("styleDefaults","annotationSize"))) latex.SetTextColor(int(self.__config.get("styleDefaults","annotationColor"))) if self.__config.has_option("styleDefaults","annotationAngle"): latex.SetTextAngle(float(self.__config.get("styleDefaults","annotationAngle"))) for label in self.__labels: latex.DrawLatex(*label) def addRun(self, serverUrl, runNr, dataset): from math import sqrt from ROOT import TH1,TFile,TObject # import ROOT import os, sys, string self.__count = self.__count + 1 histoPath = self.__config.get(self.__section, "relativePath") print "in addRun, histoPath = ", histoPath #refNr = self.__allReferenceRunNrs[-1] #if len(self.__allReferenceRunNrs) > 1: # #refNr = [i for i in self.__allReferenceRunNrs if i <= runNr][-1] # refNr=min(self.__allReferenceRunNrs) # for refRunNr in self.__allReferenceRunNrs: # if refRunNr>refNr and refRunNr<runNr: # refNr = refRunNr # print "refNr = " , refNr #if self.__reference == None or refNr > self.__reference[0]: # print "refNr = " , refNr # print "getting histo from DQM for ref run" # #refHisto = getHistoFromDQM( serverUrl, refNr, dataset, histoPath) # #self.__reference = (refNr, refHisto) # #self.__metric.setReference( self.__reference[1] ) cacheLocation = (serverUrl, runNr, dataset, histoPath, self.__config.get(self.__section,"metric")) print "cachelocation = ", cacheLocation print "dataset = ", dataset if self.__config.has_option(self.__section, "saveHistos"): try: histo1 = getHistoFromDQM( serverUrl, runNr, dataset, histoPath) histosFile = self.__config.get(self.__section, "saveHistos") if not os.path.exists(histosFile): os.makedirs(histosFile) if self.__histoSum==None: self.__histoSum=histo1 self.__FileHisto=TFile.Open(os.path.join("%s/SumAll_%s.root"%(histosFile,self.__title)),"RECREATE") self.__histoSum.Write() else: self.__histoSum.Add(histo1) self.__FileHisto.cd() self.__histoSum.Write("",TObject.kOverwrite) histo1.SetName(str(runNr)) histo1.Write() except StandardError as msg : print "WARNING: something went wrong getting the histogram ", runNr, msg try: if self.__cache == None or cacheLocation not in self.__cache: histo = getHistoFromDQM( serverUrl, runNr, dataset, histoPath) Entr=0 Entr=histo.GetEntries() print "############### GOT HISTO #################" y=0 yErr = (0.0,0.0) if Entr>self.__threshold: (y, yErr) = self.__metric(histo, cacheLocation) else: self.__cache[cacheLocation] = ((0.,0.),0.) elif cacheLocation in self.__cache: (y, yErr) = self.__metric(None, cacheLocation) except StandardError as msg : print "WARNING: something went wrong calculating", self.__metric, msg self.__count = self.__count - 1 return ySysErr = (0.,0.) if self.__config.has_option(self.__section, "relSystematic"): fraction = self.__config.getfloat(self.__section, "relSystematic") ySysErr = (fraction*y, fraction*y) if self.__config.has_option(self.__section, "absSystematic"): component = self.__config.getfloat(self.__section, "absSystematic") ySysErr = (component, component) self.__config.get(self.__section, "relativePath") self.__y.append(y) ##To turn off Errors, uncomment below... ##yErr = (0.0,0.0) ##ySysErr = (0.0,0.0) self.__yErrLow.append(yErr[0]) self.__yErrHigh.append(yErr[1]) self.__ySysErrLow.append(sqrt(yErr[0]**2+ySysErr[0]**2)) self.__ySysErrHigh.append(sqrt(yErr[1]**2+ySysErr[1]**2)) self.__runs.append(runNr) if self.__config.has_option(self.__section,"xMode"): xMode = self.__config.get(self.__section,"xMode") elif self.__config.has_option("styleDefaults","xMode"): xMode = self.__config.get("styleDefaults","xMode") else: xMode = "counted" if xMode == "runNumber": self.__x.append(run) print "*** appending run to x" self.__xTitle = "Run No." elif xMode == "runNumberOffset": runOffset = int(self.__config.get(self.__section,"runOffset")) self.__x.append(run - runOffset) self.__xTitle = "Run No. - %s"%runOffset elif xMode == "counted": self.__x.append(self.__count) self.__xTitle = "Nth processed run" elif xMode.startswith("runNumberEvery") or xMode.startswith("runNumbers"): self.__x.append(self.__count) self.__xTitle = "Run No." else: raise StandardError, "Unknown xMode: %s in %s"%(xMode, self__section) self.__addAnnotaion(runNr,self.__x[-1],y,(sqrt(yErr[0]**2+ySysErr[0]**2),sqrt(yErr[1]**2+ySysErr[1]**2))) def getName(self): return self.__section.split("plot:")[1] def getGraph(self,dset): from array import array from ROOT import TMultiGraph, TLegend, TGraphAsymmErrors n = len(self.__x) if n != len(self.__y) or n != len(self.__yErrLow) or n != len(self.__yErrHigh): raise StandardError, "The length of the x(%s), y(%s) and y error(%s,%s) lists does not match"%(len(self.__x), len(self.__y), len(self.__yErrLow), len(self.__yErrHigh)) result = TMultiGraph() legendPosition = [float(i) for i in self.__getStyleOption("legendPosition").split()] legend = TLegend(*legendPosition) legend.SetFillColor(0) result.SetTitle("%s;%s;%s"%(self.__title,self.__xTitle,self.__yTitle)) #(refArrays, refLabel) = self.__getRefernceGraphArrays() #refGraph = TGraphAsymmErrors(*refArrays) #refGraph.SetLineWidth(2) #refGraph.SetLineColor(int(self.__config.get("reference","lineColor"))) #refGraph.SetFillColor(int(self.__config.get("reference","fillColor"))) #result.Add(refGraph,"L3") #legend.AddEntry(refGraph,self.__config.get("reference","name")) xErr = array("d",[0 for i in range(n)]) print "__x = ", self.__x print "__y = ", self.__y lst = [] for inc in range (0,n): d={} d['run']=self.__runs[inc] d['x']=self.__x[inc] d['y']=self.__y[inc] d['yErr']=self.__yErrLow[inc] d['yTitle']=self.__yTitle if self.__config.has_option(self.__section,"yMin") and self.__config.has_option(self.__section,"yMax") : d['ymin']=float(self.__config.get(self.__section,"yMin")) d['ymax']=float(self.__config.get(self.__section,"yMax")) else: d['ymin']=0 d['ymax']=0 lst.append(d) obj ={} obj[self.__title]=lst #finalObj[self.__title]=lst #finalList.append(finalObj) # save_path = './JSON_A/' #completeName = os.path.join(save_path, self.__title+".json") if not os.path.exists("JSON_RECO"): os.makedirs("JSON_RECO") if not os.path.exists("JSON_RECO/"+dset): os.makedirs("JSON_RECO/"+dset) with open("./JSON_RECO/"+dset+"/"+self.__title+".json", 'w') as outfile: json.dump(obj, outfile,indent=4) print json.dumps(obj,indent=2) graph = TGraphAsymmErrors(n, self.__x, self.__y, xErr, xErr, self.__yErrLow,self.__yErrHigh) graph.SetLineWidth(2) graph.SetFillColor(0) graph.SetLineColor(int(self.__getStyleOption("lineColor"))) graph.SetMarkerColor(int(self.__getStyleOption("markerColor"))) graph.SetMarkerStyle(int(self.__getStyleOption("markerStyle"))) graph.SetMarkerSize(float(self.__getStyleOption("markerSize"))) sysGraph = TGraphAsymmErrors(n, self.__x, self.__y, xErr, xErr, self.__ySysErrLow,self.__ySysErrHigh) sysGraph.SetLineWidth(1) sysGraph.SetFillColor(0) sysGraph.SetLineColor(int(self.__getStyleOption("lineColor"))) sysGraph.SetMarkerColor(int(self.__getStyleOption("markerColor"))) sysGraph.SetMarkerStyle(int(self.__getStyleOption("markerStyle"))) sysGraph.SetMarkerSize(float(self.__getStyleOption("markerSize"))) #TOMAS removed sys error from the plot #result.Add(sysGraph,"[]") result.Add(graph,"P") # result.SetName("MultiPlots") # result.SetTitle("%s;%s;%s"%(self.__title,self.__xTitle,self.__yTitle)) result.SetName("MG_%s"%(self.__title)) legend.AddEntry(graph, self.__getStyleOption("name")) #for (x,y,yErr) in zip(self.__x, self.__y, zip(self.__yErrLow,self.__yErrHigh)): # self.__addAnnotaion("hallo",x,y,yErr) return (result, legend) #return (graph, legend) #return (result, legend, refLabel) def getGraphSimple(self): from array import array from ROOT import TMultiGraph, TLegend, TGraphAsymmErrors n = len(self.__x) if n != len(self.__y) or n != len(self.__yErrLow) or n != len(self.__yErrHigh): raise StandardError, "The length of the x(%s), y(%s) and y error(%s,%s) lists does not match"%(len(self.__x), len(self.__y), len(self.__yErrLow), len(self.__yErrHigh)) legendPosition = [float(i) for i in self.__getStyleOption("legendPosition").split()] legend = TLegend(*legendPosition) legend.SetFillColor(0) xErr = array("d",[0 for i in range(n)]) print "__x = ", self.__x print "__y = ", self.__y graph = TGraphAsymmErrors(n, self.__x, self.__y, xErr, xErr, self.__yErrLow,self.__yErrHigh) graph.SetTitle("%s;%s;%s"%(self.__title,self.__xTitle,self.__yTitle)) graph.SetLineWidth(2) graph.SetFillColor(0) graph.SetLineColor(int(self.__getStyleOption("lineColor"))) graph.SetMarkerColor(int(self.__getStyleOption("markerColor"))) graph.SetMarkerStyle(int(self.__getStyleOption("markerStyle"))) graph.SetMarkerSize(float(self.__getStyleOption("markerSize"))) graph.SetDrawOption("AP") return (graph, legend) def getHISTO(self): from array import array from ROOT import TMultiGraph, TLegend, TGraphAsymmErrors from ROOT import TH1,TH1F,TAxis from math import sqrt n = len(self.__x) if n != len(self.__y) or n != len(self.__yErrLow): raise StandardError, "The length of the x(%s), y(%s) and y error(%s,%s) lists does not match"%(len(self.__x), len(self.__y), len(self.__yErrLow), len(self.__yErrHigh)) result=TH1F(self.__title,self.__title,n,0.5,float(n)+0.5) axis = result.GetXaxis() for i in range (len(self.__x)): result.Fill(i+1,self.__y[i]) result.SetBinError(i+1,self.__yErrHigh[i]) #axis.SetBinLabel(i+1, str(self.__x[i])) axis.SetBinLabel(i+1, str(self.__runs[i])) # result = MakeNullPointer(TH1) legendPosition = [float(i) for i in self.__getStyleOption("legendPosition").split()] legend = TLegend(*legendPosition) legend.SetFillColor(0) result.SetMarkerColor(int(self.__getStyleOption("markerColor"))) result.SetMarkerStyle(int(self.__getStyleOption("markerStyle"))) result.SetMarkerSize(float(self.__getStyleOption("markerSize"))) result.SetTitle("%s;%s;%s"%(self.__title,self.__xTitle,self.__yTitle)) return (result, legend) def formatGraphAxis(self, graph): if self.__config.has_option(self.__section,"xMode"): xMode = self.__config.get(self.__section,"xMode") elif self.__config.has_option("styleDefaults","xMode"): xMode = self.__config.get("styleDefaults","xMode") else: xMode = "counted" if xMode.startswith("runNumberEvery") or xMode.startswith("runNumbers"): nRuns = len(self.__x) try: if xMode.startswith("runNumberEvery"): showEvery = int(xMode[len("runNumberEvery"):]) else: showUpTo = int(xMode[len("runNumbers"):]) if showUpTo >= nRuns: showEvery = nRuns else: showEvery = showUpTo except ValueError: raise StandardError, "Bad xMode syntax: %s" % xMode axis = graph.GetXaxis() for (x,run) in zip(self.__x,self.__runs): if int(x-self.__x[0]) % showEvery == 0 or x==self.__x[-1]: axis.SetBinLabel(axis.FindFixBin(x), str(run)) #axis.SetRangeUser(self.__x[0], self.__x[-1]) if self.__config.has_option(self.__section,"yMin") and self.__config.has_option(self.__section,"yMax") : graph.GetYaxis().SetRangeUser(float(self.__config.get(self.__section,"yMin")), float(self.__config.get(self.__section,"yMax"))) if xMode.startswith("runNumber"): axis = graph.GetXaxis() axis.LabelsOption("v") axis.SetTitleOffset(1.9) def __getRefernceGraphArrays(self): from array import array #from Numeric import minimum, maximum width = max(self.__x) - min(self.__x) (y, yErr) = self.__metric(self.__reference[1]) relPadding = 0.01 result = (2, array("d",[min(self.__x)-width*relPadding, max(self.__x)+width*relPadding,]), array("d",[y,y]), array("d",[0,0]), array("d",[0,0]), array("d",[yErr[0],yErr[0]]), array("d",[yErr[1],yErr[1]])) from ROOT import TLatex refLabel = TLatex(max(self.__x)+width*2*relPadding, y, "%.4g" % y) refLabel.SetTextSize(float(self.__config.get("styleDefaults","annotationSize"))) return (result, refLabel) def __getStyleOption(self, name): result = None if not self.__config.has_option("styleDefaults", name): raise StandardError, "there is no default style option for '%s'"%name result = self.__config.get("styleDefaults", name) if self.__config.has_option(self.__section, name): result = self.__config.get(self.__section, name) return result
class TrendPlot: def __init__(self, section, config, cache = None): from ROOT import MakeNullPointer, TH1, TFile,TObject from array import array self.__config = config self.__section = section self.__cache = cache #self.__allReferenceRunNrs = sorted([int(i) for i in self.__config.get("reference","runs").split(",")]) #self.__reference = None self.__threshold = int(self.__config.get("styleDefaults","histoThreshold")) if self.__config.has_option(self.__section,"threshold"): self.__threshold = int(self.__config.get(self.__section,"threshold")) metricString = "metrics."+self.__config.get(self.__section,"metric") metrics =__import__(".".join(metricString.split("(")[0].split(".")[:-1])) self.__metric = eval( metricString) self.__metric.setThreshold( self.__threshold ) self.__metric.setCache( self.__cache ) self.__title = self.__section.split("plot:")[1] if self.__config.has_option(self.__section,"title"): self.__title = self.__config.get(self.__section,"title") self.__xTitle ="" # this is automatically generated later self.__yTitle = metricString #.split("(")[0].split(".")[-1].split("(")[0] self.__saveHistos = metricString #.split("(")[0].split(".")[-1].split("(")[0] if self.__config.has_option(self.__section,"yTitle"): self.__yTitle = self.__config.get(self.__section,"yTitle") if self.__config.has_option(self.__section,"saveHistos"): self.__saveHistos = self.__config.get(self.__section,"saveHistos") self.__x = array("d") self.__y = array("d") self.__yErrHigh = array("d") self.__yErrLow = array("d") self.__ySysErrHigh = array("d") self.__ySysErrLow = array("d") self.__count = 0 self.__runs = [] self.__histoSum = MakeNullPointer(TH1) self.__FileHisto=MakeNullPointer(TFile) self.__labels = [] def __addAnnotaion(self,run, x, y, yErr): from math import sqrt, fabs #(refY, refYErr) = self.__metric(self.__reference[1]) #err = sqrt(yErr[0]**2+refYErr[1]**2) #if refY > y: # err = sqrt(yErr[1]**2+refYErr[0]**2) #significance = fabs(y-refY)/err if not err == 0 else 0. err=0 significance=0 if significance > float(self.__config.get("styleDefaults","significanceThreshold")): self.__labels.append((x,y," %s %.2f#sigma"%(run,significance))) if y < float(self.__config.get("styleDefaults","ksThreshold")) and 'Kolmogorov' in self.__yTitle: self.__labels.append((x,y," %s ks=%.2f"%(run,y))) if self.__config.has_option(self.__section,"yMin") and self.__config.has_option(self.__section,"yMax") : yMin = float(self.__config.get(self.__section,"yMin")) yMax = float(self.__config.get(self.__section,"yMax")) yDelta = yMax-yMin if y < yMin : self.__labels.append((x,yMin+0.05*yDelta,"run %s, value=%.2f"%(run,y))) if y > yMax : self.__labels.append((x,yMax-0.40*yDelta,"run %s, value=%.2f"%(run,y))) def drawAnnotation(self): from ROOT import TLatex latex = TLatex() latex.SetTextSize(float(self.__config.get("styleDefaults","annotationSize"))) latex.SetTextColor(int(self.__config.get("styleDefaults","annotationColor"))) if self.__config.has_option("styleDefaults","annotationAngle"): latex.SetTextAngle(float(self.__config.get("styleDefaults","annotationAngle"))) for label in self.__labels: latex.DrawLatex(*label) def addRun(self, serverUrl, runNr, dataset): from math import sqrt from ROOT import TH1,TFile,TObject # import ROOT import os, sys, string self.__count = self.__count + 1 histoPath = self.__config.get(self.__section, "relativePath") print "in addRun, histoPath = ", histoPath #refNr = self.__allReferenceRunNrs[-1] #if len(self.__allReferenceRunNrs) > 1: # #refNr = [i for i in self.__allReferenceRunNrs if i <= runNr][-1] # refNr=min(self.__allReferenceRunNrs) # for refRunNr in self.__allReferenceRunNrs: # if refRunNr>refNr and refRunNr<runNr: # refNr = refRunNr # print "refNr = " , refNr #if self.__reference == None or refNr > self.__reference[0]: # print "refNr = " , refNr # print "getting histo from DQM for ref run" # #refHisto = getHistoFromDQM( serverUrl, refNr, dataset, histoPath) # #self.__reference = (refNr, refHisto) # #self.__metric.setReference( self.__reference[1] ) cacheLocation = (serverUrl, runNr, dataset, histoPath, self.__config.get(self.__section,"metric")) print "cachelocation = ", cacheLocation print "dataset = ", dataset if self.__config.has_option(self.__section, "saveHistos"): try: histo1 = getHistoFromDQM( serverUrl, runNr, dataset, histoPath) histosFile = self.__config.get(self.__section, "saveHistos") if not os.path.exists(histosFile): os.makedirs(histosFile) if self.__FileHisto==None: print "prazan",self.__FileHisto if self.__histoSum==None: self.__histoSum=histo1 self.__FileHisto=TFile.Open(os.path.join("%s/SumAll_%s.root"%(histosFile,self.__title)),"RECREATE") self.__histoSum.Write() else: self.__histoSum.Add(histo1) self.__FileHisto.cd() self.__histoSum.Write("",TObject.kOverwrite) histo1.SetName(str(runNr)) histo1.Write() except StandardError as msg : print "WARNING: something went wrong gettin the histogram ", runNr, msg try: if self.__cache == None or cacheLocation not in self.__cache: histo = getHistoFromDQM( serverUrl, runNr, dataset, histoPath) Entr=0 Entr=histo.GetEntries() print "############### GOT HISTO #################" y=0 yErr = (0.0,0.0) if Entr>self.__threshold: (y, yErr) = self.__metric(histo, cacheLocation) elif cacheLocation in self.__cache: (y, yErr) = self.__metric(None, cacheLocation) except StandardError as msg : print "WARNING: something went wrong calculating", self.__metric, msg self.__count = self.__count - 1 return ySysErr = (0.,0.) if self.__config.has_option(self.__section, "relSystematic"): fraction = self.__config.getfloat(self.__section, "relSystematic") ySysErr = (fraction*y, fraction*y) if self.__config.has_option(self.__section, "absSystematic"): component = self.__config.getfloat(self.__section, "absSystematic") ySysErr = (component, component) self.__config.get(self.__section, "relativePath") self.__y.append(y) ##To turn off Errors, uncomment below... ##yErr = (0.0,0.0) ##ySysErr = (0.0,0.0) self.__yErrLow.append(yErr[0]) self.__yErrHigh.append(yErr[1]) self.__ySysErrLow.append(sqrt(yErr[0]**2+ySysErr[0]**2)) self.__ySysErrHigh.append(sqrt(yErr[1]**2+ySysErr[1]**2)) self.__runs.append(runNr) if self.__config.has_option(self.__section,"xMode"): xMode = self.__config.get(self.__section,"xMode") elif self.__config.has_option("styleDefaults","xMode"): xMode = self.__config.get("styleDefaults","xMode") else: xMode = "counted" if xMode == "runNumber": self.__x.append(run) print "*** appending run to x" self.__xTitle = "Run No." elif xMode == "runNumberOffset": runOffset = int(self.__config.get(self.__section,"runOffset")) self.__x.append(run - runOffset) self.__xTitle = "Run No. - %s"%runOffset elif xMode == "counted": self.__x.append(self.__count) self.__xTitle = "Nth processed run" elif xMode.startswith("runNumberEvery") or xMode.startswith("runNumbers"): self.__x.append(self.__count) self.__xTitle = "Run No." else: raise StandardError, "Unknown xMode: %s in %s"%(xMode, self__section) self.__addAnnotaion(runNr,self.__x[-1],y,(sqrt(yErr[0]**2+ySysErr[0]**2),sqrt(yErr[1]**2+ySysErr[1]**2))) def getName(self): return self.__section.split("plot:")[1] def getGraph(self): from array import array from ROOT import TMultiGraph, TLegend, TGraphAsymmErrors n = len(self.__x) if n != len(self.__y) or n != len(self.__yErrLow) or n != len(self.__yErrHigh): raise StandardError, "The length of the x(%s), y(%s) and y error(%s,%s) lists does not match"%(len(self.__x), len(self.__y), len(self.__yErrLow), len(self.__yErrHigh)) result = TMultiGraph() legendPosition = [float(i) for i in self.__getStyleOption("legendPosition").split()] legend = TLegend(*legendPosition) legend.SetFillColor(0) result.SetTitle("%s;%s;%s"%(self.__title,self.__xTitle,self.__yTitle)) #(refArrays, refLabel) = self.__getRefernceGraphArrays() #refGraph = TGraphAsymmErrors(*refArrays) #refGraph.SetLineWidth(2) #refGraph.SetLineColor(int(self.__config.get("reference","lineColor"))) #refGraph.SetFillColor(int(self.__config.get("reference","fillColor"))) #result.Add(refGraph,"L3") #legend.AddEntry(refGraph,self.__config.get("reference","name")) xErr = array("d",[0 for i in range(n)]) print "__x = ", self.__x print "__y = ", self.__y graph = TGraphAsymmErrors(n, self.__x, self.__y, xErr, xErr, self.__yErrLow,self.__yErrHigh) graph.SetLineWidth(2) graph.SetFillColor(0) graph.SetLineColor(int(self.__getStyleOption("lineColor"))) graph.SetMarkerColor(int(self.__getStyleOption("markerColor"))) graph.SetMarkerStyle(int(self.__getStyleOption("markerStyle"))) graph.SetMarkerSize(float(self.__getStyleOption("markerSize"))) sysGraph = TGraphAsymmErrors(n, self.__x, self.__y, xErr, xErr, self.__ySysErrLow,self.__ySysErrHigh) sysGraph.SetLineWidth(1) sysGraph.SetFillColor(0) sysGraph.SetLineColor(int(self.__getStyleOption("lineColor"))) sysGraph.SetMarkerColor(int(self.__getStyleOption("markerColor"))) sysGraph.SetMarkerStyle(int(self.__getStyleOption("markerStyle"))) sysGraph.SetMarkerSize(float(self.__getStyleOption("markerSize"))) result.Add(sysGraph,"[]") result.Add(graph,"P") # result.SetName("MultiPlots") # result.SetTitle("%s;%s;%s"%(self.__title,self.__xTitle,self.__yTitle)) result.SetName("MG_%s"%(self.__title)) legend.AddEntry(graph, self.__getStyleOption("name")) #for (x,y,yErr) in zip(self.__x, self.__y, zip(self.__yErrLow,self.__yErrHigh)): # self.__addAnnotaion("hallo",x,y,yErr) return (result, legend) #return (graph, legend) #return (result, legend, refLabel) def getGraphSimple(self): from array import array from ROOT import TMultiGraph, TLegend, TGraphAsymmErrors n = len(self.__x) if n != len(self.__y) or n != len(self.__yErrLow) or n != len(self.__yErrHigh): raise StandardError, "The length of the x(%s), y(%s) and y error(%s,%s) lists does not match"%(len(self.__x), len(self.__y), len(self.__yErrLow), len(self.__yErrHigh)) legendPosition = [float(i) for i in self.__getStyleOption("legendPosition").split()] legend = TLegend(*legendPosition) legend.SetFillColor(0) xErr = array("d",[0 for i in range(n)]) print "__x = ", self.__x print "__y = ", self.__y graph = TGraphAsymmErrors(n, self.__x, self.__y, xErr, xErr, self.__yErrLow,self.__yErrHigh) graph.SetTitle("%s;%s;%s"%(self.__title,self.__xTitle,self.__yTitle)) graph.SetLineWidth(2) graph.SetFillColor(0) graph.SetLineColor(int(self.__getStyleOption("lineColor"))) graph.SetMarkerColor(int(self.__getStyleOption("markerColor"))) graph.SetMarkerStyle(int(self.__getStyleOption("markerStyle"))) graph.SetMarkerSize(float(self.__getStyleOption("markerSize"))) graph.SetDrawOption("AP") return (graph, legend) def getHISTO(self): from array import array from ROOT import TMultiGraph, TLegend, TGraphAsymmErrors from ROOT import TH1,TH1F,TAxis from math import sqrt n = len(self.__x) if n != len(self.__y) or n != len(self.__yErrLow): raise StandardError, "The length of the x(%s), y(%s) and y error(%s,%s) lists does not match"%(len(self.__x), len(self.__y), len(self.__yErrLow), len(self.__yErrHigh)) result=TH1F(self.__title,self.__title,n,0.5,float(n)+0.5) axis = result.GetXaxis() for i in range (len(self.__x)): result.Fill(i+1,self.__y[i]) result.SetBinError(i+1,self.__yErrHigh[i]) #axis.SetBinLabel(i+1, str(self.__x[i])) axis.SetBinLabel(i+1, str(self.__runs[i])) # result = MakeNullPointer(TH1) legendPosition = [float(i) for i in self.__getStyleOption("legendPosition").split()] legend = TLegend(*legendPosition) legend.SetFillColor(0) result.SetMarkerColor(int(self.__getStyleOption("markerColor"))) result.SetMarkerStyle(int(self.__getStyleOption("markerStyle"))) result.SetMarkerSize(float(self.__getStyleOption("markerSize"))) result.SetTitle("%s;%s;%s"%(self.__title,self.__xTitle,self.__yTitle)) return (result, legend) def formatGraphAxis(self, graph): if self.__config.has_option(self.__section,"xMode"): xMode = self.__config.get(self.__section,"xMode") elif self.__config.has_option("styleDefaults","xMode"): xMode = self.__config.get("styleDefaults","xMode") else: xMode = "counted" if xMode.startswith("runNumberEvery") or xMode.startswith("runNumbers"): nRuns = len(self.__x) try: if xMode.startswith("runNumberEvery"): showEvery = int(xMode[len("runNumberEvery"):]) else: showUpTo = int(xMode[len("runNumbers"):]) if showUpTo >= nRuns: showEvery = nRuns else: showEvery = showUpTo except ValueError: raise StandardError, "Bad xMode syntax: %s" % xMode axis = graph.GetXaxis() for (x,run) in zip(self.__x,self.__runs): if int(x-self.__x[0]) % showEvery == 0 or x==self.__x[-1]: axis.SetBinLabel(axis.FindFixBin(x), str(run)) #axis.SetRangeUser(self.__x[0], self.__x[-1]) if self.__config.has_option(self.__section,"yMin") and self.__config.has_option(self.__section,"yMax") : graph.GetYaxis().SetRangeUser(float(self.__config.get(self.__section,"yMin")), float(self.__config.get(self.__section,"yMax"))) if xMode.startswith("runNumber"): axis = graph.GetXaxis() axis.LabelsOption("v") axis.SetTitleOffset(1.9) def __getRefernceGraphArrays(self): from array import array #from Numeric import minimum, maximum width = max(self.__x) - min(self.__x) (y, yErr) = self.__metric(self.__reference[1]) relPadding = 0.01 result = (2, array("d",[min(self.__x)-width*relPadding, max(self.__x)+width*relPadding,]), array("d",[y,y]), array("d",[0,0]), array("d",[0,0]), array("d",[yErr[0],yErr[0]]), array("d",[yErr[1],yErr[1]])) from ROOT import TLatex refLabel = TLatex(max(self.__x)+width*2*relPadding, y, "%.4g" % y) refLabel.SetTextSize(float(self.__config.get("styleDefaults","annotationSize"))) return (result, refLabel) def __getStyleOption(self, name): result = None if not self.__config.has_option("styleDefaults", name): raise StandardError, "there is no default style option for '%s'"%name result = self.__config.get("styleDefaults", name) if self.__config.has_option(self.__section, name): result = self.__config.get(self.__section, name) return result
class TrendPlot: def __init__(self, section, config, cache=None): from ROOT import MakeNullPointer, TH1, TFile, TObject from array import array self.__config = config self.__section = section self.__cache = cache self.__threshold = int( self.__config.get("styleDefaults", "histoThreshold")) if self.__config.has_option(self.__section, "threshold"): self.__threshold = int( self.__config.get(self.__section, "threshold")) metricString = "metrics." + self.__config.get(self.__section, "metric") metrics = __import__(".".join( metricString.split("(")[0].split(".")[:-1])) self.__metricName = "metrics." + self.__config.get( self.__section, "metric") self.__metric = eval(metricString) self.__metric.setThreshold(self.__threshold) self.__metric.setCache(self.__cache) self.__title = self.__section.split("plot:")[1] if self.__config.has_option(self.__section, "title"): self.__title = self.__config.get(self.__section, "title") self.__xTitle = "" # this is automatically generated later self.__yTitle = metricString #.split("(")[0].split(".")[-1].split("(")[0] self.__saveHistos = metricString #.split("(")[0].split(".")[-1].split("(")[0] if self.__config.has_option(self.__section, "yTitle"): self.__yTitle = self.__config.get(self.__section, "yTitle") if self.__config.has_option(self.__section, "saveHistos"): self.__saveHistos = self.__config.get(self.__section, "saveHistos") self.__x = array("d") self.__y = array("d") self.__yErrHigh = array("d") self.__yErrLow = array("d") self.__ySysErrHigh = array("d") self.__ySysErrLow = array("d") self.__count = 0 self.__runs = [] self.__histoSum = MakeNullPointer(TH1) self.__FileHisto = MakeNullPointer(TFile) self.__labels = [] def addRun(self, serverUrl, runNr, dataset, tfile): from math import sqrt from ROOT import TH1, TFile, TObject, TBufferFile, TH1F, TProfile, TProfile2D, TH2F import ROOT import os, sys, string from os.path import split as splitPath from src.dqmjson import dqm_get_json_hist self.__count = self.__count + 1 histoPath = self.__config.get(self.__section, "relativePath") cacheLocation = (serverUrl, runNr, dataset, histoPath, self.__config.get(self.__section, "metric")) if self.__config.has_option(self.__section, "saveHistos"): try: if (histoPath[0] == '/'): histoPath = histoPath.replace('/', '', 1) subdet = histoPath.split('/')[0] if tfile == None: histo1 = dqm_get_json_hist(serverUrl, runNr, dataset, splitPath(histoPath)[0], splitPath(histoPath)[1], rootContent=True) else: histo1 = tfile.Get( ('DQMData/Run %d/%s/Run summary/%s') % (runNr, subdet, histoPath.replace('%s/' % (subdet), '', 1))) histosFile = self.__config.get(self.__section, "saveHistos") if not os.path.exists(histosFile): os.makedirs(histosFile) if self.__histoSum == None: self.__histoSum = histo1 self.__FileHisto = TFile.Open( os.path.join("%s/SumAll_%s.root" % (histosFile, self.__title)), "RECREATE") self.__histoSum.Write() else: self.__histoSum.Add(histo1) self.__FileHisto.cd() self.__histoSum.Write("", TObject.kOverwrite) histo1.SetName(str(runNr)) histo1.Write() except StandardError as msg: print "WARNING: something went wrong getting the histogram ", runNr, msg try: if self.__cache == None or cacheLocation not in self.__cache: if (histoPath[0] == '/'): histoPath = histoPath.replace('/', '', 1) subdet = histoPath.split('/')[0] if tfile == None: histo = dqm_get_json_hist(serverUrl, runNr, dataset, splitPath(histoPath)[0], splitPath(histoPath)[1], rootContent=True) else: histo = tfile.Get( ('DQMData/Run %d/%s/Run summary/%s') % (runNr, subdet, histoPath.replace('%s/' % (subdet), '', 1))) if self.__config.has_option(self.__section, "histo1Path"): h1Path = self.__config.get(self.__section, "histo1Path") if (h1Path[0] == '/'): h1Path = h1Path.replace('/', '', 1) subdet = h1Path.split('/')[0] if tfile == None: h1 = dqm_get_json_hist(serverUrl, runNr, dataset, splitPath(h1Path)[0], splitPath(h1Path)[1], rootContent=True) else: h1 = tfile.Get( ('DQMData/Run %d/%s/Run summary/%s') % (runNr, subdet, h1Path.replace('%s/' % (subdet), '', 1))) self.__metric.setOptionalHisto1(h1) if self.__config.has_option(self.__section, "histo2Path"): h2Path = self.__config.get(self.__section, "histo2Path") if (h2Path[0] == '/'): h2Path = h1Path.replace('/', '', 1) subdet = h2Path.split('/')[0] if tfile == None: h2 = dqm_get_json_hist(serverUrl, runNr, dataset, splitPath(h2Path)[0], splitPath(h2Path)[1], rootContent=True) else: h2 = tfile.Get( ('DQMData/Run %d/%s/Run summary/%s') % (runNr, subdet, h2Path.replace('%s/' % (subdet), '', 1))) self.__metric.setOptionalHisto2(h2) self.__metric.setRun(runNr) if (histo != None): print "-> Got histogram {0} as {1}".format( splitPath(histoPath)[1], histo) if self.__config.has_option(self.__section, "histo1Path"): print " -> Got auxiliary histogram {0} as {1}".format( splitPath(h1Path)[1], h1) if self.__config.has_option(self.__section, "histo2Path"): print " -> Got auxiliary histogram {0} as {1}".format( splitPath(h2Path)[1], h2) Entr = 0 Entr = histo.GetEntries() #print "############### GOT HISTO #################" y = 0 yErr = (0.0, 0.0) if Entr > self.__threshold: print " -> {0} will be evaluated".format( self.__metricName) (y, yErr) = self.__metric(histo, cacheLocation) else: print " -> Histogram entries are {0} while threshold is {1}. Metric will not be evalueted, results set at 0".format( Entr, self.__threshold) self.__cache[cacheLocation] = ((0., 0.), 0.) else: print "WARNING: something went wrong downloading histo=", splitPath( histoPath)[1] return elif cacheLocation in self.__cache: print "-> Got {0} for histogram {1} from cache".format( self.__metricName, splitPath(histoPath)[1]) (y, yErr) = self.__metric(None, cacheLocation) except StandardError as msg: print "WARNING: something went wrong calculating", self.__metric, msg self.__count = self.__count - 1 return ySysErr = (0., 0.) if self.__config.has_option(self.__section, "relSystematic"): fraction = self.__config.getfloat(self.__section, "relSystematic") ySysErr = (fraction * y, fraction * y) if self.__config.has_option(self.__section, "absSystematic"): component = self.__config.getfloat(self.__section, "absSystematic") ySysErr = (component, component) self.__config.get(self.__section, "relativePath") self.__y.append(y) self.__yErrLow.append(yErr[0]) self.__yErrHigh.append(yErr[1]) self.__ySysErrLow.append(sqrt(yErr[0]**2 + ySysErr[0]**2)) self.__ySysErrHigh.append(sqrt(yErr[1]**2 + ySysErr[1]**2)) self.__runs.append(runNr) if self.__config.has_option(self.__section, "xMode"): xMode = self.__config.get(self.__section, "xMode") elif self.__config.has_option("styleDefaults", "xMode"): xMode = self.__config.get("styleDefaults", "xMode") else: xMode = "counted" if xMode == "runNumber": self.__x.append(run) print "*** appending run to x" self.__xTitle = "Run No." elif xMode == "runNumberOffset": runOffset = int(self.__config.get(self.__section, "runOffset")) self.__x.append(run - runOffset) self.__xTitle = "Run No. - %s" % runOffset elif xMode == "counted": self.__x.append(self.__count) self.__xTitle = "Nth processed run" elif xMode.startswith("runNumberEvery") or xMode.startswith( "runNumbers"): self.__x.append(self.__count) self.__xTitle = "Run No." else: raise StandardError, "Unknown xMode: %s in %s" % (xMode, self__section) def getName(self): return self.__section.split("plot:")[1] def getPath(self): return self.__config.get(self.__section, "relativePath") def getMetric(self): return self.__config.get(self.__section, "metric") def dumpJSON(self): n = len(self.__x) lst = [] for inc in range(0, n): d = {} d['run'] = self.__runs[inc] d['x'] = self.__x[inc] d['y'] = self.__y[inc] d['yErr'] = self.__yErrLow[inc] d['yTitle'] = self.__yTitle if self.__config.has_option(self.__section, "hTitle"): d['hTitle'] = self.__config.get(self.__section, "hTitle") else: d['hTitle'] = self.__yTitle if self.__config.has_option(self.__section, "yMin") and self.__config.has_option( self.__section, "yMax"): d['ymin'] = float(self.__config.get(self.__section, "yMin")) d['ymax'] = float(self.__config.get(self.__section, "yMax")) else: d['ymin'] = 0 d['ymax'] = 0 lst.append(d) obj = {} obj[self.__title] = lst if not os.path.exists("./JSON"): os.makedirs("./JSON") with open("./JSON/" + self.__title + ".json", 'w') as outfile: json.dump(obj, outfile, indent=4) print "Dump JSON file : {0}.json".format(self.__title) return def getGraph(self): from array import array from ROOT import TMultiGraph, TLegend, TGraphAsymmErrors n = len(self.__x) if n != len(self.__y) or n != len(self.__yErrLow) or n != len( self.__yErrHigh): raise StandardError, "The length of the x(%s), y(%s) and y error(%s,%s) lists does not match" % ( len(self.__x), len(self.__y), len( self.__yErrLow), len(self.__yErrHigh)) result = TMultiGraph() legendPosition = [ float(i) for i in self.__getStyleOption("legendPosition").split() ] legend = TLegend(*legendPosition) legend.SetFillColor(0) result.SetTitle("%s;%s;%s" % (self.__title, self.__xTitle, self.__yTitle)) xErr = array("d", [0 for i in range(n)]) graph = TGraphAsymmErrors(n, self.__x, self.__y, xErr, xErr, self.__yErrLow, self.__yErrHigh) graph.SetLineWidth(2) graph.SetFillColor(0) graph.SetLineColor(int(self.__getStyleOption("lineColor"))) graph.SetMarkerColor(int(self.__getStyleOption("markerColor"))) graph.SetMarkerStyle(int(self.__getStyleOption("markerStyle"))) graph.SetMarkerSize(float(self.__getStyleOption("markerSize"))) result.Add(graph, "P") result.SetName("MG_%s" % (self.__title)) legend.AddEntry(graph, self.__getStyleOption("name")) return (result, legend) def getHISTO(self): from array import array from ROOT import TMultiGraph, TLegend, TGraphAsymmErrors from ROOT import TH1, TH1F, TAxis from math import sqrt n = len(self.__x) if n != len(self.__y) or n != len(self.__yErrLow): raise StandardError, "The length of the x(%s), y(%s) and y error(%s,%s) lists does not match" % ( len(self.__x), len(self.__y), len( self.__yErrLow), len(self.__yErrHigh)) result = TH1F(self.__title, self.__title, n, 0.5, float(n) + 0.5) axis = result.GetXaxis() for i in range(len(self.__x)): result.Fill(i + 1, self.__y[i]) result.SetBinError(i + 1, self.__yErrHigh[i]) #axis.SetBinLabel(i+1, str(self.__x[i])) axis.SetBinLabel(i + 1, str(self.__runs[i])) # result = MakeNullPointer(TH1) legendPosition = [ float(i) for i in self.__getStyleOption("legendPosition").split() ] legend = TLegend(*legendPosition) legend.SetFillColor(0) result.SetMarkerColor(int(self.__getStyleOption("markerColor"))) result.SetMarkerStyle(int(self.__getStyleOption("markerStyle"))) result.SetMarkerSize(float(self.__getStyleOption("markerSize"))) result.SetTitle("%s;%s;%s" % (self.__title, self.__xTitle, self.__yTitle)) return (result, legend) def formatGraphAxis(self, graph): if self.__config.has_option(self.__section, "xMode"): xMode = self.__config.get(self.__section, "xMode") elif self.__config.has_option("styleDefaults", "xMode"): xMode = self.__config.get("styleDefaults", "xMode") else: xMode = "counted" if xMode.startswith("runNumberEvery") or xMode.startswith( "runNumbers"): nRuns = len(self.__x) try: if xMode.startswith("runNumberEvery"): showEvery = int(xMode[len("runNumberEvery"):]) else: showUpTo = int(xMode[len("runNumbers"):]) if showUpTo >= nRuns: showEvery = nRuns else: showEvery = showUpTo except ValueError: raise StandardError, "Bad xMode syntax: %s" % xMode axis = graph.GetXaxis() for (x, run) in zip(self.__x, self.__runs): if int(x - self.__x[0]) % showEvery == 0 or x == self.__x[-1]: axis.SetBinLabel(axis.FindFixBin(x), str(run)) #axis.SetRangeUser(self.__x[0], self.__x[-1]) if self.__config.has_option(self.__section, "yMin") and self.__config.has_option( self.__section, "yMax"): graph.GetYaxis().SetRangeUser( float(self.__config.get(self.__section, "yMin")), float(self.__config.get(self.__section, "yMax"))) if xMode.startswith("runNumber"): axis = graph.GetXaxis() axis.LabelsOption("v") axis.SetTitleOffset(1.9) def __getStyleOption(self, name): result = None if not self.__config.has_option("styleDefaults", name): raise StandardError, "there is no default style option for '%s'" % name result = self.__config.get("styleDefaults", name) if self.__config.has_option(self.__section, name): result = self.__config.get(self.__section, name) return result