예제 #1
0
    def createHistograms(self, hist_cfg, all_stack=False, verbose=False, friend_func=None, vcfgs=None):
        '''Method to create actual histogram (DataMCPlot) instances from histogram 
        config; this version handles multiple variables via MultiDraw.
        '''
        
#        set_trace()
        pool = Pool(processes=len(self.hist_cfg.cfgs))
        print('number of processes for filling histos (ie. samples): %i'%len(self.hist_cfg.cfgs))

        result = pool.map(self.makealltheplots, self.hist_cfg.cfgs) # for no return 
#        result = pool.apply_async(self.makealltheplots, self.hist_cfg.cfgs) # for no return 
#        self.plots = result.get() 
#        set_trace()
        for i, cfg in enumerate(self.hist_cfg.cfgs):
            stack = not cfg.is_data and not cfg.is_signal
#            print(cfg.name, stack)
            for vcfg in self.vcfgs:
                hist = result[i][vcfg.name].histos[0].obj # result[0]['CR_hnl_m_12'].histos[0]
#                hist = hists[vcfg.name]
                plot = self.plots[vcfg.name]

#                hist.Scale(cfg.scale)
#                set_trace()
                if cfg.name in plot:
                    print 'Histogram', cfg.name, 'already exists; adding...', cfg.dir_name
                    hist_to_add = Histogram(cfg.name, hist)
                    if not cfg.is_data:
                        hist_to_add.SetWeight(hist_cfg.lumi*cfg.xsec/cfg.sumweights)
                    plot[cfg.name].Add(hist_to_add)
                else:
#                    print(cfg.name, hist.GetEntries(), stack)
                    plot_hist = plot.AddHistogram(cfg.name, hist, stack=stack)
#                    print('added histo %s'%vcfg.name)

                    if not cfg.is_data:
                        plot_hist.SetWeight(self.hist_cfg.lumi*cfg.xsec/cfg.sumweights)
#                print(cfg.name, vcfg.name, len(plot.histos))
        print('initializing histos done, making stacks...')

        for plot in self.plots.itervalues():
            plot._ApplyPrefs()

        print('number of processes for drawing (ie. stacks to draw): %i'%len(self.plots))
        procs = []
        for i, plot in enumerate(self.plots.itervalues()):
            proc = Process(target=plot.Draw, args=())
            procs.append(proc)
            proc.start()
     
        for proc in procs:
            proc.join()       

#        for plot in self.plots.itervalues():
#            plot._ApplyPrefs()
#            plot.Draw()
        return self.plots
예제 #2
0
    def AddHistogram(self, name, histo, layer=0, legendLine=None):
        '''Add a ROOT histogram, with a given name.

        Histograms will be drawn by increasing layer.'''
        tmp = Histogram(name, histo, layer, legendLine)
        self.histos.append(tmp)
        self.histosDict[name] = tmp
예제 #3
0
파일: HistCreator.py 프로젝트: mschoene/HNL
    def makealltheplots(self, cfg):
        verbose=False
        friend_func=None
        all_stack=False
    #    for cfg in [hist_cfg.cfgs[0]]:
    #    for cfg in hist_cfg.cfgs:
            # First check whether it's a sub-histo or not
        if isinstance(cfg, HistogramCfg):
            hists = createHistograms(cfg, all_stack=True, vcfgs=self.vcfgs)
            for h in hists: print(h)
            for vcfg in self.vcfgs:
                hist = hists[vcfg.name]
                plot = self.plots[vcfg.name]
                set_trace()
                hist._BuildStack(hist._SortedHistograms(), ytitle='Events')
                print('stack built')
                total_hist = plot.AddHistogram(cfg.name, hist.stack.totalHist.weighted, stack=True)

                if cfg.norm_cfg is not None:
                    norm_hist = createHistogram(cfg.norm_cfg, all_stack=True)
                    norm_hist._BuildStack(norm_hist._SortedHistograms(), ytitle='Events')
                    total_hist.Scale(hist.stack.integral/total_hist.Yield())

                if cfg.total_scale is not None:
                    total_hist.Scale(cfg.total_scale)
                    # print 'Scaling total', hist_cfg.name, 'by', cfg.total_scale
        else:
            # print('building histgrams for %s'%cfg.name)
            # It's a sample cfg

            # Now read the tree
            if cfg.dir_name == "DDE":
                # file_name = '/'.join([cfg.ana_dir, cfg.dir_name, cfg.tree_prod_name, 'tree_fr_DR_data_v2.root'])
                file_name = '/'.join([cfg.ana_dir, cfg.dir_name, cfg.tree_prod_name, 'tree_fr_DR_data_v2_oldVars.root'])

            else:
                file_name = '/'.join([cfg.ana_dir, cfg.dir_name, cfg.tree_prod_name, 'tree.root'])

            # attach the trees to the first DataMCPlot
            plot = self.plots[self.vcfgs[0].name]
            try:
                ttree = plot.readTree(file_name, cfg.tree_name, verbose=verbose, friend_func=friend_func)
            except:
                set_trace()

            norm_cut = self.hist_cfg.cut
            shape_cut = self.hist_cfg.cut

            if cfg.norm_cut:
