示例#1
0
    def legend4Plot(plot, left = False):
        if left:
            theLeg = TLegend(0.2, 0.62, 0.55, 0.92, "", "NDC")
        else:
            theLeg = TLegend(0.60, 0.62, 0.92, 0.92, "", "NDC")
        theLeg.SetName('theLegend')

        theLeg.SetBorderSize(0)
        theLeg.SetLineColor(0)
        theLeg.SetFillColor(0)
        theLeg.SetFillStyle(0)
        theLeg.SetLineWidth(0)
        theLeg.SetLineStyle(0)
        theLeg.SetTextFont(42)
        theLeg.SetTextSize(.045)

        entryCnt = 0
        for obj in range(0, int(plot.numItems())):
            objName = plot.nameOf(obj)
            if (not plot.getInvisible(objName)):
                theObj = plot.getObject(obj)
                objTitle = theObj.GetTitle()
                if len(objTitle) < 1:
                    objTitle = objName
                dopts = plot.getDrawOptions(objName).Data()
                # print 'obj:',theObj,'title:',objTitle,'opts:',dopts,'type:',type(dopts)
                if theObj.IsA().InheritsFrom('TNamed'):
                    theLeg.AddEntry(theObj, objTitle, dopts)
                    entryCnt += 1
        theLeg.SetY1NDC(0.9 - 0.05*entryCnt - 0.005)
        theLeg.SetY1(theLeg.GetY1NDC())
        return theLeg
示例#2
0
def UnfoldFF(rawFF, detResponse, tag):
    padFF.Clear()
    padFF.Divide(2)
    # Detector response
    ResponseNorm(detResponse)
    padFF.cd(1)
    detResponse.Draw('COLZ')
    response = RooUnfoldResponse(rawFF, rawFF, detResponse)
    bayes = RooUnfoldBayes(response, rawFF)
    # Unfolding - Bayesian
    ana_util.COLOR = SelectColor(0)
    ana_util.MARKER = SelectMarker(0)
    padFF.cd(2)
    # Legend
    lgd = TLegend(0.12, 0.6, 0.3, 0.85)
    lgd.SetName('lgd' + tag)
    lgd.SetBorderSize(0)
    lgd.SetFillColor(0)
    # Z measured
    rawFF.SetBins(10, 0, 1.0)
    DrawFF(rawFF, 'hRaw_' + tag)
    lgd.AddEntry(rawFF, 'Raw')
    for nIter in range(4, 5):
        bayes.SetIterations(nIter)
        hist = DrawFF(bayes.Hreco(0), 'hBayes' + repr(nIter) + '_' + tag)
        for ix in range(1, hist.GetNbinsX()):
            hist.SetBinError(ix, rawFF.GetBinError(ix))
        lgd.AddEntry(hist, 'Bayes (N=%d)' % nIter)
    lgd.Draw('same')
    padFF.Print(printFile, 'Title:' + tag)
    padFF.Write('c' + tag)
示例#3
0
def make_legend(x1=.65,
                y2=.88,
                nentries=2,
                scale=1,
                name='l',
                y1=None,
                margin=.25,
                x2=None):
    x2 = .95 if x2 is None else x2
    y1 = y2 - nentries * .05 * scale if y1 is None else y1
    l = TLegend(x1, y1, x2, y2)
    l.SetName(name)
    l.SetTextFont(42)
    l.SetTextSize(0.03 * scale)
    l.SetMargin(margin)
    return l
示例#4
0
def DrawText(can,text='text',x1=None,y1=None,x2=None,y2=None,angle=0,align='',textsize=18,totalentries=1) :

    if x1 == None : x1 = 0.2
    if x2 == None : x2 = 0.5

    if can.GetPrimitive('pad_top') :
        if y1 == None : y1 = 0.73
        if y2 == None : y2 = 0.93
    else :
        if y1 == None : y1 = 0.78
        if y2 == None : y2 = 0.94

    can.cd()
    if can.GetPrimitive('pad_top') :
        can.GetPrimitive('pad_top').cd()
    from ROOT import TLegend
    leg = TLegend(x1,y1,x2,y2)
    leg.SetMargin(0)
    leg.SetName(can.GetName()+'_text')
    tobject_collector.append(leg)
    leg.SetTextSize(textsize)
    leg.SetTextFont(43)
    leg.SetBorderSize(0)
    leg.SetFillStyle(0)
    if type(text) == type('') :
        text = [text]
    total = 0
    for i in text :
        leg.AddEntry(0,i,'')
        total += 1
    while (total < totalentries) :
        leg.AddEntry(0,'','')
        total += 1
    leg.Draw()
    can.Modified()
    #can.Update()
    return
