Пример #1
0
    def testreweightFactorFor(self):

        n1 = mssm.n1.copy()
        n1.totalwidth = 0. * GeV
        st1 = mssm.st1.copy()
        st1.totalwidth = 1e-13 * GeV
        F_prompt = 0.3228249017964917
        Fdisp = 0.6771750982035083
        gluino = mssm.gluino.copy()
        gluino.totalwidth = 1. * 10**(-30) * GeV
        t = SMparticles.t

        branch1 = Branch()
        branch1.oddParticles = [n1]
        branch2 = Branch()
        branch2.oddParticles = [gluino]
        el1 = Element([branch1, branch2])
        f = reweightFactorFor(el1, 'prompt')
        self.assertAlmostEqual(f, 1., places=3)
        f = reweightFactorFor(el1, 'displaced')
        self.assertAlmostEqual(f, 0., places=3)

        branch3 = Branch()
        branch3.oddParticles = [st1, n1]
        branch3.evenParticles = [[t]]
        el2 = Element([branch1, branch3])
        f = reweightFactorFor(el2, resType='prompt')
        self.assertAlmostEqual(f, F_prompt, places=3)
        f = reweightFactorFor(el2, resType='displaced')
        self.assertAlmostEqual(f, Fdisp, places=3)
Пример #2
0
    def __init__(self, el, missingX, smFinalStates, bsmFinalStates):

        self.branches = [Branch() for _ in el.branches]
        self.missingX = missingX
        self.finalBSMstates = []

        for ib, branch in enumerate(el.branches):
            newParticles = []
            for vertex in branch.evenParticles:
                newVertex = vertex[:]
                for ip, particle in enumerate(vertex):
                    for particleList in smFinalStates:
                        if particleList.contains(particle):
                            newVertex[ip] = particleList
                newParticles.append(ParticleList(newVertex))
            self.branches[ib].evenParticles = newParticles

            finalBSM = branch.oddParticles[-1]
            for bsmFS in bsmFinalStates:
                if finalBSM == bsmFS:
                    finalBSM = bsmFS
                    break
            self.branches[ib].finalBSMstate = finalBSM
            self.branches[ib].setInfo()

        self.sortBranches()
        self.finalBSMstates = [br.finalBSMstate for br in self.branches]
        self._contributingElements = [el]
        self._outputDescription = str(self)
Пример #3
0
    def __init__(self, info=None):
        """
        Initializes the element. If info is defined, tries to generate
        the element using it.
        
        :parameter info: string describing the element in bracket notation
                         (e.g. [[[e+],[jet]],[[e-],[jet]]])
        """
        self.branches = [Branch(), Branch()]
        self.weight = crossSection.XSectionList()
        self.motherElements = []
        self.elID = 0
        self.covered = False
        self.tested = False

        if info:
            # Create element from particle string
            if type(info) == type(str()):
                elements = elementsInStr(info)
                if not elements or len(elements) > 1:
                    nel = 0
                    if elements:
                        nel = len(elements)
                    logger.error(
                        "Malformed input string. Number of elements "
                        "is %d (expected 1) in: ``%s''", nel, info)
                    return None
                else:
                    el = elements[0]
                    branches = elementsInStr(el[1:-1])
                    if not branches or len(branches) != 2:
                        logger.error(
                            "Malformed input string. Number of "
                            "branches is %d (expected 2) in: ``%s''",
                            len(branches), info)
                        return None
                    self.branches = []
                    for branch in branches:
                        self.branches.append(Branch(branch))
            # Create element from branch pair
            elif type(info) == type([]) and type(info[0]) == type(Branch()):
                for ib, branch in enumerate(info):
                    self.branches[ib] = branch.copy()
Пример #4
0
    def testElementCombine(self):

        gluino.mass = 500. * GeV
        st1.mass = 400. * GeV
        n1.mass = 250. * GeV
        n2.mass = 300. * GeV
        n3.mass = 320. * GeV
        n1.totalwidth = 0. * GeV
        n2.totalwidth = 0. * GeV  #just for the sake of the example

        w1 = XSectionList()
        w1.xSections.append(XSection())
        w1.xSections[0].info = XSectionInfo()
        w1.xSections[0].info.sqrts = 8. * TeV
        w1.xSections[0].info.label = '8 TeV'
        w1.xSections[0].info.order = 0
        w1.xSections[0].value = 10. * fb
        w2 = w1.copy()
        w2.xSections[0].value = 22. * fb
        w3 = w1.copy()
        w3.xSections[0].value = 2. * fb

        b1 = Branch()
        b2 = Branch()
        b1.evenParticles = [[g]]
        b1.oddParticles = [gluino, n1]
        b2.evenParticles = [[g]]
        b2.oddParticles = [gluino, n2]

        el1 = Element(info=[b1, b1])
        el1.weight = w1
        el2 = Element(info=[b2, b2])
        el2.weight = w2
        el3 = Element(info=[b1, b2])
        el3.weight = w3
        el1 += el2
        self.assertEqual(el1.weight[0].value, 32. * fb)
        self.assertEqual(
            el1.pdg,
            [[1000021, [1000022, 1000023]], [1000021, [1000022, 1000023]]])
        self.assertEqual(el1.getAverage('mass'),
                         [[gluino.mass, (n1.mass + n2.mass) / 2.]] * 2)
        el1 += el3
        self.assertEqual(el1.weight[0].value, 34. * fb)
        self.assertEqual(
            el1.pdg,
            [[1000021, [1000022, 1000023]], [1000021, [1000022, 1000023]]])
        self.assertEqual(el1.getAverage('mass'),
                         [[gluino.mass, (n1.mass + n2.mass) / 2.]] * 2)