#                norm_cut = cfg.norm_cut
                norm_cut += cfg.norm_cut  # to add met filters only for data
#            print('sample = %s, cuts = %s'%(cfg.name, norm_cut))
            if cfg.shape_cut:
                shape_cut = cfg.shape_cut

            weight = self.hist_cfg.weight
            if cfg.weight_expr:
                weight = '*'.join([weight, cfg.weight_expr])

            if cfg.cut_replace_func:
                norm_cut = cfg.cut_replace_func(norm_cut)
                shape_cut = cfg.cut_replace_func(norm_cut)


            #if needed, apply the loose selection for the non-prompt region
            if cfg.is_dde == True:
                norm_cut = norm_cut.replace('l1_reliso_rho_04 < 0.15 & l2_reliso_rho_04 < 0.15 & hnl_iso04_rel_rhoArea < 1','(l1_reliso05 > 0.15 | l2_reliso05 > 0.15) & hnl_iso04_rel_rhoArea < 1')
                shape_cut = shape_cut.replace('l1_reliso_rho_04 < 0.15 & l2_reliso_rho_04 < 0.15 & hnl_iso04_rel_rhoArea < 1','(l1_reliso05 > 0.15 | l2_reliso05 > 0.15) & hnl_iso04_rel_rhoArea < 1')

            if 'Conversion' in cfg.name:
                norm_cut = norm_cut + ' & (l0_gen_match_pdgid == 22 | l1_gen_match_pdgid == 22 | l2_gen_match_pdgid ==22)'
                shape_cut = shape_cut + ' & (l0_gen_match_pdgid == 22 | l1_gen_match_pdgid == 22 | l2_gen_match_pdgid ==22)'

            if self.hist_cfg.weight:
                norm_cut = '({c}) * {we}'.format(c=norm_cut, we=weight)
                shape_cut = '({c}) * {we}'.format(c=shape_cut, we=weight)

            #insert the fake rate weight for doublefakes
            if cfg.is_dde == True and cfg.is_doublefake == True:
                norm_cut = '({c}) * {we}'.format(c=norm_cut, we='weight_fr/(1-weight_fr)')
                shape_cut = '({c}) * {we}'.format(c=shape_cut, we='weight_fr/(1-weight_fr)')

            #insert the fake rate weight for singlefakes
            if cfg.is_dde == True and cfg.is_singlefake == True:
                norm_cut = '({c}) * {we}'.format(c=norm_cut, we='((weight_fr/(1-weight_fr))-((weight_fr/(1-weight_fr))*(weight_fr/(1-weight_fr))))')
                shape_cut = '({c}) * {we}'.format(c=shape_cut, we='((weight_fr/(1-weight_fr))-((weight_fr/(1-weight_fr))*(weight_fr/(1-weight_fr))))')

            # print '#### FULL CUT ####', norm_cut

            #adapt branch names to different software versions
            if not ttree.FindBranch("l0_reliso_rho_04"): 
                norm_cut = norm_cut.replace('l0_reliso_rho_04','l0_reliso05')
                shape_cut = shape_cut.replace('l0_reliso_rho_04','l0_reliso05')
                norm_cut = norm_cut.replace('l1_reliso_rho_04','l1_reliso05')
                shape_cut = shape_cut.replace('l1_reliso_rho_04','l1_reliso05')
                norm_cut = norm_cut.replace('l2_reliso_rho_04','l2_reliso05')
                shape_cut = shape_cut.replace('l2_reliso_rho_04','l2_reliso05')
 
            if not ttree.FindBranch("hnl_iso04_rel_rhoArea"): 
                norm_cut = norm_cut.replace('hnl_iso04_rel_rhoArea','hnl_iso_rel')
                shape_cut = shape_cut.replace('hnl_iso04_rel_rhoArea','hnl_iso_rel')


            # Initialise all hists before the multidraw
            hists = {}

            for vcfg in self.vcfgs:
                hname = '_'.join([self.hist_cfg.name, hashlib.md5(self.hist_cfg.cut).hexdigest(), cfg.name, vcfg.name, cfg.dir_name])
                if any(str(b) == 'xmin' for b in vcfg.binning):
                    hist = TH1F(hname, '', vcfg.binning['nbinsx'],
                                vcfg.binning['xmin'], vcfg.binning['xmax'])
                else:
                    hist = TH1F(hname, '', len(vcfg.binning)-1, vcfg.binning)

                initHist(hist, vcfg)
                hists[vcfg.name] = hist


            var_hist_tuples = []

            for vcfg in self.vcfgs:
                var_hist_tuples.append('{var} >> {hist}'.format(var=vcfg.drawname, hist=hists[vcfg.name].GetName()))

                        

            # Implement the multidraw.
            try:
                ttree.MultiDraw(var_hist_tuples, norm_cut)
            except:
                set_trace()
            

            # Do another multidraw here, if needed, and reset the scales in a separate loop
            if shape_cut != norm_cut:
                scale = hist.Integral()
                ttree.Project(hname, vcfg.drawname, shape_cut)
                try:
                    hist.Scale(scale/hist.Integral())
                except:
                    set_trace()

            stack = all_stack or (not cfg.is_data and not cfg.is_signal)

            # set_trace()

            # Loop again over the variables and add histograms to self.plots one by one
            for vcfg in self.vcfgs:
                hist = hists[vcfg.name]
                plot = self.plots[vcfg.name]

                hist.Scale(cfg.scale)

                if cfg.name in plot:
                    # print 'Histogram', cfg.name, 'already exists; adding...', cfg.dir_name
                    hist_to_add = Histogram(cfg.name, hist)
                    if (not cfg.is_data) and (not cfg.is_dde):
                        hist_to_add.SetWeight(self.hist_cfg.lumi*cfg.xsec/cfg.sumweights)
                    if cfg.is_dde:
                        # hist_to_add.SetWeight(hist_to_add.obj.GetEntries()/cfg.sumweights)
                        hist_to_add.SetWeight(cfg.sumweights)
    
                    plot[cfg.name].Add(hist_to_add)
                else:
