Esempio n. 1
0
    def __init__(self, outputdir='./', defaults={}, styles={}):
        ''' Initialize the BasePlotter 

    outputdir is where histograms will be saved.
    
    defaults provides basic configuration of the plotter. Most of the options 
    can be anyway overridden by the specific command in case one exception
    to the general rule is needed. Available defaults:
      - clone : (bool, default True) chooses the clone policy. If true histograms
    will be cloned before being styled and drawn
      - show_title : (bool, default False) shows the histogram title in the canvas
      - name_canvas: (bool, default False) name the canvas after the histogram.name it is drawn inside
      - save: (dict, default {'png' : True, 'pdf' : True, 'dotc' : False, 
          'dotroot' : False, 'json' : False} set the formats to which save the canvas

    styles provides the plotter a look-up table of styles to be applied to the histograms in
    the form key : style. Key is a POSIX regular expression that is matched to the 
    histogram title.
    '''
        self.outputdir = outputdir
        self.base_out_dir = outputdir
        self.canvas = plotting.Canvas(800, 800, name='adsf', title='asdf')
        self.set_canvas_style(self.canvas)
        self.canvas.cd()
        self.pad = plotting.Pad(0., 0., 1., 1.)  #ful-size pad
        self.pad.Draw()
        self.set_canvas_style(self.pad)
        self.pad.cd()
        self.lower_pad = None
        self.keep = []
        self.defaults = defaults
        self.styles = styles
        self.label_factor = None
        BasePlotter.set_canvas_style(self.canvas)
        self.set_style()
Esempio n. 2
0
    def dual_pad_format(self):
        if self.lower_pad is None:
            self.canvas.cd()
            self.canvas.SetCanvasSize(self.canvas.GetWw(),
                                      int(self.canvas.GetWh() * 1.3))
            self.set_canvas_style(self.canvas)
            self.pad.SetPad(0, 0.33, 1., 1.)
            self.set_canvas_style(self.pad)
            self.pad.SetBottomMargin(0.001)
            self.pad.Draw()
            self.canvas.cd()
            #create lower pad
            self.lower_pad = plotting.Pad(0, 0., 1., 0.33)
            self.set_canvas_style(self.lower_pad)
            self.lower_pad.Draw()
            self.lower_pad.cd()
            self.pad.cd()
            self.lower_pad.SetTopMargin(0.005)
            self.lower_pad.SetGridy(True)
            self.lower_pad.SetBottomMargin(self.lower_pad.GetBottomMargin() *
                                           3)

        labelSizeFactor1 = (self.pad.GetHNDC() +
                            self.lower_pad.GetHNDC()) / self.pad.GetHNDC()
        labelSizeFactor2 = (self.pad.GetHNDC() + self.lower_pad.GetHNDC()
                            ) / self.lower_pad.GetHNDC()
        mm = min(labelSizeFactor1, labelSizeFactor2)
        return labelSizeFactor1 / mm, labelSizeFactor2 / mm
Esempio n. 3
0
 def reset(self):
     '''hard graphic reset'''
     del self.canvas
     del self.pad
     del self.lower_pad
     self.keep = []
     self.canvas = plotting.Canvas(name='adsf', title='asdf')
     self.canvas.cd()
     self.pad = plotting.Pad('up', 'up', 0., 0., 1., 1.)  #ful-size pad
     self.pad.Draw()
     self.pad.cd()
     self.lower_pad = None
Esempio n. 4
0
 def reset(self):
     '''hard graphic reset'''
     del self.canvas
     del self.pad
     del self.lower_pad
     self.keep = []
     self.canvas = plotting.Canvas(800, 800, name='adsf', title='asdf')
     BasePlotter.set_canvas_style(self.canvas)
     self.canvas.cd()
     self.pad = plotting.Pad(0., 0., 1., 1.)  #ful-size pad
     self.pad.Draw()
     BasePlotter.set_canvas_style(self.pad)
     self.pad.cd()
     self.lower_pad = None
     self.label_factor = None