Пример #5
0
    def testEffReweight(self):

        n1 = mssm.n1.copy()
        n1.totalwidth = 1e-18 * GeV
        st1 = mssm.st1.copy()
        st1.totalwidth = 5e-15 * GeV
        gluino = mssm.gluino.copy()
        gluino.totalwidth = 1e-15 * GeV
        branch1 = Branch()
        branch1.oddParticles = [st1, n1]
        branch2 = Branch()
        branch2.oddParticles = [gluino, n1]
        el1 = Element([branch1, branch2])
        r = defaultEffReweight(el1)  #Use default values
        self.assertAlmostEqual(r * 1e5, 6.991, places=2)

        r = defaultEffReweight(el1, Leff_inner=0.1, Leff_outer=15.0)
        self.assertAlmostEqual(r, 0.314, places=2)
Пример #6
0
    def __init__(self,
                 info=None,
                 finalState=None,
                 intermediateState=None,
                 model=None):
        """
        Initializes the element. If info is defined, tries to generate
        the element using it.

        :parameter info: string describing the element in bracket notation
                         (e.g. [[[e+],[jet]],[[e-],[jet]]])

        :parameter finalState: list containing the final state labels for each branch
                         (e.g. ['MET', 'HSCP'] or ['MET','MET'])
        :parameter intermediateState: nested list containing intermediate state labels
                                     for each branch  (e.g. [['gluino'], ['gluino']])
        :parameter model: The model (Model object) to be used when converting particle labels to
                          particle objects (only used if info, finalState or intermediateState != None).
        """

        self.branches = [Branch(), Branch()]
        self.weight = crossSection.XSectionList(
        )  # gives the weight for all decays promptly
        self.decayLabels = []
        self.motherElements = [
            self
        ]  #The motheElements includes self to keep track of merged elements
        self.elID = 0
        self.coveredBy = set()
        self.testedBy = set()

        if info:
            # Create element from particle string
            if type(info) == type(str()):
                elements = elementsInStr(info)
                if not elements or len(elements) > 1:
                    nel = 0
                    if elements:
                        nel = len(elements)
                    logger.error(
                        "Malformed input string. Number of elements "
                        "is %d (expected 1) in: ``%s''", nel, info)
                    return None
                else:
                    el = elements[0]
                    branches = elementsInStr(el[1:-1])
                    if not branches or len(branches) != 2:
                        logger.error(
                            "Malformed input string. Number of "
                            "branches is %d (expected 2) in: ``%s''",
                            len(branches), info)
                        return None
                    self.branches = []
                    if intermediateState:
                        if len(intermediateState) != len(branches):
                            raise SModelSError(
                                "Number of intermediate states (%i) does not match number of branches (%i)"
                                % (len(intermediateState), len(branches)))
                    else:
                        intermediateState = [None] * len(branches)

                    if finalState:
                        if len(finalState) != len(branches):
                            raise SModelSError(
                                "Number of final states (%i) does not match number of branches (%i)"
                                % (len(finalState), len(branches)))
                    else:
                        finalState = [None] * len(branches)
                    for ibr, branch in enumerate(branches):
                        if branch == '[*]':
                            self.branches.append(
                                InclusiveBranch(
                                    finalState[ibr],
                                    intermediateState=intermediateState[ibr],
                                    model=model))
                        else:
                            self.branches.append(
                                Branch(branch,
                                       finalState[ibr],
                                       intermediateState[ibr],
                                       model=model))

            # Create element from branch pair
            elif isinstance(info, list) and all(
                    isinstance(x, (Branch, InclusiveBranch)) for x in info):
                self.branches = [br.copy() for br in info]
            else:
                raise SModelSError(
                    "Can not create element from input type %s" % type(info))

        self.setEinfo()
Пример #7
0
    def testElementInclusive(self):

        b1 = Branch()
        b1.evenParticles = [[em], [em, nue]]
        b1.oddParticles = [gluino, st1, n1]
        b1.setInfo()

        b1b = Branch()
        b1b.evenParticles = [[L], [L, nue]]
        b1b.oddParticles = [gluino, st1, n1]
        b1b.setInfo()

        b2 = Branch()
        b2.evenParticles = [[L, nue]]
        b2.oddParticles = [st1, n1]
        b2.setInfo()

        b2b = Branch()
        b2b.evenParticles = [[em, nue]]
        b2b.oddParticles = [st1, n1]
        b2b.setInfo()

        el1 = Element()
        el1.branches = [b1, b2]
        el2 = Element()
        el2.branches = [b2b, b1b]

        self.assertTrue(el1 == el2)  #Elements match (using inclusive labels)