#                    print(cfg.name, hist.GetEntries(), stack)
                    plot_hist = plot.AddHistogram(cfg.name, hist, stack=stack)
#                    print('added histo %s for %s'%(vcfg.name,cfg.name))

                    if (not cfg.is_data) and (not cfg.is_dde):
                        plot_hist.SetWeight(self.hist_cfg.lumi*cfg.xsec/cfg.sumweights)
                    if cfg.is_dde:
                        try:
                            # plot_hist.SetWeight(plot_hist.obj.GetEntries()/cfg.sumweights)
                            plot_hist.SetWeight(cfg.sumweights)
                        except:
                            set_trace()
            print('added histograms for %s'%cfg.name)
            PLOTS = self.plots
        return PLOTS
예제 #4
0
파일: HistCreator.py 프로젝트: mschoene/HNL
def createHistogram(hist_cfg, all_stack=False, verbose=False, friend_func=None):
    '''Method to create actual histogram (DataMCPlot) instance from histogram 
    config.
    '''
    plot = DataMCPlot(hist_cfg.var.name)
    plot.lumi = hist_cfg.lumi
    vcfg = hist_cfg.var
    for cfg in hist_cfg.cfgs:
        # First check whether it's a sub-histo or not
        if isinstance(cfg, HistogramCfg):
            hist = createHistogram(cfg, all_stack=True)
            hist._BuildStack(hist._SortedHistograms(), ytitle='Events')

            total_hist = plot.AddHistogram(cfg.name, hist.stack.totalHist.weighted, stack=True)

            if cfg.norm_cfg is not None:
                norm_hist = createHistogram(cfg.norm_cfg, all_stack=True)
                norm_hist._BuildStack(norm_hist._SortedHistograms(), ytitle='Events')
                total_hist.Scale(hist.stack.integral/total_hist.Yield())

            if cfg.total_scale is not None:
                total_hist.Scale(cfg.total_scale)
        else:
            # It's a sample cfg
            hname = '_'.join([hist_cfg.name, hashlib.md5(hist_cfg.cut).hexdigest(), cfg.name, vcfg.name, cfg.dir_name])
            if any(str(b) == 'xmin' for b in vcfg.binning):
                hist = TH1F(hname, '', vcfg.binning['nbinsx'],
                            vcfg.binning['xmin'], vcfg.binning['xmax'])
            else:
                hist = TH1F(hname, '', len(vcfg.binning)-1, vcfg.binning)

            initHist(hist, vcfg)

            file_name = '/'.join([cfg.ana_dir, cfg.dir_name, cfg.tree_prod_name, 'tree.root'])

            ttree = plot.readTree(file_name, cfg.tree_name, verbose=verbose, friend_func=friend_func)

            norm_cut = hist_cfg.cut
            shape_cut = hist_cfg.cut

            if cfg.norm_cut:
                norm_cut = cfg.norm_cut

            if cfg.shape_cut:
                shape_cut = cfg.shape_cut

            if cfg.cut_replace_func:
                norm_cut = cfg.cut_replace_func(norm_cut)
                shape_cut = cfg.cut_replace_func(norm_cut)

            weight = hist_cfg.weight
            if cfg.weight_expr:
                weight = '*'.join([weight, cfg.weight_expr])

            if hist_cfg.weight:
                norm_cut = '({c}) * {we}'.format(c=norm_cut, we=weight)
                shape_cut = '({c}) * {we}'.format(c=shape_cut, we=weight)

            ttree.Project(hname, vcfg.drawname, norm_cut)

            if shape_cut != norm_cut:
                scale = hist.Integral()
                ttree.Project(hname, vcfg.drawname, shape_cut)
                hist.Scale(scale/hist.Integral())

            stack = all_stack or (not cfg.is_data and not cfg.is_signal)

            hist.Scale(cfg.scale)

            if cfg.name in plot:
                # print 'Histogram', cfg.name, 'already exists; adding...', cfg.dir_name
                hist_to_add = Histogram(cfg.name, hist)
                if (not cfg.is_data) and (not cfg.is_dde):
                    hist_to_add.SetWeight(hist_cfg.lumi*cfg.xsec/cfg.sumweights)
                if cfg.is_dde:
                    # hist_to_add.SetWeight(hist_to_add.obj.GetEntries()/cfg.sumweights)
                    hist_to_add.SetWeight(cfg.sumweights)
                plot[cfg.name].Add(hist_to_add)
            else:
                plot_hist = plot.AddHistogram(cfg.name, hist, stack=stack)

                if (not cfg.is_data) and (not cfg.is_dde):
                    plot_hist.SetWeight(hist_cfg.lumi*cfg.xsec/cfg.sumweights)
                if cfg.is_dde:
                    # plot_hist.SetWeight(plot_hist.obj.GetEntries()/cfg.sumweights)
                    plot_hist.SetWeight(cfg.sumweights)

    plot._ApplyPrefs()
    return plot
