示例#1
0
def plothist(xtitle,hists,ratio=False,logy=False,norm=False):
  
  # SETTING
  outdir   = ensuredir("plots/")
  fname    = outdir+"testPlot"
  if ratio:
    fname += "_ratio"
  if logy:
    fname += "_logy"
  if norm:
    fname += "_norm" # normalize each histogram
  rrange   = 0.5
  width    = 0.2             # legend width
  position = 'topright'      # legend position
  header   = "Gaussians"     # legend header
  text     = "#mu#tau_{h}"   # corner text
  grid     = True #and False
  staterr  = True and False  # add uncertainty band to first histogram
  lstyle   = 1               # solid lines
  
  # PLOT
  LOG.header(fname)
  plot = Plot(xtitle,hists,norm=norm)
  plot.draw(ratio=ratio,logy=logy,ratiorange=rrange,lstyle=lstyle,grid=grid,staterr=staterr)
  plot.drawlegend(position,header=header,width=width)
  plot.drawtext(text)
  plot.saveas(fname+".png")
  plot.saveas(fname+".pdf")
  #plot.saveas(fname+".C")
  #plot.saveas(fname+".png",fname+".C")
  #plot.saveas(fname,ext=['png','pdf'])
  plot.close()
  print
示例#2
0
def checklatex(texts, tag=""):
    """Check legend entries: colors, titles, ..."""
    # https://root.cern.ch/doc/master/classTPaveText.html
    LOG.header("checklegend" + tag.replace('_', ' '))
    output = ensuredir('plots')
    fname = "%s/testLatex%s" % (output, tag)
    xdim = 500
    ydim = 50 * (len(texts) + 2.5)
    print ">>> Canvas: %sx%s (nlines=%d)" % (xdim, ydim, len(texts))
    canvas = TCanvas('canvas', 'canvas', xdim, int(ydim))
    #pave1  = TPaveText(0.0,0,0.5,1,'ARC') #,'BR')
    pave2 = TPaveText(0.04, 0.04, 0.96, 0.96)  #'ARC') #,'BR')
    #pave1.SetBorderSize(0)
    pave2.SetBorderSize(0)
    #pave1.SetTextAlign(12)
    pave2.SetTextAlign(12)
    #pave1.SetTextFont(42)
    pave2.SetTextFont(42)
    #pave1.SetFillColor(0)
    pave2.SetFillColor(0)
    #pave1.SetCornerRadius(0.05)
    #pave2.SetCornerRadius(0.05)
    #pave1.SetMargin(0.12)
    #pave1.SetTextSize(tsize)
    #pave2.Copy(pave1)
    for line in texts:
        latex = makelatex(line)
        print ">>> %r -> %r" % (line, latex)
        #pave1.AddText(line)
        pave2.AddText(latex)
    #pave1.Draw()
    pave2.Draw()
    canvas.SaveAs(fname + ".png")
    #canvas.SaveAs(fname+".pdf")
    canvas.Close()
示例#3
0
def plothist(xtitle,hists,ratio=False,logy=False,norm=False,**kwargs):
  
  # SETTING
  outdir   = ensuredir("plots/")
  fname    = outdir+"testLegend"
  rrange   = 0.5
  header   = "Gaussians"     # legend header
  text     = "#mu#tau_{h}"   # corner text
  grid     = True and False
  staterr  = True and False  # add uncertainty band to first histogram
  lstyle   = 1               # solid lines
  panel    = 1               # 1 = main (top) panel, 2 = ratio (bottom) panel
  hists    = [h.Clone("%s_clone%d"%(h.GetName(),i)) for i, h in enumerate(hists)]
  if kwargs.get('pos',False):
    fname += "_"+kwargs['pos'].replace(';','')
    header = kwargs['pos']
  if ratio:
    fname += "_ratio"
  
  # PLOT
  LOG.header(fname)
  plot = Plot(xtitle,hists,norm=norm)
  plot.draw(ratio=ratio,logy=logy,ratiorange=rrange,lstyle=lstyle,grid=grid,staterr=staterr)
  plot.drawlegend(border=True,header=header,panel=panel,**kwargs)
  plot.drawtext(text)
  plot.saveas(fname+".png")
  #plot.saveas(fname+".pdf")
  plot.close()
  print