Пример #8
0
    def testElementStr(self):

        b1 = Branch()
        b1.evenParticles = [ParticleList([t]), ParticleList([b, t])]
        b1.oddParticles = [gluino, st1, n1]
        b2 = Branch()
        b2.evenParticles = [ParticleList([b, t])]
        b2.oddParticles = [st1, n1]
        b1.setInfo()
        b2.setInfo()

        el1 = Element()
        el1.branches = [b1, b2]
        elstrA = Element('[[[t+],[b,t+]],[[b,t+]]]',
                         finalState=['MET', 'MET'],
                         model=finalStates)
        elstrB = Element('[[[b,t+]],[[t+],[b,t+]]]',
                         finalState=['MET', 'MET'],
                         model=finalStates)
        elstrC = Element('[[[b,t+]],[[t],[b,t]]]',
                         finalState=['MET', 'MET'],
                         model=finalStates)

        self.assertTrue(el1 == elstrA)  #Elements should be equal
        self.assertTrue(
            el1 ==
            elstrB)  #Elements should be equal (only branch order differs)
        self.assertTrue(
            el1 == elstrC)  #Elements should be equal (inclusive labels)
Пример #9
0
def decompose(model,
              sigmacut=0.1 * fb,
              doCompress=True,
              doInvisible=True,
              minmassgap=0 * GeV):
    """
    Perform decomposition using the information stored in model.
    
    :param sigmacut: minimum sigma*BR to be generated, by default sigmacut = 0.1 fb
    :param doCompress: turn mass compression on/off
    :param doInvisible: turn invisible compression on/off
    :param minmassgap: maximum value (in GeV) for considering two R-odd particles
                       degenerate (only revelant for doCompress=True )
    :returns: list of topologies (TopologyList object)

    """
    t1 = time.time()

    xSectionList = model.xsections
    pdgList = model.getValuesFor('pdg')

    if doCompress and minmassgap / GeV < 0.:
        logger.error(
            "Asked for compression without specifying minmassgap. Please set minmassgap."
        )
        raise SModelSError()

    if isinstance(sigmacut, (float, int)):
        sigmacut = sigmacut * fb
    sigmacut = sigmacut.asNumber(fb)

    xSectionList.removeLowerOrder()
    # Order xsections by PDGs to improve performance
    xSectionList.order()

    # Get maximum cross sections (weights) for single particles (irrespective
    # of sqrtS)
    maxWeight = {}
    for pid in xSectionList.getPIDs():
        maxWeight[pid] = xSectionList.getXsecsFor(pid).getMaxXsec().asNumber(
            fb)

    # Generate dictionary, where keys are the PIDs and values
    # are the list of cross sections for the PID pair (for performance)
    xSectionListDict = {}
    for pids in xSectionList.getPIDpairs():
        xSectionListDict[pids] = xSectionList.getXsecsFor(pids)

    # Create 1-particle branches with all possible mothers
    branchList = []
    for pid in maxWeight:
        branchList.append(Branch())
        bsmParticle = model.getParticlesWith(pdg=pid)
        if not bsmParticle:
            raise SModelSError("Particle for pdg %i has not been defined.")
        if len(bsmParticle) != 1:
            raise SModelSError(
                "Particle with pdg %i has multiple definitions.")
        branchList[-1].oddParticles = [bsmParticle[0]]
        if not pid in pdgList:
            logger.error("PDG %i has not been defined" % int(pid))
        branchList[-1].maxWeight = maxWeight[pid]

    # Generate final branches (after all R-odd particles have decayed)
    finalBranchList = decayBranches(branchList, sigmacut)

    # Generate dictionary, where keys are the PIDs and values are the list of branches for the PID (for performance)
    branchListDict = {}
    for branch in finalBranchList:
        if branch.oddParticles[0].pdg in branchListDict:
            branchListDict[branch.oddParticles[0].pdg].append(branch)
        else:
            branchListDict[branch.oddParticles[0].pdg] = [branch]

    for pid in xSectionList.getPIDs():
        if not pid in branchListDict:
            branchListDict[pid] = []

    #Sort the branch lists by max weight to improve performance:
    for pid in branchListDict:
        branchListDict[pid] = sorted(branchListDict[pid],
                                     key=lambda br: br.maxWeight,
                                     reverse=True)

    smsTopList = topology.TopologyList()

    # Combine pairs of branches into elements according to production
    # cross section list
    for pids in xSectionList.getPIDpairs():
        weightList = xSectionListDict[pids]
        maxxsec = weightList.getMaxXsec().asNumber(fb)
        if maxxsec == 0.:  ## protection
            continue
        minBR = sigmacut / maxxsec
        if minBR > 1.:
            continue
        for branch1 in branchListDict[pids[0]]:
            BR1 = branch1.maxWeight / maxWeight[
                pids[0]]  #Branching ratio for first branch
            if BR1 < minBR:
                break  #Stop loop if BR1 is already too low
            for branch2 in branchListDict[pids[1]]:
                BR2 = branch2.maxWeight / maxWeight[
                    pids[1]]  #Branching ratio for second branch
                if BR2 < minBR:
                    break  #Stop loop if BR2 is already too low

                finalBR = BR1 * BR2
                if finalBR < minBR:
                    continue  # Skip elements with xsec below sigmacut

                newElement = element.Element([branch1, branch2])
                newElement.weight = weightList * finalBR
                newElement.sortBranches(
                )  #Make sure elements are sorted BEFORE adding them
                smsTopList.addElement(newElement)

    smsTopList.compressElements(doCompress, doInvisible, minmassgap)
    smsTopList._setElementIds()

    logger.debug("decomposer done in %.2f s." % (time.time() - t1))

    return smsTopList