Esempio n. 5
0
    def __init__(self,
                 files,
                 lumifiles,
                 outputdir,
                 blinder=None,
                 forceLumi=-1):
        ''' Initialize the Plotter object

        Files should be a list of SAMPLE_NAME.root files.
        Lumifiles should contain floats giving the effective luminosity of
        each of the files.

        If [blinder] is not None, it will be applied to the data view.
        '''
        self.outputdir = outputdir
        self.views = data_views(files, lumifiles, forceLumi)
        self.canvas = plotting.Canvas(name='adsf', title='asdf')
        self.canvas.cd()
        self.pad = plotting.Pad('up', 'up', 0., 0., 1., 1.)  #ful-size pad
        self.pad.Draw()
        self.pad.cd()
        self.lower_pad = None
        if blinder:
            # Keep the unblinded data around if desired.
            self.views['data']['unblinded_view'] = self.views['data']['view']
            # Apply a blinding function
            self.views['data']['view'] = blinder(self.views['data']['view'])
        self.data = self.views['data']['view']
        self.keep = []
        # List of MC sample names to use.  Can be overridden.
        self.mc_samples = [
            'Zjets_M50',
            'WplusJets_madgraph',
            'TTplusJets_madgraph',
            'WZ*',
            'ZZ*',
            'WW*',
        ]
        file_to_map = filter(lambda x: x.startswith('data_'),
                             self.views.keys())[0]
        if not file_to_map:  #no data here!
            file_to_map = self.views.keys()[0]
        #from pdb import set_trace; set_trace()
        self.file_dir_structure = Plotter.map_dir_structure(
            self.views[file_to_map]['file'])
Esempio n. 6
0
    def add_ratio_plot(self,
                       data_hist,
                       mc_stack,
                       x_range=None,
                       ratio_range=0.2):
        #resize the canvas and the pad to fit the second pad
        self.canvas.SetCanvasSize(self.canvas.GetWw(),
                                  int(self.canvas.GetWh() * 1.3))
        self.canvas.cd()
        self.pad.SetPad(0, 0.33, 1., 1.)
        self.pad.Draw()
        self.canvas.cd()
        #create lower pad
        self.lower_pad = plotting.Pad('low', 'low', 0, 0., 1., 0.33)
        self.lower_pad.Draw()
        self.lower_pad.cd()

        mc_hist = None
        if isinstance(mc_stack, plotting.HistStack):
            mc_hist = sum(mc_stack.GetHists())
        else:
            mc_hist = mc_stack
        data_clone = data_hist.Clone()
        data_clone.Divide(mc_hist)
        if not x_range:
            nbins = data_clone.GetNbinsX()
            x_range = (data_clone.GetBinLowEdge(1),
                       data_clone.GetBinLowEdge(nbins) +
                       data_clone.GetBinWidth(nbins))
        else:
            data_clone.GetXaxis().SetRangeUser(*x_range)
        ref_function = ROOT.TF1('f', "1.", *x_range)
        ref_function.SetLineWidth(3)
        ref_function.SetLineStyle(2)

        data_clone.Draw('ep')
        if ratio_range:
            data_clone.GetYaxis().SetRangeUser(1 - ratio_range,
                                               1 + ratio_range)
        ref_function.Draw('same')
        self.keep.append(data_clone)
        self.keep.append(ref_function)
        self.pad.cd()
        return data_clone
