Ejemplo n.º 1
0
def elementFromEvent(event, weight=None):
    """
    Creates an element from a LHE event and the corresponding event weight.
    
    :param event: LHE event
    :param weight: event weight. Must be a XSectionList object (usually with a
                   single entry) or None if not specified.
    :returns: element
    
    """
    if not event.particles:
        logger.error("Empty event")
        return None

    brDic, massDic = _getDictionariesFromEvent(event)

    # Create branch list
    finalBranchList = []
    from smodels.particlesLoader import rOdd, rEven
    for ip, particle in enumerate(event.particles):
        keys = list ( rEven.keys() ) + \
               list ( rOdd.keys() )
        if not particle.pdg in keys:
            logger.warning(
                "Particle %i not defined in particles.py, events containing this particle will be ignored"
                % (particle.pdg))
            return None

        # Particle came from initial state (primary mother)
        if 1 in particle.moms:
            mombranch = branch.Branch()
            mombranch.PIDs = [[particle.pdg]]
            if weight:
                mombranch.maxWeight = weight.getMaxXsec()
            else:
                mombranch.maxWeight = 0. * fb
            # Get simple BR and Mass dictionaries for the corresponding branch
            branchBR = brDic[ip]
            branchMass = massDic[ip]
            mombranch.masses = [branchMass[mombranch.PIDs[0][0]]]
            # Generate final branches (after all R-odd particles have decayed)
            finalBranchList += branch.decayBranches([mombranch],
                                                    branchBR,
                                                    branchMass,
                                                    sigcut=0. * fb)

    if len(finalBranchList) != 2:
        logger.error(
            str(len(finalBranchList)) + " branches found in event; "
            "Possible R-parity violation")
        raise SModelSError()
    # Create element from event
    newElement = element.Element(finalBranchList)
    if weight:
        newElement.weight = copy.deepcopy(weight)

    return newElement
Ejemplo n.º 2
0
def elementFromEvent(event, weight=None):
    """
    Creates an element from a LHE event and the corresponding event weight.
    
    :param event: LHE event
    :param weight: event weight. Must be a XSectionList object (usually with a
                   single entry) or None if not specified.
    :returns: element
    
    """
    if not event.particles:
        logger.error("Empty event")
        return None

    brDic, massDic = _getDictionariesFromEvent(event)

    # Create branch list
    finalBranchList = []
    from smodels.particlesLoader import rOdd, rEven
    for ip, particle in enumerate(event.particles):
        keys = list ( rEven.keys() ) + \
               list ( rOdd.keys() )
        if not particle.pdg in keys:
            logger.warning("Particle %i not defined in particles.py, events containing this particle will be ignored" %(particle.pdg))
            return None
        
        # Particle came from initial state (primary mother)
        if 1 in particle.moms:
            mombranch = branch.Branch()
            mombranch.PIDs = [[particle.pdg]]           
            if weight:
                mombranch.maxWeight = weight.getMaxXsec()
            else:
                mombranch.maxWeight = 0.*fb
            # Get simple BR and Mass dictionaries for the corresponding branch
            branchBR = brDic[ip]
            branchMass = massDic[ip]
            mombranch.masses = [branchMass[mombranch.PIDs[0][0]]]
            # Generate final branches (after all R-odd particles have decayed)
            finalBranchList += branch.decayBranches([mombranch], branchBR,
                                                    branchMass, sigcut=0. * fb )

    if len(finalBranchList) != 2:
        logger.error(str(len(finalBranchList)) + " branches found in event; "
                     "Possible R-parity violation")
        raise SModelSError()
    # Create element from event
    newElement = element.Element(finalBranchList)
    if weight:
        newElement.weight = copy.deepcopy(weight)

    return newElement