示例#4
0
def plotstack(xname,xtitle,datahist,exphists,ratio=False,logy=False):
  """Plot Stack objects for a given data hisogram and list of MC histograms."""
  
  # SETTING
  outdir   = ensuredir("plots")
  fname    = "%s/testStack_%s"%(outdir,xname)
  if ratio:
    fname += "_ratio"
  if logy:
    fname += "_logy"
  rrange   = 0.5
  text     = "#mu#tau_{h} baseline"
  grid     = True and False
  position = 'topright' if logy else 'right'
  
  # PLOT
  LOG.header(fname)
  plot = Stack(xtitle,datahist,exphists)
  plot.draw(ratio=ratio,logy=logy,ratiorange=rrange,grid=grid)
  plot.drawlegend(position=position)
  plot.drawtext(text)
  plot.saveas(fname+".png")
  plot.saveas(fname+".pdf")
  #plot.saveas(fname+".C")
  #plot.saveas(fname+".png",fname+".C")
  #plot.saveas(fname,ext=['png','pdf'])
  plot.close()
  print
示例#5
0
def main():

    #### Test several initializations of Variable object.
    #### Note that key-word arguments starting with 'c' are used for context-dependent attributes
    ###mvisbins  = [0,30,40,50,60,70,75,80,90,100,120,200]
    ###variables = [
    ###  Variable('m_vis',     "m_{vis} [GeV]", 40, 0,200),
    ###  Variable('njets',     "Number of jets", 8, 0,  8),
    ###  Variable('m_vis',     40, 0,200),
    ###  Variable('njets',      8, 0,  8),
    ###  Variable('njets',      8, 0,  8, veto='njets'),
    ###  Variable('st',        20, 0,800, title="S_{T}",only="njets",blind="st>600"),
    ###  Variable('m_vis',     40, 0,200, cbins={'njets':mvisbins},blind=(70,90)),
    ###  Variable('m_vis',      mvisbins, cbins={"njets[^&]*2":(40,0,200)},),
    ###  Variable('pt_1+pt_2', 20, 0,800, title="S_{T}^{tautau}",ctitle={"njets":"S_{T}"}),
    ###]
    selections = [
        Selection(""),
        Selection("baseline", "pt_1>50 && pt_2>50"),
        Selection("njets>=1", "pt_1>50 && pt_2>50 && njets>=1"),
        Selection("1 b tags",
                  "pt_1>50 && pt_2>50 && njets>=2 && nbtags>=1",
                  weight="btagweight"),
    ]

    for selection in selections:
        LOG.header(selection.name)
        print ">>> name='%s', filename='%s', title='%s', cut='%s'" % (color(
            selection.name), color(selection.filename), color(
                selection.title), color(selection.selection))
        print ">>> weight=%r, drawcmd=%r" % (selection.weight,
                                             selection.drawcmd())
        sum1 = selection + "dzeta>-40"
        print '>>> sum1 = selection + "dzeta>-40"'
        print ">>>   name=%r, filename=%r, title=%r" % (
            sum1.name, sum1.filename, sum1.title)
        print ">>>   cut=%r" % (sum1.selection)
        sum2 = selection + Selection("dzeta", "dzeta>-40")
        print '>>> sum2 = selection + Selection("dzeta","dzeta>-40")'
        print ">>>   name=%r, filename=%r, title=%r" % (
            sum2.name, sum2.filename, sum2.title)
        print ">>>   cut=%r" % (sum2.selection)