Esempio n. 7
0
    def add_ratio_plot(self,
                       data_hist,
                       mc_distribution,
                       x_range=None,
                       ratio_range=0.2,
                       quote_errors=False):
        '''Adds a ratio plot under the main pad, with same x range'''

        mc_hist = mc_distribution
        if isinstance(mc_hist, HistStack):
            mc_hist = sum(mc_hist.GetHists())
            quote_errors = False

        #resize the canvas and the pad to fit the second pad
        self.canvas.SetCanvasSize(self.canvas.GetWw(),
                                  int(self.canvas.GetWh() * 1.3))
        self.canvas.cd()
        self.pad.SetPad(0, 0.33, 1., 1.)
        self.pad.Draw()
        self.canvas.cd()
        #create lower pad
        self.lower_pad = plotting.Pad('low', 'low', 0, 0., 1., 0.33)
        self.lower_pad.Draw()
        self.lower_pad.cd()

        nbins = data_hist.GetNbinsX()
        #make ratio, but use only data errors
        data_clone = data_hist.Clone()
        for ibin in range(1, nbins + 1):
            d_cont = data_clone.GetBinContent(ibin)
            d_err = data_clone.GetBinError(ibin)

            m_cont = mc_hist.GetBinContent(ibin)

            d_cont = (d_cont - m_cont) / m_cont if m_cont else -10.
            d_err = d_err / m_cont if m_cont else 0.

            data_clone.SetBinContent(ibin, d_cont)
            data_clone.SetBinError(ibin, d_err)

        data_clone.Draw('ep')
        self.keep.append(data_clone)
        if ratio_range:
            data_clone.GetYaxis().SetRangeUser(-ratio_range, ratio_range)

        #reference line
        if not x_range:
            nbins = data_clone.GetNbinsX()
            x_range = (data_clone.GetBinLowEdge(1),
                       data_clone.GetBinLowEdge(nbins) +
                       data_clone.GetBinWidth(nbins))
        else:
            data_clone.GetXaxis().SetRangeUser(*x_range)
        ref_function = ROOT.TF1('f', "0.", *x_range)
        ref_function.SetLineWidth(3)
        ref_function.SetLineStyle(2)
        ref_function.Draw('same')
        self.keep.append(ref_function)

        if quote_errors:
            err_histo = mc_hist.Clone()
            err_histo.SetMarkerStyle(0)
            err_histo.SetLineColor(1)
            err_histo.SetFillColor(1)

            for ibin in range(1, nbins + 1):
                cont = err_histo.GetBinContent(ibin)
                err = err_histo.GetBinError(ibin)
                err = err / cont if cont else 0.

                err_histo.SetBinContent(ibin, 0)
                err_histo.SetBinError(ibin, err)

            err_histo.Draw('pe2 same')  #was pe
            self.keep.append(err_histo)

        self.pad.cd()
        return data_clone
