def frac2str(frac) :
    flatFraction = type(first(frac)) is float
    return ('\n'.join([''.join("%12s"%s for s in fakeProcesses()),
                       ''.join("%12s"%("%.3f"%frac[s]) for s in fakeProcesses())])
            if flatFraction
            else '\n'.join([''.join("%12s"%s for s in fakeProcesses())]
                           +[''.join("%12s"%("%.3f"%frac[s].GetBinContent(b)) for s in fakeProcesses())
                             for b in getBinIndices(first(frac))]))
def main() :
    parser = optparse.OptionParser(usage=usage)
    parser.add_option('-t', '--tag')
    parser.add_option('-i', '--input_dir')
    parser.add_option('-o', '--output_file')
    parser.add_option('-p', '--output_plot')
    parser.add_option('-v','--verbose', action='store_true', default=False)
    (opts, args) = parser.parse_args()
    requiredOptions = ['tag', 'input_dir', 'output_file', 'output_plot']
    otherOptions = ['verbose']
    allOptions = requiredOptions + otherOptions
    def optIsNotSpecified(o) : return not hasattr(opts, o) or getattr(opts,o) is None
    if any(optIsNotSpecified(o) for o in requiredOptions) : parser.error('Missing required option')
    tag = opts.tag
    inputDirname  = opts.input_dir
    outputFname   = opts.output_file
    outputPlotDir = opts.output_plot
    verbose       = opts.verbose
    if verbose : print '\nUsing the following options:\n'+'\n'.join("%s : %s"%(o, str(getattr(opts, o))) for o in allOptions)

    allInputFiles = getInputFiles(inputDirname, tag, verbose) # includes allBkg, which is used only for sys
    assert all(f for f in allInputFiles.values()), ("missing inputs: \n%s"%'\n'.join(["%s : %s"%kv for kv in allInputFiles.iteritems()]))
    outputPlotDir = outputPlotDir+('/' if not outputPlotDir.endswith('/') else '')
    mkdirIfNeeded(outputPlotDir)
    inputFiles = dict((k, v) for k, v in allInputFiles.iteritems() if k in fakeProcesses())
    if verbose : print 'Using the following input files:\n'+'\n'.join(["%s : %s"%(p, f.GetName()) for p,f in inputFiles.iteritems()])
    outputFile = r.TFile.Open(outputFname, 'recreate')
    buildMuonFractions    (inputFiles, outputPlotDir, outputFile, verbose)
    buildElectronFractions(inputFiles, outputPlotDir, outputFile, verbose)
    outputFile.Close()
    if verbose : print "output plots saved to %s"%outputPlotDir
    if verbose : print "output histos saved to %s"%outputFname
