class RwzHiggs(SMLikeHiggsModel): "scale WW by mu and ZZ by cZW^2 * mu" def __init__(self): SMLikeHiggsModel.__init__( self ) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False def setPhysicsOptions(self, physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=", "").split(",") print("The Higgs mass range:", self.mHRange) if len(self.mHRange) != 2: raise RuntimeError( "Higgs mass range definition requires two extrema.") elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError( "Extrema for Higgs mass range defined with inverterd order. Second must be larger the first." ) def doParametersOfInterest(self): """Create POI out of signal strength and MH""" # --- Signal Strength as only POI --- self.modelBuilder.doVar("Rwz[1,0,10]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange( float(self.mHRange[0]), float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0], self.mHRange[1])) self.modelBuilder.doSet("POI", "Rwz,MH") else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI", "Rwz") self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): for d in ["hww", "hzz"]: self.SMH.makeBR(d) self.modelBuilder.doVar("Rhzz[1,0,10]") self.modelBuilder.factory_('expr::Rhww("@0*@1", Rhzz, Rwz)') def getHiggsSignalYieldScale(self, production, decay, energy): if decay not in ["hww", "hzz"]: return 0 else: return "R%s" % decay
class RwzHiggs(SMLikeHiggsModel): "scale WW by mu and ZZ by cZW^2 * mu" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema." elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrema for Higgs mass range defined with inverterd order. Second must be larger the first." def doParametersOfInterest(self): """Create POI out of signal strength and MH""" # --- Signal Strength as only POI --- self.modelBuilder.doVar("Rwz[1,0,10]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) self.modelBuilder.doSet("POI",'Rwz,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI",'Rwz') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): for d in [ "hww", "hzz" ]: self.SMH.makeBR(d) self.modelBuilder.doVar("Rhzz[1,0,10]") self.modelBuilder.factory_('expr::Rhww("@0*@1", Rhzz, Rwz)') def getHiggsSignalYieldScale(self,production,decay,energy): if decay not in ['hww', 'hzz']: return 0 else: return 'R%s' % decay
class FermiophobicHiggs(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.mHRange = ['115','135'] # default def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema" elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first" def doParametersOfInterest(self): """Create POI out of signal strength and MH""" # --- Signal Strength as only POI --- self.modelBuilder.doVar("r[1,0,20]") if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) self.modelBuilder.doSet("POI",'r,MH') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): ## Add FP BRs datadir = os.environ['CMSSW_BASE']+'/src/HiggsAnalysis/CombinedLimit/data/lhc-hxswg' self.SMH.textToSpline( 'FP_BR_hww', os.path.join(datadir, 'fp/BR.txt'), ycol=4 ); self.SMH.textToSpline( 'FP_BR_hzz', os.path.join(datadir, 'fp/BR.txt'), ycol=5 ); self.SMH.textToSpline( 'FP_BR_hgg', os.path.join(datadir, 'fp/BR.txt'), ycol=2 ); self.SMH.textToSpline( 'FP_BR_hzg', os.path.join(datadir, 'fp/BR.txt'), ycol=3 ); for decay in ['hww','hzz','hgg','hzg']: self.SMH.makeBR(decay) self.modelBuilder.factory_('expr::FP_BRScal_%s("@0*@1/@2",r,FP_BR_%s,SM_BR_%s)'%(decay,decay,decay)) self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self,production,decay,energy): if production not in ['VH', 'WH', 'ZH', 'qqH']: return 0 if decay not in ['hww','hzz','hgg','hzg']: return 0 return 'FP_BRScal_%s' % decay
class LambdaduHiggs(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema" elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first" def doParametersOfInterest(self): """Create POI out of signal strength and MH""" self.modelBuilder.doVar("kV[1,0,2]") self.modelBuilder.doVar("lambdadu[1,-3,3]") self.modelBuilder.doVar("ku[1,0,2]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) self.modelBuilder.doSet("POI",'kV,lambdadu,ku,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI",'kV,lambdadu,ku') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): self.decayScaling = { 'hgg':'hgg', 'hZg':'hZg', 'hww':'hvv', 'hzz':'hvv', 'hbb':'hdd', 'htt':'hdd', } self.productionScaling = { 'ttH':'ku', 'qqH':'kV', 'WH':'kV', 'ZH':'kV', 'VH':'kV', } # define kd as lambdadu*ku self.modelBuilder.factory_('expr::kd("@0*@1",ku, lambdadu)') # scalings of the loops self.SMH.makeScaling('ggH', Cb='kd', Ctop='ku') self.SMH.makeScaling('hgg', Cb='kd', Ctop='ku', CW='kV', Ctau='kd') self.SMH.makeScaling('hZg', Cb='kd', Ctop='ku', CW='kV', Ctau='kd') self.SMH.makeScaling('hgluglu', Cb='kd', Ctop='ku') # SM BR for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hZg", "hmm", "hss" ]: self.SMH.makeBR(d) ## total witdhs, normalized to the SM one self.modelBuilder.factory_('expr::lambdadu_Gscal_Vectors("@0*@0 * (@1+@2)", kV, SM_BR_hzz, SM_BR_hww)') self.modelBuilder.factory_('expr::lambdadu_Gscal_up("@0*@0 * (@1+@2)", ku, SM_BR_hcc, SM_BR_htoptop)') self.modelBuilder.factory_('expr::lambdadu_Gscal_down("@0*@0 * (@1+@2+@3+@4)", kd, SM_BR_hbb, SM_BR_htt, SM_BR_hmm, SM_BR_hss)') self.modelBuilder.factory_('expr::lambdadu_Gscal_gg("@0 * @1", Scaling_hgg, SM_BR_hgg)') self.modelBuilder.factory_('expr::lambdadu_Gscal_Zg("@0 * @1", Scaling_hZg, SM_BR_hZg)') self.modelBuilder.factory_('expr::lambdadu_Gscal_gluglu("@0 * @1", Scaling_hgluglu, SM_BR_hgluglu)') self.modelBuilder.factory_('sum::lambdadu_Gscal_tot(lambdadu_Gscal_Vectors, lambdadu_Gscal_up, lambdadu_Gscal_down, lambdadu_Gscal_gg, lambdadu_Gscal_Zg, lambdadu_Gscal_gluglu)') ## BRs, normalized to the SM ones: they scale as (partial/partial_SM)^2 / (total/total_SM)^2 self.modelBuilder.factory_('expr::lambdadu_BRscal_hvv("@0*@0/@1", kV, lambdadu_Gscal_tot)') self.modelBuilder.factory_('expr::lambdadu_BRscal_huu("@0*@0/@1", ku, lambdadu_Gscal_tot)') self.modelBuilder.factory_('expr::lambdadu_BRscal_hdd("@0*@0/@1", kd, lambdadu_Gscal_tot)') self.modelBuilder.factory_('expr::lambdadu_BRscal_hgg("@0/@1", Scaling_hgg, lambdadu_Gscal_tot)') self.modelBuilder.factory_('expr::lambdadu_BRscal_hZg("@0/@1", Scaling_hZg, lambdadu_Gscal_tot)') # verbosity #self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self,production,decay,energy): name = 'lambdadu_XSBRscal_%(production)s_%(decay)s' % locals() #Special case that depends on Energy if production == 'ggH': self.productionScaling[production] = 'Scaling_ggH_' + energy name += '_%(energy)s' % locals() if self.modelBuilder.out.function(name): return name XSscal = self.productionScaling[production] BRscal = self.decayScaling[decay] self.modelBuilder.factory_('expr::%s("@0*@0 * @1", %s, lambdadu_BRscal_%s)' % (name, XSscal, BRscal)) return name
class CfXgHiggs(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema." elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrema for Higgs mass range defined with inverterd order. Second must be larger the first." def doParametersOfInterest(self): """Create POI out of signal strength and MH""" # --- Signal Strength as only POI --- self.modelBuilder.doVar("CV[1]") self.modelBuilder.doVar("CF[1,-1.5,1.5]") self.modelBuilder.doVar("XG[0,-4,4]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) self.modelBuilder.doSet("POI",'CF,XG,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI",'CF,XG') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): ## Add some common ingredients datadir = os.environ['CMSSW_BASE']+'/src/HiggsAnalysis/CombinedLimit/data/lhc-hxswg' self.SMH.textToSpline( 'mb', os.path.join(datadir, 'running_constants.txt'), ycol=2 ); mb = self.modelBuilder.out.function('mb') mH = self.modelBuilder.out.var('MH') CF = self.modelBuilder.out.var('CF') CV = self.modelBuilder.out.var('CV') XG = self.modelBuilder.out.var('XG') RHggCfXg = ROOT.RooScaleHGamGamLOSMPlusX('CfXg_cgammaSq', 'LO SM Hgamgam scaling', mH, CF, CV, mb, CF, XG) self.modelBuilder.out._import(RHggCfXg) #Rgluglu = ROOT.RooScaleHGluGluLOSMPlusX('Rgluglu', 'LO SM Hgluglu scaling', mH, CF, mb, CF) #self.modelBuilder.out._import(Rgluglu) ## partial witdhs, normalized to the SM one, for decays scaling with F, V and total for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) self.modelBuilder.factory_('expr::CfXg_Gscal_sumf("@0*@0 * (@1+@2+@3+@4+@5+@6+@7)", CF, SM_BR_hbb, SM_BR_htt, SM_BR_hcc, SM_BR_htoptop, SM_BR_hgluglu, SM_BR_hmm, SM_BR_hss)') self.modelBuilder.factory_('sum::CfXg_Gscal_sumv(SM_BR_hww, SM_BR_hzz, SM_BR_hzg)') self.modelBuilder.factory_('expr::CfXg_Gscal_gg("@0 * @1", CfXg_cgammaSq, SM_BR_hgg)') self.modelBuilder.factory_('sum::CfXg_Gscal_tot(CfXg_Gscal_sumf, CfXg_Gscal_sumv, CfXg_Gscal_gg)') ## BRs, normalized to the SM ones: they scale as (coupling/coupling_SM)^2 / (totWidth/totWidthSM)^2 self.modelBuilder.factory_('expr::CfXg_BRscal_hgg("@0/@1", CfXg_cgammaSq, CfXg_Gscal_tot)') self.modelBuilder.factory_('expr::CfXg_BRscal_hf("@0*@0/@1", CF, CfXg_Gscal_tot)') self.modelBuilder.factory_('expr::CfXg_BRscal_hv("1.0/@0", CfXg_Gscal_tot)') self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self,production,decay,energy): name = "CfXg_XSBRscal_%s_%s" % (production,decay) if self.modelBuilder.out.function(name) == None: XSscal = 'CF' if production in ["ggH","ttH"] else 'CV' BRscal = "hgg" if decay in ["hww", "hzz"]: BRscal = "hv" if decay in ["hbb", "htt"]: BRscal = "hf" self.modelBuilder.factory_('expr::%s("@0*@0 * @1", %s, CfXg_BRscal_%s)' % (name, XSscal, BRscal)) return name
class KappaVKappaT(LHCHCGBaseModel): """ Copy of Kappas model with a combined kappa_V (for kappa_W and kappa_Z), and where hcc is independent of kappa_t. For tHq multilepton analysis (HIG-17-005) NOTE - Do not use this model for a generic analysis, instead use the LHCHCGModels:K3 or K7 models and freeze POIs accordingly """ def __init__(self, resolved=True, BRU=True, addInvisible=False, coupleTopTau=False): LHCHCGBaseModel.__init__( self ) # not using 'super(x,self).__init__' since I don't understand it self.doBRU = BRU self.resolved = resolved self.addInvisible = addInvisible self.coupleTopTau = coupleTopTau def setPhysicsOptions(self, physOptions): self.setPhysicsOptionsBase(physOptions) for po in physOptions: if po.startswith("BRU="): self.doBRU = (po.replace("BRU=", "") in ["yes", "1", "Yes", "True", "true"]) print "BR uncertainties in partial widths: %s " % self.doBRU def doParametersOfInterest(self): """Create POI out of signal strength and MH""" self.modelBuilder.doVar("r[1,0.0,10.0]") self.modelBuilder.doVar("kappa_V[1,0.0,2.0]") self.modelBuilder.doVar("kappa_t[1,-10.0,10.0]") self.modelBuilder.doVar("kappa_mu[1,0.0,5.0]") if not self.coupleTopTau: self.modelBuilder.doVar("kappa_tau[1,0.0,3.0]") self.modelBuilder.factory_( "expr::kappa_mu_expr(\"@0*@1+(1-@0)*@2\", CMS_use_kmu[0], kappa_mu, kappa_tau)" ) else: self.modelBuilder.factory_( "expr::kappa_mu_expr(\"@0*@1+(1-@0)*@2\", CMS_use_kmu[0], kappa_mu, kappa_t)" ) self.modelBuilder.doVar("kappa_b[1,0.0,3.0]") self.modelBuilder.doVar( "kappa_c[1,0.0,3.0]") # treat hcc independently from kappa_t if not self.resolved: self.modelBuilder.doVar("kappa_g[1,0.0,2.0]") self.modelBuilder.doVar("kappa_gam[1,0.0,2.5]") self.modelBuilder.doVar("BRinv[0,0,1]") if not self.addInvisible: self.modelBuilder.out.var("BRinv").setConstant(True) pois = 'kappa_V,kappa_t,kappa_b,kappa_c' if not self.coupleTopTau: pois += ',kappa_tau' if not self.resolved: pois += ',kappa_g,kappa_gam' if self.addInvisible: pois += ",BRinv" self.doMH() self.modelBuilder.doSet("POI", pois) self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): self.dobbH() # SM BR for d in SM_HIGG_DECAYS + ["hss"]: self.SMH.makeBR(d) # BR uncertainties if self.doBRU: self.SMH.makePartialWidthUncertainties() else: for d in SM_HIGG_DECAYS: self.modelBuilder.factory_( 'HiggsDecayWidth_UncertaintyScaling_%s[1.0]' % d) # get VBF, tHq, tHW, ggZH cross section self.SMH.makeScaling('qqH', CW='kappa_V', CZ='kappa_V') self.SMH.makeScaling("tHq", CW='kappa_V', Ctop="kappa_t") self.SMH.makeScaling("tHW", CW='kappa_V', Ctop="kappa_t") self.SMH.makeScaling("ggZH", CZ='kappa_V', Ctop="kappa_t", Cb="kappa_b") # resolve loops if self.resolved: self.SMH.makeScaling('ggH', Cb='kappa_b', Ctop='kappa_t', Cc="kappa_t") self.SMH.makeScaling('hgluglu', Cb='kappa_b', Ctop='kappa_t') if not self.coupleTopTau: self.SMH.makeScaling('hgg', Cb='kappa_b', Ctop='kappa_t', CW='kappa_V', Ctau='kappa_tau') self.SMH.makeScaling('hzg', Cb='kappa_b', Ctop='kappa_t', CW='kappa_V', Ctau='kappa_tau') else: self.SMH.makeScaling('hgg', Cb='kappa_b', Ctop='kappa_t', CW='kappa_V', Ctau='kappa_t') self.SMH.makeScaling('hzg', Cb='kappa_b', Ctop='kappa_t', CW='kappa_V', Ctau='kappa_t') else: self.modelBuilder.factory_( 'expr::Scaling_hgluglu("@0*@0", kappa_g)') self.modelBuilder.factory_('expr::Scaling_hgg("@0*@0", kappa_gam)') self.modelBuilder.factory_('expr::Scaling_hzg("@0*@0", kappa_gam)') self.modelBuilder.factory_( 'expr::Scaling_ggH_7TeV("@0*@0", kappa_g)') self.modelBuilder.factory_( 'expr::Scaling_ggH_8TeV("@0*@0", kappa_g)') self.modelBuilder.factory_( 'expr::Scaling_ggH_13TeV("@0*@0", kappa_g)') self.modelBuilder.factory_( 'expr::Scaling_ggH_14TeV("@0*@0", kappa_g)') ## partial witdhs, normalized to the SM one self.modelBuilder.factory_( 'expr::c7_Gscal_Z("@0*@0*@1*@2", kappa_V, SM_BR_hzz, HiggsDecayWidth_UncertaintyScaling_hzz)' ) self.modelBuilder.factory_( 'expr::c7_Gscal_W("@0*@0*@1*@2", kappa_V, SM_BR_hww, HiggsDecayWidth_UncertaintyScaling_hww)' ) if not self.coupleTopTau: self.modelBuilder.factory_( 'expr::c7_Gscal_tau("@0*@0*@1*@4+@2*@2*@3*@5", kappa_tau, SM_BR_htt, kappa_mu_expr, SM_BR_hmm, HiggsDecayWidth_UncertaintyScaling_htt, HiggsDecayWidth_UncertaintyScaling_hmm)' ) else: self.modelBuilder.factory_( 'expr::c7_Gscal_tau("@0*@0*@1*@4+@2*@2*@3*@5", kappa_t, SM_BR_htt, kappa_mu_expr, SM_BR_hmm, HiggsDecayWidth_UncertaintyScaling_htt, HiggsDecayWidth_UncertaintyScaling_hmm)' ) self.modelBuilder.factory_( 'expr::c7_Gscal_top("@0*@0 * @1*@2", kappa_c, SM_BR_hcc, HiggsDecayWidth_UncertaintyScaling_hcc)' ) self.modelBuilder.factory_( 'expr::c7_Gscal_bottom("@0*@0 * (@1*@3+@2)", kappa_b, SM_BR_hbb, SM_BR_hss, HiggsDecayWidth_UncertaintyScaling_hbb)' ) self.modelBuilder.factory_( 'expr::c7_Gscal_gluon(" @0 * @1 * @2", Scaling_hgluglu, SM_BR_hgluglu, HiggsDecayWidth_UncertaintyScaling_hgluglu)' ) self.modelBuilder.factory_( 'expr::c7_Gscal_gamma("@0*@1*@4 + @2*@3*@5", Scaling_hgg, SM_BR_hgg, Scaling_hzg, SM_BR_hzg, HiggsDecayWidth_UncertaintyScaling_hgg, HiggsDecayWidth_UncertaintyScaling_hzg)' ) # fix to have all BRs add up to unity self.modelBuilder.factory_("sum::c7_SMBRs(%s)" % (",".join( "SM_BR_" + X for X in "hzz hww htt hmm hcc hbb hss hgluglu hgg hzg".split()))) self.modelBuilder.out.function("c7_SMBRs").Print("") ## total witdh, normalized to the SM one self.modelBuilder.factory_( 'expr::c7_Gscal_tot("(@1+@2+@3+@4+@5+@6+@7)/@8/(1-@0)", BRinv, c7_Gscal_Z, c7_Gscal_W, c7_Gscal_tau, c7_Gscal_top, c7_Gscal_bottom, c7_Gscal_gluon, c7_Gscal_gamma, c7_SMBRs)' ) ## BRs, normalized to the SM ones: they scale as (partial/partial_SM) / (total/total_SM) self.modelBuilder.factory_( 'expr::c7_BRscal_hww("@0*@0*@2/@1", kappa_V, c7_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hww)' ) self.modelBuilder.factory_( 'expr::c7_BRscal_hzz("@0*@0*@2/@1", kappa_V, c7_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hzz)' ) if not self.coupleTopTau: self.modelBuilder.factory_( 'expr::c7_BRscal_htt("@0*@0*@2/@1", kappa_tau, c7_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_htt)' ) else: self.modelBuilder.factory_( 'expr::c7_BRscal_htt("@0*@0*@2/@1", kappa_t, c7_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_htt)' ) self.modelBuilder.factory_( 'expr::c7_BRscal_hmm("@0*@0*@2/@1", kappa_mu_expr, c7_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hmm)' ) self.modelBuilder.factory_( 'expr::c7_BRscal_hbb("@0*@0*@2/@1", kappa_b, c7_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hbb)' ) self.modelBuilder.factory_( 'expr::c7_BRscal_hcc("@0*@0*@2/@1", kappa_c, c7_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hcc)' ) self.modelBuilder.factory_( 'expr::c7_BRscal_hgg("@0*@2/@1", Scaling_hgg, c7_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hgg)' ) self.modelBuilder.factory_( 'expr::c7_BRscal_hzg("@0*@2/@1", Scaling_hzg, c7_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hzg)' ) self.modelBuilder.factory_( 'expr::c7_BRscal_hgluglu("@0*@2/@1", Scaling_hgluglu, c7_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hgluglu)' ) self.modelBuilder.factory_('expr::c7_BRscal_hinv("@0", BRinv)') def getHiggsSignalYieldScale(self, production, decay, energy): name = "c7_XSBRscal_%s_%s_%s" % (production, decay, energy) if self.modelBuilder.out.function(name) == None: if production in ["ggH", "qqH", "ggZH", "tHq", "tHW"]: XSscal = ("@0", "Scaling_%s_%s" % (production, energy)) elif production == "WH": XSscal = ("@0*@0", "kappa_V") elif production == "ZH": XSscal = ("@0*@0", "kappa_V") elif production == "ttH": XSscal = ("@0*@0", "kappa_t") elif production == "bbH": XSscal = ("@0*@0", "kappa_b") else: raise RuntimeError, "Production %s not supported" % production BRscal = decay if not self.modelBuilder.out.function("c7_BRscal_" + BRscal): raise RuntimeError, "Decay mode %s not supported" % decay if decay == "hss": BRscal = "hbb" if production in ['tHq', 'tHW', 'ttH']: self.modelBuilder.factory_( 'expr::%s("%s*@1*@2", %s, c7_BRscal_%s, r)' % (name, XSscal[0], XSscal[1], BRscal)) elif production == "ggH" and (decay in self.add_bbH) and energy in [ "7TeV", "8TeV", "13TeV", "14TeV" ]: b2g = "CMS_R_bbH_ggH_%s_%s[%g]" % (decay, energy, 0.01) b2gs = "CMS_bbH_scaler_%s" % energy self.modelBuilder.factory_( 'expr::%s("(%s + @1*@1*@2*@3)*@4", %s, kappa_b, %s, %s, c7_BRscal_%s)' % (name, XSscal[0], XSscal[1], b2g, b2gs, BRscal)) else: self.modelBuilder.factory_( 'expr::%s("%s*@1*@2", %s, c7_BRscal_%s,r)' % (name, XSscal[0], XSscal[1], BRscal)) print '[LHC-HCG Kappas]', name, production, decay, energy, ": ", self.modelBuilder.out.function(name).Print("") return name
class HiggsMinimal(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema" elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first" def doParametersOfInterest(self): """Create POI out of signal strength and MH""" self.modelBuilder.doVar("kgluon[1,0,2]") self.modelBuilder.doVar("kgamma[1,0,3]") self.modelBuilder.doVar("kV[1,0,3]") self.modelBuilder.doVar("kf[1,0,3]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) self.modelBuilder.doSet("POI",'kgluon,kgamma,kV,kf,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI",'kgluon,kgamma,kV,kf') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): self.decayScaling = { 'hgg':'hgg', 'hZg':'hZg', 'hww':'hvv', 'hzz':'hvv', 'hbb':'hff', 'htt':'hff', } self.productionScaling = { 'ggH':'kgluon', 'ttH':'kf', 'qqH':'kV', 'WH':'kV', 'ZH':'kV', 'VH':'kV', } self.SMH.makeScaling('hZg', Cb='kf', Ctop='kf', CW='kV', Ctau='kf') # SM BR for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hZg", "hmm", "hss" ]: self.SMH.makeBR(d) ## total witdh, normalized to the SM one self.modelBuilder.factory_('expr::minimal_Gscal_gg("@0*@0 * @1", kgamma, SM_BR_hgg)') self.modelBuilder.factory_('expr::minimal_Gscal_gluglu("@0*@0 * @1", kgluon, SM_BR_hgluglu)') self.modelBuilder.factory_('expr::minimal_Gscal_sumf("@0*@0 * (@1+@2+@3+@4+@5+@6)", kf, SM_BR_hbb, SM_BR_htt, SM_BR_hcc, SM_BR_htoptop, SM_BR_hmm, SM_BR_hss)') self.modelBuilder.factory_('expr::minimal_Gscal_sumv("@0*@0 * (@1+@2)", kV, SM_BR_hww, SM_BR_hzz)') self.modelBuilder.factory_('expr::minimal_Gscal_Zg("@0 * @1", Scaling_hZg, SM_BR_hZg)') self.modelBuilder.factory_('sum::minimal_Gscal_tot(minimal_Gscal_sumf, minimal_Gscal_sumv, minimal_Gscal_Zg, minimal_Gscal_gg, minimal_Gscal_gluglu)') ## BRs, normalized to the SM ones: they scale as (partial/partial_SM)^2 / (total/total_SM)^2 self.modelBuilder.factory_('expr::minimal_BRscal_hgg("@0*@0/@1", kgamma, minimal_Gscal_tot)') self.modelBuilder.factory_('expr::minimal_BRscal_hZg("@0/@1", Scaling_hZg, minimal_Gscal_tot)') self.modelBuilder.factory_('expr::minimal_BRscal_hff("@0*@0/@1", kf, minimal_Gscal_tot)') self.modelBuilder.factory_('expr::minimal_BRscal_hvv("@0*@0/@1", kV, minimal_Gscal_tot)') # verbosity #self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self,production,decay,energy): name = "minimal_XSBRscal_%s_%s" % (production,decay) if self.modelBuilder.out.function(name): return name XSscal = self.productionScaling[production] BRscal = self.decayScaling[decay] self.modelBuilder.factory_('expr::%s("@0*@0 * @1", %s, minimal_BRscal_%s)' % (name, XSscal, BRscal)) return name
class CvCfHiggs(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema." elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrema for Higgs mass range defined with inverterd order. Second must be larger the first." def doParametersOfInterest(self): """Create POI out of signal strength and MH""" # --- Signal Strength as only POI --- self.modelBuilder.doVar("CV[1,-5,5]") self.modelBuilder.doVar("CF[1,-5,5]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) self.modelBuilder.doSet("POI",'CV,CF,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI",'CV,CF') self.SMH = SMHiggsBuilder(self.modelBuilder) #self.doDebugDump() self.setup() def doDebugDump(self): self.modelBuilder.out.var("MH").setConstant(False) self.modelBuilder.out.var("MH").removeRange() MHvals = [ 110 + (600.-110.)*i/4900. for i in xrange(4900+1) ] for p in [ "ggH", "qqH", "WH", "ZH" ]: self.SMH.makeXS(p) self.SMH.dump("SM_XS_"+p, "MH", MHvals, "dump.XS_"+p+".txt") for p in [ "htt", "hbb", "hww", "hzz", "hgg", "hgluglu", "htoptop" ]: self.SMH.makeBR(p) self.SMH.dump("SM_BR_"+p, "MH", MHvals, "dump.BR_"+p+".txt") self.SMH.makeTotalWidth() self.SMH.dump("SM_GammaTot", "MH", MHvals, "dump.GammaTot.txt") def setup(self): ## Coefficient for couplings to photons # Based on Eq 1--4 of Nuclear Physics B 453 (1995)17-82 # ignoring b quark contributions # Taylor series around MH=125 including terms up to O(MH-125)^2 in Horner polynomial form self.modelBuilder.factory_('expr::CvCf_cgamma("\ @0*@0*(1.524292518396496 + (0.005166702799572456 - 0.00003355715038472727*@2)*@2) + \ @1*(@1*(0.07244520735564258 + (0.0008318872718720393 - 6.16997610275555e-6*@2)*@2) + \ @0*(-0.5967377257521194 + (-0.005998590071444782 + 0.00003972712648748393*@2)*@2))\ ",CV,CF,MH)') ## partial witdhs, normalized to the SM one, for decays scaling with F, V and total for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hZg", "hmm", "hss" ]: self.SMH.makeBR(d) self.modelBuilder.factory_("expr::CvCf_Gscal_sumf(\"@0*@0 * (@1+@2+@3+@4+@5+@6+@7)\", CF, SM_BR_hbb, SM_BR_htt, SM_BR_hcc, SM_BR_htoptop, SM_BR_hgluglu, SM_BR_hmm, SM_BR_hss)") self.modelBuilder.factory_("expr::CvCf_Gscal_sumv(\"@0*@0 * (@1+@2+@3)\", CV, SM_BR_hww, SM_BR_hzz, SM_BR_hZg)") self.modelBuilder.factory_("expr::CvCf_Gscal_gg(\"@0*@0 * @1\", CvCf_cgamma, SM_BR_hgg)") self.modelBuilder.factory_( "sum::CvCf_Gscal_tot(CvCf_Gscal_sumf, CvCf_Gscal_sumv, CvCf_Gscal_gg)") ## BRs, normalized to the SM ones: they scale as (coupling/coupling_SM)^2 / (totWidth/totWidthSM)^2 self.modelBuilder.factory_("expr::CvCf_BRscal_hgg(\"@0*@0/@1\", CvCf_cgamma, CvCf_Gscal_tot)") self.modelBuilder.factory_("expr::CvCf_BRscal_hf(\"@0*@0/@1\", CF, CvCf_Gscal_tot)") self.modelBuilder.factory_("expr::CvCf_BRscal_hv(\"@0*@0/@1\", CV, CvCf_Gscal_tot)") ## XS*BR scales def getHiggsSignalYieldScale(self,production,decay,energy): name = "CvCf_XSBRscal_%s_%s" % (production,decay) if self.modelBuilder.out.function(name) == None: XSscal = 'CF' if production in ["ggH","ttH"] else 'CV' BRscal = "hgg" if decay in ["hww", "hzz"]: BRscal = "hv" if decay in ["hbb", "htt"]: BRscal = "hf" self.modelBuilder.factory_('expr::%s("@0*@0 * @1", %s, CvCf_BRscal_%s)' % (name, XSscal, BRscal)) return name
class CbCtauMSSMHiggs(MSSMLikeHiggsModel): "testing Cb and Ctau. MH is fixed for now. In ggH loop assume SM for all but Cb. Everything normalized to SM." def __init__(self): MSSMLikeHiggsModel.__init__( self ) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False #self.mARange = [] self.tanb = 30 self.cbRange = ['-2', '2'] self.ctauRange = ['-2', '2'] def setPhysicsOptions(self, physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mARange = po.replace("higgsMassRange=", "").split(",") print 'The Higgs mass range:', self.mARange if len(self.mARange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema." elif float(self.mARange[0]) >= float(self.mARange[1]): raise RuntimeError, "Extrema for Higgs mass range defined with inverterd order. Second must be larger the first." if po.startswith("cbRange="): self.cbRange = po.replace("cbRange=", "").split(":") if len(self.cbRange) != 2: raise RuntimeError, "cb signal strength range requires minimal and maximal value" elif float(self.cbRange[0]) >= float(self.cbRange[1]): raise RuntimeError, "minimal and maximal range swapped. Second value must be larger first one" if po.startswith("ctauRange="): self.ctauRange = po.replace("ctauRange=", "").split(":") if len(self.ctauRange) != 2: raise RuntimeError, "ctau signal strength range requires minimal and maximal value" elif float(self.ctauRange[0]) >= float(self.ctauRange[1]): raise RuntimeError, "minimal and maximal range swapped. Second value must be larger first one" def doParametersOfInterest(self): """Create POI out of signal strength and MH""" # --- Signal Strength as only POI --- self.modelBuilder.doVar("Cb[1,%s,%s]" % (self.cbRange[0], self.cbRange[1])) self.modelBuilder.doVar("Ctau[1,%s,%s]" % (self.ctauRange[0], self.ctauRange[1])) if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange( float(self.mARange[0]), float(self.mARange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mARange[0], self.mARange[1])) self.modelBuilder.doSet("POI", 'Cb,Ctau,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI", 'Cb,Ctau') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): self.decayScaling = { 'htt': 'htautau', 'hbb': 'hbb', } self.productionScaling = { 'bbH': 'Cb', } # scalings of the loops ## self.BSMscaling('ggH', Cb='Cb', Ctau='Ctau') ## self.BSMscaling('hgg', Cb='Cb', Ctau='Ctau') ## self.BSMscaling('hzg', Cb='Cb', Ctau='Ctau') self.SMH.makeScaling('ggH', Cb='Cb', Ctop='1') self.SMH.makeScaling('hgg', Cb='Cb', Ctop='1', CW='1', Ctau='Ctau') self.SMH.makeScaling('hzg', Cb='Cb', Ctop='1', CW='1', Ctau='Ctau') ##partial widths, normalized to SM, for decays scaling with b, tau and total for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) self.modelBuilder.factory_( 'expr::CbCtau_Gscal_sumb("@0*@0 * @1", Cb, SM_BR_hbb)') self.modelBuilder.factory_( 'expr::CbCtau_Gscal_sumtau("@0*@0 * @1", Ctau, SM_BR_htt)') self.modelBuilder.factory_( 'expr::CbCtau_Gscal_gg("@0 * @1", Scaling_hgg, SM_BR_hgg)') self.modelBuilder.factory_( 'expr::CbCtau_Gscal_Zg("@0 * @1", Scaling_hzg, SM_BR_hzg)') self.modelBuilder.factory_( 'sum::CbCtau_Gscal_tot(CbCtau_Gscal_sumb, CbCtau_Gscal_sumtau, CbCtau_Gscal_gg, CbCtau_Gscal_Zg, SM_BR_hcc, SM_BR_htoptop, SM_BR_hgluglu, SM_BR_hmm, SM_BR_hss, SM_BR_hww, SM_BR_hzz)' ) ## BRs, normalized to SM: they scale as (coupling/partial_SM)^2 / (totWidth/total_SM)^2 self.modelBuilder.factory_( 'expr::CbCtau_BRscal_hbb("@0*@0/@1", Cb, CbCtau_Gscal_tot)') self.modelBuilder.factory_( 'expr::CbCtau_BRscal_htautau("@0*@0/@1", Ctau, CbCtau_Gscal_tot)') self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self, production, decay, energy): #print production, decay, energy name = "CbCtau_XSBRscal_%s_%s" % (production, decay) #Special case that depends on Energy if production == 'ggH': self.productionScaling[production] = 'Scaling_ggH_' + energy name += '_%(energy)s' % locals() if self.modelBuilder.out.function(name): #print "name", name return name XSscal = self.productionScaling[production] BRscal = self.decayScaling[decay] self.modelBuilder.factory_( 'expr::%s("@0*@0 * @1", %s, CbCtau_BRscal_%s)' % (name, XSscal, BRscal)) #print "name", name return name
class TwoHDM(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__( self ) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False self.thdmtype = ['1'] def setPhysicsOptions(self, physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=", "").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema" elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first" if po.startswith("thdmtype="): self.thdmtype = po.replace("thdmtype=", "") if len(self.thdmtype) != 1: raise RuntimeError, "2HDM type requires one value" elif int(self.thdmtype[0]) != 1 and int( self.thdmtype[0]) != 2 and int( self.thdmtype[0]) != 3 and int( self.thdmtype[0]) != 4: raise RuntimeError, "2HDM type must be 1 (default) or 2 or 3 or 4 " def doParametersOfInterest(self): """Create POI out of signal strength and MH""" self.modelBuilder.doVar("cosbma[0,-1,1]") self.modelBuilder.doVar("tanbeta[0,0.0,10]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange( float(self.mHRange[0]), float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0], self.mHRange[1])) self.modelBuilder.doSet("POI", 'cosbma,tanbeta,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI", 'cosbma,tanbeta') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): self.modelBuilder.factory_('expr::kV("sqrt(1-@0*@0)",cosbma)') self.modelBuilder.factory_( 'expr::tana("(@0*@1-@2)/(@1-@0*@2)", tanbeta, cosbma, kV)') self.modelBuilder.factory_('expr::cosa("1/sqrt(1+@0*@0)",tana)') self.modelBuilder.factory_( 'expr::sinb("tanbeta/sqrt(1+@0*@0)",tanbeta)') self.modelBuilder.factory_('expr::ku("@0/@1", cosa, sinb)') if int(self.thdmtype[0]) == 1: self.modelBuilder.factory_('expr::kd("@0", ku)') self.modelBuilder.factory_('expr::kl("@0", ku)') elif int(self.thdmtype[0]) == 2: self.modelBuilder.factory_('expr::cosb("1/sqrt(1+@0*@0)",tanbeta)') self.modelBuilder.factory_('expr::sina("tana/sqrt(1+@0*@0)",tana)') self.modelBuilder.factory_('expr::kd("-@0/@1", sina,cosb)') self.modelBuilder.factory_('expr::kl("@0", kd)') elif int(self.thdmtype[0]) == 3: self.modelBuilder.factory_('expr::cosb("1/sqrt(1+@0*@0)",tanbeta)') self.modelBuilder.factory_('expr::sina("tana/sqrt(1+@0*@0)",tana)') self.modelBuilder.factory_('expr::kd("@0", ku)') self.modelBuilder.factory_('expr::kl("-@0/@1", sina,cosb)') elif int(self.thdmtype[0]) == 4: self.modelBuilder.factory_('expr::cosb("1/sqrt(1+@0*@0)",tanbeta)') self.modelBuilder.factory_('expr::sina("tana/sqrt(1+@0*@0)",tana)') self.modelBuilder.factory_('expr::kd("-@0/@1", sina,cosb)') self.modelBuilder.factory_('expr::kl("@0", ku)') self.decayScaling = { 'hgg': 'hgg', 'hzg': 'hzg', 'hww': 'hvv', 'hzz': 'hvv', 'hbb': 'hdd', 'htt': 'hll', 'hss': 'hdd', 'hmm': 'hll', 'hcc': 'huu', 'hgluglu': 'hgluglu', } self.productionScaling = { 'ttH': 'ku', 'qqH': 'kV', 'WH': 'kV', 'ZH': 'kV', 'VH': 'kV', } # scalings of the loops self.SMH.makeScaling('ggH', Cb='kd', Ctop='ku') self.SMH.makeScaling('hgg', Cb='kd', Ctop='ku', CW='kV', Ctau='kl') self.SMH.makeScaling('hzg', Cb='kd', Ctop='ku', CW='kV', Ctau='kl') self.SMH.makeScaling('hgluglu', Cb='kd', Ctop='ku') # SM BR for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) ## total witdhs, normalized to the SM one self.modelBuilder.factory_( 'expr::twohdm_Gscal_Vectors("@0*@0 * (@1+@2)", kV, SM_BR_hzz, SM_BR_hww)' ) self.modelBuilder.factory_( 'expr::twohdm_Gscal_up("@0*@0 * (@1+@2)", ku, SM_BR_hcc, SM_BR_htoptop)' ) self.modelBuilder.factory_( 'expr::twohdm_Gscal_down("@0*@0 * (@1+@2)", kd, SM_BR_hbb, SM_BR_hss)' ) self.modelBuilder.factory_( 'expr::twohdm_Gscal_leptons("@0*@0 * (@1+@2)", kl, SM_BR_htt, SM_BR_hmm)' ) self.modelBuilder.factory_( 'expr::twohdm_Gscal_gg("@0 * @1", Scaling_hgg, SM_BR_hgg)') self.modelBuilder.factory_( 'expr::twohdm_Gscal_Zg("@0 * @1", Scaling_hzg, SM_BR_hzg)') self.modelBuilder.factory_( 'expr::twohdm_Gscal_gluglu("@0 * @1", Scaling_hgluglu, SM_BR_hgluglu)' ) self.modelBuilder.factory_( 'sum::twohdm_Gscal_tot(twohdm_Gscal_Vectors, twohdm_Gscal_up, twohdm_Gscal_down, twohdm_Gscal_leptons, twohdm_Gscal_gg, twohdm_Gscal_Zg, twohdm_Gscal_gluglu)' ) ## BRs, normalized to the SM ones: they scale as (partial/partial_SM)^2 / (total/total_SM)^2 self.modelBuilder.factory_( 'expr::twohdm_BRscal_hvv("@0*@0/@1", kV, twohdm_Gscal_tot)') self.modelBuilder.factory_( 'expr::twohdm_BRscal_huu("@0*@0/@1", ku, twohdm_Gscal_tot)') self.modelBuilder.factory_( 'expr::twohdm_BRscal_hdd("@0*@0/@1", kd, twohdm_Gscal_tot)') self.modelBuilder.factory_( 'expr::twohdm_BRscal_hll("@0*@0/@1", kl, twohdm_Gscal_tot)') self.modelBuilder.factory_( 'expr::twohdm_BRscal_hgg("@0/@1", Scaling_hgg, twohdm_Gscal_tot)') self.modelBuilder.factory_( 'expr::twohdm_BRscal_hgluglu("@0/@1", Scaling_hgluglu, twohdm_Gscal_tot)' ) self.modelBuilder.factory_( 'expr::twohdm_BRscal_hzg("@0/@1", Scaling_hzg, twohdm_Gscal_tot)') # verbosity #self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self, production, decay, energy): name = 'twohdm_XSBRscal_%(production)s_%(decay)s' % locals() #Special case that depends on Energy if production == 'ggH': self.productionScaling[production] = 'Scaling_ggH_' + energy name += '_%(energy)s' % locals() if self.modelBuilder.out.function(name): return name XSscal = self.productionScaling[production] BRscal = self.decayScaling[decay] if 'Scaling_' in XSscal: # it's a Scaling, which means it's already squared self.modelBuilder.factory_( 'expr::%s("@0 * @1", %s, twohdm_BRscal_%s)' % (name, XSscal, BRscal)) else: # It's a kappa, so it's linear and I must square it self.modelBuilder.factory_( 'expr::%s("@0*@0 * @1", %s, twohdm_BRscal_%s)' % (name, XSscal, BRscal)) return name
class MepsHiggs(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False self.MRange = ['150','350'] self.epsRange = ['-1','1'] def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema." elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrema for Higgs mass range defined with inverterd order. Second must be larger the first." if po.startswith("MRange="): self.MRange = po.replace("MRange=","").split(":") if len(self.MRange) != 2: raise RuntimeError, "M range requires minimal and maximal value" elif float(self.MRange[0]) >= float(self.MRange[1]): raise RuntimeError, "minimal and maximal range swapped. Second value must be larger first one" if po.startswith("epsRange="): self.epsRange = po.replace("epsRange=","").split(":") if len(self.epsRange) != 2: raise RuntimeError, "epsilon range requires minimal and maximal value" elif float(self.epsRange[0]) >= float(self.epsRange[1]): raise RuntimeError, "minimal and maximal range swapped. Second value must be larger first one" def doParametersOfInterest(self): """Create POI out of signal strength and MH""" # --- Signal Strength as only POI --- self.modelBuilder.doVar("M[246.22,%s,%s]" % (self.MRange[0], self.MRange[1])) self.modelBuilder.doVar("eps[0,%s,%s]" % (self.epsRange[0], self.epsRange[1])) if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) self.modelBuilder.doSet("POI",'M,eps,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI",'M,eps') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): self.modelBuilder.doVar("SM_VEV[246.22]") self.msbar = { 'top' : (160, (-4.3,+4.8)), 'b' : (4.18, (-0.03,+0.03)), 'tau' : (1.77682, (-0.16,+0.16)), 'mu' : (0.105658, (-0.0000035,+0.0000035)), 'W' : (80.385, (-0.015,+0.015)), 'Z' : (91.1876, (-0.0021,+0.0021)), } for name, vals in self.msbar.iteritems(): #self.modelBuilder.doVar("M%s_MSbar[%s,%s,%s]" % (name, vals[0], vals[0]+vals[1][0], vals[0]+vals[1][1])) self.modelBuilder.doVar("M%s_MSbar[%s]" % (name, vals[0])) if name in ('W','Z'): # # Ellis cv == v (mv^(2 e)/M^(1 + 2 e)) # self.modelBuilder.factory_( # 'expr::C%(name)s("@0 * TMath::Power(@3,2*@2) / TMath::Power(@1,1+2*@2)", SM_VEV, M, eps, M%(name)s_MSbar)' % locals() ) # # AD k = (M/v) eps m^(N(eps-1)) # self.modelBuilder.factory_( # 'expr::C%(name)s("@1 * @2 * TMath::Power(@3,2*(@2-1)) / @0", SM_VEV, M, eps, M%(name)s_MSbar)' % locals() ) # # GP k = (v/M)^2 (m/M)^(2eps) self.modelBuilder.factory_( 'expr::C%(name)s("TMath::Power(@0/@1,2) * TMath::Power(@3/@1,2*@2)", SM_VEV, M, eps, M%(name)s_MSbar)' % locals() ) else: # # Ellis cf == v (mf^e/M^(1 + e)) # self.modelBuilder.factory_( # 'expr::C%(name)s("@0 * TMath::Power(@3,@2) / TMath::Power(@1,1+@2)", SM_VEV, M, eps, M%(name)s_MSbar)' % locals() ) # AD k = (M/v) eps m^(N(eps-1)) # self.modelBuilder.factory_( # 'expr::C%(name)s("@1 * @2 * TMath::Power(@3,@2-1) / @0", SM_VEV, M, eps, M%(name)s_MSbar)' % locals() ) # GP k = (v/M) (m/M)^eps self.modelBuilder.factory_( 'expr::C%(name)s("(@0/@1) * TMath::Power(@3/@1,@2)", SM_VEV, M, eps, M%(name)s_MSbar)' % locals() ) self.productionScaling = { 'ttH':'Ctop', 'WH':'CW', 'ZH':'CZ', } self.SMH.makeScaling('ggH', Cb='Cb', Ctop='Ctop') self.SMH.makeScaling('qqH', CW='CW', CZ='CZ') self.SMH.makeScaling('hgluglu', Cb='Cb', Ctop='Ctop') self.SMH.makeScaling('hgg', Cb='Cb', Ctop='Ctop', CW='CW', Ctau='Ctau') self.SMH.makeScaling('hzg', Cb='Cb', Ctop='Ctop', CW='CW', Ctau='Ctau') ## partial widths, normalized to the SM one, for decays scaling with F, V and total for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) self.modelBuilder.factory_('expr::Meps_Gscal_w("@0*@0 * @1", CW, SM_BR_hww)') self.modelBuilder.factory_('expr::Meps_Gscal_z("@0*@0 * @1", CZ, SM_BR_hzz)') self.modelBuilder.factory_('expr::Meps_Gscal_b("@0*@0 * @1", Cb, SM_BR_hbb)') self.modelBuilder.factory_('expr::Meps_Gscal_tau("@0*@0 * @1", Ctau, SM_BR_htt)') self.modelBuilder.factory_('expr::Meps_Gscal_mu("@0*@0 * @1", Cmu, SM_BR_hmm)') self.modelBuilder.factory_('expr::Meps_Gscal_top("@0*@0 * @1", Ctop, SM_BR_htoptop)') self.modelBuilder.factory_('expr::Meps_Gscal_glu("@0 * @1", Scaling_hgluglu, SM_BR_hgluglu)') self.modelBuilder.factory_('expr::Meps_Gscal_gg("@0 * @1", Scaling_hgg, SM_BR_hgg)') self.modelBuilder.factory_('expr::Meps_Gscal_zg("@0 * @1", Scaling_hzg, SM_BR_hzg)') self.modelBuilder.factory_('sum::Meps_Gscal_tot(Meps_Gscal_w, Meps_Gscal_z, Meps_Gscal_b, Meps_Gscal_tau, Meps_Gscal_mu, Meps_Gscal_top, Meps_Gscal_glu, Meps_Gscal_gg, Meps_Gscal_zg, SM_BR_hcc, SM_BR_hss)') ## BRs, normalized to the SM ones: they scale as (coupling/coupling_SM)^2 / (totWidth/totWidthSM)^2 self.modelBuilder.factory_('expr::Meps_BRscal_hww("@0*@0/@1", CW, Meps_Gscal_tot)') self.modelBuilder.factory_('expr::Meps_BRscal_hzz("@0*@0/@1", CZ, Meps_Gscal_tot)') self.modelBuilder.factory_('expr::Meps_BRscal_hbb("@0*@0/@1", Cb, Meps_Gscal_tot)') self.modelBuilder.factory_('expr::Meps_BRscal_htt("@0*@0/@1", Ctau, Meps_Gscal_tot)') self.modelBuilder.factory_('expr::Meps_BRscal_hmm("@0*@0/@1", Cmu, Meps_Gscal_tot)') self.modelBuilder.factory_('expr::Meps_BRscal_hgg("@0/@1", Scaling_hgg, Meps_Gscal_tot)') self.modelBuilder.factory_('expr::Meps_BRscal_hzg("@0/@1", Scaling_hzg, Meps_Gscal_tot)') self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self,production,decay,energy): name = 'Meps_XSBRscal_%(production)s_%(decay)s' % locals() if production in ('ggH','qqH'): self.productionScaling[production]='Scaling_'+production+'_'+energy name += '_%(energy)s' % locals() if self.modelBuilder.out.function(name): return name if production == "VH": print "WARNING: You are trying to use a VH production mode in a model that needs WH and ZH separately. "\ "The best I can do is to scale [%(production)s, %(decay)s, %(energy)s] with the decay BR only but this is wrong..." % locals() self.modelBuilder.factory_('expr::%(name)s("1.0*@0", Meps_BRscal_%(decay)s)' % locals()) return name XSscal = self.productionScaling[production] if production == 'ggH': self.modelBuilder.factory_('expr::%(name)s("@0 * @1", %(XSscal)s, Meps_BRscal_%(decay)s)' % locals()) else: self.modelBuilder.factory_('expr::%(name)s("@0*@0 * @1", %(XSscal)s, Meps_BRscal_%(decay)s)' % locals()) return name
class CbCtauMSSMHiggs(MSSMLikeHiggsModel): "testing Cb and Ctau. MH is fixed for now. In ggH loop assume SM for all but Cb. Everything normalized to SM." def __init__(self): MSSMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False #self.mARange = [] self.tanb = 30 self.cbRange = ['-2','2'] self.ctauRange = ['-2','2'] def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mARange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mARange if len(self.mARange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema." elif float(self.mARange[0]) >= float(self.mARange[1]): raise RuntimeError, "Extrema for Higgs mass range defined with inverterd order. Second must be larger the first." if po.startswith("cbRange="): self.cbRange = po.replace("cbRange=","").split(":") if len(self.cbRange) != 2: raise RuntimeError, "cb signal strength range requires minimal and maximal value" elif float(self.cbRange[0]) >= float(self.cbRange[1]): raise RuntimeError, "minimal and maximal range swapped. Second value must be larger first one" if po.startswith("ctauRange="): self.ctauRange = po.replace("ctauRange=","").split(":") if len(self.ctauRange) != 2: raise RuntimeError, "ctau signal strength range requires minimal and maximal value" elif float(self.ctauRange[0]) >= float(self.ctauRange[1]): raise RuntimeError, "minimal and maximal range swapped. Second value must be larger first one" def doParametersOfInterest(self): """Create POI out of signal strength and MH""" # --- Signal Strength as only POI --- self.modelBuilder.doVar("Cb[1,%s,%s]" % (self.cbRange[0], self.cbRange[1])) self.modelBuilder.doVar("Ctau[1,%s,%s]" % (self.ctauRange[0], self.ctauRange[1])) if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mARange[0]),float(self.mARange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mARange[0],self.mARange[1])) self.modelBuilder.doSet("POI",'Cb,Ctau,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI",'Cb,Ctau') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): self.decayScaling = { 'htt':'htautau', 'hbb':'hbb', } self.productionScaling = { 'bbH':'Cb', } # scalings of the loops ## self.BSMscaling('ggH', Cb='Cb', Ctau='Ctau') ## self.BSMscaling('hgg', Cb='Cb', Ctau='Ctau') ## self.BSMscaling('hzg', Cb='Cb', Ctau='Ctau') self.SMH.makeScaling('ggH', Cb='Cb', Ctop='1') self.SMH.makeScaling('hgg', Cb='Cb', Ctop='1', CW='1', Ctau='Ctau') self.SMH.makeScaling('hzg', Cb='Cb', Ctop='1', CW='1', Ctau='Ctau') ##partial widths, normalized to SM, for decays scaling with b, tau and total for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss"]: self.SMH.makeBR(d) self.modelBuilder.factory_('expr::CbCtau_Gscal_sumb("@0*@0 * @1", Cb, SM_BR_hbb)') self.modelBuilder.factory_('expr::CbCtau_Gscal_sumtau("@0*@0 * @1", Ctau, SM_BR_htt)') self.modelBuilder.factory_('expr::CbCtau_Gscal_gg("@0 * @1", Scaling_hgg, SM_BR_hgg)') self.modelBuilder.factory_('expr::CbCtau_Gscal_Zg("@0 * @1", Scaling_hzg, SM_BR_hzg)') self.modelBuilder.factory_('sum::CbCtau_Gscal_tot(CbCtau_Gscal_sumb, CbCtau_Gscal_sumtau, CbCtau_Gscal_gg, CbCtau_Gscal_Zg, SM_BR_hcc, SM_BR_htoptop, SM_BR_hgluglu, SM_BR_hmm, SM_BR_hss, SM_BR_hww, SM_BR_hzz)') ## BRs, normalized to SM: they scale as (coupling/partial_SM)^2 / (totWidth/total_SM)^2 self.modelBuilder.factory_('expr::CbCtau_BRscal_hbb("@0*@0/@1", Cb, CbCtau_Gscal_tot)') self.modelBuilder.factory_('expr::CbCtau_BRscal_htautau("@0*@0/@1", Ctau, CbCtau_Gscal_tot)') self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self,production,decay,energy): #print production, decay, energy name = "CbCtau_XSBRscal_%s_%s" % (production,decay) #Special case that depends on Energy if production == 'ggH': self.productionScaling[production] = 'Scaling_ggH_' + energy name += '_%(energy)s' % locals() if self.modelBuilder.out.function(name): #print "name", name return name XSscal = self.productionScaling[production] BRscal = self.decayScaling[decay] self.modelBuilder.factory_('expr::%s("@0*@0 * @1", %s, CbCtau_BRscal_%s)' % (name, XSscal, BRscal)) #print "name", name return name
class ResolvedC6(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False self.MRange = ['150','350'] def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema." elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrema for Higgs mass range defined with inverterd order. Second must be larger the first." if po.startswith("MRange="): self.MRange = po.replace("MRange=","").split(":") if len(self.MRange) != 2: raise RuntimeError, "M range requires minimal and maximal value" elif float(self.MRange[0]) >= float(self.MRange[1]): raise RuntimeError, "minimal and maximal range swapped. Second value must be larger first one" def doParametersOfInterest(self): """Create POI out of signal strength and MH""" # --- Signal Strength as only POI --- self.modelBuilder.doVar("CW[1.0,0.0,5.0]") self.modelBuilder.doVar("CZ[1.0,0.0,5.0]") self.modelBuilder.doVar("Ctop[1.0,0.0,5.0]") self.modelBuilder.doVar("Cb[1.0,0.0,5.0]") self.modelBuilder.doVar("Ctau[1.0,0.0,5.0]") self.modelBuilder.doVar("Cmu[1.0,0.0,5.0]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) self.modelBuilder.doSet("POI",'MH,CW,CZ,Ctop,Cb,Ctau,Cmu') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI",'CW,CZ,Ctop,Cb,Ctau,Cmu') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): self.productionScaling = { 'ttH':'Ctop', 'WH':'CW', 'ZH':'CZ', } self.SMH.makeScaling('ggH', Cb='Cb', Ctop='Ctop') self.SMH.makeScaling('qqH', CW='CW', CZ='CZ') self.SMH.makeScaling('hgluglu', Cb='Cb', Ctop='Ctop') self.SMH.makeScaling('hgg', Cb='Cb', Ctop='Ctop', CW='CW', Ctau='Ctau') self.SMH.makeScaling('hzg', Cb='Cb', Ctop='Ctop', CW='CW', Ctau='Ctau') ## partial widths, normalized to the SM one, for decays scaling with F, V and total for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) self.modelBuilder.factory_('expr::wztbtm_Gscal_w("@0*@0 * @1", CW, SM_BR_hww)') self.modelBuilder.factory_('expr::wztbtm_Gscal_z("@0*@0 * @1", CZ, SM_BR_hzz)') self.modelBuilder.factory_('expr::wztbtm_Gscal_b("@0*@0 * @1", Cb, SM_BR_hbb)') self.modelBuilder.factory_('expr::wztbtm_Gscal_tau("@0*@0 * @1", Ctau, SM_BR_htt)') self.modelBuilder.factory_('expr::wztbtm_Gscal_mu("@0*@0 * @1", Cmu, SM_BR_hmm)') self.modelBuilder.factory_('expr::wztbtm_Gscal_top("@0*@0 * @1", Ctop, SM_BR_htoptop)') self.modelBuilder.factory_('expr::wztbtm_Gscal_glu("@0 * @1", Scaling_hgluglu, SM_BR_hgluglu)') self.modelBuilder.factory_('expr::wztbtm_Gscal_gg("@0 * @1", Scaling_hgg, SM_BR_hgg)') self.modelBuilder.factory_('expr::wztbtm_Gscal_zg("@0 * @1", Scaling_hzg, SM_BR_hzg)') self.modelBuilder.factory_('sum::wztbtm_Gscal_tot(wztbtm_Gscal_w, wztbtm_Gscal_z, wztbtm_Gscal_b, wztbtm_Gscal_tau, wztbtm_Gscal_mu, wztbtm_Gscal_top, wztbtm_Gscal_glu, wztbtm_Gscal_gg, wztbtm_Gscal_zg, SM_BR_hcc, SM_BR_hss)') ## BRs, normalized to the SM ones: they scale as (coupling/coupling_SM)^2 / (totWidth/totWidthSM)^2 self.modelBuilder.factory_('expr::wztbtm_BRscal_hww("@0*@0/@1", CW, wztbtm_Gscal_tot)') self.modelBuilder.factory_('expr::wztbtm_BRscal_hzz("@0*@0/@1", CZ, wztbtm_Gscal_tot)') self.modelBuilder.factory_('expr::wztbtm_BRscal_hbb("@0*@0/@1", Cb, wztbtm_Gscal_tot)') self.modelBuilder.factory_('expr::wztbtm_BRscal_hss("@0*@0/@1", Cb, wztbtm_Gscal_tot)') self.modelBuilder.factory_('expr::wztbtm_BRscal_htt("@0*@0/@1", Ctau, wztbtm_Gscal_tot)') self.modelBuilder.factory_('expr::wztbtm_BRscal_hcc("@0*@0/@1", Ctop, wztbtm_Gscal_tot)') self.modelBuilder.factory_('expr::wztbtm_BRscal_hmm("@0*@0/@1", Cmu, wztbtm_Gscal_tot)') self.modelBuilder.factory_('expr::wztbtm_BRscal_hgg("@0/@1", Scaling_hgg, wztbtm_Gscal_tot)') self.modelBuilder.factory_('expr::wztbtm_BRscal_hzg("@0/@1", Scaling_hzg, wztbtm_Gscal_tot)') self.modelBuilder.factory_('expr::wztbtm_BRscal_hgluglu("@0/@1", Scaling_hgluglu, wztbtm_Gscal_tot)') self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self,production,decay,energy): name = 'wztbtm_XSBRscal_%(production)s_%(decay)s' % locals() if production in ('ggH','qqH'): self.productionScaling[production]='Scaling_'+production+'_'+energy name += '_%(energy)s' % locals() if self.modelBuilder.out.function(name): return name if production == "VH": print "WARNING: You are trying to use a VH production mode in a model that needs WH and ZH separately. "\ "The best I can do is to scale [%(production)s, %(decay)s, %(energy)s] with the decay BR only but this is wrong..." % locals() self.modelBuilder.factory_('expr::%(name)s("1.0*@0", wztbtm_BRscal_%(decay)s)' % locals()) return name XSscal = self.productionScaling[production] if production == 'ggH': self.modelBuilder.factory_('expr::%(name)s("@0 * @1", %(XSscal)s, wztbtm_BRscal_%(decay)s)' % locals()) else: self.modelBuilder.factory_('expr::%(name)s("@0*@0 * @1", %(XSscal)s, wztbtm_BRscal_%(decay)s)' % locals()) return name
class HiggsMinimal(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__( self ) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False def setPhysicsOptions(self, physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=", "").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema" elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first" def doParametersOfInterest(self): """Create POI out of signal strength and MH""" self.modelBuilder.doVar("kgluon[1,0,2]") self.modelBuilder.doVar("kgamma[1,0,3]") self.modelBuilder.doVar("kV[1,0,3]") self.modelBuilder.doVar("kf[1,0,3]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange( float(self.mHRange[0]), float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0], self.mHRange[1])) self.modelBuilder.doSet("POI", 'kgluon,kgamma,kV,kf,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI", 'kgluon,kgamma,kV,kf') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): self.decayScaling = { 'hgg': 'hgg', 'hzg': 'hzg', 'hww': 'hvv', 'hzz': 'hvv', 'hbb': 'hff', 'htt': 'hff', } self.productionScaling = { 'ggH': 'kgluon', 'ttH': 'kf', 'qqH': 'kV', 'WH': 'kV', 'ZH': 'kV', 'VH': 'kV', } self.SMH.makeScaling('hzg', Cb='kf', Ctop='kf', CW='kV', Ctau='kf') # SM BR for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) ## total witdh, normalized to the SM one self.modelBuilder.factory_( 'expr::minimal_Gscal_gg("@0*@0 * @1", kgamma, SM_BR_hgg)') self.modelBuilder.factory_( 'expr::minimal_Gscal_gluglu("@0*@0 * @1", kgluon, SM_BR_hgluglu)') self.modelBuilder.factory_( 'expr::minimal_Gscal_sumf("@0*@0 * (@1+@2+@3+@4+@5+@6)", kf, SM_BR_hbb, SM_BR_htt, SM_BR_hcc, SM_BR_htoptop, SM_BR_hmm, SM_BR_hss)' ) self.modelBuilder.factory_( 'expr::minimal_Gscal_sumv("@0*@0 * (@1+@2)", kV, SM_BR_hww, SM_BR_hzz)' ) self.modelBuilder.factory_( 'expr::minimal_Gscal_Zg("@0 * @1", Scaling_hzg, SM_BR_hzg)') self.modelBuilder.factory_( 'sum::minimal_Gscal_tot(minimal_Gscal_sumf, minimal_Gscal_sumv, minimal_Gscal_Zg, minimal_Gscal_gg, minimal_Gscal_gluglu)' ) ## BRs, normalized to the SM ones: they scale as (partial/partial_SM)^2 / (total/total_SM)^2 self.modelBuilder.factory_( 'expr::minimal_BRscal_hgg("@0*@0/@1", kgamma, minimal_Gscal_tot)') self.modelBuilder.factory_( 'expr::minimal_BRscal_hzg("@0/@1", Scaling_hzg, minimal_Gscal_tot)' ) self.modelBuilder.factory_( 'expr::minimal_BRscal_hff("@0*@0/@1", kf, minimal_Gscal_tot)') self.modelBuilder.factory_( 'expr::minimal_BRscal_hvv("@0*@0/@1", kV, minimal_Gscal_tot)') # verbosity #self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self, production, decay, energy): name = "minimal_XSBRscal_%s_%s" % (production, decay) if self.modelBuilder.out.function(name): return name XSscal = self.productionScaling[production] BRscal = self.decayScaling[decay] self.modelBuilder.factory_( 'expr::%s("@0*@0 * @1", %s, minimal_BRscal_%s)' % (name, XSscal, BRscal)) return name
class TrilinearHiggsKappaVKappaF(LHCHCGBaseModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self, BRU=True): LHCHCGBaseModel.__init__(self) self.doBRU = BRU def setPhysicsOptions(self, physOptions): self.setPhysicsOptionsBase(physOptions) for po in physOptions: if po.startswith("BRU="): self.doBRU = (po.replace("BRU=", "") in ["yes", "1", "Yes", "True", "true"]) print "BR uncertainties in partial widths: %s " % self.doBRU def doParametersOfInterest(self): """Create POI out of signal strength and MH""" self.modelBuilder.doVar("kappa_V[1,0.0,2.0]") self.modelBuilder.doVar("kappa_F[1,-2.0,2.0]") self.modelBuilder.doVar("kappa_lambda[1,-20,20]") pois = 'kappa_V,kappa_F,kappa_lambda' self.doMH() self.modelBuilder.doSet("POI", pois) self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): #self.dobbH() # SM BR for d in SM_HIGG_DECAYS + ["hss"]: self.SMH.makeBR(d) # BR uncertainties if self.doBRU: self.SMH.makePartialWidthUncertainties() else: for d in SM_HIGG_DECAYS: self.modelBuilder.factory_( 'HiggsDecayWidth_UncertaintyScaling_%s[1.0]' % d) # fix to have all BRs add up to unity self.modelBuilder.factory_("sum::c7_SMBRs(%s)" % (",".join( "SM_BR_" + X for X in "hzz hww htt hmm hcc hbb hss hgluglu hgg hzg".split()))) self.modelBuilder.out.function("c7_SMBRs").Print("") # get VBF, tHq, tHW, ggZH cross section and resolved loops self.SMH.makeScaling('qqH', CW='kappa_V', CZ='kappa_V') self.SMH.makeScaling("tHq", CW='kappa_V', Ctop="kappa_F") self.SMH.makeScaling("tHW", CW='kappa_V', Ctop="kappa_F") self.SMH.makeScaling("ggZH", CZ='kappa_V', Ctop="kappa_F", Cb="kappa_F") self.SMH.makeScaling('ggH', Cb='kappa_F', Ctop='kappa_F', Cc="kappa_F") self.SMH.makeScaling('hgluglu', Cb='kappa_F', Ctop='kappa_F') self.SMH.makeScaling('hgg', Cb='kappa_F', Ctop='kappa_F', CW='kappa_V', Ctau='kappa_F') self.SMH.makeScaling('hzg', Cb='kappa_F', Ctop='kappa_F', CW='kappa_V', Ctau='kappa_F') cGammap = { "hgg": 0.49e-2, "hzz": 0.83e-2, "hww": 0.73e-2, "hgluglu": 0.66e-2, "htt": 0, "hbb": 0, "hcc": 0, "hmm": 0 } # First we need to create the terms that account for the self-coupling --> Just scale partial width first - https://arxiv.org/abs/1709.08649 Eq 22. # probably a better way to code this since the partial width expressions are being repeated when we write the BR for dec in cGammap.keys(): valC1 = cGammap[dec] self.modelBuilder.factory_( 'expr::kl_scalBR_%s("(@0-1)*%g",kappa_lambda)' % (dec, valC1)) # next make the partial widths, also including the kappas -> we want to include the term from the normal kappas and the one from the self-coupling self.modelBuilder.factory_( 'expr::kVkFkl_Gscal_Z("(@0*@0+@3)*@1*@2", kappa_V, SM_BR_hzz, HiggsDecayWidth_UncertaintyScaling_hzz, kl_scalBR_hzz)' ) self.modelBuilder.factory_( 'expr::kVkFkl_Gscal_W("(@0*@0+@3)*@1*@2", kappa_V, SM_BR_hww, HiggsDecayWidth_UncertaintyScaling_hww, kl_scalBR_hww)' ) self.modelBuilder.factory_( 'expr::kVkFkl_Gscal_tau("(@0*@0+@6)*@1*@4 + (@2*@2+@7)*@3*@5", kappa_F, SM_BR_htt, kappa_F, SM_BR_hmm, HiggsDecayWidth_UncertaintyScaling_htt, HiggsDecayWidth_UncertaintyScaling_hmm,kl_scalBR_htt, kl_scalBR_hmm)' ) self.modelBuilder.factory_( 'expr::kVkFkl_Gscal_top("(@0*@0+@3)*@1*@2", kappa_F, SM_BR_hcc, HiggsDecayWidth_UncertaintyScaling_hcc, kl_scalBR_hcc)' ) self.modelBuilder.factory_( 'expr::kVkFkl_Gscal_bottom("(@0*@0+@4) * (@1*@3+@2)", kappa_F, SM_BR_hbb, SM_BR_hss, HiggsDecayWidth_UncertaintyScaling_hbb, kl_scalBR_hbb)' ) self.modelBuilder.factory_( 'expr::kVkFkl_Gscal_gluon(" (@0+@3) * @1 * @2", Scaling_hgluglu, SM_BR_hgluglu, HiggsDecayWidth_UncertaintyScaling_hgluglu, kl_scalBR_hgluglu)' ) self.modelBuilder.factory_( 'expr::kVkFkl_Gscal_gamma("(@0+@6)*@1*@4 + @2*@3*@5", Scaling_hgg, SM_BR_hgg, Scaling_hzg, SM_BR_hzg, HiggsDecayWidth_UncertaintyScaling_hgg, HiggsDecayWidth_UncertaintyScaling_hzg, kl_scalBR_hgg)' ) # no kappa_lambda dependance on H->zg known yet ? # fix to have all BRs add up to unity self.modelBuilder.factory_("sum::kVkFkl_SMBRs(%s)" % (",".join( "SM_BR_" + X for X in "hzz hww htt hmm hcc hbb hss hgluglu hgg hzg".split()))) self.modelBuilder.out.function("kVkFkl_SMBRs").Print("") ## total witdh, normalized to the SM one (just the sum over the partial widths/SM total BR) self.modelBuilder.factory_( 'expr::kVkFkl_Gscal_tot("(@0+@1+@2+@3+@4+@5+@6)/@7", kVkFkl_Gscal_Z, kVkFkl_Gscal_W, kVkFkl_Gscal_tau, kVkFkl_Gscal_top, kVkFkl_Gscal_bottom, kVkFkl_Gscal_gluon, kVkFkl_Gscal_gamma, kVkFkl_SMBRs)' ) ## BRs, normalized to the SM ones: they scale as (partial/partial_SM) / (total/total_SM) self.modelBuilder.factory_( 'expr::kVkFkl_BRscal_hww("(@0*@0+@3)*@2/@1", kappa_V, kVkFkl_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hww, kl_scalBR_hww)' ) self.modelBuilder.factory_( 'expr::kVkFkl_BRscal_hzz("(@0*@0+@3)*@2/@1", kappa_V, kVkFkl_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hzz, kl_scalBR_hzz)' ) self.modelBuilder.factory_( 'expr::kVkFkl_BRscal_htt("(@0*@0+@3)*@2/@1", kappa_F, kVkFkl_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_htt, kl_scalBR_htt)' ) self.modelBuilder.factory_( 'expr::kVkFkl_BRscal_hmm("(@0*@0+@3)*@2/@1", kappa_F, kVkFkl_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hmm, kl_scalBR_hmm)' ) self.modelBuilder.factory_( 'expr::kVkFkl_BRscal_hbb("(@0*@0+@3)*@2/@1", kappa_F, kVkFkl_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hbb, kl_scalBR_hbb)' ) self.modelBuilder.factory_( 'expr::kVkFkl_BRscal_hcc("(@0*@0+@3)*@2/@1", kappa_F, kVkFkl_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hcc, kl_scalBR_hcc)' ) self.modelBuilder.factory_( 'expr::kVkFkl_BRscal_hgg("(@0+@3)*@2/@1", Scaling_hgg, kVkFkl_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hgg,kl_scalBR_hgg)' ) self.modelBuilder.factory_( 'expr::kVkFkl_BRscal_hzg("@0*@2/@1", Scaling_hzg, kVkFkl_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hzg)' ) self.modelBuilder.factory_( 'expr::kVkFkl_BRscal_hgluglu("(@0+@3)*@2/@1", Scaling_hgluglu, kVkFkl_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hgluglu, kl_scalBR_hgluglu)' ) def getHiggsSignalYieldScale(self, production, decay, energy): name = "kVkFkl_XSBRscal_%s_%s_%s" % (production, decay, energy) if self.modelBuilder.out.function(name) == None: # now make production scaling --> taken from Tab. 2 of https://arxiv.org/pdf/1607.04251v1.pdf, using formula from https://arxiv.org/pdf/1709.08649.pdf (eqn 18) cXSmap_7 = { "ggH": 0.66e-2, "qqH": 0.65e-2, "WH": 1.06e-2, "ZH": 1.23e-2, "ttH": 3.87e-2 } cXSmap_8 = { "ggH": 0.66e-2, "qqH": 0.65e-2, "WH": 1.05e-2, "ZH": 1.22e-2, "ttH": 3.78e-2 } cXSmap_13 = { "ggH": 0.66e-2, "qqH": 0.64e-2, "WH": 1.03e-2, "ZH": 1.19e-2, "ttH": 3.51e-2 } EWKmap_13 = { "ggH": 1.049, "qqH": 0.932, "WH": 0.93, "ZH": 0.947, "ttH": 1.014 } cXSmaps = {"7TeV": cXSmap_7, "8TeV": cXSmap_8, "13TeV": cXSmap_13} dZH = -1.536e-3 if production in ["ggZH", "tHq", "tHW"]: XSscal = ("@0", "Scaling_%s_%s" % (production, energy)) elif production in ["ggH", "qqH"]: C1_map = cXSmaps[energy] EWK = EWKmap_13[production] self.modelBuilder.factory_("expr::kVkFkl_XSscal_%s_%s(\"(@1+(@0-1)*%g/%g)/((1-(@0*@0-1)*%g))\",kappa_lambda,Scaling_%s_%s)"\ %(production,energy,C1_map[production],EWK,dZH,production,energy)) XSscal = ("@0", "kVkFkl_XSscal_%s_%s, " % (production, energy)) elif production in ["ZH", "WH"]: C1_map = cXSmaps[energy] EWK = EWKmap_13[production] self.modelBuilder.factory_("expr::kVkFkl_XSscal_%s_%s(\"(@1*@1+(@0-1)*%g/%g)/((1-(@0*@0-1)*%g))\",kappa_lambda,kappa_V)"\ %(production,energy,C1_map[production],EWK,dZH)) XSscal = ("@0", "kVkFkl_XSscal_%s_%s, " % (production, energy)) elif production == "ttH": C1_map = cXSmaps[energy] EWK = EWKmap_13[production] self.modelBuilder.factory_("expr::kVkFkl_XSscal_%s_%s(\"(@1*@1+(@0-1)*%g/%g)/((1-(@0*@0-1)*%g))\",kappa_lambda,kappa_F)"\ %(production,energy,C1_map[production],EWK,dZH)) XSscal = ("@0", "kVkFkl_XSscal_%s_%s, " % (production, energy)) elif production == "bbH": XSscal = ("@0*@0", "kappa_F") else: raise RuntimeError, "Production %s not supported" % production BRscal = decay if decay == "hss": BRscal = "hbb" if not self.modelBuilder.out.function("kVkFkl_BRscal_" + BRscal): raise RuntimeError, "Decay mode %s not supported" % decay self.modelBuilder.factory_( 'expr::%s("%s*@1", %s, kVkFkl_BRscal_%s)' % (name, XSscal[0], XSscal[1], BRscal)) print '[LHC-HCG Kappas]', name, production, decay, energy, ": ", self.modelBuilder.out.function(name).Print("") return name
class CvCfHiggs(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema." elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrema for Higgs mass range defined with inverterd order. Second must be larger the first." def doParametersOfInterest(self): """Create POI out of signal strength and MH""" # --- Signal Strength as only POI --- self.modelBuilder.doVar("CV[1,0.0,1.5]") self.modelBuilder.doVar("CF[1,-2,2]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) self.modelBuilder.doSet("POI",'CV,CF,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI",'CV,CF') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): ## Coefficient for couplings to photons # arXiv 1202.3144v2, below eq. 2.6: 2/9*cF - 1.04*cV, and then normalize to SM # FIXME: this should be replaced with the proper MH dependency #self.modelBuilder.factory_("expr::CvCf_cgamma(\"-0.271*@0+1.27*@1\",CF,CV)") ######################################################################### ## Coefficient for coupling to di-photons # Based on Eq 1--4 of Nuclear Physics B 453 (1995)17-82 # ignoring b quark contributions # Taylor series around MH=125 including terms up to O(MH-125)^2 in Horner polynomial form CF = self.modelBuilder.out.function('CF') CF.setVal(1.0) self.modelBuilder.factory_('expr::CvCf_cgammaSq("\ @0*@0*(1.524292518396496 + (0.005166702799572456 - 0.00003355715038472727*@2)*@2) + \ @1*(@1*(0.07244520735564258 + (0.0008318872718720393 - 6.16997610275555e-6*@2)*@2) + \ @0*(-0.5967377257521194 + (-0.005998590071444782 + 0.00003972712648748393*@2)*@2))\ ",CV,CF,MH)') ## partial witdhs, normalized to the SM one, for decays scaling with F, V and total for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) self.modelBuilder.factory_("expr::CvCf_Gscal_sumf(\"@0*@0 * (@1+@2+@3+@4+@5+@6+@7)\", CF, SM_BR_hbb, SM_BR_htt, SM_BR_hcc, SM_BR_htoptop, SM_BR_hgluglu, SM_BR_hmm, SM_BR_hss)") self.modelBuilder.factory_("expr::CvCf_Gscal_sumv(\"@0*@0 * (@1+@2+@3)\", CV, SM_BR_hww, SM_BR_hzz, SM_BR_hzg)") self.modelBuilder.factory_("expr::CvCf_Gscal_gg(\"@0 * @1\", CvCf_cgammaSq, SM_BR_hgg)") self.modelBuilder.factory_( "sum::CvCf_Gscal_tot(CvCf_Gscal_sumf, CvCf_Gscal_sumv, CvCf_Gscal_gg)") ## BRs, normalized to the SM ones: they scale as (coupling/coupling_SM)^2 / (totWidth/totWidthSM)^2 self.modelBuilder.factory_("expr::CvCf_BRscal_hgg(\"@0/@1\", CvCf_cgammaSq, CvCf_Gscal_tot)") self.modelBuilder.factory_("expr::CvCf_BRscal_hf(\"@0*@0/@1\", CF, CvCf_Gscal_tot)") self.modelBuilder.factory_("expr::CvCf_BRscal_hv(\"@0*@0/@1\", CV, CvCf_Gscal_tot)") #self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self,production,decay,energy): name = "CvCf_XSBRscal_%s_%s" % (production,decay) if self.modelBuilder.out.function(name) == None: XSscal = 'CF' if production in ["ggH","ttH"] else 'CV' BRscal = "hgg" if decay in ["hww", "hzz"]: BRscal = "hv" if decay in ["hbb", "htt"]: BRscal = "hf" self.modelBuilder.factory_('expr::%s("@0*@0 * @1", %s, CvCf_BRscal_%s)' % (name, XSscal, BRscal)) return name
class CwzHiggs(SMLikeHiggsModel): "Scale w and z and touch nothing else" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False def setPhysicsOptions(self, physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=", "").split(",") print("The Higgs mass range:", self.mHRange) if len(self.mHRange) != 2: raise RuntimeError("Higgs mass range definition requires two extrema.") elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError( "Extrema for Higgs mass range defined with inverterd order. Second must be larger the first." ) def doParametersOfInterest(self): """Create POI out of signal strength and MH""" # --- Signal Strength as only POI --- self.modelBuilder.doVar("Cwz[1,0,10]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]), float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0], self.mHRange[1])) self.modelBuilder.doSet("POI", "Cwz,MH") else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI", "Cwz") self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): for d in ["hww", "hzz"]: self.SMH.makeBR(d) self.modelBuilder.doVar("Cz[1,0,10]") self.modelBuilder.factory_('expr::Cw("@0*@1",Cz, Cwz)') ## total witdhs, normalized to the SM one self.modelBuilder.factory_( 'expr::Cwz_Gscal_tot("@0*@1 + @2*@3 + (1.0-@1-@3)", \ Cw, SM_BR_hww, Cz, SM_BR_hzz)' ) ## BRs, normalized to the SM ones: they scale as (partial/partial_SM) / (total/total_SM) self.modelBuilder.factory_('expr::Cwz_BRscal_hww("@0/@1", Cw, Cwz_Gscal_tot)') self.modelBuilder.factory_('expr::Cwz_BRscal_hzz("@0/@1", Cz, Cwz_Gscal_tot)') datadir = os.environ["CMSSW_BASE"] + "/src/combine/data/lhc-hxswg" for e in ["7TeV", "8TeV"]: print("build for %s" % e) self.SMH.textToSpline("RqqH_%s" % e, os.path.join(datadir, "couplings/R_VBF_%s.txt" % e), ycol=1) self.modelBuilder.factory_( 'expr::Cwz_XSscal_qqH_%s("(@0 + @1*@2) / (1.0 + @2) ", Cw, Cz, RqqH_%s)' % (e, e) ) self.modelBuilder.factory_('expr::Cwz_XSscal_WH_%s("@0", Cw)' % e) self.modelBuilder.factory_('expr::Cwz_XSscal_ZH_%s("@0", Cz)' % e) self.SMH.makeXS("WH", e) self.SMH.makeXS("ZH", e) self.modelBuilder.factory_( 'expr::Cwz_XSscal_VH_%s("(@0*@1 + @2*@3) / (@1 + @3) ", Cw, SM_XS_WH_%s, Cz, SM_XS_ZH_%s)' % (e, e, e) ) def getHiggsSignalYieldScale(self, production, decay, energy): if decay not in ["hww", "hzz"]: return 0 name = "Cwz_XSBRscal_%s_%s_%s" % (production, decay, energy) if self.modelBuilder.out.function(name) == None: if production in ["ggH", "ttH"]: self.modelBuilder.factory_('expr::%s("@0", Cwz_BRscal_%s)' % (name, decay)) else: self.modelBuilder.factory_( 'expr::%s("@0 * @1", Cwz_XSscal_%s_%s, Cwz_BRscal_%s)' % (name, production, energy, decay) ) return name
class CvCfHiggs(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False self.cVRange = ['0','2'] self.cFRange = ['-2','2'] def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema." elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrema for Higgs mass range defined with inverterd order. Second must be larger the first." if po.startswith("cVRange="): self.cVRange = po.replace("cVRange=","").split(":") if len(self.cVRange) != 2: raise RuntimeError, "cV signal strength range requires minimal and maximal value" elif float(self.cVRange[0]) >= float(self.cVRange[1]): raise RuntimeError, "minimal and maximal range swapped. Second value must be larger first one" if po.startswith("cFRange="): self.cFRange = po.replace("cFRange=","").split(":") if len(self.cFRange) != 2: raise RuntimeError, "cF signal strength range requires minimal and maximal value" elif float(self.cFRange[0]) >= float(self.cFRange[1]): raise RuntimeError, "minimal and maximal range swapped. Second value must be larger first one" def doParametersOfInterest(self): """Create POI out of signal strength and MH""" # --- Signal Strength as only POI --- self.modelBuilder.doVar("CV[1,%s,%s]" % (self.cVRange[0], self.cVRange[1])) self.modelBuilder.doVar("CF[1,%s,%s]" % (self.cFRange[0], self.cFRange[1])) if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) self.modelBuilder.doSet("POI",'CV,CF,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI",'CV,CF') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): self.decayScaling = { 'hgg':'hgg', 'hzg':'hzg', 'hww':'hvv', 'hzz':'hvv', 'hbb':'hff', 'hcc':'hff', 'hss':'hff', 'htt':'hff', 'hmm':'hff', 'hgluglu':'hff', } self.productionScaling = { 'ggH':'CF', 'ttH':'CF', 'qqH':'CV', 'WH':'CV', 'ZH':'CV', 'VH':'CV', } self.SMH.makeScaling('hgg', Cb='CF', Ctop='CF', CW='CV', Ctau='CF') self.SMH.makeScaling('hzg', Cb='CF', Ctop='CF', CW='CV', Ctau='CF') # Ideas for a cleaner future # self.SMH.makeScaling('hww', 'CV*CV') -> Scaling_hww("@0*@0",CV) # self.SMH.makeScaling('total', hbb='CF*CF', htoptop='CF*CF', hww='CV*CV', hzz='CV', hgg='Scaling_hgg', hgluglu='Scaling_hgluglu' ) ## partial widths, normalized to the SM one, for decays scaling with F, V and total for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) self.modelBuilder.factory_('expr::CvCf_Gscal_sumf("@0*@0 * (@1+@2+@3+@4+@5+@6+@7)", CF, SM_BR_hbb, SM_BR_htt, SM_BR_hcc, SM_BR_htoptop, SM_BR_hgluglu, SM_BR_hmm, SM_BR_hss)') self.modelBuilder.factory_('expr::CvCf_Gscal_sumv("@0*@0 * (@1+@2)", CV, SM_BR_hww, SM_BR_hzz)') self.modelBuilder.factory_('expr::CvCf_Gscal_gg("@0 * @1", Scaling_hgg, SM_BR_hgg)') self.modelBuilder.factory_('expr::CvCf_Gscal_Zg("@0 * @1", Scaling_hzg, SM_BR_hzg)') self.modelBuilder.factory_('sum::CvCf_Gscal_tot(CvCf_Gscal_sumf, CvCf_Gscal_sumv, CvCf_Gscal_gg, CvCf_Gscal_Zg)') ## BRs, normalized to the SM ones: they scale as (coupling/coupling_SM)^2 / (totWidth/totWidthSM)^2 self.modelBuilder.factory_('expr::CvCf_BRscal_hgg("@0/@1", Scaling_hgg, CvCf_Gscal_tot)') self.modelBuilder.factory_('expr::CvCf_BRscal_hzg("@0/@1", Scaling_hzg, CvCf_Gscal_tot)') self.modelBuilder.factory_('expr::CvCf_BRscal_hff("@0*@0/@1", CF, CvCf_Gscal_tot)') self.modelBuilder.factory_('expr::CvCf_BRscal_hvv("@0*@0/@1", CV, CvCf_Gscal_tot)') self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self,production,decay,energy): name = "CvCf_XSBRscal_%s_%s" % (production,decay) if self.modelBuilder.out.function(name): return name XSscal = self.productionScaling[production] BRscal = self.decayScaling[decay] self.modelBuilder.factory_('expr::%s("@0*@0 * @1", %s, CvCf_BRscal_%s)' % (name, XSscal, BRscal)) return name
class C5qlHiggs(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False self.universalCF = False self.fix = [] def setPhysicsOptions(self, physOptions): for po in physOptions: if po == "universalCF": universalCF = True if po.startswith("fix="): self.fix = po.replace("fix=", "").split(",") if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=", "").split(",") print("The Higgs mass range:", self.mHRange) if len(self.mHRange) != 2: raise RuntimeError("Higgs mass range definition requires two extrema") elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError( "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first" ) def doParametersOfInterest(self): """Create POI out of signal strength and MH""" # --- Signal Strength as only POI --- self.modelBuilder.doVar("Cg[1,0,10]") self.modelBuilder.doVar("Cv[1,0,10]") self.modelBuilder.doVar("Cglu[1,0,10]") POI = "Cg,Cv,Cglu" if self.universalCF: self.modelBuilder.doVar("Cf[1,0,10]") POI += ",Cf" else: self.modelBuilder.doVar("Cq[1,0,10]") self.modelBuilder.doVar("Cl[1,0,10]") POI += ",Cq,Cl" if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]), float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0], self.mHRange[1])) POI += ",MH" else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) for F in self.fix: self.modelBuilder.out.var(F).setConstant(True) if F + "," in POI: POI = POI.replace(F + ",", "") else: POI = POI.replace("," + F, "") self.modelBuilder.doSet("POI", POI) self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): for d in ["htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss"]: self.SMH.makeBR(d) ## total witdhs, normalized to the SM one self.modelBuilder.factory_('expr::C5ql_Gscal_sumglu("@0*@0 * @1", Cglu, SM_BR_hgluglu)') self.modelBuilder.factory_('expr::C5ql_Gscal_sumg("@0*@0 * @1", Cg, SM_BR_hgg)') self.modelBuilder.factory_('expr::C5ql_Gscal_sumv("@0*@0 * (@1+@2+@3)", Cv, SM_BR_hww, SM_BR_hzz, SM_BR_hzg )') if self.universalCF: self.modelBuilder.factory_( 'expr::C5ql_Gscal_sumf("@0*@0 * (@1+@2+@3+@4+@5+@6)",\ Cf, SM_BR_hbb, SM_BR_htt, SM_BR_hcc, SM_BR_htoptop, SM_BR_hmm, SM_BR_hss)' ) else: self.modelBuilder.factory_( 'expr::C5ql_Gscal_sumf("@0*@0 * (@1+@2+@3+@4) + @5*@5 * (@6+@7)",\ Cq, SM_BR_hbb, SM_BR_hcc, SM_BR_htoptop, SM_BR_hss,\ Cl, SM_BR_htt, SM_BR_hmm)' ) self.modelBuilder.factory_( "sum::C5ql_Gscal_tot(C5ql_Gscal_sumglu, C5ql_Gscal_sumg, C5ql_Gscal_sumv, C5ql_Gscal_sumf)" ) ## BRs, normalized to the SM ones: they scale as (partial/partial_SM)^2 / (total/total_SM)^2 self.modelBuilder.factory_('expr::C5ql_BRscal_hgg("@0*@0/@1", Cg, C5ql_Gscal_tot)') self.modelBuilder.factory_('expr::C5ql_BRscal_hvv("@0*@0/@1", Cv, C5ql_Gscal_tot)') if self.universalCF: self.modelBuilder.factory_('expr::C5ql_BRscal_hff("@0*@0/@1", Cf, C5ql_Gscal_tot)') else: self.modelBuilder.factory_('expr::C5ql_BRscal_hbb("@0*@0/@1", Cq, C5ql_Gscal_tot)') self.modelBuilder.factory_('expr::C5ql_BRscal_htt("@0*@0/@1", Cl, C5ql_Gscal_tot)') def getHiggsSignalYieldScale(self, production, decay, energy): name = "C5ql_XSBRscal_%s_%s" % (production, decay) if self.modelBuilder.out.function(name) == None: XSscal = "Cglu" if production in ["ggH"] else "Cv" if production in ["ttH"]: XSscal = "Cf" if self.universalCF else "Cq" BRscal = "hgg" if decay in ["hww", "hzz"]: BRscal = "hvv" if decay in ["hbb", "htt"]: BRscal = "hff" if self.universalCF else decay self.modelBuilder.factory_('expr::%s("@0*@0 * @1", %s, C5ql_BRscal_%s)' % (name, XSscal, BRscal)) return name
class MepsHiggs(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False self.MRange = ['150','350'] self.epsRange = ['-1','1'] def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema." elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrema for Higgs mass range defined with inverterd order. Second must be larger the first." if po.startswith("MRange="): self.MRange = po.replace("MRange=","").split(":") if len(self.MRange) != 2: raise RuntimeError, "M range requires minimal and maximal value" elif float(self.MRange[0]) >= float(self.MRange[1]): raise RuntimeError, "minimal and maximal range swapped. Second value must be larger first one" if po.startswith("epsRange="): self.epsRange = po.replace("epsRange=","").split(":") if len(self.epsRange) != 2: raise RuntimeError, "epsilon range requires minimal and maximal value" elif float(self.epsRange[0]) >= float(self.epsRange[1]): raise RuntimeError, "minimal and maximal range swapped. Second value must be larger first one" def doParametersOfInterest(self): """Create POI out of signal strength and MH""" # --- Signal Strength as only POI --- self.modelBuilder.doVar("M[246.22,%s,%s]" % (self.MRange[0], self.MRange[1])) self.modelBuilder.doVar("eps[0,%s,%s]" % (self.epsRange[0], self.epsRange[1])) if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) self.modelBuilder.doSet("POI",'M,eps,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI",'M,eps') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): self.modelBuilder.doVar("SM_VEV[246.22]") self.msbar = { 'top' : (160, (-4.3,+4.8)), 'b' : (4.18, (-0.03,+0.03)), 'tau' : (1.77682, (-0.16,+0.16)), 'mu' : (0.105658, (-0.0000035,+0.0000035)), 'W' : (80.385, (-0.015,+0.015)), 'Z' : (91.1876, (-0.0021,+0.0021)), } for name, vals in self.msbar.iteritems(): #self.modelBuilder.doVar("M%s_MSbar[%s,%s,%s]" % (name, vals[0], vals[0]+vals[1][0], vals[0]+vals[1][1])) self.modelBuilder.doVar("M%s_MSbar[%s]" % (name, vals[0])) if name in ('W','Z'): # # Ellis cv == v (mv^(2 e)/M^(1 + 2 e)) self.modelBuilder.factory_( 'expr::C%(name)s("@0 * TMath::Power(@3,2*@2) / TMath::Power(@1,1+2*@2)", SM_VEV, M, eps, M%(name)s_MSbar)' % locals() ) else: # # Ellis cf == v (mf^e/M^(1 + e)) self.modelBuilder.factory_( 'expr::C%(name)s("@0 * TMath::Power(@3,@2) / TMath::Power(@1,1+@2)", SM_VEV, M, eps, M%(name)s_MSbar)' % locals() ) self.productionScaling = { 'ttH':'Ctop', 'WH':'CW', 'ZH':'CZ', } self.SMH.makeScaling('ggH', Cb='Cb', Ctop='Ctop') self.SMH.makeScaling('qqH', CW='CW', CZ='CZ') self.SMH.makeScaling('hgluglu', Cb='Cb', Ctop='Ctop') self.SMH.makeScaling('hgg', Cb='Cb', Ctop='Ctop', CW='CW', Ctau='Ctau') self.SMH.makeScaling('hzg', Cb='Cb', Ctop='Ctop', CW='CW', Ctau='Ctau') ## partial widths, normalized to the SM one, for decays scaling with F, V and total for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) self.modelBuilder.factory_('expr::Meps_Gscal_w("@0*@0 * @1", CW, SM_BR_hww)') self.modelBuilder.factory_('expr::Meps_Gscal_z("@0*@0 * @1", CZ, SM_BR_hzz)') self.modelBuilder.factory_('expr::Meps_Gscal_b("@0*@0 * @1", Cb, SM_BR_hbb)') self.modelBuilder.factory_('expr::Meps_Gscal_tau("@0*@0 * @1", Ctau, SM_BR_htt)') self.modelBuilder.factory_('expr::Meps_Gscal_mu("@0*@0 * @1", Cmu, SM_BR_hmm)') self.modelBuilder.factory_('expr::Meps_Gscal_top("@0*@0 * @1", Ctop, SM_BR_htoptop)') self.modelBuilder.factory_('expr::Meps_Gscal_glu("@0 * @1", Scaling_hgluglu, SM_BR_hgluglu)') self.modelBuilder.factory_('expr::Meps_Gscal_gg("@0 * @1", Scaling_hgg, SM_BR_hgg)') self.modelBuilder.factory_('expr::Meps_Gscal_zg("@0 * @1", Scaling_hzg, SM_BR_hzg)') self.modelBuilder.factory_('sum::Meps_Gscal_tot(Meps_Gscal_w, Meps_Gscal_z, Meps_Gscal_b, Meps_Gscal_tau, Meps_Gscal_mu, Meps_Gscal_top, Meps_Gscal_glu, Meps_Gscal_gg, Meps_Gscal_zg, SM_BR_hcc, SM_BR_hss)') ## BRs, normalized to the SM ones: they scale as (coupling/coupling_SM)^2 / (totWidth/totWidthSM)^2 self.modelBuilder.factory_('expr::Meps_BRscal_hww("@0*@0/@1", CW, Meps_Gscal_tot)') self.modelBuilder.factory_('expr::Meps_BRscal_hzz("@0*@0/@1", CZ, Meps_Gscal_tot)') self.modelBuilder.factory_('expr::Meps_BRscal_hbb("@0*@0/@1", Cb, Meps_Gscal_tot)') self.modelBuilder.factory_('expr::Meps_BRscal_htt("@0*@0/@1", Ctau, Meps_Gscal_tot)') self.modelBuilder.factory_('expr::Meps_BRscal_hmm("@0*@0/@1", Cmu, Meps_Gscal_tot)') self.modelBuilder.factory_('expr::Meps_BRscal_hgg("@0/@1", Scaling_hgg, Meps_Gscal_tot)') self.modelBuilder.factory_('expr::Meps_BRscal_hzg("@0/@1", Scaling_hzg, Meps_Gscal_tot)') self.modelBuilder.factory_('expr::Meps_BRscal_hcc("@0*@0/@1", Ctau, Meps_Gscal_tot)') self.modelBuilder.factory_('expr::Meps_BRscal_hss("@0*@0/@1", Cb, Meps_Gscal_tot)') self.modelBuilder.factory_('expr::Meps_BRscal_hgluglu("@0/@1", Scaling_hgluglu, Meps_Gscal_tot)') self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self,production,decay,energy): name = 'Meps_XSBRscal_%(production)s_%(decay)s' % locals() if production in ('ggH','qqH'): self.productionScaling[production]='Scaling_'+production+'_'+energy name += '_%(energy)s' % locals() if self.modelBuilder.out.function(name): return name if production == "VH": print "WARNING: You are trying to use a VH production mode in a model that needs WH and ZH separately. "\ "The best I can do is to scale [%(production)s, %(decay)s, %(energy)s] with the decay BR only but this is wrong..." % locals() self.modelBuilder.factory_('expr::%(name)s("1.0*@0", Meps_BRscal_%(decay)s)' % locals()) return name XSscal = self.productionScaling[production] if production == 'ggH': self.modelBuilder.factory_('expr::%(name)s("@0 * @1", %(XSscal)s, Meps_BRscal_%(decay)s)' % locals()) else: self.modelBuilder.factory_('expr::%(name)s("@0*@0 * @1", %(XSscal)s, Meps_BRscal_%(decay)s)' % locals()) return name
class CWidth(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__( self ) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False self.doHZg = False self.doHInv = False self.doWidth = False def setPhysicsOptions(self, physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=", "").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema" elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first" if po == 'doHZg': self.doHZg = True if po == 'doHInv': self.doHInv = True if po == 'doWidth': self.doWidth = True def doParametersOfInterest(self): """Create POI out of signal strength and MH""" self.modelBuilder.doVar("kV[1,0.0,1.0]") # bounded to 1 self.modelBuilder.doVar("ktau[1,0.0,2.0]") self.modelBuilder.doVar("ktop[1,0.0,4.0]") self.modelBuilder.doVar("kbottom[1,0.0,3.0]") self.modelBuilder.doVar("kgluon[1,0.0,2.0]") self.modelBuilder.doVar("kgamma[1,0.0,2.5]") if self.doWidth: self.modelBuilder.doVar("Gscale[1,0,10]") pois = 'kV,ktau,ktop,kbottom,kgluon,kgamma,Gscale' else: self.modelBuilder.doVar("BRInvUndet[0,0,1]") pois = 'kV,ktau,ktop,kbottom,kgluon,kgamma,BRInvUndet' if self.doHZg: self.modelBuilder.doVar("kZgamma[1,0.0,30.0]") pois += ",kZgamma" if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange( float(self.mHRange[0]), float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0], self.mHRange[1])) self.modelBuilder.doSet("POI", pois + ',MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI", pois) self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): # SM BR for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) ## total witdhs, normalized to the SM one self.modelBuilder.factory_( 'expr::c7_Gscal_Vectors("@0*@0 * (@1+@2)", kV, SM_BR_hzz, SM_BR_hww)' ) self.modelBuilder.factory_( 'expr::c7_Gscal_tau("@0*@0 * (@1+@2)", ktau, SM_BR_htt, SM_BR_hmm)' ) self.modelBuilder.factory_( 'expr::c7_Gscal_top("@0*@0 * (@1+@2)", ktop, SM_BR_htoptop, SM_BR_hcc)' ) self.modelBuilder.factory_( 'expr::c7_Gscal_bottom("@0*@0 * (@1+@2)", kbottom, SM_BR_hbb, SM_BR_hss)' ) self.modelBuilder.factory_( 'expr::c7_Gscal_gluon("@0*@0 * @1", kgluon, SM_BR_hgluglu)') if not self.doHZg: self.modelBuilder.factory_( 'expr::c7_Gscal_gamma("@0*@0 * (@1+@2)", kgamma, SM_BR_hgg, SM_BR_hzg)' ) else: self.modelBuilder.factory_( 'expr::c7_Gscal_gamma("@0*@0 *@1+@2*@2*@3", kgamma, SM_BR_hgg, kZgamma, SM_BR_hzg)' ) # #RooFormulaVar::c7_Gscal_tot[ actualVars=(Gscale,c7_Gscal_Vectors,c7_Gscal_tau,c7_Gscal_top,c7_Gscal_bottom,c7_Gscal_gluon,c7_Gscal_gamma) formula="(@1+@2+@3+@4+@5+@6)<=@0?@0:0.001" ] = 0.001 #root [8] w->function("c7_Gscal_tau")->Print() #RooFormulaVar::c7_Gscal_tau[ actualVars=(ktau,SM_BR_htt,SM_BR_hmm) formula="@0*@0*(@1+@2)" ] = 0.063419 #root [9] w->function("c7_Gscal_top")->Print() #RooFormulaVar::c7_Gscal_top[ actualVars=(ktop,SM_BR_htoptop,SM_BR_hcc) formula="@0*@0*(@1+@2)" ] = 0.0291 #root [10] w->function("c7_Gscal_bottom")->Print() #RooFormulaVar::c7_Gscal_bottom[ actualVars=(kbottom,SM_BR_hbb,SM_BR_hss) formula="@0*@0*(@1+@2)" ] = 0.577246 #### The spline interpolation has small difference w.r.t YR3 number 5.769462E-01 #root [11] w->function("c7_Gscal_gluon")->Print() #RooFormulaVar::c7_Gscal_gluon[ actualVars=(kgluon,SM_BR_hgluglu) formula="@0*@0*@1" ] = 0.0857 #root [12] w->function("c7_Gscal_gamma")->Print() #RooFormulaVar::c7_Gscal_gamma[ actualVars=(kgamma,SM_BR_hgg,SM_BR_hzg) formula="@0*@0*(@1+@2)" ] = 0.00382 #root [13] w->function("c7_Gscal_Vectors")->Print() #RooFormulaVar::c7_Gscal_Vectors[ actualVars=(kV,SM_BR_hzz,SM_BR_hww) formula="@0*@0*(@1+@2)" ] = 0.2414 #############################Then the above sum = 1.000685 , so that the asimov data set will be generated with c7_Gscal_tot = 0.0001, and BRInv = -100 #root [14] w->var("ktau")->Print() #RooRealVar::ktau = 1 L(0 - 2) #root [15] w->var("ktop")->Print() #RooRealVar::ktop = 1 L(0 - 4) #root [16] w->var("kgluon")->Print() #RooRealVar::kgluon = 1 L(0 - 2) #root [17] w->var("kgamma")->Print() #RooRealVar::kgamma = 1 L(0 - 2.5) ############################either generate asimov dataset with kbottom slightly less 1 i.e. kb=0.999 is fine if self.doWidth: self.modelBuilder.factory_( 'expr::c7_Gscal_tot("(@1+@2+@3+@4+@5+@6)<=@0?@0:0.001",Gscale,c7_Gscal_Vectors, c7_Gscal_tau, c7_Gscal_top, c7_Gscal_bottom, c7_Gscal_gluon, c7_Gscal_gamma)' ) self.modelBuilder.factory_( 'expr::BRInvUndet("1 - (@1+@2+@3+@4+@5+@6)/@0",c7_Gscal_tot,c7_Gscal_Vectors, c7_Gscal_tau, c7_Gscal_top, c7_Gscal_bottom, c7_Gscal_gluon, c7_Gscal_gamma)' ) else: self.modelBuilder.factory_( 'expr::c7_Gscal_tot("(@1+@2+@3+@4+@5+@6)/(1-@0)",BRInvUndet,c7_Gscal_Vectors, c7_Gscal_tau, c7_Gscal_top, c7_Gscal_bottom, c7_Gscal_gluon, c7_Gscal_gamma)' ) ## BRs, normalized to the SM ones: they scale as (partial/partial_SM)^2 / (total/total_SM)^2 self.modelBuilder.factory_( 'expr::c7_BRscal_hvv("@0*@0/@1", kV, c7_Gscal_tot)') self.modelBuilder.factory_( 'expr::c7_BRscal_htt("@0*@0/@1", ktau, c7_Gscal_tot)') self.modelBuilder.factory_( 'expr::c7_BRscal_hbb("@0*@0/@1", kbottom, c7_Gscal_tot)') self.modelBuilder.factory_( 'expr::c7_BRscal_hgg("@0*@0/@1", kgamma, c7_Gscal_tot)') if self.doHZg: self.modelBuilder.factory_( 'expr::c7_BRscal_hzg("@0*@0/@1", kZgamma, c7_Gscal_tot)') if self.doHInv: self.modelBuilder.factory_( 'expr::c7_BRscal_hinv("@0>=0?@0:-100", BRInvUndet)') def getHiggsSignalYieldScale(self, production, decay, energy): name = "c7_XSBRscal_%s_%s" % (production, decay) print '[LOFullParametrization::C7]' print name, production, decay, energy if self.modelBuilder.out.function(name) == None: XSscal = "kgluon" if production in ["WH", "ZH", "VH", "qqH"]: XSscal = "kV" if production == "ttH": XSscal = "ktop" BRscal = "hgg" if decay in ["hbb", "htt"]: BRscal = decay if decay in ["hww", "hzz"]: BRscal = "hvv" if self.doHZg and decay == "hzg": BRscal = "hzg" if self.doHInv and decay == "hinv": BRscal = "hinv" self.modelBuilder.factory_( 'expr::%s("@0*@0 * @1", %s, c7_BRscal_%s)' % (name, XSscal, BRscal)) return name
class TwoHDM(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False self.thdmtype = ['1'] def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema" elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first" if po.startswith("thdmtype="): self.thdmtype= po.replace("thdmtype=","") if len(self.thdmtype) != 1: raise RuntimeError, "2HDM type requires one value" elif int(self.thdmtype[0]) != 1 and int(self.thdmtype[0]) !=2 and int(self.thdmtype[0]) !=3 and int(self.thdmtype[0]) !=4: raise RuntimeError, "2HDM type must be 1 (default) or 2 or 3 or 4 " def doParametersOfInterest(self): """Create POI out of signal strength and MH""" self.modelBuilder.doVar("cosbma[0,-1,1]") self.modelBuilder.doVar("tanbeta[0,0.0,10]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) self.modelBuilder.doSet("POI",'cosbma,tanbeta,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI",'cosbma,tanbeta') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): self.modelBuilder.factory_('expr::kV("sqrt(1-@0*@0)",cosbma)') self.modelBuilder.factory_('expr::tana("(@0*@1-@2)/(@1-@0*@2)", tanbeta, cosbma, kV)') self.modelBuilder.factory_('expr::cosa("1/sqrt(1+@0*@0)",tana)') self.modelBuilder.factory_('expr::sinb("tanbeta/sqrt(1+@0*@0)",tanbeta)') self.modelBuilder.factory_('expr::ku("@0/@1", cosa, sinb)') if int(self.thdmtype[0]) == 1: self.modelBuilder.factory_('expr::kd("@0", ku)') self.modelBuilder.factory_('expr::kl("@0", ku)') elif int(self.thdmtype[0]) == 2: self.modelBuilder.factory_('expr::cosb("1/sqrt(1+@0*@0)",tanbeta)') self.modelBuilder.factory_('expr::sina("tana/sqrt(1+@0*@0)",tana)') self.modelBuilder.factory_('expr::kd("-@0/@1", sina,cosb)') self.modelBuilder.factory_('expr::kl("@0", kd)') elif int(self.thdmtype[0]) == 3: self.modelBuilder.factory_('expr::cosb("1/sqrt(1+@0*@0)",tanbeta)') self.modelBuilder.factory_('expr::sina("tana/sqrt(1+@0*@0)",tana)') self.modelBuilder.factory_('expr::kd("@0", ku)') self.modelBuilder.factory_('expr::kl("-@0/@1", sina,cosb)') elif int(self.thdmtype[0]) == 4: self.modelBuilder.factory_('expr::cosb("1/sqrt(1+@0*@0)",tanbeta)') self.modelBuilder.factory_('expr::sina("tana/sqrt(1+@0*@0)",tana)') self.modelBuilder.factory_('expr::kd("-@0/@1", sina,cosb)') self.modelBuilder.factory_('expr::kl("@0", ku)') self.decayScaling = { 'hgg':'hgg', 'hzg':'hzg', 'hww':'hvv', 'hzz':'hvv', 'hbb':'hdd', 'htt':'hll', 'hss':'hdd', 'hmm':'hll', 'hcc':'huu', 'hgluglu':'hgluglu', } self.productionScaling = { 'ttH':'ku', 'qqH':'kV', 'WH':'kV', 'ZH':'kV', 'VH':'kV', } # scalings of the loops self.SMH.makeScaling('ggH', Cb='kd', Ctop='ku') self.SMH.makeScaling('hgg', Cb='kd', Ctop='ku', CW='kV', Ctau='kl') self.SMH.makeScaling('hzg', Cb='kd', Ctop='ku', CW='kV', Ctau='kl') self.SMH.makeScaling('hgluglu', Cb='kd', Ctop='ku') # SM BR for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) ## total witdhs, normalized to the SM one self.modelBuilder.factory_('expr::twohdm_Gscal_Vectors("@0*@0 * (@1+@2)", kV, SM_BR_hzz, SM_BR_hww)') self.modelBuilder.factory_('expr::twohdm_Gscal_up("@0*@0 * (@1+@2)", ku, SM_BR_hcc, SM_BR_htoptop)') self.modelBuilder.factory_('expr::twohdm_Gscal_down("@0*@0 * (@1+@2)", kd, SM_BR_hbb, SM_BR_hss)') self.modelBuilder.factory_('expr::twohdm_Gscal_leptons("@0*@0 * (@1+@2)", kl, SM_BR_htt, SM_BR_hmm)') self.modelBuilder.factory_('expr::twohdm_Gscal_gg("@0 * @1", Scaling_hgg, SM_BR_hgg)') self.modelBuilder.factory_('expr::twohdm_Gscal_Zg("@0 * @1", Scaling_hzg, SM_BR_hzg)') self.modelBuilder.factory_('expr::twohdm_Gscal_gluglu("@0 * @1", Scaling_hgluglu, SM_BR_hgluglu)') self.modelBuilder.factory_('sum::twohdm_Gscal_tot(twohdm_Gscal_Vectors, twohdm_Gscal_up, twohdm_Gscal_down, twohdm_Gscal_leptons, twohdm_Gscal_gg, twohdm_Gscal_Zg, twohdm_Gscal_gluglu)') ## BRs, normalized to the SM ones: they scale as (partial/partial_SM)^2 / (total/total_SM)^2 self.modelBuilder.factory_('expr::twohdm_BRscal_hvv("@0*@0/@1", kV, twohdm_Gscal_tot)') self.modelBuilder.factory_('expr::twohdm_BRscal_huu("@0*@0/@1", ku, twohdm_Gscal_tot)') self.modelBuilder.factory_('expr::twohdm_BRscal_hdd("@0*@0/@1", kd, twohdm_Gscal_tot)') self.modelBuilder.factory_('expr::twohdm_BRscal_hll("@0*@0/@1", kl, twohdm_Gscal_tot)') self.modelBuilder.factory_('expr::twohdm_BRscal_hgg("@0/@1", Scaling_hgg, twohdm_Gscal_tot)') self.modelBuilder.factory_('expr::twohdm_BRscal_hgluglu("@0/@1", Scaling_hgluglu, twohdm_Gscal_tot)') self.modelBuilder.factory_('expr::twohdm_BRscal_hzg("@0/@1", Scaling_hzg, twohdm_Gscal_tot)') # verbosity #self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self,production,decay,energy): name = 'twohdm_XSBRscal_%(production)s_%(decay)s' % locals() #Special case that depends on Energy if production == 'ggH': self.productionScaling[production] = 'Scaling_ggH_' + energy name += '_%(energy)s' % locals() if self.modelBuilder.out.function(name): return name XSscal = self.productionScaling[production] BRscal = self.decayScaling[decay] if 'Scaling_' in XSscal: # it's a Scaling, which means it's already squared self.modelBuilder.factory_('expr::%s("@0 * @1", %s, twohdm_BRscal_%s)' % (name, XSscal, BRscal)) else: # It's a kappa, so it's linear and I must square it self.modelBuilder.factory_('expr::%s("@0*@0 * @1", %s, twohdm_BRscal_%s)' % (name, XSscal, BRscal)) return name
class C5(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__( self ) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False def setPhysicsOptions(self, physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=", "").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema" elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first" def doParametersOfInterest(self): """Create POI out of signal strength and MH""" self.modelBuilder.doVar("kV[1,0.0,2.0]") self.modelBuilder.doVar("ktau[1,0.0,2.0]") self.modelBuilder.doVar("kquark[1,0.0,2.0]") self.modelBuilder.doVar("kgluon[1,0.0,2.0]") self.modelBuilder.doVar("kgamma[1,0.0,2.0]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange( float(self.mHRange[0]), float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0], self.mHRange[1])) self.modelBuilder.doSet("POI", 'kV,ktau,kquark,kgluon,kgamma,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI", 'kV,ktau,kquark,kgluon,kgamma') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): # SM BR for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) ## total witdhs, normalized to the SM one self.modelBuilder.factory_( 'expr::c6_Gscal_Vectors("@0*@0 * (@1+@2)", kV, SM_BR_hzz, SM_BR_hww)' ) self.modelBuilder.factory_( 'expr::c6_Gscal_tau("@0*@0 * (@1+@2)", ktau, SM_BR_htt, SM_BR_hmm)' ) self.modelBuilder.factory_( 'expr::c6_Gscal_quark("@0*@0 * (@1+@2+@3+@4)", kquark, SM_BR_htoptop, SM_BR_hcc,SM_BR_hbb, SM_BR_hss)' ) self.modelBuilder.factory_( 'expr::c6_Gscal_gluon("@0*@0 * @1", kgluon, SM_BR_hgluglu)') self.modelBuilder.factory_( 'expr::c6_Gscal_gamma("@0*@0 * (@1+@2)", kgamma, SM_BR_hgg, SM_BR_hzg)' ) self.modelBuilder.factory_( 'sum::c6_Gscal_tot(c6_Gscal_Vectors, c6_Gscal_tau, c6_Gscal_quark, c6_Gscal_gluon, c6_Gscal_gamma)' ) ## BRs, normalized to the SM ones: they scale as (partial/partial_SM)^2 / (total/total_SM)^2 self.modelBuilder.factory_( 'expr::c6_BRscal_hvv("@0*@0/@1", kV, c6_Gscal_tot)') self.modelBuilder.factory_( 'expr::c6_BRscal_htt("@0*@0/@1", ktau, c6_Gscal_tot)') self.modelBuilder.factory_( 'expr::c6_BRscal_hbb("@0*@0/@1", kquark, c6_Gscal_tot)') self.modelBuilder.factory_( 'expr::c6_BRscal_hgg("@0*@0/@1", kgamma, c6_Gscal_tot)') def getHiggsSignalYieldScale(self, production, decay, energy): name = "c6_XSBRscal_%s_%s" % (production, decay) print '[LOFullParametrization::C6]' print name, production, decay, energy if self.modelBuilder.out.function(name) == None: XSscal = "kgluon" if production in ["WH", "ZH", "VH", "qqH"]: XSscal = "kV" if production == "ttH": XSscal = "kquark" BRscal = "hgg" if decay in ["hbb", "htt"]: BRscal = decay if decay in ["hww", "hzz"]: BRscal = "hvv" self.modelBuilder.factory_( 'expr::%s("@0*@0 * @1", %s, c6_BRscal_%s)' % (name, XSscal, BRscal)) return name
class C6(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False self.doHZg = False def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema" elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first" if po == 'doHZg': self.doHZg = True def doParametersOfInterest(self): """Create POI out of signal strength and MH""" self.modelBuilder.doVar("kV[1,0.0,2.0]") self.modelBuilder.doVar("ktau[1,0.0,2.0]") self.modelBuilder.doVar("ktop[1,0.0,2.0]") self.modelBuilder.doVar("kbottom[1,0.0,2.0]") self.modelBuilder.doVar("kgluon[1,0.0,2.0]") self.modelBuilder.doVar("kgamma[1,0.0,2.0]") pois = 'kV,ktau,ktop,kbottom,kgluon,kgamma' if self.doHZg: self.modelBuilder.doVar("kZgamma[1,0.0,30.0]") pois += ",kZgamma" if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) self.modelBuilder.doSet("POI",pois+',MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI",pois) self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): # SM BR for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) ## total witdhs, normalized to the SM one self.modelBuilder.factory_('expr::c6_Gscal_Vectors("@0*@0 * (@1+@2)", kV, SM_BR_hzz, SM_BR_hww)') self.modelBuilder.factory_('expr::c6_Gscal_tau("@0*@0 * (@1+@2)", ktau, SM_BR_htt, SM_BR_hmm)') self.modelBuilder.factory_('expr::c6_Gscal_top("@0*@0 * (@1+@2)", ktop, SM_BR_htoptop, SM_BR_hcc)') self.modelBuilder.factory_('expr::c6_Gscal_bottom("@0*@0 * (@1+@2)", kbottom, SM_BR_hbb, SM_BR_hss)') self.modelBuilder.factory_('expr::c6_Gscal_gluon("@0*@0 * @1", kgluon, SM_BR_hgluglu)') if not self.doHZg: self.modelBuilder.factory_('expr::c6_Gscal_gamma("@0*@0 * (@1+@2)", kgamma, SM_BR_hgg, SM_BR_hzg)') else: self.modelBuilder.factory_('expr::c6_Gscal_gamma("@0*@0 *@1+@2*@2*@3", kgamma, SM_BR_hgg, kZgamma, SM_BR_hzg)') self.modelBuilder.factory_('sum::c6_Gscal_tot(c6_Gscal_Vectors, c6_Gscal_tau, c6_Gscal_top, c6_Gscal_bottom, c6_Gscal_gluon, c6_Gscal_gamma)') ## BRs, normalized to the SM ones: they scale as (partial/partial_SM)^2 / (total/total_SM)^2 self.modelBuilder.factory_('expr::c6_BRscal_hvv("@0*@0/@1", kV, c6_Gscal_tot)') self.modelBuilder.factory_('expr::c6_BRscal_htt("@0*@0/@1", ktau, c6_Gscal_tot)') self.modelBuilder.factory_('expr::c6_BRscal_hbb("@0*@0/@1", kbottom, c6_Gscal_tot)') self.modelBuilder.factory_('expr::c6_BRscal_hgg("@0*@0/@1", kgamma, c6_Gscal_tot)') if self.doHZg: self.modelBuilder.factory_('expr::c6_BRscal_hzg("@0*@0/@1", kZgamma, c6_Gscal_tot)') def getHiggsSignalYieldScale(self,production,decay,energy): name = "c6_XSBRscal_%s_%s" % (production,decay) print '[LOFullParametrization::C6]' print name, production, decay, energy if self.modelBuilder.out.function(name) == None: XSscal = "kgluon" if production in ["WH","ZH","VH","qqH"]: XSscal = "kV" if production == "ttH": XSscal = "ktop" BRscal = "hgg" if decay in ["hbb", "htt"]: BRscal = decay if decay in ["hww", "hzz"]: BRscal = "hvv" if self.doHZg and decay == "hzg": BRscal = "hzg" self.modelBuilder.factory_('expr::%s("@0*@0 * @1", %s, c6_BRscal_%s)' % (name, XSscal, BRscal)) return name
widthUncertainties = {} widthUncertaintiesKeys = [] for line in open(SMH.brpath + "/WidthUncertainties_126GeV.txt"): if widthUncertaintiesKeys == []: widthUncertaintiesKeys = line.split()[1:] else: fields = line.split() widthUncertainties[fields[0]] = dict([ (k, 0.01 * float(v)) for (k, v) in zip(widthUncertaintiesKeys, fields[1:]) ]) BRs = {} for d in SM_HIGGS_DECAYS: SMH.makeBR(d) BRs[d] = MB.out.function("SM_BR_" + d).getVal() THU_GROUPS = [ ('hvv', ['hww', 'hzz']), ('hqq', ['hbb', 'hcc', 'hss']), ('hll', ['htt', 'hmm']), ('hgg', ['hgg']), ('hzg', ['hzg']), ('hgluglu', ['hgluglu']), ] uncertainties = [] for s in widthUncertaintiesKeys[:-1]: key = "HiggsDecayWidth_" + s val = {}
class CWidth(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False self.doHZg = False self.doHInv = False self.doWidth = False def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema" elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first" if po == 'doHZg': self.doHZg = True if po == 'doHInv': self.doHInv = True if po == 'doWidth': self.doWidth = True def doParametersOfInterest(self): """Create POI out of signal strength and MH""" self.modelBuilder.doVar("kV[1,0.0,1.0]") # bounded to 1 self.modelBuilder.doVar("ktau[1,0.0,2.0]") self.modelBuilder.doVar("ktop[1,0.0,4.0]") self.modelBuilder.doVar("kbottom[1,0.0,3.0]") self.modelBuilder.doVar("kgluon[1,0.0,2.0]") self.modelBuilder.doVar("kgamma[1,0.0,2.5]") if self.doWidth: self.modelBuilder.doVar("Gscale[1,0,10]") pois = 'kV,ktau,ktop,kbottom,kgluon,kgamma,Gscale' else: self.modelBuilder.doVar("BRInvUndet[0,0,1]") pois = 'kV,ktau,ktop,kbottom,kgluon,kgamma,BRInvUndet' if self.doHZg: self.modelBuilder.doVar("kZgamma[1,0.0,30.0]") pois += ",kZgamma" if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) self.modelBuilder.doSet("POI",pois+',MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI",pois) self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): # SM BR for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) ## total witdhs, normalized to the SM one self.modelBuilder.factory_('expr::c7_Gscal_Vectors("@0*@0 * (@1+@2)", kV, SM_BR_hzz, SM_BR_hww)') self.modelBuilder.factory_('expr::c7_Gscal_tau("@0*@0 * (@1+@2)", ktau, SM_BR_htt, SM_BR_hmm)') self.modelBuilder.factory_('expr::c7_Gscal_top("@0*@0 * (@1+@2)", ktop, SM_BR_htoptop, SM_BR_hcc)') self.modelBuilder.factory_('expr::c7_Gscal_bottom("@0*@0 * (@1+@2)", kbottom, SM_BR_hbb, SM_BR_hss)') self.modelBuilder.factory_('expr::c7_Gscal_gluon("@0*@0 * @1", kgluon, SM_BR_hgluglu)') if not self.doHZg: self.modelBuilder.factory_('expr::c7_Gscal_gamma("@0*@0 * (@1+@2)", kgamma, SM_BR_hgg, SM_BR_hzg)') else: self.modelBuilder.factory_('expr::c7_Gscal_gamma("@0*@0 *@1+@2*@2*@3", kgamma, SM_BR_hgg, kZgamma, SM_BR_hzg)') # #RooFormulaVar::c7_Gscal_tot[ actualVars=(Gscale,c7_Gscal_Vectors,c7_Gscal_tau,c7_Gscal_top,c7_Gscal_bottom,c7_Gscal_gluon,c7_Gscal_gamma) formula="(@1+@2+@3+@4+@5+@6)<=@0?@0:0.001" ] = 0.001 #root [8] w->function("c7_Gscal_tau")->Print() #RooFormulaVar::c7_Gscal_tau[ actualVars=(ktau,SM_BR_htt,SM_BR_hmm) formula="@0*@0*(@1+@2)" ] = 0.063419 #root [9] w->function("c7_Gscal_top")->Print() #RooFormulaVar::c7_Gscal_top[ actualVars=(ktop,SM_BR_htoptop,SM_BR_hcc) formula="@0*@0*(@1+@2)" ] = 0.0291 #root [10] w->function("c7_Gscal_bottom")->Print() #RooFormulaVar::c7_Gscal_bottom[ actualVars=(kbottom,SM_BR_hbb,SM_BR_hss) formula="@0*@0*(@1+@2)" ] = 0.577246 #### The spline interpolation has small difference w.r.t YR3 number 5.769462E-01 #root [11] w->function("c7_Gscal_gluon")->Print() #RooFormulaVar::c7_Gscal_gluon[ actualVars=(kgluon,SM_BR_hgluglu) formula="@0*@0*@1" ] = 0.0857 #root [12] w->function("c7_Gscal_gamma")->Print() #RooFormulaVar::c7_Gscal_gamma[ actualVars=(kgamma,SM_BR_hgg,SM_BR_hzg) formula="@0*@0*(@1+@2)" ] = 0.00382 #root [13] w->function("c7_Gscal_Vectors")->Print() #RooFormulaVar::c7_Gscal_Vectors[ actualVars=(kV,SM_BR_hzz,SM_BR_hww) formula="@0*@0*(@1+@2)" ] = 0.2414 #############################Then the above sum = 1.000685 , so that the asimov data set will be generated with c7_Gscal_tot = 0.0001, and BRInv = -100 #root [14] w->var("ktau")->Print() #RooRealVar::ktau = 1 L(0 - 2) #root [15] w->var("ktop")->Print() #RooRealVar::ktop = 1 L(0 - 4) #root [16] w->var("kgluon")->Print() #RooRealVar::kgluon = 1 L(0 - 2) #root [17] w->var("kgamma")->Print() #RooRealVar::kgamma = 1 L(0 - 2.5) ############################either generate asimov dataset with kbottom slightly less 1 i.e. kb=0.999 is fine if self.doWidth: self.modelBuilder.factory_('expr::c7_Gscal_tot("(@1+@2+@3+@4+@5+@6)<=@0?@0:0.001",Gscale,c7_Gscal_Vectors, c7_Gscal_tau, c7_Gscal_top, c7_Gscal_bottom, c7_Gscal_gluon, c7_Gscal_gamma)') self.modelBuilder.factory_('expr::BRInvUndet("1 - (@1+@2+@3+@4+@5+@6)/@0",c7_Gscal_tot,c7_Gscal_Vectors, c7_Gscal_tau, c7_Gscal_top, c7_Gscal_bottom, c7_Gscal_gluon, c7_Gscal_gamma)') else: self.modelBuilder.factory_('expr::c7_Gscal_tot("(@1+@2+@3+@4+@5+@6)/(1-@0)",BRInvUndet,c7_Gscal_Vectors, c7_Gscal_tau, c7_Gscal_top, c7_Gscal_bottom, c7_Gscal_gluon, c7_Gscal_gamma)') ## BRs, normalized to the SM ones: they scale as (partial/partial_SM)^2 / (total/total_SM)^2 self.modelBuilder.factory_('expr::c7_BRscal_hvv("@0*@0/@1", kV, c7_Gscal_tot)') self.modelBuilder.factory_('expr::c7_BRscal_htt("@0*@0/@1", ktau, c7_Gscal_tot)') self.modelBuilder.factory_('expr::c7_BRscal_hbb("@0*@0/@1", kbottom, c7_Gscal_tot)') self.modelBuilder.factory_('expr::c7_BRscal_hgg("@0*@0/@1", kgamma, c7_Gscal_tot)') if self.doHZg: self.modelBuilder.factory_('expr::c7_BRscal_hzg("@0*@0/@1", kZgamma, c7_Gscal_tot)') if self.doHInv: self.modelBuilder.factory_('expr::c7_BRscal_hinv("@0>=0?@0:-100", BRInvUndet)') def getHiggsSignalYieldScale(self,production,decay,energy): name = "c7_XSBRscal_%s_%s" % (production,decay) print '[LOFullParametrization::C7]' print name, production, decay, energy if self.modelBuilder.out.function(name) == None: XSscal = "kgluon" if production in ["WH","ZH","VH","qqH"]: XSscal = "kV" if production == "ttH": XSscal = "ktop" BRscal = "hgg" if decay in ["hbb", "htt"]: BRscal = decay if decay in ["hww", "hzz"]: BRscal = "hvv" if self.doHZg and decay == "hzg": BRscal = "hzg" if self.doHInv and decay == "hinv": BRscal = "hinv" self.modelBuilder.factory_('expr::%s("@0*@0 * @1", %s, c7_BRscal_%s)' % (name, XSscal, BRscal)) return name
class CwzHiggs(SMLikeHiggsModel): "Scale w and z and touch nothing else" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema." elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrema for Higgs mass range defined with inverterd order. Second must be larger the first." def doParametersOfInterest(self): """Create POI out of signal strength and MH""" self.modelBuilder.doVar("Cz[1,0,10]") self.modelBuilder.doVar("Cwz[1,0,10]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) self.modelBuilder.doSet("POI",'Cwz,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI",'Cwz') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): for d in [ "hww", "hzz" ]: self.SMH.makeBR(d) self.modelBuilder.factory_('expr::Cw("@0*@1",Cz, Cwz)') ## total witdhs, normalized to the SM one self.modelBuilder.factory_('expr::Cwz_Gscal_tot("@0*@1 + @2*@3 + (1.0-@1-@3)", \ Cw, SM_BR_hww, Cz, SM_BR_hzz)') ## BRs, normalized to the SM ones: they scale as (partial/partial_SM) / (total/total_SM) self.modelBuilder.factory_('expr::Cwz_BRscal_hww("@0/@1", Cw, Cwz_Gscal_tot)') self.modelBuilder.factory_('expr::Cwz_BRscal_hzz("@0/@1", Cz, Cwz_Gscal_tot)') datadir = os.environ['CMSSW_BASE']+'/src/HiggsAnalysis/CombinedLimit/data/lhc-hxswg' for e in ['7TeV', '8TeV']: print 'build for %s'%e self.SMH.textToSpline( 'RqqH_%s'%e, os.path.join(datadir, 'couplings/R_VBF_%s.txt'%e), ycol=1 ); self.modelBuilder.factory_('expr::Cwz_XSscal_qqH_%s("(@0 + @1*@2) / (1.0 + @2) ", Cw, Cz, RqqH_%s)'%(e,e)) self.modelBuilder.factory_('expr::Cwz_XSscal_WH_%s("@0", Cw)'%e) self.modelBuilder.factory_('expr::Cwz_XSscal_ZH_%s("@0", Cz)'%e) self.SMH.makeXS('WH',e) self.SMH.makeXS('ZH',e) self.modelBuilder.factory_('expr::Cwz_XSscal_VH_%s("(@0*@1 + @2*@3) / (@1 + @3) ", Cw, SM_XS_WH_%s, Cz, SM_XS_ZH_%s)'%(e,e,e)) def getHiggsSignalYieldScale(self,production,decay,energy): if decay not in ['hww', 'hzz']: return 0 name = "Cwz_XSBRscal_%s_%s_%s" % (production,decay,energy) if self.modelBuilder.out.function(name) == None: if production in ["ggH","ttH"]: self.modelBuilder.factory_('expr::%s("@0", Cwz_BRscal_%s)' % (name, decay)) else: self.modelBuilder.factory_('expr::%s("@0 * @1", Cwz_XSscal_%s_%s, Cwz_BRscal_%s)' % (name, production, energy, decay)) return name
class Higgswidth(PhysicsModel): def __init__(self): self.mHRange = [] self.GGsmfixed = False self.is2l2nu = False self.RVRFfixed = False self.useKframework = False self.notCustodial = False self.MHScaleWW = False self.poiMap = [] self.pois = {} self.verbose = False def setModelBuilder(self, modelBuilder): PhysicsModel.setModelBuilder(self,modelBuilder) self.modelBuilder.doModelBOnly = False def getYieldScale(self,bin,process): if "hww" in bin: #if "1j" in bin: #if process == "ggH_s": return "ggH_s_funcWW_1j" #elif process == "ggH_b": return "ggH_b_funcWW_1j" #elif process == "ggH_sbi": return "ggH_sbi_funcWW_1j" #elif process == "qqH_s": return "qqH_s_funcWW_1j" #elif process == "qqH_b": return "qqH_b_funcWW_1j" #elif process == "qqH_sbi": return "qqH_sbi_funcWW_1j" #else : if process == "ggH_s": return "ggH_s_funcWW" elif process == "ggH_b": return "ggH_b_funcWW" elif process == "ggH_sbi": return "ggH_sbi_funcWW" elif process == "qqH_s": return "qqH_s_funcWW" elif process == "qqH_b": return "qqH_b_funcWW" elif process == "qqH_sbi": return "qqH_sbi_funcWW" else: if process == "ggH_s": return "ggH_s_func" elif process == "ggH_b": return "ggH_b_func" elif process == "ggH_sbi": return "ggH_sbi_func" elif process == "qqH_s": return "qqH_s_func" elif process == "qqH_b": return "qqH_b_func" elif process == "qqH_sbi": return "qqH_sbi_func" if process in ["ggH_SM","qqH_SM","WH_SM","ZH_SM"]: return "Zero" if process in ["ggH","ttH"]: print " bin= ",bin if "hww" in bin: if self.RVRFfixed: #if "1j" in bin: #print "1 jet scaling" #return "R1j" #else: return "R" else: return "kgluon_WW" else: if self.RVRFfixed: return "R" else: return "kgluon_ZZ" elif process in ["qqH","WH","ZH","VH"]: if "hww" in bin: if self.RVRFfixed: return "R" else: return "kV_WW" else: if self.RVRFfixed: return "R" else: return "kV_ZZ" else: return 1 def setPhysicsOptions(self,physOptions): for po in physOptions: if po == "GGsmfixed": print "Will fix CMS_zz4l_GGsm to 1 and float muV and muF" self.GGsmfixed = True if po == "RVRFfixed": print "Will fix muV and muF to 1 and float mu" self.RVRFfixed = True if po == "is2l2nu": print "Will make 2l2nu style cards and float muV and muF" self.is2l2nu = True if po == "GGsmRVRFfixed": print "Will fix CMS_zz4l_GGsm to 1 and float mu" self.GGsmfixed = True self.RVRFfixed = True if po == "is2l2nuRVRFfixed": print "Will make 2l2nu style cards and float mu" self.is2l2nu = True self.RVRFfixed = True if po == "is2l2nuGGsmfixed": print "Will make 2l2nu style cards, fix GGsm to 1 and float muV and muF" self.is2l2nu = True self.GGsmfixed = True if po == "is2l2nuGGsmRVRFfixed": print "Will make 2l2nu style cards, fix GGsm to 1 and float mu" self.is2l2nu = True self.RVRFfixed = True self.GGsmfixed = True if po == "useKframework": self.useKframework=True self.GGsmfixed=True if po == "notCustodial": self.notCustodial = True if po == "MHScaleWW" : self.MHScaleWW = True def doParametersOfInterest(self): """Create POI and other parameters, and define the POI set.""" print "self.MHScaleWW = ",self.MHScaleWW self.modelBuilder.doVar("Zero[0.,0.,1.]") self.modelBuilder.out.var("Zero").setVal(0.) self.modelBuilder.out.var("Zero").setConstant(True) self.modelBuilder.doVar("xsr_ggH[1.,0.,2.]") if self.MHScaleWW : print '!!!!!!! Scaling HWW from mH=125.0 GeV to mH=125.6 GeV !!!!!!!!!' self.modelBuilder.out.var("xsr_ggH").setVal(1.035) else: self.modelBuilder.out.var("xsr_ggH").setVal(1.) self.modelBuilder.out.var("xsr_ggH").setConstant(True) self.modelBuilder.doVar("xsr_qqH[1.,0.,2.]") if self.MHScaleWW : self.modelBuilder.out.var("xsr_qqH").setVal(1.041) else: self.modelBuilder.out.var("xsr_qqH").setVal(1.) self.modelBuilder.out.var("xsr_qqH").setConstant(True) #self.SMH = SMHiggsBuilder(self.modelBuilder) #for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) self.modelBuilder.doVar("lambdaWZ[1.,0.,2.]") if self.notCustodial : print "Removing Custodial symmetry" else: self.modelBuilder.out.var("lambdaWZ").setVal(1.0) self.modelBuilder.out.var("lambdaWZ").setConstant(True) if self.is2l2nu: #self.modelBuilder.factory_('sum::c7_Gscal_tot(c7_Gscal_Vectors, c7_Gscal_tau, c7_Gscal_top, c7_Gscal_bottom, c7_Gscal_gluon, c7_Gscal_gamma)') self.modelBuilder.doVar("CMS_widthH_kbkg[1.,0.,2.]") self.modelBuilder.doVar("CMS_widthH_ww_kbkg[1.,0.,2.]") self.modelBuilder.doVar("R[1.,0.,4.]") self.modelBuilder.doVar("R1j[1.,0.,4.]") self.modelBuilder.doVar("kgluon[1.,0.,4.]") self.modelBuilder.doVar("kV[1.,0.,8.]") #self.modelBuilder.doVar("CMS_zz4l_GGsm[1.,0.,30.]") self.modelBuilder.doVar("CMS_zz4l_GGsm[1.,0.,60.]") #self.modelBuilder.doVar("kV[0.0,0.0,1.0]") self.modelBuilder.doVar("ktau[0.0,0.0,2.0]") self.modelBuilder.doVar("ktop[0.0,0.0,4.0]") self.modelBuilder.doVar("kbottom[0.0,0.0,3.0]") #self.modelBuilder.doVar("kgluon[0.0,0.0,2.0]") self.modelBuilder.doVar("kgamma[0.0,0.0,2.5]") #self.modelBuilder.doVar("BRInvUndet[0,0,1]") self.modelBuilder.doVar("CMS_zz4l_scalerK[1.0,0.0,1.0]") self.modelBuilder.doVar("SM_BR_hww[0.0,0.0,1.0]") self.modelBuilder.doVar("SM_BR_hzz[0.0,0.0,1.0]") self.modelBuilder.doVar("SM_BR_htt[0.0,0.0,1.0]") self.modelBuilder.doVar("SM_BR_hmm[0.0,0.0,1.0]") self.modelBuilder.doVar("SM_BR_htoptop[0.0,0.0,1.0]") self.modelBuilder.doVar("SM_BR_hcc[0.0,0.0,1.0]") self.modelBuilder.doVar("SM_BR_hbb[0.0,0.0,1.0]") self.modelBuilder.doVar("SM_BR_hss[0.0,0.0,1.0]") self.modelBuilder.doVar("SM_BR_hgluglu[0.0,0.0,1.0]") self.modelBuilder.doVar("SM_BR_hgg[0.0,0.0,1.0]") self.modelBuilder.doVar("SM_BR_hzg[0.0,0.0,1.0]") self.modelBuilder.factory_('expr::CMS_zz4l_Gscal_Vectors("@0*@0 * (@1+@2)*abs(1-@3)", kV, SM_BR_hzz, SM_BR_hww, CMS_zz4l_scalerK)') self.modelBuilder.factory_('expr::CMS_zz4l_Gscal_tau("@0*@0 * (@1+@2)*abs(1-@3)", ktau, SM_BR_htt, SM_BR_hmm, CMS_zz4l_scalerK)') self.modelBuilder.factory_('expr::CMS_zz4l_Gscal_top("@0*@0 * (@1+@2)*abs(1-@3)", ktop, SM_BR_htoptop, SM_BR_hcc, CMS_zz4l_scalerK)') self.modelBuilder.factory_('expr::CMS_zz4l_Gscal_bottom("@0*@0 * (@1+@2)*abs(1-@3)", kbottom, SM_BR_hbb, SM_BR_hss, CMS_zz4l_scalerK)') self.modelBuilder.factory_('expr::CMS_zz4l_Gscal_gluon("@0*@0 * @1*abs(1-@2)", kgluon, SM_BR_hgluglu, CMS_zz4l_scalerK)') self.modelBuilder.factory_('expr::CMS_zz4l_Gscal_gamma("@0*@0 * (@1+@2)*abs(1-@3)", kgamma, SM_BR_hgg, SM_BR_hzg, CMS_zz4l_scalerK)') self.modelBuilder.factory_('sum::gammaK(CMS_zz4l_Gscal_Vectors, CMS_zz4l_Gscal_tau, CMS_zz4l_Gscal_top, CMS_zz4l_Gscal_bottom, CMS_zz4l_Gscal_gluon, CMS_zz4l_Gscal_gamma, CMS_zz4l_scalerK)') self.SMH = SMHiggsBuilder(self.modelBuilder) for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) if self.useKframework: self.modelBuilder.out.var("CMS_zz4l_scalerK").setVal(0.0) else: self.modelBuilder.out.var("CMS_zz4l_scalerK").setVal(1.0) if not self.is2l2nu: self.modelBuilder.out.var("SM_BR_hww").setVal(0.0) self.modelBuilder.out.var("SM_BR_hww").setConstant(True) self.modelBuilder.out.var("SM_BR_hzz").setVal(0.0) self.modelBuilder.out.var("SM_BR_hzz").setConstant(True) self.modelBuilder.out.var("SM_BR_htt").setVal(0.0) self.modelBuilder.out.var("SM_BR_hmm").setVal(0.0) self.modelBuilder.out.var("SM_BR_htt").setConstant(True) self.modelBuilder.out.var("SM_BR_hmm").setConstant(True) self.modelBuilder.out.var("SM_BR_htoptop").setVal(0.0) self.modelBuilder.out.var("SM_BR_hcc").setVal(0.0) self.modelBuilder.out.var("SM_BR_htoptop").setConstant(True) self.modelBuilder.out.var("SM_BR_hcc").setConstant(True) self.modelBuilder.out.var("SM_BR_hbb").setVal(0.0) self.modelBuilder.out.var("SM_BR_hss").setVal(0.0) self.modelBuilder.out.var("SM_BR_hbb").setConstant(True) self.modelBuilder.out.var("SM_BR_hss").setConstant(True) self.modelBuilder.out.var("SM_BR_hgluglu").setVal(0.0) self.modelBuilder.out.var("SM_BR_hgg").setVal(0.0) self.modelBuilder.out.var("SM_BR_hgluglu").setConstant(True) self.modelBuilder.out.var("SM_BR_hgg").setConstant(True) self.modelBuilder.out.var("SM_BR_hzg").setVal(0.0) self.modelBuilder.out.var("SM_BR_hzg").setConstant(True) self.modelBuilder.out.var("CMS_zz4l_scalerK").setConstant(True) if self.GGsmfixed: self.modelBuilder.out.var("CMS_zz4l_GGsm") self.modelBuilder.out.var("CMS_zz4l_GGsm").setVal(1) self.modelBuilder.out.var("CMS_zz4l_GGsm").setConstant(True) print "Fixing CMS_zz4l_GGsm" if self.RVRFfixed: self.modelBuilder.out.var("kV").setVal(1) self.modelBuilder.out.var("kV").setConstant(True) self.modelBuilder.out.var("kgluon").setVal(1) self.modelBuilder.out.var("kgluon").setConstant(True) poi = "R" else: self.modelBuilder.out.var("R").setVal(1) self.modelBuilder.out.var("R").setConstant(True) poi = "kV,kgluon" else: #self.modelBuilder.out.var("CMS_zz4l_GGsm").setVal(1) #self.modelBuilder.out.var("CMS_zz4l_GGsm").setRange(0.0001,30.0001) self.modelBuilder.out.var("kgluon").setVal(1) self.modelBuilder.out.var("kV").setVal(1) self.modelBuilder.out.var("R").setVal(1) self.modelBuilder.out.var("CMS_widthH_kbkg") self.modelBuilder.out.var("CMS_widthH_kbkg").setVal(1) self.modelBuilder.out.var("CMS_widthH_ww_kbkg") self.modelBuilder.out.var("CMS_widthH_ww_kbkg").setVal(1) if self.RVRFfixed: self.modelBuilder.out.var("R").setRange(0.0,4.0) self.modelBuilder.out.var("kV").setConstant(True) self.modelBuilder.out.var("kgluon").setConstant(True) else: self.modelBuilder.out.var("kV").setRange(0.0,100.0) self.modelBuilder.out.var("kgluon").setRange(0.0,100.0) #self.modelBuilder.out.var("kV").setRange(0.0,8.0) #self.modelBuilder.out.var("kgluon").setRange(0.0,4.0) self.modelBuilder.out.var("R").setConstant(True) poi = "CMS_zz4l_GGsm" self.modelBuilder.factory_("expr::kgluon_WW(\"@0*@1\",kgluon,xsr_ggH)") self.modelBuilder.factory_("expr::kV_WW(\"@0*@1\",kV,xsr_qqH)") self.modelBuilder.factory_("expr::kgluon_ZZ(\"@0*@1\",kgluon,lambdaWZ)") self.modelBuilder.factory_("expr::kV_ZZ(\"@0*@1\",kV,lambdaWZ)") self.modelBuilder.factory_("expr::ggH_s_func(\"@0*@3*@1*@4-sqrt(@0*@3*@1*@4*@2)\",R,CMS_zz4l_GGsm,CMS_widthH_kbkg,kgluon_ZZ,gammaK)") self.modelBuilder.factory_("expr::ggH_b_func(\"@2-sqrt(@0*@3*@1*@4*@2)\",R,CMS_zz4l_GGsm,CMS_widthH_kbkg,kgluon_ZZ,gammaK)") self.modelBuilder.factory_("expr::ggH_sbi_func(\"sqrt(@0*@3*@1*@4*@2)\",R,CMS_zz4l_GGsm,CMS_widthH_kbkg,kgluon_ZZ,gammaK)") self.modelBuilder.factory_("expr::qqH_s_func(\"@0*@2*@1*@3-sqrt(@0*@2*@1*@3)\",R,CMS_zz4l_GGsm,kV_ZZ,gammaK)") self.modelBuilder.factory_("expr::qqH_b_func(\"1-sqrt(@0*@2*@1*@3)\",R,CMS_zz4l_GGsm,kV_ZZ,gammaK)") self.modelBuilder.factory_("expr::qqH_sbi_func(\"sqrt(@0*@2*@1*@3)\",R,CMS_zz4l_GGsm,kV_ZZ,gammaK)") # CMS_widthH_ww_kbkg uncertainty for WW self.modelBuilder.factory_("expr::ggH_s_funcWW(\"@0*@2*@1*@3-sqrt(@0*@2*@1*@3*@4)\",R,CMS_zz4l_GGsm,kgluon_WW,gammaK,CMS_widthH_ww_kbkg)") self.modelBuilder.factory_("expr::ggH_b_funcWW(\"@4-sqrt(@0*@2*@1*@3*@4)\",R,CMS_zz4l_GGsm,kgluon_WW,gammaK,CMS_widthH_ww_kbkg)") self.modelBuilder.factory_("expr::ggH_sbi_funcWW(\"sqrt(@0*@2*@1*@3*@4)\",R,CMS_zz4l_GGsm,kgluon_WW,gammaK,CMS_widthH_ww_kbkg)") self.modelBuilder.factory_("expr::qqH_s_funcWW(\"@0*@2*@1*@3-sqrt(@0*@2*@1*@3)\",R,CMS_zz4l_GGsm,kV_WW,gammaK)") self.modelBuilder.factory_("expr::qqH_b_funcWW(\"1-sqrt(@0*@2*@1*@3)\",R,CMS_zz4l_GGsm,kV_WW,gammaK)") self.modelBuilder.factory_("expr::qqH_sbi_funcWW(\"sqrt(@0*@2*@1*@3)\",R,CMS_zz4l_GGsm,kV_WW,gammaK)") self.modelBuilder.factory_("expr::ggH_s_funcWW_1j(\"@0*@2*@1*@3-sqrt(@0*@2*@1*@3)\",R1j,CMS_zz4l_GGsm,kgluon_WW,gammaK)") self.modelBuilder.factory_("expr::ggH_b_funcWW_1j(\"1-sqrt(@0*@2*@1*@3)\",R1j,CMS_zz4l_GGsm,kgluon_WW,gammaK)") self.modelBuilder.factory_("expr::ggH_sbi_funcWW_1j(\"sqrt(@0*@2*@1*@3)\",R1j,CMS_zz4l_GGsm,kgluon_WW,gammaK)") self.modelBuilder.factory_("expr::qqH_s_funcWW_1j(\"@0*@2*@1*@3-sqrt(@0*@2*@1*@3)\",R1j,CMS_zz4l_GGsm,kV_WW,gammaK)") self.modelBuilder.factory_("expr::qqH_b_funcWW_1j(\"1-sqrt(@0*@2*@1*@3)\",R1j,CMS_zz4l_GGsm,kV_WW,gammaK)") self.modelBuilder.factory_("expr::qqH_sbi_funcWW_1j(\"sqrt(@0*@2*@1*@3)\",R1j,CMS_zz4l_GGsm,kV_WW,gammaK)") self.modelBuilder.doSet("POI",poi)
class LambdaWZHiggs(SMLikeHiggsModel): def __init__(self): SMLikeHiggsModel.__init__(self) self.floatMass = False self.floatKF = True def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema." elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrema for Higgs mass range defined with inverterd order. Second must be larger the first." if po == "fixKF": self.floatKF = False def doParametersOfInterest(self): """Create POI out of signal strength and MH""" self.modelBuilder.doVar("kZ[1,0,2]") if self.floatKF: self.modelBuilder.doVar("kf[1,0,2]") else: self.modelBuilder.doVar("kf[1]") self.modelBuilder.doVar("lambdaWZ[1,0,2]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) self.modelBuilder.doSet("POI",'kZ,lambdaWZ,kf,MH' if self.floatKF else 'kZ,lambdaWZ,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI",'kZ,lambdaWZ,kf' if self.floatKF else 'kZ,lambdaWZ') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): self.decayScaling = { 'hgg':'hgg', 'hzg':'hzg', 'hww':'hww', 'hzz':'hzz', 'hbb':'hff', 'htt':'hff', 'hmm':'hff', 'hcc':'hff', 'hss':'hff', 'hgluglu':'hff', } self.productionScaling = { 'ggH':'kf', 'ttH':'kf', 'WH':'kW', 'ZH':'kZ', } # define kW as lambdaWZ*kZ self.modelBuilder.factory_('expr::kW("@0*@1",kZ, lambdaWZ)') # scalings of the loops self.SMH.makeScaling('hgg', Cb='kf', Ctop='kf', CW='kW', Ctau='kf') self.SMH.makeScaling('hzg', Cb='kf', Ctop='kf', CW='kW', Ctau='kf') self.SMH.makeScaling('qqH', CW='kW', CZ='kZ') # SM BR for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) ## total witdhs, normalized to the SM one self.modelBuilder.factory_('expr::lambdaWZ_Gscal_Z("@0*@0 * @1", kZ, SM_BR_hzz)') self.modelBuilder.factory_('expr::lambdaWZ_Gscal_W("@0*@0 * @1", kW, SM_BR_hww)') self.modelBuilder.factory_('expr::lambdaWZ_Gscal_fermions("@0*@0 * (@1+@2+@3+@4+@5+@6+@7)", kf, SM_BR_hbb, SM_BR_htt, SM_BR_hcc, SM_BR_htoptop, SM_BR_hgluglu, SM_BR_hmm, SM_BR_hss)') self.modelBuilder.factory_('expr::lambdaWZ_Gscal_gg("@0 * @1", Scaling_hgg, SM_BR_hgg)') self.modelBuilder.factory_('expr::lambdaWZ_Gscal_Zg("@0 * @1", Scaling_hzg, SM_BR_hzg)') self.modelBuilder.factory_('sum::lambdaWZ_Gscal_tot(lambdaWZ_Gscal_Z, lambdaWZ_Gscal_W, lambdaWZ_Gscal_fermions, lambdaWZ_Gscal_gg, lambdaWZ_Gscal_Zg)') ## BRs, normalized to the SM ones: they scale as (partial/partial_SM) / (total/total_SM) self.modelBuilder.factory_('expr::lambdaWZ_BRscal_hzz("@0*@0/@1", kZ, lambdaWZ_Gscal_tot)') self.modelBuilder.factory_('expr::lambdaWZ_BRscal_hww("@0*@0/@1", kW, lambdaWZ_Gscal_tot)') self.modelBuilder.factory_('expr::lambdaWZ_BRscal_hff("@0*@0/@1", kf, lambdaWZ_Gscal_tot)') self.modelBuilder.factory_('expr::lambdaWZ_BRscal_hgg("@0/@1", Scaling_hgg, lambdaWZ_Gscal_tot)') self.modelBuilder.factory_('expr::lambdaWZ_BRscal_hzg("@0/@1", Scaling_hzg, lambdaWZ_Gscal_tot)') # verbosity #self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self,production,decay,energy): name = 'lambdaWZ_XSBRscal_%(production)s_%(decay)s' % locals() #Special case that depends on Energy if production == 'qqH': self.productionScaling[production]='Scaling_qqH_'+energy name += '_%(energy)s' % locals() if self.modelBuilder.out.function(name): return name try: BRscal = self.decayScaling[decay] XSscal = self.productionScaling[production] self.modelBuilder.factory_('expr::%s("@0*@0 * @1", %s, lambdaWZ_BRscal_%s)' % (name, XSscal, BRscal)) return name except KeyError: if production == "VH": print "WARNING: You are trying to use a VH production mode in a model that needs WH and ZH separately. "\ "The best I can do is to scale [%(production)s, %(decay)s, %(energy)s] with the decay BR only but this is wrong..." % locals() self.modelBuilder.factory_('expr::%s("1.0*@0", lambdaWZ_BRscal_%s)' % (name, BRscal)) return name raise
class StageZero(STXSBaseModel): "Allow different signal strength fits for the stage-0 model" def __init__(self,denominator="WW"): STXSBaseModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.denominator=denominator self.POIs = "" def doVar(self,x,constant=True): self.modelBuilder.doVar(x) vname = re.sub(r"\[.*","",x) #self.modelBuilder.out.var(vname).setConstant(constant) print "SignalStrengths:: declaring %s as %s" % (vname,x) def doParametersOfInterest(self): """Create POI out of signal strengths (and MH)""" pois = [] allProds = [] for regproc in ALL_STXS_PROCS["Stage0"].keys(): P = ALL_STXS_PROCS["Stage0"][regproc] if P in allProds: continue allProds.append(P) for dec in SM_HIGG_DECAYS: D = CMS_to_LHCHCG_DecSimple[dec] if (D==self.denominator): if (not "mu_XS_%s_x_BR_%s"%(P,self.denominator) in pois): self.modelBuilder.doVar("mu_XS_%s_x_BR_%s[1,0,5]"%(P,self.denominator)) pois.append("mu_XS_%s_x_BR_%s"%(P,self.denominator)) else: if (not "mu_BR_%s_r_BR_%s"%(D,self.denominator) in pois): self.modelBuilder.doVar("mu_BR_%s_r_BR_%s[1,0,5]"%(D,self.denominator)) pois.append("mu_BR_%s_r_BR_%s"%(D,self.denominator)) print pois self.POIs=",".join(pois) self.doMH() print "Default parameters of interest: ", self.POIs self.modelBuilder.doSet("POI",self.POIs) self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): for d in SM_HIGG_DECAYS + [ "hss" ]: self.SMH.makeBR(d) allProds = [] for regproc in ALL_STXS_PROCS["Stage0"].keys(): P = ALL_STXS_PROCS["Stage0"][regproc] if P in allProds: continue allProds.append(P) allDecs = [] for dec in SM_HIGG_DECAYS: D = CMS_to_LHCHCG_DecSimple[dec] if (D in allDecs): continue allDecs.append(D) if (D==self.denominator): muXSBR = "mu_XS_%s_x_BR_%s"%(P,self.denominator) self.modelBuilder.factory_('expr::scaling_'+P+'_'+D+'_13TeV("@0",'+muXSBR+')') else: muXSBR = "mu_XS_%s_x_BR_%s"%(P,self.denominator) muBR = "mu_BR_%s_r_BR_%s"%(D,self.denominator) decDen = CMS_to_LHCHCG_DecSimple.keys()[CMS_to_LHCHCG_DecSimple.values().index(self.denominator)] #self.modelBuilder.factory_('expr::scaling_'+P+'_'+D+'_13TeV("@0*@1*@2/@3",'+muXSBR+','+muBR+',SM_BR_'+dec+',SM_BR_'+decDen+')') self.modelBuilder.factory_('expr::scaling_'+P+'_'+D+'_13TeV("@0*@1",'+muXSBR+','+muBR+')') def getHiggsSignalYieldScale(self,production,decay,energy): for regproc in ALL_STXS_PROCS["Stage0"].keys(): if fnmatch.fnmatch(production, regproc): return "scaling_%s_%s_%s" % (ALL_STXS_PROCS["Stage0"][regproc],decay,energy) #raise RuntimeError, "No production process matching %s for Stage0 found !"%production print "WARNING: No production process matching %s for Stage0 found, will scale by 1 !"%production return 1
class FermiophobicHiggs(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__( self ) # not using 'super(x,self).__init__' since I don't understand it self.mHRange = ['115', '135'] # default def setPhysicsOptions(self, physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.mHRange = po.replace("higgsMassRange=", "").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema" elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first" def doParametersOfInterest(self): """Create POI out of signal strength and MH""" # --- Signal Strength as only POI --- self.modelBuilder.doVar("r[1,0,20]") if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]), float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0], self.mHRange[1])) self.modelBuilder.doSet("POI", 'r,MH') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): ## Add FP BRs datadir = os.environ[ 'CMSSW_BASE'] + '/src/HiggsAnalysis/CombinedLimit/data/lhc-hxswg' self.SMH.textToSpline('FP_BR_hww', os.path.join(datadir, 'fp/BR.txt'), ycol=4) self.SMH.textToSpline('FP_BR_hzz', os.path.join(datadir, 'fp/BR.txt'), ycol=5) self.SMH.textToSpline('FP_BR_hgg', os.path.join(datadir, 'fp/BR.txt'), ycol=2) self.SMH.textToSpline('FP_BR_hzg', os.path.join(datadir, 'fp/BR.txt'), ycol=3) for decay in ['hww', 'hzz', 'hgg', 'hzg']: self.SMH.makeBR(decay) self.modelBuilder.factory_( 'expr::FP_BRScal_%s("@0*@1/@2",r,FP_BR_%s,SM_BR_%s)' % (decay, decay, decay)) self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self, production, decay, energy): if production not in ['VH', 'WH', 'ZH', 'qqH']: return 0 if decay not in ['hww', 'hzz', 'hgg', 'hzg']: return 0 return 'FP_BRScal_%s' % decay
class CvCfHiggs(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False self.cVRange = ['0','2'] self.cFRange = ['-2','2'] def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema." elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrema for Higgs mass range defined with inverterd order. Second must be larger the first." if po.startswith("cVRange="): self.cVRange = po.replace("cVRange=","").split(":") if len(self.cVRange) != 2: raise RuntimeError, "cV signal strength range requires minimal and maximal value" elif float(self.cVRange[0]) >= float(self.cVRange[1]): raise RuntimeError, "minimal and maximal range swapped. Second value must be larger first one" if po.startswith("cFRange="): self.cFRange = po.replace("cFRange=","").split(":") if len(self.cFRange) != 2: raise RuntimeError, "cF signal strength range requires minimal and maximal value" elif float(self.cFRange[0]) >= float(self.cFRange[1]): raise RuntimeError, "minimal and maximal range swapped. Second value must be larger first one" def doParametersOfInterest(self): """Create POI out of signal strength and MH""" # --- Signal Strength as only POI --- self.modelBuilder.doVar("CV[1,%s,%s]" % (self.cVRange[0], self.cVRange[1])) self.modelBuilder.doVar("CF[1,%s,%s]" % (self.cFRange[0], self.cFRange[1])) if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) self.modelBuilder.doSet("POI",'CV,CF,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI",'CV,CF') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): self.decayScaling = { 'hgg':'hgg', 'hzg':'hzg', 'hww':'hvv', 'hzz':'hvv', 'hbb':'hff', 'htt':'hff', } self.productionScaling = { 'ggH':'CF', 'ttH':'CF', 'qqH':'CV', 'WH':'CV', 'ZH':'CV', 'VH':'CV', } self.SMH.makeScaling('hgg', Cb='CF', Ctop='CF', CW='CV', Ctau='CF') self.SMH.makeScaling('hzg', Cb='CF', Ctop='CF', CW='CV', Ctau='CF') # Ideas for a cleaner future # self.SMH.makeScaling('hww', 'CV*CV') -> Scaling_hww("@0*@0",CV) # self.SMH.makeScaling('total', hbb='CF*CF', htoptop='CF*CF', hww='CV*CV', hzz='CV', hgg='Scaling_hgg', hgluglu='Scaling_hgluglu' ) ## partial widths, normalized to the SM one, for decays scaling with F, V and total for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) self.modelBuilder.factory_('expr::CvCf_Gscal_sumf("@0*@0 * (@1+@2+@3+@4+@5+@6+@7)", CF, SM_BR_hbb, SM_BR_htt, SM_BR_hcc, SM_BR_htoptop, SM_BR_hgluglu, SM_BR_hmm, SM_BR_hss)') self.modelBuilder.factory_('expr::CvCf_Gscal_sumv("@0*@0 * (@1+@2)", CV, SM_BR_hww, SM_BR_hzz)') self.modelBuilder.factory_('expr::CvCf_Gscal_gg("@0 * @1", Scaling_hgg, SM_BR_hgg)') self.modelBuilder.factory_('expr::CvCf_Gscal_Zg("@0 * @1", Scaling_hzg, SM_BR_hzg)') self.modelBuilder.factory_('sum::CvCf_Gscal_tot(CvCf_Gscal_sumf, CvCf_Gscal_sumv, CvCf_Gscal_gg, CvCf_Gscal_Zg)') ## BRs, normalized to the SM ones: they scale as (coupling/coupling_SM)^2 / (totWidth/totWidthSM)^2 self.modelBuilder.factory_('expr::CvCf_BRscal_hgg("@0/@1", Scaling_hgg, CvCf_Gscal_tot)') self.modelBuilder.factory_('expr::CvCf_BRscal_hzg("@0/@1", Scaling_hzg, CvCf_Gscal_tot)') self.modelBuilder.factory_('expr::CvCf_BRscal_hff("@0*@0/@1", CF, CvCf_Gscal_tot)') self.modelBuilder.factory_('expr::CvCf_BRscal_hvv("@0*@0/@1", CV, CvCf_Gscal_tot)') self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self,production,decay,energy): name = "CvCf_XSBRscal_%s_%s" % (production,decay) if self.modelBuilder.out.function(name): return name XSscal = self.productionScaling[production] BRscal = self.decayScaling[decay] self.modelBuilder.factory_('expr::%s("@0*@0 * @1", %s, CvCf_BRscal_%s)' % (name, XSscal, BRscal)) return name
class InvisibleWidth(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__( self ) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False def setPhysicsOptions(self, physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=", "").split(",") print("The Higgs mass range:", self.mHRange) if len(self.mHRange) != 2: raise RuntimeError( "Higgs mass range definition requires two extrema") elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError( "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first" ) def doParametersOfInterest(self): """Create POI out of signal strength and MH""" self.modelBuilder.doVar("kV[1,0.0,1.1]") # bounded to 1 self.modelBuilder.doVar("ktau[1,0.0,4.0]") self.modelBuilder.doVar("ktop[1,0.0,5.0]") self.modelBuilder.doVar("kbottom[1,0.0,4.0]") self.modelBuilder.doVar("kgluon[1,0.0,3.0]") self.modelBuilder.doVar("kgamma[1,0.0,3.0]") self.modelBuilder.doVar("BRInvUndet[0,0,1]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange( float(self.mHRange[0]), float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0], self.mHRange[1])) self.modelBuilder.doSet( "POI", "kV,ktau,ktop,kbottom,kgluon,kgamma,BRInvUndet,MH") else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet( "POI", "kV,ktau,ktop,kbottom,kgluon,kgamma,BRInvUndet") self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): # SM BR for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) ## total witdhs, normalized to the SM one self.modelBuilder.factory_( 'expr::invisibleWidth_Gscal_Vectors("@0*@0 * (@1+@2)", kV, SM_BR_hzz, SM_BR_hww)' ) self.modelBuilder.factory_( 'expr::invisibleWidth_Gscal_tau("@0*@0 * (@1+@2)", ktau, SM_BR_htt, SM_BR_hmm)' ) self.modelBuilder.factory_( 'expr::invisibleWidth_Gscal_top("@0*@0 * (@1+@2)", ktop, SM_BR_htoptop, SM_BR_hcc)' ) self.modelBuilder.factory_( 'expr::invisibleWidth_Gscal_bottom("@0*@0 * (@1+@2)", kbottom, SM_BR_hbb, SM_BR_hss)' ) self.modelBuilder.factory_( 'expr::invisibleWidth_Gscal_gluon("@0*@0 * @1", kgluon, SM_BR_hgluglu)' ) self.modelBuilder.factory_( 'expr::invisibleWidth_Gscal_gamma("@0*@0 * (@1+@2)", kgamma, SM_BR_hgg, SM_BR_hzg)' ) # self.modelBuilder.factory_('sum::invisibleWidth_Gscal_tot(invisibleWidth_Gscal_Vectors, invisibleWidth_Gscal_tau, invisibleWidth_Gscal_top, invisibleWidth_Gscal_bottom, invisibleWidth_Gscal_gluon, invisibleWidth_Gscal_gamma)') self.modelBuilder.factory_( 'expr::invisibleWidth_Gscal_tot("(@1+@2+@3+@4+@5+@6)/(1-@0)",BRInvUndet,invisibleWidth_Gscal_Vectors, invisibleWidth_Gscal_tau, invisibleWidth_Gscal_top, invisibleWidth_Gscal_bottom, invisibleWidth_Gscal_gluon, invisibleWidth_Gscal_gamma)' ) ## BRs, normalized to the SM ones: they scale as (partial/partial_SM)^2 / (total/total_SM)^2 self.modelBuilder.factory_( 'expr::invisibleWidth_BRscal_hvv("@0*@0/@1", kV, invisibleWidth_Gscal_tot)' ) self.modelBuilder.factory_( 'expr::invisibleWidth_BRscal_htt("@0*@0/@1", ktau, invisibleWidth_Gscal_tot)' ) self.modelBuilder.factory_( 'expr::invisibleWidth_BRscal_hbb("@0*@0/@1", kbottom, invisibleWidth_Gscal_tot)' ) self.modelBuilder.factory_( 'expr::invisibleWidth_BRscal_hgg("@0*@0/@1", kgamma, invisibleWidth_Gscal_tot)' ) def getHiggsSignalYieldScale(self, production, decay, energy): name = "invisibleWidth_XSBRscal_%s_%s" % (production, decay) print(name, production, decay, energy) if self.modelBuilder.out.function(name) == None: XSscal = "kgluon" if production in ["WH", "ZH", "VH", "qqH"]: XSscal = "kV" if production == "ttH": XSscal = "ktop" if decay == "hinv": self.modelBuilder.factory_( 'expr::%s("@0*@0 * @1", %s, BRInvUndet)' % (name, XSscal)) else: if decay in ["hbb", "htt", "hgg"]: BRscal = decay elif decay in ["hww", "hzz"]: BRscal = "hvv" else: print("Unknown decay mode:", decay) self.modelBuilder.factory_( 'expr::%s("@0*@0 * @1", %s, invisibleWidth_BRscal_%s)' % (name, XSscal, BRscal)) return name
class C5udHiggs(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False self.universalCF = False self.fix = [] def setPhysicsOptions(self,physOptions): for po in physOptions: if po == "universalCF": universalCF = True if po.startswith("fix="): self.fix = po.replace("fix=","").split(",") if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema" elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first" def doParametersOfInterest(self): """Create POI out of signal strength and MH""" # --- Signal Strength as only POI --- self.modelBuilder.doVar("Cg[1,0,10]") self.modelBuilder.doVar("Cv[1,0,10]") self.modelBuilder.doVar("Cglu[1,0,10]") POI = "Cg,Cv,Cglu" if self.universalCF: self.modelBuilder.doVar("Cf[1,0,10]") POI += ",Cf" else: self.modelBuilder.doVar("Cu[1,0,10]") self.modelBuilder.doVar("Cd[1,0,10]") POI += ",Cu,Cd" if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) POI += ",MH" else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) for F in self.fix: self.modelBuilder.out.var(F).setConstant(True) if F+"," in POI: POI = POI.replace(F+",", "") else: POI = POI.replace(","+F, "") self.modelBuilder.doSet("POI",POI) self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hZg", "hmm", "hss" ]: self.SMH.makeBR(d) ## total witdhs, normalized to the SM one self.modelBuilder.factory_('expr::C5ud_Gscal_sumglu("@0*@0 * @1", Cglu, SM_BR_hgluglu)') self.modelBuilder.factory_('expr::C5ud_Gscal_sumg("@0*@0 * @1", Cg, SM_BR_hgg)') self.modelBuilder.factory_('expr::C5ud_Gscal_sumv("@0*@0 * (@1+@2+@3)", Cv, SM_BR_hww, SM_BR_hzz, SM_BR_hZg )') if self.universalCF: self.modelBuilder.factory_('expr::C5ud_Gscal_sumf("@0*@0 * (@1+@2+@3+@4+@5+@6)",\ Cf, SM_BR_hbb, SM_BR_htt, SM_BR_hcc, SM_BR_htoptop, SM_BR_hmm, SM_BR_hss)') else: self.modelBuilder.factory_('expr::C5ud_Gscal_sumf("@0*@0 * (@1+@2+@3+@4) + @5*@5 * (@6+@7)",\ Cd, SM_BR_hbb, SM_BR_hcc, SM_BR_htt, SM_BR_hmm,\ Cu, SM_BR_htoptop, SM_BR_hss)') self.modelBuilder.factory_('sum::C5ud_Gscal_tot(C5ud_Gscal_sumglu, C5ud_Gscal_sumg, C5ud_Gscal_sumv, C5ud_Gscal_sumf)') ## BRs, normalized to the SM ones: they scale as (partial/partial_SM)^2 / (total/total_SM)^2 self.modelBuilder.factory_("expr::C5ud_BRscal_hgg(\"@0*@0/@1\", Cg, C5ud_Gscal_tot)") self.modelBuilder.factory_("expr::C5ud_BRscal_hvv(\"@0*@0/@1\", Cv, C5ud_Gscal_tot)") if self.universalCF: self.modelBuilder.factory_("expr::C5ud_BRscal_hff(\"@0*@0/@1\", Cf, C5ud_Gscal_tot)") else: self.modelBuilder.factory_("expr::C5ud_BRscal_hbb(\"@0*@0/@1\", Cd, C5ud_Gscal_tot)") self.modelBuilder.factory_("expr::C5ud_BRscal_htt(\"@0*@0/@1\", Cd, C5ud_Gscal_tot)") def getHiggsSignalYieldScale(self,production,decay,energy): name = "C5ud_XSBRscal_%s_%s" % (production,decay) if self.modelBuilder.out.function(name) == None: XSscal = "Cglu" if production in ["ggH"] else "Cv" if production in ['ttH']: XSscal = 'Cf' if self.universalCF else 'Cu' BRscal = "hgg" if decay in ["hww", "hzz"]: BRscal = "hvv" if decay in ["hbb", "htt"]: BRscal = ("hff" if self.universalCF else decay) self.modelBuilder.factory_('expr::%s("@0*@0 * @1", %s, C5ud_BRscal_%s)' % (name, XSscal, BRscal)) return name
class LambdalqHiggs(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__( self ) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False def setPhysicsOptions(self, physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=", "").split(",") print("The Higgs mass range:", self.mHRange) if len(self.mHRange) != 2: raise RuntimeError( "Higgs mass range definition requires two extrema") elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError( "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first" ) def doParametersOfInterest(self): """Create POI out of signal strength and MH""" self.modelBuilder.doVar("kV[1,0,2]") self.modelBuilder.doVar("lambdalq[1,-3,3]") self.modelBuilder.doVar("kq[1,0,2]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange( float(self.mHRange[0]), float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0], self.mHRange[1])) self.modelBuilder.doSet("POI", "kV,lambdalq,kq,MH") else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI", "kV,lambdalq,kq") self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): self.decayScaling = { "hgg": "hgg", "hzg": "hzg", "hww": "hvv", "hzz": "hvv", "hbb": "hqq", "htt": "hll", "hmm": "hll", "hss": "hqq", "hcc": "hqq", "hgluglu": "hqq", } self.productionScaling = { "ggH": "kq", "ttH": "kq", "qqH": "kV", "WH": "kV", "ZH": "kV", "VH": "kV" } # define kd as lambdalq*kq self.modelBuilder.factory_('expr::kl("@0*@1",kq, lambdalq)') # scalings of the loops self.SMH.makeScaling("hgg", Cb="kq", Ctop="kq", CW="kV", Ctau="kl") self.SMH.makeScaling("hzg", Cb="kq", Ctop="kq", CW="kV", Ctau="kl") # SM BR for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) ## total witdhs, normalized to the SM one self.modelBuilder.factory_( 'expr::lambdalq_Gscal_Vectors("@0*@0 * (@1+@2)", kV, SM_BR_hzz, SM_BR_hww)' ) self.modelBuilder.factory_( 'expr::lambdalq_Gscal_quarks("@0*@0 * (@1+@2+@3+@4+@5)", kq, SM_BR_hcc, SM_BR_hbb, SM_BR_htoptop, SM_BR_hss, SM_BR_hgluglu)' ) self.modelBuilder.factory_( 'expr::lambdalq_Gscal_leptons("@0*@0 * (@1+@2)", kl, SM_BR_htt, SM_BR_hmm)' ) self.modelBuilder.factory_( 'expr::lambdalq_Gscal_gg("@0 * @1", Scaling_hgg, SM_BR_hgg)') self.modelBuilder.factory_( 'expr::lambdalq_Gscal_Zg("@0 * @1", Scaling_hzg, SM_BR_hzg)') self.modelBuilder.factory_( "sum::lambdalq_Gscal_tot(lambdalq_Gscal_Vectors, lambdalq_Gscal_quarks, lambdalq_Gscal_leptons, lambdalq_Gscal_gg, lambdalq_Gscal_Zg)" ) ## BRs, normalized to the SM ones: they scale as (partial/partial_SM)^2 / (total/total_SM)^2 self.modelBuilder.factory_( 'expr::lambdalq_BRscal_hvv("@0*@0/@1", kV, lambdalq_Gscal_tot)') self.modelBuilder.factory_( 'expr::lambdalq_BRscal_hqq("@0*@0/@1", kq, lambdalq_Gscal_tot)') self.modelBuilder.factory_( 'expr::lambdalq_BRscal_hll("@0*@0/@1", kl, lambdalq_Gscal_tot)') self.modelBuilder.factory_( 'expr::lambdalq_BRscal_hgg("@0/@1", Scaling_hgg, lambdalq_Gscal_tot)' ) self.modelBuilder.factory_( 'expr::lambdalq_BRscal_hzg("@0/@1", Scaling_hzg, lambdalq_Gscal_tot)' ) # verbosity # self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self, production, decay, energy): name = "lambdalq_XSBRscal_%(production)s_%(decay)s" % locals() if self.modelBuilder.out.function(name): return name XSscal = self.productionScaling[production] BRscal = self.decayScaling[decay] self.modelBuilder.factory_( 'expr::%s("@0*@0 * @1", %s, lambdalq_BRscal_%s)' % (name, XSscal, BRscal)) return name
class HiggsLoops(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__( self ) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False self.doHZg = False def setPhysicsOptions(self, physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=", "").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema" elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first" if po == 'doHZg': self.doHZg = True def doParametersOfInterest(self): """Create POI out of signal strength and MH""" self.modelBuilder.doVar("kgluon[1,0,2]") self.modelBuilder.doVar("kgamma[1,0,3]") myPOIs = ['kgluon', 'kgamma'] if self.doHZg: self.modelBuilder.doVar("kZgamma[1,0,10]") myPOIs.append('kZgamma') if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange( float(self.mHRange[0]), float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0], self.mHRange[1])) myPOIs.append('MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet('POI', ','.join(myPOIs)) self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): self.decayScaling = { 'hgg': 'hgg', 'hzg': 'hxx', 'hww': 'hxx', 'hzz': 'hxx', 'hbb': 'hxx', 'htt': 'hxx', 'hmm': 'hxx', } if self.doHZg: self.decayScaling['hzg'] = 'hzg' # SM BR for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) ## total witdh, normalized to the SM one if self.doHZg: self.modelBuilder.factory_( 'sum::loopGluonGamma_Gscal_OtherDecays(SM_BR_hbb, SM_BR_htt, SM_BR_hmm, SM_BR_hss, SM_BR_hzz, SM_BR_hww, SM_BR_hcc, SM_BR_htoptop)' ) self.modelBuilder.factory_( 'expr::loopGluonGamma_Gscal_Zg("@0*@0* @1", kZgamma, SM_BR_hzg)' ) else: self.modelBuilder.factory_( 'sum::loopGluonGamma_Gscal_OtherDecays(SM_BR_hbb, SM_BR_htt, SM_BR_hmm, SM_BR_hss, SM_BR_hzz, SM_BR_hww, SM_BR_hcc, SM_BR_htoptop, SM_BR_hzg)' ) self.modelBuilder.factory_( 'expr::loopGluonGamma_Gscal_gg("@0*@0* @1", kgamma, SM_BR_hgg)') self.modelBuilder.factory_( 'expr::loopGluonGamma_Gscal_gluglu("@0*@0* @1", kgluon, SM_BR_hgluglu)' ) if self.doHZg: self.modelBuilder.factory_( 'sum::loopGluonGamma_Gscal_tot(loopGluonGamma_Gscal_OtherDecays, loopGluonGamma_Gscal_gg, loopGluonGamma_Gscal_Zg, loopGluonGamma_Gscal_gluglu)' ) else: self.modelBuilder.factory_( 'sum::loopGluonGamma_Gscal_tot(loopGluonGamma_Gscal_OtherDecays, loopGluonGamma_Gscal_gg, loopGluonGamma_Gscal_gluglu)' ) ## BRs, normalized to the SM ones: they scale as (partial/partial_SM)^2 / (total/total_SM)^2 self.modelBuilder.factory_( 'expr::loopGluonGamma_BRscal_hxx("1.0/@0",loopGluonGamma_Gscal_tot)' ) self.modelBuilder.factory_( 'expr::loopGluonGamma_BRscal_hgg("@0*@0/@1", kgamma, loopGluonGamma_Gscal_tot)' ) if self.doHZg: self.modelBuilder.factory_( 'expr::loopGluonGamma_BRscal_hzg("@0*@0/@1", kZgamma, loopGluonGamma_Gscal_tot)' ) # verbosity #self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self, production, decay, energy): name = "loopGluonGamma_XSBRscal_%s_%s" % (production, decay) if self.modelBuilder.out.function(name): return name BRscal = self.decayScaling[decay] if production == "ggH": self.modelBuilder.factory_( 'expr::%s("@0*@0 * @1", kgluon, loopGluonGamma_BRscal_%s)' % (name, BRscal)) else: self.modelBuilder.factory_( 'expr::%s("1.0 * @0", loopGluonGamma_BRscal_%s)' % (name, BRscal)) return name
class LambdaduHiggs(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__( self ) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False def setPhysicsOptions(self, physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=", "").split(",") print("The Higgs mass range:", self.mHRange) if len(self.mHRange) != 2: raise RuntimeError( "Higgs mass range definition requires two extrema") elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError( "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first" ) def doParametersOfInterest(self): """Create POI out of signal strength and MH""" self.modelBuilder.doVar("kV[1,0,2]") self.modelBuilder.doVar("lambdadu[1,-3,3]") self.modelBuilder.doVar("ku[1,0,2]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange( float(self.mHRange[0]), float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0], self.mHRange[1])) self.modelBuilder.doSet("POI", "kV,lambdadu,ku,MH") else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI", "kV,lambdadu,ku") self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): self.decayScaling = { "hgg": "hgg", "hzg": "hzg", "hww": "hvv", "hzz": "hvv", "hbb": "hdd", "htt": "hdd", "hss": "hdd", "hmm": "hdd", "hcc": "huu", "hgluglu": "hgluglu", } self.productionScaling = { "ttH": "ku", "qqH": "kV", "WH": "kV", "ZH": "kV", "VH": "kV" } # define kd as lambdadu*ku self.modelBuilder.factory_('expr::kd("@0*@1",ku, lambdadu)') # scalings of the loops self.SMH.makeScaling("ggH", Cb="kd", Ctop="ku") self.SMH.makeScaling("hgg", Cb="kd", Ctop="ku", CW="kV", Ctau="kd") self.SMH.makeScaling("hzg", Cb="kd", Ctop="ku", CW="kV", Ctau="kd") self.SMH.makeScaling("hgluglu", Cb="kd", Ctop="ku") # SM BR for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss" ]: self.SMH.makeBR(d) ## total witdhs, normalized to the SM one self.modelBuilder.factory_( 'expr::lambdadu_Gscal_Vectors("@0*@0 * (@1+@2)", kV, SM_BR_hzz, SM_BR_hww)' ) self.modelBuilder.factory_( 'expr::lambdadu_Gscal_up("@0*@0 * (@1+@2)", ku, SM_BR_hcc, SM_BR_htoptop)' ) self.modelBuilder.factory_( 'expr::lambdadu_Gscal_down("@0*@0 * (@1+@2+@3+@4)", kd, SM_BR_hbb, SM_BR_htt, SM_BR_hmm, SM_BR_hss)' ) self.modelBuilder.factory_( 'expr::lambdadu_Gscal_gg("@0 * @1", Scaling_hgg, SM_BR_hgg)') self.modelBuilder.factory_( 'expr::lambdadu_Gscal_Zg("@0 * @1", Scaling_hzg, SM_BR_hzg)') self.modelBuilder.factory_( 'expr::lambdadu_Gscal_gluglu("@0 * @1", Scaling_hgluglu, SM_BR_hgluglu)' ) self.modelBuilder.factory_( "sum::lambdadu_Gscal_tot(lambdadu_Gscal_Vectors, lambdadu_Gscal_up, lambdadu_Gscal_down, lambdadu_Gscal_gg, lambdadu_Gscal_Zg, lambdadu_Gscal_gluglu)" ) ## BRs, normalized to the SM ones: they scale as (partial/partial_SM)^2 / (total/total_SM)^2 self.modelBuilder.factory_( 'expr::lambdadu_BRscal_hvv("@0*@0/@1", kV, lambdadu_Gscal_tot)') self.modelBuilder.factory_( 'expr::lambdadu_BRscal_huu("@0*@0/@1", ku, lambdadu_Gscal_tot)') self.modelBuilder.factory_( 'expr::lambdadu_BRscal_hdd("@0*@0/@1", kd, lambdadu_Gscal_tot)') self.modelBuilder.factory_( 'expr::lambdadu_BRscal_hgg("@0/@1", Scaling_hgg, lambdadu_Gscal_tot)' ) self.modelBuilder.factory_( 'expr::lambdadu_BRscal_hgluglu("@0/@1", Scaling_hgluglu, lambdadu_Gscal_tot)' ) self.modelBuilder.factory_( 'expr::lambdadu_BRscal_hzg("@0/@1", Scaling_hzg, lambdadu_Gscal_tot)' ) # verbosity # self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self, production, decay, energy): name = "lambdadu_XSBRscal_%(production)s_%(decay)s" % locals() # Special case that depends on Energy if production == "ggH": self.productionScaling[production] = "Scaling_ggH_" + energy name += "_%(energy)s" % locals() if self.modelBuilder.out.function(name): return name XSscal = self.productionScaling[production] BRscal = self.decayScaling[decay] if "Scaling_" in XSscal: # it's a Scaling, which means it's already squared self.modelBuilder.factory_( 'expr::%s("@0 * @1", %s, lambdadu_BRscal_%s)' % (name, XSscal, BRscal)) else: # It's a kappa, so it's linear and I must square it self.modelBuilder.factory_( 'expr::%s("@0*@0 * @1", %s, lambdadu_BRscal_%s)' % (name, XSscal, BRscal)) return name
class CvCfHiggs(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False def setPhysicsOptions(self, physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=", "").split(",") print("The Higgs mass range:", self.mHRange) if len(self.mHRange) != 2: raise RuntimeError("Higgs mass range definition requires two extrema.") elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError( "Extrema for Higgs mass range defined with inverterd order. Second must be larger the first." ) def doParametersOfInterest(self): """Create POI out of signal strength and MH""" # --- Signal Strength as only POI --- self.modelBuilder.doVar("CV[1,0.0,1.5]") self.modelBuilder.doVar("CF[1,-2,2]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]), float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0], self.mHRange[1])) self.modelBuilder.doSet("POI", "CV,CF,MH") else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI", "CV,CF") self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): ## Coefficient for couplings to photons # arXiv 1202.3144v2, below eq. 2.6: 2/9*cF - 1.04*cV, and then normalize to SM # FIXME: this should be replaced with the proper MH dependency # self.modelBuilder.factory_("expr::CvCf_cgamma(\"-0.271*@0+1.27*@1\",CF,CV)") ######################################################################### ## Coefficient for coupling to di-photons # Based on Eq 1--4 of Nuclear Physics B 453 (1995)17-82 # ignoring b quark contributions # Taylor series around MH=125 including terms up to O(MH-125)^2 in Horner polynomial form CF = self.modelBuilder.out.function("CF") CF.setVal(1.0) self.modelBuilder.factory_( 'expr::CvCf_cgammaSq("\ @0*@0*(1.524292518396496 + (0.005166702799572456 - 0.00003355715038472727*@2)*@2) + \ @1*(@1*(0.07244520735564258 + (0.0008318872718720393 - 6.16997610275555e-6*@2)*@2) + \ @0*(-0.5967377257521194 + (-0.005998590071444782 + 0.00003972712648748393*@2)*@2))\ ",CV,CF,MH)' ) ## partial witdhs, normalized to the SM one, for decays scaling with F, V and total for d in ["htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hzg", "hmm", "hss"]: self.SMH.makeBR(d) self.modelBuilder.factory_( 'expr::CvCf_Gscal_sumf("@0*@0 * (@1+@2+@3+@4+@5+@6+@7)", CF, SM_BR_hbb, SM_BR_htt, SM_BR_hcc, SM_BR_htoptop, SM_BR_hgluglu, SM_BR_hmm, SM_BR_hss)' ) self.modelBuilder.factory_('expr::CvCf_Gscal_sumv("@0*@0 * (@1+@2+@3)", CV, SM_BR_hww, SM_BR_hzz, SM_BR_hzg)') self.modelBuilder.factory_('expr::CvCf_Gscal_gg("@0 * @1", CvCf_cgammaSq, SM_BR_hgg)') self.modelBuilder.factory_("sum::CvCf_Gscal_tot(CvCf_Gscal_sumf, CvCf_Gscal_sumv, CvCf_Gscal_gg)") ## BRs, normalized to the SM ones: they scale as (coupling/coupling_SM)^2 / (totWidth/totWidthSM)^2 self.modelBuilder.factory_('expr::CvCf_BRscal_hgg("@0/@1", CvCf_cgammaSq, CvCf_Gscal_tot)') self.modelBuilder.factory_('expr::CvCf_BRscal_hf("@0*@0/@1", CF, CvCf_Gscal_tot)') self.modelBuilder.factory_('expr::CvCf_BRscal_hv("@0*@0/@1", CV, CvCf_Gscal_tot)') # self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self, production, decay, energy): name = "CvCf_XSBRscal_%s_%s" % (production, decay) if self.modelBuilder.out.function(name) == None: XSscal = "CF" if production in ["ggH", "ttH"] else "CV" BRscal = "hgg" if decay in ["hww", "hzz"]: BRscal = "hv" if decay in ["hbb", "htt"]: BRscal = "hf" self.modelBuilder.factory_('expr::%s("@0*@0 * @1", %s, CvCf_BRscal_%s)' % (name, XSscal, BRscal)) return name
class HHModel(PhysicsModel): """ Models the HH production as linear sum of 6 components (VBF) and 3 components (GGF) """ #scaleBR=True to scale for branching ratio dependence #setBR1 to overwrite the single Higgs decay mode and one of the double Higgs decay modes #setBR2 to overwrite the second decay mode of double Higgs def __init__(self, ggf_sample_list, vbf_sample_list, name, setBR1="", setBR2=""): PhysicsModel.__init__(self) self.name = name self.check_validity_ggf(ggf_sample_list) self.check_validity_vbf(vbf_sample_list) self.ggf_formula = GGFHHFormula(ggf_sample_list) self.vbf_formula = VBFHHFormula(vbf_sample_list) self.setBR1 = setBR1 self.setBR2 = setBR2 self.scaleBR = True # include branching ratio uncertainties in the systematics # if only one single HH channel is considered, it is suggested to # include the specific BR uncertainty(s) directly in the datacard. # This should be re-evaluated for a HH combination self.doBRU = False self.dump_inputs() self.f_r_singleH_names = [] def setPhysicsOptions(self, physOptions): for po in physOptions: if po.startswith("BRU="): self.doBRU = (po.replace("BRU=", "") in ["yes", "1", "Yes", "True", "true"]) if po.startswith("scaleBR="): self.scaleBR = (po.replace("BRU=", "") in ["no", "0", "No", "False", "false"]) print "BR uncertainties in partial widths: %s " % self.doBRU def check_validity_ggf(self, ggf_sample_list): if len(ggf_sample_list) != 3: raise RuntimeError( "%s : malformed GGF input sample list - expect 3 samples" % self.name) if not isinstance(ggf_sample_list, list) and not isinstance( ggf_sample_list, tuple): raise RuntimeError( "%s : malformed GGF input sample list - expect list or tuple" % self.name) for s in ggf_sample_list: if not isinstance(s, GGFHHSample): raise RuntimeError( "%s : malformed GGF input sample list - each element must be a GGFHHSample" % self.name) def check_validity_vbf(self, vbf_sample_list): if len(vbf_sample_list) != 6: raise RuntimeError( "%s : malformed VBF input sample list - expect 6 samples" % self.name) if not isinstance(vbf_sample_list, list) and not isinstance( vbf_sample_list, tuple): raise RuntimeError( "%s : malformed VBF input sample list - expect list or tuple" % self.name) for s in vbf_sample_list: if not isinstance(s, VBFHHSample): raise RuntimeError( "%s : malformed VBF input sample list - each element must be a VBFHHSample" % self.name) def dump_inputs(self): print "[INFO] HH model : ", self.name print "...... GGF configuration" for i, s in enumerate(self.ggf_formula.sample_list): print " {0:<3} ... kl : {1:<3}, kt : {2:<3}, xs : {3:<3.8f} pb, label : {4}".format( i, s.val_kl, s.val_kt, s.val_xs, s.label) print "...... VBF configuration" for i, s in enumerate(self.vbf_formula.sample_list): print " {0:<3} ... CV : {1:<3}, C2V : {2:<3}, kl : {3:<3}, xs : {4:<3.8f} pb, label : {5}".format( i, s.val_CV, s.val_C2V, s.val_kl, s.val_xs, s.label) def doParametersOfInterest(self): ## the model is built with: ## r x [GGF + VBF] ## GGF = r_GGF x [sum samples(kl, kt)] ## VBF = r_VBF x [sum samples(kl, CV, C2V)] POIs = "r,r_gghh,r_qqhh,CV,C2V,kl,kt" self.modelBuilder.doVar("r[1,0,10]") self.modelBuilder.doVar("r_gghh[1,0,10]") self.modelBuilder.doVar("r_qqhh[1,0,10]") self.modelBuilder.doVar("CV[1,-10,10]") self.modelBuilder.doVar("C2V[1,-10,10]") self.modelBuilder.doVar("kl[1,-30,30]") self.modelBuilder.doVar("kt[1,-10,10]") self.modelBuilder.doSet("POI", POIs) self.SMH = SMHiggsBuilder(self.modelBuilder) self.modelBuilder.out.var("r_gghh").setConstant(True) self.modelBuilder.out.var("r_qqhh").setConstant(True) self.modelBuilder.out.var("CV").setConstant(True) self.modelBuilder.out.var("C2V").setConstant(True) self.modelBuilder.out.var("kl").setConstant(True) self.modelBuilder.out.var("kt").setConstant(True) #I need to build MH variables because the BR are tabulated as a function of MH # the mass setting must be provided as input, i.e. '-m 125' if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.create_scalings() def create_scalings(self): """ create the functions that scale the six components of vbf and the 3 components of ggf """ ###################################################################### #create Higgs BR scalings for d in SM_HIGG_DECAYS + ["hss"]: self.SMH.makeBR(d) # BR uncertainties if self.doBRU: self.SMH.makePartialWidthUncertainties() else: for d in SM_HIGG_DECAYS: self.modelBuilder.factory_( 'HiggsDecayWidth_UncertaintyScaling_%s[1.0]' % d) # fix to have all BRs add up to unity self.modelBuilder.factory_("sum::c7_SMBRs(%s)" % (",".join( "SM_BR_" + X for X in "hzz hww htt hmm hcc hbb hss hgluglu hgg hzg".split()))) self.modelBuilder.out.function("c7_SMBRs").Print("") # get VBF, tHq, tHW, ggZH cross section and resolved loops self.SMH.makeScaling('qqH', CW='CV', CZ='CV') self.SMH.makeScaling("tHq", CW='CV', Ctop="kt") self.SMH.makeScaling("tHW", CW='CV', Ctop="kt") self.SMH.makeScaling("ggZH", CZ='CV', Ctop="kt", Cb="1") self.SMH.makeScaling('ggH', Cb='1', Ctop='kt', Cc="1") self.SMH.makeScaling('hgluglu', Cb='1', Ctop='kt') self.SMH.makeScaling('hgg', Cb='1', Ctop='kt', CW='CV', Ctau='1') self.SMH.makeScaling('hzg', Cb='1', Ctop='kt', CW='CV', Ctau='1') cGammap = { "hgg": 0.49e-2, "hzz": 0.83e-2, "hww": 0.73e-2, "hgluglu": 0.66e-2, "htt": 0, "hbb": 0, "hcc": 0, "hmm": 0 } # First we need to create the terms that account for the self-coupling --> Just scale partial width first - https://arxiv.org/abs/1709.08649 Eq 22. # probably a better way to code this since the partial width expressions are being repeated when we write the BR for dec in cGammap.keys(): valC1 = cGammap[dec] self.modelBuilder.factory_('expr::kl_scalBR_%s("(@0-1)*%g",kl)' % (dec, valC1)) # next make the partial widths, also including the kappas -> we want to include the term from the normal kappas and the one from the self-coupling self.modelBuilder.factory_( 'expr::kVktkl_Gscal_Z("(@0*@0+@3)*@1*@2", CV, SM_BR_hzz, HiggsDecayWidth_UncertaintyScaling_hzz, kl_scalBR_hzz)' ) self.modelBuilder.factory_( 'expr::kVktkl_Gscal_W("(@0*@0+@3)*@1*@2", CV, SM_BR_hww, HiggsDecayWidth_UncertaintyScaling_hww, kl_scalBR_hww)' ) self.modelBuilder.factory_( 'expr::kVktkl_Gscal_tau("(1+@4)*@0*@2 + (1+@5)*@1*@3", SM_BR_htt, SM_BR_hmm, HiggsDecayWidth_UncertaintyScaling_htt, HiggsDecayWidth_UncertaintyScaling_hmm,kl_scalBR_htt, kl_scalBR_hmm)' ) self.modelBuilder.factory_( 'expr::kVktkl_Gscal_top("(1+@2)*@0*@1", SM_BR_hcc, HiggsDecayWidth_UncertaintyScaling_hcc, kl_scalBR_hcc)' ) self.modelBuilder.factory_( 'expr::kVktkl_Gscal_bottom("(1+@3) * (@0*@2+@1)", SM_BR_hbb, SM_BR_hss, HiggsDecayWidth_UncertaintyScaling_hbb, kl_scalBR_hbb)' ) self.modelBuilder.factory_( 'expr::kVktkl_Gscal_gluon(" (@0+@3) * @1 * @2", Scaling_hgluglu, SM_BR_hgluglu, HiggsDecayWidth_UncertaintyScaling_hgluglu, kl_scalBR_hgluglu)' ) self.modelBuilder.factory_( 'expr::kVktkl_Gscal_gamma("(@0+@6)*@1*@4 + @2*@3*@5", Scaling_hgg, SM_BR_hgg, Scaling_hzg, SM_BR_hzg, HiggsDecayWidth_UncertaintyScaling_hgg, HiggsDecayWidth_UncertaintyScaling_hzg, kl_scalBR_hgg)' ) # no kl dependance on H->zg known yet ? # fix to have all BRs add up to unity self.modelBuilder.factory_("sum::kVktkl_SMBRs(%s)" % (",".join( "SM_BR_" + X for X in "hzz hww htt hmm hcc hbb hss hgluglu hgg hzg".split()))) self.modelBuilder.out.function("kVktkl_SMBRs").Print("") ## total witdh, normalized to the SM one (just the sum over the partial widths/SM total BR) self.modelBuilder.factory_( 'expr::kVktkl_Gscal_tot("(@0+@1+@2+@3+@4+@5+@6)/@7", kVktkl_Gscal_Z, kVktkl_Gscal_W, kVktkl_Gscal_tau, kVktkl_Gscal_top, kVktkl_Gscal_bottom, kVktkl_Gscal_gluon, kVktkl_Gscal_gamma, kVktkl_SMBRs)' ) ## BRs, normalized to the SM ones: they scale as (partial/partial_SM) / (total/total_SM) self.modelBuilder.factory_( 'expr::kVktkl_BRscal_hww("(@0*@0+@3)*@2/@1", CV, kVktkl_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hww, kl_scalBR_hww)' ) self.modelBuilder.factory_( 'expr::kVktkl_BRscal_hzz("(@0*@0+@3)*@2/@1", CV, kVktkl_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hzz, kl_scalBR_hzz)' ) self.modelBuilder.factory_( 'expr::kVktkl_BRscal_htt("(1+@2)*@1/@0", kVktkl_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_htt, kl_scalBR_htt)' ) self.modelBuilder.factory_( 'expr::kVktkl_BRscal_hmm("(1+@2)*@1/@0", kVktkl_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hmm, kl_scalBR_hmm)' ) self.modelBuilder.factory_( 'expr::kVktkl_BRscal_hbb("(1+@2)*@1/@0", kVktkl_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hbb, kl_scalBR_hbb)' ) self.modelBuilder.factory_( 'expr::kVktkl_BRscal_hcc("(1+@2)*@1/@0", kVktkl_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hcc, kl_scalBR_hcc)' ) self.modelBuilder.factory_( 'expr::kVktkl_BRscal_hgg("(@0+@3)*@2/@1", Scaling_hgg, kVktkl_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hgg,kl_scalBR_hgg)' ) self.modelBuilder.factory_( 'expr::kVktkl_BRscal_hzg("@0*@2/@1", Scaling_hzg, kVktkl_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hzg)' ) self.modelBuilder.factory_( 'expr::kVktkl_BRscal_hgluglu("(@0+@3)*@2/@1", Scaling_hgluglu, kVktkl_Gscal_tot, HiggsDecayWidth_UncertaintyScaling_hgluglu, kl_scalBR_hgluglu)' ) ###################################################################### #create single Higgs production scalings energy = "13TeV" cXSmap_13 = { "ggH": 0.66e-2, "qqH": 0.64e-2, "WH": 1.03e-2, "ZH": 1.19e-2, "ttH": 3.51e-2, "VH": (0.5 * (1.03e-2 + 1.19e-2)) } EWKmap_13 = { "ggH": 1.049, "qqH": 0.932, "WH": 0.93, "ZH": 0.947, "ttH": 1.014, "VH": (0.5 * (0.93 + 0.947)) } dZH = -1.536e-3 for production in SM_HIGG_PROD: if production in ["ggZH", "tHq", "tHW"]: self.f_r_singleH_names.append("Scaling_%s_%s" % (production, energy)) elif production in ["ggH", "qqH"]: EWK = EWKmap_13[production] self.modelBuilder.factory_("expr::kVktkl_XSscal_%s_%s(\"(@1+(@0-1)*%g/%g)/((1-(@0*@0-1)*%g))\",kl,Scaling_%s_%s)"\ %(production,energy,cXSmap_13[production],EWK,dZH,production,energy)) self.f_r_singleH_names.append("kVktkl_XSscal_%s_%s" % (production, energy)) elif production in ["ZH", "WH", "VH"]: EWK = EWKmap_13[production] self.modelBuilder.factory_("expr::kVktkl_XSscal_%s_%s(\"(@1*@1+(@0-1)*%g/%g)/((1-(@0*@0-1)*%g))\",kl,CV)"\ %(production,energy,cXSmap_13[production],EWK,dZH)) self.f_r_singleH_names.append("kVktkl_XSscal_%s_%s" % (production, energy)) elif production == "ttH": EWK = EWKmap_13[production] self.modelBuilder.factory_("expr::kVktkl_XSscal_%s_%s(\"(@1*@1+(@0-1)*%g/%g)/((1-(@0*@0-1)*%g))\",kl,kt)"\ %(production,energy,cXSmap_13[production],EWK,dZH)) self.f_r_singleH_names.append("kVktkl_XSscal_%s_%s" % (production, energy)) self.f_r_vbf_names = [ ] # the RooFormulae that scale the components (VBF) self.f_r_ggf_names = [ ] # the RooFormulae that scale the components (GGF) def pow_to_mul_string(expr): """ Convert integer powers in an expression to Muls, like a**2 => a*a. Returns a string """ pows = list(expr.atoms(Pow)) if any(not e.is_Integer for b, e in (i.as_base_exp() for i in pows)): raise ValueError("A power contains a non-integer exponent") s = str(expr) repl = zip(pows, (Mul(*[b] * e, evaluate=False) for b, e in (i.as_base_exp() for i in pows))) for fr, to in repl: s = s.replace(str(fr), str(to)) return s ### loop on the GGF scalings for i, s in enumerate(self.ggf_formula.sample_list): f_name = 'f_ggfhhscale_sample_{0}'.format(i) f_expr = self.ggf_formula.coeffs[ i] # the function that multiplies each sample # print f_expr # for ROOFit, this will convert expressions as a**2 to a*a s_expr = pow_to_mul_string(f_expr) couplings_in_expr = [] if 'kl' in s_expr: couplings_in_expr.append('kl') if 'kt' in s_expr: couplings_in_expr.append('kt') # no constant expressions are expected if len(couplings_in_expr) == 0: raise RuntimeError( 'GGF HH : scaling expression has no coefficients') for idx, ce in enumerate(couplings_in_expr): # print '..replacing', ce symb = '@{}'.format(idx) s_expr = s_expr.replace(ce, symb) arglist = ','.join(couplings_in_expr) exprname = 'expr::{}(\"{}\" , {})'.format(f_name, s_expr, arglist) # print exprname self.modelBuilder.factory_( exprname) # the function that scales each VBF sample f_prod_name_pmode = f_name + '_r_gghh' prodname_pmode = 'prod::{}(r_gghh,{})'.format( f_prod_name_pmode, f_name) self.modelBuilder.factory_( prodname_pmode ) ## the function that scales this production mode # self.modelBuilder.out.function(f_prod_name).Print("") ## will just print out the values f_prod_name = f_prod_name_pmode + '_r' prodname = 'prod::{}(r,{})'.format(f_prod_name, f_prod_name_pmode) self.modelBuilder.factory_( prodname) ## the function that scales this production mode # self.modelBuilder.out.function(f_prod_name).Print("") ## will just print out the values self.f_r_ggf_names.append( f_prod_name) #bookkeep the scaling that has been created ### loop on the VBF scalings for i, s in enumerate(self.vbf_formula.sample_list): f_name = 'f_vbfhhscale_sample_{0}'.format(i) f_expr = self.vbf_formula.coeffs[ i] # the function that multiplies each sample # print f_expr # for ROOFit, this will convert expressions as a**2 to a*a s_expr = pow_to_mul_string(f_expr) couplings_in_expr = [] if 'CV' in s_expr: couplings_in_expr.append('CV') if 'C2V' in s_expr: couplings_in_expr.append('C2V') if 'kl' in s_expr: couplings_in_expr.append('kl') # no constant expressions are expected if len(couplings_in_expr) == 0: raise RuntimeError( 'VBF HH : scaling expression has no coefficients') for idx, ce in enumerate(couplings_in_expr): # print '..replacing', ce symb = '@{}'.format(idx) s_expr = s_expr.replace(ce, symb) arglist = ','.join(couplings_in_expr) exprname = 'expr::{}(\"{}\" , {})'.format(f_name, s_expr, arglist) # print exprname self.modelBuilder.factory_( exprname) # the function that scales each VBF sample f_prod_name_pmode = f_name + '_r_qqhh' prodname_pmode = 'prod::{}(r_qqhh,{})'.format( f_prod_name_pmode, f_name) self.modelBuilder.factory_( prodname_pmode ) ## the function that scales this production mode # self.modelBuilder.out.function(f_prod_name_pmode).Print("") ## will just print out the values f_prod_name = f_prod_name_pmode + '_r' prodname = 'prod::{}(r,{})'.format(f_prod_name, f_prod_name_pmode) self.modelBuilder.factory_( prodname) ## the function that scales this production mode # self.modelBuilder.out.function(f_prod_name).Print("") ## will just print out the values self.f_r_vbf_names.append( f_prod_name) #bookkeep the scaling that has been created def getYieldScale(self, bin, process): if not self.DC.isSignal[process]: return 1 processSource = process.split("_")[0] # It might happen that I use a different process naming than the default one # In that case I will convert it to the default naming if not processSource in processSource_dict: for defaultname, equivalentnames in processSource_dict.items(): for equivalentname in equivalentnames: if processSource == equivalentname: print "[WARNING]: process name \"%s\" is not the default name but I found it equivalent to \"%s\"" % ( processSource, defaultname) print " --> if this is not the case fix the naming!" processSource = defaultname decaySource = [] if self.setBR1 != "": decaySource.append(self.setBR1) else: decaySource.append(process.split("_")[-1]) #in case of HH I have to consider an additional Higgs decay if processSource == "ggHH" or processSource == "qqHH": if self.setBR2 != "": decaySource.append(self.setBR2) else: decaySource.append(process.split("_")[-2]) if not (processSource == "ggHH" or processSource == "qqHH"): if (processSource == "bbH"): return 1 #neglect bbH dependence on kl for XS_scaling_name in self.f_r_singleH_names: if processSource in XS_scaling_name: if not self.modelBuilder.out.function("kVktkl_BRscal_" + decaySource[0]): raise RuntimeError, "Decay mode %s not supported" % decaySource[ 0] if not self.scaleBR: return XS_scaling_name else: BR_scaling_name = "kVktkl_BRscal_" + decaySource[0] XSBR_scaling_name = "kVktkl_XSBRscal_%s_%s" % ( processSource, decaySource[0]) if not self.modelBuilder.out.function( XSBR_scaling_name): self.modelBuilder.factory_( "expr::%s(\"0.+@0*(@0>0.)*@1\",%s,%s)" % (XSBR_scaling_name, XS_scaling_name, BR_scaling_name) ) #I used a trick to avoid negative XS reweights return XSBR_scaling_name #if I am here I have a double H process or an unsopported process ## my control to verify for a unique association between process <-> scaling function try: self.scalingMap except AttributeError: self.scalingMap = {} # match the process name in the datacard to the input sample of the calculation # this is the only point where the two things must be matched if not process in self.scalingMap: self.scalingMap[process] = [] imatched_ggf = [] imatched_vbf = [] for isample, sample in enumerate(self.ggf_formula.sample_list): if process.startswith(sample.label): # print self.name, ": {:>40} ===> {:>40}".format(process, sample.label) imatched_ggf.append(isample) for isample, sample in enumerate(self.vbf_formula.sample_list): if process.startswith(sample.label): # print self.name, ": {:>40} ===> {:>40}".format(process, sample.label) imatched_vbf.append(isample) ## this checks that a process finds a unique scaling if len(imatched_ggf) + len(imatched_vbf) != 1: print "[ERROR] : in HH model named", self.name, "there are", len( imatched_ggf), "GGF name matches and", len( imatched_vbf), "VBF name matches" raise RuntimeError( 'HHModel : could not uniquely match the process %s to the expected sample list' % process) if len(imatched_ggf) == 1: isample = imatched_ggf[0] self.scalingMap[process].append((isample, 'GGF')) XS_scaling_name = self.f_r_ggf_names[isample] if not self.scaleBR: return XS_scaling_name else: BR1_scaling_name = "kVktkl_BRscal_" + decaySource[0] BR2_scaling_name = "kVktkl_BRscal_" + decaySource[1] if not self.modelBuilder.out.function(BR1_scaling_name): raise RuntimeError, "Decay mode %s not supported" % BR1_scaling_name if not self.modelBuilder.out.function(BR2_scaling_name): raise RuntimeError, "Decay mode %s not supported" % BR2_scaling_name XSBR_scaling_name = "%s_%s_%s" % ( XS_scaling_name, decaySource[0], decaySource[1]) if not self.modelBuilder.out.function(XSBR_scaling_name): self.modelBuilder.factory_( 'expr::%s("@0*@1*@2",%s,%s,%s)' % (XSBR_scaling_name, XS_scaling_name, BR1_scaling_name, BR2_scaling_name)) return XSBR_scaling_name if len(imatched_vbf) == 1: isample = imatched_vbf[0] self.scalingMap[process].append((isample, 'VBF')) XS_scaling_name = self.f_r_vbf_names[isample] if not self.scaleBR: return XS_scaling_name else: BR1_scaling_name = "kVktkl_BRscal_" + decaySource[0] BR2_scaling_name = "kVktkl_BRscal_" + decaySource[1] if not self.modelBuilder.out.function(BR1_scaling_name): raise RuntimeError, "Decay mode %s not supported" % BR1_scaling_name if not self.modelBuilder.out.function(BR2_scaling_name): raise RuntimeError, "Decay mode %s not supported" % BR2_scaling_name XSBR_scaling_name = "%s_%s_%s" % ( XS_scaling_name, decaySource[0], decaySource[1]) if not self.modelBuilder.out.function(XSBR_scaling_name): self.modelBuilder.factory_( 'expr::%s("@0*@1*@2",%s,%s,%s)' % (XSBR_scaling_name, XS_scaling_name, BR1_scaling_name, BR2_scaling_name)) return XSBR_scaling_name raise RuntimeError( 'HHModel : fatal error in getYieldScale - this should never happen' ) def done(self): ## this checks that a scaling has been attached to a unique process scalings = {} for k, i in self.scalingMap.items( ): ## key -> process, item -> [(isample, 'type')] samples = list(set(i)) # remove duplicates for s in samples: if not s in scalings: scalings[s] = [] scalings[s].append(k) for key, val in scalings.items(): if len(val) > 1: print "[WARNING] : in HH model named", self.name, "there is a double assignment of a scaling : ", key, " ==> ", val #raise RuntimeError('HHModel : coudl not uniquely match the scaling to the process') ## now check that, if a VBF/GGF scaling exists, there are actually 6/3 samples in the card n_VBF = 0 n_GGF = 0 for k, i in self.scalingMap.items(): # the step above ensured me that the list contains a single element -> i[0] if i[0][1] == "GGF": n_GGF += 1 elif i[0][1] == "VBF": n_VBF += 1 else: raise RuntimeError( "HHModel : unrecognised type %s - should never happen" % i[0][1]) if n_GGF > 0 and n_GGF < 3: raise RuntimeError( "HHModel : you did not pass all the 3 samples needed to build the GGF HH model" ) if n_VBF > 0 and n_VBF < 6: raise RuntimeError( "HHModel : you did not pass all the 6 samples needed to build the VBF HH model" )
class HiggsLoopsInvisible(SMLikeHiggsModel): "assume the SM coupling but let the Higgs mass to float" def __init__(self): SMLikeHiggsModel.__init__(self) # not using 'super(x,self).__init__' since I don't understand it self.floatMass = False def setPhysicsOptions(self,physOptions): for po in physOptions: if po.startswith("higgsMassRange="): self.floatMass = True self.mHRange = po.replace("higgsMassRange=","").split(",") print 'The Higgs mass range:', self.mHRange if len(self.mHRange) != 2: raise RuntimeError, "Higgs mass range definition requires two extrema" elif float(self.mHRange[0]) >= float(self.mHRange[1]): raise RuntimeError, "Extrama for Higgs mass range defined with inverterd order. Second must be larger the first" def doParametersOfInterest(self): """Create POI out of signal strength and MH""" self.modelBuilder.doVar("kgluon[1,0,2]") self.modelBuilder.doVar("kgamma[1,0,3]") self.modelBuilder.doVar("BRInvUndet[0,0,1]") if self.floatMass: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setRange(float(self.mHRange[0]),float(self.mHRange[1])) self.modelBuilder.out.var("MH").setConstant(False) else: self.modelBuilder.doVar("MH[%s,%s]" % (self.mHRange[0],self.mHRange[1])) self.modelBuilder.doSet("POI",'kgluon,kgamma,BRInvUndet,MH') else: if self.modelBuilder.out.var("MH"): self.modelBuilder.out.var("MH").setVal(self.options.mass) self.modelBuilder.out.var("MH").setConstant(True) else: self.modelBuilder.doVar("MH[%g]" % self.options.mass) self.modelBuilder.doSet("POI",'kgluon,kgamma,BRInvUndet') self.SMH = SMHiggsBuilder(self.modelBuilder) self.setup() def setup(self): self.decayScaling = { 'hgg':'hgg', 'hZg':'hxx', 'hww':'hxx', 'hzz':'hxx', 'hbb':'hxx', 'htt':'hxx', } # SM BR for d in [ "htt", "hbb", "hcc", "hww", "hzz", "hgluglu", "htoptop", "hgg", "hZg", "hmm", "hss" ]: self.SMH.makeBR(d) ## total witdh, normalized to the SM one self.modelBuilder.factory_('sum::loopGluonGamma_Gscal_OtherDecays(SM_BR_hbb, SM_BR_htt, SM_BR_hmm, SM_BR_hss, SM_BR_hzz, SM_BR_hww, SM_BR_hcc, SM_BR_htoptop, SM_BR_hZg)') self.modelBuilder.factory_('expr::loopGluonGamma_Gscal_gg("@0*@0* @1", kgamma, SM_BR_hgg)') self.modelBuilder.factory_('expr::loopGluonGamma_Gscal_gluglu("@0*@0* @1", kgluon, SM_BR_hgluglu)') self.modelBuilder.factory_('expr::loopGluonGamma_Gscal_tot("(@1+@2+@3)/(1.0-@0)", BRInvUndet, loopGluonGamma_Gscal_OtherDecays, loopGluonGamma_Gscal_gg, loopGluonGamma_Gscal_gluglu)') ## BRs, normalized to the SM ones: they scale as (partial/partial_SM)^2 / (total/total_SM)^2 self.modelBuilder.factory_('expr::loopGluonGamma_BRscal_hxx("1.0/@0",loopGluonGamma_Gscal_tot)') self.modelBuilder.factory_('expr::loopGluonGamma_BRscal_hgg("@0*@0/@1", kgamma, loopGluonGamma_Gscal_tot)') # verbosity #self.modelBuilder.out.Print() def getHiggsSignalYieldScale(self,production,decay,energy): name = "loopGluonGamma_XSBRscal_%s_%s" % (production,decay) if self.modelBuilder.out.function(name): return name BRscal = self.decayScaling[decay] if production == "ggH": self.modelBuilder.factory_('expr::%s("@0*@0 * @1", kgluon, loopGluonGamma_BRscal_%s)' % (name, BRscal)) else: self.modelBuilder.factory_('expr::%s("1.0 * @0", loopGluonGamma_BRscal_%s)' % (name, BRscal)) return name
SMH = SMHiggsBuilder(MB) widthUncertainties = {} widthUncertaintiesKeys = [] for line in open(SMH.brpath + "/WidthUncertainties_126GeV.txt"): if widthUncertaintiesKeys == []: widthUncertaintiesKeys = line.split()[1:] else: fields = line.split() widthUncertainties[fields[0]] = dict( [(k, 0.01 * float(v)) for (k, v) in zip(widthUncertaintiesKeys, fields[1:])] ) BRs = {} for d in SM_HIGGS_DECAYS: SMH.makeBR(d) BRs[d] = MB.out.function("SM_BR_" + d).getVal() THU_GROUPS = [ ("hvv", ["hww", "hzz"]), ("hqq", ["hbb", "hcc", "hss"]), ("hll", ["htt", "hmm"]), ("hgg", ["hgg"]), ("hzg", ["hzg"]), ("hgluglu", ["hgluglu"]), ] uncertainties = [] for s in widthUncertaintiesKeys[:-1]: key = "HiggsDecayWidth_" + s val = {}