예제 #5
0
파일: HistCreator.py 프로젝트: mschoene/HNL
    def createHistograms(self, hist_cfg, all_stack=False, verbose=False, friend_func=None, vcfgs=None, multiprocess = True):
        '''Method to create actual histogram (DataMCPlot) instances from histogram 
        config; this version handles multiple variables via MultiDraw.
        '''
        
        print('###########################################################')
        print('# creating histograms for %i sample(s)...'%len(self.hist_cfg.cfgs))
        if multiprocess == True:
            print('# multiprocess-mode: ON')
        if multiprocess == False:
            print('# multiprocess-mode: OFF')
        print('###########################################################')

        if multiprocess == True:
            #using multiprocess to create the histograms
            pool = Pool(processes=len(self.hist_cfg.cfgs))
            result = pool.map(self.makealltheplots, self.hist_cfg.cfgs) 
       
        # if we don't use multiprocess, we compute the histos one by one - good for debugging.
        if multiprocess == False:
            for i, cfg in enumerate(self.hist_cfg.cfgs):
                # result = self.makealltheplots(self.hist_cfg.cfgs[i]) 
                try:
                    result = self.makealltheplots(self.hist_cfg.cfgs[i]) 
                except:
                    set_trace()

#        workers = cpu_count()
#        result = []
#        batches = len(self.hist_cfg.cfgs) / workers + 1 if len(self.hist_cfg.cfgs) % workers != 0 else len(self.hist_cfg.cfgs) / workers
#        pool = Pool(processes=batches)
#        print('number of batches for filling histos (%i samples each): %i'%(workers, batches))
#        for i in range(batches):
#           try:    histlist = self.hist_cfg.cfgs[i*workers:(i+1)*workers] 
#           except: print('entering exception'); histlist = self.hist_cfg.cfgs[(batches-1)*workers:len(self.hist_cfg.cfgs)-1]
#           result += pool.map(self.makealltheplots, histlist)

        for i, cfg in enumerate(self.hist_cfg.cfgs):
            stack = not cfg.is_data and not cfg.is_signal
