def runPseudoExperiments(wsfile,pefile,experimentTag,options):
    prepend = '[runPseudoExperiments %s] '%experimentTag

    #read the file with input distributions
    inputDistsF = ROOT.TFile.Open(pefile, 'READ')
    print prepend+'Reading PE input from %s with %s' % (pefile, experimentTag)
    if not checkKeyInFile(experimentTag, inputDistsF, doraise=False):
        print prepend+"ERROR: experiment tag %s not found in input file %s" %(experimentTag, pefile)
        sys.exit(-1)

    wsInputFile = ROOT.TFile.Open(wsfile, 'READ')
    ws = wsInputFile.Get('w')
    wsInputFile.Close()
    print prepend+'Read workspace from %s' % wsfile

    #readout calibration from a file
    calibMap=None
    if options.calib:
         cachefile = open(options.calib,'r')
         calibMap  = pickle.load(cachefile)
         cachefile.close()
         print prepend+'Read calibration from %s'%options.calib

    genMtop=172.5
    try:
        genMtop=float(experimentTag.rsplit('_', 1)[1].replace('v','.'))
    except (IndexError, ValueError) as e:
        print ("%sERROR: Could not extract generated mass value "
               "from experiment tag: '%s'"%(prepend, experimentTag))
        sys.exit(-1)
    print prepend+'Generated top mass is %5.1f GeV'%genMtop

    #prepare results summary
    selTag=''
    if len(options.selection)>0 : selTag='_%s'%options.selection
    summary=PseudoExperimentResults(genMtop=genMtop,
                                    outFileUrl=osp.join(options.outDir,
                                       '%s%s_results.root'%(experimentTag,selTag)),
                                    selection=options.selection)

    #load the model parameters and set all to constant
    ws.loadSnapshot("model_params")
    allVars = ws.allVars()
    varIter = allVars.createIterator()
    var = varIter.Next()
    varCtr=0
    while var :
        varName=var.GetName()
        if not varName in ['mtop', 'SVLMass', 'mu']:
            ws.var(varName).setConstant(True)
            varCtr+=1
        var = varIter.Next()
    print prepend+'setting to constant %d numbers in the model'%varCtr

    ws.var("mtop").setVal(genMtop)
    ws.var("mu").setVal(1.0)

    #build the relevant PDFs
    print prepend+"Building pdfs"
    channels = ['em','mm','ee','m','e','eplus','mplus','eminus','mminus']
    allPdfs = buildPDFs(ws=ws, options=options,
                        channels=channels,
                        calibMap=calibMap,
                        prepend=prepend)

    #throw pseudo-experiments
    poi = ROOT.RooArgSet( ws.var('mtop') )
    if options.verbose>1:
        print prepend+'Running %d experiments' % options.nPexp
        print 80*'-'

    # if not 'nominal' in experimentTag:
    #     cfilepath = osp.abspath(osp.join(osp.dirname(wsfile),'../../'))
    #     # cfilepath = osp.abspath(osp.join(osp.dirname(__file__),'../'))
    #     cfilepath = osp.join(cfilepath, ".svlsysthistos.pck")
    #     cachefile = open(cfilepath, 'r')
    #     systhistos = pickle.load(cachefile)
    #     print prepend+'>>> Read systematics histograms from cache (.svlsysthistos.pck)'
    #     cachefile.close()

    for i in xrange(0,options.nPexp):

        #iterate over available categories to build the set of likelihoods to combine
        indNLLs=[]
        nllMap={}
        allPseudoDataH=[]
        allPseudoData=[]
        if options.verbose>1 and options.verbose<=3:
            printProgress(i, options.nPexp, prepend+' ')

        for key in sorted(allPdfs):
            chsel, trk = key
            mukey=(chsel+'_mu',trk)
            if options.verbose>3:
                sys.stdout.write(prepend+'Exp %-3d (%-12s, %d):' % (i+1, chsel, trk))
                sys.stdout.flush()

            ws.var('mtop').setVal(172.5)
            ws.var('mu').setVal(1.0)

            #read histogram and generate random data
            ihist = inputDistsF.Get('%s/SVLMass_%s_%s_%d'%(experimentTag,chsel,experimentTag,trk))

            # Get number of events to be generated either:
            # - From properly scaled input files for nominal mass variations
            #   to estimate the actual statistical error
            # - From the number of generated MC events, to estimate statistical
            #   uncertainty of variation
            # THIS SCREWS UP THE MASS EXTRACTION: WHY??
            nevtsSeed = ihist.Integral()
            # if not 'nominal' in experimentTag:
            #     try:
            #         nevtsSeed = systhistos[(chsel, experimentTag.replace('_172v5',''),
            #                                 'tot' ,trk)].GetEntries() ## FIXME: GetEntries or Integral?
            #     except KeyError:
            #         print prepend+"  >>> COULD NOT FIND SYSTHISTO FOR",chsel, experimentTag, trk

            # print '[Generation] Will generate PEs with %6.1f events' % nevtsSeed
            nevtsToGen = ROOT.gRandom.Poisson(nevtsSeed)

            pseudoDataH,pseudoData=None,None
            if options.genFromPDF:
                obs = ROOT.RooArgSet(ws.var('SVLMass'))
                pseudoData = allPdfs[key].generateBinned(obs, nevtsToGen)
            else:
                pseudoDataH = ihist.Clone('peh')
                if options.nPexp>1:
                    pseudoDataH.Reset('ICE')
                    pseudoDataH.FillRandom(ihist, nevtsToGen)
                else:
                    print 'Single pseudo-experiment won\'t be randomized'
                pseudoData  = ROOT.RooDataHist('PseudoData_%s_%s_%d'%(experimentTag,chsel,trk),
                                               'PseudoData_%s_%s_%d'%(experimentTag,chsel,trk),
                                               ROOT.RooArgList(ws.var('SVLMass')), pseudoDataH)

            if options.verbose>3:
                sys.stdout.write(' [generated pseudodata]')
                sys.stdout.flush()

            #create likelihood : store it in the appropriate categories for posterior combination
            nll = allPdfs[key].createNLL(pseudoData, ROOT.RooFit.Extended())
            indNLLs.append( nll )

            chType=''
            if chsel in ['em','mm','ee']   : chType='ll'
            if chsel in ['e','m']          : chType='lj'
            if chsel in ['eplus','mplus']  : chType='lplus'
            if chsel in ['eminus','minus'] : chType='lminus'
            nllMapKeys=[('comb%s'%chsel,0),('comb%s'%chType,trk),('comb%s'%chType,0)]
            if chType!='lplus' and chType!='lminus':
                nllMapKeys.insert(0,('comb',trk))
                nllMapKeys.insert(0,('comb',0))
            for nllMapKey in nllMapKeys:
                if not (nllMapKey in nllMap):
                    nllMap[nllMapKey]=[]
                if nllMapKey[0]=='comb' and nllMapKey[1]==0:
                    nllMap[nllMapKey].append( nll )
                else:
                    nllMap[nllMapKey].append( nll )

            if options.verbose>3:
                sys.stdout.write(' [running Minuit]')
                sys.stdout.flush()

            minuit=ROOT.RooMinuit(nll)
            minuit.setErrorLevel(0.5)
            minuit.migrad()
            minuit.hesse()
            minuit.minos(poi)


            #save fit results
            summary.addFitResult(key=key,ws=ws)

            #show, if required
            selstring = options.selection if options.selection else 'inclusive'
            if options.spy and i==0:
                pll=nll.createProfile(poi)
                showFinalFitResult(data=pseudoData,pdf=allPdfs[key], nll=[pll],
                                   SVLMass=ws.var('SVLMass'),mtop=ws.var('mtop'),
                                   outDir=options.outDir,
                                   tag=[selstring,
                                   "%s channel, =%s tracks"%(
                                     str(chsel.split('_',1)[0]),
                                     str(trk))])
                #raw_input('press key to continue...')

            #save to erase later
            if pseudoDataH : allPseudoDataH.append(pseudoDataH)
            allPseudoData.append(pseudoData)
            if options.verbose>3:
                sys.stdout.write('%s DONE %s'
                                 '(mt: %6.2f+-%4.2f GeV, '
                                  'mu: %4.2f+-%4.2f'%
                                (bcolors.OKGREEN, bcolors.ENDC,
                                 ws.var('mtop').getVal(), ws.var('mtop').getError(),
                                 ws.var('mu').getVal(), ws.var('mu').getError()))
                if options.floatCorrFrac:
                    sys.stdout.write(' corfrac: %4.2f+-%4.2f)'% (
                                     ws.var('ttcorfracshift_%s_%d'%(chsel,trk)).getVal()+1.0,
                                     ws.var('ttcorfracshift_%s_%d'%(chsel,trk)).getError()))
                sys.stdout.write('\n')
                sys.stdout.flush()

        #combined likelihoods
        if options.verbose>3:
            print '%s------ Combining channels and categories'%(prepend)

        for key in sorted(nllMap.keys()):

            #reset to central values
            ws.var('mtop').setVal(172.5)
            ws.var('mu').setVal(1.0)

            #add the log likelihoods and minimize
            llSet = ROOT.RooArgSet()
            for ll in nllMap[key]: llSet.add(ll)
            combll = ROOT.RooAddition("combll","combll",llSet)
            minuit=ROOT.RooMinuit(combll)
            minuit.setErrorLevel(0.5)
            minuit.migrad()
            minuit.hesse()
            minuit.minos(poi)
            summary.addFitResult(key=key,ws=ws)

            combll.Delete()

            if options.verbose>3:
                try: catlabel = CATTOLABEL[('%s_%d'%key)]
                except KeyError: catlabel = CATTOLABEL[('%s_%d'%key).replace('_%s'%options.selection, '')]
                sys.stdout.write(prepend)
                sys.stdout.write('%8s (%2d cats): ' % (catlabel,len(nllMap[key])))
                resultstring = ('mt: %6.2f+-%4.2f GeV, mu: %5.3f+-%5.3f \n' % (
                                   ws.var('mtop').getVal(), ws.var('mtop').getError(),
                                   ws.var('mu').getVal(), ws.var('mu').getError()) )
                if key == ('comb', 0):
                    resultstring = bcolors.BOLD + resultstring + bcolors.ENDC
                sys.stdout.write(resultstring)
                sys.stdout.flush()
        print 80*'-'

        #free used memory
        for h in allPseudoDataH : h.Delete()
        for d in allPseudoData  : d.Delete()
        for ll in indNLLs       : ll.Delete()

    summary.saveResults()
        cfilepath = osp.abspath(osp.join(osp.dirname(wsfile),'../../'))
        # cfilepath = osp.abspath(osp.join(osp.dirname(__file__),'../'))
        cfilepath = osp.join(cfilepath, ".svlsysthistos.pck")
        cachefile = open(cfilepath, 'r')
        systhistos = pickle.load(cachefile)
        print prepend+'>>> Read systematics histograms from cache (.svlsysthistos.pck)'
        cachefile.close()

    for i in xrange(0,options.nPexp):

        #iterate over available categories to build the set of likelihoods to combine
        nllMap={}
        allPseudoDataH=[]
        allPseudoData=[]
        if options.verbose>1 and options.verbose<=3:
            printProgress(i, options.nPexp, prepend+' ')

        for key in sorted(allPdfs):
            chsel, trk = key
            mukey=(chsel+'_mu',trk)
            if options.verbose>3:
                sys.stdout.write(prepend+'Exp %-3d (%-2s, %d):' % (i+1, chsel, trk))
                sys.stdout.flush()

            ws.var('mtop').setVal(172.5)
            ws.var('mu').setVal(1.0)

            #read histogram and generate random data
            ihist = inputDistsF.Get('%s/SVLMass_%s_%s_%d'%(experimentTag,chsel,experimentTag,trk))

            # Get number of events to be generated either:
            
    histos[model]['Btype']=ROOT.TH1F('Btype',';B-hadron type;B-hadrons',4,0,4)
    histos[model]['Btype'].GetXaxis().SetBinLabel(1,'B^{0}')
    histos[model]['Btype'].GetXaxis().SetBinLabel(2,'B^{#pm}')
    histos[model]['Btype'].GetXaxis().SetBinLabel(3,'B_{s}')
    histos[model]['Btype'].GetXaxis().SetBinLabel(4,'Others')
    histos[model]['Btype'].SetTitle('%s'%model)
    histos[model]['Btype'].Sumw2()
    histos[model]['Btype'].SetDirectory(0)
    histos[model]['Btype_wgt']=histos[model]['Btype'].Clone('Btype_wgt')
    histos[model]['Btype_wgt'].SetDirectory(0)

    totalEntries=int(0.2*tree.GetEntriesFast())
    for i in xrange(0,totalEntries):
        tree.GetEntry(i)
        printProgress(i,totalEntries)
        
        for ib in xrange(0,tree.nB):

            bid,bidCtr='Others',3
            if ROOT.TMath.Abs(tree.Bid[ib])==511   : bid,bidCtr='B0',0
            elif ROOT.TMath.Abs(tree.Bid[ib])==521 : bid,bidCtr='Bpm',1
            elif ROOT.TMath.Abs(tree.Bid[ib])==531 : bid,bidCtr='Bs',2

            ptratio = tree.Bpt[ib]/tree.Bjpt[ib]
            
            if ptratio>fragWgt[model][bid].GetXaxis().GetXmax() : continue
            bwgt=fragWgt[model][bid].GetBinContent( fragWgt[model][bid].GetXaxis().FindBin(ptratio) )
            histos[model]['Btype'].Fill(bidCtr)
            histos[model]['Btype_wgt'].Fill(bidCtr,bwgt)
            for bkey in ['inc',bid]:
def runPseudoExperiments(wsfile,pefile,experimentTag,options):
    prepend = '[runPseudoExperiments %s] '%experimentTag

    #read the file with input distributions
    inputDistsF = ROOT.TFile.Open(pefile, 'READ')
    print prepend+'Reading PE input from %s with %s' % (pefile, experimentTag)
    if not checkKeyInFile(experimentTag, inputDistsF, doraise=False):
        print prepend+"ERROR: experiment tag %s not found in input file %s" %(experimentTag, pefile)
        sys.exit(-1)

    wsInputFile = ROOT.TFile.Open(wsfile, 'READ')
    ws = wsInputFile.Get('w')
    wsInputFile.Close()
    print prepend+'Read workspace from %s' % wsfile

    #readout calibration from a file
    calibMap=None
    if options.calib:
         cachefile = open(options.calib,'r')
         calibMap  = pickle.load(cachefile)
         cachefile.close()
         print prepend+'Read calibration from %s'%options.calib

    genMtop=172.5
    try:
        genMtop=float(experimentTag.rsplit('_', 1)[1].replace('v','.'))
    except (IndexError, ValueError) as e:
        print ("%sERROR: Could not extract generated mass value "
               "from experiment tag: '%s'"%(prepend, experimentTag))
        sys.exit(-1)
    print prepend+'Generated top mass is %5.1f GeV'%genMtop

    #prepare results summary
    selTag=''
    if len(options.selection)>0 : selTag='_%s'%options.selection
    summary=PseudoExperimentResults(genMtop=genMtop,
                                    outFileUrl=osp.join(options.outDir,
                                       '%s%s_results.root'%(experimentTag,selTag)),
                                    selection=options.selection)

    #load the model parameters and set all to constant
    ws.loadSnapshot("model_params")
    allVars = ws.allVars()
    varIter = allVars.createIterator()
    var = varIter.Next()
    varCtr=0
    while var :
        varName=var.GetName()
        if not varName in ['mtop', 'SVLMass', 'mu']:
            ws.var(varName).setConstant(True)
            varCtr+=1
        var = varIter.Next()
    print prepend+'setting to constant %d numbers in the model'%varCtr

    ws.var("mtop").setVal(genMtop)
    ws.var("mu").setVal(1.0)

    #build the relevant PDFs
    print prepend+"Building pdfs"
    allPdfs = buildPDFs(ws=ws, options=options,
                        calibMap=calibMap,
                        prepend=prepend)

    #throw pseudo-experiments
    poi = ROOT.RooArgSet( ws.var('mtop') )
    if options.verbose>1:
        print prepend+'Running %d experiments' % options.nPexp
        print 80*'-'

    # if not 'nominal' in experimentTag:
    #     cfilepath = osp.abspath(osp.join(osp.dirname(wsfile),'../../'))
    #     # cfilepath = osp.abspath(osp.join(osp.dirname(__file__),'../'))
    #     cfilepath = osp.join(cfilepath, ".svlsysthistos.pck")
    #     cachefile = open(cfilepath, 'r')
    #     systhistos = pickle.load(cachefile)
    #     print prepend+'>>> Read systematics histograms from cache (.svlsysthistos.pck)'
    #     cachefile.close()

    for i in xrange(0,options.nPexp):

        #iterate over available categories to build the set of likelihoods to combine
        indNLLs=[]
        nllMap={}
        allPseudoDataH=[]
        allPseudoData=[]
        if options.verbose>1 and options.verbose<=3:
            printProgress(i, options.nPexp, prepend+' ')

        for key in sorted(allPdfs):
            chsel, trk = key
            mukey=(chsel+'_mu',trk)
            if options.verbose>3:
                sys.stdout.write(prepend+'Exp %-3d (%-12s, %d):' % (i+1, chsel, trk))
                sys.stdout.flush()

            ws.var('mtop').setVal(172.5)
            ws.var('mu').setVal(1.0)

            #read histogram and generate random data
            ihist = inputDistsF.Get('%s/SVLMass_%s_%s_%d'%(experimentTag,chsel,experimentTag,trk))

            # Get number of events to be generated either:
            # - From properly scaled input files for nominal mass variations
            #   to estimate the actual statistical error
            # - From the number of generated MC events, to estimate statistical
            #   uncertainty of variation
            # THIS SCREWS UP THE MASS EXTRACTION: WHY??
            nevtsSeed = ihist.Integral()
            # if not 'nominal' in experimentTag:
            #     try:
            #         nevtsSeed = systhistos[(chsel, experimentTag.replace('_172v5',''),
            #                                 'tot' ,trk)].GetEntries() ## FIXME: GetEntries or Integral?
            #     except KeyError:
            #         print prepend+"  >>> COULD NOT FIND SYSTHISTO FOR",chsel, experimentTag, trk

            # print '[Generation] Will generate PEs with %6.1f events' % nevtsSeed
            nevtsToGen = ROOT.gRandom.Poisson(nevtsSeed)

            pseudoDataH,pseudoData=None,None
            if options.genFromPDF:
                obs = ROOT.RooArgSet(ws.var('SVLMass'))
                pseudoData = allPdfs[key].generateBinned(obs, nevtsToGen)
            else:
                pseudoDataH = ihist.Clone('peh')
                if options.nPexp>1:
                    pseudoDataH.Reset('ICE')
                    pseudoDataH.FillRandom(ihist, nevtsToGen)
                else:
                    print 'Single pseudo-experiment won\'t be randomized'
                pseudoData  = ROOT.RooDataHist('PseudoData_%s_%s_%d'%(experimentTag,chsel,trk),
                                               'PseudoData_%s_%s_%d'%(experimentTag,chsel,trk),
                                               ROOT.RooArgList(ws.var('SVLMass')), pseudoDataH)

            if options.verbose>3:
                sys.stdout.write(' [generated pseudodata]')
                sys.stdout.flush()

            #create likelihood : store it in the appropriate categories for posterior combination
            nll = allPdfs[key].createNLL(pseudoData, ROOT.RooFit.Extended())
            indNLLs.append( nll )

            chType=''
            if chsel in ['em','mm','ee']   : chType='ll'
            if chsel in ['e','m']          : chType='lj'
            if chsel in ['eplus','mplus']  : chType='lplus'
            if chsel in ['eminus','minus'] : chType='lminus'
            nllMapKeys=[('comb%s'%chsel,0),('comb%s'%chType,trk),('comb%s'%chType,0)]
            if chType!='lplus' and chType!='lminus':
                nllMapKeys.insert(0,('comb',trk))
                nllMapKeys.insert(0,('comb',0))
            for nllMapKey in nllMapKeys:
                if not (nllMapKey in nllMap):
                    nllMap[nllMapKey]=[]
                if nllMapKey[0]=='comb' and nllMapKey[1]==0:
                    nllMap[nllMapKey].append( nll )                
                else:
                    nllMap[nllMapKey].append( nll )
            
            if options.verbose>3:
                sys.stdout.write(' [running Minuit]')
                sys.stdout.flush()

            minuit=ROOT.RooMinuit(nll)
            minuit.setErrorLevel(0.5)
            minuit.migrad()
            minuit.hesse()
            minuit.minos(poi)
            

            #save fit results
            summary.addFitResult(key=key,ws=ws)

            #show, if required
            selstring = options.selection if options.selection else 'inclusive'
            if options.spy and i==0:
                pll=nll.createProfile(poi)
                showFinalFitResult(data=pseudoData,pdf=allPdfs[key], nll=[pll],
                                   SVLMass=ws.var('SVLMass'),mtop=ws.var('mtop'),
                                   outDir=options.outDir,
                                   tag=[selstring,
                                   "%s channel, =%s tracks"%(
                                     str(chsel.split('_',1)[0]),
                                     str(trk))])
                #raw_input('press key to continue...')

            #save to erase later
            if pseudoDataH : allPseudoDataH.append(pseudoDataH)
            allPseudoData.append(pseudoData)
            if options.verbose>3:
                sys.stdout.write('%s DONE %s'
                                 '(mt: %6.2f+-%4.2f GeV, '
                                  'mu: %4.2f+-%4.2f'%
                                (bcolors.OKGREEN, bcolors.ENDC,
                                 ws.var('mtop').getVal(), ws.var('mtop').getError(),
                                 ws.var('mu').getVal(), ws.var('mu').getError()))
                if options.floatCorrFrac:
                    sys.stdout.write(' corfrac: %4.2f+-%4.2f)'% (
                                     ws.var('ttcorfracshift_%s_%d'%(chsel,trk)).getVal()+1.0,
                                     ws.var('ttcorfracshift_%s_%d'%(chsel,trk)).getError()))
                sys.stdout.write('\n')
                sys.stdout.flush()

        #combined likelihoods
        if options.verbose>3:
            print '%s------ Combining channels and categories'%(prepend)

        for key in sorted(nllMap.keys()):

            #reset to central values
            ws.var('mtop').setVal(172.5)
            ws.var('mu').setVal(1.0)

            #add the log likelihoods and minimize
            llSet = ROOT.RooArgSet()
            for ll in nllMap[key]: llSet.add(ll)
            combll = ROOT.RooAddition("combll","combll",llSet)
            minuit=ROOT.RooMinuit(combll)
            minuit.setErrorLevel(0.5)
            minuit.migrad()
            minuit.hesse()
            minuit.minos(poi)
            summary.addFitResult(key=key,ws=ws)

            combll.Delete()

            if options.verbose>3:
                try: catlabel = CATTOLABEL[('%s_%d'%key)]
                except KeyError: catlabel = CATTOLABEL[('%s_%d'%key).replace('_%s'%options.selection, '')]
                sys.stdout.write(prepend)
                sys.stdout.write('%8s (%2d cats): ' % (catlabel,len(nllMap[key])))
                resultstring = ('mt: %6.2f+-%4.2f GeV, mu: %5.3f+-%5.3f \n' % (
                                   ws.var('mtop').getVal(), ws.var('mtop').getError(),
                                   ws.var('mu').getVal(), ws.var('mu').getError()) )
                if key == ('comb', 0):
                    resultstring = bcolors.BOLD + resultstring + bcolors.ENDC
                sys.stdout.write(resultstring)
                sys.stdout.flush()
        print 80*'-'

        #free used memory
        for h in allPseudoDataH : h.Delete()
        for d in allPseudoData  : d.Delete()
        for ll in indNLLs       : ll.Delete()

    summary.saveResults()