def buildMuonRates(inputFiles, outputfile, outplotdir, inputFracFile=None, verbose=False, zoomIn=False) :
    """
    For each selection region, build the real eff and fake rate
    histo as a weighted sum of the corresponding fractions.
    """
    processes = fakeProcesses()
    brsit, iF, v = buildRatioAndScaleIt, inputFiles, verbose
    print "buildMuonRates: values to be fixed: ",' '.join(["%s: %s"%(_, eval(_)) for _ in ['mu_qcdSF', 'mu_realSF']])
    eff_qcd  = dict((p, brsit('muon_qcdMC_all_l_pt_coarse',  iF[p], mu_qcdSF, v))  for p in processes)
    eff_real = dict((p, brsit('muon_realMC_all_l_pt_coarse', iF[p], mu_realSF, v)) for p in processes)
    eff2d_qcd  = dict((p, brsit('muon_qcdMC_all_l_pt_eta',  iF[p], mu_qcdSF, v))  for p in processes)
    eff2d_real = dict((p, brsit('muon_realMC_all_l_pt_eta', iF[p], mu_realSF, v)) for p in processes)
    lT, lX, lY = '#varepsilon(T|L)', 'p_{T} [GeV]', '#varepsilon(T|L)'
    plot1dEfficiencies(eff_qcd,  'eff_mu_qcd',  outplotdir, lT+' qcd fake #mu'+';'+lX+';'+lY, zoomIn=zoomIn)
    plot1dEfficiencies(eff_real, 'eff_mu_real', outplotdir, lT+' real #mu'    +';'+lX+';'+lY, zoomIn=zoomIn)
    lT, lX, lY = '#varepsilon(T|L)', 'p_{T} [GeV]', '#eta'
    plot2dEfficiencies(eff2d_qcd,  'eff2d_mu_qcd', outplotdir, lT+' qcd fake #mu'+';'+lX+';'+lY)
    plot2dEfficiencies(eff2d_real, 'eff2d_mu_real', outplotdir, lT+' real #mu'   +';'+lX+';'+lY)
    mu_frac = dict()
    for sr in selectionRegions() :
        fC, bP = fetchCompositions, buildPercentages
        isf = inputFracFile
        hnTemplateQcd = '%(proc)s_muon_'+sr+'_all_flavor_pt_den_qcd'
        hnTemplateReal = '%(proc)s_muon_'+sr+'_all_flavor_pt_den_real'
        frac_qcd  = fC(isf, hnTemplateQcd,  processes) if isf else bP(inputFiles, 'muon_'+sr+'_all_flavor_den', 'qcd')
        frac_real = fC(isf, hnTemplateReal, processes) if isf else bP(inputFiles, 'muon_'+sr+'_all_flavor_den', 'real')
        if verbose : print "mu : sr ",sr,"\n frac_qcd  : ",frac2str(frac_qcd )
        if verbose : print "mu : sr ",sr,"\n frac_real : ",frac2str(frac_real)
        fake1d = buildWeightedHisto(eff_qcd,  frac_qcd, 'mu_fake_rate_'+sr, 'Muon fake rate '+sr)
        real1d = buildWeightedHisto(eff_real, frac_real, 'mu_real_eff_'+sr, 'Muon real eff ' +sr)

        c2dC = compose2Dcompositions
        hnTemplateQcd = '%(proc)s_muon_'+sr+'_all_flavor_pt_%(etabin)s_den_qcd'
        hnTemplateReal = '%(proc)s_muon_'+sr+'_all_flavor_pt_%(etabin)s_den_real'
        frac_qcd2d  = c2dC(isf, hnTemplateQcd,  processes) if isf else frac_qcd
        frac_real2d = c2dC(isf, hnTemplateReal, processes) if isf else frac_real
        fake2d = buildWeightedHisto(eff2d_qcd,  frac_qcd2d, 'mu_fake_rate2d_'+sr, 'Muon fake rate #eta vs. p_{T}'+sr)
        real2d = buildWeightedHisto(eff2d_real, frac_real2d, 'mu_real_eff2d_'+sr, 'Muon real eff  #eta vs. p_{T}'+sr)

        outputfile.cd()
        fake1d.Write()
        real1d.Write()
        fake2d.Write()
        real2d.Write()
        mu_frac[sr] = {'qcd' : frac_qcd, 'real' : frac_real}
        if isRegionToBePlotted(sr) :
            print "plotting eff2d_mu_fake:"
            fake2d.Print('all')
            print "plotting eff2d_mu_real"
            real2d.Print('all')
            lT, lX, lY = '#varepsilon(T|L)', 'p_{T} [GeV]', '#eta'
            plot2dEfficiencies({sr : fake2d}, 'eff2d_mu_fake', outplotdir, lT+' fake #mu'+';'+lX+';'+lY)
            plot2dEfficiencies({sr : real2d}, 'eff2d_mu_real', outplotdir, lT+' real #mu'+';'+lX+';'+lY)
    #json_write(mu_frac, outplotdir+/outFracFilename)
    doPlotFractions = not inputFracFile
    if doPlotFractions : plotFractions(mu_frac, outplotdir, 'frac_mu')
