CMS 3D CMS Logo

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PhysicsModel.py
Go to the documentation of this file.
1 
2 ### Class that takes care of building a physics model by combining individual channels and processes together
3 ### Things that it can do:
4 ### - define the parameters of interest (in the default implementation , "r")
5 ### - define other constant model parameters (e.g., "MH")
6 ### - yields a scaling factor for each pair of bin and process (by default, constant for background and linear in "r" for signal)
7 ### - possibly modifies the systematical uncertainties (does nothing by default)
9  def __init__(self):
10  pass
11  def setModelBuilder(self, modelBuilder):
12  "Connect to the ModelBuilder to get workspace, datacard and options. Should not be overloaded."
13  self.modelBuilder = modelBuilder
14  self.DC = modelBuilder.DC
15  self.options = modelBuilder.options
16  def setPhysicsOptions(self,physOptions):
17  "Receive a list of strings with the physics options from command line"
18  pass
20  """Create POI and other parameters, and define the POI set."""
21  # --- Signal Strength as only POI ---
22  self.modelBuilder.doVar("r[0,20]");
23  self.modelBuilder.doSet("POI","r")
24  # --- Higgs Mass as other parameter ----
25  if self.options.mass != 0:
26  if self.modelBuilder.out.var("MH"):
27  self.modelBuilder.out.var("MH").removeRange()
28  self.modelBuilder.out.var("MH").setVal(self.options.mass)
29  else:
30  self.modelBuilder.doVar("MH[%g]" % self.options.mass);
31  def preProcessNuisances(self,nuisances):
32  "receive the usual list of (name,nofloat,pdf,args,errline) to be edited"
33  pass # do nothing by default
34  def getYieldScale(self,bin,process):
35  "Return the name of a RooAbsReal to scale this yield by or the two special values 1 and 0 (don't scale, and set to zero)"
36  return "r" if self.DC.isSignal[process] else 1;
37 
38 
39 ### This base class implements signal yields by production and decay mode
40 ### Specific models can be obtained redefining getHiggsSignalYieldScale
42  def getHiggsSignalYieldScale(self, production, decay, energy):
43  raise RuntimeError, "Not implemented"
44  def getYieldScale(self,bin,process):
45  "Split in production and decay, and call getHiggsSignalYieldScale; return 1 for backgrounds "
46  if not self.DC.isSignal[process]: return 1
47  processSource = process
48  decaySource = self.options.fileName+":"+bin # by default, decay comes from the datacard name or bin label
49  if "_" in process: (processSource, decaySource) = process.split("_")
50  if processSource not in ["ggH", "qqH", "VH", "WH", "ZH", "ttH"]:
51  raise RuntimeError, "Validation Error: signal process %s not among the allowed ones." % processSource
52 
53  foundDecay = None
54  for D in [ "hww", "hzz", "hgg", "htt", "hbb" ]:
55  if D in decaySource:
56  if foundDecay: raise RuntimeError, "Validation Error: decay string %s contains multiple known decay names" % decaySource
57  foundDecay = D
58  if not foundDecay: raise RuntimeError, "Validation Error: decay string %s does not contain any known decay name" % decaySource
59 
60  foundEnergy = None
61  for D in [ '7TeV', '8TeV', '14TeV' ]:
62  if D in decaySource:
63  if foundEnergy: raise RuntimeError, "Validation Error: decay string %s contains multiple known energies" % decaySource
64  foundEnergy = D
65  if not foundEnergy:
66  foundEnergy = '7TeV' ## To ensure backward compatibility
67  print "Warning: decay string %s does not contain any known energy, assuming %s" % (decaySource, foundEnergy)
68 
69  return self.getHiggsSignalYieldScale(processSource, foundDecay, foundEnergy)
70 
72  "Doesn't do anything more, but validates that the signal process names are correct"
73  def getHiggsSignalYieldScale(self,production,decay, energy):
74  return "r"
75 
77  "assume the SM coupling but let the Higgs mass to float"
78  def __init__(self):
79  SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it
80  self.mHRange = ['115','135'] # default
81  def setPhysicsOptions(self,physOptions):
82  for po in physOptions:
83  if po.startswith("higgsMassRange="):
84  self.mHRange = po.replace("higgsMassRange=","").split(",")
85  print 'The Higgs mass range:', self.mHRange
86  if len(self.mHRange) != 2:
87  raise RuntimeError, "Higgs mass range definition requires two extrema"
88  elif float(self.mHRange[0]) >= float(self.mHRange[1]):
89  raise RuntimeError, "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first"
91  """Create POI out of signal strength and MH"""
92  # --- Signal Strength as only POI ---
93  self.modelBuilder.doVar("r[1,0,20]")
94  if self.modelBuilder.out.var("MH"):
95  self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1]))
96  self.modelBuilder.out.var("MH").setConstant(False)
97  else:
98  self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1]))
99  self.modelBuilder.doSet("POI",'r,MH')
100  def getHiggsSignalYieldScale(self,production,decay, energy):
101  return "r"
102 
103 
105  "Float independently ggH and qqH cross sections"
106  def __init__(self):
107  SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it
108  self.modes = [ "ggH", "qqH", "VH", "ttH" ]
109  self.mHRange = []
110  def setPhysicsOptions(self,physOptions):
111  for po in physOptions:
112  if po.startswith("modes="): self.modes = po.replace("modes=","").split(",")
113  if po.startswith("higgsMassRange="):
114  self.mHRange = po.replace("higgsMassRange=","").split(",")
115  if len(self.mHRange) != 2:
116  raise RuntimeError, "Higgs mass range definition requires two extrema"
117  elif float(self.mHRange[0]) >= float(self.mHRange[1]):
118  raise RuntimeError, "Extrema for Higgs mass range defined with inverterd order. Second must be larger the first"
120  """Create POI and other parameters, and define the POI set."""
121  # --- Signal Strength as only POI ---
122  if "ggH" in self.modes: self.modelBuilder.doVar("r_ggH[1,0,5]");
123  if "qqH" in self.modes: self.modelBuilder.doVar("r_qqH[1,0,20]");
124  if "VH" in self.modes: self.modelBuilder.doVar("r_VH[1,0,20]");
125  if "ttH" in self.modes: self.modelBuilder.doVar("r_ttH[1,0,20]");
126  poi = ",".join(["r_"+m for m in self.modes])
127  # --- Higgs Mass as other parameter ----
128  if self.modelBuilder.out.var("MH"):
129  if len(self.mHRange):
130  print 'MH will be left floating within', self.mHRange[0], 'and', self.mHRange[1]
131  self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1]))
132  self.modelBuilder.out.var("MH").setConstant(False)
133  poi+=',MH'
134  else:
135  print 'MH will be assumed to be', self.options.mass
136  self.modelBuilder.out.var("MH").removeRange()
137  self.modelBuilder.out.var("MH").setVal(self.options.mass)
138  else:
139  if len(self.mHRange):
140  print 'MH will be left floating within', self.mHRange[0], 'and', self.mHRange[1]
141  self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1]))
142  poi+=',MH'
143  else:
144  print 'MH (not there before) will be assumed to be', self.options.mass
145  self.modelBuilder.doVar("MH[%g]" % self.options.mass)
146  self.modelBuilder.doSet("POI",poi)
147  def getHiggsSignalYieldScale(self,production,decay, energy):
148  if production == "ggH": return ("r_ggH" if "ggH" in self.modes else 1)
149  if production == "qqH": return ("r_qqH" if "qqH" in self.modes else 1)
150  if production == "ttH": return ("r_ttH" if "ttH" in self.modes else 1)
151  if production in [ "WH", "ZH", "VH" ]: return ("r_VH" if "VH" in self.modes else 1)
152  raise RuntimeError, "Unknown production mode '%s'" % production
153 
155  "Float independently ggH and qqH cross sections"
156  def __init__(self):
157  SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it
158  self.modes = [ "hbb", "htt", "hgg", "hww", "hzz" ]
159  self.mHRange = []
160  def setPhysicsOptions(self,physOptions):
161  for po in physOptions:
162  if po.startswith("modes="): self.modes = po.replace("modes=","").split(",")
163  if po.startswith("higgsMassRange="):
164  self.mHRange = po.replace("higgsMassRange=","").split(",")
165  if len(self.mHRange) != 2:
166  raise RuntimeError, "Higgs mass range definition requires two extrema"
167  elif float(self.mHRange[0]) >= float(self.mHRange[1]):
168  raise RuntimeError, "Extrema for Higgs mass range defined with inverterd order. Second must be larger the first"
170  """Create POI and other parameters, and define the POI set."""
171  # --- Signal Strength as only POI ---
172  for m in self.modes:
173  self.modelBuilder.doVar("r_%s[1,0,10]" % m);
174  poi = ",".join(["r_"+m for m in self.modes])
175  # --- Higgs Mass as other parameter ----
176  if self.modelBuilder.out.var("MH"):
177  if len(self.mHRange):
178  print 'MH will be left floating within', self.mHRange[0], 'and', self.mHRange[1]
179  self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1]))
180  self.modelBuilder.out.var("MH").setConstant(False)
181  poi+=',MH'
182  else:
183  print 'MH will be assumed to be', self.options.mass
184  self.modelBuilder.out.var("MH").removeRange()
185  self.modelBuilder.out.var("MH").setVal(self.options.mass)
186  else:
187  if len(self.mHRange):
188  print 'MH will be left floating within', self.mHRange[0], 'and', self.mHRange[1]
189  self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1]))
190  poi+=',MH'
191  else:
192  print 'MH (not there before) will be assumed to be', self.options.mass
193  self.modelBuilder.doVar("MH[%g]" % self.options.mass)
194  self.modelBuilder.doSet("POI",poi)
195  def getHiggsSignalYieldScale(self,production,decay, energy):
196  if decay in self.modes:
197  return "r_"+decay
198  elif decay not in [ "hbb", "htt", "hgg", "hww", "hzz" ]:
199  raise RuntimeError, "Unknown decay mode '%s'" % decay
200 
201 defaultModel = PhysicsModel()
202 strictSMLikeHiggs = StrictSMLikeHiggsModel()
203 floatingXSHiggs = FloatingXSHiggs()
204 floatingBRHiggs = FloatingBRHiggs()
205 floatingHiggsMass = FloatingHiggsMass()
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
double split
Definition: MVATrainer.cc:139
Class that takes care of building a physics model by combining individual channels and processes toge...
Definition: PhysicsModel.py:8