DictionaryApi
Source code in mmcif/api/DictionaryApi.py
class DictionaryApi(object):
def __init__(self, containerList, consolidate=True, expandItemLinked=False, replaceDefinition=False, **kwargs):
"""Return an instance of the mmCIF dictionary API.
Args:
containerList (list): list of definition or data containers holding dictionary content
consolidate (bool, optional): consolidate dictionary attributes within a single definition. Defaults to True.
expandItemLinked (bool, optional): distribute item and item linked attributes defined for the parent
to child definitions. Defaults to False.
replaceDefinition (bool, optional): when consolidating definitions in the case of multiple occurences of the same definition,
attributes from the latter occurences replace prior definitions content. Defaults to False.
"""
_ = kwargs
#
self.__containerList = containerList
self.__replaceDefinition = replaceDefinition
#
if consolidate:
self.__consolidateDefinitions()
#
if expandItemLinked:
self.__expandLoopedDefinitions()
self.__fullIndex = OrderedDict()
# ---
#
# Map category name to the unique list of attributes
self.__catNameIndex = OrderedDict()
# Map category name to the unique list of item names
self.__catNameItemIndex = OrderedDict()
# Full unique list of item names -
self.__itemNameList = []
#
# Map dictionary objects names to definition containers -
self.__definitionIndex = OrderedDict()
#
# data section/objects of the dictionary by category name -
self.__dataIndex = OrderedDict()
#
# Map of types id->(regex,primitive_type)
self.__typesDict = OrderedDict()
#
self.__enumD = {
"ENUMERATION_VALUE": ("item_enumeration", "value"),
"ENUMERATION_DETAIL": ("item_enumeration", "detail"),
"ENUMERATION_TYPE_UNITS": ("item_enumeration", "rcsb_type_units_code"),
"ENUMERATION_DETAIL_BRIEF": ("item_enumeration", "rcsb_detail_brief"),
"ENUMERATION_TUPLE": ("item_enumeration", None),
"ITEM_LINKED_PARENT": ("item_linked", "parent_name"),
"ITEM_LINKED_CHILD": ("item_linked", "child_name"),
"DATA_TYPE_CODE": ("item_type", "code"),
"DATA_TYPE_REGEX": ("item_type_list", "construct"),
"DATA_TYPE_PRIMITIVE": ("item_type_list", "primitive_code"),
"ITEM_NAME": ("item", "name"),
"ITEM_CATEGORY_ID": ("item", "category_id"),
"ITEM_MANDATORY_CODE": ("item", "mandatory_code"),
"ITEM_DESCRIPTION": ("item_description", "description"),
"ITEM_UNITS": ("item_units", "code"),
"ITEM_DEFAULT_VALUE": ("item_default", "value"),
"ITEM_EXAMPLE_CASE": ("item_examples", "case"),
"ITEM_EXAMPLE_DETAIL": ("item_examples", "detail"),
"ITEM_RANGE_MAXIMUM": ("item_range", "maximum"),
"ITEM_RANGE_MINIMUM": ("item_range", "minimum"),
"CATEGORY_KEY_ITEMS": ("category_key", "name"),
"CATEGORY_EXAMPLE_CASE": ("category_examples", "case"),
"CATEGORY_EXAMPLE_DETAIL": ("category_examples", "detail"),
"CATEGORY_MANDATORY_CODE": ("category", "mandatory_code"),
"CATEGORY_DESCRIPTION": ("category", "description"),
"CATEGORY_NX_MAPPING_DETAILS": ("category", "NX_mapping_details"),
#
"DATA_TYPE_CODE_NDB": ("ndb_item_type", "code"),
"ITEM_DESCRIPTION_NDB": ("ndb_item_description", "description"),
"ENUMERATION_VALUE_NDB": ("ndb_item_enumeration", "value"),
"ENUMERATION_DETAIL_NDB": ("ndb_item_enumeration", "detail"),
"ITEM_MANDATORY_CODE_NDB": ("ndb_item", "mandatory_code"),
"ITEM_EXAMPLE_CASE_NDB": ("ndb_item_examples", "case"),
"ITEM_EXAMPLE_DETAIL_NDB": ("ndb_item_examples", "detail"),
"ITEM_RANGE_MAXIMUM_NDB": ("ndb_item_range", "maximum"),
"ITEM_RANGE_MINIMUM_NDB": ("ndb_item_range", "minimum"),
"CATEGORY_EXAMPLE_CASE_NDB": ("ndb_category_examples", "case"),
"CATEGORY_EXAMPLE_DETAIL_NDB": ("ndb_category_examples", "detail"),
"CATEGORY_DESCRIPTION_NDB": ("ndb_category_description", "description"),
#
"DATA_TYPE_CODE_PDBX": ("pdbx_item_type", "code"),
"ITEM_DESCRIPTION_PDBX": ("pdbx_item_description", "description"),
"ENUMERATION_VALUE_PDBX": ("pdbx_item_enumeration", "value"),
"ENUMERATION_DETAIL_PDBX": ("pdbx_item_enumeration", "detail"),
"ENUMERATION_TYPE_UNITS_PDBX": ("pdbx_item_enumeration", "type_units_code"),
"ENUMERATION_DETAIL_BRIEF_PDBX": ("pdbx_item_enumeration", "detail_brief"),
"ITEM_MANDATORY_CODE_PDBX": ("pdbx_item", "mandatory_code"),
"ITEM_EXAMPLE_CASE_PDBX": ("pdbx_item_examples", "case"),
"ITEM_EXAMPLE_DETAIL_PDBX": ("pdbx_item_examples", "detail"),
"ITEM_RANGE_MAXIMUM_PDBX": ("pdbx_item_range", "maximum"),
"ITEM_RANGE_MINIMUM_PDBX": ("pdbx_item_range", "minimum"),
"CATEGORY_EXAMPLE_CASE_PDBX": ("pdbx_category_examples", "case"),
"CATEGORY_EXAMPLE_DETAIL_PDBX": ("pdbx_category_examples", "detail"),
"CATEGORY_DESCRIPTION_PDBX": ("pdbx_category_description", "description"),
#
"CATEGORY_CONTEXT": ("pdbx_category_context", "type"),
"CATEGORY_GROUP": ("category_group", "id"),
"ITEM_CONTEXT": ("pdbx_item_context", "type"),
"ENUMERATION_CLOSED_FLAG": ("pdbx_item_enumeration_details", "closed_flag"),
#
"ITEM_RELATED_FUNCTION_CODE": ("item_related", "function_code"),
"ITEM_RELATED_RELATED_NAME": ("item_related", "related_name"),
"ITEM_ALIAS_ALIAS_NAME": ("item_aliases", "alias_name"),
"ITEM_ALIAS_DICTIONARY": ("item_aliases", "dictionary"),
"ITEM_ALIAS_VERSION": ("item_aliases", "version"),
"ITEM_DEPENDENT_DEPENDENT_NAME": ("item_dependent", "dependent_name"),
"ITEM_SUB_CATEGORY_ID": ("item_sub_category", "id"),
"ITEM_SUB_CATEGORY_LABEL": ("item_sub_category", "pdbx_label"),
"ITEM_TYPE_CONDITIONS_CODE": ("item_type_conditions", "code"),
#
"ITEM_VALUE_CONDITION_DEPENDENT_NAME": ("pdbx_item_value_condition", "dependent_item_name"),
#
"ITEM_LINKED_PDBX_ID": ("pdbx_item_linked", "id"),
"ITEM_LINKED_PDBX_CONDITION_ID": ("pdbx_item_linked", "condition_id"),
"ITEM_LINKED_PDBX_PARENT_NAME": ("pdbx_item_linked", "parent_name"),
"ITEM_LINKED_PDBX_CHILD_NAME": ("pdbx_item_linked", "child_name"),
#
"ITEM_LINKED_PDBX_CONDITION_CHILD_NAME": ("pdbx_item_linked", "condition_child_name"),
"ITEM_LINKED_PDBX_CONDITION_CHILD_VALUE": ("pdbx_item_linked", "condition_child_value"),
"ITEM_LINKED_PDBX_CONDITION_CHILD_TARGET_NAME": ("pdbx_item_linked", "condition_child_target_name"),
"ITEM_LINKED_PDBX_CONDITION_CHILD_CMP_OP": ("pdbx_item_linked", "condition_child_cmp_op"),
"ITEM_LINKED_PDBX_CONDITION_LOG_OP": ("pdbx_item_linked", "condition_log_op"),
}
#
self.__methodDict = OrderedDict()
self.__methodIndex = OrderedDict()
#
self.__makeIndex()
self.__getMethods()
#
self.__fullParentD, self.__fullChildD = self.__makeFullParentChildDictionaries()
#
#
self.__dataBlockDictList = []
self.__dictionaryDictList = []
#
self.__subCategoryDict = OrderedDict()
self.__categoryGroupDict = OrderedDict()
self.__groupIndex = False
self.__groupChildIndex = OrderedDict()
#
# Data sections -
#
self.__dictionaryHistoryList = []
self.__itemUnitsDict = OrderedDict()
self.__itemUnitsConversionList = []
self.__itemLinkedGroupDict = OrderedDict()
self.__itemLinkedGroupItemDict = OrderedDict()
#
self.__dictionaryIncludeDict = OrderedDict()
self.__categoryIncludeDict = OrderedDict()
self.__itemIncludeDict = OrderedDict()
#
self.__dictionaryComponentList = []
self.__dictionaryComponentHistoryDict = OrderedDict()
#
self.__itemValueConditionDict = OrderedDict()
self.__compOpDict = OrderedDict()
#
self.__getDataSections()
#
def testCache(self):
return len(self.__containerList) > 0
#
# Methods for data sections --
#
def getItemValueConditionDict(self):
try:
return self.__itemValueConditionDict if self.__itemValueConditionDict else {}
except Exception:
return {}
def getComparisonOperators(self):
try:
return list(self.__compOpDict.keys()) if self.__compOpDict else []
except Exception:
return []
def getComparisonOperatorDict(self):
try:
return self.__compOpDict if self.__compOpDict else {}
except Exception:
return {}
#
def getDictionaryVersion(self):
try:
return ",".join([str(tD["version"]) for tD in self.__dictionaryDictList])
except Exception:
return None
def getDictionaryTitle(self):
try:
return ",".join([str(tD["title"]) for tD in self.__dictionaryDictList])
except Exception:
return None
def getDictionaryUpdate(self, order="reverse"):
"""Get details from the first/last history element."""
try:
if order == "reverse":
tD = self.__dictionaryHistoryList[-1]
else:
tD = self.__dictionaryHistoryList[0]
return tD["update"]
except Exception:
return None
def getDictionaryRevisionCount(self):
"""Get the count of revision history records."""
try:
return len(self.__dictionaryHistoryList)
except Exception:
return 0
def getDictionaryHistory(self, order="reverse"):
"""Returns the revision history as a list of tuples [(version,update,revisionText,dictionary),...]"""
oL = []
try:
if order == "reverse":
for tD in reversed(self.__dictionaryHistoryList):
oL.append((tD["version"], tD["update"], tD["revision"], tD["dictionary"]))
else:
for tD in self.__dictionaryHistoryList:
oL.append((tD["version"], tD["update"], tD["revision"], tD["dictionary"]))
except Exception:
pass
return oL
#
def getDictionaryComponentDetails(self):
"""Returns the component dictionary list as tuples [(version,title,dictionary_component_id),...]"""
oL = []
try:
for tD in self.__dictionaryComponentList:
oL.append((tD["version"], tD["title"], tD["dictionary_component_id"]))
except Exception:
pass
return oL
def getDictionaryComponentCount(self):
"""Get the count of dictionary components."""
try:
return len(self.__dictionaryComponentList)
except Exception:
return 0
def getDictionaryComponents(self):
"""Get the list of dictionary components."""
try:
return list(self.__dictionaryComponentHistoryDict.keys())
except Exception:
return []
def getDictionaryComponentHistory(self, dictionaryComponentId, order="reverse"):
"""Returns the revision history as a list of tuples [(version,update,revisionText,dictionary),...]"""
oL = []
try:
if order == "reverse":
for tD in reversed(self.__dictionaryComponentHistoryDict[dictionaryComponentId]):
oL.append((tD["version"], tD["update"], tD["revision"], tD["dictionary_component_id"]))
else:
for tD in self.__dictionaryComponentHistoryDict[dictionaryComponentId]:
oL.append((tD["version"], tD["update"], tD["revision"], tD["dictionary_component_id"]))
except Exception:
pass
return oL
#
def __makeCategoryGroupIndex(self):
catNameList = self.getCategoryList()
# add categories in group to self.__categoryGroupDict[<groupName>]['categories']
for catName in catNameList:
groupNameList = self.getCategoryGroupList(catName)
# logger.info("Category %s group list %r\n" % (catName,groupNameList))
for groupName in groupNameList:
if groupName not in self.__categoryGroupDict:
# handle undefined category group ?
tD = OrderedDict()
tD["description"] = None
tD["parent_id"] = None
tD["categories"] = []
self.__categoryGroupDict[groupName] = tD
self.__categoryGroupDict[groupName]["categories"].append(catName)
#
for groupName in self.__categoryGroupDict:
# logger.info("Group %s count %r\n" % (groupName, len(self.__categoryGroupDict[groupName]['categories'])))
if "categories" in self.__categoryGroupDict[groupName]:
self.__categoryGroupDict[groupName]["categories"].sort()
self.__groupChildIndex = OrderedDict()
for groupName, gD in self.__categoryGroupDict.items():
if "parent" in gD:
self.__groupChildIndex.setdefault(gD["parent"], []).append(groupName)
#
self.__groupIndex = True
#
def getCategoryGroupDescription(self, groupName):
try:
return self.__categoryGroupDict[groupName]["description"]
except Exception:
return None
def getCategoryGroupParent(self, groupName):
try:
return self.__categoryGroupDict[groupName]["parent_id"]
except Exception:
return None
def getCategoryGroupChildGroups(self, parentGroupName):
try:
return self.__groupChildIndex[parentGroupName]
except Exception:
return []
def getCategoryGroupCategories(self, groupName, followChildren=False):
try:
if not self.__groupIndex:
self.__makeCategoryGroupIndex()
#
if followChildren:
cL = []
grpL = [groupName]
grpL.extend(self.getCategoryGroupChildGroups(groupName))
for grp in grpL:
cL.extend(self.__categoryGroupDict[grp]["categories"] if grp in self.__categoryGroupDict else [])
return sorted(set(cL))
else:
return self.__categoryGroupDict[groupName]["categories"] if groupName in self.__categoryGroupDict else []
#
except Exception:
logger.exception("DictionaryApi.getCategoryGroupCategories failed for group %s", groupName)
return []
def getCategoryGroups(self):
try:
kL = self.__categoryGroupDict.keys()
return kL
except Exception:
return []
#
def getParentCategories(self, categoryName):
itemNameList = self.getItemNameList(categoryName)
parentCategories = set()
for itemName in itemNameList:
categoryName = CifName.categoryPart(itemName)
attributeName = CifName.attributePart(itemName)
parentItemList = self.getFullParentList(categoryName, attributeName)
for parentItem in parentItemList:
parentCategoryName = CifName.categoryPart(parentItem)
parentCategories.add(parentCategoryName)
return list(parentCategories)
def getChildCategories(self, categoryName):
itemNameList = self.getItemNameList(categoryName)
childCategories = set()
for itemName in itemNameList:
categoryName = CifName.categoryPart(itemName)
attributeName = CifName.attributePart(itemName)
childItemList = self.getFullChildList(categoryName, attributeName)
for childItem in childItemList:
childCategoryName = CifName.categoryPart(childItem)
childCategories.add(childCategoryName)
return list(childCategories)
#
def definitionExists(self, definitionName):
if definitionName in self.__definitionIndex:
return True
return False
def getTypeConditionsCode(self, category, attribute):
return self.__get("ITEM_TYPE_CONDITIONS_CODE", category, attribute)
def getItemDependentNameList(self, category, attribute):
return self.__getList("ITEM_DEPENDENT_DEPENDENT_NAME", category, attribute)
def getItemValueConditionDependentList(self, category, attribute):
return self.__getList("ITEM_VALUE_CONDITION_DEPENDENT_NAME", category, attribute)
def getItemSubCategoryIdList(self, category, attribute):
return self.__getList("ITEM_SUB_CATEGORY_ID", category, attribute)
def getItemSubCategoryLabelList(self, category, attribute):
return self.__getList("ITEM_SUB_CATEGORY_LABEL", category, attribute)
def getItemSubCategoryList(self, category, attribute):
aL = []
itemName = CifName.itemName(category, attribute)
obL = self.__definitionIndex[itemName] if itemName in self.__definitionIndex else None
for ob in obL:
tObj = ob.getObj(self.__enumD["ITEM_SUB_CATEGORY_ID"][0])
if tObj is not None:
atId = self.__enumD["ITEM_SUB_CATEGORY_ID"][1]
atLabel = self.__enumD["ITEM_SUB_CATEGORY_LABEL"][1]
for row in tObj.getRowList():
# logger.info("subcategories for %s row is %r" % (itemName, row))
idVal = row[tObj.getIndex(atId)] if tObj.hasAttribute(atId) else None
labVal = row[tObj.getIndex(atLabel)] if tObj.hasAttribute(atLabel) else None
aL.append((idVal, labVal))
return aL
def getItemAliasList(self, category, attribute):
aNL = self.__getListAll("ITEM_ALIAS_ALIAS_NAME", category, attribute)
aDL = self.__getListAll("ITEM_ALIAS_DICTIONARY", category, attribute)
aVL = self.__getListAll("ITEM_ALIAS_VERSION", category, attribute)
aL = []
for aN, aD, aV in zip(aNL, aDL, aVL):
aL.append((aN, aD, aV))
return aL
def getEnumListWithDetail(self, category, attribute):
eVL = self.__getListAll("ENUMERATION_VALUE", category, attribute)
eDL = self.__getListAll("ENUMERATION_DETAIL", category, attribute)
rL = []
dD = {}
if len(eVL) == len(eDL):
for eV, eD in zip(eVL, eDL):
if not eD or eD in [".", "?"]:
dD[eV] = (eV, None)
else:
dD[eV] = (eV, eD)
else:
for eV in eVL:
dD[eV] = (eV, None)
#
for ky in sorted(dD.keys()):
rL.append(dD[ky])
return rL
def getEnumListAltWithFullDetails(self, category, attribute):
rL = []
dD = {}
try:
eVL = self.__getListAll("ENUMERATION_VALUE_PDBX", category, attribute)
eDL = self.__getListAll("ENUMERATION_DETAIL_PDBX", category, attribute)
eBL = self.__getListAll("ENUMERATION_DETAIL_BRIEF_PDBX", category, attribute)
eUL = self.__getListAll("ENUMERATION_TYPE_UNITS_PDBX", category, attribute)
rL = []
dD = {}
for eV, eD, eB, eU in zip_longest(eVL, eDL, eBL, eUL):
oL = [v if v and v not in [".", "?"] else None for v in [eV, eD, eB, eU]]
dD[eV] = tuple(oL)
for ky in sorted(dD.keys()):
rL.append(dD[ky])
if rL:
return rL
#
eVL = self.__getListAll("ENUMERATION_VALUE", category, attribute)
eDL = self.__getListAll("ENUMERATION_DETAIL", category, attribute)
eBL = self.__getListAll("ENUMERATION_DETAIL_BRIEF", category, attribute)
eUL = self.__getListAll("ENUMERATION_TYPE_UNITS", category, attribute)
rL = []
dD = {}
for eV, eD, eB, eU in zip_longest(eVL, eDL, eBL, eUL):
oL = [v if v and v not in [".", "?"] else None for v in [eV, eD, eB, eU]]
dD[eV] = tuple(oL)
for ky in sorted(dD.keys()):
rL.append(dD[ky])
except Exception as e:
logger.exception("Failing dD %r rL %r with %s", dD, rL, str(e))
return rL
def getEnumListWithFullDetails(self, category, attribute):
rL = []
dD = {}
try:
eVL = self.__getListAll("ENUMERATION_VALUE", category, attribute)
eDL = self.__getListAll("ENUMERATION_DETAIL", category, attribute)
eBL = self.__getListAll("ENUMERATION_DETAIL_BRIEF", category, attribute)
eUL = self.__getListAll("ENUMERATION_TYPE_UNITS", category, attribute)
#
for eV, eD, eB, eU in zip_longest(eVL, eDL, eBL, eUL):
oL = [v if v and v not in [".", "?"] else None for v in [eV, eD, eB, eU]]
dD[eV] = tuple(oL)
for ky in sorted(dD.keys()):
rL.append(dD[ky])
except Exception as e:
logger.info("eVL %r", eVL)
logger.info("eDL %r", eDL)
logger.info("eBL %r", eBL)
logger.info("eUL %r", eUL)
logger.exception("Failing category %s attribute %s dD %r rL %r with %s", category, attribute, dD, rL, str(e))
return rL
def getEnumListAltWithDetail(self, category, attribute):
eVL = self.__getListAll("ENUMERATION_VALUE_PDBX", category, attribute)
eDL = self.__getListAll("ENUMERATION_DETAIL_PDBX", category, attribute)
rL = []
dD = {}
if len(eVL) == len(eDL):
for eV, eD in zip(eVL, eDL):
if not eD or eD in [".", "?"]:
dD[eV] = (eV, None)
else:
dD[eV] = (eV, eD)
else:
for eV in eVL:
dD[eV] = (eV, None)
#
for ky in sorted(dD.keys()):
rL.append(dD[ky])
#
if not rL:
return self.getEnumListWithDetail(category, attribute)
else:
return rL
def getItemRelatedList(self, category, attribute):
rNL = self.__getListAll("ITEM_RELATED_RELATED_NAME", category, attribute)
rFL = self.__getListAll("ITEM_RELATED_FUNCTION_CODE", category, attribute)
rL = []
for rN, rF in zip(rNL, rFL):
rL.append((rN, rF))
return rL
def getTypeCode(self, category, attribute):
return self.__get("DATA_TYPE_CODE", category, attribute, followAncestors=True)
def getTypeCodeAlt(self, category, attribute, fallBack=True):
v = self.getTypeCodePdbx(category, attribute)
if v is None:
v = self.getTypeCodeNdb(category, attribute)
if fallBack and v is None:
v = self.getTypeCode(category, attribute)
return v
def getTypeCodeNdb(self, category, attribute):
return self.__get("DATA_TYPE_CODE_NDB", category, attribute, followAncestors=False)
def getTypeCodePdbx(self, category, attribute):
return self.__get("DATA_TYPE_CODE_PDBX", category, attribute, followAncestors=False)
def getDefaultValue(self, category, attribute):
return self.__get("ITEM_DEFAULT_VALUE", category, attribute)
def getMandatoryCode(self, category, attribute):
return self.__get("ITEM_MANDATORY_CODE", category, attribute)
def getMandatoryCodeAlt(self, category, attribute, fallBack=True):
v = self.getMandatoryCodePdbx(category, attribute)
if v is None:
v = self.getMandatoryCodeNdb(category, attribute)
if fallBack and v is None:
v = self.getMandatoryCode(category, attribute)
return v
def getMandatoryCodeNdb(self, category, attribute):
return self.__get("ITEM_MANDATORY_CODE_NDB", category, attribute)
def getMandatoryCodePdbx(self, category, attribute):
return self.__get("ITEM_MANDATORY_CODE_PDBX", category, attribute)
def getTypeRegex(self, category, attribute):
code = self.getTypeCode(category, attribute)
if code in self.__typesDict:
return self.__typesDict[code][1]
return None
def getTypeRegexAlt(self, category, attribute, fallBack=True):
v = self.getTypeRegexPdbx(category, attribute)
if v is None:
v = self.getTypeRegexNdb(category, attribute)
if fallBack and v is None:
v = self.getTypeRegex(category, attribute)
return v
def getTypeRegexNdb(self, category, attribute):
code = self.getTypeCodeNdb(category, attribute)
if code in self.__typesDict:
return self.__typesDict[code][1]
return None
def getTypeRegexPdbx(self, category, attribute):
code = self.getTypeCodePdbx(category, attribute)
if code in self.__typesDict:
return self.__typesDict[code][1]
return None
def getTypePrimitive(self, category, attribute):
code = self.getTypeCode(category, attribute)
if code in self.__typesDict:
return self.__typesDict[code][0]
return None
def getTypeDetail(self, category, attribute):
code = self.getTypeCode(category, attribute)
if code in self.__typesDict:
return self.__typesDict[code][2]
return None
def getContextList(self, category, attribute):
return self.__getList("ITEM_CONTEXT", category, attribute)
def getCategoryContextList(self, category):
return self.__getList("CATEGORY_CONTEXT", category, attribute=None)
def getEnumList(self, category, attribute, sortFlag=True):
if sortFlag:
return self.__getList("ENUMERATION_VALUE", category, attribute)
else:
return self.__getListAll("ENUMERATION_VALUE", category, attribute)
def getEnumListAlt(self, category, attribute, fallBack=True, sortFlag=True):
vL = self.getEnumListPdbx(category, attribute, sortFlag=sortFlag)
if not vL:
vL = self.getEnumListNdb(category, attribute, sortFlag=sortFlag)
if fallBack and not vL:
vL = self.getEnumList(category, attribute, sortFlag=sortFlag)
return vL
def getEnumListNdb(self, category, attribute, sortFlag=True):
if sortFlag:
return self.__getList("ENUMERATION_VALUE_NDB", category, attribute)
else:
return self.__getListAll("ENUMERATION_VALUE_NDB", category, attribute)
def getEnumListPdbx(self, category, attribute, sortFlag=True):
if sortFlag:
return self.__getList("ENUMERATION_VALUE_PDBX", category, attribute)
else:
return self.__getListAll("ENUMERATION_VALUE_PDBX", category, attribute)
def isEnumerated(self, category, attribute):
return len(self.__getList("ENUMERATION_VALUE", category, attribute)) > 0
def isEnumeratedAlt(self, category, attribute, fallBack=True):
eC = len(self.__getList("ENUMERATION_VALUE_PDBX", category, attribute))
if eC == 0:
eC = len(self.__getList("ENUMERATION_VALUE_NDB", category, attribute))
if fallBack and (eC == 0):
eC = len(self.__getList("ENUMERATION_VALUE", category, attribute))
return eC > 0
def getEnumerationClosedFlag(self, category, attribute):
return self.__get("ENUMERATION_CLOSED_FLAG", category, attribute)
def getUltimateParent(self, category, attribute):
"""Return the first ultimate parent item for the input item."""
# pL=self.__getList('ITEM_LINKED_PARENT',category,attribute)
pL = self.getFullParentList(category, attribute)
itemName = CifName.itemName(category, attribute)
while pL and (pL[0] != itemName):
attN = CifName.attributePart(pL[0])
catN = CifName.categoryPart(pL[0])
itemName = pL[0]
pL = self.getFullParentList(catN, attN)
# pL=self.__getList('ITEM_LINKED_PARENT',catN,attN)
return itemName
def getParentList(self, category, attribute, stripSelfParent=False):
if stripSelfParent:
itemName = CifName.itemName(category, attribute)
pL = self.__getList("ITEM_LINKED_PARENT", category, attribute)
if pL:
try:
pL.remove(itemName)
except Exception:
pass
return pL
else:
return self.__getList("ITEM_LINKED_PARENT", category, attribute)
def getChildList(self, category, attribute):
return self.__getList("ITEM_LINKED_CHILD", category, attribute)
def getFullChildList(self, category, attribute):
try:
itemName = CifName.itemName(category, attribute)
return self.__fullChildD[itemName]
except Exception:
return []
def getFullDescendentList(self, category, attribute):
itemNameL = []
try:
itemName = CifName.itemName(category, attribute)
itemNameL = self.__fullChildD[itemName] if itemName in self.__fullChildD else []
itemNameL = list(set(itemNameL))
if itemNameL:
begLen = 0
endLen = 1
#
while endLen > begLen:
begLen = len(itemNameL)
for itemName in itemNameL:
if itemName in self.__fullChildD:
itemNameL.extend(self.__fullChildD[itemName])
itemNameL = list(set(itemNameL))
endLen = len(itemNameL)
except Exception as e:
logger.exception("Failing for %s %s with %s", category, attribute, str(e))
return itemNameL
def getFullParentList(self, category, attribute, stripSelfParent=False):
try:
itemName = CifName.itemName(category, attribute)
pL = self.__fullParentD[itemName]
if stripSelfParent:
if pL:
try:
pL.remove(itemName)
except Exception:
pass
return pL
else:
return pL
except Exception:
return []
def getUnits(self, category, attribute):
return self.__get("ITEM_UNITS", category, attribute)
def getImplicitList(self):
iL = []
for name, dL in self.__definitionIndex.items():
for dD in dL:
dType = dD.getType()
if dType == "definition" and dD.isAttribute():
catN = CifName.categoryPart(name)
attN = CifName.attributePart(name)
if self.__get("ITEM_MANDATORY_CODE", catN, attN) == "implicit":
if name not in iL:
iL.append(name)
return iL
def getDescription(self, category, attribute):
return self.__get("ITEM_DESCRIPTION", category, attribute)
def getDescriptionAlt(self, category, attribute, fallBack=True):
v = self.getDescriptionPdbx(category, attribute)
if v is None:
v = self.getDescriptionNdb(category, attribute)
if fallBack and v is None:
v = self.getDescription(category, attribute)
return v
def getDescriptionNdb(self, category, attribute):
return self.__get("ITEM_DESCRIPTION_NDB", category, attribute)
def getDescriptionPdbx(self, category, attribute):
return self.__get("ITEM_DESCRIPTION_PDBX", category, attribute)
def getExampleList(self, category, attribute):
exCL = self.__getListAll("ITEM_EXAMPLE_CASE", category, attribute)
exDL = self.__getListAll("ITEM_EXAMPLE_DETAIL", category, attribute)
exL = []
if len(exCL) == len(exDL):
for exC, exD in zip(exCL, exDL):
exL.append((exC, exD))
else:
for exC in exCL:
exL.append((exC, None))
return exL
def getExampleListAlt(self, category, attribute, fallBack=True):
vL = self.getExampleListPdbx(category, attribute)
if not vL:
vL = self.getExampleListNdb(category, attribute)
if fallBack and not vL:
vL = self.getExampleList(category, attribute)
return vL
def getExampleListNdb(self, category, attribute):
exCL = self.__getListAll("ITEM_EXAMPLE_CASE_NDB", category, attribute)
exDL = self.__getListAll("ITEM_EXAMPLE_DETAIL_NDB", category, attribute)
exL = []
if len(exCL) == len(exDL):
for exC, exD in zip(exCL, exDL):
exL.append((exC, exD))
else:
for exC in exCL:
exL.append((exC, None))
return exL
def getExampleListPdbx(self, category, attribute):
exCL = self.__getListAll("ITEM_EXAMPLE_CASE_PDBX", category, attribute)
exDL = self.__getListAll("ITEM_EXAMPLE_DETAIL_PDBX", category, attribute)
exL = []
if len(exCL) == len(exDL):
for exC, exD in zip(exCL, exDL):
exL.append((exC, exD))
else:
for exC in exCL:
exL.append((exC, None))
return exL
def getBoundaryList(self, category, attribute):
minL = self.__getListAll("ITEM_RANGE_MINIMUM", category, attribute)
maxL = self.__getListAll("ITEM_RANGE_MAXIMUM", category, attribute)
bL = []
for vMin, vMax in zip(minL, maxL):
bL.append((vMin, vMax))
return bL
def getBoundaryListAlt(self, category, attribute, fallBack=True):
vL = self.getBoundaryListPdbx(category, attribute)
if not vL:
vL = self.getBoundaryListNdb(category, attribute)
if fallBack and not vL:
vL = self.getBoundaryList(category, attribute)
return vL
def getBoundaryListNdb(self, category, attribute):
minL = self.__getListAll("ITEM_RANGE_MINIMUM_NDB", category, attribute)
maxL = self.__getListAll("ITEM_RANGE_MAXIMUM_NDB", category, attribute)
bL = []
for vMin, vMax in zip(minL, maxL):
bL.append((vMin, vMax))
#
return bL
def getBoundaryListPdbx(self, category, attribute):
minL = self.__getListAll("ITEM_RANGE_MINIMUM_PDBX", category, attribute)
maxL = self.__getListAll("ITEM_RANGE_MAXIMUM_PDBX", category, attribute)
bL = []
for vMin, vMax in zip(minL, maxL):
bL.append((vMin, vMax))
#
return bL
def getCategoryKeyList(self, category):
return self.__getList("CATEGORY_KEY_ITEMS", category, attribute=None)
def getCategoryGroupList(self, category):
return self.__getList("CATEGORY_GROUP", category, attribute=None)
def getCategoryMandatoryCode(self, category):
return self.__get("CATEGORY_MANDATORY_CODE", category, attribute=None)
def getCategoryDescription(self, category):
return self.__get("CATEGORY_DESCRIPTION", category, attribute=None)
def getCategoryNxMappingDetails(self, category):
return self.__get("CATEGORY_NX_MAPPING_DETAILS", category, attribute=None)
def getCategoryDescriptionAlt(self, category, fallBack=True):
v = self.getCategoryDescriptionPdbx(category)
if v is None:
v = self.getCategoryDescriptionNdb(category)
if fallBack and v is None:
v = self.getCategoryDescription(category)
return v
def getCategoryDescriptionNdb(self, category):
val = self.__get("CATEGORY_DESCRIPTION_NDB", category, attribute=None)
return val
def getCategoryDescriptionPdbx(self, category):
val = self.__get("CATEGORY_DESCRIPTION_PDBX", category, attribute=None)
return val
def getCategoryExampleList(self, category):
exCL = self.__getListAll("CATEGORY_EXAMPLE_CASE", category, attribute=None)
exDL = self.__getListAll("CATEGORY_EXAMPLE_DETAIL", category, attribute=None)
exL = []
if len(exCL) == len(exDL):
for exC, exD in zip(exCL, exDL):
exL.append((exC, exD))
else:
for exC in exCL:
exL.append((exC, None))
return exL
def getCategoryExampleListAlt(self, category, fallBack=True):
vL = self.getCategoryExampleListPdbx(category)
if not vL:
vL = self.getCategoryExampleListNdb(category)
if fallBack and not vL:
vL = self.getCategoryExampleList(category)
return vL
def getCategoryExampleListNdb(self, category):
exCL = self.__getListAll("CATEGORY_EXAMPLE_CASE_NDB", category, attribute=None)
exDL = self.__getListAll("CATEGORY_EXAMPLE_DETAIL_NDB", category, attribute=None)
exL = []
if len(exCL) == len(exDL):
for exC, exD in zip(exCL, exDL):
exL.append((exC, exD))
else:
for exC in exCL:
exL.append((exC, None))
return exL
def getCategoryExampleListPdbx(self, category):
exCL = self.__getListAll("CATEGORY_EXAMPLE_CASE_PDBX", category, attribute=None)
exDL = self.__getListAll("CATEGORY_EXAMPLE_DETAIL_PDBX", category, attribute=None)
exL = []
if len(exCL) == len(exDL):
for exC, exD in zip(exCL, exDL):
exL.append((exC, exD))
else:
for exC in exCL:
exL.append((exC, None))
return exL
def getParentDictionary(self):
"""Create a dictionary of parents relations accross all definnitions
as {child : [parent, parent,...]
Exclude self parents.
"""
parentD = {}
pAtN = self.__enumD["ITEM_LINKED_PARENT"][1]
cAtN = self.__enumD["ITEM_LINKED_CHILD"][1]
for dObj in self.__containerList:
dc = dObj.getObj(self.__enumD["ITEM_LINKED_PARENT"][0])
if dc is not None:
idxP = dc.getIndex(pAtN)
idxC = dc.getIndex(cAtN)
for row in dc.getRowList():
pVal = row[idxP]
cVal = row[idxC]
if pVal == cVal:
continue
if cVal not in parentD:
parentD[cVal] = []
parentD[cVal].append(pVal)
#
return parentD
def getItemLinkedConditions(self):
"""Create a dictionary of conditional item link relationships.
Returns:
(dict): {{parent_name, child_name}: [{"id": , "condition_id": , "condition_child_name": , "condition_child_value": ,
"condition_child_cmp_op": , "condition_log_op": ,}, {},...]}
Example:
```text
loop_
_pdbx_item_linked.id
_pdbx_item_linked.condition_id
_pdbx_item_linked.parent_name
_pdbx_item_linked.child_name
#
_pdbx_item_linked.condition_child_name
_pdbx_item_linked.condition_child_value
_pdbx_item_linked.condition_child_cmp_op
_pdbx_item_linked.condition_child_target_name
_pdbx_item_linked.condition_child_log_op
1 1 '_entity_poly_seq.num' '_atom_site.label_seq_id' '_atom_site.label_entity_id' . 'eq' '_entity.id' .
2 1 '_entity_poly_seq.num' '_atom_site.label_seq_id' '_entity.type' 'polymer' 'eq' . 'and'
```
"""
rD = OrderedDict()
try:
for ob in self.__containerList:
if ob.getType() == "data":
continue
tl = ob.getObj(self.__enumD["ITEM_LINKED_PDBX_ID"][0])
if tl is not None:
for row in tl.getRowList():
if (
tl.hasAttribute(self.__enumD["ITEM_LINKED_PDBX_ID"][1])
and tl.hasAttribute(self.__enumD["ITEM_LINKED_PDBX_CONDITION_ID"][1])
and tl.hasAttribute(self.__enumD["ITEM_LINKED_PDBX_CHILD_NAME"][1])
and tl.hasAttribute(self.__enumD["ITEM_LINKED_PDBX_PARENT_NAME"][1])
):
tD = OrderedDict()
tD["id"] = row[tl.getIndex(self.__enumD["ITEM_LINKED_PDBX_ID"][1])]
tD["condition_id"] = row[tl.getIndex(self.__enumD["ITEM_LINKED_PDBX_CONDITION_ID"][1])]
parentName = row[tl.getIndex(self.__enumD["ITEM_LINKED_PDBX_PARENT_NAME"][1])]
childName = row[tl.getIndex(self.__enumD["ITEM_LINKED_PDBX_CHILD_NAME"][1])]
#
tD["condition_child_name"] = (
row[tl.getIndex(self.__enumD["ITEM_LINKED_PDBX_CONDITION_CHILD_NAME"][1])]
if tl.hasAttribute(self.__enumD["ITEM_LINKED_PDBX_CONDITION_CHILD_NAME"][1])
else None
)
tD["condition_child_value"] = (
row[tl.getIndex(self.__enumD["ITEM_LINKED_PDBX_CONDITION_CHILD_VALUE"][1])]
if tl.hasAttribute(self.__enumD["ITEM_LINKED_PDBX_CONDITION_CHILD_VALUE"][1])
else None
)
tD["condition_child_cmp_op"] = (
row[tl.getIndex(self.__enumD["ITEM_LINKED_PDBX_CONDITION_CHILD_CMP_OP"][1])]
if tl.hasAttribute(self.__enumD["ITEM_LINKED_PDBX_CONDITION_CHILD_CMP_OP"][1])
else None
)
tD["condition_child_target_name"] = (
row[tl.getIndex(self.__enumD["ITEM_LINKED_PDBX_CONDITION_CHILD_TARGET_NAME"][1])]
if tl.hasAttribute(self.__enumD["ITEM_LINKED_PDBX_CONDITION_CHILD_TARGET_NAME"][1])
else None
)
tD["condition_log_op"] = (
row[tl.getIndex(self.__enumD["ITEM_LINKED_PDBX_CONDITION_LOG_OP"][1])] if tl.hasAttribute(self.__enumD["ITEM_LINKED_PDBX_CONDITION_LOG_OP"][1]) else None
)
#
rD.setdefault((parentName, childName), []).append(tD)
except Exception as e:
logger.exception("Failing with %s", str(e))
return rD
def __makeFullParentChildDictionaries(self):
"""Create a dictionaries of full parent/child relations accross all definnitions
as fullParentD[child]=[parent,parent,...]
and fullChildD[parent]=[child,child,...]
Exclude self parents.
"""
fullParentD = {}
fullChildD = {}
pAtN = self.__enumD["ITEM_LINKED_PARENT"][1]
cAtN = self.__enumD["ITEM_LINKED_CHILD"][1]
for dObj in self.__containerList:
# logger.info("\n\nSearching object %s\n" % dObj.getName())
dc = dObj.getObj(self.__enumD["ITEM_LINKED_PARENT"][0])
if dc is not None:
idxP = dc.getIndex(pAtN)
idxC = dc.getIndex(cAtN)
for row in dc.getRowList():
pVal = row[idxP]
cVal = row[idxC]
# logger.info("%s found parent %s child %s \n" % (dObj.getName(),pVal,cVal))
if pVal == cVal:
continue
if cVal not in fullParentD:
fullParentD[cVal] = []
fullParentD[cVal].append(pVal)
#
if pVal not in fullChildD:
fullChildD[pVal] = []
fullChildD[pVal].append(cVal)
#
return fullParentD, fullChildD
#
def __get(self, enumCode, category, attribute=None, followAncestors=False):
"""Return the last occurrence of the input dictionary metadata. If the value
for the input category/attribute is null/missing then optionally check for
an ancestor value.
"""
v0 = self.__getValue(enumCode, category, attribute)
if not followAncestors:
return v0
else:
if (v0 is None) or (not v0) or (v0 in [".", "?"]):
pItem = self.getUltimateParent(category, attribute)
if (pItem is not None) and pItem and (pItem != CifName.itemName(category, attribute)):
logger.debug("Reassigning enum code %s category %s attribute %s to parent %r", enumCode, category, attribute, pItem)
return self.__getValue(enumCode, CifName.categoryPart(pItem), CifName.attributePart(pItem))
return v0
#
def __getValue(self, enumCode, category, attribute=None):
"""Returns the last occurrence of the input dictionary metadata (enumCode) for the input category/attribute
encountered in the list of objects stored at the indicated definition index.
"""
eS = None
if enumCode not in self.__enumD:
return eS
if attribute is not None:
nm = "_" + category + "." + attribute
else:
nm = category
if nm in self.__definitionIndex:
dObjL = self.__definitionIndex[nm]
for dObj in dObjL:
dc = dObj.getObj(self.__enumD[enumCode][0])
if dc is not None:
atN = self.__enumD[enumCode][1]
rL = dc.getRowList()
if rL:
row = rL[0]
if atN is not None:
if dc.hasAttribute(atN):
eS = row[dc.getIndex(atN)]
else:
eS = [rv for rv in row]
return eS
def __getList(self, enumCode, category, attribute=None):
"""Return the list of unique values"""
return list(set(self.__getListAll(enumCode, category, attribute)))
def __getListAll(self, enumCode, category, attribute=None):
"""Return a list of all values"""
eL = []
if enumCode not in self.__enumD:
return eL
if attribute is not None:
nm = "_" + category + "." + attribute
else:
nm = category
if nm in self.__definitionIndex:
dObjL = self.__definitionIndex[nm]
for dObj in dObjL:
dc = dObj.getObj(self.__enumD[enumCode][0])
if dc is not None:
atN = self.__enumD[enumCode][1]
for row in dc.getRowList():
if atN is not None:
if dc.hasAttribute(atN):
eL.append(row[dc.getIndex(atN)])
else:
eL = [rv for rv in row]
return eL
def getMethodIndex(self):
return self.__methodIndex
def __makeIndex(self):
"""Create indices of definitions, categories and items."""
iD = OrderedDict()
for dD in self.__containerList:
name = dD.getName()
dType = dD.getType()
#
if name not in self.__fullIndex:
self.__fullIndex[name] = []
self.__fullIndex[name].append(dD)
#
if dType == "definition" and dD.isCategory():
if name not in self.__catNameIndex:
self.__catNameIndex[name] = []
if name not in self.__catNameItemIndex:
self.__catNameItemIndex[name] = []
if name not in self.__definitionIndex:
self.__definitionIndex[name] = []
self.__definitionIndex[name].append(dD)
elif dType == "definition" and dD.isAttribute():
catN = CifName.categoryPart(name)
attN = CifName.attributePart(name)
if catN not in self.__catNameItemIndex:
self.__catNameItemIndex[catN] = []
if name not in self.__catNameItemIndex:
self.__catNameItemIndex[catN].append(name)
if catN not in self.__catNameIndex:
self.__catNameIndex[catN] = []
if attN not in self.__catNameIndex[catN]:
self.__catNameIndex[catN].append(attN)
if name not in self.__definitionIndex:
self.__definitionIndex[name] = []
self.__definitionIndex[name].append(dD)
iD[name] = name
elif dType == "data":
for nm in dD.getObjNameList():
if nm not in self.__dataIndex:
self.__dataIndex[nm] = dD.getObj(nm)
else:
pass
#
self.__itemNameList = list(iD.keys())
def getDefinitionIndex(self):
return self.__definitionIndex
def getFullIndex(self):
return self.__fullIndex
def getMethod(self, mId):
if mId in self.__methodDict:
return self.__methodDict[mId]
else:
return None
def getCategoryList(self):
return list(self.__catNameIndex.keys())
def getCategoryIndex(self):
return self.__catNameIndex
def getAttributeNameList(self, category):
try:
return self.__catNameIndex[category]
except Exception:
pass
return []
def getItemNameList(self, category):
try:
return self.__catNameItemIndex[category]
except Exception:
pass
return []
def getSubCategoryDescription(self, subCategoryName):
if subCategoryName in self.__subCategoryDict:
return self.__subCategoryDict[subCategoryName]
else:
return ""
def __getMethods(self):
self.__methodDict = OrderedDict()
self.__methodIndex = OrderedDict()
for ob in self.__containerList:
if ob.getType() == "data":
ml = ob.getObj("method_list")
if ml is not None:
# Use row order as priority
for ii, row in enumerate(ml.getRowList(), 1):
if ml.hasAttribute("id") and ml.hasAttribute("code") and ml.hasAttribute("language") and ml.hasAttribute("implementation_source"):
tInline = row[ml.getIndex("inline")] if ml.hasAttribute("inline") else None
tImpl = row[ml.getIndex("implementation")] if ml.hasAttribute("implementation") else None
mth = MethodDefinition(
row[ml.getIndex("id")], row[ml.getIndex("code")], row[ml.getIndex("language")], tInline, ii, tImpl, row[ml.getIndex("implementation_source")]
)
self.__methodDict[row[ml.getIndex("id")]] = mth
ml = ob.getObj("datablock_methods")
if ml is not None:
for row in ml.getRowList():
if ml.hasAttribute("method_id"):
# mth = MethodReference(row[ml.getIndex('method_id')], 'datablock', ob.getName(), None)
mth = MethodReference(row[ml.getIndex("method_id")], "datablock", None, None)
if ob.getName() in self.__methodIndex:
self.__methodIndex[ob.getName()].append(mth)
else:
self.__methodIndex[ob.getName()] = []
self.__methodIndex[ob.getName()].append(mth)
elif ob.getType() == "definition":
mi = ob.getObj("category_methods")
if mi is not None:
for row in mi.getRowList():
if mi.hasAttribute("method_id"):
mth = MethodReference(row[mi.getIndex("method_id")], "category", ob.getName(), None)
if ob.getName() in self.__methodIndex:
self.__methodIndex[ob.getName()].append(mth)
else:
self.__methodIndex[ob.getName()] = []
self.__methodIndex[ob.getName()].append(mth)
mi = ob.getObj("item_methods")
if mi is not None:
for row in mi.getRowList():
if mi.hasAttribute("method_id"):
mth = MethodReference(row[mi.getIndex("method_id")], "attribute", CifName.categoryPart(ob.getName()), CifName.attributePart(ob.getName()))
if ob.getName() in self.__methodIndex:
self.__methodIndex[ob.getName()].append(mth)
else:
self.__methodIndex[ob.getName()] = []
self.__methodIndex[ob.getName()].append(mth)
else:
pass
return self.__methodIndex
def dumpCategoryIndex(self, fh=sys.stdout):
for k, vL in self.__catNameIndex.items():
uvL = list(set(vL))
fh.write("Category: %s has %d attributes\n" % (k, len(uvL)))
for v in sorted(uvL):
fh.write(" Attribute: %s\n" % v)
def dumpMethods(self, fh=sys.stdout):
for k, vL in self.__methodIndex.items():
fh.write("Method index key: %s length %d\n" % (k, len(vL)))
for v in vL:
v.printIt(fh)
#
fh.write("Inline method details\n")
for k, vL in self.__methodIndex.items():
fh.write("\n------------------------------------\n")
fh.write("Method index key: %s\n" % k)
for v in vL:
fh.write("Method ID: %r\n" % v.getId())
if self.getMethod(v.getId()):
fh.write("%r" % v)
# fh.write("Method text: %s\n" % self.getMethod(v.getId()).getInline())
else:
fh.write("Missing method for %r" % v.getId())
def dumpEnumFeatures(self, fh=sys.stdout):
for k, vL in self.__catNameIndex.items():
uvL = list(set(vL))
for v in sorted(uvL):
itL = self.getEnumList(k, v)
if itL:
fh.write("-----------------------------------------------\n")
fh.write(" Category : %s\n" % k)
fh.write(" Attribute: %s\n" % v)
fh.write(" Description: \n%s\n" % self.getDescription(k, v))
fh.write(" Type: %s\n" % self.getTypeCode(k, v))
fh.write(" Primitive type: %s\n" % self.getTypePrimitive(k, v))
fh.write(" Regex type: %s\n" % self.getTypeRegex(k, v))
fh.write(" Enum list length %d\n" % len(itL))
for it in itL:
fh.write(" Enum: %s\n" % it)
def dumpFeatures(self, fh=sys.stdout):
for k, vL in self.__catNameIndex.items():
uvL = list(set(vL))
fh.write("-----------------------------------------------\n")
fh.write("Category: %s has %d attributes\n" % (k, len(uvL)))
fh.write(" Category description: %s\n" % self.getCategoryDescription(k))
fh.write(" Alt category description: %s\n" % self.getCategoryDescriptionAlt(k))
fh.write(" Category context: %s\n" % self.getCategoryContextList(k))
ctL = self.getCategoryExampleList(k)
if ctL:
fh.write(" Category example list length %d\n" % len(ctL))
for ct1, ct2 in ctL:
fh.write(" Example case: %s\n" % ct1)
fh.write(" Example detail: %s\n" % ct2)
ctL = self.getCategoryExampleListAlt(k)
if ctL:
fh.write(" Alt category example list length %d\n" % len(ctL))
for ct1, ct2 in ctL:
fh.write(" Alt example case: %s\n" % ct1)
fh.write(" Alt example detail: %s\n" % ct2)
for v in sorted(uvL):
fh.write(" Attribute: %s\n" % v)
fh.write(" Description: %s\n" % self.getDescription(k, v))
fh.write(" Alt description: %s\n" % self.getDescriptionAlt(k, v))
fh.write(" Type: %s\n" % self.getTypeCode(k, v))
fh.write(" Alt Type: %s\n" % self.getTypeCodeAlt(k, v))
fh.write(" Primitive type: %s\n" % self.getTypePrimitive(k, v))
fh.write(" Regex type: %s\n" % self.getTypeRegex(k, v))
fh.write(" Context: %s\n" % self.getContextList(k, v))
#
fh.write(" Type conditions: %s\n" % self.getTypeConditionsCode(k, v))
fh.write(" Subcategories: %s\n" % self.getItemSubCategoryIdList(k, v))
#
itL = self.getEnumList(k, v)
if itL:
fh.write(" Enum list length %d\n" % len(itL))
for it in itL:
fh.write(" Enum: %s\n" % it)
itL = self.getParentList(k, v)
if itL:
fh.write(" Parent list length %d\n" % len(itL))
for it in itL:
fh.write(" Parent: %s\n" % it)
itL = self.getChildList(k, v)
if itL:
fh.write(" Child list length %d\n" % len(itL))
for it in itL:
fh.write(" Child: %s\n" % it)
itL = self.getExampleList(k, v)
if itL:
fh.write(" Example list length %d\n" % len(itL))
for it1, it2 in itL:
fh.write(" Example case: %s\n" % it1)
fh.write(" Example detail: %s\n" % it2)
itL = self.getBoundaryList(k, v)
if itL:
fh.write(" Boundary list length %d\n" % len(itL))
for (it1, it2) in itL:
fh.write(" Boundary condition (min,max): (%s,%s)\n" % (it1, it2))
itL = self.getEnumListAlt(k, v)
if itL:
fh.write(" Alt enum list length %d\n" % len(itL))
for it in itL:
fh.write(" Alt enum: %s\n" % it)
itL = self.getExampleListAlt(k, v)
if itL:
fh.write(" Alt example list length %d\n" % len(itL))
for it1, it2 in itL:
fh.write(" Alt example case: %s\n" % it1)
fh.write(" Alt example detail: %s\n" % it2)
itL = self.getBoundaryListAlt(k, v)
if itL:
fh.write(" Alt boundary list length %d\n" % len(itL))
for (it1, it2) in itL:
fh.write(" Alt boundary condition (min,max): (%s,%s)\n" % (it1, it2))
itL = self.getItemRelatedList(k, v)
if itL:
fh.write(" Related name list length %d\n" % len(itL))
for (it1, it2) in itL:
fh.write(" Related item name %s function code %s\n" % (it1, it2))
itL = self.getItemAliasList(k, v)
if itL:
fh.write(" Alias name list length %d\n" % len(itL))
for (it1, it2, it3) in itL:
fh.write(" Alias name %s dictionary %s version %s\n" % (it1, it2, it3))
itL = self.getItemDependentNameList(k, v)
if itL:
fh.write(" Dependent name list length %d\n" % len(itL))
for it1 in itL:
fh.write(" Dependent item name %s\n" % it1)
def dumpDataSections(self, fh=sys.stdout):
fh.write("Datablock: %r\n" % list(self.__dataBlockDictList))
fh.write("Dictionary: %r\n" % list(self.__dictionaryDictList))
fh.write("Dictionary History: %r\n" % self.__dictionaryHistoryList)
fh.write("Subcategories: %r\n" % list(self.__subCategoryDict.items()))
fh.write("Category groups: %r\n" % list(self.__categoryGroupDict.items()))
fh.write("Item units: %r\n" % list(self.__itemUnitsDict.items()))
fh.write("Item units conversions: %r \n" % self.__itemUnitsConversionList)
fh.write("Item linked groups: %r\n" % list(self.__itemLinkedGroupDict.items()))
fh.write("Item linked group item list: %r\n" % list(self.__itemLinkedGroupItemDict.items()))
def dumpItemLinkedGroups(self, fh=sys.stdout):
for categoryId, lgList in self.__itemLinkedGroupDict.items():
for lg in lgList:
if (categoryId, lg[1]) in self.__itemLinkedGroupItemDict:
fh.write(" Category %s linked group %s:\n" % (categoryId, lg[1]))
lgIList = self.__itemLinkedGroupItemDict[(categoryId, lg[1])]
for lgI in lgIList:
fh.write(" group %s --- child item %s parent item %s\n" % (lg[1], lgI[0], lgI[1]))
def __addItemLinkToDef(self, dObj, parentName, childName):
"""Add the input link relationship to the input definition object."""
if dObj.exists("item_linked"):
# update in place --
cObj = dObj.getObj("item_linked")
iFound = False
idxP = cObj.getIndex("parent_name")
idxC = cObj.getIndex("child_name")
for row in cObj.getRowList():
if parentName == row[idxP] and childName == row[idxC]:
iFound = True
break
if not iFound:
nRows = cObj.getRowCount()
cObj.setValue(childName, "child_name", nRows)
cObj.setValue(parentName, "parent_name", nRows)
logger.debug("Appending item link in category %s", dObj.getName())
return True
else:
# create new category and append to input object
cObj = DataCategory("item_linked", attributeNameList=["child_name", "parent_name"])
cObj.append([childName, parentName])
dObj.append(cObj)
logger.debug("Created new item link in category %s", dObj.getName())
return True
def __expandLoopedDefinitions(self):
"""Handle definitions containing looped item and item_linked categories --"""
fullIndex = OrderedDict()
for dD in self.__containerList:
name = dD.getName()
if name not in fullIndex:
fullIndex[name] = []
fullIndex[name].append(dD)
for name, dObjL in fullIndex.items():
if dObjL:
ob = dObjL[0]
if (ob.getType() == "definition") and ob.exists("item_linked"):
cObj = ob.getObj("item_linked")
if cObj.getRowCount() > 0:
idxP = cObj.getIndex("parent_name")
idxC = cObj.getIndex("child_name")
itemName = ob.getName()
logger.debug("Current target item %s", itemName)
cObjNext = DataCategory("item_linked", attributeNameList=["child_name", "parent_name"])
#
# Distribute the data for each row --
iChanges = 0
for row in cObj.getRowList():
#
parentItemName = row[idxP]
childItemName = row[idxC]
if parentItemName == childItemName:
continue
if childItemName != itemName:
iChanges += 1
if childItemName in fullIndex:
#
# Add this p/c link to the child definition -
#
self.__addItemLinkToDef(fullIndex[childItemName][0], parentItemName, childItemName)
else:
# error missing child definition object.
logger.warning("Missing child item %s", childItemName)
else:
cObjNext.append([row[idxC], row[idxP]])
if cObjNext.getRowCount() > 0:
ob.replace(cObjNext)
else:
ob.remove("item_linked")
def __consolidateDefinitions(self):
"""Consolidate definition attributes into a single save frame section per definition."""
fullIndex = OrderedDict()
for dD in self.__containerList:
name = dD.getName()
fullIndex.setdefault(name, []).append(dD)
# preserve the original order of sections -
#
nList = []
for dObj in self.__containerList:
nm = dObj.getName()
if nm not in nList:
nList.append(nm)
#
for name, dObjL in fullIndex.items():
if len(dObjL) > 1:
for dD in dObjL[1:]:
xList = dD.getObjNameList()
for nm in xList:
if nm not in dObjL[0].getObjNameList():
logger.debug("Adding %s to %s", nm, name)
catObj = dD.getObj(nm)
dObjL[0].append(catObj)
elif self.__replaceDefinition:
logger.debug("Replacing dictionary %s in %s", nm, name)
catObj = dD.getObj(nm)
dObjL[0].replace(catObj)
# create a new list of consolidated objects in original list order
dList = []
for nm in nList:
if nm in fullIndex:
dl = fullIndex[nm]
dList.append(dl[0])
else:
logger.info("+DictionaryApi().__consolidate() missing object name %s", nm)
# update lists
self.__containerList = dList
def getDataTypeList(self):
"""Return list of tuples containing ('code','primitive_code','construct','detail' )"""
rowList = []
for code in sorted(self.__typesDict.keys()):
tup = self.__typesDict[code]
rowList.append((code, tup[0], tup[1], tup[2]))
return rowList
def getSubCategoryList(self):
"""Return list of tuples containing ('id', 'description')"""
rowList = []
for tId in sorted(self.__subCategoryDict.keys()):
description = self.__subCategoryDict[tId]
rowList.append((tId, description))
return rowList
def getUnitsList(self):
"""Return list of tuples containing ('id', 'description')"""
rowList = []
for tId in sorted(self.__itemUnitsDict.keys()):
description = self.__itemUnitsDict[tId]
rowList.append((tId, description))
return rowList
def getUnitsConversionList(self):
"""Return list of tuples containing ('from_code','to_code','operator','factor')"""
return self.__itemUnitsConversionList
def __getDataSections(self):
""" """
for ob in self.__containerList:
if ob.getType() == "data":
logger.debug("Adding data sections from container name %s type %s", ob.getName(), ob.getType())
# add detail to data type tuple
tl = ob.getObj("item_type_list")
if tl is not None:
for row in tl.getRowList():
if tl.hasAttribute("code") and tl.hasAttribute("primitive_code") and tl.hasAttribute("construct") and tl.hasAttribute("detail"):
self.__typesDict[row[tl.getIndex("code")]] = (row[tl.getIndex("primitive_code")], row[tl.getIndex("construct")], row[tl.getIndex("detail")])
tl = ob.getObj("datablock")
if tl is not None:
rL = tl.getRowList()
if rL:
if tl.hasAttribute("id") and tl.hasAttribute("description"):
tD = OrderedDict()
row = rL[0]
tD["id"] = row[tl.getIndex("id")]
tD["description"] = row[tl.getIndex("description")]
self.__dataBlockDictList.append(tD)
tl = ob.getObj("dictionary")
if tl is not None:
rL = tl.getRowList()
if rL:
tD = OrderedDict()
row = rL[0]
if tl.hasAttribute("datablock_id"):
tD["datablock_id"] = row[tl.getIndex("datablock_id")]
if tl.hasAttribute("title"):
tD["title"] = row[tl.getIndex("title")]
if tl.hasAttribute("version"):
tD["version"] = row[tl.getIndex("version")]
self.__dictionaryDictList.append(tD)
tl = ob.getObj("dictionary_history")
if tl is not None:
# history as a list of dictionaries -
dName = ob.getName()
for row in tl.getRowList():
if tl.hasAttribute("version") and tl.hasAttribute("revision") and tl.hasAttribute("update"):
tD = OrderedDict()
tD["version"] = row[tl.getIndex("version")]
tD["revision"] = row[tl.getIndex("revision")]
tD["update"] = row[tl.getIndex("update")]
tD["dictionary"] = dName
self.__dictionaryHistoryList.append(tD)
# JDW
tl = ob.getObj("pdbx_include_dictionary")
if tl is not None:
for row in tl.getRowList():
tD = OrderedDict()
if tl.hasAttribute("dictionary_id"):
tD["dictionary_id"] = row[tl.getIndex("dictionary_id")]
if tl.hasAttribute("dictionary_locator"):
tD["dictionary_locator"] = row[tl.getIndex("dictionary_locator")]
if tl.hasAttribute("include_mode"):
tD["include_mode"] = row[tl.getIndex("include_mode")]
if tl.hasAttribute("dictionary_namespace"):
tD["dictionary_namespace_prefix"] = row[tl.getIndex("dictionary_namespace_prefix")]
if tl.hasAttribute("dictionary_namespace_replace"):
tD["dictionary_namespace_prefix"] = row[tl.getIndex("dictionary_namespace_prefix_replace")]
#
self.__dictionaryIncludeDict[tD["dictionary_id"]] = tD
#
tl = ob.getObj("pdbx_include_category")
if tl is not None:
for row in tl.getRowList():
tD = OrderedDict()
if tl.hasAttribute("dictionary_id"):
tD["dictionary_id"] = row[tl.getIndex("dictionary_id")]
if tl.hasAttribute("category_id"):
tD["category_id"] = row[tl.getIndex("category_id")]
if tl.hasAttribute("include_as_category_id"):
tD["include_as_category_id"] = row[tl.getIndex("include_as_category_id")]
if tl.hasAttribute("include_mode"):
tD["include_mode"] = row[tl.getIndex("include_mode")]
#
self.__categoryIncludeDict.setdefault(tD["dictionary_id"], {}).setdefault(tD["category_id"], tD)
tl = ob.getObj("pdbx_include_item")
if tl is not None:
for row in tl.getRowList():
tD = OrderedDict()
if tl.hasAttribute("dictionary_id"):
tD["dictionary_id"] = row[tl.getIndex("dictionary_id")]
if tl.hasAttribute("item_name"):
tD["item_name"] = row[tl.getIndex("item_name")]
if tl.hasAttribute("include_as_item_name"):
tD["include_as_item_name"] = row[tl.getIndex("include_as_item_name")]
if tl.hasAttribute("include_mode"):
tD["include_mode"] = row[tl.getIndex("include_mode")]
#
categoryId = CifName.categoryPart(tD["item_name"])
self.__itemIncludeDict.setdefault(tD["dictionary_id"], {}).setdefault(categoryId, {}).setdefault(tD["item_name"], tD)
tl = ob.getObj("dictionary_history")
if tl is not None:
# history as a list of dictionaries -
dName = ob.getName()
for row in tl.getRowList():
if tl.hasAttribute("version") and tl.hasAttribute("revision") and tl.hasAttribute("update"):
tD = OrderedDict()
tD["version"] = row[tl.getIndex("version")]
tD["revision"] = row[tl.getIndex("revision")]
tD["update"] = row[tl.getIndex("update")]
tD["dictionary"] = dName
self.__dictionaryHistoryList.append(tD)
#
tl = ob.getObj("pdbx_dictionary_component")
if tl is not None:
for row in tl.getRowList():
tD = OrderedDict()
if tl.hasAttribute("dictionary_component_id"):
tD["dictionary_component_id"] = row[tl.getIndex("dictionary_component_id")]
if tl.hasAttribute("title"):
tD["title"] = row[tl.getIndex("title")]
if tl.hasAttribute("version"):
tD["version"] = row[tl.getIndex("version")]
self.__dictionaryComponentList.append(tD)
tl = ob.getObj("pdbx_dictionary_component_history")
if tl is not None:
for row in tl.getRowList():
if tl.hasAttribute("version") and tl.hasAttribute("revision") and tl.hasAttribute("update"):
tD = OrderedDict()
tD["version"] = row[tl.getIndex("version")]
tD["revision"] = row[tl.getIndex("revision")]
tD["update"] = row[tl.getIndex("update")]
tD["dictionary_component_id"] = row[tl.getIndex("dictionary_component_id")]
self.__dictionaryComponentHistoryDict.setdefault(tD["dictionary_component_id"], []).append(tD)
# JDW
tl = ob.getObj("sub_category")
if tl is not None:
# subcategories as a dictionary by id
self.__subCategoryDict = OrderedDict()
for row in tl.getRowList():
if tl.hasAttribute("id") and tl.hasAttribute("description"):
self.__subCategoryDict[row[tl.getIndex("id")]] = row[tl.getIndex("description")]
tl = ob.getObj("category_group_list")
if tl is not None:
# category groups as a dictionary by id of tuples
self.__categoryGroupDict = OrderedDict()
for row in tl.getRowList():
if tl.hasAttribute("id") and tl.hasAttribute("description") and tl.hasAttribute("parent_id"):
tD = OrderedDict()
tD["description"] = row[tl.getIndex("description")]
tD["parent_id"] = row[tl.getIndex("parent_id")]
tD["categories"] = []
self.__categoryGroupDict[row[tl.getIndex("id")]] = tD
tl = ob.getObj("item_units_list")
if tl is not None:
# units as a dictionary by code
self.__itemUnitsDict = OrderedDict()
for row in tl.getRowList():
if tl.hasAttribute("code") and tl.hasAttribute("detail"):
self.__itemUnitsDict[row[tl.getIndex("code")]] = row[tl.getIndex("detail")]
tl = ob.getObj("item_units_conversion")
if tl is not None:
# units conversion as a simple list now
self.__itemUnitsConversionList = []
for row in tl.getRowList():
if tl.hasAttribute("from_code") and tl.hasAttribute("to_code") and tl.hasAttribute("operator") and tl.hasAttribute("factor"):
self.__itemUnitsConversionList.append((row[tl.getIndex("from_code")], row[tl.getIndex("to_code")], row[tl.getIndex("operator")], row[tl.getIndex("factor")]))
tl = ob.getObj("pdbx_item_linked_group")
if tl is not None:
# parent-child collections [category_id] -> [(1,...),(3,...),(4,...) ]
self.__itemLinkedGroupDict = OrderedDict()
for row in tl.getRowList():
if (
tl.hasAttribute("category_id")
and tl.hasAttribute("link_group_id")
and tl.hasAttribute("label")
and tl.hasAttribute("context")
and tl.hasAttribute("condition_id")
):
categoryId = row[tl.getIndex("category_id")]
if categoryId not in self.__itemLinkedGroupDict:
self.__itemLinkedGroupDict[categoryId] = []
self.__itemLinkedGroupDict[categoryId].append(
(row[tl.getIndex("category_id")], row[tl.getIndex("link_group_id")], row[tl.getIndex("context")], row[tl.getIndex("condition_id")])
)
tl = ob.getObj("pdbx_item_linked_group_list")
if tl is not None:
# parent-child collections [(category_id,link_group_id)] -> [(child_name,parent_name,parent_category),(,...),(,...) ]
self.__itemLinkedGroupItemDict = OrderedDict()
for row in tl.getRowList():
if (
tl.hasAttribute("child_category_id")
and tl.hasAttribute("link_group_id")
and tl.hasAttribute("child_name")
and tl.hasAttribute("parent_name")
and tl.hasAttribute("parent_category_id")
):
childCategoryId = row[tl.getIndex("child_category_id")]
linkGroupId = row[tl.getIndex("link_group_id")]
if (childCategoryId, linkGroupId) not in self.__itemLinkedGroupItemDict:
self.__itemLinkedGroupItemDict[(childCategoryId, linkGroupId)] = []
self.__itemLinkedGroupItemDict[(childCategoryId, linkGroupId)].append(
(row[tl.getIndex("child_name")], row[tl.getIndex("parent_name")], row[tl.getIndex("parent_category_id")])
)
#
tl = ob.getObj("pdbx_item_value_condition_list")
if tl is not None:
for row in tl.getRowList():
if tl.hasAttribute("dependent_item_name") and tl.hasAttribute("dependent_item_cmp_op") and tl.hasAttribute("target_item_name") and tl.hasAttribute("cond_id"):
tD = OrderedDict()
tD["cond_id"] = row[tl.getIndex("cond_id")]
tD["target_item_name"] = row[tl.getIndex("target_item_name")]
tD["dependent_item_name"] = row[tl.getIndex("dependent_item_name")]
tD["dependent_item_cmp_op"] = row[tl.getIndex("dependent_item_cmp_op")]
tD["target_item_value"] = row[tl.getIndex("target_item_value")] if tl.hasAttribute("target_item_value") else None
tD["dependent_item_value"] = row[tl.getIndex("dependent_item_value")] if tl.hasAttribute("dependent_item_value") else None
tD["log_op"] = row[tl.getIndex("log_op")] if tl.hasAttribute("log_op") else "and"
self.__itemValueConditionDict.setdefault(tD["target_item_name"], {}).setdefault(tD["dependent_item_name"], []).append(tD)
#
tl = ob.getObj("pdbx_comparison_operator_list")
if tl is not None:
for row in tl.getRowList():
if tl.hasAttribute("code") and tl.hasAttribute("description"):
tD = OrderedDict()
tD["code"] = row[tl.getIndex("code")]
tD["description"] = row[tl.getIndex("description")]
self.__compOpDict[tD["code"]] = tD["description"]
__init__(self, containerList, consolidate=True, expandItemLinked=False, replaceDefinition=False, **kwargs)
special
Return an instance of the mmCIF dictionary API.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
containerList |
list |
list of definition or data containers holding dictionary content |
required |
consolidate |
bool |
consolidate dictionary attributes within a single definition. Defaults to True. |
True |
expandItemLinked |
bool |
distribute item and item linked attributes defined for the parent to child definitions. Defaults to False. |
False |
replaceDefinition |
bool |
when consolidating definitions in the case of multiple occurences of the same definition, attributes from the latter occurences replace prior definitions content. Defaults to False. |
False |
Source code in mmcif/api/DictionaryApi.py
def __init__(self, containerList, consolidate=True, expandItemLinked=False, replaceDefinition=False, **kwargs):
"""Return an instance of the mmCIF dictionary API.
Args:
containerList (list): list of definition or data containers holding dictionary content
consolidate (bool, optional): consolidate dictionary attributes within a single definition. Defaults to True.
expandItemLinked (bool, optional): distribute item and item linked attributes defined for the parent
to child definitions. Defaults to False.
replaceDefinition (bool, optional): when consolidating definitions in the case of multiple occurences of the same definition,
attributes from the latter occurences replace prior definitions content. Defaults to False.
"""
_ = kwargs
#
self.__containerList = containerList
self.__replaceDefinition = replaceDefinition
#
if consolidate:
self.__consolidateDefinitions()
#
if expandItemLinked:
self.__expandLoopedDefinitions()
self.__fullIndex = OrderedDict()
# ---
#
# Map category name to the unique list of attributes
self.__catNameIndex = OrderedDict()
# Map category name to the unique list of item names
self.__catNameItemIndex = OrderedDict()
# Full unique list of item names -
self.__itemNameList = []
#
# Map dictionary objects names to definition containers -
self.__definitionIndex = OrderedDict()
#
# data section/objects of the dictionary by category name -
self.__dataIndex = OrderedDict()
#
# Map of types id->(regex,primitive_type)
self.__typesDict = OrderedDict()
#
self.__enumD = {
"ENUMERATION_VALUE": ("item_enumeration", "value"),
"ENUMERATION_DETAIL": ("item_enumeration", "detail"),
"ENUMERATION_TYPE_UNITS": ("item_enumeration", "rcsb_type_units_code"),
"ENUMERATION_DETAIL_BRIEF": ("item_enumeration", "rcsb_detail_brief"),
"ENUMERATION_TUPLE": ("item_enumeration", None),
"ITEM_LINKED_PARENT": ("item_linked", "parent_name"),
"ITEM_LINKED_CHILD": ("item_linked", "child_name"),
"DATA_TYPE_CODE": ("item_type", "code"),
"DATA_TYPE_REGEX": ("item_type_list", "construct"),
"DATA_TYPE_PRIMITIVE": ("item_type_list", "primitive_code"),
"ITEM_NAME": ("item", "name"),
"ITEM_CATEGORY_ID": ("item", "category_id"),
"ITEM_MANDATORY_CODE": ("item", "mandatory_code"),
"ITEM_DESCRIPTION": ("item_description", "description"),
"ITEM_UNITS": ("item_units", "code"),
"ITEM_DEFAULT_VALUE": ("item_default", "value"),
"ITEM_EXAMPLE_CASE": ("item_examples", "case"),
"ITEM_EXAMPLE_DETAIL": ("item_examples", "detail"),
"ITEM_RANGE_MAXIMUM": ("item_range", "maximum"),
"ITEM_RANGE_MINIMUM": ("item_range", "minimum"),
"CATEGORY_KEY_ITEMS": ("category_key", "name"),
"CATEGORY_EXAMPLE_CASE": ("category_examples", "case"),
"CATEGORY_EXAMPLE_DETAIL": ("category_examples", "detail"),
"CATEGORY_MANDATORY_CODE": ("category", "mandatory_code"),
"CATEGORY_DESCRIPTION": ("category", "description"),
"CATEGORY_NX_MAPPING_DETAILS": ("category", "NX_mapping_details"),
#
"DATA_TYPE_CODE_NDB": ("ndb_item_type", "code"),
"ITEM_DESCRIPTION_NDB": ("ndb_item_description", "description"),
"ENUMERATION_VALUE_NDB": ("ndb_item_enumeration", "value"),
"ENUMERATION_DETAIL_NDB": ("ndb_item_enumeration", "detail"),
"ITEM_MANDATORY_CODE_NDB": ("ndb_item", "mandatory_code"),
"ITEM_EXAMPLE_CASE_NDB": ("ndb_item_examples", "case"),
"ITEM_EXAMPLE_DETAIL_NDB": ("ndb_item_examples", "detail"),
"ITEM_RANGE_MAXIMUM_NDB": ("ndb_item_range", "maximum"),
"ITEM_RANGE_MINIMUM_NDB": ("ndb_item_range", "minimum"),
"CATEGORY_EXAMPLE_CASE_NDB": ("ndb_category_examples", "case"),
"CATEGORY_EXAMPLE_DETAIL_NDB": ("ndb_category_examples", "detail"),
"CATEGORY_DESCRIPTION_NDB": ("ndb_category_description", "description"),
#
"DATA_TYPE_CODE_PDBX": ("pdbx_item_type", "code"),
"ITEM_DESCRIPTION_PDBX": ("pdbx_item_description", "description"),
"ENUMERATION_VALUE_PDBX": ("pdbx_item_enumeration", "value"),
"ENUMERATION_DETAIL_PDBX": ("pdbx_item_enumeration", "detail"),
"ENUMERATION_TYPE_UNITS_PDBX": ("pdbx_item_enumeration", "type_units_code"),
"ENUMERATION_DETAIL_BRIEF_PDBX": ("pdbx_item_enumeration", "detail_brief"),
"ITEM_MANDATORY_CODE_PDBX": ("pdbx_item", "mandatory_code"),
"ITEM_EXAMPLE_CASE_PDBX": ("pdbx_item_examples", "case"),
"ITEM_EXAMPLE_DETAIL_PDBX": ("pdbx_item_examples", "detail"),
"ITEM_RANGE_MAXIMUM_PDBX": ("pdbx_item_range", "maximum"),
"ITEM_RANGE_MINIMUM_PDBX": ("pdbx_item_range", "minimum"),
"CATEGORY_EXAMPLE_CASE_PDBX": ("pdbx_category_examples", "case"),
"CATEGORY_EXAMPLE_DETAIL_PDBX": ("pdbx_category_examples", "detail"),
"CATEGORY_DESCRIPTION_PDBX": ("pdbx_category_description", "description"),
#
"CATEGORY_CONTEXT": ("pdbx_category_context", "type"),
"CATEGORY_GROUP": ("category_group", "id"),
"ITEM_CONTEXT": ("pdbx_item_context", "type"),
"ENUMERATION_CLOSED_FLAG": ("pdbx_item_enumeration_details", "closed_flag"),
#
"ITEM_RELATED_FUNCTION_CODE": ("item_related", "function_code"),
"ITEM_RELATED_RELATED_NAME": ("item_related", "related_name"),
"ITEM_ALIAS_ALIAS_NAME": ("item_aliases", "alias_name"),
"ITEM_ALIAS_DICTIONARY": ("item_aliases", "dictionary"),
"ITEM_ALIAS_VERSION": ("item_aliases", "version"),
"ITEM_DEPENDENT_DEPENDENT_NAME": ("item_dependent", "dependent_name"),
"ITEM_SUB_CATEGORY_ID": ("item_sub_category", "id"),
"ITEM_SUB_CATEGORY_LABEL": ("item_sub_category", "pdbx_label"),
"ITEM_TYPE_CONDITIONS_CODE": ("item_type_conditions", "code"),
#
"ITEM_VALUE_CONDITION_DEPENDENT_NAME": ("pdbx_item_value_condition", "dependent_item_name"),
#
"ITEM_LINKED_PDBX_ID": ("pdbx_item_linked", "id"),
"ITEM_LINKED_PDBX_CONDITION_ID": ("pdbx_item_linked", "condition_id"),
"ITEM_LINKED_PDBX_PARENT_NAME": ("pdbx_item_linked", "parent_name"),
"ITEM_LINKED_PDBX_CHILD_NAME": ("pdbx_item_linked", "child_name"),
#
"ITEM_LINKED_PDBX_CONDITION_CHILD_NAME": ("pdbx_item_linked", "condition_child_name"),
"ITEM_LINKED_PDBX_CONDITION_CHILD_VALUE": ("pdbx_item_linked", "condition_child_value"),
"ITEM_LINKED_PDBX_CONDITION_CHILD_TARGET_NAME": ("pdbx_item_linked", "condition_child_target_name"),
"ITEM_LINKED_PDBX_CONDITION_CHILD_CMP_OP": ("pdbx_item_linked", "condition_child_cmp_op"),
"ITEM_LINKED_PDBX_CONDITION_LOG_OP": ("pdbx_item_linked", "condition_log_op"),
}
#
self.__methodDict = OrderedDict()
self.__methodIndex = OrderedDict()
#
self.__makeIndex()
self.__getMethods()
#
self.__fullParentD, self.__fullChildD = self.__makeFullParentChildDictionaries()
#
#
self.__dataBlockDictList = []
self.__dictionaryDictList = []
#
self.__subCategoryDict = OrderedDict()
self.__categoryGroupDict = OrderedDict()
self.__groupIndex = False
self.__groupChildIndex = OrderedDict()
#
# Data sections -
#
self.__dictionaryHistoryList = []
self.__itemUnitsDict = OrderedDict()
self.__itemUnitsConversionList = []
self.__itemLinkedGroupDict = OrderedDict()
self.__itemLinkedGroupItemDict = OrderedDict()
#
self.__dictionaryIncludeDict = OrderedDict()
self.__categoryIncludeDict = OrderedDict()
self.__itemIncludeDict = OrderedDict()
#
self.__dictionaryComponentList = []
self.__dictionaryComponentHistoryDict = OrderedDict()
#
self.__itemValueConditionDict = OrderedDict()
self.__compOpDict = OrderedDict()
#
self.__getDataSections()
#
getDataTypeList(self)
Return list of tuples containing ('code','primitive_code','construct','detail' )
Source code in mmcif/api/DictionaryApi.py
def getDataTypeList(self):
"""Return list of tuples containing ('code','primitive_code','construct','detail' )"""
rowList = []
for code in sorted(self.__typesDict.keys()):
tup = self.__typesDict[code]
rowList.append((code, tup[0], tup[1], tup[2]))
return rowList
getDictionaryComponentCount(self)
Get the count of dictionary components.
Source code in mmcif/api/DictionaryApi.py
def getDictionaryComponentCount(self):
"""Get the count of dictionary components."""
try:
return len(self.__dictionaryComponentList)
except Exception:
return 0
getDictionaryComponentDetails(self)
Returns the component dictionary list as tuples [(version,title,dictionary_component_id),...]
Source code in mmcif/api/DictionaryApi.py
def getDictionaryComponentDetails(self):
"""Returns the component dictionary list as tuples [(version,title,dictionary_component_id),...]"""
oL = []
try:
for tD in self.__dictionaryComponentList:
oL.append((tD["version"], tD["title"], tD["dictionary_component_id"]))
except Exception:
pass
return oL
getDictionaryComponentHistory(self, dictionaryComponentId, order='reverse')
Returns the revision history as a list of tuples [(version,update,revisionText,dictionary),...]
Source code in mmcif/api/DictionaryApi.py
def getDictionaryComponentHistory(self, dictionaryComponentId, order="reverse"):
"""Returns the revision history as a list of tuples [(version,update,revisionText,dictionary),...]"""
oL = []
try:
if order == "reverse":
for tD in reversed(self.__dictionaryComponentHistoryDict[dictionaryComponentId]):
oL.append((tD["version"], tD["update"], tD["revision"], tD["dictionary_component_id"]))
else:
for tD in self.__dictionaryComponentHistoryDict[dictionaryComponentId]:
oL.append((tD["version"], tD["update"], tD["revision"], tD["dictionary_component_id"]))
except Exception:
pass
return oL
getDictionaryComponents(self)
Get the list of dictionary components.
Source code in mmcif/api/DictionaryApi.py
def getDictionaryComponents(self):
"""Get the list of dictionary components."""
try:
return list(self.__dictionaryComponentHistoryDict.keys())
except Exception:
return []
getDictionaryHistory(self, order='reverse')
Returns the revision history as a list of tuples [(version,update,revisionText,dictionary),...]
Source code in mmcif/api/DictionaryApi.py
def getDictionaryHistory(self, order="reverse"):
"""Returns the revision history as a list of tuples [(version,update,revisionText,dictionary),...]"""
oL = []
try:
if order == "reverse":
for tD in reversed(self.__dictionaryHistoryList):
oL.append((tD["version"], tD["update"], tD["revision"], tD["dictionary"]))
else:
for tD in self.__dictionaryHistoryList:
oL.append((tD["version"], tD["update"], tD["revision"], tD["dictionary"]))
except Exception:
pass
return oL
getDictionaryRevisionCount(self)
Get the count of revision history records.
Source code in mmcif/api/DictionaryApi.py
def getDictionaryRevisionCount(self):
"""Get the count of revision history records."""
try:
return len(self.__dictionaryHistoryList)
except Exception:
return 0
getDictionaryUpdate(self, order='reverse')
Get details from the first/last history element.
Source code in mmcif/api/DictionaryApi.py
def getDictionaryUpdate(self, order="reverse"):
"""Get details from the first/last history element."""
try:
if order == "reverse":
tD = self.__dictionaryHistoryList[-1]
else:
tD = self.__dictionaryHistoryList[0]
return tD["update"]
except Exception:
return None
getItemLinkedConditions(self)
Create a dictionary of conditional item link relationships.
Returns:
Type | Description |
---|---|
(dict) |
{{parent_name, child_name}: [{"id": , "condition_id": , "condition_child_name": , "condition_child_value": , "condition_child_cmp_op": , "condition_log_op": ,}, {},...]} |
Examples:
loop_
_pdbx_item_linked.id
_pdbx_item_linked.condition_id
_pdbx_item_linked.parent_name
_pdbx_item_linked.child_name
#
_pdbx_item_linked.condition_child_name
_pdbx_item_linked.condition_child_value
_pdbx_item_linked.condition_child_cmp_op
_pdbx_item_linked.condition_child_target_name
_pdbx_item_linked.condition_child_log_op
1 1 '_entity_poly_seq.num' '_atom_site.label_seq_id' '_atom_site.label_entity_id' . 'eq' '_entity.id' .
2 1 '_entity_poly_seq.num' '_atom_site.label_seq_id' '_entity.type' 'polymer' 'eq' . 'and'
Source code in mmcif/api/DictionaryApi.py
def getItemLinkedConditions(self):
"""Create a dictionary of conditional item link relationships.
Returns:
(dict): {{parent_name, child_name}: [{"id": , "condition_id": , "condition_child_name": , "condition_child_value": ,
"condition_child_cmp_op": , "condition_log_op": ,}, {},...]}
Example:
```text
loop_
_pdbx_item_linked.id
_pdbx_item_linked.condition_id
_pdbx_item_linked.parent_name
_pdbx_item_linked.child_name
#
_pdbx_item_linked.condition_child_name
_pdbx_item_linked.condition_child_value
_pdbx_item_linked.condition_child_cmp_op
_pdbx_item_linked.condition_child_target_name
_pdbx_item_linked.condition_child_log_op
1 1 '_entity_poly_seq.num' '_atom_site.label_seq_id' '_atom_site.label_entity_id' . 'eq' '_entity.id' .
2 1 '_entity_poly_seq.num' '_atom_site.label_seq_id' '_entity.type' 'polymer' 'eq' . 'and'
```
"""
rD = OrderedDict()
try:
for ob in self.__containerList:
if ob.getType() == "data":
continue
tl = ob.getObj(self.__enumD["ITEM_LINKED_PDBX_ID"][0])
if tl is not None:
for row in tl.getRowList():
if (
tl.hasAttribute(self.__enumD["ITEM_LINKED_PDBX_ID"][1])
and tl.hasAttribute(self.__enumD["ITEM_LINKED_PDBX_CONDITION_ID"][1])
and tl.hasAttribute(self.__enumD["ITEM_LINKED_PDBX_CHILD_NAME"][1])
and tl.hasAttribute(self.__enumD["ITEM_LINKED_PDBX_PARENT_NAME"][1])
):
tD = OrderedDict()
tD["id"] = row[tl.getIndex(self.__enumD["ITEM_LINKED_PDBX_ID"][1])]
tD["condition_id"] = row[tl.getIndex(self.__enumD["ITEM_LINKED_PDBX_CONDITION_ID"][1])]
parentName = row[tl.getIndex(self.__enumD["ITEM_LINKED_PDBX_PARENT_NAME"][1])]
childName = row[tl.getIndex(self.__enumD["ITEM_LINKED_PDBX_CHILD_NAME"][1])]
#
tD["condition_child_name"] = (
row[tl.getIndex(self.__enumD["ITEM_LINKED_PDBX_CONDITION_CHILD_NAME"][1])]
if tl.hasAttribute(self.__enumD["ITEM_LINKED_PDBX_CONDITION_CHILD_NAME"][1])
else None
)
tD["condition_child_value"] = (
row[tl.getIndex(self.__enumD["ITEM_LINKED_PDBX_CONDITION_CHILD_VALUE"][1])]
if tl.hasAttribute(self.__enumD["ITEM_LINKED_PDBX_CONDITION_CHILD_VALUE"][1])
else None
)
tD["condition_child_cmp_op"] = (
row[tl.getIndex(self.__enumD["ITEM_LINKED_PDBX_CONDITION_CHILD_CMP_OP"][1])]
if tl.hasAttribute(self.__enumD["ITEM_LINKED_PDBX_CONDITION_CHILD_CMP_OP"][1])
else None
)
tD["condition_child_target_name"] = (
row[tl.getIndex(self.__enumD["ITEM_LINKED_PDBX_CONDITION_CHILD_TARGET_NAME"][1])]
if tl.hasAttribute(self.__enumD["ITEM_LINKED_PDBX_CONDITION_CHILD_TARGET_NAME"][1])
else None
)
tD["condition_log_op"] = (
row[tl.getIndex(self.__enumD["ITEM_LINKED_PDBX_CONDITION_LOG_OP"][1])] if tl.hasAttribute(self.__enumD["ITEM_LINKED_PDBX_CONDITION_LOG_OP"][1]) else None
)
#
rD.setdefault((parentName, childName), []).append(tD)
except Exception as e:
logger.exception("Failing with %s", str(e))
return rD
getParentDictionary(self)
Create a dictionary of parents relations accross all definnitions as {child : [parent, parent,...]
Exclude self parents.
Source code in mmcif/api/DictionaryApi.py
def getParentDictionary(self):
"""Create a dictionary of parents relations accross all definnitions
as {child : [parent, parent,...]
Exclude self parents.
"""
parentD = {}
pAtN = self.__enumD["ITEM_LINKED_PARENT"][1]
cAtN = self.__enumD["ITEM_LINKED_CHILD"][1]
for dObj in self.__containerList:
dc = dObj.getObj(self.__enumD["ITEM_LINKED_PARENT"][0])
if dc is not None:
idxP = dc.getIndex(pAtN)
idxC = dc.getIndex(cAtN)
for row in dc.getRowList():
pVal = row[idxP]
cVal = row[idxC]
if pVal == cVal:
continue
if cVal not in parentD:
parentD[cVal] = []
parentD[cVal].append(pVal)
#
return parentD
getSubCategoryList(self)
Return list of tuples containing ('id', 'description')
Source code in mmcif/api/DictionaryApi.py
def getSubCategoryList(self):
"""Return list of tuples containing ('id', 'description')"""
rowList = []
for tId in sorted(self.__subCategoryDict.keys()):
description = self.__subCategoryDict[tId]
rowList.append((tId, description))
return rowList
getUltimateParent(self, category, attribute)
Return the first ultimate parent item for the input item.
Source code in mmcif/api/DictionaryApi.py
def getUltimateParent(self, category, attribute):
"""Return the first ultimate parent item for the input item."""
# pL=self.__getList('ITEM_LINKED_PARENT',category,attribute)
pL = self.getFullParentList(category, attribute)
itemName = CifName.itemName(category, attribute)
while pL and (pL[0] != itemName):
attN = CifName.attributePart(pL[0])
catN = CifName.categoryPart(pL[0])
itemName = pL[0]
pL = self.getFullParentList(catN, attN)
# pL=self.__getList('ITEM_LINKED_PARENT',catN,attN)
return itemName
getUnitsConversionList(self)
Return list of tuples containing ('from_code','to_code','operator','factor')
Source code in mmcif/api/DictionaryApi.py
def getUnitsConversionList(self):
"""Return list of tuples containing ('from_code','to_code','operator','factor')"""
return self.__itemUnitsConversionList
getUnitsList(self)
Return list of tuples containing ('id', 'description')
Source code in mmcif/api/DictionaryApi.py
def getUnitsList(self):
"""Return list of tuples containing ('id', 'description')"""
rowList = []
for tId in sorted(self.__itemUnitsDict.keys()):
description = self.__itemUnitsDict[tId]
rowList.append((tId, description))
return rowList