Ejemplo n.º 3
0
def elementFromEvent(event, weight=None):
    """
    Creates an element from a LHE event and the corresponding event weight.
    
    :param event: LHE event
    :param weight: event weight. Must be a XSectionList object (usually with a
                   single entry) or None if not specified.
    :returns: element
    
    """
    if not event.particles:
        logger.error("Empty event")
        return None

    brDic, massDic = _getDictionariesFromEvent(event)

    # Create branch list
    finalBranchList = []
    for ip, particle in enumerate(event.particles):
        # Particle came from initial state (primary mother)
        if 1 in particle.moms:
            mombranch = branch.Branch()
            mombranch.momID = particle.pdg
            mombranch.daughterID = particle.pdg
            if weight:
                mombranch.maxWeight = weight.getMaxXsec()
            # Get simple BR and Mass dictionaries for the corresponding branch
            branchBR = brDic[ip]
            branchMass = massDic[ip]
            mombranch.masses = [branchMass[mombranch.momID]]
            # Generate final branches (after all R-odd particles have decayed)
            finalBranchList += branch.decayBranches([mombranch],
                                                    branchBR,
                                                    branchMass,
                                                    sigcut=0. * fb)

    if len(finalBranchList) != 2:
        logger.error(
            str(len(finalBranchList)) + " branches found in event; "
            "Possible R-parity violation")
        import sys
        sys.exit()
    # Create element from event
    newElement = element.Element(finalBranchList)
    if weight:
        newElement.weight = copy.deepcopy(weight)

    return newElement
Ejemplo n.º 4
0
def elementFromEvent(event, weight=None):
    """
    Creates an element from a LHE event and the corresponding event weight.
    
    :param event: LHE event
    :param weight: event weight. Must be a XSectionList object (usually with a
                   single entry) or None if not specified.
    :returns: element
    
    """
    if not event.particles:
        logger.error("Empty event")
        return None

    brDic, massDic = _getDictionariesFromEvent(event)
    
    # Create branch list
    finalBranchList = []
    for ip, particle in enumerate(event.particles):
        # Particle came from initial state (primary mother)
        if 1 in particle.moms:
            mombranch = branch.Branch()
            mombranch.momID = particle.pdg
            mombranch.daughterID = particle.pdg            
            if weight:
                mombranch.maxWeight = weight.getMaxXsec()
            # Get simple BR and Mass dictionaries for the corresponding branch
            branchBR = brDic[ip]
            branchMass = massDic[ip]
            mombranch.masses = [branchMass[mombranch.momID]]
            # Generate final branches (after all R-odd particles have decayed)
            finalBranchList += branch.decayBranches([mombranch], branchBR,
                                                    branchMass, sigcut=0. * fb )

    if len(finalBranchList) != 2:
        logger.error(str(len(finalBranchList)) + " branches found in event; "
                     "Possible R-parity violation")
        import sys
        sys.exit()
    # Create element from event
    newElement = element.Element(finalBranchList)
    if weight:
        newElement.weight = copy.deepcopy(weight)

    return newElement
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
Ejemplo n.º 6
0
    # 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():
        if not pid in branchListDict: branchListDict[pid] = []

    smsTopList = topology.TopologyList()
    # Combine pairs of branches into elements according to production
    # cross-section list
    for pids in xSectionList.getPIDpairs():
        weightList = xSectionListDict[pids]
Ejemplo n.º 7
0
def decompose(slhafile, sigcut=.1 * fb, doCompress=False, doInvisible=False,
              minmassgap=-1.*GeV, useXSecs=None):
    """
    Perform SLHA-based decomposition.

    :param slhafile: the slha input file. May be an URL (though http, ftp only).
    :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)

    """
    if slhafile.startswith("http") or slhafile.startswith("ftp"):
        logger.info ( "asked for remote slhafile %s. will fetch it." % slhafile )
        import requests
        import os.path
        r=requests.get(slhafile)
        if r.status_code != 200:
            logger.error ( "could not retrieve remote file %d: %s" % ( r.status_code, r.reason ) )
            raise SModelSError()
        basename = os.path.basename ( slhafile )
        f=open ( basename, "w" )
        f.write ( r.text )
        f.close()
        slhafile = basename
    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()
    #Reweight decays by fraction of prompt decays and add fraction of long-lived
    brDic = _getPromptDecays(slhafile,brDic)

    # 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
                newElement.sortBranches()  #Make sure elements are sorted BEFORE adding them
                smsTopList.addElement(newElement)
    
    smsTopList.compressElements(doCompress, doInvisible, minmassgap)
    smsTopList._setElementIds()

    logger.debug("slhaDecomposer done in %.2f s." % (time.time() -t1 ) )
    return smsTopList
Ejemplo n.º 8
0
    # 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():
        if not pid in branchListDict: branchListDict[pid] = []

    smsTopList = topology.TopologyList()
    # Combine pairs of branches into elements according to production
    # cross-section list
    for pids in xSectionList.getPIDpairs():
        weightList = xSectionListDict[pids]
Ejemplo n.º 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