CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
interpolateCardsSimpleSMto4G.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] [refmass1] mass3 > datacard3.txt \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")
14 #parser.add_option("--doeff", dest="doeff", action="store_true", default=False, help="Include interpolation of efficiency")
15 #parser.add_option("--nobg", dest="nobg", action="store_true", default=False, help="No interpolation of background normalizations")
16 parser.add_option("--log", dest="log", action="store_true", default=False, help="Use log-scale interpolation for yields (default is linear)")
17 parser.add_option("--ddir", dest="ddir", type="string", default=".", help="Path to the datacards")
18 parser.add_option("--refmasses", dest="refmasses", type="string", default="hww.masses.txt", help="File containing the reference masses between which to interpolate (relative to --options.ddir)")
19 parser.add_option("--postfix", dest="postfix", type="string", default="", help="Postfix to add to datacard name")
20 parser.add_option("--extraThUncertainty", dest="etu", type="float", default=0.0, help="Add this amount linearly to gg->H cross section uncertainties")
21 (options, args) = parser.parse_args()
22 options.bin = True; options.stat = False
23 if len(args) not in [1,3]:
24  parser.print_usage()
25  exit(1)
26 
28 
29 refmasses = [ int(line) for line in open(options.ddir+"/"+options.refmasses,"r") ]
30 
31 if len(args) == 1:
32  mass = float(args[0])
33  mass1 = refmasses[0]
34  for m in refmasses[1:]:
35  if abs(mass1 - mass) > abs(m - mass) or (abs(mass1 - mass) == abs(m - mass) and abs(mass1 - 164) < abs(m - 164)):
36  mass1 = m
37 else:
38  mass1 = int(args[0])
39  mass = float(args[1])
40 
41 xsbr1 = { 'ggH':1.0, 'qqH':1.0 }
42 xsbr = { 'ggH':1.0, 'qqH':1.0 }
43 def file2map(x):
44  ret = {}; headers = []
45  for x in open(x,"r"):
46  cols = x.split()
47  if len(cols) < 2: continue
48  if "mH" in x:
49  headers = [i.strip() for i in cols[1:]]
50  else:
51  fields = [ float(i) for i in cols ]
52  ret[fields[0]] = dict(zip(headers,fields[1:]))
53  return ret
54 path = os.environ['CMSSW_BASE']+"/src/HiggsAnalysis/CombinedLimit/data/";
55 ggXS = file2map(path+"YR-XS-ggH.txt")
56 qqXS = file2map(path+"YR-XS-vbfH.txt")
57 br = file2map(path+"YR-BR3.txt")
58 sm4 = file2map(path+"SM4-600GeV.txt")
59 # create points at 450, 550 by interpolation
60 for M in (450,550):
61  ggXS[M] = dict([ (key, 0.5*(ggXS[M+10][key] + ggXS[M-10][key])) for key in ggXS[M+10].iterkeys() ])
62  qqXS[M] = dict([ (key, 0.5*(qqXS[M+10][key] + qqXS[M-10][key])) for key in qqXS[M+10].iterkeys() ])
63  br[M] = dict([ (key, 0.5*(br[M+10][key] + br[M-10][key])) for key in br[M+10].iterkeys() ])
64  sm4[M] = dict([ (key, 0.5*(sm4[M+10][key] + sm4[M-10][key])) for key in sm4[M+10].iterkeys() ])
65 if options.xsbr:
66  xsbr1['ggH'] = ggXS[mass1]['XS_pb'] * br[mass1]['H_evmv']
67  xsbr ['ggH'] = ggXS[mass ]['XS_pb'] * br[mass ]['H_evmv'] * sm4[mass ]['XS_over_SM'] * sm4[mass ]['brWW_over_SM']
68  xsbr1['qqH'] = qqXS[mass1]['XS_pb'] * br[mass1]['H_evmv']
69  xsbr ['qqH'] = qqXS[mass ]['XS_pb'] * br[mass ]['H_evmv'] * sm4[mass ]['brWW_over_SM']
70 else:
71  xsbr['ggH'] = sm4[mass1]['XS_over_SM'] * sm4[mass1]['brWW_over_SM']
72  xsbr['qqH'] = sm4[mass1]['brWW_over_SM']
73 
74 
75 print "Will interpolate %g from %d" % (mass, mass1)
76 
77 for X in [ 'hwwof_0j_shape', 'hwwof_1j_shape', 'hwwsf_0j_shape', 'hwwsf_1j_shape', 'hww_2j_cut']:
78  #print "Considering datacard ",X
79  if "shape" in X:
80  XS = X.replace("_shape","")
81  os.system("cp %s/%d/%s.input.root %s/%g/SM4_%s%s.input.root" % (options.ddir,mass1,XS,options.ddir,mass,XS,options.postfix))
82  ofile = ROOT.TFile( "%s/%g/SM4_%s%s.input.root" % (options.ddir,mass,XS,options.postfix) , "UPDATE" )
83 
84  file1 = options.ddir+"/%d/%s.txt" % (mass1, X)
85  options.fileName = file1; options.mass = mass1;
86  DC1 = parseCard(open(file1,"r"), options)
87 
88  if len(DC1.bins) != 1: raise RuntimeError, "This does not work on multi-channel"
89  obsline = [str(x) for x in DC1.obs.values()]; obskeyline = DC1.bins; cmax = 5;
90  keyline = []; expline = []; systlines = {};
91  signals = []; backgrounds = []; shapeLines = [];
92  paramSysts = {}; flatParamNuisances = {}
93  for (name,nf,pdf,args,errline) in DC1.systs:
94  if options.etu != 0 and name in [ "QCDscale_ggH", "QCDscale_ggH1in", "QCDscale_ggH2in" ]:
95  for b in errline.iterkeys():
96  for p in errline[b].iterkeys():
97  if errline[b][p] != 0 and errline[b][p] != 1:
98  inflated = errline[b][p]+options.etu if errline[b][p] > 1 else errline[b][p]-options.etu
99  #print "Inflating uncertainty from %s to %s" % (errline[b][p], inflated);
100  errline[b][p] = inflated
101  systlines[name] = [ pdf, args, errline, nf ]
102  for b,p,sig in DC1.keyline:
103  rate = DC1.exp[b][p]
104  if p in ['ggH', 'qqH']:
105  eff = rate/xsbr1[p]
106  rate = eff * xsbr[p]
107  if (rate != 0) and ("shape" in X):
108  histo = ofile.Get("histo_%s" % p);
109  histo.Scale(rate/histo.Integral())
110  ofile.WriteTObject(histo,"histo_%s" % p,"Overwrite");
111  keyline.append( (b, p, DC1.isSignal[p]) )
112  expline.append( "%.4f" % rate )
113  if "shape" in X:
114  shapeLines.append( ("*", obskeyline[0], [ "SM4_%s%s.input.root" % (XS,options.postfix), "histo_$PROCESS" ]) )
115  shapeLines.append( ("data_obs", obskeyline[0], [ "SM4_%s%s.input.root" % (XS,options.postfix), "histo_Data" ]) )
116 
117 
118  xfile = open(options.ddir+"/%d/SM4_%s%s.txt" % (mass, X,options.postfix), "w")
119  xfile.write(" ".join(["imax %d number of bins" % len(DC1.bins)])+"\n")
120  xfile.write(" ".join(["jmax * number of processes minus 1"])+"\n")
121  xfile.write(" ".join(["kmax * number of nuisance parameters"])+"\n")
122  xfile.write(" ".join(["-" * 130])+"\n")
123  if shapeLines:
124  chmax = max([max(len(p),len(c)) for p,c,x in shapeLines]);
125  cfmt = "%-"+str(chmax)+"s ";
126  for (process,channel,stuff) in shapeLines:
127  xfile.write(" ".join(["shapes", cfmt % process, cfmt % channel, ' '.join(stuff)])+"\n")
128  xfile.write(" ".join(["-" * 130])+"\n")
129 
130  if obsline:
131  cmax = max([cmax]+[len(l) for l in obskeyline]+[len(x) for x in obsline])
132  cfmt = "%-"+str(cmax)+"s";
133  xfile.write(" ".join(["bin ", " ".join([cfmt % x for x in obskeyline])])+"\n")
134  xfile.write(" ".join(["observation ", " ".join([cfmt % x for x in obsline])])+"\n")
135 
136  xfile.write(" ".join(["-" * 150])+"\n")
137 
138  pidline = []; signals = []; backgrounds = []
139  for (b,p,s) in keyline:
140  if s:
141  if p not in signals: signals.append(p)
142  pidline.append(-len(DC1.signals)+signals.index(p)+1)
143  else:
144  if p not in backgrounds: backgrounds.append(p)
145  pidline.append(1+backgrounds.index(p))
146  cmax = max([cmax]+[max(len(p),len(b)) for p,b,s in keyline]+[len(e) for e in expline])
147  hmax = max([10] + [len("%-12s %s %s" % (l,p,a)) for l,(p,a,e,nf) in systlines.items()])
148  cfmt = "%-"+str(cmax)+"s"; hfmt = "%-"+str(hmax)+"s ";
149  xfile.write(" ".join([hfmt % "bin", " ".join([cfmt % p for p,b,s in keyline])])+"\n")
150  xfile.write(" ".join([hfmt % "process", " ".join([cfmt % b for p,b,s in keyline])])+"\n")
151  xfile.write(" ".join([hfmt % "process", " ".join([cfmt % x for x in pidline])])+"\n")
152  xfile.write(" ".join([hfmt % "rate", " ".join([cfmt % x for x in expline])])+"\n")
153  xfile.write(" ".join(["-" * 150])+"\n")
154  sysnamesSorted = systlines.keys(); sysnamesSorted.sort()
155  for name in sysnamesSorted:
156  (pdf,pdfargs,effect,nofloat) = systlines[name]
157  if nofloat: name += "[nofloat]"
158  systline = []
159  for b,p,s in keyline:
160  try:
161  systline.append(effect[b][p] if (effect[b][p] != 1.0 or pdf != 'lnN') else "-")
162  except KeyError:
163  systline.append("-");
164  xfile.write(" ".join([hfmt % ("%-28s %s %s" % (name, pdf, " ".join(pdfargs))), " ".join([cfmt % x for x in systline])])+"\n")
165  for (pname, pargs) in paramSysts.items():
166  xfile.write(" ".join(["%-12s param %s" % (pname, " ".join(pargs))])+"\n")
167 
168  for pname in flatParamNuisances.iterkeys():
169  xfile.write(" ".join(["%-12s flatParam" % pname])+"\n")
#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