Example #1
0
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
Example #2
0
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