CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
scaleCards.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 import re, os
3 from sys import argv, stdout, stderr, exit
4 from optparse import OptionParser
5 from math import *
6 
7 # import ROOT with a fix to get batch mode (http://root.cern.ch/phpBB3/viewtopic.php?t=3198)
8 argv.append( '-b-' )
9 import ROOT
10 ROOT.gROOT.SetBatch(True)
11 argv.remove( '-b-' )
12 parser = OptionParser(usage="usage: %prog [options] mass \nrun with --help to get list of options")
13 parser.add_option("--xsbr", dest="xsbr", action="store_true", default=False, help="Use correct XS*BR for Higgs (if not enabled, just makes a flat copy)")
14 parser.add_option("--ddir", dest="ddir", type="string", default=".", help="Path to the datacards")
15 parser.add_option("--refmasse", dest="refmass", type="float", default="0", help="Reference mass to start from (default = nearest one, left in case of ties)")
16 parser.add_option("--postfix", dest="postfix", type="string", default="", help="Postfix to add to datacard name")
17 parser.add_option("--flavour", dest="flavour", type="string", default="BDT", help="flavour of datacard (vhbb_DC_ALL_<FLAVOUR>.<MASS.DECIMAL>.txt)")
18 (options, args) = parser.parse_args()
19 options.bin = True; options.stat = False
20 if len(args) not in [1]:
21  parser.print_usage()
22  exit(1)
23 
25 
26 refmasses = range(110,135+1,5)
27 mass = float(args[0])
28 
29 if options.refmass == 0:
30  options.refmass = refmasses[0]
31  for m in refmasses[1:]:
32  if abs(mass-m) < abs(mass-options.refmass):
33  options.refmass = m
34 
35 if mass in refmasses and options.postfix == "": raise RuntimeError, "Will not overwrite the reference masses"
36 
37 xsbrR = { 'WH':1.0, 'ZH':1.0 }
38 xsbr = { 'WH':1.0, 'ZH':1.0 }
39 if options.xsbr:
40  def file2map(x):
41  ret = {}; headers = []
42  for x in open(x,"r"):
43  cols = x.split()
44  if len(cols) < 2: continue
45  if "mH" in x:
46  headers = [i.strip() for i in cols[1:]]
47  else:
48  fields = [ float(i) for i in cols ]
49  ret[fields[0]] = dict(zip(headers,fields[1:]))
50  return ret
51  path = os.environ['CMSSW_BASE']+"/src/HiggsAnalysis/CombinedLimit/data/";
52  whXS = file2map(path+"YR-XS-WH.txt")
53  zhXS = file2map(path+"YR-XS-ZH.txt")
54  br = file2map(path+"YR-BR1.txt")
55  xsbrR['WH'] = whXS[options.refmass]['XS_pb'] * br[options.refmass]['H_bb']
56  xsbr ['WH'] = whXS[mass ]['XS_pb'] * br[mass ]['H_bb']
57  xsbrR['ZH'] = zhXS[options.refmass]['XS_pb'] * br[options.refmass]['H_bb']
58  xsbr ['ZH'] = zhXS[mass ]['XS_pb'] * br[mass ]['H_bb']
59  print "Will interpolate %g from %g (XS*BR ratio: %.3f for WH, %.3f for ZH)" % (mass, options.refmass, xsbr['WH']/xsbrR['WH'], xsbr['ZH']/xsbrR['ZH'])
60 else:
61  print "Will copy %g from %g" % (mass, options.refmass)
62 
63 fileR = options.ddir+"/%g/vhbb_DC_ALL_%s.%.1f.txt" % (options.refmass, options.flavour, options.refmass)
64 options.fileName = fileR; options.mass = options.refmass;
65 DCR = parseCard(open(fileR,"r"), options)
66 
67 obskeyline = DCR.bins;
68 obsline = [str(DCR.obs[b]) for b in DCR.bins];
69 cmax = 5;
70 keyline = []; expline = []; systlines = {}; systlines2 = {}
71 signals = []; backgrounds = []; shapeLines = [];
72 paramSysts = {}; flatParamNuisances = {}
73 for (name,nf,pdf,args,errline) in DCR.systs:
74  systlines[name] = [ pdf, args, errline, nf ]
75 
76 for b,p,sig in DCR.keyline:
77  rate = DCR.exp[b][p]
78  if p == "VH":
79  pTrue = "WH" if b[0] == "W" else "ZH";
80  rate = rate * xsbr[pTrue]/xsbrR[pTrue]
81  keyline.append( (b, p, DCR.isSignal[p]) )
82  expline.append( "%.4f" % rate )
83 
84 xfile = open(options.ddir+"/%g/vhbb_DC_ALL_%s%s.%.1f.txt" % (mass, options.flavour, options.postfix, mass), "w")
85 xfile.write(" ".join(["imax %d number of bins" % len(DCR.bins)])+"\n")
86 xfile.write(" ".join(["jmax * number of processes minus 1"])+"\n")
87 xfile.write(" ".join(["kmax * number of nuisance parameters"])+"\n")
88 xfile.write(" ".join(["-" * 130])+"\n")
89 
90 cmax = max([cmax]+[len(l) for l in obskeyline]+[len(x) for x in obsline])
91 cfmt = "%-"+str(cmax)+"s";
92 xfile.write(" ".join(["bin ", " ".join([cfmt % x for x in obskeyline])])+"\n")
93 xfile.write(" ".join(["observation ", " ".join([cfmt % x for x in obsline])])+"\n")
94 
95 xfile.write(" ".join(["-" * 150])+"\n")
96 
97 pidline = []; signals = []; backgrounds = []
98 for (b,p,s) in keyline:
99  if s:
100  if p not in signals: signals.append(p)
101  pidline.append(-len(DCR.signals)+signals.index(p)+1)
102  else:
103  if p not in backgrounds: backgrounds.append(p)
104  pidline.append(1+backgrounds.index(p))
105 cmax = max([cmax]+[max(len(p),len(b)) for p,b,s in keyline]+[len(e) for e in expline])
106 hmax = max([10] + [len("%-12s %s %s" % (l,p,a)) for l,(p,a,e,nf) in systlines.items()])
107 cfmt = "%-"+str(cmax)+"s"; hfmt = "%-"+str(hmax)+"s ";
108 xfile.write(" ".join([hfmt % "bin", " ".join([cfmt % p for p,b,s in keyline])])+"\n")
109 xfile.write(" ".join([hfmt % "process", " ".join([cfmt % b for p,b,s in keyline])])+"\n")
110 xfile.write(" ".join([hfmt % "process", " ".join([cfmt % x for x in pidline])])+"\n")
111 xfile.write(" ".join([hfmt % "rate", " ".join([cfmt % x for x in expline])])+"\n")
112 xfile.write(" ".join(["-" * 150])+"\n")
113 sysnamesSorted = systlines.keys(); sysnamesSorted.sort()
114 for name in sysnamesSorted:
115  (pdf,pdfargs,effect,nofloat) = systlines[name]
116  if nofloat: name += "[nofloat]"
117  systline = []
118  for b,p,s in keyline:
119  try:
120  systline.append(effect[b][p] if (effect[b][p] != 1.0 or pdf != 'lnN') else "-")
121  except KeyError:
122  systline.append("-");
123  xfile.write(" ".join([hfmt % ("%-28s %s %s" % (name, pdf, " ".join(pdfargs))), " ".join([cfmt % x for x in systline])])+"\n")
124 
#define abs(x)
Definition: mlp_lapack.h:159
const T & max(const T &a, const T &b)
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def file2map
Definition: scaleCards.py:40