Source code for decomposition.topologyDict
#!/usr/bin/env python3
"""
.. module:: topology
:synopsis: Provides a Topology class and a TopologyList collection type.
.. moduleauthor:: Andre Lessa <lessa.a.p@gmail.com>
.. moduleauthor:: Wolfgang Magerl <wolfgang.magerl@gmail.com>
"""
from smodels.decomposition.theorySMS import TheorySMS
from collections import OrderedDict
[docs]class TopologyDict(OrderedDict):
"""
An instance of this class represents an iterable collection of topologies.
"""
def __init__(self):
self.__dict__ = {}
[docs] def addSMS(self, newSMS):
if isinstance(newSMS, TheorySMS):
canonName = newSMS.canonName
if canonName not in self:
self[canonName] = [newSMS]
else:
smsList = self[canonName]
# Find position to insert element
# (using a bisection method)
lo = 0
hi = len(smsList)
while lo < hi:
mid = (lo+hi)//2
cmp = smsList[mid].compareTo(newSMS)
if cmp < 0:
lo = mid+1
elif cmp > 0:
hi = mid
elif cmp == 0:
lo = mid
break
index = lo
if cmp == 0:
smsList[index] = smsList[index] + newSMS
else:
smsList.insert(index, newSMS)
self[canonName] = smsList[:]
return True
else:
return False
[docs] def getSMSList(self, canonName=None):
"""
Return a list with all the SMS appearing in the dict.
If canonName is not None, return the SMS with the corresponding
canonical name only.
:param canonName: if None, return all SMS, otherwise return only the
the SMS with the corresponding canonical name.
:return: List of TheorySMS objects.
"""
allsmsList = []
if canonName is None:
cNames = sorted(list(self.keys()))
else:
cNames = [canonName]
for cName in cNames:
if cName not in self:
continue
allsmsList.extend(self[cName])
return allsmsList
[docs] def compress(self, doCompress, doInvisible, minmassgap):
"""
Compress all SMS in the dictionary and include the compressed
SMS in the topology list.
:parameter doCompress: if True, perform mass compression
:parameter doInvisible: if True, perform invisible compression
:parameter minmassgap: value (in GeV) of the maximum
mass difference for compression
(if mass difference < minmassgap, perform mass compression)
"""
for sms in self.getSMSList():
newSMSList = sms.compress(doCompress, doInvisible, minmassgap)
if not newSMSList:
continue
for sms in newSMSList:
self.addSMS(sms)
[docs] def sort(self):
"""
Sort the dictionary keys and store it in a new ordered dict in self.
"""
newDict = OrderedDict()
for key in sorted(self.keys()):
newDict[key] = self.pop(key)
for key,smsList in newDict.items():
self[key] = smsList
[docs] def setSMSIds(self):
"""
Assign unique ID to each SMS in the Topology list
"""
smsID = 1
for sms in self.getSMSList():
sms.smsID = smsID
smsID += 1
[docs] def getTotalWeight(self, canonName=None):
"""
Compute the summed cross-section over all the SMS.
If canonName is not None, return the total cross-section
for the SMS with the corresponding canonName.
"""
if canonName is not None:
smsList = self[canonName]
else:
smsList = self.getSMSList()
totxsec = smsList[0].weightList
for sms in smsList[1:]:
totxsec = totxsec + sms.weightList
return totxsec