def main() :
    parser = optparse.OptionParser(usage=usage)
    parser.add_option('-t', '--tag')
    parser.add_option('-i', '--input_dir')
    parser.add_option('-f', '--input_fractions')
    parser.add_option('-o', '--output_file')
    parser.add_option('-p', '--output_plot')
    parser.add_option('-s', '--input-el-sf', default=[], action='append', help='electron bin-by-bin scale factors (from compute_fake_el_scale_factor)')
    parser.add_option('-z', '--zoom-in', help='vertical axis efficiency plots')
    parser.add_option('-v','--verbose', action='store_true', default=False)
    (opts, args) = parser.parse_args()
    requiredOptions = ['tag', 'input_dir', 'output_file', 'output_plot']
    otherOptions = ['verbose']
    allOptions = requiredOptions + otherOptions
    def optIsNotSpecified(o) : return not hasattr(opts, o) or getattr(opts,o) is None
    if any(optIsNotSpecified(o) for o in requiredOptions) : parser.error('Missing required option')
    tag = opts.tag
    inputDirname  = opts.input_dir
    inputFracFname= opts.input_fractions
    inputSfFnames = opts.input_el_sf
    outputFname   = opts.output_file
    outputPlotDir = opts.output_plot
    zoomIn        = opts.zoom_in
    verbose       = opts.verbose
    if verbose : print '\nUsing the following options:\n'+'\n'.join("%s : %s"%(o, str(getattr(opts, o))) for o in allOptions)

    allInputFiles = getInputFiles(inputDirname, tag, verbose) # includes allBkg, which is used only for sys
    assert all(f for f in allInputFiles.values()), ("missing inputs: \n%s"%'\n'.join(["%s : %s"%kv for kv in allInputFiles.iteritems()]))
    if inputSfFnames and any([not os.path.exists(f) for f in inputSfFnames]) : parser.error("invalid electron sf file(s) %s"%inputSfFnames)
    outputPlotDir = outputPlotDir+'/' if not outputPlotDir.endswith('/') else ''
    mkdirIfNeeded(outputPlotDir)
    outputFile = r.TFile.Open(outputFname, 'recreate')
    inputFiles = dict((k, v) for k, v in allInputFiles.iteritems() if k in fakeProcesses())
    inputFracFile = r.TFile.Open(inputFracFname) if inputFracFname else None
    if inputFracFname and not inputFracFile : parser.error("invalid fraction file %s"%inputFracFname)

    buildMuonRates    (inputFiles, outputFile, outputPlotDir, inputFracFile=inputFracFile, verbose=verbose, zoomIn=zoomIn)
    buildElectronRates(inputFiles, outputFile, outputPlotDir, inputFracFile=inputFracFile, inputElecSfFiles=inputSfFnames, verbose=verbose, zoomIn=zoomIn)
    buildSystematics  (allInputFiles['allBkg'], outputFile, verbose)
    outputFile.Close()
    if verbose : print "output saved to \n%s"%'\n'.join([outputFname, outputPlotDir])