Esempio n. 8
0
def run_module(**kwargs):
   args = Struct(**kwargs)
   mkdir(args.out)
   canvas = plotting.Canvas()

   pars_regex = None
   if args.pars_regex:
      pars_regex = re.compile(args.pars_regex)
      
   sample_regex = None
   if args.sample_regex:
      sample_regex = re.compile(args.sample_regex)

   pars_out_regex = None
   if args.pars_out_regex:
      pars_out_regex = re.compile(args.pars_out_regex)
      
   sample_out_regex = None
   if args.sample_out_regex:
      sample_out_regex = re.compile(args.sample_out_regex)

   output_file = io.root_open('%s/output.root' % args.out, 'recreate')
   fpars_tdir = output_file.mkdir('floating_pars')
   pulls_tdir = output_file.mkdir('postfit_pulls')

   failed_fits = set()
   fit_statuses = plotting.Hist(10, -1.5, 8.5)
   with io.root_open(args.mlfit) as mlfit:
      failed_results = []
      passes_results = []
      pars = {}
      yields = {}
      first = True
      toys = [i.GetName() for i in mlfit.keys() if i.GetName().startswith('toy_')] if not args.oneshot else [None]
      log.info('examining %i toys' % len(toys))
      prefit_nuis = None
      if args.useprefit:
         prefit_nuis = ArgSet(mlfit.nuisances_prefit)

      nfailed = 0
      for toy in toys:
         toy_dir = mlfit.Get(toy) if not args.oneshot else mlfit
         keys = set([i.GetName() for i in toy_dir.GetListOfKeys()])
         if 'norm_fit_s' not in keys or 'fit_s' not in keys:
            log.error('Fit %s failed to produce output!' % toy)
            failed_fits.add(toy)
            continue
         norms = ArgSet(
            toy_dir.Get(
               'norm_fit_s'
               )
            )
         norms = [i for i in norms]

         fit_result = toy_dir.Get(
            'fit_s'
            )
         fit_pars = ArgList(fit_result.floatParsFinal())
         
         if first:
            first = False
            for i in fit_pars:
               if pars_regex and not pars_regex.match(i.GetName()): continue
               if pars_out_regex and pars_out_regex.match(i.GetName()): continue
               pars[i.GetName()] = []

            for i in norms:
               if sample_regex and not sample_regex.match(i.GetName()): continue
               if sample_out_regex and sample_out_regex.match(i.GetName()): continue
               yields[i.GetName()] = []

         fit_statuses.Fill(fit_result.status())
         fit_failed = any(i.getError() == 0 for i in fit_pars) or fit_result.status() != 0
         if fit_failed:
            log.error('Fit %s failed to converge properly. It has status %i!' % (toy, fit_result.status()))
            nfailed+=1
            failed_fits.add(toy)
            failed_results.append(fit_result)
            continue

         passes_results.append(fit_result)

         for i in norms:
            if i.GetName() in yields:
               yields[i.GetName()].append(i)
            
         for i in fit_pars:
            if i.GetName() in pars:
               pars[i.GetName()].append(i)

      if nfailed:
         log.error('There were %i fit failed!' % nfailed)
      with open('%s/info.txt' % args.out, 'w') as info:
         info.write('There were %i fit failed!\n' % nfailed)
      fit_statuses.Draw()
      canvas.SaveAs('%s/fit_status.png' % args.out)

      if not args.nopars:
         #Plots the post-fit distribution of the POI and nuisances
         out = os.path.join(args.out, 'floating_parameters')
         mkdir(out)
         for i, j in yields.iteritems():
            make_hist(i, j, out, prefix='yield_')
            
         for i, j in pars.iteritems():
            make_hist(i, j, out, prefix='par_')

      if not args.postpulls:
         #Plots the post-fit pulls (nuisance(post) - nuisance(pre))/unc(post)
         pulls_dir = os.path.join(args.out, 'postfit_pulls')
         mkdir(pulls_dir)

         ROOT.gStyle.SetOptFit(11111)
         singlenames=set()
         for name,value in pars.iteritems():
            if pars_regex and not pars_regex.match(name): continue
            if pars_out_regex and pars_out_regex.match(i): continue
            singlenames.add(get_key(name))
         
         pulls_mean_summary={}
         pulls_sigma_summary={}
         deltas_mean_summary={}
         deltas_sigma_summary={}
         for name in singlenames:
            nbins = 0
            for fullname in pars:
               if name in fullname:
                  nbins = nbins + 1
            #print name, nbins
            try:
               hist = plotting.Hist(nbins, 0.5,nbins+0.5, name = "%s_pull_mean_summary" %name)
               pulls_mean_summary[name] = hist
               hist = plotting.Hist(nbins, 0.5,nbins+0.5, name = "%s_pull_sigma_summary" %name)
               pulls_sigma_summary[name] = hist
               hist = plotting.Hist(nbins, 0.5,nbins+0.5, name = "%s_delta_mean_summary" %name)
               deltas_mean_summary[name] = hist
               hist = plotting.Hist(nbins, 0.5,nbins+0.5, name = "%s_delta_sigma_summary" %name)
               deltas_sigma_summary[name] = hist
            except:
               set_trace()

         pulls_mean_summary[  'all'] = plotting.Hist(len(pars), 0.5, len(pars)+0.5, name = "all_pull_mean_summary"  )
         pulls_sigma_summary[ 'all'] = plotting.Hist(len(pars), 0.5, len(pars)+0.5, name = "all_pull_sigma_summary" )
         deltas_mean_summary[ 'all'] = plotting.Hist(len(pars), 0.5, len(pars)+0.5, name = "all_delta_mean_summary" )
         deltas_sigma_summary['all'] = plotting.Hist(len(pars), 0.5, len(pars)+0.5, name = "all_delta_sigma_summary")

         
         for i, j in pars.iteritems():
            make_post_distributions(i, j, pulls_dir, pulls_mean_summary, pulls_sigma_summary, prefix='pull_',
                                    dist='pull', prefit=prefit_nuis, tdir=pulls_tdir, skipFit=args.skipFit)
            make_post_distributions(i, j, pulls_dir, deltas_mean_summary, deltas_sigma_summary, prefix='delta_',
                                    dist='delta', prefit=prefit_nuis, tdir=pulls_tdir, skipFit=args.skipFit)
         
         for name,histo in pulls_mean_summary.iteritems():
            canvas = plotting.Canvas()
            histo.Draw()
            canvas.Update()
            line = ROOT.TLine(histo.GetBinLowEdge(1),0,histo.GetBinLowEdge(histo.GetNbinsX()+1),0)
            line.SetLineColor(2)
            line.Draw("same")
            canvas.Update()
            canvas.SaveAs('%s/%s.png' % (pulls_dir,histo.GetName()))
            canvas.SaveAs('%s/%s.pdf' % (pulls_dir,histo.GetName()))
            pulls_tdir.WriteObject(histo, histo.GetName())
         for name,histo in pulls_sigma_summary.iteritems():
            canvas = plotting.Canvas()
            histo.Draw()
            canvas.Update()
            line = ROOT.TLine(histo.GetBinLowEdge(1),1,histo.GetBinLowEdge(histo.GetNbinsX()+1),1)
            line.SetLineColor(2)
            line.Draw("same")
            canvas.Update()
            canvas.SaveAs('%s/%s.png' % (pulls_dir,histo.GetName()))
            canvas.SaveAs('%s/%s.pdf' % (pulls_dir,histo.GetName()))
            pulls_tdir.WriteObject(histo, histo.GetName())
         
         for name,histo in deltas_mean_summary.iteritems():
            canvas = plotting.Canvas()
            histo.Draw()
            canvas.Update()
            line = ROOT.TLine(histo.GetBinLowEdge(1),0,histo.GetBinLowEdge(histo.GetNbinsX()+1),0)
            line.SetLineColor(2)
            line.Draw("same")
            canvas.Update()
            canvas.SaveAs('%s/%s.png' % (pulls_dir,histo.GetName()))
            canvas.SaveAs('%s/%s.pdf' % (pulls_dir,histo.GetName()))
            pulls_tdir.WriteObject(histo, histo.GetName())
         for name,histo in deltas_sigma_summary.iteritems():
            histo.Draw()
            canvas.Update()
            #line = ROOT.TLine(histo.GetBinLowEdge(1),1,histo.GetBinLowEdge(histo.GetNbinsX()+1),1)
            #line.Draw("same")
            canvas.Update()
            canvas.SaveAs('%s/%s.png' % (pulls_dir,histo.GetName()))
            canvas.SaveAs('%s/%s.pdf' % (pulls_dir,histo.GetName()))
            pulls_tdir.WriteObject(histo, histo.GetName())


   if not args.noshapes:
      #Overlays the prefit values of the different shapes with the envelope of 
      #what is fitted by the toys
      out = os.path.join(args.out, 'shapes')
      mkdir(out)
      biased_shapes={}
      if args.biasFile:
         with io.root_open(args.biasFile) as biased:
            biased_dir= biased.prefit \
               if hasattr(biased, 'prefit') else \
               None
            ROOT.TH1.AddDirectory(False)
            for key in biased_dir.keys():
               biased_shapes[key.name] = asrootpy(key.ReadObj().Clone())

      with io.root_open(args.harvested) as harvest:
         has_prefit = hasattr(harvest, 'prefit')
         prefit = harvest.prefit if has_prefit else None
         toys = EnvelopeView(
            *[harvest.get(i.GetName()).get(args.variable) 
              for i in harvest.keys() 
              if i.GetName().startswith('toy_')
              and (i.GetName() not in failed_fits) ]
             )
         #shapes = [i.GetName() for i in prefit.keys()] #FIXME! should not depend on prefit!
         first_toy = [i.GetName() for i in harvest.keys() if i.GetName().startswith('toy_')][0]
         not_shapes = set('correlation_matrix')
         shapes = [i.GetName() for i in harvest.get(first_toy).get(args.variable).keys() if i.GetName() not in not_shapes]

         for shape in shapes:
            canvas = plotting.Canvas()
            canvas.SetCanvasSize( canvas.GetWw(), int(canvas.GetWh()*1.3) )
            upper_pad = plotting.Pad(0, 0.33, 1., 1.)
            lower_pad = plotting.Pad(0, 0., 1., 0.33)
            upper_pad.set_bottom_margin(0.001)
            lower_pad.set_top_margin(0.005)
            lower_pad.set_bottom_margin(lower_pad.get_bottom_margin()*3)
            upper_pad.Draw()
            lower_pad.Draw()
            upper_pad.cd()

            biased_shape = biased_shapes.get(shape, None)
            toy_shape = toys.Get(shape)
            pre_shape = None

            legend = plotting.Legend(
               3+int(has_prefit)+int(bool(biased_shape)), 
               rightmargin=0.07, topmargin=0.05, leftmargin=0.45)
            legend.SetBorderSize(0)
            
            if biased_shape:
               biased_shape.title = 'true shape'
               biased_shape.legendstyle = 'p'
               biased_shape.inlegend = True               
               biased_shape.drawstyle = 'p'

            if has_prefit:
               pre_shape = prefit.Get(shape)
               pre_shape.title = 'input shape'
               pre_shape.legendstyle = 'p'
               pre_shape.drawstyle = 'p'
               if biased_shape:
                  pre_shape.legendstyle = 'l'
                  pre_shape.drawstyle = 'hist'
                  pre_shape.linecolor = 'blue'
                  pre_shape.fillstyle = 0
            
            toy_shape.Draw()
            if has_prefit:
               pre_shape.Draw('same')
            if biased_shape:
               biased_shape.Draw('same')
               
            legend.AddEntry(toy_shape.two_sigma)
            legend.AddEntry(toy_shape.one_sigma)
            legend.AddEntry(toy_shape.median)
            if has_prefit:
               legend.AddEntry(pre_shape)
            if biased_shape:
               legend.AddEntry(biased_shape)
            legend.Draw()

            #compute pulls
            pulls = None
            labelSizeFactor2 = (upper_pad.GetHNDC()+lower_pad.GetHNDC()) / lower_pad.GetHNDC()
            labelSizeFactor1 = (upper_pad.GetHNDC()+lower_pad.GetHNDC()) / upper_pad.GetHNDC()
            label_factor = labelSizeFactor2/labelSizeFactor1
            if has_prefit or biased_shape:
               lower_pad.cd()            
               ref_histo = biased_shape if biased_shape else pre_shape
               pulls = toy_shape.median.Clone()
               pulls.Reset()
               for ref, toy, pull in zip(ref_histo, toy_shape, pulls):
                  if toy.error == (0.0, 0.0): continue
                  abs_pull = toy.median-ref.value
                  #pick correct side of the errors
                  err = toy.error[1] if abs_pull < 0 else toy.error[0]
                  pull.value = abs_pull/err
               pulls.xaxis.title = args.variable
               pulls.yaxis.title = 'pulls'
               pulls.set_label_size(ROOT.gStyle.GetLabelSize()*label_factor, "XYZ")
               pulls.set_title_size(ROOT.gStyle.GetTitleSize()*label_factor, "XYZ")
               pulls.yaxis.set_title_offset(pulls.GetYaxis().GetTitleOffset()/label_factor)
               
               pulls.Draw()

            canvas.Update()
            canvas.SaveAs('%s/%s.png' % (out, shape))
            canvas.SaveAs('%s/%s.pdf' % (out, shape))
            with open(os.path.join(out, '%s.json' % shape), 'w') as jfile:
               jfile.write(toy_shape.json())

   output_file.Close()