Пример #10
0
    def testElement(self):

        b1 = Branch()
        b1.evenParticles = [[t], [b, t]]
        b1.oddParticles = [gluino, st1, n1]
        b2 = Branch()
        b2.evenParticles = [[b, t]]
        b2.oddParticles = [st1, n1]
        b1.setInfo()
        b2.setInfo()

        el1 = Element()
        el1.branches = [b1, b2]
        el2 = Element()
        el2.branches = [b2, b2]
        el1B = Element()
        el1B.branches = [b2, b1]
        self.assertEqual(el1 > el2, True)  #Bigger by number of vertices
        self.assertEqual(el1, el1B)  #Just differ by branch ordering
        el1.sortBranches()
        e1Info = {"vertnumb": [1, 2], "vertparts": [[2], [1, 2]]}
        self.assertEqual(el1.getEinfo() == e1Info, True)
Пример #11
0
    def testElementMassComp(self):

        b1 = Branch()
        b1.evenParticles = [[t], [b, t]]
        b1.oddParticles = [gluino, st1, n1]
        b2 = Branch()
        b2.evenParticles = [[b, t]]
        b2.oddParticles = [st1, n1]
        b1.setInfo()
        b2.setInfo()

        el1 = Element()
        el1.branches = [b1, b2]

        #Compress gluino-stop1
        gluino.mass = 400. * GeV
        gluino.totalwidth = float('inf') * GeV
        st1.mass = 398. * GeV
        st1.totalwidth = float('inf') * GeV
        n1.mass = 390. * GeV
        n1.totalwidth = 0. * GeV
        el1Comp = el1.massCompress(minmassgap=5. * GeV)
        b1Comp = Branch()
        b1Comp.evenParticles = [[b, t]]
        b1Comp.oddParticles = [st1, n1]
        b2Comp = Branch()
        b2Comp.evenParticles = [[b, t]]
        b2Comp.oddParticles = [st1, n1]
        el2 = Element()
        el2.branches = [b1Comp, b2Comp]
        el2.setEinfo()
        self.assertEqual(el1Comp, el2)  #Elements should be equal

        #Compress stop1-neutralino1
        gluino.mass = 400. * GeV
        st1.mass = 393. * GeV
        n1.mass = 390. * GeV
        el1Comp = el1.massCompress(minmassgap=5. * GeV)

        b1Comp = Branch()
        b1Comp.evenParticles = [[t]]
        b1Comp.oddParticles = [gluino, n1]
        b2Comp = Branch()
        b2Comp.evenParticles = []
        b2Comp.oddParticles = [n1]
        el2 = Element(info=[b1Comp, b2Comp])
        el1.sortBranches()
        el2.sortBranches()
        self.assertEqual(el1Comp, el2)  #Elements should be equal

        #Compress everything
        el1Comp = el1.massCompress(minmassgap=10. * GeV)  #Fully compress
        b1Comp = Branch()
        b1Comp.evenParticles = []
        b1Comp.oddParticles = [n1]
        b2Comp = b1Comp.copy()
        el2 = Element(info=[b1Comp, b2Comp])
        self.assertEqual(el1Comp, el2)  #Elements should be equal
Пример #12
0
    def testElementInvComp(self):

        gluino.mass = 500. * GeV
        st1.mass = 400. * GeV
        n1.mass = 300. * GeV
        n2.mass = 310. * GeV
        n3.mass = 320. * GeV
        n4.mass = 330. * GeV

        #Compress one step:
        #N3 --> N1 + [nue,nue]
        #gluino --> st_1 + [t+]/st_1 --> N3 + [t+]/N3 --> N1 + [nue,nue]
        b1 = Branch()
        b1.evenParticles = [[t], [t], [nue, nue]]
        b1.oddParticles = [gluino, st1, n3, n1]
        b2 = Branch()
        b2.evenParticles = [[nue, nue]]
        b2.oddParticles = [n3, n1]
        el1 = Element(info=[b1, b2])
        el1Comp = el1.invisibleCompress()

        b1Comp = Branch()
        b1Comp.evenParticles = [[t], [t]]
        b1Comp.oddParticles = [gluino, st1, n3]
        b2Comp = Branch()
        b2Comp.evenParticles = []
        b2Comp.oddParticles = [n3]
        el2 = Element(info=[b1Comp, b2Comp])
        el2.sortBranches()
        self.assertEqual(el1Comp, el2)  #Elements should be equal

        #Compress two steps:
        #N3 --> N1 + [nue,nue]
        #gluino --> st_1 + [t+]/st_1 --> N3 + [t+]/N3 --> N2 + [nue]/N2 --> N1 + [nue,nue,nue,nue]
        b1 = Branch()
        b1.evenParticles = [[nue, nue]]
        b1.oddParticles = [n3, n1]
        b2 = Branch()
        b2.evenParticles = [[t], [t], [nue], [nue, nue, nue, nue]]
        b2.oddParticles = [gluino, st1, n3, n2, n1]
        el1 = Element(info=[b1, b2])

        el1Comp = el1.invisibleCompress()
        b1Comp = Branch()
        b1Comp.evenParticles = []
        b1Comp.oddParticles = [n3]
        b2Comp = Branch()
        b2Comp.evenParticles = [[t], [t]]
        b2Comp.oddParticles = [gluino, st1, n3]
        el2 = Element(info=[b1Comp, b2Comp])
        self.assertEqual(el1Comp, el2)  #Elements should be equal

        #Make sure compression only happens at the end:
        #N3 --> N1 + [nue,nue]
        #gluino --> st_1 + [t+]/st_1 --> N3 + [t+]/N3 --> N2 + [nue]/N2 --> N1 + [e-,nue,nue,nue]
        b1 = Branch()
        b1.evenParticles = [[nue, nue]]
        b1.oddParticles = [n3, n1]
        b2 = Branch()
        b2.evenParticles = [[t], [t], [nue], [e, nue, nue, nue]]
        b2.oddParticles = [gluino, st1, n3, n2, n1]
        el1 = Element(info=[b1, b2])

        el1Comp = el1.invisibleCompress()
        b1Comp = Branch()
        b1Comp.evenParticles = []
        b1Comp.oddParticles = [n3]
        b2Comp = b2.copy()
        el2 = Element(info=[b1Comp, b2Comp])
        self.assertEqual(el1Comp, el2)  #Elements should be equal