#            print(cfg.name, stack)
            for vcfg in self.vcfgs:
                try:
                    hist = result[i][vcfg.name].histos[0].obj # result[0]['CR_hnl_m_12'].histos[0]
                except:
                    try:
                        hist = result[vcfg.name].histos[0].obj # result[0]['CR_hnl_m_12'].histos[0]
                    except:
                        set_trace()
#                hist = hists[vcfg.name]
                plot = self.plots[vcfg.name]

#                hist.Scale(cfg.scale)
                if cfg.name in plot:
                    # print 'Histogram', cfg.name, 'already exists; adding...', cfg.dir_name
                    hist_to_add = Histogram(cfg.name, hist)
                    if (not cfg.is_data) and (not cfg.is_dde):
                        hist_to_add.SetWeight(hist_cfg.lumi*cfg.xsec/cfg.sumweights)
                    plot[cfg.name].Add(hist_to_add)
                    if cfg.is_dde:
                        try:
                            # hist_to_add.SetWeight(hist_to_add.obj.GetEntries()/cfg.sumweights)
                            hist_to_add.SetWeight(cfg.sumweights)
                        except:
                            set_trace()
                else:
#                    print(cfg.name, hist.GetEntries(), stack)
                    plot_hist = plot.AddHistogram(cfg.name, hist, stack=stack)
#                    print('added histo %s'%vcfg.name)


                    if (not cfg.is_data) and (not cfg.is_dde):
                        plot_hist.SetWeight(self.hist_cfg.lumi*cfg.xsec/cfg.sumweights)
                    if cfg.is_dde:
                        # plot_hist.SetWeight(plot_hist.obj.GetEntries()/cfg.sumweights)
                        plot_hist.SetWeight(cfg.sumweights)
#                print(cfg.name, vcfg.name, len(plot.histos))
    
        print('###########################################################')
        print('# initializing histos done, making stacks...')
        for plot in self.plots.itervalues():
            try:
                plot._ApplyPrefs()
            except:
                set_trace() #if this error is raised, check in HNLStyle.py whether the style is defined coffectly
        print('# number of plots to draw: %i'%len(self.plots))
        print('###########################################################')


        procs = []
        for i, plot in enumerate(self.plots.itervalues()):
            proc = Process(target=plot.Draw, args=())
            procs.append(proc)
            proc.start()
     
        for proc in procs:
            proc.join()       

#        for plot in self.plots.itervalues():
#            plot._ApplyPrefs()
#            plot.Draw()

        return self.plots