示例#6
0
def compare(fnames, variables, **kwargs):

    # SETTING
    tnames = kwargs.get('tree', [])
    entries = kwargs.get('entries', [])  # entries of files
    outdir = kwargs.get('outdir', "compare")
    tag = kwargs.get('tag', "")
    cut = kwargs.get('cut', "")
    norm = kwargs.get('norm', False)
    ensuredir(outdir)
    if isinstance(tnames, str):
        tnames = [tnames] * len(fnames)
    else:
        while len(tnames) < len(fnames):
            tnames.append(tnames[-1])
    if norm:
        tag += "_norm"  # normalize each histogram

    # GET FILES & TREES
    files = []
    trees = []
    for fname, tname in zip(fnames, tnames):
        file = TFile.Open(fname, 'READ')
        tree = file.Get(tname)
        files.append(file)
        trees.append(tree)
        for variable in variables[:]:
            if not hasattr(tree, variable.name):
                LOG.warning(
                    "compare: tree %s:%s does not contain branch %r! Skipping..."
                    % (fname, tname, variable.name))
                variables.remove(variable)
    while len(entries) < len(trees):
        i = len(entries)
        entry = "%s %d" % (tnames[i], i + 1)
        entries.append(entry)

    # PLOT
    for variable in variables:
        fname = "%s/%s%s.png" % (outdir, variable, tag)
        rrange = 0.5
        header = "Compare"  # legend header
        text = ""  # corner text
        ratio = True  #and False
        logy = True and False
        grid = True  #and False
        staterr = True  #and False # add uncertainty band to first histogram
        lstyle = 1  # solid lines
        LOG.header(fname)

        # GET HISOGRAMS
        hists = []
        for i, (tree, htitle) in enumerate(zip(trees, entries)):
            hname = "%s_%d" % (variable.filename, i)
            #hist   = variable.gethist(hname,htitle)
            #dcmd   = variable.drawcmd(hname)
            hist = variable.draw(
                tree, cut, name=hname,
                title=htitle)  # create and fill hist from tree
            evts = hist.GetEntries()
            hist.SetTitle("%s (%d)" % (htitle, evts))
            hists.append(hist)
            print ">>>   %r: entries=%d, integral=%s, mean=%#.6g, s.d.=%#.6g" % (
                htitle, evts, hist.Integral(), hist.GetMean(),
                hist.GetStdDev())

        # DRAW PLOT
        plot = Plot(variable, hists, norm=norm)
        plot.draw(ratio=True,
                  logy=logy,
                  ratiorange=rrange,
                  lstyle=lstyle,
                  grid=grid,
                  staterr=staterr)
        plot.drawlegend(header=header)
        plot.drawtext(text)
        plot.saveas(fname)
        plot.close()
        print
示例#7
0
def compare(fnames, varsets, **kwargs):

    # SETTING
    tname = kwargs.get('tree', 'Events')
    entries = kwargs.get('entries', [])  # entries of files
    outdir = kwargs.get('outdir', "compare")
    tag = kwargs.get('tag', "")
    cut = kwargs.get('cut', "")
    norm = kwargs.get('norm', False)
    ensuredir(outdir)
    if norm:
        tag += "_norm"  # normalize each histogram
    tree = TChain(tname)

    # GET FILES & TREES
    for fname in fnames:
        tree.Add(fname)

    # PLOT
    for varset in varsets:
        fname = "%s/%s%s.png" % (outdir, '-'.join(v.filename
                                                  for v in varset), tag)
        rrange = 0.5
        header = "Compare"  # legend header
        text = ""  # corner text
        ratio = True  #and False
        logy = True and False
        grid = True  #and False
        staterr = True  #and False # add uncertainty band to first histogram
        lstyle = 1  # solid lines
        xvar = varset[0]
        LOG.header(fname)

        # GET HISOGRAMS
        hists = []
        for i, variable in enumerate(varset):
            hname = "%s_%d" % (variable.filename, i)
            htitle = variable.name
            #hist   = variable.gethist(hname,htitle)
            #dcmd   = variable.drawcmd(hname)
            hist = variable.draw(
                tree, cut, name=hname,
                title=htitle)  # create and fill hist from tree
            evts = hist.GetEntries()
            hist.SetTitle(htitle)  #"%s (%d)"%(htitle,evts)
            hists.append(hist)
            print ">>>   %r: entries=%d, integral=%s, mean=%#.6g, s.d.=%#.6g" % (
                htitle, evts, hist.Integral(), hist.GetMean(),
                hist.GetStdDev())

        # DRAW PLOT
        plot = Plot(xvar, hists, norm=norm)
        plot.draw(ratio=True,
                  logy=logy,
                  ratiorange=rrange,
                  lstyle=lstyle,
                  grid=grid,
                  staterr=staterr)
        plot.drawlegend(header=header, latex=False)
        plot.drawtext(text)
        plot.saveas(fname)
        plot.close()
        print