def buildElectronRates(inputFiles, outputfile, outplotdir, inputFracFile=None, inputElecSfFiles=[], verbose=False, zoomIn=False) :
    """
    For each selection region, build the real eff and fake rate
    histo as a weighted sum of the corresponding fractions.
    Note that the fake has two components (conversion and qcd).
    """
    processes = fakeProcesses()
    brsit, iF, v = buildRatioAndScaleIt, inputFiles, verbose
    # if we have the sf vs eta, use it in the 2d parametrization
    lepton = 'el'
    el_convSF_vs_eta = el_convSF if not inputElecSfFiles else fetchSfHistos(inputElecSfFiles, lepton, verbose)['conv']
    el_qcdSF_vs_eta  = el_qcdSF if not inputElecSfFiles else fetchSfHistos(inputElecSfFiles,  lepton, verbose)['hflf']
    if inputElecSfFiles : el_convSF_vs_eta.Print("all")
    if inputElecSfFiles : el_qcdSF_vs_eta.Print("all")

    eff_conv = dict((p, brsit('elec_convMC_all_l_pt_coarse', iF[p], el_convSF, v)) for p in processes)
    eff_qcd  = dict((p, brsit('elec_qcdMC_all_l_pt_coarse',  iF[p], el_qcdSF, v))  for p in processes)
    eff_real = dict((p, brsit('elec_realMC_all_l_pt_coarse', iF[p], el_realSF, v)) for p in processes)
    eff2d_conv = dict((p, brsit('elec_convMC_all_l_pt_eta', iF[p], el_convSF_vs_eta, v)) for p in processes)
    eff2d_qcd  = dict((p, brsit('elec_qcdMC_all_l_pt_eta',  iF[p], el_qcdSF_vs_eta, v))  for p in processes)
    eff2d_real = dict((p, brsit('elec_realMC_all_l_pt_eta', iF[p], el_realSF, v)) for p in processes)

    lT, lX, lY = '#varepsilon(T|L)', 'p_{T} [GeV]', '#varepsilon(T|L)'
    plot1dEfficiencies(eff_conv, 'eff_el_conv', outplotdir, lT+' conv fake el'+';'+lX+';'+lY, zoomIn=zoomIn)
    plot1dEfficiencies(eff_qcd,  'eff_el_qcd',  outplotdir, lT+' qcd fake el' +';'+lX+';'+lY, zoomIn=zoomIn)
    plot1dEfficiencies(eff_real, 'eff_el_real', outplotdir, lT+' real el'     +';'+lX+';'+lY, zoomIn=zoomIn)
    lT, lX, lY = '#varepsilon(T|L)', 'p_{T} [GeV]', '#eta'
    plot2dEfficiencies(eff2d_conv, 'eff2d_el_conv', outplotdir, lT+' conv fake el'+';'+lX+';'+lY)
    plot2dEfficiencies(eff2d_qcd,  'eff2d_el_qcd',  outplotdir, lT+' qcd fake el' +';'+lX+';'+lY)
    plot2dEfficiencies(eff2d_real, 'eff2d_el_real', outplotdir, lT+' real el'     +';'+lX+';'+lY)

    el_frac = dict()
    for sr in selectionRegions() :
        fC, bPt = fetchCompositions, buildPercentagesTwice
        isf = inputFracFile
        hnTemplateQcd  = '%(proc)s_elec_'+sr+'_all_flavor_pt_den_qcd'
        hnTemplateConv = '%(proc)s_elec_'+sr+'_all_flavor_pt_den_conv'
        hnTemplateReal = '%(proc)s_elec_'+sr+'_all_flavor_pt_den_real'
        frac_conv, frac_qcd= (fC(isf, hnTemplateConv,  processes), fC(isf, hnTemplateQcd,  processes)) if isf else bPt(inputFiles, 'elec_'+sr+'_all_flavor_den', 'conv', 'qcd')
        frac_real = fC(isf, hnTemplateReal, processes) if isf else buildPercentages(inputFiles, 'elec_'+sr+'_all_flavor_den', 'real')
        if verbose : print "el : sr ",sr,"\n frac_conv : ",frac2str(frac_conv)
        if verbose : print "el : sr ",sr,"\n frac_qcd  : ",frac2str(frac_qcd )
        if verbose : print "el : sr ",sr,"\n frac_real : ",frac2str(frac_real)
        real1d = buildWeightedHisto     (eff_real, frac_real,                     'el_real_eff_'+sr, 'Electron real eff '+sr)
        fake1d = buildWeightedHistoTwice(eff_conv, frac_conv, eff_qcd,  frac_qcd, 'el_fake_rate_'+sr, 'Electron fake rate '+sr)

        c2dC = compose2Dcompositions
        hnTemplateQcd  = '%(proc)s_elec_'+sr+'_all_flavor_pt_%(etabin)s_den_qcd'
        hnTemplateConv = '%(proc)s_elec_'+sr+'_all_flavor_pt_%(etabin)s_den_conv'
        hnTemplateReal = '%(proc)s_elec_'+sr+'_all_flavor_pt_%(etabin)s_den_real'
        frac_qcd2d  = c2dC(isf, hnTemplateQcd,  processes) if isf else frac_qcd
        frac_conv2d = c2dC(isf, hnTemplateConv, processes) if isf else frac_conv
        frac_real2d = c2dC(isf, hnTemplateReal, processes) if isf else frac_real
        real2d = buildWeightedHisto     (eff2d_real, frac_real2d,                     'el_real_eff2d_'+sr, 'Electron real eff  #eta vs. p_{T}'+sr)
        fake2d = buildWeightedHistoTwice(eff2d_conv, frac_conv2d, eff2d_qcd,  frac_qcd2d, 'el_fake_rate2d_'+sr, 'Electron fake rate  #eta vs. p_{T}'+sr)

        outputfile.cd()
        fake1d.Write()
        real1d.Write()
        fake2d.Write()
        real2d.Write()
        el_frac[sr] = {'conv' : frac_conv, 'qcd' : frac_qcd, 'real' : frac_real}
        if isRegionToBePlotted(sr) :
            lT, lX, lY = '#varepsilon(T|L)', 'p_{T} [GeV]', '#eta'
            plot2dEfficiencies({sr : fake2d}, 'eff2d_el_fake', outplotdir, lT+' fake e'+';'+lX+';'+lY)
            plot2dEfficiencies({sr : real2d}, 'eff2d_el_real', outplotdir, lT+' real e'+';'+lX+';'+lY)
    #json_write(el_frac, outFracFilename)
    doPlotFractions = not inputFracFile
    if doPlotFractions : plotFractions(el_frac, outplotdir, 'frac_el')