CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_9_patch3/src/HiggsAnalysis/CombinedLimit/data/hww/interpolateCardsSimple4G.py

Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 import re, os
00003 from sys import argv, stdout, stderr, exit
00004 from optparse import OptionParser
00005 from math import *
00006 
00007 # import ROOT with a fix to get batch mode (https://root.cern.ch/phpBB3/viewtopic.php?t=3198)
00008 argv.append( '-b-' )
00009 import ROOT
00010 ROOT.gROOT.SetBatch(True)
00011 argv.remove( '-b-' )
00012 parser = OptionParser(usage="usage: %prog [options] [refmass1] mass3 > datacard3.txt \nrun with --help to get list of options")
00013 parser.add_option("--xsbr",  dest="xsbr",   action="store_true", default=False, help="Use correct XS*BR for Higgs")
00014 #parser.add_option("--doeff", dest="doeff",  action="store_true", default=False, help="Include interpolation of efficiency")
00015 #parser.add_option("--nobg",  dest="nobg",   action="store_true", default=False, help="No interpolation of background normalizations")
00016 parser.add_option("--log",   dest="log",    action="store_true", default=False, help="Use log-scale interpolation for yields (default is linear)")
00017 parser.add_option("--ddir",  dest="ddir", type="string", default=".", help="Path to the datacards")
00018 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)")
00019 parser.add_option("--postfix",    dest="postfix",   type="string",  default="",               help="Postfix to add to datacard name")
00020 (options, args) = parser.parse_args()
00021 options.bin = True; options.stat = False
00022 if len(args) not in [1,3]:
00023     parser.print_usage()
00024     exit(1)
00025 
00026 from HiggsAnalysis.CombinedLimit.DatacardParser import *
00027 
00028 refmasses = [ int(line) for line in open(options.ddir+"/"+options.refmasses,"r") ]
00029 
00030 if len(args) == 1:
00031     mass = float(args[0])
00032     mass1 = refmasses[0]
00033     for m in refmasses[1:]:
00034         if abs(mass1 - mass) > abs(m - mass) or (abs(mass1 - mass) == abs(m - mass) and abs(mass1 - 164) < abs(m - 164)):
00035             mass1 = m
00036 else:
00037     mass1 = int(args[0])
00038     mass  = float(args[1])
00039 
00040 if mass in refmasses and options.postfix == "": raise RuntimeError, "Will not overwrite the reference masses"
00041 
00042 xsbr1 = { 'ggH':1.0, 'qqH':1.0 }
00043 xsbr  = { 'ggH':1.0, 'qqH':1.0 }
00044 if options.xsbr:
00045     def file2map(x): 
00046         ret = {}; headers = []
00047         for x in open(x,"r"):
00048             cols = x.split()
00049             if len(cols) < 2: continue
00050             if "mH" in x: 
00051                 headers = [i.strip() for i in cols[1:]]
00052             else:
00053                 fields = [ float(i) for i in cols ]
00054                 ret[fields[0]] = dict(zip(headers,fields[1:]))
00055         return ret
00056     path = os.environ['CMSSW_BASE']+"/src/HiggsAnalysis/CombinedLimit/data/";   
00057     ggXS = file2map(path+"YR-XS-ggH.txt")
00058     qqXS = file2map(path+"YR-XS-vbfH.txt")
00059     br   = file2map(path+"YR-BR3.txt")
00060     sm4  = file2map(path+"SM4-600GeV.txt")
00061     # create points at 450, 550 by interpolation
00062     for M in (450,550):
00063         ggXS[M] = dict([ (key, 0.5*(ggXS[M+10][key] + ggXS[M-10][key])) for key in ggXS[M+10].iterkeys() ])
00064         qqXS[M] = dict([ (key, 0.5*(qqXS[M+10][key] + qqXS[M-10][key])) for key in qqXS[M+10].iterkeys() ])
00065         br[M] = dict([ (key, 0.5*(br[M+10][key] + br[M-10][key])) for key in br[M+10].iterkeys() ])
00066         sm4[M] = dict([ (key, 0.5*(sm4[M+10][key] + sm4[M-10][key])) for key in sm4[M+10].iterkeys() ])
00067     xsbr1['ggH'] = ggXS[mass1]['XS_pb'] * br[mass1]['H_evmv'] * sm4[mass1]['XS_over_SM'] * sm4[mass1]['brWW_over_SM']
00068     xsbr ['ggH'] = ggXS[mass ]['XS_pb'] * br[mass ]['H_evmv'] * sm4[mass ]['XS_over_SM'] * sm4[mass ]['brWW_over_SM']
00069     xsbr1['qqH'] = qqXS[mass1]['XS_pb'] * br[mass1]['H_evmv']
00070     xsbr ['qqH'] = qqXS[mass ]['XS_pb'] * br[mass ]['H_evmv']
00071 
00072 print "Will interpolate %g from %d" % (mass, mass1)
00073 
00074 for X in [ 'SM4_hwwof_0j_shape',  'SM4_hwwof_1j_shape',  'SM4_hwwsf_0j_shape',  'SM4_hwwsf_1j_shape', 'SM4_hww_2j_cut']:
00075     print "Considering datacard ",X
00076     if "shape" in X:
00077         XS = X.replace("_shape","")
00078         os.system("cp %s/%d/%s.input.root  %s/%g/%s%s.input.root" % (options.ddir,mass1,XS,options.ddir,mass,XS,options.postfix))
00079         ofile  = ROOT.TFile( "%s/%g/%s%s.input.root" % (options.ddir,mass,XS,options.postfix) , "UPDATE" )
00080 
00081     file1 = options.ddir+"/%d/%s.txt" % (mass1, X)
00082     options.fileName = file1; options.mass = mass1;
00083     DC1 = parseCard(open(file1,"r"), options)
00084 
00085     if len(DC1.bins) != 1: raise RuntimeError, "This does not work on multi-channel"
00086     obsline = [str(x) for x in DC1.obs.values()]; obskeyline = DC1.bins; cmax = 5;
00087     keyline = []; expline = []; systlines = {}; 
00088     signals = []; backgrounds = []; shapeLines = []; 
00089     paramSysts = {}; flatParamNuisances = {}
00090     for (name,nf,pdf,args,errline) in DC1.systs:
00091         systlines[name] = [ pdf, args, errline, nf ]
00092     for b,p,sig in DC1.keyline:
00093         rate = DC1.exp[b][p]
00094         if p in  ['ggH', 'qqH']:
00095             eff = rate/xsbr1[p]
00096             rate = eff * xsbr[p]
00097         if (rate != 0) and ("shape" in X): 
00098             histo = ofile.Get("histo_%s" % p);
00099             histo.Scale(rate/histo.Integral())
00100             ofile.WriteTObject(histo,"histo_%s" % p,"Overwrite");
00101         keyline.append( (b, p, DC1.isSignal[p]) )
00102         expline.append( "%.4f" % rate )
00103     shapeLines.append( ("*",        obskeyline[0], [ "%s%s.input.root" % (X,options.postfix),  "histo_$PROCESS" ]) )
00104     shapeLines.append( ("data_obs", obskeyline[0], [ "%s%s.input.root" % (X,options.postfix),  "histo_Data"     ]) )
00105 
00106 
00107     xfile = open(options.ddir+"/%d/%s%s.txt" % (mass, X,options.postfix), "w")
00108     xfile.write(" ".join(["imax %d number of bins" % len(DC1.bins)])+"\n")
00109     xfile.write(" ".join(["jmax *  number of processes minus 1"])+"\n")
00110     xfile.write(" ".join(["kmax *  number of nuisance parameters"])+"\n")
00111     xfile.write(" ".join(["-" * 130])+"\n")
00112     if shapeLines:
00113         chmax = max([max(len(p),len(c)) for p,c,x in shapeLines]);
00114         cfmt = "%-"+str(chmax)+"s ";
00115         for (process,channel,stuff) in shapeLines:
00116             xfile.write(" ".join(["shapes", cfmt % process, cfmt % channel, ' '.join(stuff)])+"\n")
00117         xfile.write(" ".join(["-" * 130])+"\n")
00118 
00119     if obsline:
00120         cmax = max([cmax]+[len(l) for l in obskeyline]+[len(x) for x in obsline])
00121         cfmt = "%-"+str(cmax)+"s";
00122         xfile.write(" ".join(["bin         ", "  ".join([cfmt % x for x in obskeyline])])+"\n")
00123         xfile.write(" ".join(["observation ", "  ".join([cfmt % x for x in obsline])])+"\n")
00124 
00125     xfile.write(" ".join(["-" * 150])+"\n")
00126 
00127     pidline = []; signals = []; backgrounds = []
00128     for (b,p,s) in keyline:
00129         if s:
00130             if p not in signals: signals.append(p)
00131             pidline.append(-len(DC1.signals)+signals.index(p)+1)
00132         else:
00133             if p not in backgrounds: backgrounds.append(p)
00134             pidline.append(1+backgrounds.index(p))
00135     cmax = max([cmax]+[max(len(p),len(b)) for p,b,s in keyline]+[len(e) for e in expline])
00136     hmax = max([10] + [len("%-12s  %s %s" % (l,p,a)) for l,(p,a,e,nf) in systlines.items()])
00137     cfmt  = "%-"+str(cmax)+"s"; hfmt = "%-"+str(hmax)+"s  ";
00138     xfile.write(" ".join([hfmt % "bin",     "  ".join([cfmt % p for p,b,s in keyline])])+"\n")
00139     xfile.write(" ".join([hfmt % "process", "  ".join([cfmt % b for p,b,s in keyline])])+"\n")
00140     xfile.write(" ".join([hfmt % "process", "  ".join([cfmt % x for x in pidline])])+"\n")
00141     xfile.write(" ".join([hfmt % "rate",    "  ".join([cfmt % x for x in expline])])+"\n")
00142     xfile.write(" ".join(["-" * 150])+"\n")
00143     sysnamesSorted = systlines.keys(); sysnamesSorted.sort()
00144     for name in sysnamesSorted:
00145         (pdf,pdfargs,effect,nofloat) = systlines[name]
00146         if nofloat: name += "[nofloat]"
00147         systline = []
00148         for b,p,s in keyline:
00149             try:
00150                 systline.append(effect[b][p] if (effect[b][p] != 1.0 or pdf != 'lnN') else "-")
00151             except KeyError:
00152                 systline.append("-");
00153         xfile.write(" ".join([hfmt % ("%-28s   %s  %s" % (name, pdf, " ".join(pdfargs))), "  ".join([cfmt % x for x in systline])])+"\n")
00154     for (pname, pargs) in paramSysts.items():
00155         xfile.write(" ".join(["%-12s  param  %s" %  (pname, " ".join(pargs))])+"\n")
00156 
00157     for pname in flatParamNuisances.iterkeys(): 
00158         xfile.write(" ".join(["%-12s  flatParam" % pname])+"\n")