示例#1
0
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)

        self.SMH.makeScaling("tHq", CW='kV', Ctop="ktop")
        self.SMH.makeScaling("tHW", CW='kV', Ctop="ktop")

        ## 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"
            if production in ["tHq", "tHW"]:
                XSscal = "Scaling_%s_%s" % (production, energy)
            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 "Scaling" in XSscal:  # already squared, just put XSscal
                self.modelBuilder.factory_(
                    'expr::%s("@0 * @1", %s, c6_BRscal_%s)' %
                    (name, XSscal, BRscal))
            else:  # plain coupling, put (XSscal)^2
                self.modelBuilder.factory_(
                    'expr::%s("@0*@0 * @1", %s, c6_BRscal_%s)' %
                    (name, XSscal, BRscal))

        return name
示例#2
0
class PartialWidthsModel(SMLikeHiggsModel):
    "As in ATL-PHYS-PUB-2012-004"

    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("r_WZ[1,0.0,1.0]")  # bounded to 1
        self.modelBuilder.doVar("r_gZ[1,0.0,2.0]")
        self.modelBuilder.doVar("r_tZ[1,0.0,4.0]")
        self.modelBuilder.doVar("r_bZ[1,0.0,4.0]")
        self.modelBuilder.doVar("r_mZ[1,0.0,4.0]")
        self.modelBuilder.doVar("r_topglu[1,0.0,4.0]")
        self.modelBuilder.doVar("r_Zglu[1,0.0,4.0]")
        self.modelBuilder.doVar("c_gluZ[1,0.0,3.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", 'r_WZ,r_gZ,r_tZ,r_bZ,r_mZ,r_topglu,r_Zglu,c_gluZ,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", 'r_WZ,r_gZ,r_tZ,r_bZ,r_mZ,r_topglu,r_Zglu,c_gluZ')
        self.SMH = SMHiggsBuilder(self.modelBuilder)
        self.setup()

    def setup(self):
        self.modelBuilder.doVar("PW_one[1]")

        self.modelBuilder.factory_("prod::sr_WZ(r_WZ,r_WZ)")
        self.modelBuilder.factory_("prod::sr_bZ(r_bZ,r_bZ)")
        self.modelBuilder.factory_("prod::sr_tZ(r_tZ,r_tZ)")
        self.modelBuilder.factory_("prod::sr_mZ(r_mZ,r_mZ)")
        self.modelBuilder.factory_("prod::sr_gZ(r_gZ,r_gZ)")
        self.modelBuilder.factory_("prod::sr_Zglu(r_Zglu,r_Zglu)")
        self.modelBuilder.factory_("prod::sr_topglu(r_topglu,r_topglu)")
        self.modelBuilder.factory_("prod::sc_gluZ(c_gluZ,c_gluZ)")

        self.modelBuilder.factory_("prod::PW_XSscal_WH(sr_Zglu,sr_WZ)")
        #self.modelBuilder.factory_("expr::PW_lambdaWZ(\"sqrt(@0)\",sr_WZ)")
        #self.SMH.makeScaling("qqH", CW='PW_lambdaWZ', CZ="PW_one")
        self.SMH.makeScaling("qqH", CW='r_WZ', CZ="PW_one")
        self.modelBuilder.factory_(
            "prod::PW_XSscal_qqH_7TeV(Scaling_qqH_7TeV,sr_Zglu)")
        self.modelBuilder.factory_(
            "prod::PW_XSscal_qqH_8TeV(Scaling_qqH_8TeV,sr_Zglu)")
        self.decayScales_ = {
            'hzz': 'PW_one',
            'hww': 'sr_WZ',
            'hbb': 'sr_bZ',
            'htt': 'sr_tZ',
            'hmm': 'sr_mZ',
            'hgg': 'sr_gZ',
            'hss': 'sr_bZ',
            'hcc': 'PW_one',  #
            'hgluglu': 'PW_one',  #
            'hzg': 'PW_one',  #
        }
        self.prodScales_ = {
            'ggH': 'PW_one',
            'qqH': 'PW_XSscal_qqH',
            'WH': 'PW_XSscal_WH',
            'ZH': 'sr_Zglu',
            'ttH': 'sr_topglu',
        }

    def getHiggsSignalYieldScale(self, production, decay, energy):
        name = "c7_XSBRscal_%s_%s" % (production, decay)
        if production == 'qqH': name += "_%s" % energy
        if self.modelBuilder.out.function(name):
            return name

        dscale = self.decayScales_[decay]
        pscale = self.prodScales_[production]
        if production == "qqH": pscale += "_%s" % energy
        print '[LOFullParametrization::PartialWidthModel]: ', name, production, decay, energy, pscale, dscale
        self.modelBuilder.factory_("prod::%s(%s,sc_gluZ,%s)" %
                                   (name, dscale, pscale))
        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
示例#4
0
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 PartialWidthsModel(SMLikeHiggsModel):
    "As in ATL-PHYS-PUB-2012-004"
    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("r_WZ[1,0.0,1.0]") # bounded to 1
        self.modelBuilder.doVar("r_gZ[1,0.0,2.0]")
        self.modelBuilder.doVar("r_tZ[1,0.0,4.0]")
        self.modelBuilder.doVar("r_bZ[1,0.0,4.0]")
        self.modelBuilder.doVar("r_mZ[1,0.0,4.0]")
        self.modelBuilder.doVar("r_topglu[1,0.0,4.0]")
        self.modelBuilder.doVar("r_Zglu[1,0.0,4.0]")
        self.modelBuilder.doVar("c_gluZ[1,0.0,3.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",'r_WZ,r_gZ,r_tZ,r_bZ,r_mZ,r_topglu,r_Zglu,c_gluZ,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",'r_WZ,r_gZ,r_tZ,r_bZ,r_mZ,r_topglu,r_Zglu,c_gluZ')
        self.SMH = SMHiggsBuilder(self.modelBuilder)
        self.setup()
    def setup(self):
        self.modelBuilder.doVar("PW_one[1]")

	self.modelBuilder.factory_("prod::sr_WZ(r_WZ,r_WZ)")
	self.modelBuilder.factory_("prod::sr_bZ(r_bZ,r_bZ)")
	self.modelBuilder.factory_("prod::sr_tZ(r_tZ,r_tZ)")
	self.modelBuilder.factory_("prod::sr_mZ(r_mZ,r_mZ)")
	self.modelBuilder.factory_("prod::sr_gZ(r_gZ,r_gZ)")
	self.modelBuilder.factory_("prod::sr_Zglu(r_Zglu,r_Zglu)")
	self.modelBuilder.factory_("prod::sr_topglu(r_topglu,r_topglu)")
	self.modelBuilder.factory_("prod::sc_gluZ(c_gluZ,c_gluZ)")

        self.modelBuilder.factory_("prod::PW_XSscal_WH(sr_Zglu,sr_WZ)")
        #self.modelBuilder.factory_("expr::PW_lambdaWZ(\"sqrt(@0)\",sr_WZ)")
        #self.SMH.makeScaling("qqH", CW='PW_lambdaWZ', CZ="PW_one")
        self.SMH.makeScaling("qqH", CW='r_WZ', CZ="PW_one")
        self.modelBuilder.factory_("prod::PW_XSscal_qqH_7TeV(Scaling_qqH_7TeV,sr_Zglu)")
        self.modelBuilder.factory_("prod::PW_XSscal_qqH_8TeV(Scaling_qqH_8TeV,sr_Zglu)")
        self.decayScales_ = {
            'hzz' : 'PW_one',
            'hww' : 'sr_WZ',
            'hbb' : 'sr_bZ',
            'htt' : 'sr_tZ',
            'hmm' : 'sr_mZ',
            'hgg' : 'sr_gZ',
	    'hss' : 'sr_bZ',
	    'hcc' : 'PW_one',   #
            'hgluglu' : 'PW_one', #
	    'hzg' : 'PW_one', #
        }
        self.prodScales_ = {
            'ggH' : 'PW_one',
            'qqH' : 'PW_XSscal_qqH',
            'WH'  : 'PW_XSscal_WH',
            'ZH'  : 'sr_Zglu',
            'ttH' : 'sr_topglu',
        }
    def getHiggsSignalYieldScale(self,production,decay,energy):
        name = "c7_XSBRscal_%s_%s" % (production,decay)
        if production == 'qqH': name += "_%s" % energy
        if self.modelBuilder.out.function(name):
            return name

        dscale = self.decayScales_[decay]
        pscale = self.prodScales_[production]
        if production == "qqH": pscale += "_%s" % energy
        print '[LOFullParametrization::PartialWidthModel]: ', name, production, decay, energy, pscale, dscale
        self.modelBuilder.factory_("prod::%s(%s,sc_gluZ,%s)" % (name, dscale, pscale))
        return name
示例#6
0
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 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
示例#8
0
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 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 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
示例#12
0
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 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)

        self.SMH.makeScaling("tHq", CW='kV', Ctop="ktop")
        self.SMH.makeScaling("tHW", CW='kV', Ctop="ktop")

        ## 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"
            if production in [ "tHq", "tHW" ]: XSscal = "Scaling_%s_%s" % (production, energy)
            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 "Scaling" in XSscal: # already squared, just put XSscal
                self.modelBuilder.factory_('expr::%s("@0 * @1", %s, c6_BRscal_%s)' % (name, XSscal, BRscal))
            else: # plain coupling, put (XSscal)^2
                self.modelBuilder.factory_('expr::%s("@0*@0 * @1", %s, c6_BRscal_%s)' % (name, XSscal, BRscal))
    
        return name
示例#14
0
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
示例#15
0
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
示例#16
0
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
示例#17
0
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 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
示例#19
0
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
示例#20
0
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
示例#21
0
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"
            )
示例#22
0
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 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