Пример #13
0
n3 = mssm.n3
n4 = mssm.n4

w1 = XSectionList()
w1.xSections.append(XSection())
w1.xSections[0].info = XSectionInfo()
w1.xSections[0].info.sqrts = 8. * TeV
w1.xSections[0].info.label = '8 TeV'
w1.xSections[0].info.order = 0
w1.xSections[0].value = 10. * fb
w2 = w1.copy()
w2.xSections[0].value = 22. * fb
w3 = w1.copy()
w3.xSections[0].value = 2. * fb

b1 = Branch()
b1.evenParticles = [[t], [b, t]]
b1.oddParticles = [gluino, st1, n1]
b1b = Branch()
b1b.evenParticles = [[t], [b, t]]
b1b.oddParticles = [gluino, st1, n1]
b2 = Branch()
b2.evenParticles = [[b, t]]
b2.oddParticles = [st1, n1]
b1.setInfo()
b2.setInfo()

el1 = Element()
el1.branches = [b1, b2]
el1.weight = w1
el2 = Element()
Пример #14
0
    def testUncovered(self):

        topolist = TopologyList()

        # prompt
        b1 = Branch()
        b1.evenParticles = [[b,t]]
        b1.oddParticles = [st1,n1]
        b1.setInfo()
        el1 = Element()
        el1.branches=[b1,b1]

        # long-lived
        b3 = Branch()
        b3.evenParticles = []
        b3.oddParticles = [gluino]
        b4 = Branch()
        b4.evenParticles = [[b,t]]
        b4.oddParticles = [st1,n1]
        b3.setInfo()
        b4.setInfo()
        el2 = Element()
        el2.branches=[b3,b4]

        # prompt and displaced
        b5 = Branch()
        b5.evenParticles = [[t],[b,t]]
        b5.oddParticles = [st2,st1,n1]
        b6 = Branch()
        b6.evenParticles = [[b,t]]
        b6.oddParticles = [st1,n1]
        b5.setInfo()
        b6.setInfo()
        el3 = Element()
        el3.branches=[b5,b6]

        w1 = XSectionList()
        w1.xSections.append(XSection())
        w1.xSections[0].info = XSectionInfo()
        w1.xSections[0].info.sqrts = 8.*TeV
        w1.xSections[0].info.label = '8 TeV'
        w1.xSections[0].info.order = 0
        w1.xSections[0].value = 10.*fb
        el1.weight = w1
        el2.weight = w1
        el3.weight = w1

        topolist.addElement(el1)
        topolist.addElement(el2)
        topolist.addElement(el3)
        topolist._setElementIds()
        uncovered = Uncovered(topolist,groupFilters=filters,groupFactors=factors)
        longLived = uncovered.getGroup('missing non-MET (prompt)')

        MET = uncovered.getGroup('missing MET (prompt)')
        displaced = uncovered.getGroup('missing (displaced)')

        self.assertEqual(len(longLived.generalElements), 1)
        self.assertEqual(len(displaced.generalElements), 1)
        self.assertEqual(len(MET.generalElements), 2)

        self.assertAlmostEqual(longLived.generalElements[0].missingX, 10.)
        self.assertAlmostEqual(displaced.generalElements[0].missingX, 9.96109334317542,places=4)
        self.assertAlmostEqual(MET.generalElements[0].missingX, 10.)
        self.assertAlmostEqual(MET.generalElements[1].missingX, 0.03890665682,places=4)