예제 #6
0
def createHistograms(hist_cfg,
                     all_stack=False,
                     verbose=False,
                     friend_func=None):
    '''Method to create actual histogram (DataMCPlot) instances from histogram 
    config; this version handles multiple variables via MultiDraw.
    '''
    vcfgs = hist_cfg.vars
    plots = {}

    for vcfg in vcfgs:
        plot = DataMCPlot(vcfg.name)
        plot.lumi = hist_cfg.lumi
        if vcfg.name in plots:
            print 'Adding variable with same name twice', vcfg.name, 'not yet foreseen; taking the last'
        plots[vcfg.name] = plot

    for cfg in hist_cfg.cfgs:
        # First check whether it's a sub-histo or not
        if isinstance(cfg, HistogramCfg):
            hists = createHistograms(cfg, all_stack=True)
            for vcfg in vcfgs:
                hist = hists[vcfg.name]
                plot = plots[vcfg.name]
                hist._BuildStack(hist._SortedHistograms(), ytitle='Events')

                total_hist = plot.AddHistogram(cfg.name,
                                               hist.stack.totalHist.weighted,
                                               stack=True)

                if cfg.norm_cfg is not None:
                    norm_hist = createHistogram(cfg.norm_cfg, all_stack=True)
                    norm_hist._BuildStack(norm_hist._SortedHistograms(),
                                          ytitle='Events')
                    total_hist.Scale(hist.stack.integral / total_hist.Yield())

                if cfg.total_scale is not None:
                    total_hist.Scale(cfg.total_scale)
                    # print 'Scaling total', hist_cfg.name, 'by', cfg.total_scale
        else:
            # It's a sample cfg

            # Now read the tree
            file_name = '/'.join(
                [cfg.ana_dir, cfg.dir_name, cfg.tree_prod_name, 'tree.root'])

            # attach the trees to the first DataMCPlot
            plot = plots[vcfgs[0].name]
            ttree = plot.readTree(file_name,
                                  cfg.tree_name,
                                  verbose=verbose,
                                  friend_func=friend_func)

            norm_cut = hist_cfg.cut
            shape_cut = hist_cfg.cut

            if cfg.norm_cut:
                norm_cut = cfg.norm_cut

            if cfg.shape_cut:
                shape_cut = cfg.shape_cut

            weight = hist_cfg.weight
            if cfg.weight_expr:
                weight = '*'.join([weight, cfg.weight_expr])

            if hist_cfg.weight:
                norm_cut = '({c}) * {we}'.format(c=norm_cut, we=weight)
                shape_cut = '({c}) * {we}'.format(c=shape_cut, we=weight)

            # Initialise all hists before the multidraw
            hists = {}

            for vcfg in vcfgs:
                # plot = plots[vcfg.name]

                hname = '_'.join(
                    [hist_cfg.name, cfg.name, vcfg.name, cfg.dir_name])
                if 'xmin' in vcfg.binning:
                    hist = TH1F(hname, '', vcfg.binning['nbinsx'],
                                vcfg.binning['xmin'], vcfg.binning['xmax'])
                else:
                    hist = TH1F(hname, '', len(vcfg.binning) - 1, vcfg.binning)

                initHist(hist, vcfg)
                hists[vcfg.name] = hist

            var_hist_tuples = []

            for vcfg in vcfgs:
                # var_hist_tuples.append(('{var} >> {hist}'.format(var=vcfg.drawname, hist=hists[vcfg.name].GetName()), '1.'))
                var_hist_tuples.append('{var} >> {hist}'.format(
                    var=vcfg.drawname, hist=hists[vcfg.name].GetName()))

            # Implement the multidraw.
            ttree.MultiDraw(var_hist_tuples, norm_cut)

            # Do another multidraw here, if needed, and reset the scales in a separate loop
            if shape_cut != norm_cut:
                scale = hist.Integral()
                ttree.Project(hname, vcfg.drawname, shape_cut)
                hist.Scale(scale / hist.Integral())

            stack = all_stack or (not cfg.is_data and not cfg.is_signal)

            # Loop again over the variables and add histograms to plots one by one
            for vcfg in vcfgs:
                hist = hists[vcfg.name]
                plot = plots[vcfg.name]

                hist.Scale(cfg.scale)

                if cfg.name in plot:
                    print 'Histogram', cfg.name, 'already exists; adding...'
                    plot[cfg.name].Add(Histogram(cfg.name, hist))
                else:
                    plot_hist = plot.AddHistogram(cfg.name, hist, stack=stack)

                if not cfg.is_data:
                    plot_hist.SetWeight(hist_cfg.lumi * cfg.xsec /
                                        cfg.sumweights)

    for plot in plots.itervalues():
        plot._ApplyPrefs()
    return plots