示例#5
0
def DrawText(can,
             text='text',
             x1=.2,
             y1=.84,
             x2=.5,
             y2=.9,
             angle=0,
             align='',
             textsize=18,
             totalentries=0):
    can.cd()
    if can.GetPrimitive('pad_top'):
        can.GetPrimitive('pad_top').cd()
    from ROOT import TLegend
    leg = TLegend(x1, y1, x2, y2)
    leg.SetName('text')
    tobject_collector.append(leg)
    leg.SetTextSize(textsize)
    leg.SetTextFont(43)
    leg.SetBorderSize(0)
    leg.SetFillStyle(0)
    if type(text) == type(''):
        text = [text]
    total = 0
    for i in text:
        leg.AddEntry(0, i, '')
        total += 1
    for i in range(100):
        if totalentries == 0: break
        if total >= totalentries: break
        leg.AddEntry(None, '', '')
        total += 1
    leg.Draw()
    can.Modified()
    can.Update()
    return
示例#6
0
def MakeLegend(can,
               x1=.8,
               y1=.8,
               x2=.9,
               y2=.9,
               textsize=18,
               ncolumns=1,
               totalentries=0,
               option='f',
               skip=[]):
    from ROOT import TLegend, TH1, gStyle, TGraph
    if can.GetPrimitive('pad_top'):
        MakeLegend(can.GetPrimitive('pad_top'),
                   x1,
                   y1,
                   x2,
                   y2,
                   textsize,
                   ncolumns,
                   totalentries,
                   skip=skip)
        return
    if CanvasEmpty(can):
        print 'Error: trying to make legend from canvas with 0 plots. Will do nothing.'
        return
    #
    # if a previous version exists from this function, delete it
    #
    if can.GetPrimitive('legend'):
        can.GetPrimitive('legend').Delete()
    leg = TLegend(x1, y1, x2, y2)
    leg.SetName('legend')
    tobject_collector.append(leg)
    leg.SetTextFont(43)
    leg.SetTextSize(textsize)
    leg.SetTextFont(43)
    leg.SetBorderSize(0)
    leg.SetFillStyle(0)
    leg.SetNColumns(ncolumns)
    #
    # Add by TH1 GetTitle()
    #
    the_primitives = can.GetListOfPrimitives()
    if can.GetPrimitive('pad_top'):
        the_primitives = can.GetPrimitive('pad_top').GetListOfPrimitives()
    if can.GetPrimitive('stack'):
        the_stack = list(reversed(list(can.GetPrimitive('stack').GetHists())))
        the_primitives = the_stack + list(the_primitives)

    if type(option) == type(''):
        option = [option] * 100

    total = 0
    for i in the_primitives:
        if i.GetName() == 'stack': continue
        drawopt = i.GetDrawOption()
        if issubclass(type(i), TH1) or issubclass(type(i), TGraph):
            if i.GetTitle() in skip:
                continue
            leg.AddEntry(i, i.GetTitle(), option[total])  # plef
            total += 1

    #
    # Add empty entries to ensure a standard layout
    #
    for i in range(100):
        if totalentries == 0: break
        if total >= totalentries: break
        leg.AddEntry(None, '', '')
        total += 1

    # recipe for making roughly square boxes
    h = leg.GetY2() - leg.GetY1()
    w = leg.GetX2() - leg.GetX1()
    leg.SetMargin(leg.GetNColumns() * h / float(leg.GetNRows() * w))
    can.cd()
    if can.GetPrimitive('pad_top'):
        can.GetPrimitive('pad_top').cd()
    leg.Draw()
    can.Modified()
    can.Update()
    return