Пример #15
0
    def testTxnameDataReweight(self):

        c1 = mssm.c1.copy()
        c1.totalwidth = 1e-17 * GeV
        c1.mass = 100 * GeV
        gluino = mssm.gluino.copy()
        gluino.totalwidth = 1e-15 * GeV
        gluino.mass = 500 * GeV
        branch1 = Branch()
        branch1.oddParticles = [gluino, c1]
        branch2 = Branch()
        branch2.oddParticles = [gluino, c1]
        el1 = Element([branch1, branch2])

        listofanalyses = database.getExpResults(analysisIDs=["CMS-EXO-13-006"],
                                                dataTypes=['efficiencyMap'])

        exp = listofanalyses[0]
        ds = [d for d in exp.datasets if d.dataInfo.dataId == 'c000'][0]
        tx = [t for t in ds.txnameList if str(t) == 'THSCPM3'][0]
        effDefault = tx.getEfficiencyFor(el1)
        self.assertAlmostEqual(tx.txnameData.Leff_inner, 0.007)
        self.assertAlmostEqual(tx.txnameData.Leff_outer, 7.0)
        self.assertAlmostEqual(effDefault / 1e-5, 5.223348, places=3)

        ds = [d for d in exp.datasets if d.dataInfo.dataId == 'c000track'][0]
        tx = [t for t in ds.txnameList if str(t) == 'THSCPM3'][0]
        effNewSize = tx.getEfficiencyFor(el1)
        self.assertAlmostEqual(tx.txnameData.Leff_inner, 0.007)
        self.assertAlmostEqual(tx.txnameData.Leff_outer, 3.0)
        self.assertAlmostEqual(effNewSize / 1e-5, 7.83466, places=3)

        branch1 = Branch()
        branch1.oddParticles = [c1]
        branch2 = Branch()
        branch2.oddParticles = [c1]
        el2 = Element([branch1, branch2])

        ds = [d for d in exp.datasets if d.dataInfo.dataId == 'c000'][0]
        tx = [t for t in ds.txnameList if str(t) == 'THSCPM1'][0]
        effDefault = tx.getEfficiencyFor(el2)
        self.assertAlmostEqual(tx.txnameData.Leff_inner, 0.007)
        self.assertAlmostEqual(tx.txnameData.Leff_outer, 7.0)
        self.assertAlmostEqual(effDefault, 0.073292924, places=3)

        ds = [d for d in exp.datasets if d.dataInfo.dataId == 'c000track'][0]
        tx = [t for t in ds.txnameList if str(t) == 'THSCPM1'][0]
        effNewSize = tx.getEfficiencyFor(el2)
        self.assertAlmostEqual(tx.txnameData.Leff_inner, 0.1)
        self.assertAlmostEqual(tx.txnameData.Leff_outer, 5.0)
        self.assertAlmostEqual(effNewSize, 0.0897630, places=3)
def decompose(slhafile,
              sigcut=.1 * fb,
              doCompress=False,
              doInvisible=False,
              minmassgap=-1. * GeV,
              useXSecs=None):
    """
    Perform SLHA-based decomposition.
    
    :param sigcut: minimum sigma*BR to be generated, by default sigcut = 0.1 fb
    :param doCompress: turn mass compression on/off
    :param doInvisible: turn invisible compression on/off
    :param minmassgap: maximum value (in GeV) for considering two R-odd particles
                       degenerate (only revelant for doCompress=True )
    :param useXSecs: optionally a dictionary with cross sections for pair
                 production, by default reading the cross sections
                 from the SLHA file.
    :returns: list of topologies (TopologyList object)

    """
    t1 = time.time()

    if doCompress and minmassgap / GeV < 0.:
        logger.error(
            "Asked for compression without specifying minmassgap. Please set minmassgap."
        )
        raise SModelSError()

    if type(sigcut) == type(1.):
        sigcut = sigcut * fb

    try:
        f = pyslha.readSLHAFile(slhafile)
    except pyslha.ParseError as e:
        logger.error("The file %s cannot be parsed as an SLHA file: %s" %
                     (slhafile, e))
        raise SModelSError()

    # Get cross section from file
    xSectionList = crossSection.getXsecFromSLHAFile(slhafile, useXSecs)
    # Get BRs and masses from file
    brDic, massDic = _getDictionariesFromSLHA(slhafile)
    # Only use the highest order cross sections for each process
    xSectionList.removeLowerOrder()
    # Order xsections by PDGs to improve performance
    xSectionList.order()

    # Get maximum cross sections (weights) for single particles (irrespective
    # of sqrtS)
    maxWeight = {}
    for pid in xSectionList.getPIDs():
        maxWeight[pid] = xSectionList.getXsecsFor(pid).getMaxXsec()

    # Generate dictionary, where keys are the PIDs and values
    # are the list of cross sections for the PID pair (for performance)
    xSectionListDict = {}
    for pids in xSectionList.getPIDpairs():
        xSectionListDict[pids] = xSectionList.getXsecsFor(pids)

    # Create 1-particle branches with all possible mothers
    branchList = []
    for pid in maxWeight:
        branchList.append(Branch())
        branchList[-1].PIDs = [[pid]]
        if not pid in massDic:
            logger.error(
                "pid %d does not appear in masses dictionary %s in slhafile %s"
                % (pid, massDic, slhafile))
        branchList[-1].masses = [massDic[pid]]
        branchList[-1].maxWeight = maxWeight[pid]

    # Generate final branches (after all R-odd particles have decayed)
    finalBranchList = decayBranches(branchList, brDic, massDic, sigcut)
    # Generate dictionary, where keys are the PIDs and values are the list of branches for the PID (for performance)
    branchListDict = {}
    for branch in finalBranchList:
        if len(branch.PIDs) != 1:
            logger.error("During decomposition the branches should \
                            not have multiple PID lists!")
            return False
        if branch.PIDs[0][0] in branchListDict:
            branchListDict[branch.PIDs[0][0]].append(branch)
        else:
            branchListDict[branch.PIDs[0][0]] = [branch]
    for pid in xSectionList.getPIDs():
        if not pid in branchListDict: branchListDict[pid] = []

    #Sort the branch lists by max weight to improve performance:
    for pid in branchListDict:
        branchListDict[pid] = sorted(branchListDict[pid],
                                     key=lambda br: br.maxWeight,
                                     reverse=True)

    smsTopList = topology.TopologyList()
    # Combine pairs of branches into elements according to production
    # cross section list
    for pids in xSectionList.getPIDpairs():
        weightList = xSectionListDict[pids]
        minBR = (sigcut / weightList.getMaxXsec()).asNumber()
        if minBR > 1.: continue
        for branch1 in branchListDict[pids[0]]:
            BR1 = branch1.maxWeight / maxWeight[
                pids[0]]  #Branching ratio for first branch
            if BR1 < minBR: break  #Stop loop if BR1 is already too low
            for branch2 in branchListDict[pids[1]]:
                BR2 = branch2.maxWeight / maxWeight[
                    pids[1]]  #Branching ratio for second branch
                if BR2 < minBR: break  #Stop loop if BR2 is already too low

                finalBR = BR1 * BR2
                if type(finalBR) == type(1. * fb):
                    finalBR = finalBR.asNumber()
                if finalBR < minBR:
                    continue  # Skip elements with xsec below sigcut

                if len(branch1.PIDs) != 1 or len(branch2.PIDs) != 1:
                    logger.error("During decomposition the branches should \
                            not have multiple PID lists!")
                    return False

                newElement = element.Element([branch1, branch2])
                newElement.weight = weightList * finalBR
                allElements = [newElement]
                # Perform compression
                if doCompress or doInvisible:
                    allElements += newElement.compressElement(
                        doCompress, doInvisible, minmassgap)

                for el in allElements:
                    el.sortBranches(
                    )  #Make sure elements are sorted BEFORE adding them
                    smsTopList.addElement(el)
    smsTopList._setElementIds()

    logger.debug("slhaDecomposer done in %.2f s." % (time.time() - t1))
    return smsTopList