示例#8
0
def main(args):
  channels  = args.channels
  eras      = args.eras
  parallel  = args.parallel
  verbosity = args.verbosity
  obsset    = args.observables
  plot      = True
  analysis  = 'ztt_tid' # $PROCESS_$ANALYSIS
  tag       = ""
  fileexp   = "$OUTDIR/$ANALYSIS_$OBS_$CHANNEL-$ERA$TAG.inputs.root"
  outdir    = ensuredir("input")
  plotdir   = "input/plots/$ERA"
  
  for era in eras:
    for channel in channels:
      for obs in obsset:
        PLOG.header("%s, %s, %s"%(obs,channel,era))
        splitbydm = 'mtau' in obs and 'mumu' not in channel
        
        
        ###############
        #   SAMPLES   #
        ###############
        # sample set and their systematic variations
        
        # GET SAMPLESET
        join      = ['VV','TT','ST']
        sname     = "$PICODIR/$SAMPLE_$CHANNEL$TAG.root"
        sampleset = getsampleset(channel,era,fname=sname,join=join,split=None,table=False,verb=1)
        
        if channel=='mumu':
          
          # RENAME (HTT convention)
          sampleset.rename('DY_M50','ZLL')
          sampleset.rename('WJ','W')
          sampleset.datasample.name = 'data_obs'
          
          # SYSTEMATIC VARIATIONS
          varprocs = { # processes to be varied
            'Nom': ['ZLL','W','VV','ST','TT','QCD','data_obs'],
          }
          samplesets = { # sets of samples per variation
            'Nom': sampleset, # nominal
          }
          samplesets['Nom'].printtable(merged=True,split=True)
          if verbosity>=2:
            samplesets['Nom'].printobjs(file=True)
        
        else:
          
          # SPLIT & RENAME (HTT convention)
          GMR = "genmatch_2==5"
          GML = "genmatch_2>0 && genmatch_2<5"
          GMJ = "genmatch_2==0"
          GMF = "genmatch_2<5"
          if splitbydm:
            idweights = getdmsf(era) # DM-dependent SF, pT > 20 GeV
            print idweights
            sampleset.split('DY',[('ZTT_DM0', GMR+" && dm_2==0"), ('ZTT_DM1', GMR+" && dm_2==1"),
                                  ('ZTT_DM10',GMR+" && dm_2==10"),('ZTT_DM11',GMR+" && dm_2==11"),
                                  ('ZL',GML),('ZJ',GMJ)])
            sampleset.get('DY',unique=True).replaceweight('idweight_2',idweights[0],verb=2) # replace tau ID SF
          else:
            idweights = ('idweight_2', 'idweightUp_2', 'idweightDown_2') # pT-dependent SF
            sampleset.split('DY',[('ZTT',GMR),('ZL',GML),('ZJ',GMJ),])
          sampleset.split('TT',[('TTT',GMR),('TTL',GML),('TTJ',GMJ)])
          #sampleset.split('ST',[('STT',GMR),('STJ',GMF),]) # small background
          sampleset.rename('WJ','W')
          sampleset.datasample.name = 'data_obs'
          
          # SYSTEMATIC VARIATIONS
          systs = preparesysts( # prepare systematic variations: syskey, systag, procs
            ('Nom',"",          ['ZTT','ZL','ZJ','W','VV','ST','TTT','TTL','TTJ','QCD','data_obs']), #,'STT','STJ'
            ('TES',"_shape_tes",['ZTT','TTT']),           # tau energy scale
            ('LTF',"_shape_ltf",['ZL', 'TTL']),           # l -> tau energy scale
            ('JTF',"_shape_jtf",['ZJ', 'TTJ','QCD','W']), # j -> tau energy scale
            ('tid',"_shape_tid",['ZTT','TTT'],     idweights), # replace 'idweight_2' with up/down variations
            ('zpt',"_shape_dy", ['ZTT','ZL','ZJ'], ('zptweight','(1.1*zptweight-0.1)','(0.9*zptweight+0.1)')), # replace 'zptweight'
            ERA=era,CHANNEL=channel) # keys to replace in systag
          if splitbydm:
            for syskey, syst in systs.iteritems():
              if 'ZTT' in syst.procs: # split all ZTT shapes
                syst.procs = ['ZTT_DM0','ZTT_DM1','ZTT_DM10','ZTT_DM11']+syst.procs[1:]
          samplesets = { # sets of samples per variation
            'Nom':     sampleset, # nominal
            'TESUp':   sampleset.shift(systs['TES'].procs,"_TES1p030",systs['TES'].up," +3% TES", split=True,filter=False,share=True),
            'TESDown': sampleset.shift(systs['TES'].procs,"_TES0p970",systs['TES'].dn," -3% TES", split=True,filter=False,share=True),
            #'TESUp':   sampleset.shift(systs['TES'].procs,"_TESUp",  systs['TES'].up," +3% TES", split=True,filter=False,share=True),
            #'TESDown': sampleset.shift(systs['TES'].procs,"_TESDown",systs['TES'].dn," -3% TES", split=True,filter=False,share=True),
            'LTFUp':   sampleset.shift(systs['LTF'].procs,"_LTF1p030",systs['LTF'].up," +3% LTF", split=True,filter=False,share=True),
            'LTFDown': sampleset.shift(systs['LTF'].procs,"_LTF0p970",systs['LTF'].dn," -3% LTF", split=True,filter=False,share=True),
            'JTFUp':   sampleset.shift(systs['JTF'].procs,"_JTF1p100",systs['JTF'].up," +10% JTF",split=True,filter=False,share=True),
            'JTFDown': sampleset.shift(systs['JTF'].procs,"_JTF0p900",systs['JTF'].dn," -10% JTF",split=True,filter=False,share=True),
          }
          keys = samplesets.keys() if verbosity>=1 else ['Nom','TESUp','TESDown']
          for shift in keys: # print table
            if not shift in samplesets: continue
            samplesets[shift].printtable(merged=True,split=True)
            if verbosity>=2:
              samplesets[shift].printobjs(file=True)
        
        
        ###################
        #   OBSERVABLES   #
        ###################
        # observable/variables to be fitted in combine
        
        if channel=='mumu':
        
          observables = [
            Var('m_vis', 1, 60, 120, fname='mvis', ymargin=1.6, rrange=0.08),
          ]
        
        elif splitbydm:
          observables = [
            Var('dm_2==0?0.1396:m_2', "m_tau", 18, 0, 1.8, fname='mtau'),
          ]
        
        else:
          mvis = Var('m_vis', 30, 50, 200, fname='mvis')
          observables = [
            #Var('m_vis', 30, 50, 200, fname='mvis'),
            Var('m_vis', 38, 10, 200, fname='mvis'), # broad range
            #Var('m_vis', 15, 50, 200, tag="_10"), # coarser binning
          ]
        
        
        ############
        #   BINS   #
        ############
        # selection categories
        
        if channel=='mumu':
          
          baseline  = "q_1*q_2<0 && iso_1<0.15 && iso_2<0.15 && !lepton_vetoes && metfilter"
          bins = [
            Sel('ZMM', baseline),
          ]
        
        else:
          
          tauwps    = ['VVVLoose','VVLoose','VLoose','Loose','Medium','Tight','VTight','VVTight']
          tauwpbits = { wp: 2**i for i, wp in enumerate(tauwps)}
          tauwps    = ['Tight'] # only do Tight
          iso_1     = "iso_1<0.15"
          iso_2     = "idDecayModeNewDMs_2 && idDeepTau2017v2p1VSjet_2>=$WP && idDeepTau2017v2p1VSe_2>=2 && idDeepTau2017v2p1VSmu_2>=8"
          baseline  = "q_1*q_2<0 && %s && %s && !lepton_vetoes_notau && metfilter"%(iso_1,iso_2)
          zttregion = "%s && mt_1<60 && dzeta>-25 && abs(deta_ll)<1.5"%(baseline)
          bins = [
            #Sel('baseline', repkey(baseline,WP=16)),
            #Sel('zttregion',repkey(zttregion,WP=16)),
          ]
          for wpname in tauwps: # loop over tau ID WPs
            wpbit = tauwpbits[wpname]
            bins.append(Sel(wpname,repkey(zttregion,WP=wpbit)))
        
        
        #######################
        #   DATACARD INPUTS   #
        #######################
        # histogram inputs for the datacards
        
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/SMTauTau2016
        chshort = channel.replace('tau','t').replace('mu','m') # abbreviation of channel
        fname   = repkey(fileexp,OUTDIR=outdir,ANALYSIS=analysis,CHANNEL=chshort,ERA=era,TAG=tag)
        createinputs(fname,samplesets['Nom'],observables,bins,recreate=True)
        if channel in ['mutau']:
          createinputs(fname,samplesets['TESUp'],  observables,bins,systs['TES'].up,filter=systs['TES'].procs)
          createinputs(fname,samplesets['TESDown'],observables,bins,systs['TES'].dn,filter=systs['TES'].procs)
          createinputs(fname,samplesets['LTFUp'],  observables,bins,systs['LTF'].up,filter=systs['LTF'].procs)
          createinputs(fname,samplesets['LTFDown'],observables,bins,systs['LTF'].dn,filter=systs['LTF'].procs)
          createinputs(fname,samplesets['JTFUp'],  observables,bins,systs['JTF'].up,filter=systs['JTF'].procs)
          createinputs(fname,samplesets['JTFDown'],observables,bins,systs['JTF'].dn,filter=systs['JTF'].procs)
          createinputs(fname,samplesets['Nom'],observables,bins,systs['tid'].up,filter=systs['tid'].procs,replaceweight=systs['tid'].wgtup)
          createinputs(fname,samplesets['Nom'],observables,bins,systs['tid'].dn,filter=systs['tid'].procs,replaceweight=systs['tid'].wgtdn)
          createinputs(fname,samplesets['Nom'],observables,bins,systs['zpt'].up,filter=systs['zpt'].procs,replaceweight=systs['zpt'].wgtup)
          createinputs(fname,samplesets['Nom'],observables,bins,systs['zpt'].dn,filter=systs['zpt'].procs,replaceweight=systs['zpt'].wgtdn)
        
        
        ############
        #   PLOT   #
        ############
        # control plots of the histogram inputs
        
        if plot:
          plotdir_ = ensuredir(repkey(plotdir,ERA=era,CHANNEL=channel))
          pname    = repkey(fileexp,OUTDIR=plotdir_,ANALYSIS=analysis,CHANNEL=chshort+"-$BIN",ERA=era,TAG='$TAG'+tag).replace('.root','.png')
          text     = "%s: $BIN"%(channel.replace("mu","#mu").replace("tau","#tau_{h}"))
          groups   = [ ] #(['^TT','ST'],'Top'),]
          plotinputs(fname,systs,observables,bins,text=text,
                     pname=pname,tag=tag,group=groups)