def train_and_apply():

    np.random.seed(1)
    ROOT.gROOT.SetBatch()

    #Extract data from root file
    tree = uproot.open("out_all.root")["outA/Tevts"]
    branch_mc = [
        "MC_B_P", "MC_B_eta", "MC_B_phi", "MC_B_pt", "MC_D0_P", "MC_D0_eta",
        "MC_D0_phi", "MC_D0_pt", "MC_Dst_P", "MC_Dst_eta", "MC_Dst_phi",
        "MC_Dst_pt", "MC_Est_mu", "MC_M2_miss", "MC_mu_P", "MC_mu_eta",
        "MC_mu_phi", "MC_mu_pt", "MC_pis_P", "MC_pis_eta", "MC_pis_phi",
        "MC_pis_pt", "MC_q2"
    ]
    branch_rec = [
        "B_P", "B_eta", "B_phi", "B_pt", "D0_P", "D0_eta", "D0_phi", "D0_pt",
        "Dst_P", "Dst_eta", "Dst_phi", "Dst_pt", "Est_mu", "M2_miss", "mu_P",
        "mu_eta", "mu_phi", "mu_pt", "pis_P", "pis_eta", "pis_phi", "pis_pt",
        "q2"
    ]
    nvariable = len(branch_mc)
    x_train = tree.array(branch_mc[0], entrystop=options.maxevents)
    for i in range(1, nvariable):
        x_train = np.vstack(
            (x_train, tree.array(branch_mc[i], entrystop=options.maxevents)))
    x_test = tree.array(branch_rec[0], entrystop=options.maxevents)
    for i in range(1, nvariable):
        x_test = np.vstack(
            (x_test, tree.array(branch_rec[i], entrystop=options.maxevents)))
    x_train = x_train.T
    x_test = x_test.T
    x_test = array2D_float(x_test)
    #Different type of reconstruction variables

    #BN normalization
    gamma = 0
    beta = 0.2

    ar = np.array(x_train)
    a = K.constant(ar[:, 0])
    mean = K.mean(a)
    var = K.var(a)
    x_train = K.eval(K.batch_normalization(a, mean, var, gamma, beta))
    for i in range(1, nvariable):
        a = K.constant(ar[:, i])
        mean = K.mean(a)
        var = K.var(a)
        a = K.eval(K.batch_normalization(a, mean, var, gamma, beta))
        x_train = np.vstack((x_train, a))
    x_train = x_train.T

    ar = np.array(x_test)
    a = K.constant(ar[:, 0])
    mean = K.mean(a)
    var = K.var(a)
    x_test = K.eval(K.batch_normalization(a, mean, var, gamma, beta))
    for i in range(1, nvariable):
        a = K.constant(ar[:, i])
        mean = K.mean(a)
        var = K.var(a)
        a = K.eval(K.batch_normalization(a, mean, var, gamma, beta))
        x_test = np.vstack((x_test, a))
    x_test = x_test.T

    #Add noise, remain to be improved
    noise = np.random.normal(loc=0.0, scale=0.01, size=x_train.shape)
    x_train_noisy = x_train + noise
    noise = np.random.normal(loc=0.0, scale=0.01, size=x_test.shape)
    x_test_noisy = x_test + noise
    x_train = np.clip(x_train, -1., 1.)
    x_test = np.clip(x_test, -1., 1.)
    x_train_noisy = np.clip(x_train_noisy, -1., 1.)
    x_test_noisy = np.clip(x_test_noisy, -1., 1.)

    # Network parameters
    input_shape = (x_train.shape[1], )
    batch_size = 128
    latent_dim = 2

    # Build the Autoencoder Model
    # First build the Encoder Model
    inputs = Input(shape=input_shape, name='encoder_input')
    x = inputs

    # Shape info needed to build Decoder Model
    shape = K.int_shape(x)

    # Generate the latent vector
    latent = Dense(latent_dim, name='latent_vector')(x)

    # Instantiate Encoder Model
    encoder = Model(inputs, latent, name='encoder')
    encoder.summary()

    # Build the Decoder Model
    latent_inputs = Input(shape=(latent_dim, ), name='decoder_input')
    x = Dense(shape[1])(latent_inputs)
    x = Reshape((shape[1], ))(x)
    outputs = Activation('tanh', name='decoder_output')(x)

    # Instantiate Decoder Model
    decoder = Model(latent_inputs, outputs, name='decoder')
    decoder.summary()

    # Autoencoder = Encoder + Decoder
    # Instantiate Autoencoder Model
    autoencoder = Model(inputs, decoder(encoder(inputs)), name='autoencoder')
    autoencoder.summary()

    autoencoder.compile(loss='mse', optimizer='adam')

    # Train the autoencoder
    autoencoder.fit(x_train_noisy,
                    x_train,
                    validation_data=(x_test_noisy, x_test),
                    epochs=options.epochs,
                    batch_size=batch_size)

    # Predict the Autoencoder output from corrupted test imformation
    x_decoded = autoencoder.predict(x_test_noisy)

    # Draw Comparision Plots
    c = TCanvas("c", "c", 700, 700)
    fPads1 = TPad("pad1", "Run2", 0.0, 0.29, 1.00, 1.00)
    fPads2 = TPad("pad2", "", 0.00, 0.00, 1.00, 0.29)
    fPads1.SetBottomMargin(0.007)
    fPads1.SetLeftMargin(0.10)
    fPads1.SetRightMargin(0.03)
    fPads2.SetLeftMargin(0.10)
    fPads2.SetRightMargin(0.03)
    fPads2.SetBottomMargin(0.25)
    fPads1.Draw()
    fPads2.Draw()
    fPads1.cd()
    nbin = 50
    min = -1.
    max = 1.
    variable = "P^{B}"
    lbin = (max - min) / nbin
    lbin = str(float((max - min) / nbin))
    xtitle = branch_rec[options.branch - 1]
    ytitle = "Events/" + lbin + "GeV"
    h_rec = TH1D("h_rec", "" + ";%s;%s" % (xtitle, ytitle), nbin, min, max)
    h_rec.Sumw2()
    h_pre = TH1D("h_pre", "" + ";%s;%s" % (xtitle, ytitle), nbin, min, max)
    h_pre.Sumw2()
    for i in range(x_test_noisy.shape[0]):
        h_rec.Fill(x_test_noisy[i][options.branch - 1])
        h_pre.Fill(x_decoded[i][options.branch - 1])
    h_rec = UnderOverFlow1D(h_rec)
    h_pre = UnderOverFlow1D(h_pre)
    maxY = TMath.Max(h_rec.GetMaximum(), h_pre.GetMaximum())
    h_rec.SetLineColor(2)
    h_rec.SetFillStyle(0)
    h_rec.SetLineWidth(2)
    h_rec.SetLineStyle(1)
    h_pre.SetLineColor(3)
    h_pre.SetFillStyle(0)
    h_pre.SetLineWidth(2)
    h_pre.SetLineStyle(1)
    h_rec.SetStats(0)
    h_pre.SetStats(0)
    h_rec.GetYaxis().SetRangeUser(0, maxY * 1.1)
    h_rec.Draw("HIST")
    h_pre.Draw("same HIST")
    h_rec.GetYaxis().SetTitleSize(0.06)
    h_rec.GetYaxis().SetTitleOffset(0.78)
    theLeg = TLegend(0.5, 0.45, 0.95, 0.82, "", "NDC")
    theLeg.SetName("theLegend")
    theLeg.SetBorderSize(0)
    theLeg.SetLineColor(0)
    theLeg.SetFillColor(0)
    theLeg.SetFillStyle(0)
    theLeg.SetLineWidth(0)
    theLeg.SetLineStyle(0)
    theLeg.SetTextFont(42)
    theLeg.SetTextSize(.05)
    theLeg.AddEntry(h_rec, "Reconstruction", "L")
    theLeg.AddEntry(h_pre, "Prediction", "L")
    theLeg.SetY1NDC(0.9 - 0.05 * 6 - 0.005)
    theLeg.SetY1(theLeg.GetY1NDC())
    fPads1.cd()
    theLeg.Draw()
    title = TLatex(
        0.91, 0.93, "AE prediction compare with reconstruction, epochs=" +
        str(options.epochs))
    title.SetNDC()
    title.SetTextSize(0.05)
    title.SetTextFont(42)
    title.SetTextAlign(31)
    title.SetLineWidth(2)
    title.Draw()
    fPads2.cd()
    h_Ratio = h_pre.Clone("h_Ratio")
    h_Ratio.Divide(h_rec)
    h_Ratio.SetLineColor(1)
    h_Ratio.SetLineWidth(2)
    h_Ratio.SetMarkerStyle(8)
    h_Ratio.SetMarkerSize(0.7)
    h_Ratio.GetYaxis().SetRangeUser(0, 2)
    h_Ratio.GetYaxis().SetNdivisions(504, 0)
    h_Ratio.GetYaxis().SetTitle("Pre/Rec")
    h_Ratio.GetYaxis().SetTitleOffset(0.35)
    h_Ratio.GetYaxis().SetTitleSize(0.13)
    h_Ratio.GetYaxis().SetTitleSize(0.13)
    h_Ratio.GetYaxis().SetLabelSize(0.11)
    h_Ratio.GetXaxis().SetLabelSize(0.1)
    h_Ratio.GetXaxis().SetTitleOffset(0.8)
    h_Ratio.GetXaxis().SetTitleSize(0.14)
    h_Ratio.SetStats(0)
    axis1 = TGaxis(min, 1, max, 1, 0, 0, 0, "L")
    axis1.SetLineColor(1)
    axis1.SetLineWidth(1)
    for i in range(1, h_Ratio.GetNbinsX() + 1, 1):
        D = h_rec.GetBinContent(i)
        eD = h_rec.GetBinError(i)
        if D == 0: eD = 0.92
        B = h_pre.GetBinContent(i)
        eB = h_pre.GetBinError(i)
        if B < 0.1 and eB >= B:
            eB = 0.92
            Err = 0.
        if B != 0.:
            Err = TMath.Sqrt((eD * eD) / (B * B) + (D * D * eB * eB) /
                             (B * B * B * B))
            h_Ratio.SetBinContent(i, D / B)
            h_Ratio.SetBinError(i, Err)
        if B == 0.:
            Err = TMath.Sqrt((eD * eD) / (eB * eB) + (D * D * eB * eB) /
                             (eB * eB * eB * eB))
            h_Ratio.SetBinContent(i, D / 0.92)
            h_Ratio.SetBinError(i, Err)
        if D == 0 and B == 0:
            h_Ratio.SetBinContent(i, -1)
            h_Ratio.SetBinError(i, 0)
        h_Ratio.Draw("e0")
        axis1.Draw()

    c.SaveAs(branch_rec[options.branch - 1] + "_comparision.png")