Пример #17
0
    # Get maximum cross-sections (weights) for single particles (irrespective
    # of sqrtS)
    maxWeight = {}
    for pid in xSectionList.getPIDs():
        maxWeight[pid] = xSectionList.getXsecsFor(pid).getMaxXsec()

    # Generate dictionary, where keys are the PIDs and values
    # are the list of cross-sections for the PID pair (for performance)
    xSectionListDict = {}
    for pids in xSectionList.getPIDpairs():
        xSectionListDict[pids] = xSectionList.getXsecsFor(pids)

    # Create 1-particle branches with all possible mothers
    branchList = []
    for pid in maxWeight:
        branchList.append(Branch())
        branchList[-1].momID = pid
        branchList[-1].daughterID = pid
        branchList[-1].masses = [massDic[pid]]
        branchList[-1].maxWeight = maxWeight[pid]

    # Generate final branches (after all R-odd particles have decayed)
    finalBranchList = decayBranches(branchList, brDic, massDic, sigcut)
    # Generate dictionary, where keys are the PIDs and values are the list of branches for the PID (for performance)
    branchListDict = {}
    for branch in finalBranchList:
        if branch.momID in branchListDict:
            branchListDict[branch.momID].append(branch)
        else:
            branchListDict[branch.momID] = [branch]
    for pid in xSectionList.getPIDs():
Пример #18
0
    def testSimpleCluster(self):
        """ test the mass clusterer """

        data = [[[[674.99 * GeV, 199.999 * GeV], [674.99 * GeV,
                                                  199.999 * GeV]], .03 * fb],
                [[[725.0001 * GeV, 200. * GeV], [725.0001 * GeV, 200. * GeV]],
                 .06 * fb],
                [[[750. * GeV, 250. * GeV], [750. * GeV, 250. * GeV]],
                 .03 * fb]]
        info = Info(
            "./database/8TeV/ATLAS/ATLAS-SUSY-2013-05/data/dataInfo.txt")
        globalInfo = Info(
            "./database/8TeV/ATLAS/ATLAS-SUSY-2013-05/globalInfo.txt")
        txnameData = TxNameData(data, "upperLimit", Id=1)
        txname = TxName(
            "./database/8TeV/ATLAS/ATLAS-SUSY-2013-05/data/T2bb.txt",
            globalInfo, info, finalStates)
        txname.txnameData = txnameData
        dataset = DataSet(info=globalInfo, createInfo=False)
        dataset.dataInfo = info
        dataset.txnameList = [txname]

        u = SMparticles.u
        gluino = mssm.gluino.copy()
        gluino.__setattr__("mass", 675. * GeV)
        gluino.__setattr__('totalwidth', float('inf') * GeV)
        n1 = mssm.n1.copy()
        n1.__setattr__("mass", 200. * GeV)
        n1.__setattr__('totalwidth', 0. * GeV)

        w1 = XSectionList()
        w1.xSections.append(XSection())
        w1.xSections[0].info = XSectionInfo()
        w1.xSections[0].info.sqrts = 8. * TeV
        w1.xSections[0].info.label = '8 TeV'
        w1.xSections[0].info.order = 0
        w1.xSections[0].value = 10. * fb

        b1 = Branch()
        b1.evenParticles = [[u, u]]
        b1.oddParticles = [gluino, n1]
        b2 = b1.copy()
        el1 = Element()
        el1.branches = [b1, b2]
        el1.weight = w1
        el1.txname = txname
        el1.eff = 1.  #(Used in clustering)

        ## make a second element with a slightly different gluino mass
        el2 = el1.copy()
        el2.motherElements = [el2]  #Enforce el2 and el1 not to be related
        el2.txname = txname
        el2.branches[0].oddParticles = [
            ptc.copy() for ptc in el1.branches[0].oddParticles
        ]
        el2.branches[1].oddParticles = [
            ptc.copy() for ptc in el1.branches[1].oddParticles
        ]
        el2.branches[0].oddParticles[0].__setattr__("mass", 725. * GeV)
        el2.branches[1].oddParticles[0].__setattr__("mass", 725. * GeV)
        el2.eff = 1.  #(Used in clustering)

        #Cluster for upper limits (all elements close in upper limit should be clustered together)
        maxDist = 5.  #Cluster all elements
        newel = clusterTools.clusterElements([el1, el2], maxDist, dataset)[0]
        newmasses = newel.averageElement().mass
        self.assertEqual(newmasses, [[700. * GeV, 200. * GeV]] * 2)

        maxDist = 0.5  #Elements differ and should not be clustered
        newel = clusterTools.clusterElements([el1, el2], maxDist, dataset)
        #in this example the distance is not in maxdist, so we dont cluster
        self.assertTrue(len(newel) == 2)

        info = Info(
            "./database/8TeV/CMS/CMS-SUS-13-012-eff/6NJet8_1000HT1250_200MHT300/dataInfo.txt"
        )
        globalInfo = Info(
            "./database/8TeV/CMS/CMS-SUS-13-012-eff/globalInfo.txt")
        txnameData = TxNameData(data, "efficiencyMap", Id=1)
        txname = TxName(
            "./database/8TeV/CMS/CMS-SUS-13-012-eff/6NJet8_1000HT1250_200MHT300/T2.txt",
            globalInfo, info, finalStates)
        txname.txnameData = txnameData
        dataset = DataSet(info=globalInfo, createInfo=False)
        dataset.dataInfo = info
        dataset.txnameList = [txname]

        #Cluster for efficiency maps (all elements should be clustered together independent of maxDist)
        maxDist = 0.001
        newel = clusterTools.clusterElements([el1, el2], maxDist, dataset)[0]
        newmasses = newel.averageElement().mass
        self.assertEqual(newmasses, [[700. * GeV, 200. * GeV]] * 2)