示例#5
0
    histos[model]['Btype'] = ROOT.TH1F('Btype', ';B-hadron type;B-hadrons', 4,
                                       0, 4)
    histos[model]['Btype'].GetXaxis().SetBinLabel(1, 'B^{0}')
    histos[model]['Btype'].GetXaxis().SetBinLabel(2, 'B^{#pm}')
    histos[model]['Btype'].GetXaxis().SetBinLabel(3, 'B_{s}')
    histos[model]['Btype'].GetXaxis().SetBinLabel(4, 'Others')
    histos[model]['Btype'].SetTitle('%s' % model)
    histos[model]['Btype'].Sumw2()
    histos[model]['Btype'].SetDirectory(0)
    histos[model]['Btype_wgt'] = histos[model]['Btype'].Clone('Btype_wgt')
    histos[model]['Btype_wgt'].SetDirectory(0)

    totalEntries = tree.GetEntriesFast()
    for i in xrange(0, totalEntries):
        tree.GetEntry(i)
        printProgress(i, totalEntries)

        for ib in xrange(0, tree.nB):

            bid, bidCtr = 'Others', 3
            if ROOT.TMath.Abs(tree.Bid[ib]) == 511: bid, bidCtr = 'B0', 0
            elif ROOT.TMath.Abs(tree.Bid[ib]) == 521: bid, bidCtr = 'Bpm', 1
            elif ROOT.TMath.Abs(tree.Bid[ib]) == 531: bid, bidCtr = 'Bs', 2

            ptratio = tree.Bpt[ib] / tree.Bjpt[ib]

            if ptratio > fragWgt[model][bid].GetXaxis().GetXmax(): continue
            bwgt = fragWgt[model][bid].GetBinContent(
                fragWgt[model][bid].GetXaxis().FindBin(ptratio))
            histos[model]['Btype'].Fill(bidCtr)
            histos[model]['Btype_wgt'].Fill(bidCtr, bwgt)