示例#8
0
class Property:
    def __init__(self, name, bkg_hists, data_hist, signal_hists, sample_hists):
        self.Name = name
        self.Bkg = bkg_hists
        self.Data = data_hist
        self.Signal = signal_hists
        self.Samples = sample_hists

    @staticmethod
    def AddOFUF(h):
        UF = h.GetBinContent(0)
        UF_E = h.GetBinError(0)

        b1 = h.GetBinContent(1)
        b1_e = h.GetBinError(1)

        h.SetBinContent(1, UF + b1)
        h.SetBinError(1, sqrt(UF_E * UF_E + b1_e * b1_e))

        h.SetBinContent(0, 0.0)
        h.SetBinError(0, 0.0)

        lastBin = h.GetNbinsX()
        OF = h.GetBinContent(lastBin + 1)
        OF_E = h.GetBinError(lastBin + 1)

        bL = h.GetBinContent(lastBin)
        bL_e = h.GetBinError(lastBin)

        h.SetBinContent(lastBin, OF + bL)
        h.SetBinError(lastBin, sqrt(OF_E * OF_E + bL_e * bL_e))

        h.SetBinContent(lastBin + 1, 0.0)
        h.SetBinError(lastBin + 1, 0.0)

    def AddOF_UF_Bins(self):
        Property.AddOFUF(self.Data)
        for s in self.Signal:
            Property.AddOFUF(s)
        for s in self.Bkg:
            Property.AddOFUF(self.Bkg[s])
        for s in self.Samples:
            Property.AddOFUF(s)

    def GetBkgFromCR(self, CRProp, Bkgs, replacement, yieldsMethod=1):
        """ 
        extract the shape of bkg from CRProp using data minus all Bkgs
        for the normalization in SR (which is the current property) several methods are foreseen :
        yieldsMethod = 1 : sum of the integral of Bkgs in CR (so taken from the simulation and cross section of backgrounds, trusted in signal region)
        yieldsMethod = 2 : data minus other MC's except Bkgs
        yieldsMethod = 3 : template fit

        replacement is a list with this format : [ NewName , NewColor ]
        """

        notInBkg = [item for item in self.Bkg if item not in Bkgs]
        template = CRProp.SubtractDataMC(notInBkg, self.Name)
        if template.Integral() == 0:
            return -1
        nMCBkgsSR = 0
        nDataMinusBkgsSR = self.Data.Integral()
        for bkg in Bkgs:
            nMCBkgsSR += self.Bkg.pop(bkg).Integral()
        for bkg in self.Bkg:
            nDataMinusBkgsSR -= self.Bkg[bkg].Integral()

        nNormalization = 0
        if yieldsMethod == 1:
            nNormalization = nMCBkgsSR
        elif yieldsMethod == 2:
            nNormalization = nDataMinusBkgsSR
        elif yieldsMethod == 3:
            nFit = 1.0
            var = RooRealVar(self.Name, self.Name,
                             self.Data.GetXaxis().GetXmin(),
                             self.Data.GetXaxis().GetXmax())
            templatehist = RooDataHist("%s_bkg_templateHist" % (self.Name),
                                       self.Name, RooArgList(var), template)
            templatepdf = RooHistPdf("%s_bkg_templatePDF" % (self.Name),
                                     self.Name, RooArgSet(var), templatehist)

            SumNonBkg = self.Data.Clone("sum_%s_%s_th1" %
                                        (self.Name, "_".join(notInBkg)))
            SumNonBkg.Reset()
            for bkg in notInBkg:
                SumNonBkg.Add(self.Bkg[bkg])
            SumNonBkgHist = RooDataHist(
                "sum_%s_%s_Hist" % (self.Name, "_".join(notInBkg)), self.Name,
                RooArgList(var), SumNonBkg)
            SumNonBkgpdf = RooHistPdf(
                "sum_%s_%s_PDF" % (self.Name, "_".join(notInBkg)), self.Name,
                RooArgSet(var), SumNonBkgHist)

            DataHist = RooDataHist("data_%s_Hist" % (self.Name), self.Name,
                                   RooArgList(var), self.Data)

            nBkgs = None
            if nDataMinusBkgsSR > 0:
                nBkgs = RooRealVar("nBkgs", "NBkgs", nDataMinusBkgsSR,
                                   0.5 * nDataMinusBkgsSR,
                                   2 * nDataMinusBkgsSR)
            elif nDataMinusBkgsSR < 0:
                nBkgs = RooRealVar("nBkgs", "NBkgs", nDataMinusBkgsSR,
                                   2 * nDataMinusBkgsSR, -2 * nDataMinusBkgsSR)
            else:
                nBkgs = RooRealVar("nBkgs", "NBkgs", nDataMinusBkgsSR, -10, 10)
            nFixed = RooRealVar("nFixed", "NFIXED", SumNonBkg.Integral(),
                                SumNonBkg.Integral(), SumNonBkg.Integral())
            model = RooAddPdf("model", "model",
                              RooArgList(SumNonBkgpdf, templatepdf),
                              RooArgList(nFixed, nBkgs))
            res = model.fitTo(DataHist, RooFit.Extended(True),
                              RooFit.Save(True), RooFit.SumW2Error(True))
            nNormalization = nBkgs.getVal()

        template.Scale(nNormalization / template.Integral())
        template.SetLineWidth(2)
        template.SetLineColor(1)
        template.SetFillColor(replacement[1])
        template.SetFillStyle(1001)
        self.Bkg[replacement[0]] = template

        return nNormalization

    def Rebin(self, newbins):
        bins = sorted(newbins)
        runArray = array('d', bins)
        self.Data = self.Data.Rebin(
            len(newbins) - 1,
            self.Data.GetName() + "_rebined", runArray)
        if self.Signal:
            for i in range(0, len(self.Signal)):
                self.Signal[i] = self.Signal[i].Rebin(
                    len(newbins) - 1, self.Signal[i].GetName() + "_rebined",
                    runArray)
        for bkg in self.Bkg:
            self.Bkg[bkg] = self.Bkg[bkg].Rebin(
                len(newbins) - 1, self.Bkg[bkg].GetName() + "_rebined",
                runArray)

    @staticmethod
    def addLabels(histo, labels):
        if not histo:
            return
        for i in range(1, histo.GetNbinsX() + 1):
            if not i > len(labels):
                histo.GetXaxis().SetBinLabel(i, labels[i - 1])

    def SetLabels(self, labels):
        Property.addLabels(self.Data, labels)
        for s in self.Signal:
            Property.addLabels(s, labels)
        for bkg in self.Bkg:
            Property.addLabels(self.Bkg[bkg], labels)
        for smpl in self.Samples:
            Property.addLabels(smpl, labels)

    def Clone(self, newname, allsamples=False):
        ret = Property(newname, {}, None, None, [])
        ret.Data = self.Data.Clone(
            string.replace(self.Data.GetName(), self.Name, newname))
        if self.Signal:
            ret.Signal = []
            for i in range(0, len(self.Signal)):
                ret.Signal.append(self.Signal[i].Clone(
                    string.replace(self.Signal[i].GetName(), self.Name,
                                   newname)))
        for bkg in self.Bkg:
            ret.Bkg[bkg] = self.Bkg[bkg].Clone(
                string.replace(self.Bkg[bkg].GetName(), self.Name, newname))
        if allsamples:
            ret.Samples = [
                h.Clone(string.replace(h.GetName(), self.Name, newname))
                for h in self.Samples
            ]

        return ret

    def SubtractDataMC(self, tosubtract, appendix=""):
        tokeep = [item for item in self.Bkg if item not in tosubtract]
        ret = self.Data.Clone("%s_%s_template_%s" %
                              (self.Name, "_".join(tokeep), appendix))
        for bkg in tosubtract:
            ret.Add(self.Bkg[bkg], -1)
        return ret

    def GetStack(self, normtodata=False):
        if not hasattr(self, "Stack"):
            stackname = "%s_stack" % (self.Name)
            scale = 1.0
            if normtodata:
                totalmc = 0.
                for st in self.Bkg:
                    totalmc += self.Bkg[st].Integral()
                if totalmc > 0.000001:
                    scale = self.Data.Integral() / totalmc
                else:
                    print "\t%s was not normalized to data as the mc yield is %.2f" % (
                        self.Name, totalmc)
            #print "in getStack, normtodata = %s and scale is %f" % (str(normtodata) , scale)
            self.Stack = THStack(stackname, self.Name)
            for st in self.Bkg:
                if normtodata:
                    self.Bkg[st].Scale(scale)
                self.Stack.Add(self.Bkg[st])

        return self.Stack

    def GetSignalCanvas(self):
        canvasname = "%s_signal_canvas" % (self.Name)
        if not hasattr(self, "SignalCanvas"):
            self.SignalCanvas = TCanvas(canvasname)

            if self.Signal:
                for s in self.Signal:
                    s.DrawNormalized("E SAME HIST")
                self.GetSLegend().Draw()
        return self.SignalCanvas

    def GetCanvas(self, padid, padOrCanvas=0):
        canvasname = "%s_canvas" % (self.Name)
        pad1name = "%s_pad1" % (self.Name)
        pad2name = "%s_pad2" % (self.Name)
        if not hasattr(self, "Canvas"):
            #print canvasname
            if padOrCanvas == 0:
                self.Canvas = TCanvas(canvasname)
            else:
                self.Canvas = gPad
            self.Canvas.cd()
            self.Pad1 = TPad(pad1name, pad1name, 0, 0.25, 1, 1)
            self.Pad1.SetBottomMargin(0.1)
            self.Pad1.Draw()

            self.Canvas.cd()

            self.Pad2 = TPad(pad2name, pad2name, 0, 0, 1, 0.24)
            self.Pad2.SetTopMargin(0.1)
            self.Pad2.SetBottomMargin(0.1)
            self.Pad2.Draw()

        if padid == 0:
            self.Canvas.cd()
        elif padid == 1:
            self.Pad1.cd()
        if padid == 2:
            self.Pad2.cd()

        return self.Canvas

    def GetLegend(self):
        legendname = "%s_legend" % (self.Name)
        if not hasattr(self, "Legend"):
            self.Legend = TLegend(0.7, 0.6, 0.9, 0.9, "", "brNDC")
            self.Legend.SetName(legendname)
            self.Legend.AddEntry(self.Data, "Data", "lp")
            for st in reversed(self.Bkg.keys()):
                self.Legend.AddEntry(self.Bkg[st], st, "f")

        return self.Legend

    def GetSLegend(self):
        legendname = "%s_Slegend" % (self.Name)
        if not hasattr(self, "SLegend"):
            self.SLegend = TLegend(0.6, 0.6, 0.7, 0.9, "", "brNDC")
            self.SLegend.SetName(legendname)
            for st in self.Signal:
                self.SLegend.AddEntry(st, st.GetTitle(), "l")

        return self.SLegend

    def GetRatioPlot(self):
        rationame = "%s_Ratio" % (self.Name)
        if not hasattr(self, "Ratio"):
            self.Ratio = self.Data.Clone(rationame)
            self.Ratio.SetStats(0)
            self.Ratio.Divide(self.GetStack().GetStack().Last())
            for i in range(1, self.Data.GetNbinsX() + 1):
                self.Ratio.GetXaxis().SetBinLabel(i, "")
            self.Ratio.SetMarkerStyle(20)
            self.Ratio.GetYaxis().SetRangeUser(0, 2)
            self.Ratio.GetXaxis().SetLabelSize(0.)
            self.Ratio.GetYaxis().SetTitle("Data / MC")
            self.Ratio.GetXaxis().SetTitleSize(0.2)
            self.Ratio.GetXaxis().SetTitleOffset(0.25)
            self.Ratio.GetYaxis().SetLabelSize(0.1)
            self.Ratio.GetXaxis().SetTickLength(0.09)
            self.Ratio.GetYaxis().SetTitleSize(0.18)
            self.Ratio.GetYaxis().SetNdivisions(509)
            self.Ratio.GetYaxis().SetTitleOffset(0.25)
            self.Ratio.SetFillStyle(3001)

        return self.Ratio

    def GetRatioUnc(self):
        rationame = "%s_RatioUncert" % (self.Name)
        if not hasattr(self, "RatioUncert"):
            mc = self.GetStack().GetStack().Last()
            self.RatioUncert = mc.Clone(rationame)
            self.RatioUncert.SetStats(0)
            self.RatioUncert.Divide(mc)
            for i in range(1, self.Data.GetNbinsX() + 1):
                self.RatioUncert.GetXaxis().SetBinLabel(i, "")
            #self.RatioUncert.SetMarkerStyle(20)
            self.RatioUncert.GetYaxis().SetRangeUser(0, 2)
            #self.RatioUncert.GetXaxis().SetLabelSize( 0.)
            self.RatioUncert.GetYaxis().SetTitle("Data / MC")
            self.RatioUncert.GetXaxis().SetTitleSize(0.2)
            self.RatioUncert.GetXaxis().SetTitleOffset(0.25)
            self.RatioUncert.GetYaxis().SetLabelSize(0.1)
            self.RatioUncert.GetXaxis().SetTickLength(0.09)
            self.RatioUncert.GetYaxis().SetTitleSize(0.18)
            self.RatioUncert.GetYaxis().SetNdivisions(509)
            self.RatioUncert.GetYaxis().SetTitleOffset(0.25)
            self.RatioUncert.SetFillStyle(3001)
            self.RatioUncert.SetFillColor(1)

        return self.RatioUncert

    def GetLineOne(self):
        linename = "%s_lineone" % (self.Name)
        if not hasattr(self, "LineOne"):
            self.LineOne = TLine(self.GetRatioPlot().GetXaxis().GetXmin(),
                                 1.00,
                                 self.GetRatioPlot().GetXaxis().GetXmax(),
                                 1.00)
            self.LineOne.SetLineWidth(2)
            self.LineOne.SetLineStyle(7)

        return self.LineOne

    def Draw(self, normalizetodata=False, padOrCanvas=0):
        gStyle.SetOptTitle(0)
        #self.AddOF_UF_Bins()
        self.GetCanvas(1, padOrCanvas)
        self.Data.Draw("E")
        #if normalizetodata:
        #    print "Norm to data"
        self.GetStack(normalizetodata).Draw("HIST SAME")
        self.Data.Draw("E SAME P")
        if self.Signal:
            for s in self.Signal:
                s.Draw("E SAME HIST")
            self.GetSLegend().Draw()
        self.GetLegend().Draw()

        self.GetCanvas(2)
        self.GetRatioUnc().Draw("E2")
        self.GetRatioPlot().Draw("ep same")
        self.GetLineOne().Draw()

    def Write(self, propdir, normtodata, mkdir=False):
        if mkdir:
            propdir = propdir.mkdir(self.Name)
        propdir.cd()
        catdir = propdir.mkdir("cats")
        catdir.cd()
        self.Data.Write()
        for bkg in self.Bkg:
            self.Bkg[bkg].Write()
        self.GetStack(normtodata).GetStack().Last().Write("SumMC")

        if self.Signal:
            sigdir = propdir.mkdir("signals")
            sigdir.cd()
            for i in range(0, len(self.Signal)):
                self.Signal[i].Write()

        sampledir = propdir.mkdir("samples")
        sampledir.cd()
        for ss in self.Samples:
            ss.Write()

        propdir.cd()
        self.Draw(normtodata)
        self.GetCanvas(0).Write()