Пример #19
0
    def testClustererLifeTimes(self):
        """ test the clustering with distinct lifetimes"""

        data = [[[[674.99 * GeV, 199.999 * GeV], [674.99 * GeV,
                                                  199.999 * GeV]], .03 * fb],
                [[[725.0001 * GeV, 200. * GeV], [725.0001 * GeV, 200. * GeV]],
                 .06 * fb],
                [[[750. * GeV, 250. * GeV], [750. * GeV, 250. * GeV]],
                 .03 * fb]]
        info = Info(
            "./database/8TeV/ATLAS/ATLAS-SUSY-2013-05/data/dataInfo.txt")
        globalInfo = Info(
            "./database/8TeV/ATLAS/ATLAS-SUSY-2013-05/globalInfo.txt")
        txnameData = TxNameData(data, "upperLimit", Id=1)
        txname = TxName(
            "./database/8TeV/ATLAS/ATLAS-SUSY-2013-05/data/T2bb.txt",
            globalInfo, info, finalStates)
        txname.txnameData = txnameData
        dataset = DataSet(info=globalInfo, createInfo=False)
        dataset.dataInfo = info
        dataset.txnameList = [txname]

        u = SMparticles.u
        gluino = mssm.gluino.copy()
        gluino.__setattr__("mass", 675. * GeV)
        gluino.__setattr__('totalwidth', 1e-15 * GeV)
        n1 = mssm.n1.copy()
        n1.__setattr__("mass", 200. * GeV)
        n1.__setattr__('totalwidth', 0. * GeV)

        w1 = XSectionList()
        w1.xSections.append(XSection())
        w1.xSections[0].info = XSectionInfo()
        w1.xSections[0].info.sqrts = 8. * TeV
        w1.xSections[0].info.label = '8 TeV'
        w1.xSections[0].info.order = 0
        w1.xSections[0].value = 10. * fb

        b1 = Branch()
        b1.evenParticles = [ParticleList([u, u])]
        b1.oddParticles = [gluino, n1]
        b2 = b1.copy()
        el1 = Element()
        el1.branches = [b1, b2]
        el1.weight = w1
        el1.txname = txname
        el1.eff = 1.  #(Used in clustering)

        ## make a second element with a slightly different gluino width
        el2 = el1.copy()
        el2.motherElements = [el2]  #Enforce el2 and el1 not to be related
        el2.txname = txname
        el2.branches[0].oddParticles = [
            ptc.copy() for ptc in el1.branches[0].oddParticles
        ]
        el2.branches[1].oddParticles = [
            ptc.copy() for ptc in el1.branches[1].oddParticles
        ]
        el2.eff = 1.  #(Used in clustering)

        el2.branches[0].oddParticles[0].__setattr__("mass", 675. * GeV)
        el2.branches[1].oddParticles[0].__setattr__("mass", 675. * GeV)
        el2.branches[0].oddParticles[0].__setattr__("totalwidth",
                                                    0.9e-15 * GeV)
        el2.branches[1].oddParticles[0].__setattr__("totalwidth",
                                                    0.9e-15 * GeV)

        newel = clusterTools.clusterElements([el1, el2], 5., dataset)
        ## this example gives an avg cluster mass of 700 gev
        self.assertEqual(newel[0].averageElement().mass[0][0], 675. * GeV)
        self.assertAlmostEqual(
            newel[0].averageElement().totalwidth[0][0].asNumber(GeV) * 1e15,
            0.95)

        newel = clusterTools.clusterElements([el1, el2], .5, dataset)
        #in this example the distance is in maxdist, so we cluster
        self.assertTrue(len(newel) == 1)

        newel = clusterTools.clusterElements([el1, el2], .1, dataset)
        #in this example the distance is not in maxdist, so we dont cluster
        self.assertTrue(len(newel) == 2)