示例#9
0
def main():

    mvisbins = [0, 30, 40, 50, 60, 70, 75, 80, 90, 100, 120, 200]

    # Test several initializations of Variable object.
    # Note that key-word arguments starting with 'c' are used for context-dependent attributes
    variables = [
        Variable('m_vis', "m_{vis} [GeV]", 40, 0, 200),
        Variable('njets', "Number of jets", 8, 0, 8),
        Variable('m_vis', 40, 0, 200),
        Variable('njets', 8, 0, 8),
        Variable('njets', 8, 0, 8, veto='njets'),
        Variable('st', 20, 0, 800, title="S_{T}", only="njets",
                 blind="st>600"),
        Variable('m_vis',
                 40,
                 0,
                 200,
                 cbins={'njets': mvisbins},
                 blind=(70, 90)),
        Variable(
            'm_vis',
            mvisbins,
            cbins={"njets[^&]*2": (40, 0, 200)},
        ),
        Variable('pt_1+pt_2',
                 20,
                 0,
                 800,
                 title="S_{T}^{tautau}",
                 ctitle={"njets": "S_{T}"}),
    ]
    selections = [
        "pt_1>50 && pt_2>50",
        "pt_1>50 && pt_2>50 && njets>=1",
        "pt_1>50 && pt_2>50 && njets>=2 && nbtags>=1",
        "pt_1>50 && pt_2>50 && njets==0",
        "pt_1>50 && pt_2>50 && dzeta>-40",
    ]

    for var in variables:
        LOG.header(var.name)
        print ">>> string=%s, repr=%r" % (var, var)
        print ">>> name='%s', filename='%s', title='%s'" % (color(
            var.name), color(var.filename), color(var.title))
        print ">>> (nbins,xmin,xmax)=(%s,%s,%s), bins=%s" % (
            var.nbins, var.xmin, var.xmax, var.bins)
        print ">>> hasintbins=%s, hasvariablebins=%s" % (var.hasintbins(),
                                                         var.hasvariablebins())
        print ">>> cut=%r, blindcuts=%r, blind(50,60)=%r" % (
            var.cut, var.blindcuts, var.blind(50, 60))
        hist = var.gethist()
        print ">>> hist=%s, (nbins,xmin,xmax)=(%s,%s,%s), variable=%s" % (
            hist, hist.GetXaxis().GetNbins(), hist.GetXaxis().GetXmin(),
            hist.GetXaxis().GetXmax(), hist.GetXaxis().IsVariableBinSize())
        gDirectory.Delete(hist.GetName())
        for sel in selections:  # context-dependent attributes
            var.changecontext(sel)
            print ">>> context: '%s'" % color(sel, 'grey')
            print ">>>   plotfor=%s, name='%s', title='%s'" % (
                var.plotfor(sel), color(var.name), color(var.title))
            print ">>>   (nbins,xmin,xmax)=(%s,%s,%s), bins=%s" % (
                var.nbins, var.xmin, var.xmax, var.bins)
        print