예제 #7
0
    def makealltheplots(self, cfg):
        verbose=False
        friend_func=None
        all_stack=False
    #    for cfg in [hist_cfg.cfgs[0]]:
    #    for cfg in hist_cfg.cfgs:
            # First check whether it's a sub-histo or not
        if isinstance(cfg, HistogramCfg):
            hists = createHistograms(cfg, all_stack=True, vcfgs=self.vcfgs)
            for h in hists: print(h)
            for vcfg in self.vcfgs:
                hist = hists[vcfg.name]
                plot = self.plots[vcfg.name]
                set_trace()
                hist._BuildStack(hist._SortedHistograms(), ytitle='Events')
                print('stack built')
                total_hist = plot.AddHistogram(cfg.name, hist.stack.totalHist.weighted, stack=True)

                if cfg.norm_cfg is not None:
                    norm_hist = createHistogram(cfg.norm_cfg, all_stack=True)
                    norm_hist._BuildStack(norm_hist._SortedHistograms(), ytitle='Events')
                    total_hist.Scale(hist.stack.integral/total_hist.Yield())

                if cfg.total_scale is not None:
                    total_hist.Scale(cfg.total_scale)
                    # print 'Scaling total', hist_cfg.name, 'by', cfg.total_scale
        else:
            print('building histos for %s'%cfg.name)
            # It's a sample cfg

            # Now read the tree
            file_name = '/'.join([cfg.ana_dir, cfg.dir_name, cfg.tree_prod_name, 'tree.root'])

            # attach the trees to the first DataMCPlot
            plot = self.plots[self.vcfgs[0].name]
#            set_trace()
            ttree = plot.readTree(file_name, cfg.tree_name, verbose=verbose, friend_func=friend_func)

            norm_cut = self.hist_cfg.cut
            shape_cut = self.hist_cfg.cut

            if cfg.norm_cut:
                norm_cut = cfg.norm_cut

            if cfg.shape_cut:
                shape_cut = cfg.shape_cut

            weight = self.hist_cfg.weight
            if cfg.weight_expr:
                weight = '*'.join([weight, cfg.weight_expr])

            if cfg.cut_replace_func:
                norm_cut = cfg.cut_replace_func(norm_cut)
                shape_cut = cfg.cut_replace_func(norm_cut)

            if self.hist_cfg.weight:
                norm_cut = '({c}) * {we}'.format(c=norm_cut, we=weight)
                shape_cut = '({c}) * {we}'.format(c=shape_cut, we=weight)

            # print '#### FULL CUT ####', norm_cut

            # Initialise all hists before the multidraw
            hists = {}

            for vcfg in self.vcfgs:
                # plot = self.plots[vcfg.name]

                hname = '_'.join([self.hist_cfg.name, hashlib.md5(self.hist_cfg.cut).hexdigest(), cfg.name, vcfg.name, cfg.dir_name])
                if any(str(b) == 'xmin' for b in vcfg.binning):
                    hist = TH1F(hname, '', vcfg.binning['nbinsx'],
                                vcfg.binning['xmin'], vcfg.binning['xmax'])
                else:
                    hist = TH1F(hname, '', len(vcfg.binning)-1, vcfg.binning)

                initHist(hist, vcfg)
                hists[vcfg.name] = hist

            var_hist_tuples = []

            for vcfg in self.vcfgs:
                # var_hist_tuples.append(('{var} >> {hist}'.format(var=vcfg.drawname, hist=hists[vcfg.name].GetName()), '1.'))
    #                pool.map(var_hist_tuples.append,('{var} >> {hist}'.format(var=vcfg.drawname, hist=hists[vcfg.name].GetName())))
                var_hist_tuples.append('{var} >> {hist}'.format(var=vcfg.drawname, hist=hists[vcfg.name].GetName()))

            # Implement the multidraw.
            ttree.MultiDraw(var_hist_tuples, norm_cut)

            # Do another multidraw here, if needed, and reset the scales in a separate loop
            if shape_cut != norm_cut:
                scale = hist.Integral()
                ttree.Project(hname, vcfg.drawname, shape_cut)
                hist.Scale(scale/hist.Integral())

            stack = all_stack or (not cfg.is_data and not cfg.is_signal)

            # Loop again over the variables and add histograms to self.plots one by one
            for vcfg in self.vcfgs:
                hist = hists[vcfg.name]
                plot = self.plots[vcfg.name]

                hist.Scale(cfg.scale)

                if cfg.name in plot:
                    print 'Histogram', cfg.name, 'already exists; adding...', cfg.dir_name
                    hist_to_add = Histogram(cfg.name, hist)
                    if not cfg.is_data:
                        hist_to_add.SetWeight(hist_cfg.lumi*cfg.xsec/cfg.sumweights)
                    plot[cfg.name].Add(hist_to_add)
                else:
