def buildWeightedHisto(histos={}, fractions={}, histoName='', histoTitle='') :
    "was getFinalRate"
    hout = first(histos).Clone(histoName if histoName else 'final_rate') # should pick a better default
    hout.SetTitle(histoTitle)
    hout.Reset()
    flatFraction = type(first(fractions)) is float
    if flatFraction :
        print "averaging flat ",histoName
        print 'keys -> ',histos.keys()
        for b in getBinIndices(hout) :
            tot, err2 = binWeightedSum(histos, fractions, b)
            hout.SetBinContent(b, tot)
            hout.SetBinError(b, sqrt(err2))
    else :
        bH, bF = getBinning(first(histos)), getBinning(first(fractions))
        assert bH == bF,"different binning %s: %s, %s: %s"%(first(histos).GetName(), bH, first(fractions).GetName(), bF)
        weightedHistos = dict((p, h.Clone(h.GetName()+'_weighted_for_'+histoName)) for p,h in histos.iteritems()) # preserve originals
        print "averaging 2d ",histoName
        for b in getBinIndices(hout):
            print "bin %d (w=%.1f):  %.3f = %s"%(b,
                                                 sum(fractions[p].GetBinContent(b) for p in fractions.keys()),
                                                 sum(fractions[p].GetBinContent(b)*weightedHistos[p].GetBinContent(b) for p in fractions.keys()),
                                                 '+'.join("%.2f*%.2f"%(fractions[p].GetBinContent(b), weightedHistos[p].GetBinContent(b))
                                                          for p in fractions.keys()))
        for p,h in weightedHistos.iteritems() :
            h.Multiply(fractions[p])
            hout.Add(h)
    return hout
def buildWeightedHistoTwice(histosA={}, fractionsA={}, histosB={}, fractionsB={},
                            histoName='', histoTitle='') :
    "was getFinalRate"
    assert not set(histosA)-set(histosB),"different keys A[%s], B[%s]"%(str(histosA.keys()), str(histosB.keys()))
    assert type(first(fractionsA)) is type(first(fractionsB)),"etherogenous fractions A %s, B %s"%(type(first(fractionsA)), type(first(fractionsB)))
    hout = first(histosA).Clone(histoName if histoName else 'final_rate') # should pick a better default
    hout.SetTitle(histoTitle)
    hout.Reset()
    flatFraction = type(first(fractionsA)) is float
    if flatFraction :
        print "averaging flat ",histoName
        print 'keys -> ',histosA.keys()
        for b in getBinIndices(hout) :
            totA, errA2 = binWeightedSum(histosA, fractionsA, b)
            totB, errB2 = binWeightedSum(histosB, fractionsB, b)
            hout.SetBinContent(b, totA + totB)
            hout.SetBinError(b, sqrt(errA2 + errB2))
    else :
        bHA, bFA = getBinning(first(histosA)), getBinning(first(fractionsA))
        bHB, bFB = getBinning(first(histosB)), getBinning(first(fractionsB))
        assert bHA == bFA,"different binning %s: %s, %s: %s"%(first(histosA).GetName(), bHA, first(fractionsA).GetName(), bFA)
        assert bHB == bFB,"different binning %s: %s, %s: %s"%(first(histosB).GetName(), bHB, first(fractionsB).GetName(), bFB)
        assert bHA == bHB,"different binning %s: %s, %s: %s"%(first(histosA).GetName(), bHA, first(histosB).GetName(), bHB)
        weightedHistosA = dict((p, h.Clone(h.GetName()+'_weighted_for_'+histoName)) for p,h in histosA.iteritems()) # preserve originals
        weightedHistosB = dict((p, h.Clone(h.GetName()+'_weighted_for_'+histoName)) for p,h in histosB.iteritems())


        print "averaging 2d ",histoName
        for b in getBinIndices(hout):
            print "bin %d (w=%.1f):  %.3f = %s"%(b,
                                                 sum(fractionsA[p].GetBinContent(b)+fractionsB[p].GetBinContent(b) for p in fractionsA.keys()),
                                                 sum(fractionsA[p].GetBinContent(b)*weightedHistosA[p].GetBinContent(b)
                                                     +fractionsB[p].GetBinContent(b)*weightedHistosB[p].GetBinContent(b)
                                                     for p in fractionsA.keys()),
                                                 '+'.join(["%.2f*%.2f"%(fractionsA[p].GetBinContent(b),
                                                                        weightedHistosA[p].GetBinContent(b))
                                                           for p in fractionsA.keys()]+
                                                          ["%.2f*%.2f"%(fractionsB[p].GetBinContent(b),
                                                                        weightedHistosB[p].GetBinContent(b))
                                                           for p in fractionsB.keys()]))


        for p in weightedHistosA.keys() :
            hA, fA = weightedHistosA[p], fractionsA[p]
            hB, fB = weightedHistosB[p], fractionsB[p]
            hA.Multiply(fA)
            hB.Multiply(fB)
            hout.Add(hA)
            hout.Add(hB)
    return hout