#                    print(cfg.name, hist.GetEntries(), stack)
                    plot_hist = plot.AddHistogram(cfg.name, hist, stack=stack)
#                    print('added histo %s for %s'%(vcfg.name,cfg.name))

                    if not cfg.is_data:
                        plot_hist.SetWeight(self.hist_cfg.lumi*cfg.xsec/cfg.sumweights)
            print('added histos for %s'%cfg.name)
            PLOTS = self.plots
        return PLOTS
예제 #8
0
def createHistogram(hist_cfg, all_stack=False, verbose=False):
    '''Method to create actual histogram (DataMCPlot) instance from histogram 
    config.
    '''
    plot = DataMCPlot(hist_cfg.var.name)
    plot.lumi = hist_cfg.lumi
    vcfg = hist_cfg.var
    for cfg in hist_cfg.cfgs:
        # First check whether it's a sub-histo or not
        if isinstance(cfg, HistogramCfg):
            hist = createHistogram(cfg, all_stack=True)
            hist._BuildStack(hist._SortedHistograms(), ytitle='Events')

            total_hist = plot.AddHistogram(cfg.name,
                                           hist.stack.totalHist.weighted,
                                           stack=True)

            if cfg.norm_cfg is not None:
                norm_hist = createHistogram(cfg.norm_cfg, all_stack=True)
                norm_hist._BuildStack(norm_hist._SortedHistograms(),
                                      ytitle='Events')
                total_hist.Scale(hist.stack.integral / total_hist.Yield())

            if cfg.total_scale is not None:
                total_hist.Scale(cfg.total_scale)
        else:
            # It's a sample cfg
            hname = '_'.join(
                [hist_cfg.name, cfg.name, vcfg.name, cfg.dir_name])
            if 'xmin' in vcfg.binning:
                hist = TH1F(hname, '', vcfg.binning['nbinsx'],
                            vcfg.binning['xmin'], vcfg.binning['xmax'])
            else:
                hist = TH1F(hname, '', len(vcfg.binning) - 1, vcfg.binning)

            initHist(hist, vcfg)

            file_name = '/'.join(
                [cfg.ana_dir, cfg.dir_name, cfg.tree_prod_name, 'tree.root'])

            ttree = plot.readTree(file_name, cfg.tree_name, verbose=verbose)

            norm_cut = hist_cfg.cut
            shape_cut = hist_cfg.cut

            if cfg.norm_cut:
                norm_cut = cfg.norm_cut

            if cfg.shape_cut:
                shape_cut = cfg.shape_cut

            weight = hist_cfg.weight
            if cfg.weight_expr:
                weight = '*'.join([weight, cfg.weight_expr])

            if hist_cfg.weight:
                norm_cut = '({c}) * {we}'.format(c=norm_cut, we=weight)
                shape_cut = '({c}) * {we}'.format(c=shape_cut, we=weight)

            ttree.Project(hname, vcfg.drawname, norm_cut)

            if shape_cut != norm_cut:
                scale = hist.Integral()
                ttree.Project(hname, vcfg.drawname, shape_cut)
                hist.Scale(scale / hist.Integral())

            stack = all_stack or (not cfg.is_data and not cfg.is_signal)

            hist.Scale(cfg.scale)

            if cfg.name in plot:
                plot[cfg.name].Add(Histogram(cfg.name, hist))
            else:
                plot_hist = plot.AddHistogram(cfg.name, hist, stack=stack)

            if not cfg.is_data:
                plot_hist.SetWeight(hist_cfg.lumi * cfg.xsec / cfg.sumweights)

    plot._ApplyPrefs()
    return plot