From 03582ae21abc493b09fe106ab684bcf0e34a416e Mon Sep 17 00:00:00 2001 From: ":GH_USER" <:GH_EMAIL> Date: Wed, 6 Dec 2023 17:03:25 +0000 Subject: [PATCH] Deployed a405085 with MkDocs version: 1.5.3 --- api_reference/BinaryCifWriter/index.html | 22 +- api_reference/DataCategoryTyped/index.html | 3 +- api_reference/IoAdapterCore/index.html | 332 +++++++----- api_reference/IoAdapterPy/index.html | 600 ++++++++++++++------- search/search_index.json | 2 +- sitemap.xml | 42 +- sitemap.xml.gz | Bin 380 -> 381 bytes 7 files changed, 664 insertions(+), 337 deletions(-) diff --git a/api_reference/BinaryCifWriter/index.html b/api_reference/BinaryCifWriter/index.html index 4e990bb8..93ad17e5 100644 --- a/api_reference/BinaryCifWriter/index.html +++ b/api_reference/BinaryCifWriter/index.html @@ -1195,7 +1195,7 @@
class BinaryCifWriter(object):
"""Writer methods for the binary CIF format."""
- def __init__(self, dictionaryApi, storeStringsAsBytes=False, defaultStringEncoding="utf-8", applyTypes=True, useStringTypes=False, useFloat64=False):
+ def __init__(self, dictionaryApi, storeStringsAsBytes=False, defaultStringEncoding="utf-8", applyTypes=True, useStringTypes=False, useFloat64=False, copyInputData=False):
"""Create an instance of the binary CIF writer class.
Args:
@@ -1205,6 +1205,7 @@ BinaryCifWriter
applyTypes (bool, optional): apply explicit data typing before encoding. Defaults to True.
useStringTypes (bool, optional): assume all types are string. Defaults to False.
useFloat64 (bool, optional): store floats with 64 bit precision. Defaults to False.
+ copyInputData (bool, optional): make a new copy input data. Defaults to False.
"""
self.__version = "0.01"
self.__storeStringsAsBytes = storeStringsAsBytes
@@ -1213,6 +1214,7 @@ BinaryCifWriter
self.__useStringTypes = useStringTypes
self.__useFloat64 = useFloat64
self.__dApi = dictionaryApi
+ self.__copyInputData = copyInputData
def serialize(self, filePath, containerList):
"""Serialize the input container list in binary CIF and store these data in the input file path.
@@ -1231,7 +1233,7 @@ BinaryCifWriter
for catName in container.getObjNameList():
cObj = container.getObj(catName)
if self.__applyTypes:
- cObj = DataCategoryTyped(cObj, dictionaryApi=self.__dApi, copyInputData=False)
+ cObj = DataCategoryTyped(cObj, dictionaryApi=self.__dApi, copyInputData=self.__copyInputData)
#
rowCount = cObj.getRowCount()
#
@@ -1302,7 +1304,7 @@ BinaryCifWriter
"""
cifDataType = self.__dApi.getTypeCode(dObj.getName(), atName)
cifPrimitiveType = self.__dApi.getTypePrimitive(dObj.getName(), atName)
- dataType = "integer" if "int" in cifDataType else "float" if cifPrimitiveType == "numb" else "string"
+ dataType = "string" if cifDataType is None else "integer" if "int" in cifDataType else "float" if cifPrimitiveType == "numb" else "string"
return dataType
__init__(self, dictionaryApi, storeStringsAsBytes=False, defaultStringEncoding='utf-8', applyTypes=True, useStringTypes=False, useFloat64=False)
+__init__(self, dictionaryApi, storeStringsAsBytes=False, defaultStringEncoding='utf-8', applyTypes=True, useStringTypes=False, useFloat64=False, copyInputData=False)
special
@@ -1383,11 +1385,17 @@ mmcif/io/BinaryCifWriter.py
def __init__(self, dictionaryApi, storeStringsAsBytes=False, defaultStringEncoding="utf-8", applyTypes=True, useStringTypes=False, useFloat64=False):
+ def __init__(self, dictionaryApi, storeStringsAsBytes=False, defaultStringEncoding="utf-8", applyTypes=True, useStringTypes=False, useFloat64=False, copyInputData=False):
"""Create an instance of the binary CIF writer class.
Args:
@@ -1397,6 +1405,7 @@ applyTypes (bool, optional): apply explicit data typing before encoding. Defaults to True.
useStringTypes (bool, optional): assume all types are string. Defaults to False.
useFloat64 (bool, optional): store floats with 64 bit precision. Defaults to False.
+ copyInputData (bool, optional): make a new copy input data. Defaults to False.
"""
self.__version = "0.01"
self.__storeStringsAsBytes = storeStringsAsBytes
@@ -1405,6 +1414,7 @@ self.__useStringTypes = useStringTypes
self.__useFloat64 = useFloat64
self.__dApi = dictionaryApi
+ self.__copyInputData = copyInputData
class IoAdapterCore(IoAdapterBase):
"""Adapter between Python mmCIF API and Pybind11 wrappers for the PDB C++ Core mmCIF Library."""
- # def __init__(self, *args, **kwargs):
- # super(IoAdapterCore, self).__init__(*args, **kwargs)
# pylint: disable=arguments-differ
- def readFile(self, inputFilePath, enforceAscii=True, selectList=None, excludeFlag=False, logFilePath=None, outDirPath=None, cleanUp=True, **kwargs):
+ def readFile(
+ self,
+ inputFilePath,
+ enforceAscii=True,
+ selectList=None,
+ excludeFlag=False,
+ logFilePath=None,
+ outDirPath=None,
+ cleanUp=True,
+ fmt="mmcif",
+ **kwargs
+ ):
"""Parse the data blocks in the input mmCIF format data file into list of DataContainers(). The data category content within each data block
is stored a collection of DataCategory objects within each DataContainer.
@@ -1030,6 +1039,8 @@ IoAdapterCore
logFilePath (string, optional): Log file path (if not provided this will be derived from the input file.)
outDirPath (string, optional): Path for translated/reencoded files and default logfiles.
cleanUp (bool, optional): Flag to automatically remove logs and temporary files on exit.
+ fmt (string, optional): Format of input file (currently only supports "mmcif"). Defaults to "mmcif".
+
**kwargs: Placeholder for missing keyword arguments.
Returns:
@@ -1041,6 +1052,7 @@ IoAdapterCore
filePath = str(inputFilePath)
# oPath = outDirPath if outDirPath else '.'
oPath = self._chooseTemporaryPath(inputFilePath, outDirPath=outDirPath)
+ containerL = []
try:
#
lPath = logFilePath
@@ -1052,28 +1064,33 @@ IoAdapterCore
if not self._fileExists(filePath):
return []
#
- filePath = self._uncompress(filePath, oPath)
- tPath = filePath
- if enforceAscii:
- asciiFilePath = self._getDefaultFileName(filePath, fileType="cif-parser-ascii", fileExt="cif", outDirPath=oPath)
- encodingErrors = "xmlcharrefreplace" if self._useCharRefs else "ignore"
- logger.debug("Filtering input file to %s using encoding errors as %s", asciiFilePath, encodingErrors)
- ok = self._toAscii(filePath, asciiFilePath, chunkSize=5000, encodingErrors=encodingErrors, readEncodingErrors=self._readEncodingErrors)
- if ok:
- tPath = asciiFilePath
- #
- readDef = None
- if selectList is not None and selectList:
- readDef = self.__getSelectionDef(selectList, excludeFlag)
+ fmt = fmt.lower()
#
- containerL, _ = self.__readData(tPath, readDef=readDef, cleanUp=cleanUp, logFilePath=lPath, maxLineLength=self._maxInputLineLength)
- #
- if cleanUp:
- self._cleanupFile(asciiFilePath, asciiFilePath)
- self._cleanupFile(filePath != str(inputFilePath), filePath)
- self._setContainerProperties(containerL, locator=str(inputFilePath), load_date=self._getTimeStamp(), uid=uuid.uuid4().hex)
+ if fmt == "mmcif":
+ filePath = self._uncompress(filePath, oPath)
+ tPath = filePath
+ if enforceAscii:
+ asciiFilePath = self._getDefaultFileName(filePath, fileType="cif-parser-ascii", fileExt="cif", outDirPath=oPath)
+ encodingErrors = "xmlcharrefreplace" if self._useCharRefs else "ignore"
+ logger.debug("Filtering input file to %s using encoding errors as %s", asciiFilePath, encodingErrors)
+ ok = self._toAscii(filePath, asciiFilePath, chunkSize=5000, encodingErrors=encodingErrors, readEncodingErrors=self._readEncodingErrors)
+ if ok:
+ tPath = asciiFilePath
+ #
+ readDef = None
+ if selectList is not None and selectList:
+ readDef = self.__getSelectionDef(selectList, excludeFlag)
+ #
+ containerL, _ = self.__readData(tPath, readDef=readDef, cleanUp=cleanUp, logFilePath=lPath, maxLineLength=self._maxInputLineLength)
+ #
+ if cleanUp:
+ self._cleanupFile(asciiFilePath, asciiFilePath)
+ self._cleanupFile(filePath != str(inputFilePath), filePath)
+ self._setContainerProperties(containerL, locator=str(inputFilePath), load_date=self._getTimeStamp(), uid=uuid.uuid4().hex)
#
- return containerL
+ else:
+ logger.error("Unsupported fmt %r. Currently only 'mmcif' is supported by IoAdapterCore. For 'bcif', use IoAdapterPy instead.", fmt)
+ #
except (PdbxError, PdbxSyntaxError) as ex:
self._cleanupFile(asciiFilePath and cleanUp, asciiFilePath)
if self._raiseExceptions:
@@ -1084,7 +1101,7 @@ IoAdapterCore
msg = "Failing read for %s with %s" % (filePath, str(e))
self._logError(msg)
- return []
+ return containerL
def getReadDiags(self):
"""Recover the diagnostics for the previous readFile() operation.readFile
@@ -1246,7 +1263,18 @@ IoAdapterCore
return containerList, diagL
- def writeFile(self, outputFilePath, containerList=None, doubleQuotingFlag=False, maxLineLength=900, enforceAscii=True, lastInOrder=None, selectOrder=None, **kwargs):
+ def writeFile(
+ self,
+ outputFilePath,
+ containerList=None,
+ doubleQuotingFlag=False,
+ maxLineLength=900,
+ enforceAscii=True,
+ lastInOrder=None,
+ selectOrder=None,
+ fmt="mmcif",
+ **kwargs
+ ):
"""Write input list of data containers to the specified output file path in mmCIF format.
Args:
@@ -1256,12 +1284,13 @@ IoAdapterCore
enforceAscii (bool, optional): Filter output (not implemented - content must be ascii compatible on input)
lastInOrder (list of category names, optional): Move data categories in this list to end of each data block
selectOrder (list of category names, optional): Write only data categories on this list.
+ fmt (string, optional): Format of input file (currently only supports "mmcif"). Defaults to "mmcif".
+
**kwargs: Placeholder for unsupported key value pairs
Returns:
bool: Completion status
-
"""
_ = enforceAscii
lastInOrder = lastInOrder if lastInOrder else ["pdbx_nonpoly_scheme", "pdbx_poly_seq_scheme", "atom_site", "atom_site_anisotrop"]
@@ -1271,45 +1300,53 @@ IoAdapterCore
try:
startTime = time.time()
logger.debug("write container length %d", len(containerL))
- # (CifFile args: placeholder, verbose: bool, caseSense: Char::eCompareType, maxLineLength: int, nullValue: str)
- cF = CifFile(True, self._verbose, 0, maxLineLength, "?")
- for container in containerL:
- containerName = container.getName()
- logger.debug("writing container %s", containerName)
- cF.AddBlock(containerName)
- block = cF.GetBlock(containerName)
- #
- # objNameList = container.getObjNameList()
- # logger.debug("write category length %d\n" % len(objNameList))
+ fmt = fmt.lower()
+ #
+ if fmt == "mmcif":
+ # (CifFile args: placeholder, verbose: bool, caseSense: Char::eCompareType, maxLineLength: int, nullValue: str)
+ cF = CifFile(True, self._verbose, 0, maxLineLength, "?")
+ for container in containerL:
+ containerName = container.getName()
+ logger.debug("writing container %s", containerName)
+ cF.AddBlock(containerName)
+ block = cF.GetBlock(containerName)
+ #
+ # objNameList = container.getObjNameList()
+ # logger.debug("write category length %d\n" % len(objNameList))
+ #
+ # Reorder/Filter - container object list-
+ objNameList = container.filterObjectNameList(lastInOrder=lastInOrder, selectOrder=selectOrder)
+ logger.debug("write category names %r", objNameList)
+ #
+ for objName in objNameList:
+ name, attributeNameList, rowList = container.getObj(objName).get()
+ table = block.AddTable(name)
+ for attributeName in attributeNameList:
+ table.AddColumn(attributeName)
+ try:
+ rLen = len(attributeNameList)
+ for ii, row in enumerate(rowList):
+ table.AddRow()
+ table.FillRow(ii, [str(row[jj]) if row[jj] is not None else "?" for jj in range(0, rLen)])
+ except Exception as e:
+ logger.error("Exception for %s preparing category %r (%d) attributes %r for writing %s", outputFilePath, name, len(rowList), attributeNameList, str(e))
+ #
+ block.WriteTable(table)
#
- # Reorder/Filter - container object list-
- objNameList = container.filterObjectNameList(lastInOrder=lastInOrder, selectOrder=selectOrder)
- logger.debug("write category names %r", objNameList)
+ if self._timing:
+ stepTime1 = time.time()
+ logger.info("Timing %d container(s) api loaded in %.4f seconds", len(containerL), stepTime1 - startTime)
+ if self._debug:
+ self.__dumpBlocks(cF)
+ if doubleQuotingFlag:
+ cF.SetQuoting(cF.eDOUBLE)
#
- for objName in objNameList:
- name, attributeNameList, rowList = container.getObj(objName).get()
- table = block.AddTable(name)
- for attributeName in attributeNameList:
- table.AddColumn(attributeName)
- try:
- rLen = len(attributeNameList)
- for ii, row in enumerate(rowList):
- table.AddRow()
- table.FillRow(ii, [str(row[jj]) if row[jj] is not None else "?" for jj in range(0, rLen)])
- except Exception as e:
- logger.error("Exception for %s preparing category %r (%d) attributes %r for writing %s", outputFilePath, name, len(rowList), attributeNameList, str(e))
- #
- block.WriteTable(table)
+ cF.Write(str(outputFilePath))
#
- if self._timing:
- stepTime1 = time.time()
- logger.info("Timing %d container(s) api loaded in %.4f seconds", len(containerL), stepTime1 - startTime)
- if self._debug:
- self.__dumpBlocks(cF)
- if doubleQuotingFlag:
- cF.SetQuoting(cF.eDOUBLE)
+ else:
+ logger.error("Unsupported fmt %r. Currently only 'mmcif' is supported by IoAdapterCore. For 'bcif', use IoAdapterPy instead.", fmt)
+ return False
#
- cF.Write(str(outputFilePath))
if self._timing:
stepTime2 = time.time()
logger.info("Timing %d container(s) written in %.4f seconds total time %.4f", len(containerList), stepTime2 - stepTime1, stepTime2 - startTime)
@@ -1419,7 +1456,7 @@
-readFile(self, inputFilePath, enforceAscii=True, selectList=None, excludeFlag=False, logFilePath=None, outDirPath=None, cleanUp=True, **kwargs)
+readFile(self, inputFilePath, enforceAscii=True, selectList=None, excludeFlag=False, logFilePath=None, outDirPath=None, cleanUp=True, fmt='mmcif', **kwargs)
@@ -1482,6 +1519,12 @@
Flag to automatically remove logs and temporary files on exit.
True
+
+ fmt
+ string
+ Format of input file (currently only supports "mmcif"). Defaults to "mmcif".
+ 'mmcif'
+
**kwargs
@@ -1507,7 +1550,18 @@
Source code in mmcif/io/IoAdapterCore.py
- def readFile(self, inputFilePath, enforceAscii=True, selectList=None, excludeFlag=False, logFilePath=None, outDirPath=None, cleanUp=True, **kwargs):
+ def readFile(
+ self,
+ inputFilePath,
+ enforceAscii=True,
+ selectList=None,
+ excludeFlag=False,
+ logFilePath=None,
+ outDirPath=None,
+ cleanUp=True,
+ fmt="mmcif",
+ **kwargs
+):
"""Parse the data blocks in the input mmCIF format data file into list of DataContainers(). The data category content within each data block
is stored a collection of DataCategory objects within each DataContainer.
@@ -1519,6 +1573,8 @@
logFilePath (string, optional): Log file path (if not provided this will be derived from the input file.)
outDirPath (string, optional): Path for translated/reencoded files and default logfiles.
cleanUp (bool, optional): Flag to automatically remove logs and temporary files on exit.
+ fmt (string, optional): Format of input file (currently only supports "mmcif"). Defaults to "mmcif".
+
**kwargs: Placeholder for missing keyword arguments.
Returns:
@@ -1530,6 +1586,7 @@
filePath = str(inputFilePath)
# oPath = outDirPath if outDirPath else '.'
oPath = self._chooseTemporaryPath(inputFilePath, outDirPath=outDirPath)
+ containerL = []
try:
#
lPath = logFilePath
@@ -1541,28 +1598,33 @@
if not self._fileExists(filePath):
return []
#
- filePath = self._uncompress(filePath, oPath)
- tPath = filePath
- if enforceAscii:
- asciiFilePath = self._getDefaultFileName(filePath, fileType="cif-parser-ascii", fileExt="cif", outDirPath=oPath)
- encodingErrors = "xmlcharrefreplace" if self._useCharRefs else "ignore"
- logger.debug("Filtering input file to %s using encoding errors as %s", asciiFilePath, encodingErrors)
- ok = self._toAscii(filePath, asciiFilePath, chunkSize=5000, encodingErrors=encodingErrors, readEncodingErrors=self._readEncodingErrors)
- if ok:
- tPath = asciiFilePath
- #
- readDef = None
- if selectList is not None and selectList:
- readDef = self.__getSelectionDef(selectList, excludeFlag)
- #
- containerL, _ = self.__readData(tPath, readDef=readDef, cleanUp=cleanUp, logFilePath=lPath, maxLineLength=self._maxInputLineLength)
+ fmt = fmt.lower()
#
- if cleanUp:
- self._cleanupFile(asciiFilePath, asciiFilePath)
- self._cleanupFile(filePath != str(inputFilePath), filePath)
- self._setContainerProperties(containerL, locator=str(inputFilePath), load_date=self._getTimeStamp(), uid=uuid.uuid4().hex)
+ if fmt == "mmcif":
+ filePath = self._uncompress(filePath, oPath)
+ tPath = filePath
+ if enforceAscii:
+ asciiFilePath = self._getDefaultFileName(filePath, fileType="cif-parser-ascii", fileExt="cif", outDirPath=oPath)
+ encodingErrors = "xmlcharrefreplace" if self._useCharRefs else "ignore"
+ logger.debug("Filtering input file to %s using encoding errors as %s", asciiFilePath, encodingErrors)
+ ok = self._toAscii(filePath, asciiFilePath, chunkSize=5000, encodingErrors=encodingErrors, readEncodingErrors=self._readEncodingErrors)
+ if ok:
+ tPath = asciiFilePath
+ #
+ readDef = None
+ if selectList is not None and selectList:
+ readDef = self.__getSelectionDef(selectList, excludeFlag)
+ #
+ containerL, _ = self.__readData(tPath, readDef=readDef, cleanUp=cleanUp, logFilePath=lPath, maxLineLength=self._maxInputLineLength)
+ #
+ if cleanUp:
+ self._cleanupFile(asciiFilePath, asciiFilePath)
+ self._cleanupFile(filePath != str(inputFilePath), filePath)
+ self._setContainerProperties(containerL, locator=str(inputFilePath), load_date=self._getTimeStamp(), uid=uuid.uuid4().hex)
#
- return containerL
+ else:
+ logger.error("Unsupported fmt %r. Currently only 'mmcif' is supported by IoAdapterCore. For 'bcif', use IoAdapterPy instead.", fmt)
+ #
except (PdbxError, PdbxSyntaxError) as ex:
self._cleanupFile(asciiFilePath and cleanUp, asciiFilePath)
if self._raiseExceptions:
@@ -1573,7 +1635,7 @@
msg = "Failing read for %s with %s" % (filePath, str(e))
self._logError(msg)
- return []
+ return containerL
@@ -1587,7 +1649,7 @@
-writeFile(self, outputFilePath, containerList=None, doubleQuotingFlag=False, maxLineLength=900, enforceAscii=True, lastInOrder=None, selectOrder=None, **kwargs)
+writeFile(self, outputFilePath, containerList=None, doubleQuotingFlag=False, maxLineLength=900, enforceAscii=True, lastInOrder=None, selectOrder=None, fmt='mmcif', **kwargs)
@@ -1643,6 +1705,12 @@
Write only data categories on this list.
None
+
+ fmt
+ string
+ Format of input file (currently only supports "mmcif"). Defaults to "mmcif".
+ 'mmcif'
+
**kwargs
@@ -1668,7 +1736,18 @@
Source code in mmcif/io/IoAdapterCore.py
- def writeFile(self, outputFilePath, containerList=None, doubleQuotingFlag=False, maxLineLength=900, enforceAscii=True, lastInOrder=None, selectOrder=None, **kwargs):
+ def writeFile(
+ self,
+ outputFilePath,
+ containerList=None,
+ doubleQuotingFlag=False,
+ maxLineLength=900,
+ enforceAscii=True,
+ lastInOrder=None,
+ selectOrder=None,
+ fmt="mmcif",
+ **kwargs
+):
"""Write input list of data containers to the specified output file path in mmCIF format.
Args:
@@ -1678,12 +1757,13 @@
enforceAscii (bool, optional): Filter output (not implemented - content must be ascii compatible on input)
lastInOrder (list of category names, optional): Move data categories in this list to end of each data block
selectOrder (list of category names, optional): Write only data categories on this list.
+ fmt (string, optional): Format of input file (currently only supports "mmcif"). Defaults to "mmcif".
+
**kwargs: Placeholder for unsupported key value pairs
Returns:
bool: Completion status
-
"""
_ = enforceAscii
lastInOrder = lastInOrder if lastInOrder else ["pdbx_nonpoly_scheme", "pdbx_poly_seq_scheme", "atom_site", "atom_site_anisotrop"]
@@ -1693,45 +1773,53 @@
try:
startTime = time.time()
logger.debug("write container length %d", len(containerL))
- # (CifFile args: placeholder, verbose: bool, caseSense: Char::eCompareType, maxLineLength: int, nullValue: str)
- cF = CifFile(True, self._verbose, 0, maxLineLength, "?")
- for container in containerL:
- containerName = container.getName()
- logger.debug("writing container %s", containerName)
- cF.AddBlock(containerName)
- block = cF.GetBlock(containerName)
- #
- # objNameList = container.getObjNameList()
- # logger.debug("write category length %d\n" % len(objNameList))
+ fmt = fmt.lower()
+ #
+ if fmt == "mmcif":
+ # (CifFile args: placeholder, verbose: bool, caseSense: Char::eCompareType, maxLineLength: int, nullValue: str)
+ cF = CifFile(True, self._verbose, 0, maxLineLength, "?")
+ for container in containerL:
+ containerName = container.getName()
+ logger.debug("writing container %s", containerName)
+ cF.AddBlock(containerName)
+ block = cF.GetBlock(containerName)
+ #
+ # objNameList = container.getObjNameList()
+ # logger.debug("write category length %d\n" % len(objNameList))
+ #
+ # Reorder/Filter - container object list-
+ objNameList = container.filterObjectNameList(lastInOrder=lastInOrder, selectOrder=selectOrder)
+ logger.debug("write category names %r", objNameList)
+ #
+ for objName in objNameList:
+ name, attributeNameList, rowList = container.getObj(objName).get()
+ table = block.AddTable(name)
+ for attributeName in attributeNameList:
+ table.AddColumn(attributeName)
+ try:
+ rLen = len(attributeNameList)
+ for ii, row in enumerate(rowList):
+ table.AddRow()
+ table.FillRow(ii, [str(row[jj]) if row[jj] is not None else "?" for jj in range(0, rLen)])
+ except Exception as e:
+ logger.error("Exception for %s preparing category %r (%d) attributes %r for writing %s", outputFilePath, name, len(rowList), attributeNameList, str(e))
+ #
+ block.WriteTable(table)
#
- # Reorder/Filter - container object list-
- objNameList = container.filterObjectNameList(lastInOrder=lastInOrder, selectOrder=selectOrder)
- logger.debug("write category names %r", objNameList)
+ if self._timing:
+ stepTime1 = time.time()
+ logger.info("Timing %d container(s) api loaded in %.4f seconds", len(containerL), stepTime1 - startTime)
+ if self._debug:
+ self.__dumpBlocks(cF)
+ if doubleQuotingFlag:
+ cF.SetQuoting(cF.eDOUBLE)
#
- for objName in objNameList:
- name, attributeNameList, rowList = container.getObj(objName).get()
- table = block.AddTable(name)
- for attributeName in attributeNameList:
- table.AddColumn(attributeName)
- try:
- rLen = len(attributeNameList)
- for ii, row in enumerate(rowList):
- table.AddRow()
- table.FillRow(ii, [str(row[jj]) if row[jj] is not None else "?" for jj in range(0, rLen)])
- except Exception as e:
- logger.error("Exception for %s preparing category %r (%d) attributes %r for writing %s", outputFilePath, name, len(rowList), attributeNameList, str(e))
- #
- block.WriteTable(table)
+ cF.Write(str(outputFilePath))
#
- if self._timing:
- stepTime1 = time.time()
- logger.info("Timing %d container(s) api loaded in %.4f seconds", len(containerL), stepTime1 - startTime)
- if self._debug:
- self.__dumpBlocks(cF)
- if doubleQuotingFlag:
- cF.SetQuoting(cF.eDOUBLE)
+ else:
+ logger.error("Unsupported fmt %r. Currently only 'mmcif' is supported by IoAdapterCore. For 'bcif', use IoAdapterPy instead.", fmt)
+ return False
#
- cF.Write(str(outputFilePath))
if self._timing:
stepTime2 = time.time()
logger.info("Timing %d container(s) written in %.4f seconds total time %.4f", len(containerList), stepTime2 - stepTime1, stepTime2 - startTime)
diff --git a/api_reference/IoAdapterPy/index.html b/api_reference/IoAdapterPy/index.html
index b16f272d..75cf0eef 100644
--- a/api_reference/IoAdapterPy/index.html
+++ b/api_reference/IoAdapterPy/index.html
@@ -1008,37 +1008,53 @@ IoAdapterPy
- Python implementation of IoAdapterBase class providing essential read and write methods for mmCIF data files -
+ Python implementation of IoAdapterBase class providing essential read and write methods for mmCIF and BCIF data files -
Source code in mmcif/io/IoAdapterPy.py
class IoAdapterPy(IoAdapterBase):
- """Python implementation of IoAdapterBase class providing essential read and write methods for mmCIF data files -"""
+ """Python implementation of IoAdapterBase class providing essential read and write methods for mmCIF and BCIF data files -"""
- # def __init__(self, *args, **kwargs):
- # super(IoAdapterPy, self).__init__(*args, **kwargs)
# pylint: disable=arguments-differ
- def readFile(self, inputFilePath, enforceAscii=False, selectList=None, excludeFlag=False, logFilePath=None, outDirPath=None, cleanUp=False, **kwargs):
- """Parse the data blocks in the input mmCIF format data file into list of data or definition containers. The data category content within
- each data block is stored a collection of DataCategory objects within each container.
+ def readFile(
+ self,
+ inputFilePath,
+ enforceAscii=False,
+ selectList=None,
+ excludeFlag=False,
+ logFilePath=None,
+ outDirPath=None,
+ cleanUp=True,
+ fmt="mmcif",
+ timeout=None,
+ storeStringsAsBytes=False,
+ defaultStringEncoding="utf-8",
+ **kwargs
+ ):
+ """Parse the data blocks in the input mmCIF or BCIF format data file into list of data or definition containers. The data category
+ content within each data block is stored a collection of DataCategory objects within each container.
Args:
inputFilePath (string): Input file path
- enforceAscii (bool, optional): Flag to requiring ASCII encoding. See encoding error options.
+ enforceAscii (bool, optional): Flag to require ASCII encoding when reading in 'mmcif' file. See encoding error options. Defaults to False.
selectList (List, optional): List of data category names to be extracted or excluded from the input file (default: select/extract)
excludeFlag (bool, optional): Flag to indicate selectList should be treated as an exclusion list
logFilePath (string, optional): Log file path (if not provided this will be derived from the input file.)
outDirPath (string, optional): Path for translated/re-encoded files and default logfiles.
cleanUp (bool, optional): Flag to automatically remove logs and temporary files on exit.
+ fmt (string, optional): Format of input file (either "mmcif" or "bcif"). Defaults to "mmcif".
timeout (float, optional): Timeout in seconds for fetching data from remote urls
+
+ # BCIF-specific args:
+ storeStringsAsBytes (bool, optional): Strings are stored as lists of bytes (for BCIF files only). Defaults to False.
+ defaultStringEncoding (str, optional): Default encoding for string data (for BCIF files only). Defaults to "utf-8".
+
**kwargs: Placeholder for missing keyword arguments.
Returns:
List of DataContainers: Contents of input file parsed into a list of DataContainer objects.
"""
- timeout = kwargs.pop("timeout", None)
-
if kwargs:
logger.warning("Unsupported keyword arguments %s", kwargs.keys())
filePath = str(inputFilePath)
@@ -1060,57 +1076,73 @@ IoAdapterPy
if self.__isLocal(filePath) and not self._fileExists(filePath):
return []
#
- if sys.version_info[0] > 2:
- if self.__isLocal(filePath):
- filePath = self._uncompress(filePath, oPath)
- with open(filePath, "r", encoding=encoding, errors=self._readEncodingErrors) as ifh:
- pRd = PdbxReader(ifh)
- pRd.read(containerList, selectList, excludeFlag=excludeFlag)
- else:
- if filePath.endswith(".gz"):
- customHeader = {"Accept-Encoding": "gzip"}
- with closing(requests.get(filePath, headers=customHeader, timeout=timeout)) as ifh:
- if self._raiseExceptions:
- ifh.raise_for_status()
- gzit = gzip.GzipFile(fileobj=io.BytesIO(ifh.content))
- it = (line.decode(encoding, "ignore") for line in gzit)
- pRd = PdbxReader(it)
- pRd.read(containerList, selectList, excludeFlag=excludeFlag)
- else:
- with closing(requests.get(filePath, timeout=timeout)) as ifh:
- if self._raiseExceptions:
- ifh.raise_for_status()
- it = (line.decode(encoding, "ignore") + "\n" for line in ifh.iter_lines())
- pRd = PdbxReader(it)
- pRd.read(containerList, selectList, excludeFlag=excludeFlag)
- else:
- if self.__isLocal(filePath):
- filePath = self._uncompress(filePath, oPath)
- if enforceAscii:
- with io.open(filePath, "r", encoding=encoding, errors=self._readEncodingErrors) as ifh:
- pRd = PdbxReader(ifh)
- pRd.read(containerList, selectList, excludeFlag=excludeFlag)
- else:
- with open(filePath, "r") as ifh:
+ fmt = fmt.lower()
+ #
+ if sys.version_info[0] > 2: # Check if using Python version higher than 2
+ if fmt == "mmcif":
+ if self.__isLocal(filePath):
+ filePath = self._uncompress(filePath, oPath)
+ with open(filePath, "r", encoding=encoding, errors=self._readEncodingErrors) as ifh:
pRd = PdbxReader(ifh)
pRd.read(containerList, selectList, excludeFlag=excludeFlag)
+ else: # handle files from the internet...
+ if filePath.endswith(".gz"):
+ customHeader = {"Accept-Encoding": "gzip"}
+ with closing(requests.get(filePath, headers=customHeader, timeout=timeout)) as ifh:
+ if self._raiseExceptions:
+ ifh.raise_for_status()
+ gzit = gzip.GzipFile(fileobj=io.BytesIO(ifh.content))
+ it = (line.decode(encoding, "ignore") for line in gzit)
+ pRd = PdbxReader(it)
+ pRd.read(containerList, selectList, excludeFlag=excludeFlag)
+ else:
+ with closing(requests.get(filePath, timeout=timeout)) as ifh:
+ if self._raiseExceptions:
+ ifh.raise_for_status()
+ it = (line.decode(encoding, "ignore") + "\n" for line in ifh.iter_lines())
+ pRd = PdbxReader(it)
+ pRd.read(containerList, selectList, excludeFlag=excludeFlag)
+ elif fmt == "bcif":
+ # local vs. remote and gzip business is already done in BinaryCifReader
+ bcifRd = BinaryCifReader(storeStringsAsBytes=storeStringsAsBytes, defaultStringEncoding=defaultStringEncoding)
+ containerList = bcifRd.deserialize(filePath)
else:
- if filePath.endswith(".gz"):
- customHeader = {"Accept-Encoding": "gzip"}
- with closing(requests.get(filePath, headers=customHeader, timeout=timeout)) as ifh:
- if self._raiseExceptions:
- ifh.raise_for_status()
- gzit = gzip.GzipFile(fileobj=io.BytesIO(ifh.content))
- it = (line.decode(encoding, "ignore") for line in gzit)
- pRd = PdbxReader(it)
- pRd.read(containerList, selectList, excludeFlag=excludeFlag)
+ logger.error("Unsupported fmt %r. Currently only supports 'mmcif' or 'bcif'.", fmt)
+ else:
+ logger.warning("Support for Python 2 will be deprecated soon. Please use Python 3.")
+ if fmt == "bcif":
+ logger.error("Support for BCIF reading only available in Python 3.")
+ elif fmt == "mmcif":
+ if self.__isLocal(filePath):
+ filePath = self._uncompress(filePath, oPath)
+ if enforceAscii:
+ with io.open(filePath, "r", encoding=encoding, errors=self._readEncodingErrors) as ifh:
+ pRd = PdbxReader(ifh)
+ pRd.read(containerList, selectList, excludeFlag=excludeFlag)
+ else:
+ with open(filePath, "r") as ifh:
+ pRd = PdbxReader(ifh)
+ pRd.read(containerList, selectList, excludeFlag=excludeFlag)
else:
- with closing(requests.get(filePath, timeout=timeout)) as ifh:
- if self._raiseExceptions:
- ifh.raise_for_status()
- it = (line.decode(encoding, "ignore") + "\n" for line in ifh.iter_lines())
- pRd = PdbxReader(it)
- pRd.read(containerList, selectList, excludeFlag=excludeFlag)
+ if filePath.endswith(".gz"):
+ customHeader = {"Accept-Encoding": "gzip"}
+ with closing(requests.get(filePath, headers=customHeader, timeout=timeout)) as ifh:
+ if self._raiseExceptions:
+ ifh.raise_for_status()
+ gzit = gzip.GzipFile(fileobj=io.BytesIO(ifh.content))
+ it = (line.decode(encoding, "ignore") for line in gzit)
+ pRd = PdbxReader(it)
+ pRd.read(containerList, selectList, excludeFlag=excludeFlag)
+ else:
+ with closing(requests.get(filePath, timeout=timeout)) as ifh:
+ if self._raiseExceptions:
+ ifh.raise_for_status()
+ it = (line.decode(encoding, "ignore") + "\n" for line in ifh.iter_lines())
+ pRd = PdbxReader(it)
+ pRd.read(containerList, selectList, excludeFlag=excludeFlag)
+ else:
+ logger.error("Unsupported fmt %r for Python2 installation of mmcif.io.IoAdapterPy. Currently only 'mmcif' is supported. Upgrade to Python3 for 'bcif' support", fmt)
+
if cleanUp:
self._cleanupFile(lPath, lPath)
self._cleanupFile(filePath != str(inputFilePath), filePath)
@@ -1149,27 +1181,44 @@ IoAdapterPy
columnAlignFlag=True,
useStopTokens=False,
formattingStep=None,
+ fmt="mmcif",
+ storeStringsAsBytes=False,
+ defaultStringEncoding="utf-8",
+ applyTypes=True,
+ dictionaryApi=None,
+ useStringTypes=False,
+ useFloat64=False,
+ copyInputData=False,
**kwargs
):
- """Write input list of data containers to the specified output file path in mmCIF format.
+ """Write input list of data containers to the specified output file path in mmCIF or BCIF format.
Args:
outputFilePath (string): output file path
containerList (list DataContainer objects, optional)
maxLineLength (int, optional): Maximum length of output line (content is wrapped beyond this length)
- enforceAscii (bool, optional): Filter output (not implemented - content must be ascii compatible on input)
+ enforceAscii (bool, optional): Enforce ASCII encoding when writing out 'mmcif' file. Defaults to True.
lastInOrder (list of category names, optional): Move data categories in this list to end of each data block
selectOrder (list of category names, optional): Write only data categories on this list.
-
columnAlignFlag (bool, optional): Format the output in aligned columns (default=True) (Native Python Only)
useStopTokens (bool, optional): Include terminating 'stop_' tokens at the end of mmCIF categories (loop_'s) (Native Python only)
formattingStep (int, optional): The number row samples within each category used to estimate maximum column width for data alignment (Native Python only)
+ fmt (string, optional): Format of output file (either "mmcif" or "bcif"). Defaults to "mmcif".
+
+ # BCIF-specific args:
+ storeStringsAsBytes (bool, optional): Strings are stored as lists of bytes (for BCIF files only). Defaults to False.
+ defaultStringEncoding (str, optional): Default encoding for string data (for BCIF files only). Defaults to "utf-8".
+ applyTypes (bool, optional): apply explicit data typing before encoding (for BCIF files only; requires dictionaryApi to be passed too). Defaults to True.
+ dictionaryApi (object, optional): DictionaryApi object instance (needed for BCIF files, only when applyTypes is True). Defaults to None.
+ useStringTypes (bool, optional): assume all types are string (for BCIF files only). Defaults to False.
+ useFloat64 (bool, optional): store floats with 64 bit precision (for BCIF files only). Defaults to False.
+ copyInputData (bool, optional): make a new copy input data (for BCIF files only). Defaults to False.
+
**kwargs: Placeholder for unsupported key value pairs
Returns:
bool: Completion status
-
"""
lastInOrder = lastInOrder if lastInOrder else ["pdbx_nonpoly_scheme", "pdbx_poly_seq_scheme", "atom_site", "atom_site_anisotrop"]
if kwargs:
@@ -1180,23 +1229,11 @@ IoAdapterPy
else:
encoding = "utf-8"
#
- if sys.version_info[0] > 2:
- with open(outputFilePath, "w", encoding=encoding) as ofh:
- self.__writeFile(
- ofh,
- containerList,
- maxLineLength=maxLineLength,
- columnAlignFlag=columnAlignFlag,
- lastInOrder=lastInOrder,
- selectOrder=selectOrder,
- useStopTokens=useStopTokens,
- formattingStep=formattingStep,
- enforceAscii=enforceAscii,
- cnvCharRefs=self._useCharRefs,
- )
- else:
- if enforceAscii:
- with io.open(outputFilePath, "w", encoding=encoding) as ofh:
+ fmt = fmt.lower()
+ #
+ if sys.version_info[0] > 2: # Check if using Python version higher than 2
+ if fmt == "mmcif":
+ with open(outputFilePath, "w", encoding=encoding) as ofh:
self.__writeFile(
ofh,
containerList,
@@ -1209,20 +1246,57 @@ IoAdapterPy
enforceAscii=enforceAscii,
cnvCharRefs=self._useCharRefs,
)
+ elif fmt == "bcif":
+ bcifW = BinaryCifWriter(
+ dictionaryApi=dictionaryApi,
+ storeStringsAsBytes=storeStringsAsBytes,
+ defaultStringEncoding=defaultStringEncoding,
+ applyTypes=applyTypes,
+ useStringTypes=useStringTypes,
+ useFloat64=useFloat64,
+ copyInputData=copyInputData,
+ )
+ bcifW.serialize(outputFilePath, containerList)
else:
- with open(outputFilePath, "wb") as ofh:
- self.__writeFile(
- ofh,
- containerList,
- maxLineLength=maxLineLength,
- columnAlignFlag=columnAlignFlag,
- lastInOrder=lastInOrder,
- selectOrder=selectOrder,
- useStopTokens=useStopTokens,
- formattingStep=formattingStep,
- enforceAscii=enforceAscii,
- cnvCharRefs=self._useCharRefs,
- )
+ logger.error("Unsupported fmt %r. Currently only supports 'mmcif' or 'bcif'.", fmt)
+ return False
+ else:
+ logger.warning("Support for Python 2 will be deprecated soon. Please use Python 3.")
+ if fmt == "bcif":
+ logger.error("Support for BCIF writing only available in Python 3.")
+ return False
+ elif fmt == "mmcif":
+ if enforceAscii:
+ with io.open(outputFilePath, "w", encoding=encoding) as ofh:
+ self.__writeFile(
+ ofh,
+ containerList,
+ maxLineLength=maxLineLength,
+ columnAlignFlag=columnAlignFlag,
+ lastInOrder=lastInOrder,
+ selectOrder=selectOrder,
+ useStopTokens=useStopTokens,
+ formattingStep=formattingStep,
+ enforceAscii=enforceAscii,
+ cnvCharRefs=self._useCharRefs,
+ )
+ else:
+ with open(outputFilePath, "wb") as ofh:
+ self.__writeFile(
+ ofh,
+ containerList,
+ maxLineLength=maxLineLength,
+ columnAlignFlag=columnAlignFlag,
+ lastInOrder=lastInOrder,
+ selectOrder=selectOrder,
+ useStopTokens=useStopTokens,
+ formattingStep=formattingStep,
+ enforceAscii=enforceAscii,
+ cnvCharRefs=self._useCharRefs,
+ )
+ else:
+ logger.error("Unsupported fmt %r for Python2 installation of mmcif.io.IoAdapterPy. Currently only 'mmcif' is supported. Upgrade to Python3 for 'bcif' support", fmt)
+ return False
return True
except Exception as ex:
if self._raiseExceptions:
@@ -1314,15 +1388,15 @@
-readFile(self, inputFilePath, enforceAscii=False, selectList=None, excludeFlag=False, logFilePath=None, outDirPath=None, cleanUp=False, **kwargs)
+readFile(self, inputFilePath, enforceAscii=False, selectList=None, excludeFlag=False, logFilePath=None, outDirPath=None, cleanUp=True, fmt='mmcif', timeout=None, storeStringsAsBytes=False, defaultStringEncoding='utf-8', **kwargs)
- Parse the data blocks in the input mmCIF format data file into list of data or definition containers. The data category content within
- each data block is stored a collection of DataCategory objects within each container.
+ Parse the data blocks in the input mmCIF or BCIF format data file into list of data or definition containers. The data category
+ content within each data block is stored a collection of DataCategory objects within each container.
Parameters:
@@ -1344,7 +1418,7 @@
enforceAscii
bool
- Flag to requiring ASCII encoding. See encoding error options.
+ Flag to require ASCII encoding when reading in 'mmcif' file. See encoding error options. Defaults to False.
False
@@ -1375,14 +1449,38 @@
cleanUp
bool
Flag to automatically remove logs and temporary files on exit.
- False
+ True
+
+
+ fmt
+ string
+ Format of input file (either "mmcif" or "bcif"). Defaults to "mmcif".
+ 'mmcif'
timeout
float
Timeout in seconds for fetching data from remote urls
+ None
+
+
+ #
+ BCIF-specific args
+
required
+
+ storeStringsAsBytes
+ bool
+ Strings are stored as lists of bytes (for BCIF files only). Defaults to False.
+ False
+
+
+ defaultStringEncoding
+ str
+ Default encoding for string data (for BCIF files only). Defaults to "utf-8".
+ 'utf-8'
+
**kwargs
@@ -1408,27 +1506,45 @@
Source code in mmcif/io/IoAdapterPy.py
- def readFile(self, inputFilePath, enforceAscii=False, selectList=None, excludeFlag=False, logFilePath=None, outDirPath=None, cleanUp=False, **kwargs):
- """Parse the data blocks in the input mmCIF format data file into list of data or definition containers. The data category content within
- each data block is stored a collection of DataCategory objects within each container.
+ def readFile(
+ self,
+ inputFilePath,
+ enforceAscii=False,
+ selectList=None,
+ excludeFlag=False,
+ logFilePath=None,
+ outDirPath=None,
+ cleanUp=True,
+ fmt="mmcif",
+ timeout=None,
+ storeStringsAsBytes=False,
+ defaultStringEncoding="utf-8",
+ **kwargs
+):
+ """Parse the data blocks in the input mmCIF or BCIF format data file into list of data or definition containers. The data category
+ content within each data block is stored a collection of DataCategory objects within each container.
Args:
inputFilePath (string): Input file path
- enforceAscii (bool, optional): Flag to requiring ASCII encoding. See encoding error options.
+ enforceAscii (bool, optional): Flag to require ASCII encoding when reading in 'mmcif' file. See encoding error options. Defaults to False.
selectList (List, optional): List of data category names to be extracted or excluded from the input file (default: select/extract)
excludeFlag (bool, optional): Flag to indicate selectList should be treated as an exclusion list
logFilePath (string, optional): Log file path (if not provided this will be derived from the input file.)
outDirPath (string, optional): Path for translated/re-encoded files and default logfiles.
cleanUp (bool, optional): Flag to automatically remove logs and temporary files on exit.
+ fmt (string, optional): Format of input file (either "mmcif" or "bcif"). Defaults to "mmcif".
timeout (float, optional): Timeout in seconds for fetching data from remote urls
+
+ # BCIF-specific args:
+ storeStringsAsBytes (bool, optional): Strings are stored as lists of bytes (for BCIF files only). Defaults to False.
+ defaultStringEncoding (str, optional): Default encoding for string data (for BCIF files only). Defaults to "utf-8".
+
**kwargs: Placeholder for missing keyword arguments.
Returns:
List of DataContainers: Contents of input file parsed into a list of DataContainer objects.
"""
- timeout = kwargs.pop("timeout", None)
-
if kwargs:
logger.warning("Unsupported keyword arguments %s", kwargs.keys())
filePath = str(inputFilePath)
@@ -1450,57 +1566,73 @@
if self.__isLocal(filePath) and not self._fileExists(filePath):
return []
#
- if sys.version_info[0] > 2:
- if self.__isLocal(filePath):
- filePath = self._uncompress(filePath, oPath)
- with open(filePath, "r", encoding=encoding, errors=self._readEncodingErrors) as ifh:
- pRd = PdbxReader(ifh)
- pRd.read(containerList, selectList, excludeFlag=excludeFlag)
- else:
- if filePath.endswith(".gz"):
- customHeader = {"Accept-Encoding": "gzip"}
- with closing(requests.get(filePath, headers=customHeader, timeout=timeout)) as ifh:
- if self._raiseExceptions:
- ifh.raise_for_status()
- gzit = gzip.GzipFile(fileobj=io.BytesIO(ifh.content))
- it = (line.decode(encoding, "ignore") for line in gzit)
- pRd = PdbxReader(it)
- pRd.read(containerList, selectList, excludeFlag=excludeFlag)
- else:
- with closing(requests.get(filePath, timeout=timeout)) as ifh:
- if self._raiseExceptions:
- ifh.raise_for_status()
- it = (line.decode(encoding, "ignore") + "\n" for line in ifh.iter_lines())
- pRd = PdbxReader(it)
- pRd.read(containerList, selectList, excludeFlag=excludeFlag)
- else:
- if self.__isLocal(filePath):
- filePath = self._uncompress(filePath, oPath)
- if enforceAscii:
- with io.open(filePath, "r", encoding=encoding, errors=self._readEncodingErrors) as ifh:
- pRd = PdbxReader(ifh)
- pRd.read(containerList, selectList, excludeFlag=excludeFlag)
- else:
- with open(filePath, "r") as ifh:
+ fmt = fmt.lower()
+ #
+ if sys.version_info[0] > 2: # Check if using Python version higher than 2
+ if fmt == "mmcif":
+ if self.__isLocal(filePath):
+ filePath = self._uncompress(filePath, oPath)
+ with open(filePath, "r", encoding=encoding, errors=self._readEncodingErrors) as ifh:
pRd = PdbxReader(ifh)
pRd.read(containerList, selectList, excludeFlag=excludeFlag)
+ else: # handle files from the internet...
+ if filePath.endswith(".gz"):
+ customHeader = {"Accept-Encoding": "gzip"}
+ with closing(requests.get(filePath, headers=customHeader, timeout=timeout)) as ifh:
+ if self._raiseExceptions:
+ ifh.raise_for_status()
+ gzit = gzip.GzipFile(fileobj=io.BytesIO(ifh.content))
+ it = (line.decode(encoding, "ignore") for line in gzit)
+ pRd = PdbxReader(it)
+ pRd.read(containerList, selectList, excludeFlag=excludeFlag)
+ else:
+ with closing(requests.get(filePath, timeout=timeout)) as ifh:
+ if self._raiseExceptions:
+ ifh.raise_for_status()
+ it = (line.decode(encoding, "ignore") + "\n" for line in ifh.iter_lines())
+ pRd = PdbxReader(it)
+ pRd.read(containerList, selectList, excludeFlag=excludeFlag)
+ elif fmt == "bcif":
+ # local vs. remote and gzip business is already done in BinaryCifReader
+ bcifRd = BinaryCifReader(storeStringsAsBytes=storeStringsAsBytes, defaultStringEncoding=defaultStringEncoding)
+ containerList = bcifRd.deserialize(filePath)
else:
- if filePath.endswith(".gz"):
- customHeader = {"Accept-Encoding": "gzip"}
- with closing(requests.get(filePath, headers=customHeader, timeout=timeout)) as ifh:
- if self._raiseExceptions:
- ifh.raise_for_status()
- gzit = gzip.GzipFile(fileobj=io.BytesIO(ifh.content))
- it = (line.decode(encoding, "ignore") for line in gzit)
- pRd = PdbxReader(it)
- pRd.read(containerList, selectList, excludeFlag=excludeFlag)
+ logger.error("Unsupported fmt %r. Currently only supports 'mmcif' or 'bcif'.", fmt)
+ else:
+ logger.warning("Support for Python 2 will be deprecated soon. Please use Python 3.")
+ if fmt == "bcif":
+ logger.error("Support for BCIF reading only available in Python 3.")
+ elif fmt == "mmcif":
+ if self.__isLocal(filePath):
+ filePath = self._uncompress(filePath, oPath)
+ if enforceAscii:
+ with io.open(filePath, "r", encoding=encoding, errors=self._readEncodingErrors) as ifh:
+ pRd = PdbxReader(ifh)
+ pRd.read(containerList, selectList, excludeFlag=excludeFlag)
+ else:
+ with open(filePath, "r") as ifh:
+ pRd = PdbxReader(ifh)
+ pRd.read(containerList, selectList, excludeFlag=excludeFlag)
else:
- with closing(requests.get(filePath, timeout=timeout)) as ifh:
- if self._raiseExceptions:
- ifh.raise_for_status()
- it = (line.decode(encoding, "ignore") + "\n" for line in ifh.iter_lines())
- pRd = PdbxReader(it)
- pRd.read(containerList, selectList, excludeFlag=excludeFlag)
+ if filePath.endswith(".gz"):
+ customHeader = {"Accept-Encoding": "gzip"}
+ with closing(requests.get(filePath, headers=customHeader, timeout=timeout)) as ifh:
+ if self._raiseExceptions:
+ ifh.raise_for_status()
+ gzit = gzip.GzipFile(fileobj=io.BytesIO(ifh.content))
+ it = (line.decode(encoding, "ignore") for line in gzit)
+ pRd = PdbxReader(it)
+ pRd.read(containerList, selectList, excludeFlag=excludeFlag)
+ else:
+ with closing(requests.get(filePath, timeout=timeout)) as ifh:
+ if self._raiseExceptions:
+ ifh.raise_for_status()
+ it = (line.decode(encoding, "ignore") + "\n" for line in ifh.iter_lines())
+ pRd = PdbxReader(it)
+ pRd.read(containerList, selectList, excludeFlag=excludeFlag)
+ else:
+ logger.error("Unsupported fmt %r for Python2 installation of mmcif.io.IoAdapterPy. Currently only 'mmcif' is supported. Upgrade to Python3 for 'bcif' support", fmt)
+
if cleanUp:
self._cleanupFile(lPath, lPath)
self._cleanupFile(filePath != str(inputFilePath), filePath)
@@ -1534,14 +1666,14 @@
-writeFile(self, outputFilePath, containerList, maxLineLength=900, enforceAscii=True, lastInOrder=None, selectOrder=None, columnAlignFlag=True, useStopTokens=False, formattingStep=None, **kwargs)
+writeFile(self, outputFilePath, containerList, maxLineLength=900, enforceAscii=True, lastInOrder=None, selectOrder=None, columnAlignFlag=True, useStopTokens=False, formattingStep=None, fmt='mmcif', storeStringsAsBytes=False, defaultStringEncoding='utf-8', applyTypes=True, dictionaryApi=None, useStringTypes=False, useFloat64=False, copyInputData=False, **kwargs)
- Write input list of data containers to the specified output file path in mmCIF format.
+ Write input list of data containers to the specified output file path in mmCIF or BCIF format.
Parameters:
@@ -1569,7 +1701,7 @@
enforceAscii
bool
- Filter output (not implemented - content must be ascii compatible on input)
+ Enforce ASCII encoding when writing out 'mmcif' file. Defaults to True.
True
@@ -1602,6 +1734,60 @@
The number row samples within each category used to estimate maximum column width for data alignment (Native Python only)
None
+
+ fmt
+ string
+ Format of output file (either "mmcif" or "bcif"). Defaults to "mmcif".
+ 'mmcif'
+
+
+ #
+ BCIF-specific args
+
+ required
+
+
+ storeStringsAsBytes
+ bool
+ Strings are stored as lists of bytes (for BCIF files only). Defaults to False.
+ False
+
+
+ defaultStringEncoding
+ str
+ Default encoding for string data (for BCIF files only). Defaults to "utf-8".
+ 'utf-8'
+
+
+ applyTypes
+ bool
+ apply explicit data typing before encoding (for BCIF files only; requires dictionaryApi to be passed too). Defaults to True.
+ True
+
+
+ dictionaryApi
+ object
+ DictionaryApi object instance (needed for BCIF files, only when applyTypes is True). Defaults to None.
+ None
+
+
+ useStringTypes
+ bool
+ assume all types are string (for BCIF files only). Defaults to False.
+ False
+
+
+ useFloat64
+ bool
+ store floats with 64 bit precision (for BCIF files only). Defaults to False.
+ False
+
+
+ copyInputData
+ bool
+ make a new copy input data (for BCIF files only). Defaults to False.
+ False
+
**kwargs
@@ -1638,27 +1824,44 @@
columnAlignFlag=True,
useStopTokens=False,
formattingStep=None,
+ fmt="mmcif",
+ storeStringsAsBytes=False,
+ defaultStringEncoding="utf-8",
+ applyTypes=True,
+ dictionaryApi=None,
+ useStringTypes=False,
+ useFloat64=False,
+ copyInputData=False,
**kwargs
):
- """Write input list of data containers to the specified output file path in mmCIF format.
+ """Write input list of data containers to the specified output file path in mmCIF or BCIF format.
Args:
outputFilePath (string): output file path
containerList (list DataContainer objects, optional)
maxLineLength (int, optional): Maximum length of output line (content is wrapped beyond this length)
- enforceAscii (bool, optional): Filter output (not implemented - content must be ascii compatible on input)
+ enforceAscii (bool, optional): Enforce ASCII encoding when writing out 'mmcif' file. Defaults to True.
lastInOrder (list of category names, optional): Move data categories in this list to end of each data block
selectOrder (list of category names, optional): Write only data categories on this list.
-
columnAlignFlag (bool, optional): Format the output in aligned columns (default=True) (Native Python Only)
useStopTokens (bool, optional): Include terminating 'stop_' tokens at the end of mmCIF categories (loop_'s) (Native Python only)
formattingStep (int, optional): The number row samples within each category used to estimate maximum column width for data alignment (Native Python only)
+ fmt (string, optional): Format of output file (either "mmcif" or "bcif"). Defaults to "mmcif".
+
+ # BCIF-specific args:
+ storeStringsAsBytes (bool, optional): Strings are stored as lists of bytes (for BCIF files only). Defaults to False.
+ defaultStringEncoding (str, optional): Default encoding for string data (for BCIF files only). Defaults to "utf-8".
+ applyTypes (bool, optional): apply explicit data typing before encoding (for BCIF files only; requires dictionaryApi to be passed too). Defaults to True.
+ dictionaryApi (object, optional): DictionaryApi object instance (needed for BCIF files, only when applyTypes is True). Defaults to None.
+ useStringTypes (bool, optional): assume all types are string (for BCIF files only). Defaults to False.
+ useFloat64 (bool, optional): store floats with 64 bit precision (for BCIF files only). Defaults to False.
+ copyInputData (bool, optional): make a new copy input data (for BCIF files only). Defaults to False.
+
**kwargs: Placeholder for unsupported key value pairs
Returns:
bool: Completion status
-
"""
lastInOrder = lastInOrder if lastInOrder else ["pdbx_nonpoly_scheme", "pdbx_poly_seq_scheme", "atom_site", "atom_site_anisotrop"]
if kwargs:
@@ -1669,23 +1872,11 @@
else:
encoding = "utf-8"
#
- if sys.version_info[0] > 2:
- with open(outputFilePath, "w", encoding=encoding) as ofh:
- self.__writeFile(
- ofh,
- containerList,
- maxLineLength=maxLineLength,
- columnAlignFlag=columnAlignFlag,
- lastInOrder=lastInOrder,
- selectOrder=selectOrder,
- useStopTokens=useStopTokens,
- formattingStep=formattingStep,
- enforceAscii=enforceAscii,
- cnvCharRefs=self._useCharRefs,
- )
- else:
- if enforceAscii:
- with io.open(outputFilePath, "w", encoding=encoding) as ofh:
+ fmt = fmt.lower()
+ #
+ if sys.version_info[0] > 2: # Check if using Python version higher than 2
+ if fmt == "mmcif":
+ with open(outputFilePath, "w", encoding=encoding) as ofh:
self.__writeFile(
ofh,
containerList,
@@ -1698,20 +1889,57 @@
enforceAscii=enforceAscii,
cnvCharRefs=self._useCharRefs,
)
+ elif fmt == "bcif":
+ bcifW = BinaryCifWriter(
+ dictionaryApi=dictionaryApi,
+ storeStringsAsBytes=storeStringsAsBytes,
+ defaultStringEncoding=defaultStringEncoding,
+ applyTypes=applyTypes,
+ useStringTypes=useStringTypes,
+ useFloat64=useFloat64,
+ copyInputData=copyInputData,
+ )
+ bcifW.serialize(outputFilePath, containerList)
else:
- with open(outputFilePath, "wb") as ofh:
- self.__writeFile(
- ofh,
- containerList,
- maxLineLength=maxLineLength,
- columnAlignFlag=columnAlignFlag,
- lastInOrder=lastInOrder,
- selectOrder=selectOrder,
- useStopTokens=useStopTokens,
- formattingStep=formattingStep,
- enforceAscii=enforceAscii,
- cnvCharRefs=self._useCharRefs,
- )
+ logger.error("Unsupported fmt %r. Currently only supports 'mmcif' or 'bcif'.", fmt)
+ return False
+ else:
+ logger.warning("Support for Python 2 will be deprecated soon. Please use Python 3.")
+ if fmt == "bcif":
+ logger.error("Support for BCIF writing only available in Python 3.")
+ return False
+ elif fmt == "mmcif":
+ if enforceAscii:
+ with io.open(outputFilePath, "w", encoding=encoding) as ofh:
+ self.__writeFile(
+ ofh,
+ containerList,
+ maxLineLength=maxLineLength,
+ columnAlignFlag=columnAlignFlag,
+ lastInOrder=lastInOrder,
+ selectOrder=selectOrder,
+ useStopTokens=useStopTokens,
+ formattingStep=formattingStep,
+ enforceAscii=enforceAscii,
+ cnvCharRefs=self._useCharRefs,
+ )
+ else:
+ with open(outputFilePath, "wb") as ofh:
+ self.__writeFile(
+ ofh,
+ containerList,
+ maxLineLength=maxLineLength,
+ columnAlignFlag=columnAlignFlag,
+ lastInOrder=lastInOrder,
+ selectOrder=selectOrder,
+ useStopTokens=useStopTokens,
+ formattingStep=formattingStep,
+ enforceAscii=enforceAscii,
+ cnvCharRefs=self._useCharRefs,
+ )
+ else:
+ logger.error("Unsupported fmt %r for Python2 installation of mmcif.io.IoAdapterPy. Currently only 'mmcif' is supported. Upgrade to Python3 for 'bcif' support", fmt)
+ return False
return True
except Exception as ex:
if self._raiseExceptions:
diff --git a/search/search_index.json b/search/search_index.json
index b6a3d0c9..575a1c1b 100644
--- a/search/search_index.json
+++ b/search/search_index.json
@@ -1 +1 @@
-{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"mmCIF Core Access Library","text":""},{"location":"#introduction","title":"Introduction","text":"
This module includes a native Python mmCIF API for data files and dictionaries along with pybind11 wrappers for the PDB C++ Core mmCIF Library.
"},{"location":"#installation","title":"Installation","text":"Download the library source software from the project repository:
git clone --recurse-submodules https://github.com/rcsb/py-mmcif.git\n
Optionally, run test suite using the Tox test runner. The C++ library bindings have been tested on Centos 7/Ubuntu 20.04 Linux with GCC/G++ > 4.8.5 and MacOS (10.15) with > clang-900.0.39.2 using Python versions 2.7.18 and 3.9.4.
tox\n
Installation is via the program pip.
pip install mmcif\n\nor from the local repository:\n\npip install .\n
To generate API documentation using Sphinx:
cd scripts\n# Check Sphinx dependencies in the introductory comments to the following script.\n./initdocs.sh\n
A command-line script is provided as a preprocessor for modular dictionaries that include definition and data content using categories pdbx_include_dictionary, pdbx_include_category and pdbx_include_item.
build_dict_cli --help\nusage: build_dict_cli [-h] --op OP --input_dict_path INPUT_DICT_PATH [--output_dict_path OUTPUT_DICT_PATH] [--cleanup]\n\noptional arguments:\n -h, --help show this help message and exit\n --op OP Operation (build | get_version)\n --input_dict_path INPUT_DICT_PATH\n Path to dictionary generator file\n --output_dict_path OUTPUT_DICT_PATH\n Path to output dictionary text file\n --cleanup Remove include instruction categories after processing\n________________________________________________________________________________\n
"},{"location":"api_reference/BinaryCifReader/","title":"BinaryCifReader","text":"Reader methods for the binary CIF format.
Source code in mmcif/io/BinaryCifReader.py
class BinaryCifReader(object):\n \"\"\"Reader methods for the binary CIF format.\"\"\"\n\n def __init__(self, storeStringsAsBytes=False, defaultStringEncoding=\"utf-8\"):\n \"\"\"Create an instance of the binary CIF reader class.\n\n Args:\n storeStringsAsBytes (bool, optional): strings are stored as lists of bytes. Defaults to False.\n defaultStringEncoding (str, optional): default encoding for string data. Defaults to \"utf-8\".\n \"\"\"\n self.__storeStringsAsBytes = storeStringsAsBytes\n self.__defaultStringEncoding = defaultStringEncoding\n\n def deserialize(self, locator, timeout=None):\n \"\"\"Deserialize the input binary CIF file stored in the file/URL locator path.\n\n Args:\n locator (str): input file path or URL\n timeout (float): timeout for fetching a remote url\n\n Returns:\n list: list DataContainer objects\n \"\"\"\n cL = []\n try:\n if self.__isLocal(locator):\n with gzip.open(locator, mode=\"rb\") if locator[-3:] == \".gz\" else open(locator, \"rb\") as fh:\n cL = self.__deserialize(fh, storeStringsAsBytes=self.__storeStringsAsBytes)\n else:\n if locator.endswith(\".gz\"):\n customHeader = {\"Accept-Encoding\": \"gzip\"}\n with closing(requests.get(locator, headers=customHeader, timeout=timeout)) as fh:\n ufh = gzip.GzipFile(fileobj=io.BytesIO(fh.content))\n cL = self.__deserialize(ufh, storeStringsAsBytes=self.__storeStringsAsBytes)\n else:\n with closing(requests.get(locator, timeout=timeout)) as fh:\n cL = self.__deserialize(io.BytesIO(fh.content), storeStringsAsBytes=self.__storeStringsAsBytes)\n\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n return cL\n\n def __deserialize(self, fh, storeStringsAsBytes=False):\n cL = []\n try:\n dec = BinaryCifDecoders(storeStringsAsBytes=storeStringsAsBytes)\n bD = msgpack.unpack(fh)\n #\n logger.debug(\"bD.keys() %r\", bD.keys())\n logger.debug(\"bD['dataBlocks'] %s\", bD[self.__toBytes(\"dataBlocks\")])\n #\n for dataBlock in bD[self.__toBytes(\"dataBlocks\")]:\n header = self.__fromBytes(dataBlock[self.__toBytes(\"header\")]) if self.__toBytes(\"header\") in dataBlock else None\n logger.debug(\"header %r\", header)\n logger.debug(\"dataBlock %r\", dataBlock)\n #\n dc = DataContainer(header)\n categoryList = dataBlock[self.__toBytes(\"categories\")] if self.__toBytes(\"categories\") in dataBlock else []\n for category in categoryList:\n catName = self.__fromBytes(category[self.__toBytes(\"name\")])[1:]\n colList = category[self.__toBytes(\"columns\")]\n logger.debug(\"catName %r columns %r\", catName, colList)\n colD = OrderedDict()\n atNameList = []\n for col in colList:\n logger.debug(\"col.keys() %r\", col.keys())\n atName = self.__fromBytes(col[self.__toBytes(\"name\")])\n atData = col[self.__toBytes(\"data\")]\n logger.debug(\"atData encoding (%d) data (%d)\", len(atData[self.__toBytes(\"encoding\")]), len(atData[self.__toBytes(\"data\")]))\n atMask = col[self.__toBytes(\"mask\")]\n logger.debug(\"catName %r atName %r\", catName, atName)\n logger.debug(\" >atData.data %r\", atData[self.__toBytes(\"data\")])\n logger.debug(\" >atData.encoding (%d) %r\", len(atData[self.__toBytes(\"encoding\")]), atData[self.__toBytes(\"encoding\")])\n logger.debug(\" >mask %r\", atMask)\n tVal = dec.decode(col[self.__toBytes(\"data\")][self.__toBytes(\"data\")], col[self.__toBytes(\"data\")][self.__toBytes(\"encoding\")])\n if col[self.__toBytes(\"mask\")]:\n mVal = dec.decode(col[self.__toBytes(\"mask\")][self.__toBytes(\"data\")], col[self.__toBytes(\"mask\")][self.__toBytes(\"encoding\")])\n tVal = [\"?\" if m == 2 else \".\" if m == 1 else d for d, m in zip(tVal, mVal)]\n colD[atName] = tVal\n atNameList.append(atName)\n #\n cObj = DataCategory(catName, attributeNameList=atNameList)\n genL = [colGen for colGen in colD.values()]\n for row in zip(*genL):\n logger.debug(\"row %r\", row)\n cObj.append(row)\n #\n dc.append(cObj)\n cL.append(dc)\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n return cL\n\n def __isLocal(self, locator):\n \"\"\"Returns true if input string can be interpreted as a local file path.\n\n Args:\n locator (str): url or path string\n\n Returns:\n bool: True if locator is a local path\n \"\"\"\n try:\n locSp = urlsplit(locator)\n return locSp.scheme in [\"\", \"file\"]\n except Exception as e:\n logger.exception(\"For locator %r failing with %s\", locator, str(e))\n return None\n\n def __toBytes(self, strVal):\n \"\"\"Optional conversion of the input string to bytes according to the class setting (storeStringsAsBytes).\n\n Args:\n strVal (string): input string\n\n Returns:\n string or bytes: optionally converted string.\n \"\"\"\n try:\n return strVal.encode(self.__defaultStringEncoding) if self.__storeStringsAsBytes else strVal\n except (UnicodeDecodeError, AttributeError):\n logger.exception(\"Bad type for %r\", strVal)\n return strVal\n\n def __fromBytes(self, byteVal):\n \"\"\"Optional conversion of the input value according to the class setting (storeStringsAsBytes).\n\n Args:\n byteVal (string): input byte object\n\n Returns:\n string: optionally converted input value\n \"\"\"\n try:\n return byteVal.decode(self.__defaultStringEncoding) if self.__storeStringsAsBytes else byteVal\n except (UnicodeDecodeError, AttributeError):\n logger.exception(\"Bad type for %r\", byteVal)\n return byteVal\n
Column oriented Binary CIF decoders implementing StringArray, ByteArray, IntegerPacking, Delta, RunLength, FixedPoint, and IntervalQuantization from the BinaryCIF specification described in:
Sehnal D, Bittrich S, Velankar S, Koca J, Svobodova R, Burley SK, Rose AS. BinaryCIF and CIFTools-Lightweight, efficient and extensible macromolecular data management. PLoS Comput Biol. 2020 Oct 19;16(10):e1008247. doi: 10.1371/journal.pcbi.1008247. PMID: 33075050; PMCID: PMC7595629.
and in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
and from the I/HM Python implementation at https://github.com/ihmwg/python-ihm[summary]
Source code in mmcif/io/BinaryCifReader.py
class BinaryCifDecoders(object):\n \"\"\"Column oriented Binary CIF decoders implementing\n StringArray, ByteArray, IntegerPacking, Delta, RunLength,\n FixedPoint, and IntervalQuantization from the BinaryCIF\n specification described in:\n\n Sehnal D, Bittrich S, Velankar S, Koca J, Svobodova R, Burley SK, Rose AS.\n BinaryCIF and CIFTools-Lightweight, efficient and extensible macromolecular data management.\n PLoS Comput Biol. 2020 Oct 19;16(10):e1008247.\n doi: 10.1371/journal.pcbi.1008247. PMID: 33075050; PMCID: PMC7595629.\n\n and in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n and from the I/HM Python implementation at https://github.com/ihmwg/python-ihm[summary]\n\n \"\"\"\n\n bCifCodeTypeD = {1: \"integer_8\", 2: \"integer_16\", 3: \"integer_32\", 4: \"unsigned_integer_8\", 5: \"unsigned_integer_16\", 6: \"unsigned_integer_32\", 32: \"float_32\", 33: \"float_64\"}\n \"\"\"Binary CIF protocol internal data type codes to integer and float types\n \"\"\"\n bCifTypeD = {\n \"integer_8\": {\"struct_format_code\": \"b\", \"min\": -0x7F - 1, \"max\": 0x7F},\n \"integer_16\": {\"struct_format_code\": \"h\", \"min\": -0x7FFF - 1, \"max\": 0x7FFF},\n \"integer_32\": {\"struct_format_code\": \"i\", \"min\": -0x7FFFFFFF - 1, \"max\": 0x7FFFFFFF},\n \"unsigned_integer_8\": {\"struct_format_code\": \"B\", \"min\": 0, \"max\": 0xFF},\n \"unsigned_integer_16\": {\"struct_format_code\": \"H\", \"min\": 0, \"max\": 0xFFFF},\n \"unsigned_integer_32\": {\"struct_format_code\": \"I\", \"min\": 0, \"max\": 0xFFFFFFFF},\n \"float_32\": {\"struct_format_code\": \"f\", \"min\": 1.175494351e-38, \"max\": 3.402823466e38},\n \"float_64\": {\"struct_format_code\": \"d\", \"min\": 2.2250738585072014e-308, \"max\": 1.7976931348623158e308},\n }\n \"\"\"Binary CIF data type feature dictionary\n \"\"\"\n\n def __init__(self, storeStringsAsBytes=False, defaultStringEncoding=\"utf-8\", verbose=False):\n \"\"\"Create an instance of the binary CIF encoder class.\n\n Args:\n storeStringsAsBytes (bool, optional): express keys and strings as byte types otherwise follow the default encoding. Defaults to False.\n defaultStringEncoding (str, optional): default encoding for string types. Defaults to \"utf-8\".\n verbose(bool, optional): provide tracking of type conversion issues. Defaults to False.\n \"\"\"\n self.__storeStringsAsBytes = storeStringsAsBytes\n self.__defaultStringEncoding = defaultStringEncoding\n self.__verbose = verbose\n #\n self.__encodersMethodD = {\n \"StringArray\": self.stringArrayDecoder,\n \"ByteArray\": self.byteArrayDecoder,\n \"IntegerPacking\": self.integerPackingDecoder,\n \"Delta\": self.deltaDecoder,\n \"RunLength\": self.runLengthDecoder,\n \"FixedPoint\": self.fixedPointDecoder,\n \"IntervalQuantization\": self.intervalQuantizationDecoder,\n }\n\n def decode(self, colDataList, encodingDictList):\n \"\"\"Return the decoded input data column using the input list of encodings\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDictList (list): list of dictionary holding binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of column data\n \"\"\"\n for encoding in reversed(encodingDictList):\n encType = self.__fromBytes(encoding[self.__toBytes(\"kind\")])\n colDataList = self.__encodersMethodD[encType](colDataList, encoding)\n return colDataList\n\n def stringArrayDecoder(self, colDataList, encodingDict):\n \"\"\"Decode an array of strings stored as a concatenation of all unique\n strings, a list of offsets to construct the unique substrings, and indices into\n the offset array.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of string data\n \"\"\"\n offsetList = list(self.decode(encodingDict[self.__toBytes(\"offsets\")], encodingDict[self.__toBytes(\"offsetEncoding\")]))\n lookupIndexIt = self.decode(colDataList, encodingDict[self.__toBytes(\"dataEncoding\")])\n\n stringData = self.__fromBytes(encodingDict[self.__toBytes(\"stringData\")])\n uniqueStringList = []\n for iBegin, iEnd in zip(offsetList, offsetList[1:]):\n uniqueStringList.append(stringData[iBegin:iEnd])\n logger.debug(\"iBegin %d iEnd %d %r \", iBegin, iEnd, stringData[iBegin:iEnd])\n\n for ii in lookupIndexIt:\n yield uniqueStringList[ii] if ii >= 0 else None\n\n def byteArrayDecoder(self, colDataList, encodingDict):\n \"\"\"Decode input byte list into a list of integers/floats\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of integer/float data\n \"\"\"\n structKey = self.bCifCodeTypeD[encodingDict[self.__toBytes(\"type\")]]\n structFormatCode = self.bCifTypeD[structKey][\"struct_format_code\"]\n count = len(colDataList) // struct.calcsize(structFormatCode)\n # struct.unpack() format string for little-endian = < format_string code * counts\n return struct.unpack(\"<\" + structFormatCode * count, colDataList)\n\n def __unsignedDecode(self, colDataList, encodingDict):\n upperLimit = self.bCifTypeD[\"unsigned_integer_8\"][\"max\"] if encodingDict[self.__toBytes(\"byteCount\")] == 1 else self.bCifTypeD[\"unsigned_integer_16\"][\"max\"]\n ii = 0\n while ii < len(colDataList):\n value = 0\n tVal = colDataList[ii]\n while tVal == upperLimit:\n value += tVal\n ii += 1\n tVal = colDataList[ii]\n yield value + tVal\n ii += 1\n\n def __signedDecode(self, colDataList, encodingDict):\n upperLimit = self.bCifTypeD[\"integer_8\"][\"max\"] if encodingDict[self.__toBytes(\"byteCount\")] == 1 else self.bCifTypeD[\"integer_16\"][\"max\"]\n lowerLimit = self.bCifTypeD[\"integer_8\"][\"min\"] if encodingDict[self.__toBytes(\"byteCount\")] == 1 else self.bCifTypeD[\"integer_16\"][\"min\"]\n ii = 0\n while ii < len(colDataList):\n value = 0\n tVal = colDataList[ii]\n while tVal == upperLimit or tVal == lowerLimit:\n value += tVal\n ii += 1\n tVal = colDataList[ii]\n yield value + tVal\n ii += 1\n\n def integerPackingDecoder(self, colDataList, encodingDict):\n \"\"\"Decode a (32-bit) integer list packed into 8- or 16-bit values.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of integer data\n\n \"\"\"\n if encodingDict[self.__toBytes(\"isUnsigned\")]:\n return self.__unsignedDecode(colDataList, encodingDict)\n else:\n return self.__signedDecode(colDataList, encodingDict)\n\n def deltaDecoder(self, colDataList, encodingDict):\n \"\"\"Decode an integer list stored as a list of consecutive differences.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of integer data\n \"\"\"\n val = encodingDict[self.__toBytes(\"origin\")]\n for diff in colDataList:\n val += diff\n yield val\n\n def runLengthDecoder(self, colDataList, encodingDict):\n \"\"\"Decode an integer list stored as pairs of (value, number of repeats).\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of integer data\n \"\"\"\n _ = encodingDict\n colDataList = list(colDataList)\n for ii in range(0, len(colDataList), 2):\n for _ in range(colDataList[ii + 1]):\n yield colDataList[ii]\n\n def fixedPointDecoder(self, colDataList, encodingDict):\n \"\"\"Decode a floating point list stored as integers and a multiplicative factor.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of float data\n \"\"\"\n factor = float(encodingDict[self.__toBytes(\"factor\")])\n for val in colDataList:\n yield float(val) / factor\n\n def intervalQuantizationDecoder(self, colDataList, encodingDict):\n \"\"\"Decode a list of 32-bit integers quantized within a given interval into a list of floats.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of float data\n\n \"\"\"\n delta = float(encodingDict[self.__toBytes(\"max\")] - encodingDict[self.__toBytes(\"min\")]) / float(encodingDict[self.__toBytes(\"numSteps\")] - 1.0)\n minVal = encodingDict[self.__toBytes(\"min\")]\n for val in colDataList:\n yield minVal + delta * val\n\n def __toBytes(self, strVal):\n \"\"\"Optional conversion of the input string to bytes according to the class setting (storeStringsAsBytes).\n\n Args:\n strVal (string): input string\n\n Returns:\n string or bytes: optionally converted string.\n \"\"\"\n try:\n return strVal.encode(self.__defaultStringEncoding) if self.__storeStringsAsBytes else strVal\n except (UnicodeDecodeError, AttributeError):\n if self.__verbose:\n logger.exception(\"Bad type for %r\", strVal)\n return strVal\n\n def __fromBytes(self, byteVal):\n \"\"\"Optional conversion of the input value according to the class setting (storeStringsAsBytes).\n\n Args:\n byteVal (string): input byte object\n\n Returns:\n string: optionally converted input value\n \"\"\"\n try:\n return byteVal.decode(self.__defaultStringEncoding) if self.__storeStringsAsBytes else byteVal\n except (UnicodeDecodeError, AttributeError):\n if self.__verbose:\n logger.exception(\"Bad type for %r\", byteVal)\n return byteVal\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifReader.__init__","title":"__init__(self, storeStringsAsBytes=False, defaultStringEncoding='utf-8')
special
","text":"Create an instance of the binary CIF reader class.
Parameters:
Name Type Description Default storeStringsAsBytes
bool
strings are stored as lists of bytes. Defaults to False.
False
defaultStringEncoding
str
default encoding for string data. Defaults to \"utf-8\".
'utf-8'
Source code in mmcif/io/BinaryCifReader.py
def __init__(self, storeStringsAsBytes=False, defaultStringEncoding=\"utf-8\"):\n \"\"\"Create an instance of the binary CIF reader class.\n\n Args:\n storeStringsAsBytes (bool, optional): strings are stored as lists of bytes. Defaults to False.\n defaultStringEncoding (str, optional): default encoding for string data. Defaults to \"utf-8\".\n \"\"\"\n self.__storeStringsAsBytes = storeStringsAsBytes\n self.__defaultStringEncoding = defaultStringEncoding\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifReader.deserialize","title":"deserialize(self, locator, timeout=None)
","text":"Deserialize the input binary CIF file stored in the file/URL locator path.
Parameters:
Name Type Description Default locator
str
input file path or URL
required timeout
float
timeout for fetching a remote url
None
Returns:
Type Description list
list DataContainer objects
Source code in mmcif/io/BinaryCifReader.py
def deserialize(self, locator, timeout=None):\n \"\"\"Deserialize the input binary CIF file stored in the file/URL locator path.\n\n Args:\n locator (str): input file path or URL\n timeout (float): timeout for fetching a remote url\n\n Returns:\n list: list DataContainer objects\n \"\"\"\n cL = []\n try:\n if self.__isLocal(locator):\n with gzip.open(locator, mode=\"rb\") if locator[-3:] == \".gz\" else open(locator, \"rb\") as fh:\n cL = self.__deserialize(fh, storeStringsAsBytes=self.__storeStringsAsBytes)\n else:\n if locator.endswith(\".gz\"):\n customHeader = {\"Accept-Encoding\": \"gzip\"}\n with closing(requests.get(locator, headers=customHeader, timeout=timeout)) as fh:\n ufh = gzip.GzipFile(fileobj=io.BytesIO(fh.content))\n cL = self.__deserialize(ufh, storeStringsAsBytes=self.__storeStringsAsBytes)\n else:\n with closing(requests.get(locator, timeout=timeout)) as fh:\n cL = self.__deserialize(io.BytesIO(fh.content), storeStringsAsBytes=self.__storeStringsAsBytes)\n\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n return cL\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.bCifCodeTypeD","title":"bCifCodeTypeD
","text":"Binary CIF protocol internal data type codes to integer and float types
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.bCifTypeD","title":"bCifTypeD
","text":"Binary CIF data type feature dictionary
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.__init__","title":"__init__(self, storeStringsAsBytes=False, defaultStringEncoding='utf-8', verbose=False)
special
","text":"Create an instance of the binary CIF encoder class.
Parameters:
Name Type Description Default storeStringsAsBytes
bool
express keys and strings as byte types otherwise follow the default encoding. Defaults to False.
False
defaultStringEncoding
str
default encoding for string types. Defaults to \"utf-8\".
'utf-8'
verbose(bool,
optional
provide tracking of type conversion issues. Defaults to False.
required Source code in mmcif/io/BinaryCifReader.py
def __init__(self, storeStringsAsBytes=False, defaultStringEncoding=\"utf-8\", verbose=False):\n \"\"\"Create an instance of the binary CIF encoder class.\n\n Args:\n storeStringsAsBytes (bool, optional): express keys and strings as byte types otherwise follow the default encoding. Defaults to False.\n defaultStringEncoding (str, optional): default encoding for string types. Defaults to \"utf-8\".\n verbose(bool, optional): provide tracking of type conversion issues. Defaults to False.\n \"\"\"\n self.__storeStringsAsBytes = storeStringsAsBytes\n self.__defaultStringEncoding = defaultStringEncoding\n self.__verbose = verbose\n #\n self.__encodersMethodD = {\n \"StringArray\": self.stringArrayDecoder,\n \"ByteArray\": self.byteArrayDecoder,\n \"IntegerPacking\": self.integerPackingDecoder,\n \"Delta\": self.deltaDecoder,\n \"RunLength\": self.runLengthDecoder,\n \"FixedPoint\": self.fixedPointDecoder,\n \"IntervalQuantization\": self.intervalQuantizationDecoder,\n }\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.byteArrayDecoder","title":"byteArrayDecoder(self, colDataList, encodingDict)
","text":"Decode input byte list into a list of integers/floats
Parameters:
Name Type Description Default colDataList
list
column of data to be decoded
required encodingDict
dict
dictionary of binary CIF encoding details elements described in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
required Yields:
Type Description list
decoded list of integer/float data
Source code in mmcif/io/BinaryCifReader.py
def byteArrayDecoder(self, colDataList, encodingDict):\n \"\"\"Decode input byte list into a list of integers/floats\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of integer/float data\n \"\"\"\n structKey = self.bCifCodeTypeD[encodingDict[self.__toBytes(\"type\")]]\n structFormatCode = self.bCifTypeD[structKey][\"struct_format_code\"]\n count = len(colDataList) // struct.calcsize(structFormatCode)\n # struct.unpack() format string for little-endian = < format_string code * counts\n return struct.unpack(\"<\" + structFormatCode * count, colDataList)\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.decode","title":"decode(self, colDataList, encodingDictList)
","text":"Return the decoded input data column using the input list of encodings
Parameters:
Name Type Description Default colDataList
list
column of data to be decoded
required encodingDictList
list
list of dictionary holding binary CIF encoding details elements described in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
required Yields:
Type Description list
decoded list of column data
Source code in mmcif/io/BinaryCifReader.py
def decode(self, colDataList, encodingDictList):\n \"\"\"Return the decoded input data column using the input list of encodings\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDictList (list): list of dictionary holding binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of column data\n \"\"\"\n for encoding in reversed(encodingDictList):\n encType = self.__fromBytes(encoding[self.__toBytes(\"kind\")])\n colDataList = self.__encodersMethodD[encType](colDataList, encoding)\n return colDataList\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.deltaDecoder","title":"deltaDecoder(self, colDataList, encodingDict)
","text":"Decode an integer list stored as a list of consecutive differences.
Parameters:
Name Type Description Default colDataList
list
column of data to be decoded
required encodingDict
dict
dictionary of binary CIF encoding details elements described in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
required Yields:
Type Description list
decoded list of integer data
Source code in mmcif/io/BinaryCifReader.py
def deltaDecoder(self, colDataList, encodingDict):\n \"\"\"Decode an integer list stored as a list of consecutive differences.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of integer data\n \"\"\"\n val = encodingDict[self.__toBytes(\"origin\")]\n for diff in colDataList:\n val += diff\n yield val\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.fixedPointDecoder","title":"fixedPointDecoder(self, colDataList, encodingDict)
","text":"Decode a floating point list stored as integers and a multiplicative factor.
Parameters:
Name Type Description Default colDataList
list
column of data to be decoded
required encodingDict
dict
dictionary of binary CIF encoding details elements described in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
required Yields:
Type Description list
decoded list of float data
Source code in mmcif/io/BinaryCifReader.py
def fixedPointDecoder(self, colDataList, encodingDict):\n \"\"\"Decode a floating point list stored as integers and a multiplicative factor.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of float data\n \"\"\"\n factor = float(encodingDict[self.__toBytes(\"factor\")])\n for val in colDataList:\n yield float(val) / factor\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.integerPackingDecoder","title":"integerPackingDecoder(self, colDataList, encodingDict)
","text":"Decode a (32-bit) integer list packed into 8- or 16-bit values.
Parameters:
Name Type Description Default colDataList
list
column of data to be decoded
required encodingDict
dict
dictionary of binary CIF encoding details elements described in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
required Yields:
Type Description list
decoded list of integer data
Source code in mmcif/io/BinaryCifReader.py
def integerPackingDecoder(self, colDataList, encodingDict):\n \"\"\"Decode a (32-bit) integer list packed into 8- or 16-bit values.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of integer data\n\n \"\"\"\n if encodingDict[self.__toBytes(\"isUnsigned\")]:\n return self.__unsignedDecode(colDataList, encodingDict)\n else:\n return self.__signedDecode(colDataList, encodingDict)\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.intervalQuantizationDecoder","title":"intervalQuantizationDecoder(self, colDataList, encodingDict)
","text":"Decode a list of 32-bit integers quantized within a given interval into a list of floats.
Parameters:
Name Type Description Default colDataList
list
column of data to be decoded
required encodingDict
dict
dictionary of binary CIF encoding details elements described in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
required Yields:
Type Description list
decoded list of float data
Source code in mmcif/io/BinaryCifReader.py
def intervalQuantizationDecoder(self, colDataList, encodingDict):\n \"\"\"Decode a list of 32-bit integers quantized within a given interval into a list of floats.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of float data\n\n \"\"\"\n delta = float(encodingDict[self.__toBytes(\"max\")] - encodingDict[self.__toBytes(\"min\")]) / float(encodingDict[self.__toBytes(\"numSteps\")] - 1.0)\n minVal = encodingDict[self.__toBytes(\"min\")]\n for val in colDataList:\n yield minVal + delta * val\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.runLengthDecoder","title":"runLengthDecoder(self, colDataList, encodingDict)
","text":"Decode an integer list stored as pairs of (value, number of repeats).
Parameters:
Name Type Description Default colDataList
list
column of data to be decoded
required encodingDict
dict
dictionary of binary CIF encoding details elements described in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
required Yields:
Type Description list
decoded list of integer data
Source code in mmcif/io/BinaryCifReader.py
def runLengthDecoder(self, colDataList, encodingDict):\n \"\"\"Decode an integer list stored as pairs of (value, number of repeats).\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of integer data\n \"\"\"\n _ = encodingDict\n colDataList = list(colDataList)\n for ii in range(0, len(colDataList), 2):\n for _ in range(colDataList[ii + 1]):\n yield colDataList[ii]\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.stringArrayDecoder","title":"stringArrayDecoder(self, colDataList, encodingDict)
","text":"Decode an array of strings stored as a concatenation of all unique strings, a list of offsets to construct the unique substrings, and indices into the offset array.
Parameters:
Name Type Description Default colDataList
list
column of data to be decoded
required encodingDict
dict
dictionary of binary CIF encoding details elements described in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
required Yields:
Type Description list
decoded list of string data
Source code in mmcif/io/BinaryCifReader.py
def stringArrayDecoder(self, colDataList, encodingDict):\n \"\"\"Decode an array of strings stored as a concatenation of all unique\n strings, a list of offsets to construct the unique substrings, and indices into\n the offset array.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of string data\n \"\"\"\n offsetList = list(self.decode(encodingDict[self.__toBytes(\"offsets\")], encodingDict[self.__toBytes(\"offsetEncoding\")]))\n lookupIndexIt = self.decode(colDataList, encodingDict[self.__toBytes(\"dataEncoding\")])\n\n stringData = self.__fromBytes(encodingDict[self.__toBytes(\"stringData\")])\n uniqueStringList = []\n for iBegin, iEnd in zip(offsetList, offsetList[1:]):\n uniqueStringList.append(stringData[iBegin:iEnd])\n logger.debug(\"iBegin %d iEnd %d %r \", iBegin, iEnd, stringData[iBegin:iEnd])\n\n for ii in lookupIndexIt:\n yield uniqueStringList[ii] if ii >= 0 else None\n
"},{"location":"api_reference/BinaryCifWriter/","title":"BinaryCifWriter","text":"Writer methods for the binary CIF format.
Source code in mmcif/io/BinaryCifWriter.py
class BinaryCifWriter(object):\n \"\"\"Writer methods for the binary CIF format.\"\"\"\n\n def __init__(self, dictionaryApi, storeStringsAsBytes=False, defaultStringEncoding=\"utf-8\", applyTypes=True, useStringTypes=False, useFloat64=False):\n \"\"\"Create an instance of the binary CIF writer class.\n\n Args:\n dictionaryApi (object): DictionaryApi object instance\n storeStringsAsBytes (bool, optional): strings are stored as lists of bytes. Defaults to False.\n defaultStringEncoding (str, optional): default encoding for string data. Defaults to \"utf-8\".\n applyTypes (bool, optional): apply explicit data typing before encoding. Defaults to True.\n useStringTypes (bool, optional): assume all types are string. Defaults to False.\n useFloat64 (bool, optional): store floats with 64 bit precision. Defaults to False.\n \"\"\"\n self.__version = \"0.01\"\n self.__storeStringsAsBytes = storeStringsAsBytes\n self.__defaultStringEncoding = defaultStringEncoding\n self.__applyTypes = applyTypes\n self.__useStringTypes = useStringTypes\n self.__useFloat64 = useFloat64\n self.__dApi = dictionaryApi\n\n def serialize(self, filePath, containerList):\n \"\"\"Serialize the input container list in binary CIF and store these data in the input file path.\n\n Args:\n filePath (str): output file path\n containerList (list): list of DataContainer objects\n \"\"\"\n try:\n blocks = []\n for container in containerList:\n name = container.getName()\n block = {self.__toBytes(\"header\"): self.__toBytes(name), self.__toBytes(\"categories\"): []}\n categories = block[self.__toBytes(\"categories\")]\n blocks.append(block)\n for catName in container.getObjNameList():\n cObj = container.getObj(catName)\n if self.__applyTypes:\n cObj = DataCategoryTyped(cObj, dictionaryApi=self.__dApi, copyInputData=False)\n #\n rowCount = cObj.getRowCount()\n #\n cols = []\n for ii, atName in enumerate(cObj.getAttributeList()):\n colDataList = cObj.getColumn(ii)\n dataType = self.__getAttributeType(cObj, atName) if not self.__useStringTypes else \"string\"\n logger.debug(\"catName %r atName %r dataType %r\", catName, atName, dataType)\n colMaskDict, encodedColDataList, encodingDictL = self.__encodeColumnData(colDataList, dataType)\n cols.append(\n {\n self.__toBytes(\"name\"): self.__toBytes(atName),\n self.__toBytes(\"mask\"): colMaskDict,\n self.__toBytes(\"data\"): {self.__toBytes(\"data\"): encodedColDataList, self.__toBytes(\"encoding\"): encodingDictL},\n }\n )\n categories.append({self.__toBytes(\"name\"): self.__toBytes(\"_\" + catName), self.__toBytes(\"columns\"): cols, self.__toBytes(\"rowCount\"): rowCount})\n #\n data = {\n self.__toBytes(\"version\"): self.__toBytes(self.__version),\n self.__toBytes(\"encoder\"): self.__toBytes(\"python-mmcif library\"),\n self.__toBytes(\"dataBlocks\"): blocks,\n }\n with open(filePath, \"wb\") as ofh:\n msgpack.pack(data, ofh)\n return True\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n return False\n\n def __encodeColumnData(self, colDataList, dataType):\n colMaskDict = {}\n enc = BinaryCifEncoders(defaultStringEncoding=self.__defaultStringEncoding, storeStringsAsBytes=self.__storeStringsAsBytes, useFloat64=self.__useFloat64)\n #\n maskEncoderList = [\"Delta\", \"RunLength\", \"ByteArray\"]\n typeEncoderD = {\"string\": \"StringArrayMasked\", \"integer\": \"IntArrayMasked\", \"float\": \"FloatArrayMasked\"}\n colMaskList = enc.getMask(colDataList)\n dataEncType = typeEncoderD[dataType]\n colDataEncoded, colDataEncodingDictL = enc.encodeWithMask(colDataList, colMaskList, dataEncType)\n if colMaskList:\n maskEncoded, maskEncodingDictL = enc.encode(colMaskList, maskEncoderList, \"integer\")\n colMaskDict = {self.__toBytes(\"data\"): maskEncoded, self.__toBytes(\"encoding\"): maskEncodingDictL}\n return colMaskDict, colDataEncoded, colDataEncodingDictL\n\n def __toBytes(self, strVal):\n \"\"\"Optional conversion of the input string to bytes according to the class setting (storeStringsAsBytes).\n\n Args:\n strVal (string): input string\n\n Returns:\n string or bytes: optionally converted string.\n \"\"\"\n try:\n return strVal.encode(self.__defaultStringEncoding) if self.__storeStringsAsBytes else strVal\n except (UnicodeDecodeError, AttributeError):\n logger.exception(\"Bad type for %r\", strVal)\n return strVal\n\n def __getAttributeType(self, dObj, atName):\n \"\"\"Get attribute data type (string, integer, or float) and optionality\n\n Args:\n atName (str): attribute name\n\n Returns:\n (string): data type (string, integer or float)\n \"\"\"\n cifDataType = self.__dApi.getTypeCode(dObj.getName(), atName)\n cifPrimitiveType = self.__dApi.getTypePrimitive(dObj.getName(), atName)\n dataType = \"integer\" if \"int\" in cifDataType else \"float\" if cifPrimitiveType == \"numb\" else \"string\"\n return dataType\n
Column oriented Binary CIF encoders implementing StringArray, ByteArray, IntegerPacking, Delta, RunLength, and FixedPoint encoders from the BinaryCIF specification described in:
Sehnal D, Bittrich S, Velankar S, Koca J, Svobodova R, Burley SK, Rose AS. BinaryCIF and CIFTools-Lightweight, efficient and extensible macromolecular data management. PLoS Comput Biol. 2020 Oct 19;16(10):e1008247. doi: 10.1371/journal.pcbi.1008247. PMID: 33075050; PMCID: PMC7595629.
and in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
and from the I/HM Python implementation at https://github.com/ihmwg/python-ihm
Source code in mmcif/io/BinaryCifWriter.py
class BinaryCifEncoders(object):\n \"\"\"Column oriented Binary CIF encoders implementing\n StringArray, ByteArray, IntegerPacking, Delta, RunLength,\n and FixedPoint encoders from the BinaryCIF specification described in:\n\n Sehnal D, Bittrich S, Velankar S, Koca J, Svobodova R, Burley SK, Rose AS.\n BinaryCIF and CIFTools-Lightweight, efficient and extensible macromolecular data management.\n PLoS Comput Biol. 2020 Oct 19;16(10):e1008247.\n doi: 10.1371/journal.pcbi.1008247. PMID: 33075050; PMCID: PMC7595629.\n\n and in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n and from the I/HM Python implementation at https://github.com/ihmwg/python-ihm\n\n \"\"\"\n\n def __init__(self, defaultStringEncoding=\"utf-8\", storeStringsAsBytes=True, useFloat64=False):\n \"\"\"Instantiate the binary CIF encoder class.\n\n Args:\n defaultStringEncoding (str, optional): default encoding for string data . Defaults to \"utf-8\".\n storeStringsAsBytes (bool, optional): strings are stored as bytes. Defaults to True.\n useFloat64 (bool, optional): store floats in 64 bit precision. Defaults to True.\n \"\"\"\n self.__unknown = [\".\", \"?\"]\n self.__defaultStringEncoding = defaultStringEncoding\n self.__storeStringsAsBytes = storeStringsAsBytes\n self.__useFloat64 = useFloat64\n self.__bCifTypeCodeD = {v: k for k, v in BinaryCifDecoders.bCifCodeTypeD.items()}\n\n def encode(self, colDataList, encodingTypeList, dataType):\n \"\"\"Encode the data using the input list of encoding types returning encoded data and encoding instructions.\n\n Args:\n colDataList (list): input data to be encoded\n encodingTypeList (list): list of encoding types (ByteArray, Delta, or RunLength)\n dataType (string): column input data type (string, integer, float)\n\n Returns:\n (list, list ): encoded data column, list of encoding instructions\n \"\"\"\n encodingDictL = []\n for encType in encodingTypeList:\n if encType == \"ByteArray\":\n colDataList, encDict = self.byteArrayEncoder(colDataList, dataType)\n elif encType == \"Delta\":\n colDataList, encDict = self.deltaEncoder(colDataList)\n elif encType == \"RunLength\":\n colDataList, encDict = self.runLengthEncoder(colDataList)\n else:\n logger.info(\"unsupported encoding %r\", encType)\n if encDict is not None:\n encodingDictL.append(encDict)\n return colDataList, encodingDictL\n\n def encodeWithMask(self, colDataList, colMaskList, encodingType):\n \"\"\"Encode the data using the input mask and encoding type returning encoded data and encoding instructions.\n\n Args:\n colDataList (string): input data column\n colMaskList (list): incompleteness mask for the input data column\n encodingType (string): encoding type to apply (StringArrayMask, IntArrayMasked, FloatArrayMasked)\n\n Returns:\n (list, list ): encoded data column, list of encoding instructions\n \"\"\"\n encodedColDataList = []\n encodingDictL = []\n if encodingType == \"StringArrayMasked\":\n encodedColDataList, encodingDictL = self.stringArrayMaskedEncoder(colDataList, colMaskList)\n elif encodingType == \"IntArrayMasked\":\n encodedColDataList, encodingDictL = self.intArrayMaskedEncoder(colDataList, colMaskList)\n elif encodingType == \"FloatArrayMasked\":\n encodedColDataList, encodingDictL = self.floatArrayMaskedEncoder(colDataList, colMaskList)\n else:\n logger.info(\"unsupported masked encoding %r\", encodingType)\n return encodedColDataList, encodingDictL\n\n def __getIntegerPackingType(self, colDataList):\n \"\"\"Determine the integer packing type of the input integer data list\"\"\"\n try:\n minV = min(colDataList)\n maxV = max(colDataList)\n if minV >= 0:\n # Unsigned types\n for typeName in [\"unsigned_integer_8\", \"unsigned_integer_16\", \"unsigned_integer_32\"]:\n byteArrayType = self.__bCifTypeCodeD[typeName]\n upperLimit = BinaryCifDecoders.bCifTypeD[typeName][\"max\"]\n if maxV <= upperLimit:\n return byteArrayType\n else:\n # Signed types\n for typeName in [\"integer_8\", \"integer_16\", \"integer_32\"]:\n byteArrayType = self.__bCifTypeCodeD[typeName]\n upperLimit = BinaryCifDecoders.bCifTypeD[typeName][\"max\"]\n lowerLimit = BinaryCifDecoders.bCifTypeD[typeName][\"min\"]\n if minV >= lowerLimit and maxV <= upperLimit:\n return byteArrayType\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n raise TypeError(\"Cannot determine interger packing type\")\n\n def byteArrayEncoder(self, colDataList, dataType):\n \"\"\"Encode integer or float list in a packed byte array.\n\n Args:\n data (list): list of integer or float data\n dataType (str): data type (integer|float)\n\n Returns:\n bytes: byte encoded packed data\n \"\"\"\n if dataType == \"float\":\n byteArrayType = self.__bCifTypeCodeD[\"float_64\"] if self.__useFloat64 else self.__bCifTypeCodeD[\"float_32\"]\n else:\n byteArrayType = self.__getIntegerPackingType(colDataList)\n encodingD = {self.__toBytes(\"kind\"): self.__toBytes(\"ByteArray\"), self.__toBytes(\"type\"): byteArrayType}\n fmt = BinaryCifDecoders.bCifTypeD[BinaryCifDecoders.bCifCodeTypeD[byteArrayType]][\"struct_format_code\"]\n # Data are encoded little-endian '<'\n return struct.pack(\"<\" + fmt * len(colDataList), *colDataList), encodingD\n\n def deltaEncoder(self, colDataList, minLen=40):\n \"\"\"Encode an integer list as a list of consecutive differences.\n\n Args:\n colDataList (list): list of integer data\n minLen (int, optional): minimum list length to apply encoder. Defaults to 40.\n\n Returns:\n list: delta encoded integer list\n \"\"\"\n if len(colDataList) <= minLen:\n return colDataList, None\n byteArrayType = self.__getIntegerPackingType(colDataList)\n encodingD = {self.__toBytes(\"kind\"): self.__toBytes(\"Delta\"), self.__toBytes(\"origin\"): colDataList[0], self.__toBytes(\"srcType\"): byteArrayType}\n encodedColDataList = [0] + [colDataList[i] - colDataList[i - 1] for i in range(1, len(colDataList))]\n return encodedColDataList, encodingD\n\n def runLengthEncoder(self, colDataList, minLen=40):\n \"\"\"Encode an integer array as pairs of (value, number of repeats)\n\n Args:\n colDataList (list): list of integer data\n minLen (int, optional): minimum list length to apply encoder. Defaults to 40.\n\n Returns:\n list: runlength encoded integer list\n \"\"\"\n\n if len(colDataList) <= minLen:\n return colDataList, None\n byteArrayType = self.__getIntegerPackingType(colDataList)\n encodingD = {self.__toBytes(\"kind\"): self.__toBytes(\"RunLength\"), self.__toBytes(\"srcType\"): byteArrayType, self.__toBytes(\"srcSize\"): len(colDataList)}\n encodedColDataList = []\n val = None\n repeat = 1\n for colVal in colDataList:\n if colVal != val:\n if val is not None:\n encodedColDataList.extend((val, repeat))\n val = colVal\n repeat = 1\n else:\n repeat += 1\n encodedColDataList.extend((val, repeat))\n # Check for any gains and possibly retreat\n if len(encodedColDataList) > len(colDataList):\n return colDataList, None\n else:\n return encodedColDataList, encodingD\n\n def stringArrayMaskedEncoder(self, colDataList, colMaskList):\n \"\"\"Encode the input data column (string) along with the incompleteness mask.\n\n Args:\n colDataList (list): input data column (string)\n colMaskList (list): incompleteness mask\n\n Returns:\n (list, list): encoded data column, list of encoding instructions\n \"\"\"\n integerEncoderList = [\"Delta\", \"RunLength\", \"ByteArray\"]\n uniqStringIndex = {} # keys are substrings, values indices\n uniqStringList = []\n indexList = []\n for i, strVal in enumerate(colDataList):\n if colMaskList is not None and colMaskList[i]:\n indexList.append(-1)\n else:\n tS = strVal\n tS = str(tS)\n if tS not in uniqStringIndex:\n uniqStringIndex[tS] = len(uniqStringIndex)\n uniqStringList.append(tS)\n indexList.append(uniqStringIndex[tS])\n offsetList = [0]\n runningLen = 0\n for tS in uniqStringList:\n runningLen += len(tS)\n offsetList.append(runningLen)\n\n encodedOffsetList, offsetEncodingDictL = self.encode(offsetList, integerEncoderList, \"integer\")\n encodedIndexList, indexEncodingDictL = self.encode(indexList, integerEncoderList, \"integer\")\n\n encodingDict = {\n self.__toBytes(\"kind\"): self.__toBytes(\"StringArray\"),\n self.__toBytes(\"dataEncoding\"): indexEncodingDictL,\n self.__toBytes(\"stringData\"): self.__toBytes(\"\".join(uniqStringList)),\n self.__toBytes(\"offsetEncoding\"): offsetEncodingDictL,\n self.__toBytes(\"offsets\"): encodedOffsetList,\n }\n return encodedIndexList, [encodingDict]\n\n def intArrayMaskedEncoder(self, colDataList, colMaskList):\n \"\"\"Encode the input data column (integer) along with the incompleteness mask.\n\n Args:\n colDataList (list): input data column (string)\n colMaskList (list): incompleteness mask\n\n Returns:\n (list, list): encoded data column, list of encoding instructions\n \"\"\"\n integerEncoderList = [\"Delta\", \"RunLength\", \"ByteArray\"]\n\n if colMaskList:\n maskedColDataList = [-1 if m else d for m, d in zip(colMaskList, colDataList)]\n else:\n maskedColDataList = colDataList\n encodedColDataList, encodingDictL = self.encode(maskedColDataList, integerEncoderList, \"integer\")\n return encodedColDataList, encodingDictL\n\n def floatArrayMaskedEncoder(self, colDataList, colMaskList):\n \"\"\"Encode the input data column (float) along with the incompleteness mask.\n\n Args:\n colDataList (list): input data column (string)\n colMaskList (list): incompleteness mask\n\n Returns:\n (list, list): encoded data column, list of encoding instructions\n \"\"\"\n floatEncoderList = [\"ByteArray\"]\n\n if colMaskList:\n maskedColDataList = [0.0 if m else d for m, d in zip(colMaskList, colDataList)]\n else:\n maskedColDataList = colDataList\n encodedColDataList, encodingDictL = self.encode(maskedColDataList, floatEncoderList, \"float\")\n return encodedColDataList, encodingDictL\n\n def getMask(self, colDataList):\n \"\"\"Create an incompleteness mask list identifying missing/omitted values in the input data column.\n The mask is assigned: 0 = Value is present, 1 = '.' (value not specified), and 2 = '?' (value unknown).\n\n Args:\n colDataList (list): input data column\n\n Returns:\n list or None: mask list or None if the column contains no missing values\n \"\"\"\n mask = None\n for ii, colVal in enumerate(colDataList):\n if colVal is not None and colVal not in self.__unknown:\n continue\n if not mask:\n mask = [0] * len(colDataList)\n mask[ii] = 2 if colVal is None or colVal == \"?\" else 1\n return mask\n\n def __toBytes(self, strVal):\n \"\"\"Optional conversion of the input string to bytes according to the class setting (storeStringsAsBytes).\n\n Args:\n strVal (string): input string\n\n Returns:\n string or bytes: optionally converted string.\n \"\"\"\n try:\n return strVal.encode(self.__defaultStringEncoding) if self.__storeStringsAsBytes else strVal\n except (UnicodeDecodeError, AttributeError):\n logger.exception(\"Bad type for %r\", strVal)\n return strVal\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifWriter.__init__","title":"__init__(self, dictionaryApi, storeStringsAsBytes=False, defaultStringEncoding='utf-8', applyTypes=True, useStringTypes=False, useFloat64=False)
special
","text":"Create an instance of the binary CIF writer class.
Parameters:
Name Type Description Default dictionaryApi
object
DictionaryApi object instance
required storeStringsAsBytes
bool
strings are stored as lists of bytes. Defaults to False.
False
defaultStringEncoding
str
default encoding for string data. Defaults to \"utf-8\".
'utf-8'
applyTypes
bool
apply explicit data typing before encoding. Defaults to True.
True
useStringTypes
bool
assume all types are string. Defaults to False.
False
useFloat64
bool
store floats with 64 bit precision. Defaults to False.
False
Source code in mmcif/io/BinaryCifWriter.py
def __init__(self, dictionaryApi, storeStringsAsBytes=False, defaultStringEncoding=\"utf-8\", applyTypes=True, useStringTypes=False, useFloat64=False):\n \"\"\"Create an instance of the binary CIF writer class.\n\n Args:\n dictionaryApi (object): DictionaryApi object instance\n storeStringsAsBytes (bool, optional): strings are stored as lists of bytes. Defaults to False.\n defaultStringEncoding (str, optional): default encoding for string data. Defaults to \"utf-8\".\n applyTypes (bool, optional): apply explicit data typing before encoding. Defaults to True.\n useStringTypes (bool, optional): assume all types are string. Defaults to False.\n useFloat64 (bool, optional): store floats with 64 bit precision. Defaults to False.\n \"\"\"\n self.__version = \"0.01\"\n self.__storeStringsAsBytes = storeStringsAsBytes\n self.__defaultStringEncoding = defaultStringEncoding\n self.__applyTypes = applyTypes\n self.__useStringTypes = useStringTypes\n self.__useFloat64 = useFloat64\n self.__dApi = dictionaryApi\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifWriter.serialize","title":"serialize(self, filePath, containerList)
","text":"Serialize the input container list in binary CIF and store these data in the input file path.
Parameters:
Name Type Description Default filePath
str
output file path
required containerList
list
list of DataContainer objects
required Source code in mmcif/io/BinaryCifWriter.py
def serialize(self, filePath, containerList):\n \"\"\"Serialize the input container list in binary CIF and store these data in the input file path.\n\n Args:\n filePath (str): output file path\n containerList (list): list of DataContainer objects\n \"\"\"\n try:\n blocks = []\n for container in containerList:\n name = container.getName()\n block = {self.__toBytes(\"header\"): self.__toBytes(name), self.__toBytes(\"categories\"): []}\n categories = block[self.__toBytes(\"categories\")]\n blocks.append(block)\n for catName in container.getObjNameList():\n cObj = container.getObj(catName)\n if self.__applyTypes:\n cObj = DataCategoryTyped(cObj, dictionaryApi=self.__dApi, copyInputData=False)\n #\n rowCount = cObj.getRowCount()\n #\n cols = []\n for ii, atName in enumerate(cObj.getAttributeList()):\n colDataList = cObj.getColumn(ii)\n dataType = self.__getAttributeType(cObj, atName) if not self.__useStringTypes else \"string\"\n logger.debug(\"catName %r atName %r dataType %r\", catName, atName, dataType)\n colMaskDict, encodedColDataList, encodingDictL = self.__encodeColumnData(colDataList, dataType)\n cols.append(\n {\n self.__toBytes(\"name\"): self.__toBytes(atName),\n self.__toBytes(\"mask\"): colMaskDict,\n self.__toBytes(\"data\"): {self.__toBytes(\"data\"): encodedColDataList, self.__toBytes(\"encoding\"): encodingDictL},\n }\n )\n categories.append({self.__toBytes(\"name\"): self.__toBytes(\"_\" + catName), self.__toBytes(\"columns\"): cols, self.__toBytes(\"rowCount\"): rowCount})\n #\n data = {\n self.__toBytes(\"version\"): self.__toBytes(self.__version),\n self.__toBytes(\"encoder\"): self.__toBytes(\"python-mmcif library\"),\n self.__toBytes(\"dataBlocks\"): blocks,\n }\n with open(filePath, \"wb\") as ofh:\n msgpack.pack(data, ofh)\n return True\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n return False\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.__init__","title":"__init__(self, defaultStringEncoding='utf-8', storeStringsAsBytes=True, useFloat64=False)
special
","text":"Instantiate the binary CIF encoder class.
Parameters:
Name Type Description Default defaultStringEncoding
str
default encoding for string data . Defaults to \"utf-8\".
'utf-8'
storeStringsAsBytes
bool
strings are stored as bytes. Defaults to True.
True
useFloat64
bool
store floats in 64 bit precision. Defaults to True.
False
Source code in mmcif/io/BinaryCifWriter.py
def __init__(self, defaultStringEncoding=\"utf-8\", storeStringsAsBytes=True, useFloat64=False):\n \"\"\"Instantiate the binary CIF encoder class.\n\n Args:\n defaultStringEncoding (str, optional): default encoding for string data . Defaults to \"utf-8\".\n storeStringsAsBytes (bool, optional): strings are stored as bytes. Defaults to True.\n useFloat64 (bool, optional): store floats in 64 bit precision. Defaults to True.\n \"\"\"\n self.__unknown = [\".\", \"?\"]\n self.__defaultStringEncoding = defaultStringEncoding\n self.__storeStringsAsBytes = storeStringsAsBytes\n self.__useFloat64 = useFloat64\n self.__bCifTypeCodeD = {v: k for k, v in BinaryCifDecoders.bCifCodeTypeD.items()}\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.byteArrayEncoder","title":"byteArrayEncoder(self, colDataList, dataType)
","text":"Encode integer or float list in a packed byte array.
Parameters:
Name Type Description Default data
list
list of integer or float data
required dataType
str
data type (integer|float)
required Returns:
Type Description bytes
byte encoded packed data
Source code in mmcif/io/BinaryCifWriter.py
def byteArrayEncoder(self, colDataList, dataType):\n \"\"\"Encode integer or float list in a packed byte array.\n\n Args:\n data (list): list of integer or float data\n dataType (str): data type (integer|float)\n\n Returns:\n bytes: byte encoded packed data\n \"\"\"\n if dataType == \"float\":\n byteArrayType = self.__bCifTypeCodeD[\"float_64\"] if self.__useFloat64 else self.__bCifTypeCodeD[\"float_32\"]\n else:\n byteArrayType = self.__getIntegerPackingType(colDataList)\n encodingD = {self.__toBytes(\"kind\"): self.__toBytes(\"ByteArray\"), self.__toBytes(\"type\"): byteArrayType}\n fmt = BinaryCifDecoders.bCifTypeD[BinaryCifDecoders.bCifCodeTypeD[byteArrayType]][\"struct_format_code\"]\n # Data are encoded little-endian '<'\n return struct.pack(\"<\" + fmt * len(colDataList), *colDataList), encodingD\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.deltaEncoder","title":"deltaEncoder(self, colDataList, minLen=40)
","text":"Encode an integer list as a list of consecutive differences.
Parameters:
Name Type Description Default colDataList
list
list of integer data
required minLen
int
minimum list length to apply encoder. Defaults to 40.
40
Returns:
Type Description list
delta encoded integer list
Source code in mmcif/io/BinaryCifWriter.py
def deltaEncoder(self, colDataList, minLen=40):\n \"\"\"Encode an integer list as a list of consecutive differences.\n\n Args:\n colDataList (list): list of integer data\n minLen (int, optional): minimum list length to apply encoder. Defaults to 40.\n\n Returns:\n list: delta encoded integer list\n \"\"\"\n if len(colDataList) <= minLen:\n return colDataList, None\n byteArrayType = self.__getIntegerPackingType(colDataList)\n encodingD = {self.__toBytes(\"kind\"): self.__toBytes(\"Delta\"), self.__toBytes(\"origin\"): colDataList[0], self.__toBytes(\"srcType\"): byteArrayType}\n encodedColDataList = [0] + [colDataList[i] - colDataList[i - 1] for i in range(1, len(colDataList))]\n return encodedColDataList, encodingD\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.encode","title":"encode(self, colDataList, encodingTypeList, dataType)
","text":"Encode the data using the input list of encoding types returning encoded data and encoding instructions.
Parameters:
Name Type Description Default colDataList
list
input data to be encoded
required encodingTypeList
list
list of encoding types (ByteArray, Delta, or RunLength)
required dataType
string
column input data type (string, integer, float)
required Returns:
Type Description (list, list )
encoded data column, list of encoding instructions
Source code in mmcif/io/BinaryCifWriter.py
def encode(self, colDataList, encodingTypeList, dataType):\n \"\"\"Encode the data using the input list of encoding types returning encoded data and encoding instructions.\n\n Args:\n colDataList (list): input data to be encoded\n encodingTypeList (list): list of encoding types (ByteArray, Delta, or RunLength)\n dataType (string): column input data type (string, integer, float)\n\n Returns:\n (list, list ): encoded data column, list of encoding instructions\n \"\"\"\n encodingDictL = []\n for encType in encodingTypeList:\n if encType == \"ByteArray\":\n colDataList, encDict = self.byteArrayEncoder(colDataList, dataType)\n elif encType == \"Delta\":\n colDataList, encDict = self.deltaEncoder(colDataList)\n elif encType == \"RunLength\":\n colDataList, encDict = self.runLengthEncoder(colDataList)\n else:\n logger.info(\"unsupported encoding %r\", encType)\n if encDict is not None:\n encodingDictL.append(encDict)\n return colDataList, encodingDictL\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.encodeWithMask","title":"encodeWithMask(self, colDataList, colMaskList, encodingType)
","text":"Encode the data using the input mask and encoding type returning encoded data and encoding instructions.
Parameters:
Name Type Description Default colDataList
string
input data column
required colMaskList
list
incompleteness mask for the input data column
required encodingType
string
encoding type to apply (StringArrayMask, IntArrayMasked, FloatArrayMasked)
required Returns:
Type Description (list, list )
encoded data column, list of encoding instructions
Source code in mmcif/io/BinaryCifWriter.py
def encodeWithMask(self, colDataList, colMaskList, encodingType):\n \"\"\"Encode the data using the input mask and encoding type returning encoded data and encoding instructions.\n\n Args:\n colDataList (string): input data column\n colMaskList (list): incompleteness mask for the input data column\n encodingType (string): encoding type to apply (StringArrayMask, IntArrayMasked, FloatArrayMasked)\n\n Returns:\n (list, list ): encoded data column, list of encoding instructions\n \"\"\"\n encodedColDataList = []\n encodingDictL = []\n if encodingType == \"StringArrayMasked\":\n encodedColDataList, encodingDictL = self.stringArrayMaskedEncoder(colDataList, colMaskList)\n elif encodingType == \"IntArrayMasked\":\n encodedColDataList, encodingDictL = self.intArrayMaskedEncoder(colDataList, colMaskList)\n elif encodingType == \"FloatArrayMasked\":\n encodedColDataList, encodingDictL = self.floatArrayMaskedEncoder(colDataList, colMaskList)\n else:\n logger.info(\"unsupported masked encoding %r\", encodingType)\n return encodedColDataList, encodingDictL\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.floatArrayMaskedEncoder","title":"floatArrayMaskedEncoder(self, colDataList, colMaskList)
","text":"Encode the input data column (float) along with the incompleteness mask.
Parameters:
Name Type Description Default colDataList
list
input data column (string)
required colMaskList
list
incompleteness mask
required Returns:
Type Description (list, list)
encoded data column, list of encoding instructions
Source code in mmcif/io/BinaryCifWriter.py
def floatArrayMaskedEncoder(self, colDataList, colMaskList):\n \"\"\"Encode the input data column (float) along with the incompleteness mask.\n\n Args:\n colDataList (list): input data column (string)\n colMaskList (list): incompleteness mask\n\n Returns:\n (list, list): encoded data column, list of encoding instructions\n \"\"\"\n floatEncoderList = [\"ByteArray\"]\n\n if colMaskList:\n maskedColDataList = [0.0 if m else d for m, d in zip(colMaskList, colDataList)]\n else:\n maskedColDataList = colDataList\n encodedColDataList, encodingDictL = self.encode(maskedColDataList, floatEncoderList, \"float\")\n return encodedColDataList, encodingDictL\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.getMask","title":"getMask(self, colDataList)
","text":"Create an incompleteness mask list identifying missing/omitted values in the input data column. The mask is assigned: 0 = Value is present, 1 = '.' (value not specified), and 2 = '?' (value unknown).
Parameters:
Name Type Description Default colDataList
list
input data column
required Returns:
Type Description list or None
mask list or None if the column contains no missing values
Source code in mmcif/io/BinaryCifWriter.py
def getMask(self, colDataList):\n \"\"\"Create an incompleteness mask list identifying missing/omitted values in the input data column.\n The mask is assigned: 0 = Value is present, 1 = '.' (value not specified), and 2 = '?' (value unknown).\n\n Args:\n colDataList (list): input data column\n\n Returns:\n list or None: mask list or None if the column contains no missing values\n \"\"\"\n mask = None\n for ii, colVal in enumerate(colDataList):\n if colVal is not None and colVal not in self.__unknown:\n continue\n if not mask:\n mask = [0] * len(colDataList)\n mask[ii] = 2 if colVal is None or colVal == \"?\" else 1\n return mask\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.intArrayMaskedEncoder","title":"intArrayMaskedEncoder(self, colDataList, colMaskList)
","text":"Encode the input data column (integer) along with the incompleteness mask.
Parameters:
Name Type Description Default colDataList
list
input data column (string)
required colMaskList
list
incompleteness mask
required Returns:
Type Description (list, list)
encoded data column, list of encoding instructions
Source code in mmcif/io/BinaryCifWriter.py
def intArrayMaskedEncoder(self, colDataList, colMaskList):\n \"\"\"Encode the input data column (integer) along with the incompleteness mask.\n\n Args:\n colDataList (list): input data column (string)\n colMaskList (list): incompleteness mask\n\n Returns:\n (list, list): encoded data column, list of encoding instructions\n \"\"\"\n integerEncoderList = [\"Delta\", \"RunLength\", \"ByteArray\"]\n\n if colMaskList:\n maskedColDataList = [-1 if m else d for m, d in zip(colMaskList, colDataList)]\n else:\n maskedColDataList = colDataList\n encodedColDataList, encodingDictL = self.encode(maskedColDataList, integerEncoderList, \"integer\")\n return encodedColDataList, encodingDictL\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.runLengthEncoder","title":"runLengthEncoder(self, colDataList, minLen=40)
","text":"Encode an integer array as pairs of (value, number of repeats)
Parameters:
Name Type Description Default colDataList
list
list of integer data
required minLen
int
minimum list length to apply encoder. Defaults to 40.
40
Returns:
Type Description list
runlength encoded integer list
Source code in mmcif/io/BinaryCifWriter.py
def runLengthEncoder(self, colDataList, minLen=40):\n \"\"\"Encode an integer array as pairs of (value, number of repeats)\n\n Args:\n colDataList (list): list of integer data\n minLen (int, optional): minimum list length to apply encoder. Defaults to 40.\n\n Returns:\n list: runlength encoded integer list\n \"\"\"\n\n if len(colDataList) <= minLen:\n return colDataList, None\n byteArrayType = self.__getIntegerPackingType(colDataList)\n encodingD = {self.__toBytes(\"kind\"): self.__toBytes(\"RunLength\"), self.__toBytes(\"srcType\"): byteArrayType, self.__toBytes(\"srcSize\"): len(colDataList)}\n encodedColDataList = []\n val = None\n repeat = 1\n for colVal in colDataList:\n if colVal != val:\n if val is not None:\n encodedColDataList.extend((val, repeat))\n val = colVal\n repeat = 1\n else:\n repeat += 1\n encodedColDataList.extend((val, repeat))\n # Check for any gains and possibly retreat\n if len(encodedColDataList) > len(colDataList):\n return colDataList, None\n else:\n return encodedColDataList, encodingD\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.stringArrayMaskedEncoder","title":"stringArrayMaskedEncoder(self, colDataList, colMaskList)
","text":"Encode the input data column (string) along with the incompleteness mask.
Parameters:
Name Type Description Default colDataList
list
input data column (string)
required colMaskList
list
incompleteness mask
required Returns:
Type Description (list, list)
encoded data column, list of encoding instructions
Source code in mmcif/io/BinaryCifWriter.py
def stringArrayMaskedEncoder(self, colDataList, colMaskList):\n \"\"\"Encode the input data column (string) along with the incompleteness mask.\n\n Args:\n colDataList (list): input data column (string)\n colMaskList (list): incompleteness mask\n\n Returns:\n (list, list): encoded data column, list of encoding instructions\n \"\"\"\n integerEncoderList = [\"Delta\", \"RunLength\", \"ByteArray\"]\n uniqStringIndex = {} # keys are substrings, values indices\n uniqStringList = []\n indexList = []\n for i, strVal in enumerate(colDataList):\n if colMaskList is not None and colMaskList[i]:\n indexList.append(-1)\n else:\n tS = strVal\n tS = str(tS)\n if tS not in uniqStringIndex:\n uniqStringIndex[tS] = len(uniqStringIndex)\n uniqStringList.append(tS)\n indexList.append(uniqStringIndex[tS])\n offsetList = [0]\n runningLen = 0\n for tS in uniqStringList:\n runningLen += len(tS)\n offsetList.append(runningLen)\n\n encodedOffsetList, offsetEncodingDictL = self.encode(offsetList, integerEncoderList, \"integer\")\n encodedIndexList, indexEncodingDictL = self.encode(indexList, integerEncoderList, \"integer\")\n\n encodingDict = {\n self.__toBytes(\"kind\"): self.__toBytes(\"StringArray\"),\n self.__toBytes(\"dataEncoding\"): indexEncodingDictL,\n self.__toBytes(\"stringData\"): self.__toBytes(\"\".join(uniqStringList)),\n self.__toBytes(\"offsetEncoding\"): offsetEncodingDictL,\n self.__toBytes(\"offsets\"): encodedOffsetList,\n }\n return encodedIndexList, [encodingDict]\n
"},{"location":"api_reference/CifFile/","title":"CifFile","text":"CifFile
New method prototype --
CifFile* ParseCifSimple(const std::string& fileName, const bool verbose = false, const unsigned int intCaseSense = 0, const unsigned int maxLineLength = CifFile::STD_CIF_LINE_LENGTH, const std::string& nullValue = CifString::UnknownValue, const std::string& parseLogFileName = std::string());
Source code in mmcif/io/CifFile.py
class CifFile(object):\n \"\"\"\n CifFile\n\n New method prototype --\n\n CifFile* ParseCifSimple(const std::string& fileName,\n const bool verbose = false,\n const unsigned int intCaseSense = 0,\n const unsigned int maxLineLength = CifFile::STD_CIF_LINE_LENGTH,\n const std::string& nullValue = CifString::UnknownValue,\n const std::string& parseLogFileName = std::string());\n\n \"\"\"\n\n def __init__(self, fileName, parseLogFileName=None):\n self.__fileName = fileName\n\n if parseLogFileName is None:\n self.__cifFile = ParseCifSimple(self.__fileName, False, 0, 255, \"?\", \"\")\n else:\n self.__cifFile = ParseCifSimple(self.__fileName, False, 0, 255, \"?\", parseLogFileName)\n\n def getCifFile(self):\n return self.__cifFile\n\n @classmethod\n def getFileExt(cls):\n return \"cif\"\n\n def write(self, fileName):\n self.__cifFile.Write(fileName)\n\n @classmethod\n def read(cls, fileName):\n return cls(fileName)\n
"},{"location":"api_reference/DataCategory/","title":"DataCategory","text":"Methods for creating, accessing, and formatting PDBx/mmCif data categories.
Source code in mmcif/api/DataCategory.py
class DataCategory(DataCategoryBase):\n \"\"\"Methods for creating, accessing, and formatting PDBx/mmCif data categories.\"\"\"\n\n def __init__(self, name, attributeNameList=None, rowList=None, raiseExceptions=True, copyInputData=True):\n \"\"\"Summary\n\n Args:\n name (str): Category name\n attributeNameList (None, optional): Initial attribute names\n rowList (None, optional): Initial category data organized in rows corresponding to the attribute name list\n raiseExceptions (bool, optional): Flag to control if expections are raised or handled internally\n copyInputData (bool, optional): Copy rather than reference input data\n \"\"\"\n super(DataCategory, self).__init__(name, attributeNameList, rowList, raiseExceptions=raiseExceptions, copyInputData=copyInputData)\n #\n self.__verbose = False\n self._currentRowIndex = 0\n self.__currentAttribute = None\n #\n\n def setVerboseMode(self, boolVal):\n self.__verbose = boolVal\n\n def getCurrentAttribute(self):\n return self.__currentAttribute\n\n def getRowIndex(self):\n return self._currentRowIndex\n\n def getFullRow(self, index):\n \"\"\"Return a full row based on the length of the the attribute list or a row initialized with missing values\"\"\"\n try:\n if len(self.data[index]) < self._numAttributes:\n for _ in range(self._numAttributes - len(self.data[index])):\n self.data[index].append(\"?\")\n return self.data[index]\n except Exception as e:\n logger.debug(\"Returning an empty row at %d (%s)\", index, str(e))\n return [\"?\" for ii in range(self._numAttributes)]\n\n def getAttributeListWithOrder(self):\n oL = []\n for ii, att in enumerate(self._attributeNameList):\n oL.append((att, ii))\n return oL\n\n def appendAttributeExtendRows(self, attributeName, defaultValue=\"?\"):\n attributeNameLC = attributeName.lower()\n if attributeNameLC in self._catalog:\n i = self._attributeNameList.index(self._catalog[attributeNameLC])\n self._attributeNameList[i] = attributeName\n self._catalog[attributeNameLC] = attributeName\n logger.info(\"Appending existing attribute %s\", attributeName)\n else:\n self._attributeNameList.append(attributeName)\n self._catalog[attributeNameLC] = attributeName\n # add a placeholder to any existing rows for the new attribute.\n if self.data:\n for row in self.data:\n row.append(defaultValue)\n #\n self._numAttributes = len(self._attributeNameList)\n return self._numAttributes\n\n def getValue(self, attributeName=None, rowIndex=None):\n if attributeName is None:\n attribute = self.__currentAttribute\n else:\n attribute = attributeName\n if rowIndex is None:\n rowI = self._currentRowIndex\n else:\n rowI = rowIndex\n\n if isinstance(attribute, self._stringTypes) and isinstance(rowI, int):\n try:\n return self.data[rowI][self._attributeNameList.index(attribute)]\n except IndexError:\n if self._raiseExceptions:\n raise IndexError\n if self._raiseExceptions:\n raise IndexError(attribute)\n else:\n return None\n\n def getValueOrDefault(self, attributeName=None, rowIndex=None, defaultValue=\"\"):\n \"\"\"Within the current category return the value of input attribute in the input rowIndex [0-based].\n\n On error or if the value missing or null return the default value. Empty values returned as is.\n\n Exceptions on for unknown attributeNames and out-of-range indices.\n \"\"\"\n if attributeName is None:\n attribute = self.__currentAttribute\n else:\n attribute = attributeName\n if rowIndex is None:\n rowI = self._currentRowIndex\n else:\n rowI = rowIndex\n\n if isinstance(attribute, self._stringTypes) and isinstance(rowI, int):\n try:\n tV = self.data[rowI][self._attributeNameList.index(attribute)]\n if (tV is None) or (tV in [\".\", \"?\"]):\n return defaultValue\n else:\n return tV\n except Exception as e:\n logger.debug(\"Failing attributeName %s rowIndex %r defaultValue %r with %s\", attributeName, rowIndex, defaultValue, str(e))\n # if self._raiseExceptions:\n # raise e\n # Returning default -- no exception\n else:\n if self._raiseExceptions:\n raise ValueError\n #\n return defaultValue\n\n def getFirstValueOrDefault(self, attributeNameList, rowIndex=0, defaultValue=\"\"):\n \"\"\"Return the value from the first non-null attribute found in the input attribute list\n from the row (rowIndex) in the current category object.\n \"\"\"\n try:\n for at in attributeNameList:\n if self.hasAttribute(at):\n tV = self.getValue(at, rowIndex)\n if (tV is None) or (tV in [\"\", \".\", \"?\"]):\n continue\n else:\n return tV\n except Exception as e:\n logger.debug(\"Failing with %s\", str(e))\n # if self._raiseExceptions:\n # raise e\n return defaultValue\n\n def setValue(self, value, attributeName=None, rowIndex=None):\n \"\"\"Set the value of an existing attribute. rowIndex values >=0, where\n the category will be extended in length as needed.\n \"\"\"\n if attributeName is None:\n attribute = self.__currentAttribute\n else:\n attribute = attributeName\n\n if rowIndex is None:\n rowI = self._currentRowIndex\n else:\n rowI = rowIndex\n\n if isinstance(attribute, self._stringTypes) and isinstance(rowI, int) and (rowI >= 0):\n try:\n ind = -2\n # if row index is out of range - add the rows -\n for ii in range(rowI + 1 - len(self.data)):\n self.data.append(self.__emptyRow())\n # self.data[rowI][attribute]=value\n ll = len(self.data[rowI])\n ind = self._attributeNameList.index(attribute)\n\n # extend the list if needed -\n if ind >= ll:\n self.data[rowI].extend([None for ii in range(ind - (ll - 1))])\n\n self.data[rowI][ind] = value\n return True\n except IndexError:\n if self.__verbose:\n logger.exception(\n \"DataCategory(setvalue) index error category %s attribute %s row index %d col %d rowlen %d value %r\",\n self._name,\n attribute,\n rowI,\n ind,\n len(self.data[rowI]),\n value,\n )\n logger.debug(\"DataCategory(setvalue) attribute %r length attribute list %d\", attribute, len(self._attributeNameList))\n for ii, aV in enumerate(self._attributeNameList):\n logger.debug(\"DataCategory(setvalue) %d attributeName %r\", ii, aV)\n if self._raiseExceptions:\n raise IndexError\n except ValueError:\n if self.__verbose:\n logger.exception(\"DataCategory(setvalue) value error category %s attribute %s row index %d value %r\", self._name, attribute, rowI, value)\n if self._raiseExceptions:\n raise ValueError\n else:\n if self._raiseExceptions:\n raise ValueError\n return False\n\n def __emptyRow(self):\n return [None for ii in range(len(self._attributeNameList))]\n\n def replaceValue(self, oldValue, newValue, attributeName):\n try:\n numReplace = 0\n if attributeName not in self._attributeNameList:\n return numReplace\n ind = self._attributeNameList.index(attributeName)\n for row in self.data:\n if row[ind] == oldValue:\n row[ind] = newValue\n numReplace += 1\n return numReplace\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return numReplace\n\n def replaceSubstring(self, oldValue, newValue, attributeName):\n try:\n numReplace = 0\n if attributeName not in self._attributeNameList:\n return numReplace\n ind = self._attributeNameList.index(attributeName)\n for row in self.data:\n val = row[ind]\n row[ind] = val.replace(oldValue, newValue)\n if val != row[ind]:\n numReplace += 1\n return numReplace\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return numReplace\n\n def selectIndices(self, attributeValue, attributeName):\n try:\n rL = []\n if attributeName not in self._attributeNameList:\n return rL\n ind = self._attributeNameList.index(attributeName)\n for ii, row in enumerate(self.data):\n if attributeValue == row[ind]:\n rL.append(ii)\n return rL\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return rL\n\n def selectIndicesFromList(self, attributeValueList, attributeNameList):\n rL = []\n try:\n indList = []\n for at in attributeNameList:\n indList.append(self._attributeNameList.index(at))\n indValList = list(zip(indList, attributeValueList))\n #\n numList = len(indValList)\n for ii, row in enumerate(self.data):\n nMatch = 0\n for ind, tVal in indValList:\n if tVal == row[ind]:\n nMatch += 1\n if nMatch == numList:\n rL.append(ii)\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection/index failure for values %r\", attributeValueList)\n if self._raiseExceptions:\n raise e\n\n return rL\n\n def selectValuesWhere(self, attributeName, attributeValueWhere, attributeNameWhere, returnCount=0):\n rL = []\n try:\n iCount = 0\n ind = self._attributeNameList.index(attributeName)\n indWhere = self._attributeNameList.index(attributeNameWhere)\n for row in self.data:\n if attributeValueWhere == row[indWhere]:\n rL.append(row[ind])\n iCount += 1\n if returnCount and (iCount >= returnCount):\n break\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return rL\n\n def selectValueListWhere(self, attributeNameList, attributeValueWhere, attributeNameWhere, returnCount=0):\n \"\"\"Return a list of lists containing the values of input attributeNameList\n satisfying the attribute value where condition.\n \"\"\"\n rL = []\n try:\n iCount = 0\n indList = []\n for at in attributeNameList:\n indList.append(self._attributeNameList.index(at))\n indWhere = self._attributeNameList.index(attributeNameWhere)\n for row in self.data:\n if attributeValueWhere == row[indWhere]:\n rL.append([row[jj] for jj in indList])\n iCount += 1\n if returnCount and (iCount >= returnCount):\n break\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return rL\n\n def selectValuesWhereConditions(self, attributeName, conditionsD, returnCount=0):\n rL = []\n try:\n iCount = 0\n ind = self._attributeNameList.index(attributeName)\n idxD = {k: self._attributeNameList.index(k) for k, v in conditionsD.items()}\n #\n #\n for row in self.data:\n ok = True\n for k, v in conditionsD.items():\n ok = (v == row[idxD[k]]) and ok\n if ok:\n rL.append(row[ind])\n iCount += 1\n if returnCount and (iCount >= returnCount):\n break\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return rL\n\n def countValuesWhereConditions(self, conditionsD):\n \"\"\"Count row instances subject to input equivalence conditions\n\n Args:\n conditionsD (dict): {'atName': value, ....}\n\n Raises:\n e: any failure\n\n Returns:\n int: count of instances satisfying input conditions\n \"\"\"\n try:\n iCount = 0\n idxD = {k: self._attributeNameList.index(k) for k, v in conditionsD.items()}\n #\n for row in self.data:\n ok = True\n for k, v in conditionsD.items():\n ok = (v == row[idxD[k]]) and ok\n if ok:\n iCount += 1\n\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return iCount\n\n def countValuesWhereOpConditions(self, conditionTupleList):\n \"\"\"Count row instances subject to input condition list\n\n Args:\n conditionTupleList (list): (attributeName, op, value) where (op = 'eq', 'gt(int)', 'lt(int)', 'in', 'ne', 'not in')\n\n Raises:\n e: any failure\n\n Returns:\n int: count of instances satisfying input conditions\n \"\"\"\n try:\n iCount = 0\n idxD = {atName: self._attributeNameList.index(atName) for (atName, op, value) in conditionTupleList}\n #\n for row in self.data:\n ok = True\n for (atName, op, v) in conditionTupleList:\n if op == \"eq\":\n ok = (v == row[idxD[atName]]) and ok\n elif op == \"ne\":\n ok = (v != row[idxD[atName]]) and ok\n elif op == \"lt(int)\":\n ok = (int(row[idxD[atName]]) < v) and ok\n elif op == \"gt(int)\":\n ok = (int(row[idxD[atName]]) > v) and ok\n elif op == \"in\":\n ok = (row[idxD[atName]] in v) and ok\n elif op == \"not in\":\n ok = (row[idxD[atName]] not in v) and ok\n if ok:\n iCount += 1\n\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return iCount\n\n #\n def getCombinationCounts(self, attributeList):\n \"\"\"Count the value occurrences of the input attributeList in the category.\n\n Args:\n attributeList (list): target list of attribute names\n\n Returns:\n\n cD[(attribute value, ... )] = count\n\n \"\"\"\n cD = {}\n try:\n idxL = [self._attributeNameList.index(atName) for atName in attributeList]\n #\n for row in self.data:\n ky = tuple([row[jj] for jj in idxL])\n cD[ky] = cD[ky] + 1 if ky in cD else 1\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return cD\n\n def getCombinationCountsWithConditions(self, attributeList, conditionTupleList):\n \"\"\"Count the value occurrences of the input attributeList in the category.\n\n Args:\n attributeList (list): target list of attribute names\n conditionTupleList (list): (attributeName, op, value) where (op = 'eq', 'gt(int)', 'lt(int)', 'in', 'ne', 'not in')\n\n Returns:\n\n cD[(attribute value, ... )] = count\n \"\"\"\n cD = {}\n try:\n idxL = [self._attributeNameList.index(atName) for atName in attributeList]\n idxD = {atName: self._attributeNameList.index(atName) for (atName, op, value) in conditionTupleList}\n #\n for row in self.data:\n ok = True\n for (atName, op, v) in conditionTupleList:\n if op == \"eq\":\n ok = (v == row[idxD[atName]]) and ok\n elif op == \"ne\":\n ok = (v != row[idxD[atName]]) and ok\n elif op == \"lt(int)\":\n ok = (int(row[idxD[atName]]) < v) and ok\n elif op == \"gt(int)\":\n ok = (int(row[idxD[atName]]) > v) and ok\n elif op == \"in\":\n ok = (row[idxD[atName]] in v) and ok\n elif op == \"not in\":\n ok = (row[idxD[atName]] not in v) and ok\n if ok:\n ky = tuple([row[jj] for jj in idxL])\n cD[ky] = cD[ky] + 1 if ky in cD else 1\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return cD\n\n def invokeAttributeMethod(self, attributeName, mType, method, db):\n _ = mType\n _ = db\n self._currentRowIndex = 0\n self.__currentAttribute = attributeName\n self.appendAttribute(attributeName)\n currentRowIndex = self._currentRowIndex # pylint: disable=possibly-unused-variable\n #\n ind = self._attributeNameList.index(attributeName)\n if not self.data:\n row = [None for ii in range(len(self._attributeNameList) * 2)]\n row[ind] = None\n self.data.append(row)\n\n for row in self.data:\n ll = len(row)\n if ind >= ll:\n row.extend([None for ii in range(2 * ind - ll)])\n row[ind] = None\n exec(method.getInline(), globals(), locals()) # pylint: disable=exec-used\n self._currentRowIndex += 1\n currentRowIndex = self._currentRowIndex\n\n def invokeCategoryMethod(self, mType, method, db):\n _ = mType\n _ = db\n self._currentRowIndex = 0\n exec(method.getInline(), globals(), locals()) # pylint: disable=exec-used\n\n def printIt(self, fh=sys.stdout):\n fh.write(\"--------------------------------------------\\n\")\n fh.write(\" Category: %s attribute list length: %d\\n\" % (self._name, len(self._attributeNameList)))\n for at in self._attributeNameList:\n fh.write(\" Category: %s attribute: %s\\n\" % (self._name, at))\n\n fh.write(\" Row value list length: %d\\n\" % len(self.data))\n #\n for row in self.data[:2]:\n #\n if len(row) == len(self._attributeNameList):\n for ii, v in enumerate(row):\n fh.write(\" %30s: %s ...\\n\" % (self._attributeNameList[ii], str(v)[:30]))\n else:\n fh.write(\"+WARNING - %s data length %d attribute name length %s mismatched\\n\" % (self._name, len(row), len(self._attributeNameList)))\n\n def dumpIt(self, fh=sys.stdout):\n fh.write(\"--------------------------------------------\\n\")\n fh.write(\" Category: %s attribute list length: %d\\n\" % (self._name, len(self._attributeNameList)))\n for at in self._attributeNameList:\n fh.write(\" Category: %s attribute: %s\\n\" % (self._name, at))\n\n fh.write(\" Value list length: %d\\n\" % len(self.data))\n for jj, row in enumerate(self.data):\n for ii, v in enumerate(row):\n fh.write(\"%4d %30s: %s\\n\" % (jj, self._attributeNameList[ii], v))\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.__init__","title":"__init__(self, name, attributeNameList=None, rowList=None, raiseExceptions=True, copyInputData=True)
special
","text":"Summary
Parameters:
Name Type Description Default name
str
Category name
required attributeNameList
None
Initial attribute names
None
rowList
None
Initial category data organized in rows corresponding to the attribute name list
None
raiseExceptions
bool
Flag to control if expections are raised or handled internally
True
copyInputData
bool
Copy rather than reference input data
True
Source code in mmcif/api/DataCategory.py
def __init__(self, name, attributeNameList=None, rowList=None, raiseExceptions=True, copyInputData=True):\n \"\"\"Summary\n\n Args:\n name (str): Category name\n attributeNameList (None, optional): Initial attribute names\n rowList (None, optional): Initial category data organized in rows corresponding to the attribute name list\n raiseExceptions (bool, optional): Flag to control if expections are raised or handled internally\n copyInputData (bool, optional): Copy rather than reference input data\n \"\"\"\n super(DataCategory, self).__init__(name, attributeNameList, rowList, raiseExceptions=raiseExceptions, copyInputData=copyInputData)\n #\n self.__verbose = False\n self._currentRowIndex = 0\n self.__currentAttribute = None\n #\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.countValuesWhereConditions","title":"countValuesWhereConditions(self, conditionsD)
","text":"Count row instances subject to input equivalence conditions
Parameters:
Name Type Description Default conditionsD
dict
{'atName': value, ....}
required Exceptions:
Type Description e
any failure
Returns:
Type Description int
count of instances satisfying input conditions
Source code in mmcif/api/DataCategory.py
def countValuesWhereConditions(self, conditionsD):\n \"\"\"Count row instances subject to input equivalence conditions\n\n Args:\n conditionsD (dict): {'atName': value, ....}\n\n Raises:\n e: any failure\n\n Returns:\n int: count of instances satisfying input conditions\n \"\"\"\n try:\n iCount = 0\n idxD = {k: self._attributeNameList.index(k) for k, v in conditionsD.items()}\n #\n for row in self.data:\n ok = True\n for k, v in conditionsD.items():\n ok = (v == row[idxD[k]]) and ok\n if ok:\n iCount += 1\n\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return iCount\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.countValuesWhereOpConditions","title":"countValuesWhereOpConditions(self, conditionTupleList)
","text":"Count row instances subject to input condition list
Parameters:
Name Type Description Default conditionTupleList
list
(attributeName, op, value) where (op = 'eq', 'gt(int)', 'lt(int)', 'in', 'ne', 'not in')
required Exceptions:
Type Description e
any failure
Returns:
Type Description int
count of instances satisfying input conditions
Source code in mmcif/api/DataCategory.py
def countValuesWhereOpConditions(self, conditionTupleList):\n \"\"\"Count row instances subject to input condition list\n\n Args:\n conditionTupleList (list): (attributeName, op, value) where (op = 'eq', 'gt(int)', 'lt(int)', 'in', 'ne', 'not in')\n\n Raises:\n e: any failure\n\n Returns:\n int: count of instances satisfying input conditions\n \"\"\"\n try:\n iCount = 0\n idxD = {atName: self._attributeNameList.index(atName) for (atName, op, value) in conditionTupleList}\n #\n for row in self.data:\n ok = True\n for (atName, op, v) in conditionTupleList:\n if op == \"eq\":\n ok = (v == row[idxD[atName]]) and ok\n elif op == \"ne\":\n ok = (v != row[idxD[atName]]) and ok\n elif op == \"lt(int)\":\n ok = (int(row[idxD[atName]]) < v) and ok\n elif op == \"gt(int)\":\n ok = (int(row[idxD[atName]]) > v) and ok\n elif op == \"in\":\n ok = (row[idxD[atName]] in v) and ok\n elif op == \"not in\":\n ok = (row[idxD[atName]] not in v) and ok\n if ok:\n iCount += 1\n\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return iCount\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.getCombinationCounts","title":"getCombinationCounts(self, attributeList)
","text":"Count the value occurrences of the input attributeList in the category.
Parameters:
Name Type Description Default attributeList
list
target list of attribute names
required Returns:
Type Description cD[(attribute value, ... )] = count
Source code in mmcif/api/DataCategory.py
def getCombinationCounts(self, attributeList):\n \"\"\"Count the value occurrences of the input attributeList in the category.\n\n Args:\n attributeList (list): target list of attribute names\n\n Returns:\n\n cD[(attribute value, ... )] = count\n\n \"\"\"\n cD = {}\n try:\n idxL = [self._attributeNameList.index(atName) for atName in attributeList]\n #\n for row in self.data:\n ky = tuple([row[jj] for jj in idxL])\n cD[ky] = cD[ky] + 1 if ky in cD else 1\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return cD\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.getCombinationCountsWithConditions","title":"getCombinationCountsWithConditions(self, attributeList, conditionTupleList)
","text":"Count the value occurrences of the input attributeList in the category.
Parameters:
Name Type Description Default attributeList
list
target list of attribute names
required conditionTupleList
list
(attributeName, op, value) where (op = 'eq', 'gt(int)', 'lt(int)', 'in', 'ne', 'not in')
required Returns:
Type Description cD[(attribute value, ... )] = count
Source code in mmcif/api/DataCategory.py
def getCombinationCountsWithConditions(self, attributeList, conditionTupleList):\n \"\"\"Count the value occurrences of the input attributeList in the category.\n\n Args:\n attributeList (list): target list of attribute names\n conditionTupleList (list): (attributeName, op, value) where (op = 'eq', 'gt(int)', 'lt(int)', 'in', 'ne', 'not in')\n\n Returns:\n\n cD[(attribute value, ... )] = count\n \"\"\"\n cD = {}\n try:\n idxL = [self._attributeNameList.index(atName) for atName in attributeList]\n idxD = {atName: self._attributeNameList.index(atName) for (atName, op, value) in conditionTupleList}\n #\n for row in self.data:\n ok = True\n for (atName, op, v) in conditionTupleList:\n if op == \"eq\":\n ok = (v == row[idxD[atName]]) and ok\n elif op == \"ne\":\n ok = (v != row[idxD[atName]]) and ok\n elif op == \"lt(int)\":\n ok = (int(row[idxD[atName]]) < v) and ok\n elif op == \"gt(int)\":\n ok = (int(row[idxD[atName]]) > v) and ok\n elif op == \"in\":\n ok = (row[idxD[atName]] in v) and ok\n elif op == \"not in\":\n ok = (row[idxD[atName]] not in v) and ok\n if ok:\n ky = tuple([row[jj] for jj in idxL])\n cD[ky] = cD[ky] + 1 if ky in cD else 1\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return cD\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.getFirstValueOrDefault","title":"getFirstValueOrDefault(self, attributeNameList, rowIndex=0, defaultValue='')
","text":"Return the value from the first non-null attribute found in the input attribute list from the row (rowIndex) in the current category object.
Source code in mmcif/api/DataCategory.py
def getFirstValueOrDefault(self, attributeNameList, rowIndex=0, defaultValue=\"\"):\n \"\"\"Return the value from the first non-null attribute found in the input attribute list\n from the row (rowIndex) in the current category object.\n \"\"\"\n try:\n for at in attributeNameList:\n if self.hasAttribute(at):\n tV = self.getValue(at, rowIndex)\n if (tV is None) or (tV in [\"\", \".\", \"?\"]):\n continue\n else:\n return tV\n except Exception as e:\n logger.debug(\"Failing with %s\", str(e))\n # if self._raiseExceptions:\n # raise e\n return defaultValue\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.getFullRow","title":"getFullRow(self, index)
","text":"Return a full row based on the length of the the attribute list or a row initialized with missing values
Source code in mmcif/api/DataCategory.py
def getFullRow(self, index):\n \"\"\"Return a full row based on the length of the the attribute list or a row initialized with missing values\"\"\"\n try:\n if len(self.data[index]) < self._numAttributes:\n for _ in range(self._numAttributes - len(self.data[index])):\n self.data[index].append(\"?\")\n return self.data[index]\n except Exception as e:\n logger.debug(\"Returning an empty row at %d (%s)\", index, str(e))\n return [\"?\" for ii in range(self._numAttributes)]\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.getValueOrDefault","title":"getValueOrDefault(self, attributeName=None, rowIndex=None, defaultValue='')
","text":"Within the current category return the value of input attribute in the input rowIndex [0-based].
On error or if the value missing or null return the default value. Empty values returned as is.
Exceptions on for unknown attributeNames and out-of-range indices.
Source code in mmcif/api/DataCategory.py
def getValueOrDefault(self, attributeName=None, rowIndex=None, defaultValue=\"\"):\n \"\"\"Within the current category return the value of input attribute in the input rowIndex [0-based].\n\n On error or if the value missing or null return the default value. Empty values returned as is.\n\n Exceptions on for unknown attributeNames and out-of-range indices.\n \"\"\"\n if attributeName is None:\n attribute = self.__currentAttribute\n else:\n attribute = attributeName\n if rowIndex is None:\n rowI = self._currentRowIndex\n else:\n rowI = rowIndex\n\n if isinstance(attribute, self._stringTypes) and isinstance(rowI, int):\n try:\n tV = self.data[rowI][self._attributeNameList.index(attribute)]\n if (tV is None) or (tV in [\".\", \"?\"]):\n return defaultValue\n else:\n return tV\n except Exception as e:\n logger.debug(\"Failing attributeName %s rowIndex %r defaultValue %r with %s\", attributeName, rowIndex, defaultValue, str(e))\n # if self._raiseExceptions:\n # raise e\n # Returning default -- no exception\n else:\n if self._raiseExceptions:\n raise ValueError\n #\n return defaultValue\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.selectValueListWhere","title":"selectValueListWhere(self, attributeNameList, attributeValueWhere, attributeNameWhere, returnCount=0)
","text":"Return a list of lists containing the values of input attributeNameList satisfying the attribute value where condition.
Source code in mmcif/api/DataCategory.py
def selectValueListWhere(self, attributeNameList, attributeValueWhere, attributeNameWhere, returnCount=0):\n \"\"\"Return a list of lists containing the values of input attributeNameList\n satisfying the attribute value where condition.\n \"\"\"\n rL = []\n try:\n iCount = 0\n indList = []\n for at in attributeNameList:\n indList.append(self._attributeNameList.index(at))\n indWhere = self._attributeNameList.index(attributeNameWhere)\n for row in self.data:\n if attributeValueWhere == row[indWhere]:\n rL.append([row[jj] for jj in indList])\n iCount += 1\n if returnCount and (iCount >= returnCount):\n break\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return rL\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.setValue","title":"setValue(self, value, attributeName=None, rowIndex=None)
","text":"Set the value of an existing attribute. rowIndex values >=0, where the category will be extended in length as needed.
Source code in mmcif/api/DataCategory.py
def setValue(self, value, attributeName=None, rowIndex=None):\n \"\"\"Set the value of an existing attribute. rowIndex values >=0, where\n the category will be extended in length as needed.\n \"\"\"\n if attributeName is None:\n attribute = self.__currentAttribute\n else:\n attribute = attributeName\n\n if rowIndex is None:\n rowI = self._currentRowIndex\n else:\n rowI = rowIndex\n\n if isinstance(attribute, self._stringTypes) and isinstance(rowI, int) and (rowI >= 0):\n try:\n ind = -2\n # if row index is out of range - add the rows -\n for ii in range(rowI + 1 - len(self.data)):\n self.data.append(self.__emptyRow())\n # self.data[rowI][attribute]=value\n ll = len(self.data[rowI])\n ind = self._attributeNameList.index(attribute)\n\n # extend the list if needed -\n if ind >= ll:\n self.data[rowI].extend([None for ii in range(ind - (ll - 1))])\n\n self.data[rowI][ind] = value\n return True\n except IndexError:\n if self.__verbose:\n logger.exception(\n \"DataCategory(setvalue) index error category %s attribute %s row index %d col %d rowlen %d value %r\",\n self._name,\n attribute,\n rowI,\n ind,\n len(self.data[rowI]),\n value,\n )\n logger.debug(\"DataCategory(setvalue) attribute %r length attribute list %d\", attribute, len(self._attributeNameList))\n for ii, aV in enumerate(self._attributeNameList):\n logger.debug(\"DataCategory(setvalue) %d attributeName %r\", ii, aV)\n if self._raiseExceptions:\n raise IndexError\n except ValueError:\n if self.__verbose:\n logger.exception(\"DataCategory(setvalue) value error category %s attribute %s row index %d value %r\", self._name, attribute, rowI, value)\n if self._raiseExceptions:\n raise ValueError\n else:\n if self._raiseExceptions:\n raise ValueError\n return False\n
"},{"location":"api_reference/DataCategoryBase/","title":"DataCategoryBase","text":"Base object definition for a data category -
This class subclasses UserList and implements many list-like features for row data managed by this class.
Source code in mmcif/api/DataCategoryBase.py
class DataCategoryBase(UserList):\n\n \"\"\"Base object definition for a data category -\n\n This class subclasses UserList and implements many list-like features for\n row data managed by this class.\n\n \"\"\"\n\n def __init__(self, name, attributeNameList=None, rowList=None, raiseExceptions=True, copyInputData=True):\n self._name = name\n if copyInputData:\n self._attributeNameList = copy.deepcopy(attributeNameList) if attributeNameList is not None else []\n # self.data = copy.deepcopy(rowList) if rowList is not None else []\n else:\n self._attributeNameList = attributeNameList if attributeNameList is not None else []\n # self.data = rowList if rowList is not None else []\n #\n # -------\n if rowList is None or (isinstance(rowList, list) and not rowList):\n self.data = []\n elif isinstance(rowList, list) and rowList:\n if isinstance(rowList[0], (list, tuple)):\n if copyInputData:\n self.data = copy.deepcopy(rowList) if rowList is not None else []\n else:\n self.data = rowList if rowList is not None else []\n\n elif isinstance(rowList[0], dict):\n rL = []\n for rowD in rowList:\n rL.append([rowD[k] if k in rowD else None for k in self._attributeNameList])\n if copyInputData:\n self.data = copy.deepcopy(rL)\n else:\n self.data = rL\n\n else:\n if raiseExceptions:\n raise ValueError\n else:\n logger.error(\"Initialization failure\")\n else:\n if raiseExceptions:\n raise ValueError\n else:\n logger.error(\"Initialization failure\")\n\n # -------\n #\n self._itemNameList = []\n self.__mappingType = \"DATA\"\n self._raiseExceptions = raiseExceptions\n self._copyInputData = copyInputData\n #\n super(DataCategoryBase, self).__init__(self.data)\n #\n # Derived class data -\n #\n self._catalog = {}\n self._numAttributes = 0\n #\n self._stringTypes = basestring\n self.__setup()\n\n def __setup(self):\n self._numAttributes = len(self._attributeNameList)\n self._catalog = {}\n for attributeName in self._attributeNameList:\n attributeNameLC = attributeName.lower()\n self._catalog[attributeNameLC] = attributeName\n self.__updateItemLabels()\n\n # Add append/extend methods to accept row lists and dictionaries -\n #\n\n def append(self, row):\n if isinstance(row, (list, tuple)):\n self.data.append(row)\n return True\n elif isinstance(row, dict):\n try:\n # -\n self.data.append([row[k] if k in row else None for k in self._attributeNameList])\n return False\n except Exception as e:\n if self._raiseExceptions:\n raise e\n else:\n logger.error(\"Row processing failing with %s\", str(e))\n else:\n if self._raiseExceptions:\n raise ValueError\n else:\n logger.error(\"Unsupported row type\")\n return False\n\n def extend(self, rowList):\n if isinstance(rowList, list) and rowList:\n if isinstance(rowList[0], (list, tuple)):\n if self._copyInputData:\n self.data.extend(copy.deepcopy(rowList))\n else:\n self.data.extend(rowList)\n return True\n elif isinstance(rowList[0], dict):\n rL = []\n for rowD in rowList:\n # -\n rL.append([rowD[k] if k in rowD else None for k in self._attributeNameList])\n if self._copyInputData:\n self.data.extend(copy.deepcopy(rL))\n else:\n self.data.extend(rL)\n return True\n else:\n if self._raiseExceptions:\n raise ValueError\n else:\n logger.error(\"unexpected row data type\")\n else:\n logger.error(\"unexpected input data type\")\n return False\n\n #\n # Setters/appenders\n #\n\n def setName(self, name):\n self._name = name\n\n def setRowList(self, rowList):\n if self._copyInputData:\n self.data = copy.deepcopy(rowList)\n else:\n self.data = rowList\n\n def setAttributeNameList(self, attributeNameList):\n if self._copyInputData:\n self._attributeNameList = copy.deepcopy(attributeNameList)\n else:\n self._attributeNameList = attributeNameList\n self.__setup()\n\n def appendAttribute(self, attributeName):\n attributeNameLC = attributeName.lower()\n if attributeNameLC in self._catalog:\n i = self._attributeNameList.index(self._catalog[attributeNameLC])\n self._attributeNameList[i] = attributeName\n self._catalog[attributeNameLC] = attributeName\n else:\n self._attributeNameList.append(attributeName)\n self._catalog[attributeNameLC] = attributeName\n #\n self._numAttributes = len(self._attributeNameList)\n return self._numAttributes\n\n def renameAttributes(self, mapDict):\n \"\"\"Rename attributes according to mapping information in the input mapping dictionary {oldName: newName}\"\"\"\n atL = []\n for atName in self._attributeNameList:\n atL.append(mapDict[atName] if atName in mapDict else atName)\n self._attributeNameList = atL\n self.__setup()\n return True\n\n ##\n # Getters\n ##\n def get(self):\n return (self._name, self._attributeNameList, self.data)\n\n def getName(self):\n return self._name\n\n def getAttributeList(self):\n return self._attributeNameList\n\n def getAttributeCount(self):\n return len(self._attributeNameList)\n\n def getAttributeIndex(self, attributeName):\n try:\n return self._attributeNameList.index(attributeName)\n except Exception as e:\n logger.debug(\"Fails for %s with %s\", attributeName, str(e))\n\n return -1\n\n def getAttributeIndexDict(self):\n rD = {}\n for ii, attributeName in enumerate(self._attributeNameList):\n rD[attributeName] = ii\n return rD\n\n def getIndex(self, attributeName):\n return self.getAttributeIndex(attributeName)\n\n def hasAttribute(self, attributeName):\n return attributeName in self._attributeNameList\n\n def getItemNameList(self):\n return self.__updateItemLabels()\n\n def getRowList(self):\n return self.data\n\n def getRowCount(self):\n return len(self.data)\n\n def getRow(self, index):\n try:\n return self.data[index]\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return []\n\n def getColumn(self, index):\n try:\n return [row[index] for row in self.data]\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return []\n\n def getRowAttributeDict(self, index):\n rD = {}\n try:\n for ii, v in enumerate(self.data[index]):\n rD[self._attributeNameList[ii]] = v\n return rD\n except Exception as e:\n if self._raiseExceptions:\n raise e\n\n return rD\n\n def getRowItemDict(self, index):\n rD = {}\n try:\n self.__updateItemLabels()\n for ii, v in enumerate(self.data[index]):\n rD[self._itemNameList[ii]] = v\n return rD\n except Exception as e:\n if self._raiseExceptions:\n raise e\n\n return rD\n\n def getAttributeValueList(self, attributeName):\n \"\"\"Return a list of attribute values.\"\"\"\n rL = []\n try:\n idx = self.getAttributeIndex(attributeName)\n rL = [row[idx] for row in self.data]\n return rL\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return rL\n\n def getAttributeUniqueValueList(self, attributeName):\n \"\"\"Return a sorted list of unique attribute values.\"\"\"\n rL = []\n try:\n rD = {}\n idx = self.getAttributeIndex(attributeName)\n rD = {row[idx]: True for row in self.data}\n return sorted(rD.keys())\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return rL\n\n def removeRow(self, index):\n try:\n del self.data[index]\n return True\n except Exception as e:\n if self._raiseExceptions:\n raise e\n\n return False\n\n def removeRows(self, indexList):\n try:\n iL = sorted(indexList, reverse=True)\n for i in iL:\n del self.data[i]\n return True\n except Exception as e:\n if self._raiseExceptions:\n raise e\n\n return False\n\n def removeDuplicateRows(self):\n \"\"\"Remove duplicate rows from the category\n\n Raises:\n e: any exception\n\n Returns:\n bool: True for success or False otherwise\n \"\"\"\n try:\n filteredL = []\n for row in self.data:\n if row not in filteredL:\n filteredL.append(row)\n self.data = filteredL\n return True\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return False\n\n def removeAttribute(self, attributeName):\n \"\"\"Remove the attribute from the attribute list along with any\n corresponding row data.\n \"\"\"\n idx = self.getAttributeIndex(attributeName)\n if idx != -1:\n try:\n del self._attributeNameList[idx]\n for row in self.data:\n try:\n del row[idx]\n except Exception:\n pass\n self.__setup()\n return True\n except Exception:\n return False\n\n ##\n ##\n ##\n def __updateItemLabels(self):\n \"\"\"Internal method to create mmCIF style item names for the current attribute\n list.\n \"\"\"\n self._itemNameList = []\n for atName in self._attributeNameList:\n self._itemNameList.append(\"_\" + str(self._name) + \".\" + atName)\n #\n return self._itemNameList\n\n def __alignLabels(self, row):\n \"\"\"Internal method which aligns the list of input attributes with row data.\n\n If there are fewer labels than data elements in a row, then placeholder labels\n are created (e.g. \"unlabeled_#\")\n\n \"\"\"\n if len(row) > len(self._attributeNameList):\n for i in range(len(self._attributeNameList), len(row) - 1):\n self._attributeNameList.insert(i, \"unlabeled_\" + str(i))\n if self.__mappingType == \"ITEM\":\n self.__updateItemLabels()\n\n def setMapping(self, mType):\n \"\"\"Controls the manner in which this class returns data when accessed by\n index or in the context of an iterator:\n\n DATA = list of row data elements as these were input. [default]\n\n ATTRIBUTE = row returned as a dictionary with attribute key\n\n ITEM = row returned as a dictionary with item key\n\n \"\"\"\n if mType in [\"DATA\", \"ATTRIBUTE\", \"ITEM\"]:\n self.__mappingType = mType\n return True\n else:\n return False\n\n def __str__(self):\n ans = \"name:%r\\nattrbuteList: %r\\nData: %r\\n\" % (self._name, self._attributeNameList, list(self.data))\n return ans\n\n def __repr__(self):\n return self.__class__.__name__ + \"(\" + str(self) + \")\"\n\n def __iter__(self):\n for dD in self.data:\n yield self.__applyMapping(dD)\n\n def __getitem__(self, idx):\n return self.__applyMapping(self.data[idx])\n\n def __setitem__(self, idx, value):\n dL = self.__extractMapping(value)\n self.data[idx] = dL\n\n def __applyMapping(self, dD):\n if self.__mappingType == \"DATA\":\n return dD\n elif self.__mappingType == \"ATTRIBUTE\":\n self.__alignLabels(dD)\n return dict(list(zip(self._attributeNameList, dD)))\n elif self.__mappingType == \"ITEM\":\n self.__alignLabels(dD)\n self.__updateItemLabels()\n return dict(list(zip(self._itemNameList, dD)))\n\n def __extractMapping(self, dD):\n try:\n if self.__mappingType == \"DATA\":\n return dD\n elif self.__mappingType == \"ATTRIBUTE\":\n rL = []\n for k, v in dD.items():\n rL.insert(self._attributeNameList.index(k), v)\n return rL\n elif self.__mappingType == \"ITEM\":\n rL = []\n for k, v in dD.items():\n rL.insert(self._itemNameList.index(k), v)\n return rL\n except Exception:\n if self._raiseExceptions:\n raise IndexError\n return None\n\n def cmpAttributeNames(self, dcObj):\n \"\"\"Compare the attributeNameList in current data category (dca) and input data category .\n\n Return: (current attributes not in dcObj), (attributes common to both), (attributes in dcObj not in current data category)\n \"\"\"\n sa = set(self.getAttributeList())\n sb = set(dcObj.getAttributeList())\n return tuple(sa - sb), tuple(sa & sb), tuple(sb - sa)\n\n def cmpAttributeValues(self, dcObj, ignoreOrder=True, **kwargs):\n \"\"\"Compare the values by attribute for current data category (dca) and input data category.\n The comparison is performed independently for the values of corresponding attributes.\n Length differences are treated inequality out of hand.\n\n Return: [(attributeName, values equal flag (bool)), (attributeName, values equal flag (bool), ...]\n \"\"\"\n rL = []\n try:\n _ = kwargs\n sa = set(self.getAttributeList())\n sb = set(dcObj.getAttributeList())\n atComList = list(sa & sb)\n #\n lenEq = self.getRowCount() == dcObj.getRowCount()\n for at in atComList:\n if lenEq:\n if ignoreOrder:\n same = sorted(self.getAttributeValueList(at)) == sorted(dcObj.getAttributeValueList(at))\n else:\n same = self.getAttributeValueList(at) == dcObj.getAttributeValueList(at)\n else:\n same = False\n rL.append((at, same))\n return rL\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return rL\n\n def __eq__(self, other):\n \"\"\"Override the default Equals behavior\"\"\"\n if isinstance(other, self.__class__):\n return self.__dict__ == other.__dict__\n return NotImplemented\n\n def __ne__(self, other):\n \"\"\"Define a non-equality test\"\"\"\n if isinstance(other, self.__class__):\n return not self.__eq__(other)\n return NotImplemented\n\n def __hash__(self):\n \"\"\"Override the default hash behavior (that returns the id or the object)\"\"\"\n # return hash(tuple(sorted(self.__dict__.items())))\n return hash((self._name, tuple(self._attributeNameList), tuple(tuple(x) for x in self.data)))\n\n #\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.__eq__","title":"__eq__(self, other)
special
","text":"Override the default Equals behavior
Source code in mmcif/api/DataCategoryBase.py
def __eq__(self, other):\n \"\"\"Override the default Equals behavior\"\"\"\n if isinstance(other, self.__class__):\n return self.__dict__ == other.__dict__\n return NotImplemented\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.__hash__","title":"__hash__(self)
special
","text":"Override the default hash behavior (that returns the id or the object)
Source code in mmcif/api/DataCategoryBase.py
def __hash__(self):\n \"\"\"Override the default hash behavior (that returns the id or the object)\"\"\"\n # return hash(tuple(sorted(self.__dict__.items())))\n return hash((self._name, tuple(self._attributeNameList), tuple(tuple(x) for x in self.data)))\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.__ne__","title":"__ne__(self, other)
special
","text":"Define a non-equality test
Source code in mmcif/api/DataCategoryBase.py
def __ne__(self, other):\n \"\"\"Define a non-equality test\"\"\"\n if isinstance(other, self.__class__):\n return not self.__eq__(other)\n return NotImplemented\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.append","title":"append(self, row)
","text":"S.append(value) -- append value to the end of the sequence
Source code in mmcif/api/DataCategoryBase.py
def append(self, row):\n if isinstance(row, (list, tuple)):\n self.data.append(row)\n return True\n elif isinstance(row, dict):\n try:\n # -\n self.data.append([row[k] if k in row else None for k in self._attributeNameList])\n return False\n except Exception as e:\n if self._raiseExceptions:\n raise e\n else:\n logger.error(\"Row processing failing with %s\", str(e))\n else:\n if self._raiseExceptions:\n raise ValueError\n else:\n logger.error(\"Unsupported row type\")\n return False\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.cmpAttributeNames","title":"cmpAttributeNames(self, dcObj)
","text":"Compare the attributeNameList in current data category (dca) and input data category .
Return: (current attributes not in dcObj), (attributes common to both), (attributes in dcObj not in current data category)
Source code in mmcif/api/DataCategoryBase.py
def cmpAttributeNames(self, dcObj):\n \"\"\"Compare the attributeNameList in current data category (dca) and input data category .\n\n Return: (current attributes not in dcObj), (attributes common to both), (attributes in dcObj not in current data category)\n \"\"\"\n sa = set(self.getAttributeList())\n sb = set(dcObj.getAttributeList())\n return tuple(sa - sb), tuple(sa & sb), tuple(sb - sa)\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.cmpAttributeValues","title":"cmpAttributeValues(self, dcObj, ignoreOrder=True, **kwargs)
","text":"Compare the values by attribute for current data category (dca) and input data category. The comparison is performed independently for the values of corresponding attributes. Length differences are treated inequality out of hand.
Return: [(attributeName, values equal flag (bool)), (attributeName, values equal flag (bool), ...]
Source code in mmcif/api/DataCategoryBase.py
def cmpAttributeValues(self, dcObj, ignoreOrder=True, **kwargs):\n \"\"\"Compare the values by attribute for current data category (dca) and input data category.\n The comparison is performed independently for the values of corresponding attributes.\n Length differences are treated inequality out of hand.\n\n Return: [(attributeName, values equal flag (bool)), (attributeName, values equal flag (bool), ...]\n \"\"\"\n rL = []\n try:\n _ = kwargs\n sa = set(self.getAttributeList())\n sb = set(dcObj.getAttributeList())\n atComList = list(sa & sb)\n #\n lenEq = self.getRowCount() == dcObj.getRowCount()\n for at in atComList:\n if lenEq:\n if ignoreOrder:\n same = sorted(self.getAttributeValueList(at)) == sorted(dcObj.getAttributeValueList(at))\n else:\n same = self.getAttributeValueList(at) == dcObj.getAttributeValueList(at)\n else:\n same = False\n rL.append((at, same))\n return rL\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return rL\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.extend","title":"extend(self, rowList)
","text":"S.extend(iterable) -- extend sequence by appending elements from the iterable
Source code in mmcif/api/DataCategoryBase.py
def extend(self, rowList):\n if isinstance(rowList, list) and rowList:\n if isinstance(rowList[0], (list, tuple)):\n if self._copyInputData:\n self.data.extend(copy.deepcopy(rowList))\n else:\n self.data.extend(rowList)\n return True\n elif isinstance(rowList[0], dict):\n rL = []\n for rowD in rowList:\n # -\n rL.append([rowD[k] if k in rowD else None for k in self._attributeNameList])\n if self._copyInputData:\n self.data.extend(copy.deepcopy(rL))\n else:\n self.data.extend(rL)\n return True\n else:\n if self._raiseExceptions:\n raise ValueError\n else:\n logger.error(\"unexpected row data type\")\n else:\n logger.error(\"unexpected input data type\")\n return False\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.getAttributeUniqueValueList","title":"getAttributeUniqueValueList(self, attributeName)
","text":"Return a sorted list of unique attribute values.
Source code in mmcif/api/DataCategoryBase.py
def getAttributeUniqueValueList(self, attributeName):\n \"\"\"Return a sorted list of unique attribute values.\"\"\"\n rL = []\n try:\n rD = {}\n idx = self.getAttributeIndex(attributeName)\n rD = {row[idx]: True for row in self.data}\n return sorted(rD.keys())\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return rL\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.getAttributeValueList","title":"getAttributeValueList(self, attributeName)
","text":"Return a list of attribute values.
Source code in mmcif/api/DataCategoryBase.py
def getAttributeValueList(self, attributeName):\n \"\"\"Return a list of attribute values.\"\"\"\n rL = []\n try:\n idx = self.getAttributeIndex(attributeName)\n rL = [row[idx] for row in self.data]\n return rL\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return rL\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.removeAttribute","title":"removeAttribute(self, attributeName)
","text":"Remove the attribute from the attribute list along with any corresponding row data.
Source code in mmcif/api/DataCategoryBase.py
def removeAttribute(self, attributeName):\n \"\"\"Remove the attribute from the attribute list along with any\n corresponding row data.\n \"\"\"\n idx = self.getAttributeIndex(attributeName)\n if idx != -1:\n try:\n del self._attributeNameList[idx]\n for row in self.data:\n try:\n del row[idx]\n except Exception:\n pass\n self.__setup()\n return True\n except Exception:\n return False\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.removeDuplicateRows","title":"removeDuplicateRows(self)
","text":"Remove duplicate rows from the category
Exceptions:
Type Description e
any exception
Returns:
Type Description bool
True for success or False otherwise
Source code in mmcif/api/DataCategoryBase.py
def removeDuplicateRows(self):\n \"\"\"Remove duplicate rows from the category\n\n Raises:\n e: any exception\n\n Returns:\n bool: True for success or False otherwise\n \"\"\"\n try:\n filteredL = []\n for row in self.data:\n if row not in filteredL:\n filteredL.append(row)\n self.data = filteredL\n return True\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return False\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.renameAttributes","title":"renameAttributes(self, mapDict)
","text":"Rename attributes according to mapping information in the input mapping dictionary {oldName: newName}
Source code in mmcif/api/DataCategoryBase.py
def renameAttributes(self, mapDict):\n \"\"\"Rename attributes according to mapping information in the input mapping dictionary {oldName: newName}\"\"\"\n atL = []\n for atName in self._attributeNameList:\n atL.append(mapDict[atName] if atName in mapDict else atName)\n self._attributeNameList = atL\n self.__setup()\n return True\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.setMapping","title":"setMapping(self, mType)
","text":"Controls the manner in which this class returns data when accessed by index or in the context of an iterator:
DATA = list of row data elements as these were input. [default]
ATTRIBUTE = row returned as a dictionary with attribute key
ITEM = row returned as a dictionary with item key
Source code in mmcif/api/DataCategoryBase.py
def setMapping(self, mType):\n \"\"\"Controls the manner in which this class returns data when accessed by\n index or in the context of an iterator:\n\n DATA = list of row data elements as these were input. [default]\n\n ATTRIBUTE = row returned as a dictionary with attribute key\n\n ITEM = row returned as a dictionary with item key\n\n \"\"\"\n if mType in [\"DATA\", \"ATTRIBUTE\", \"ITEM\"]:\n self.__mappingType = mType\n return True\n else:\n return False\n
"},{"location":"api_reference/DataCategoryFormatted/","title":"DataCategoryFormatted","text":"A subclass of DataCategory including additional formatting methods.
Source code in mmcif/api/DataCategoryFormatted.py
class DataCategoryFormatted(DataCategory):\n \"\"\"A subclass of DataCategory including additional formatting methods.\"\"\"\n\n def __init__(self, dataCategoryObj, preferDoubleQuotes=True):\n self.__dcObj = dataCategoryObj\n super(DataCategoryFormatted, self).__init__(self.__dcObj.getName(), self.__dcObj.getAttributeList(), self.__dcObj.data)\n #\n self._currentRowIndex = 0\n self._currentAttribute = None\n #\n self.__avoidEmbeddedQuoting = False\n self.__preferDoubleQuotes = preferDoubleQuotes\n #\n # --------------------------------------------------------------------\n # any whitespace\n self.__wsRe = re.compile(r\"\\s\")\n # self.__wsAndQuotesRe=re.compile(r\"[\\s'\\\"]\")\n self.__wsAndQuotesRe = re.compile(r\"[\\s'\\\"#]\")\n # any newline or carriage control\n self.__nlRe = re.compile(r\"[\\n\\r]\")\n #\n # single quote\n self.__sqRe = re.compile(r\"[']\")\n #\n self.__sqWsRe = re.compile(r\"('\\s)|(\\s')\")\n\n # double quote\n self.__dqRe = re.compile(r'[\"]')\n self.__dqWsRe = re.compile(r'(\"\\s)|(\\s\")')\n #\n self.__intRe = re.compile(r\"^[0-9]+$\")\n self.__floatRe = re.compile(r\"^-?(([0-9]+)[.]?|([0-9]*[.][0-9]+))([(][0-9]+[)])?([eE][+-]?[0-9]+)?$\")\n #\n self.__dataTypeList = [\n \"DT_NULL_VALUE\",\n \"DT_INTEGER\",\n \"DT_FLOAT\",\n \"DT_UNQUOTED_STRING\",\n \"DT_ITEM_NAME\",\n \"DT_DOUBLE_QUOTED_STRING\",\n \"DT_SINGLE_QUOTED_STRING\",\n \"DT_MULTI_LINE_STRING\",\n ]\n self.__formatTypeList = [\n \"FT_NULL_VALUE\",\n \"FT_NUMBER\",\n \"FT_NUMBER\",\n \"FT_UNQUOTED_STRING\",\n \"FT_QUOTED_STRING\",\n \"FT_QUOTED_STRING\",\n \"FT_QUOTED_STRING\",\n \"FT_MULTI_LINE_STRING\",\n ]\n #\n # try:\n # basestring\n # except NameError:\n # basestring = str\n #\n # self.__string_types = basestring\n\n def __formatPdbx(self, inp):\n \"\"\"Format input data following PDBx quoting rules -\"\"\"\n try:\n if inp is None:\n return (\"?\", \"DT_NULL_VALUE\")\n\n # pure numerical values are returned as unquoted strings\n # if (isinstance(inp, int) or self.__intRe.search(str(inp))):\n #\n try:\n if isinstance(inp, int) or self.__intRe.search(inp):\n return ([str(inp)], \"DT_INTEGER\")\n except Exception:\n pass\n\n # if (isinstance(inp, float) or self.__floatRe.search(str(inp))):\n try:\n if isinstance(inp, float) or self.__floatRe.search(inp):\n return ([str(inp)], \"DT_FLOAT\")\n except Exception:\n pass\n\n # null value handling -\n\n if inp == \".\" or inp == \"?\":\n return ([inp], \"DT_NULL_VALUE\")\n\n if inp == \"\":\n return ([\".\"], \"DT_NULL_VALUE\")\n\n # Contains white space or quotes ?\n if not self.__wsAndQuotesRe.search(inp):\n # if inp.startswith(\"_\"):\n if inp[0] in [\"_\"]:\n return (self.__doubleQuotedList(inp), \"DT_ITEM_NAME\")\n elif inp[0] in [\"[\", \"]\", \"$\", \"#\", \";\"]:\n return (self.__doubleQuotedList(inp), \"DT_DOUBLE_QUOTED_STRING\")\n elif inp[:5].lower() in [\"data_\", \"loop_\", \"save_\", \"stop_\"]:\n return (self.__doubleQuotedList(inp), \"DT_DOUBLE_QUOTED_STRING\")\n else:\n return ([str(inp)], \"DT_UNQUOTED_STRING\")\n else:\n if self.__nlRe.search(inp):\n return (self.__semiColonQuotedList(inp), \"DT_MULTI_LINE_STRING\")\n else:\n if self.__preferDoubleQuotes:\n if self.__avoidEmbeddedQuoting:\n # change priority to choose double quoting where possible.\n if not self.__dqRe.search(inp) and not self.__sqWsRe.search(inp):\n return (self.__doubleQuotedList(inp), \"DT_DOUBLE_QUOTED_STRING\")\n elif not self.__sqRe.search(inp) and not self.__dqWsRe.search(inp):\n return (self.__singleQuotedList(inp), \"DT_SINGLE_QUOTED_STRING\")\n else:\n return (self.__semiColonQuotedList(inp), \"DT_MULTI_LINE_STRING\")\n else:\n # change priority to choose double quoting where possible.\n if not self.__dqRe.search(inp):\n return (self.__doubleQuotedList(inp), \"DT_DOUBLE_QUOTED_STRING\")\n elif not self.__sqRe.search(inp):\n return (self.__singleQuotedList(inp), \"DT_SINGLE_QUOTED_STRING\")\n else:\n return (self.__semiColonQuotedList(inp), \"DT_MULTI_LINE_STRING\")\n else:\n if self.__avoidEmbeddedQuoting:\n # change priority to choose double quoting where possible.\n if not self.__sqRe.search(inp) and not self.__dqWsRe.search(inp):\n return (self.__singleQuotedList(inp), \"DT_SINGLE_QUOTED_STRING\")\n elif not self.__dqRe.search(inp) and not self.__sqWsRe.search(inp):\n return (self.__doubleQuotedList(inp), \"DT_DOUBLE_QUOTED_STRING\")\n else:\n return (self.__semiColonQuotedList(inp), \"DT_MULTI_LINE_STRING\")\n else:\n # change priority to choose double quoting where possible.\n if not self.__sqRe.search(inp):\n return (self.__singleQuotedList(inp), \"DT_SINGLE_QUOTED_STRING\")\n elif not self.__dqRe.search(inp):\n return (self.__doubleQuotedList(inp), \"DT_DOUBLE_QUOTED_STRING\")\n else:\n return (self.__semiColonQuotedList(inp), \"DT_MULTI_LINE_STRING\")\n except Exception as e:\n logger.exception(\"Failing with %s on input %r %r\", str(e), inp, type(inp))\n\n return (\"?\", \"DT_NULL_VALUE\")\n\n def __dataTypePdbx(self, inp):\n \"\"\"Detect the PDBx data type -\"\"\"\n if inp is None:\n return \"DT_NULL_VALUE\"\n\n # pure numerical values are returned as unquoted strings\n # if isinstance(inp, int) or self.__intRe.search(str(inp)):\n if isinstance(inp, int) or (isinstance(inp, string_types) and self.__intRe.search(inp)):\n return \"DT_INTEGER\"\n\n # if isinstance(inp, float) or self.__floatRe.search(str(inp)):\n if isinstance(inp, float) or (isinstance(inp, string_types) and self.__floatRe.search(inp)):\n return \"DT_FLOAT\"\n\n # null value handling -\n\n if inp == \".\" or inp == \"?\":\n return \"DT_NULL_VALUE\"\n\n if inp == \"\":\n return \"DT_NULL_VALUE\"\n\n # Contains white space or quotes ?\n if not self.__wsAndQuotesRe.search(inp):\n if inp.startswith(\"_\"):\n return \"DT_ITEM_NAME\"\n else:\n return \"DT_UNQUOTED_STRING\"\n else:\n if self.__nlRe.search(inp):\n return \"DT_MULTI_LINE_STRING\"\n else:\n if self.__avoidEmbeddedQuoting:\n if not self.__sqRe.search(inp) and not self.__dqWsRe.search(inp):\n return \"DT_DOUBLE_QUOTED_STRING\"\n elif not self.__dqRe.search(inp) and not self.__sqWsRe.search(inp):\n return \"DT_SINGLE_QUOTED_STRING\"\n else:\n return \"DT_MULTI_LINE_STRING\"\n else:\n if not self.__sqRe.search(inp):\n return \"DT_DOUBLE_QUOTED_STRING\"\n elif not self.__dqRe.search(inp):\n return \"DT_SINGLE_QUOTED_STRING\"\n else:\n return \"DT_MULTI_LINE_STRING\"\n\n def __singleQuotedList(self, inp):\n ll = []\n ll.append(\"'\")\n ll.append(inp)\n ll.append(\"'\")\n return ll\n\n def __doubleQuotedList(self, inp):\n ll = []\n ll.append('\"')\n ll.append(inp)\n ll.append('\"')\n return ll\n\n def __semiColonQuotedList(self, inp):\n ll = []\n ll.append(\"\\n\")\n if inp[-1] == \"\\n\":\n ll.append(\";\")\n ll.append(inp)\n ll.append(\";\")\n ll.append(\"\\n\")\n else:\n ll.append(\";\")\n ll.append(inp)\n ll.append(\"\\n\")\n ll.append(\";\")\n ll.append(\"\\n\")\n\n return ll\n\n def getValueFormatted(self, attributeName=None, rowIndex=None):\n if attributeName is None:\n attribute = self._currentAttribute\n else:\n attribute = attributeName\n\n if rowIndex is None:\n rowI = self._currentRowIndex\n else:\n rowI = rowIndex\n\n if isinstance(attribute, self._stringTypes) and isinstance(rowI, int):\n try:\n fList, _ = self.__formatPdbx(self.data[rowI][self._attributeNameList.index(attribute)])\n return \"\".join(fList)\n except IndexError:\n logger.exception(\"attributeName %s rowI %r rowdata %r\", attributeName, rowI, self.data[rowI])\n raise IndexError\n except Exception as e:\n logger.exception(\" Failing with %s - AttributeName %s rowI %r rowdata %r\", str(e), attributeName, rowI, self.data[rowI])\n else:\n logger.error(\" Type error - AttributeName %r rowI %r rowdata %r\", attributeName, rowI, self.data[rowI])\n logger.error(\" Type error - string types %r\", self._stringTypes)\n raise TypeError(attribute)\n\n def getValueFormattedByIndex(self, attributeIndex, rowIndex):\n try:\n fList, _ = self.__formatPdbx(self.data[rowIndex][attributeIndex])\n return \"\".join(fList)\n except IndexError:\n logger.exception(\"attributeIndex %r rowIndex %r rowdata %r\", attributeIndex, rowIndex, self.data[rowIndex][attributeIndex])\n raise IndexError\n except Exception as e:\n logger.exception(\"Failing with %s - attributeIndex %r rowIndex %r rowdata %r\", str(e), attributeIndex, rowIndex, self.data[rowIndex][attributeIndex])\n raise e\n\n def getAttributeValueMaxLengthList(self, steps=1):\n mList = [0 for i in range(len(self._attributeNameList))]\n for row in self.data[::steps]:\n for indx in range(len(self._attributeNameList)):\n val = row[indx]\n if isinstance(val, self._stringTypes):\n tLen = len(val)\n else:\n tLen = len(str(val))\n\n mList[indx] = max(mList[indx], tLen)\n return mList\n\n def getFormatTypeList(self, steps=1):\n try:\n curFormatTypeList = []\n curDataTypeList = [\"DT_NULL_VALUE\" for i in range(len(self._attributeNameList))]\n for row in self.data[::steps]:\n for indx in range(len(self._attributeNameList)):\n val = row[indx]\n # print \"index \",indx,\" val \",val\n dType = self.__dataTypePdbx(val)\n dIndx = self.__dataTypeList.index(dType)\n # print \"d type\", dType, \" d type index \",dIndx\n\n cType = curDataTypeList[indx]\n cIndx = self.__dataTypeList.index(cType)\n cIndx = max(cIndx, dIndx)\n curDataTypeList[indx] = self.__dataTypeList[cIndx]\n\n # Map the format types to the data types\n curFormatTypeList = []\n for dt in curDataTypeList:\n ii = self.__dataTypeList.index(dt)\n curFormatTypeList.append(self.__formatTypeList[ii])\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n\n return curFormatTypeList, curDataTypeList\n
"},{"location":"api_reference/DataCategoryTyped/","title":"DataCategoryTyped","text":"A subclass of DataCategory with methods to apply explicit data typing.
Source code in mmcif/api/DataCategoryTyped.py
class DataCategoryTyped(DataCategory):\n \"\"\"A subclass of DataCategory with methods to apply explicit data typing.\"\"\"\n\n def __init__(\n self,\n dataCategoryObj,\n dictionaryApi=None,\n raiseExceptions=True,\n copyInputData=True,\n ignoreCastErrors=False,\n useCifUnknowns=True,\n missingValueString=None,\n missingValueInteger=None,\n missingValueFloat=None,\n ):\n \"\"\"A subclass of DataCategory with methods to apply explicit data typing.\n\n Args:\n dataCategoryObj (object): DataCategory object instance\n dictionaryApi (object, optional): instance of DictionaryApi class. Defaults to None.\n raiseExceptions (bool, optional): raise exceptions. Defaults to True.\n copyInputData (bool, optional): make a new copy input data. Defaults to True.\n ignoreCastErrors (bool, optional): ignore data processing cast errors. Defaults to False.\n useCifUnknowns (bool, optional): use CIF style missing values ('.' and '?'). Defaults to True.\n missingValueString (str, optional): missing string value . Defaults to None.\n missingValueInteger (integer, optional): missing integer value. Defaults to None.\n missingValueFloat (float, optional): missing float value. Defaults to None.\n \"\"\"\n self.__dcObj = dataCategoryObj\n super(DataCategoryTyped, self).__init__(\n self.__dcObj.getName(),\n self.__dcObj.getAttributeList(),\n self.__dcObj.data,\n raiseExceptions=raiseExceptions,\n copyInputData=copyInputData,\n )\n #\n self.__dApi = dictionaryApi\n self.__attributeTypeD = {}\n self.__castD = {\"integer\": int, \"float\": float, \"string\": str}\n self.__typesSet = self.applyTypes(\n ignoreCastErrors=ignoreCastErrors,\n useCifUnknowns=useCifUnknowns,\n missingValueString=missingValueString,\n missingValueInteger=missingValueInteger,\n missingValueFloat=missingValueFloat,\n )\n\n def applyTypes(self, ignoreCastErrors=False, useCifUnknowns=True, missingValueString=None, missingValueInteger=None, missingValueFloat=None):\n \"\"\"Cast data types (string, integer, float) in the current object based on dictionary type details.\n Missing values ('.' or '?') are set to None.\n\n Raises:\n e: any exception\n\n Returns:\n bool: True for success or False otherwise\n \"\"\"\n ok = False\n try:\n for ii, atName in enumerate(self.getAttributeList()):\n # colValL = self.getColumn(ii)\n dataType, isMandatory = self.__getAttributeInfo(atName)\n missingValue = missingValueInteger if dataType == \"integer\" else missingValueFloat if dataType in [\"integer\", \"float\"] else missingValueString\n missingValue = missingValue if not useCifUnknowns else \".\" if isMandatory else \"?\"\n for row in self.data:\n try:\n row[ii] = self.__castD[dataType](row[ii]) if row[ii] is not None and row[ii] not in [\".\", \"?\"] else missingValue\n except Exception as e:\n if not ignoreCastErrors:\n logger.error(\"Cast error %s %s (%s) %r %r\", self.getName(), atName, dataType, row[ii], str(e))\n row[ii] = missingValue\n #\n logger.debug(\"%s %s %r\", self.getName(), atName, [row[ii] for row in self.data])\n self.__attributeTypeD[atName] = dataType\n ok = True\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n if self._raiseExceptions:\n raise e\n return ok\n\n def getAttributeInfo(self, atName):\n \"\"\"Get attribute data type (string, integer, or float) and optionality\n\n Args:\n atName (str): attribute name\n\n Returns:\n (string, bool): data type (string, integer or float) and mandatory code\n \"\"\"\n try:\n dataType, mandatoryCode = self.__getAttributeInfo(atName)\n return dataType, mandatoryCode\n except Exception:\n return None, None\n\n def applyStringTypes(self):\n \"\"\"Cast data types to strings in the current object. Missing values are set to '?' and '.' for\n optional and mandatory attributes, respectively.\n\n Raises:\n e: any exception\n\n Returns:\n bool: True for success or False otherwise\n \"\"\"\n ok = False\n try:\n for ii, atName in enumerate(self.getAttributeList()):\n _, isMandatory = self.__getAttributeInfo(atName)\n dataType = \"string\"\n for row in self.data:\n if row[ii] is None or row[ii] in [\".\", \"?\"]:\n row[ii] = \".\" if isMandatory else \"?\"\n else:\n row[ii] = self.__castD[dataType](row[ii])\n #\n self.__attributeTypeD[atName] = dataType\n ok = True\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n if self._raiseExceptions:\n raise e\n return ok\n\n def cmpAttributeValues(self, dcObj, ignoreOrder=True, **kwargs):\n \"\"\"Compare the values by attribute for current typed data category (dca) and input data category.\n The comparison is performed for values of the attributes common to both objects. Length differences\n are treated inequality out of hand.\n\n Args:\n dcObj (object): DataCategory object\n ignoreOrder (bool, optional): ignore attribute order. Defaults to True.\n floatRelTolerance (float, optional): relative tolerance for float comparisons. Defaults to 1e-05.\n floatAbsTolerance (float, optional): absolute tolerance for float comparisons. Defaults to 1e-04.\n\n Raises:\n e: any exception\n\n Returns:\n list: [(attributeName, values equal/close flag (bool)), (attributeName, values equal/close flag (bool), ...]\n\n \"\"\"\n rL = []\n floatRelTolerance = kwargs.get(\"floatRelTolerance\", 1.0e-05)\n floatAbsTolerance = kwargs.get(\"floatAbsTolerance\", 1.0e-04)\n try:\n sa = set(self.getAttributeList())\n sb = set(dcObj.getAttributeList())\n atNameComList = list(sa & sb)\n #\n lenEq = self.getRowCount() == dcObj.getRowCount()\n if not lenEq:\n return [(atName, False) for atName in atNameComList]\n #\n for atName in atNameComList:\n dataType, _ = self.__getAttributeInfo(atName)\n if dataType in [\"string\", \"integer\"]:\n if ignoreOrder:\n same = sorted(self.getAttributeValueList(atName)) == sorted(dcObj.getAttributeValueList(atName))\n else:\n same = self.getAttributeValueList(atName) == dcObj.getAttributeValueList(atName)\n elif dataType in [\"float\"]:\n aVL = self.getAttributeValueList(atName)\n bVL = dcObj.getAttributeValueList(atName)\n if ignoreOrder:\n for aV, bV in zip(sorted(aVL), sorted(bVL)):\n same = self.__isClose(aV, bV, relTol=floatRelTolerance, absTol=floatAbsTolerance)\n if not same:\n break\n else:\n for aV, bV in zip(aVL, bVL):\n same = self.__isClose(aV, bV, relTol=floatRelTolerance, absTol=floatAbsTolerance)\n if not same:\n logger.info(\"%s %s (rel=%r) (abs=%r) %r (%r)\", self.getName(), atName, aV * floatRelTolerance, floatAbsTolerance, aV, abs(aV - bV))\n break\n rL.append((atName, same))\n #\n return rL\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return rL\n\n def __getAttributeInfo(self, atName):\n \"\"\"Get attribute data type (string, integer, or float) and optionality\n\n Args:\n atName (str): attribute name\n\n Returns:\n (string, bool): data type (string, integer or float) and mandatory code\n \"\"\"\n cifDataType = self.__dApi.getTypeCode(self.getName(), atName)\n cifPrimitiveType = self.__dApi.getTypePrimitive(self.getName(), atName)\n isMandatory = self.__dApi.getMandatoryCode(self.getName(), atName) in [\"yes\", \"implicit\", \"implicit-ordinal\"]\n dataType = \"integer\" if \"int\" in cifDataType else \"float\" if cifPrimitiveType == \"numb\" else \"string\"\n return dataType, isMandatory\n\n def __isClose(self, aV, bV, relTol=1e-09, absTol=1e-06):\n if aV is None and bV is None:\n return True\n elif aV is not None and bV is not None and aV == bV:\n return True\n elif isinstance(aV, (float)) and isinstance(bV, (float)):\n return abs(aV - bV) <= max(relTol * max(abs(aV), abs(bV)), absTol)\n else:\n raise ValueError\n
"},{"location":"api_reference/DataCategoryTyped/#mmcif.api.DataCategoryTyped.DataCategoryTyped.__init__","title":"__init__(self, dataCategoryObj, dictionaryApi=None, raiseExceptions=True, copyInputData=True, ignoreCastErrors=False, useCifUnknowns=True, missingValueString=None, missingValueInteger=None, missingValueFloat=None)
special
","text":"A subclass of DataCategory with methods to apply explicit data typing.
Parameters:
Name Type Description Default dataCategoryObj
object
DataCategory object instance
required dictionaryApi
object
instance of DictionaryApi class. Defaults to None.
None
raiseExceptions
bool
raise exceptions. Defaults to True.
True
copyInputData
bool
make a new copy input data. Defaults to True.
True
ignoreCastErrors
bool
ignore data processing cast errors. Defaults to False.
False
useCifUnknowns
bool
use CIF style missing values ('.' and '?'). Defaults to True.
True
missingValueString
str
missing string value . Defaults to None.
None
missingValueInteger
integer
missing integer value. Defaults to None.
None
missingValueFloat
float
missing float value. Defaults to None.
None
Source code in mmcif/api/DataCategoryTyped.py
def __init__(\n self,\n dataCategoryObj,\n dictionaryApi=None,\n raiseExceptions=True,\n copyInputData=True,\n ignoreCastErrors=False,\n useCifUnknowns=True,\n missingValueString=None,\n missingValueInteger=None,\n missingValueFloat=None,\n):\n \"\"\"A subclass of DataCategory with methods to apply explicit data typing.\n\n Args:\n dataCategoryObj (object): DataCategory object instance\n dictionaryApi (object, optional): instance of DictionaryApi class. Defaults to None.\n raiseExceptions (bool, optional): raise exceptions. Defaults to True.\n copyInputData (bool, optional): make a new copy input data. Defaults to True.\n ignoreCastErrors (bool, optional): ignore data processing cast errors. Defaults to False.\n useCifUnknowns (bool, optional): use CIF style missing values ('.' and '?'). Defaults to True.\n missingValueString (str, optional): missing string value . Defaults to None.\n missingValueInteger (integer, optional): missing integer value. Defaults to None.\n missingValueFloat (float, optional): missing float value. Defaults to None.\n \"\"\"\n self.__dcObj = dataCategoryObj\n super(DataCategoryTyped, self).__init__(\n self.__dcObj.getName(),\n self.__dcObj.getAttributeList(),\n self.__dcObj.data,\n raiseExceptions=raiseExceptions,\n copyInputData=copyInputData,\n )\n #\n self.__dApi = dictionaryApi\n self.__attributeTypeD = {}\n self.__castD = {\"integer\": int, \"float\": float, \"string\": str}\n self.__typesSet = self.applyTypes(\n ignoreCastErrors=ignoreCastErrors,\n useCifUnknowns=useCifUnknowns,\n missingValueString=missingValueString,\n missingValueInteger=missingValueInteger,\n missingValueFloat=missingValueFloat,\n )\n
"},{"location":"api_reference/DataCategoryTyped/#mmcif.api.DataCategoryTyped.DataCategoryTyped.applyStringTypes","title":"applyStringTypes(self)
","text":"Cast data types to strings in the current object. Missing values are set to '?' and '.' for optional and mandatory attributes, respectively.
Exceptions:
Type Description e
any exception
Returns:
Type Description bool
True for success or False otherwise
Source code in mmcif/api/DataCategoryTyped.py
def applyStringTypes(self):\n \"\"\"Cast data types to strings in the current object. Missing values are set to '?' and '.' for\n optional and mandatory attributes, respectively.\n\n Raises:\n e: any exception\n\n Returns:\n bool: True for success or False otherwise\n \"\"\"\n ok = False\n try:\n for ii, atName in enumerate(self.getAttributeList()):\n _, isMandatory = self.__getAttributeInfo(atName)\n dataType = \"string\"\n for row in self.data:\n if row[ii] is None or row[ii] in [\".\", \"?\"]:\n row[ii] = \".\" if isMandatory else \"?\"\n else:\n row[ii] = self.__castD[dataType](row[ii])\n #\n self.__attributeTypeD[atName] = dataType\n ok = True\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n if self._raiseExceptions:\n raise e\n return ok\n
"},{"location":"api_reference/DataCategoryTyped/#mmcif.api.DataCategoryTyped.DataCategoryTyped.applyTypes","title":"applyTypes(self, ignoreCastErrors=False, useCifUnknowns=True, missingValueString=None, missingValueInteger=None, missingValueFloat=None)
","text":"Cast data types (string, integer, float) in the current object based on dictionary type details. Missing values ('.' or '?') are set to None.
Exceptions:
Type Description e
any exception
Returns:
Type Description bool
True for success or False otherwise
Source code in mmcif/api/DataCategoryTyped.py
def applyTypes(self, ignoreCastErrors=False, useCifUnknowns=True, missingValueString=None, missingValueInteger=None, missingValueFloat=None):\n \"\"\"Cast data types (string, integer, float) in the current object based on dictionary type details.\n Missing values ('.' or '?') are set to None.\n\n Raises:\n e: any exception\n\n Returns:\n bool: True for success or False otherwise\n \"\"\"\n ok = False\n try:\n for ii, atName in enumerate(self.getAttributeList()):\n # colValL = self.getColumn(ii)\n dataType, isMandatory = self.__getAttributeInfo(atName)\n missingValue = missingValueInteger if dataType == \"integer\" else missingValueFloat if dataType in [\"integer\", \"float\"] else missingValueString\n missingValue = missingValue if not useCifUnknowns else \".\" if isMandatory else \"?\"\n for row in self.data:\n try:\n row[ii] = self.__castD[dataType](row[ii]) if row[ii] is not None and row[ii] not in [\".\", \"?\"] else missingValue\n except Exception as e:\n if not ignoreCastErrors:\n logger.error(\"Cast error %s %s (%s) %r %r\", self.getName(), atName, dataType, row[ii], str(e))\n row[ii] = missingValue\n #\n logger.debug(\"%s %s %r\", self.getName(), atName, [row[ii] for row in self.data])\n self.__attributeTypeD[atName] = dataType\n ok = True\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n if self._raiseExceptions:\n raise e\n return ok\n
"},{"location":"api_reference/DataCategoryTyped/#mmcif.api.DataCategoryTyped.DataCategoryTyped.cmpAttributeValues","title":"cmpAttributeValues(self, dcObj, ignoreOrder=True, **kwargs)
","text":"Compare the values by attribute for current typed data category (dca) and input data category. The comparison is performed for values of the attributes common to both objects. Length differences are treated inequality out of hand.
Parameters:
Name Type Description Default dcObj
object
DataCategory object
required ignoreOrder
bool
ignore attribute order. Defaults to True.
True
floatRelTolerance
float
relative tolerance for float comparisons. Defaults to 1e-05.
required floatAbsTolerance
float
absolute tolerance for float comparisons. Defaults to 1e-04.
required Exceptions:
Type Description e
any exception
Returns:
Type Description list
[(attributeName, values equal/close flag (bool)), (attributeName, values equal/close flag (bool), ...]
Source code in mmcif/api/DataCategoryTyped.py
def cmpAttributeValues(self, dcObj, ignoreOrder=True, **kwargs):\n \"\"\"Compare the values by attribute for current typed data category (dca) and input data category.\n The comparison is performed for values of the attributes common to both objects. Length differences\n are treated inequality out of hand.\n\n Args:\n dcObj (object): DataCategory object\n ignoreOrder (bool, optional): ignore attribute order. Defaults to True.\n floatRelTolerance (float, optional): relative tolerance for float comparisons. Defaults to 1e-05.\n floatAbsTolerance (float, optional): absolute tolerance for float comparisons. Defaults to 1e-04.\n\n Raises:\n e: any exception\n\n Returns:\n list: [(attributeName, values equal/close flag (bool)), (attributeName, values equal/close flag (bool), ...]\n\n \"\"\"\n rL = []\n floatRelTolerance = kwargs.get(\"floatRelTolerance\", 1.0e-05)\n floatAbsTolerance = kwargs.get(\"floatAbsTolerance\", 1.0e-04)\n try:\n sa = set(self.getAttributeList())\n sb = set(dcObj.getAttributeList())\n atNameComList = list(sa & sb)\n #\n lenEq = self.getRowCount() == dcObj.getRowCount()\n if not lenEq:\n return [(atName, False) for atName in atNameComList]\n #\n for atName in atNameComList:\n dataType, _ = self.__getAttributeInfo(atName)\n if dataType in [\"string\", \"integer\"]:\n if ignoreOrder:\n same = sorted(self.getAttributeValueList(atName)) == sorted(dcObj.getAttributeValueList(atName))\n else:\n same = self.getAttributeValueList(atName) == dcObj.getAttributeValueList(atName)\n elif dataType in [\"float\"]:\n aVL = self.getAttributeValueList(atName)\n bVL = dcObj.getAttributeValueList(atName)\n if ignoreOrder:\n for aV, bV in zip(sorted(aVL), sorted(bVL)):\n same = self.__isClose(aV, bV, relTol=floatRelTolerance, absTol=floatAbsTolerance)\n if not same:\n break\n else:\n for aV, bV in zip(aVL, bVL):\n same = self.__isClose(aV, bV, relTol=floatRelTolerance, absTol=floatAbsTolerance)\n if not same:\n logger.info(\"%s %s (rel=%r) (abs=%r) %r (%r)\", self.getName(), atName, aV * floatRelTolerance, floatAbsTolerance, aV, abs(aV - bV))\n break\n rL.append((atName, same))\n #\n return rL\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return rL\n
"},{"location":"api_reference/DataCategoryTyped/#mmcif.api.DataCategoryTyped.DataCategoryTyped.getAttributeInfo","title":"getAttributeInfo(self, atName)
","text":"Get attribute data type (string, integer, or float) and optionality
Parameters:
Name Type Description Default atName
str
attribute name
required Returns:
Type Description (string, bool)
data type (string, integer or float) and mandatory code
Source code in mmcif/api/DataCategoryTyped.py
def getAttributeInfo(self, atName):\n \"\"\"Get attribute data type (string, integer, or float) and optionality\n\n Args:\n atName (str): attribute name\n\n Returns:\n (string, bool): data type (string, integer or float) and mandatory code\n \"\"\"\n try:\n dataType, mandatoryCode = self.__getAttributeInfo(atName)\n return dataType, mandatoryCode\n except Exception:\n return None, None\n
"},{"location":"api_reference/DictMethodRunner/","title":"DictMethodRunner","text":"Manage the invocation of dictionary methods implemented as class methods.
Source code in mmcif/api/DictMethodRunner.py
class DictMethodRunner(object):\n \"\"\"Manage the invocation of dictionary methods implemented as class methods.\"\"\"\n\n def __init__(self, dictionaryApi, modulePathMap=None, **kwargs):\n \"\"\"Manage invocation of dictionary methods referenced in external modules.\n\n Arguments:\n dictionaryApi {object} -- instance of DictionaryApi() for dictionary with target method definitions\n\n Keyword Arguments:\n modulePathMap {dict str} -- mapping between dictionary module path and execution path (default: {None})\n cacheModuleFlag {bool} -- flag to cache module instances (defaullt: True)\n implentationSource {str} -- method implementation (default: 'reference')\n methodCodes (list str) -- filter methods by codes {default: ['calculation']}\n \"\"\"\n self.__dApi = dictionaryApi\n self.__modulePathMap = modulePathMap if modulePathMap else {}\n self.__cacheModuleFlag = kwargs.get(\"cacheModuleFlag\", True)\n methodCodes = kwargs.get(\"methodCodes\", [\"calculation\"])\n implementationSource = kwargs.get(\"implementationCodes\", \"reference\")\n #\n self.__kwargs = kwargs\n #\n # Preserve and reuse the module instances if caching is enabled\n self.__moduleCache = {}\n #\n self.__methodD = self.__getMethodInfo(implementationSource=implementationSource, methodCodes=methodCodes)\n logger.debug(\"Method index %r\", self.__methodD.items())\n\n def __getMethodInfo(self, implementationSource=\"reference\", methodCodes=None):\n \"\"\"Get method implementation with the input implementation source.\"\"\"\n catName = atName = mId = mType = methDef = None\n methodCodes = methodCodes if methodCodes else [\"calculation\"]\n methodD = {}\n try:\n methodIndex = self.__dApi.getMethodIndex()\n for _, mrL in methodIndex.items():\n for mr in mrL:\n mId = mr.getId()\n catName = mr.getCategoryName()\n atName = mr.getAttributeName()\n mType = mr.getType()\n if (catName, atName) not in methodD:\n methodD[(catName, atName)] = []\n methDef = self.__dApi.getMethod(mId)\n logger.debug(\"Category %s attribute %s mId %r type %r methDef %r\", catName, atName, mId, mType, methDef)\n mSource = methDef.getImplementationSource()\n mCode = methDef.getCode()\n if mSource == implementationSource and mCode in methodCodes:\n mPriority = methDef.getPriority()\n mLang = methDef.getLanguage()\n mImplement = methDef.getImplementation()\n dD = {\"METHOD_LANGUAGE\": mLang, \"METHOD_IMPLEMENT\": mImplement, \"METHOD_TYPE\": mType, \"METHOD_CODE\": mCode, \"METHOD_PRIORITY\": mPriority}\n methodD[(catName, atName)].append(dD)\n #\n except Exception as e:\n logger.exception(\"Failing for category %r attribute %r mId %r type %r methDef %r with %s\", catName, atName, mId, mType, methDef, str(e))\n\n ##\n logger.debug(\"Method dictionary %r\", methodD)\n return methodD\n\n def __invokeAttributeMethod(self, methodPath, dataContainer, catName, atName, **kwargs):\n \"\"\"Invoke the input attribute method\"\"\"\n ok = False\n try:\n modulePath, methodName = self.__methodPathSplit(methodPath)\n mObj = self.__getModuleInstance(modulePath, **kwargs)\n theMeth = getattr(mObj, methodName, None)\n ok = theMeth(dataContainer, catName, atName, **kwargs)\n except Exception as e:\n logger.exception(\"Failed invoking attribute %s %s method %r with %s\", catName, atName, methodPath, str(e))\n return ok\n\n def __invokeCategoryMethod(self, methodPath, dataContainer, catName, **kwargs):\n \"\"\"Invoke the input category method\"\"\"\n ok = False\n try:\n modulePath, methodName = self.__methodPathSplit(methodPath)\n mObj = self.__getModuleInstance(modulePath, **kwargs)\n theMeth = getattr(mObj, methodName, None)\n ok = theMeth(dataContainer, catName, **kwargs)\n except Exception as e:\n logger.exception(\"Failed invoking category %s method %r with %s\", catName, methodPath, str(e))\n return ok\n\n def __invokeDatablockMethod(self, methodPath, dataContainer, blockName, **kwargs):\n \"\"\"Invoke the input data block method\"\"\"\n ok = False\n try:\n modulePath, methodName = self.__methodPathSplit(methodPath)\n mObj = self.__getModuleInstance(modulePath, **kwargs)\n theMeth = getattr(mObj, methodName, None)\n ok = theMeth(dataContainer, blockName, **kwargs)\n except Exception as e:\n logger.exception(\"Failed invoking block %s method %r with %s\", blockName, methodPath, str(e))\n return ok\n\n def apply(self, dataContainer):\n \"\"\"Apply category, attribute and block level dictionary methods on the input data container.\"\"\"\n kwargs = self.__kwargs\n mTupL = self.__getCategoryMethods()\n logger.debug(\"Category methods %r\", mTupL)\n for catName, _, methodPath, _ in mTupL:\n self.__invokeCategoryMethod(methodPath, dataContainer, catName, **kwargs)\n\n mTupL = self.__getAttributeMethods()\n logger.debug(\"Attribute methods %r\", mTupL)\n for catName, atName, methodPath, _ in mTupL:\n self.__invokeAttributeMethod(methodPath, dataContainer, catName, atName, **kwargs)\n\n mTupL = self.__getDatablockMethods()\n logger.debug(\"Datablock methods %r\", mTupL)\n for _, _, methodPath, _ in mTupL:\n self.__invokeDatablockMethod(methodPath, dataContainer, dataContainer.getName(), **kwargs)\n\n return True\n\n def __getDatablockMethods(self):\n mL = []\n try:\n for (dictName, _), mDL in self.__methodD.items():\n for mD in mDL:\n if mD[\"METHOD_TYPE\"].lower() == \"datablock\":\n methodPath = mD[\"METHOD_IMPLEMENT\"]\n mL.append((dictName, None, methodPath, mD[\"METHOD_PRIORITY\"]))\n mL = sorted(mL, key=itemgetter(3))\n return mL\n except Exception as e:\n logger.exception(\"Failing dictName %s with %s\", dictName, str(e))\n return mL\n\n def __getCategoryMethods(self):\n mL = []\n try:\n for (catName, _), mDL in self.__methodD.items():\n for mD in mDL:\n if mD[\"METHOD_TYPE\"].lower() == \"category\":\n methodPath = mD[\"METHOD_IMPLEMENT\"]\n mL.append((catName, None, methodPath, mD[\"METHOD_PRIORITY\"]))\n mL = sorted(mL, key=itemgetter(3))\n return mL\n except Exception as e:\n logger.exception(\"Failing catName %r with %s\", catName, str(e))\n return mL\n\n def __getAttributeMethods(self):\n mL = []\n try:\n for (catName, atName), mDL in self.__methodD.items():\n for mD in mDL:\n if mD[\"METHOD_TYPE\"].lower() == \"attribute\":\n methodPath = mD[\"METHOD_IMPLEMENT\"]\n mL.append((catName, atName, methodPath, mD[\"METHOD_PRIORITY\"]))\n mL = sorted(mL, key=itemgetter(3))\n return mL\n except Exception as e:\n logger.exception(\"Failing catName %s atName %s with %s\", catName, atName, str(e))\n return mL\n\n def __methodPathSplit(self, methodPath):\n \"\"\"Extract module path and the method name from the input path. Optional\n remap the module path.\n\n Arguments:\n methodPath {str} -- implementation path from dictionary method definition\n\n Returns:\n {tuple str} -- module path, method name\n \"\"\"\n try:\n # Strip off any leading path of the module from the method path.\n mpL = str(methodPath).split(\".\")\n methodName = mpL[-1]\n tp = \".\".join(mpL[:-1])\n modulePath = self.__modulePathMap[tp] if tp in self.__modulePathMap else tp\n return modulePath, methodName\n except Exception as e:\n logger.error(\"Failing for method path %r with %s\", methodPath, str(e))\n return None, None\n\n def __getModuleInstance(self, modulePath, **kwargs):\n #\n if self.__cacheModuleFlag and modulePath in self.__moduleCache:\n return self.__moduleCache[modulePath]\n #\n mObj = None\n try:\n aMod = __import__(modulePath, globals(), locals(), [\"\"])\n sys.modules[modulePath] = aMod\n #\n # Strip off any leading path to the module before we instaniate the module object.\n mpL = str(modulePath).split(\".\")\n moduleName = mpL[-1]\n #\n # Add the internal dictionaryApi object instance as a kw option\n #\n kwargs[\"dictionaryApi\"] = self.__dApi\n mObj = getattr(aMod, moduleName)(**kwargs)\n self.__moduleCache[modulePath] = mObj\n\n except Exception as e:\n logger.error(\"Failing to instance helper %r with %s\", modulePath, str(e))\n return mObj\n
"},{"location":"api_reference/DictMethodRunner/#mmcif.api.DictMethodRunner.DictMethodRunner.__init__","title":"__init__(self, dictionaryApi, modulePathMap=None, **kwargs)
special
","text":"Manage invocation of dictionary methods referenced in external modules.
Keyword arguments:
Name Type Description modulePathMap
{dict str} -- mapping between dictionary module path and execution path (default
{None})
cacheModuleFlag
{bool} -- flag to cache module instances (defaullt
True)
implentationSource
{str} -- method implementation (default
'reference')
methodCodes
list str) -- filter methods by codes {default
['calculation']}
Source code in mmcif/api/DictMethodRunner.py
def __init__(self, dictionaryApi, modulePathMap=None, **kwargs):\n \"\"\"Manage invocation of dictionary methods referenced in external modules.\n\n Arguments:\n dictionaryApi {object} -- instance of DictionaryApi() for dictionary with target method definitions\n\n Keyword Arguments:\n modulePathMap {dict str} -- mapping between dictionary module path and execution path (default: {None})\n cacheModuleFlag {bool} -- flag to cache module instances (defaullt: True)\n implentationSource {str} -- method implementation (default: 'reference')\n methodCodes (list str) -- filter methods by codes {default: ['calculation']}\n \"\"\"\n self.__dApi = dictionaryApi\n self.__modulePathMap = modulePathMap if modulePathMap else {}\n self.__cacheModuleFlag = kwargs.get(\"cacheModuleFlag\", True)\n methodCodes = kwargs.get(\"methodCodes\", [\"calculation\"])\n implementationSource = kwargs.get(\"implementationCodes\", \"reference\")\n #\n self.__kwargs = kwargs\n #\n # Preserve and reuse the module instances if caching is enabled\n self.__moduleCache = {}\n #\n self.__methodD = self.__getMethodInfo(implementationSource=implementationSource, methodCodes=methodCodes)\n logger.debug(\"Method index %r\", self.__methodD.items())\n
"},{"location":"api_reference/DictMethodRunner/#mmcif.api.DictMethodRunner.DictMethodRunner.apply","title":"apply(self, dataContainer)
","text":"Apply category, attribute and block level dictionary methods on the input data container.
Source code in mmcif/api/DictMethodRunner.py
def apply(self, dataContainer):\n \"\"\"Apply category, attribute and block level dictionary methods on the input data container.\"\"\"\n kwargs = self.__kwargs\n mTupL = self.__getCategoryMethods()\n logger.debug(\"Category methods %r\", mTupL)\n for catName, _, methodPath, _ in mTupL:\n self.__invokeCategoryMethod(methodPath, dataContainer, catName, **kwargs)\n\n mTupL = self.__getAttributeMethods()\n logger.debug(\"Attribute methods %r\", mTupL)\n for catName, atName, methodPath, _ in mTupL:\n self.__invokeAttributeMethod(methodPath, dataContainer, catName, atName, **kwargs)\n\n mTupL = self.__getDatablockMethods()\n logger.debug(\"Datablock methods %r\", mTupL)\n for _, _, methodPath, _ in mTupL:\n self.__invokeDatablockMethod(methodPath, dataContainer, dataContainer.getName(), **kwargs)\n\n return True\n
"},{"location":"api_reference/DictionaryApi/","title":"DictionaryApi","text":"Source code in mmcif/api/DictionaryApi.py
class DictionaryApi(object):\n def __init__(self, containerList, consolidate=True, expandItemLinked=False, replaceDefinition=False, **kwargs):\n \"\"\"Return an instance of the mmCIF dictionary API.\n\n Args:\n containerList (list): list of definition or data containers holding dictionary content\n consolidate (bool, optional): consolidate dictionary attributes within a single definition. Defaults to True.\n expandItemLinked (bool, optional): distribute item and item linked attributes defined for the parent\n to child definitions. Defaults to False.\n replaceDefinition (bool, optional): when consolidating definitions in the case of multiple occurences of the same definition,\n attributes from the latter occurences replace prior definitions content. Defaults to False.\n \"\"\"\n _ = kwargs\n #\n self.__containerList = containerList\n self.__replaceDefinition = replaceDefinition\n #\n if consolidate:\n self.__consolidateDefinitions()\n #\n if expandItemLinked:\n self.__expandLoopedDefinitions()\n\n self.__fullIndex = OrderedDict()\n\n # ---\n #\n # Map category name to the unique list of attributes\n self.__catNameIndex = OrderedDict()\n # Map category name to the unique list of item names\n self.__catNameItemIndex = OrderedDict()\n # Full unique list of item names -\n self.__itemNameList = []\n #\n # Map dictionary objects names to definition containers -\n self.__definitionIndex = OrderedDict()\n #\n # data section/objects of the dictionary by category name -\n self.__dataIndex = OrderedDict()\n #\n # Map of types id->(regex,primitive_type)\n self.__typesDict = OrderedDict()\n #\n self.__enumD = {\n \"ENUMERATION_VALUE\": (\"item_enumeration\", \"value\"),\n \"ENUMERATION_DETAIL\": (\"item_enumeration\", \"detail\"),\n \"ENUMERATION_TYPE_UNITS\": (\"item_enumeration\", \"rcsb_type_units_code\"),\n \"ENUMERATION_DETAIL_BRIEF\": (\"item_enumeration\", \"rcsb_detail_brief\"),\n \"ENUMERATION_TUPLE\": (\"item_enumeration\", None),\n \"ITEM_LINKED_PARENT\": (\"item_linked\", \"parent_name\"),\n \"ITEM_LINKED_CHILD\": (\"item_linked\", \"child_name\"),\n \"DATA_TYPE_CODE\": (\"item_type\", \"code\"),\n \"DATA_TYPE_REGEX\": (\"item_type_list\", \"construct\"),\n \"DATA_TYPE_PRIMITIVE\": (\"item_type_list\", \"primitive_code\"),\n \"ITEM_NAME\": (\"item\", \"name\"),\n \"ITEM_CATEGORY_ID\": (\"item\", \"category_id\"),\n \"ITEM_MANDATORY_CODE\": (\"item\", \"mandatory_code\"),\n \"ITEM_DESCRIPTION\": (\"item_description\", \"description\"),\n \"ITEM_UNITS\": (\"item_units\", \"code\"),\n \"ITEM_DEFAULT_VALUE\": (\"item_default\", \"value\"),\n \"ITEM_EXAMPLE_CASE\": (\"item_examples\", \"case\"),\n \"ITEM_EXAMPLE_DETAIL\": (\"item_examples\", \"detail\"),\n \"ITEM_RANGE_MAXIMUM\": (\"item_range\", \"maximum\"),\n \"ITEM_RANGE_MINIMUM\": (\"item_range\", \"minimum\"),\n \"CATEGORY_KEY_ITEMS\": (\"category_key\", \"name\"),\n \"CATEGORY_EXAMPLE_CASE\": (\"category_examples\", \"case\"),\n \"CATEGORY_EXAMPLE_DETAIL\": (\"category_examples\", \"detail\"),\n \"CATEGORY_MANDATORY_CODE\": (\"category\", \"mandatory_code\"),\n \"CATEGORY_DESCRIPTION\": (\"category\", \"description\"),\n \"CATEGORY_NX_MAPPING_DETAILS\": (\"category\", \"NX_mapping_details\"),\n #\n \"DATA_TYPE_CODE_NDB\": (\"ndb_item_type\", \"code\"),\n \"ITEM_DESCRIPTION_NDB\": (\"ndb_item_description\", \"description\"),\n \"ENUMERATION_VALUE_NDB\": (\"ndb_item_enumeration\", \"value\"),\n \"ENUMERATION_DETAIL_NDB\": (\"ndb_item_enumeration\", \"detail\"),\n \"ITEM_MANDATORY_CODE_NDB\": (\"ndb_item\", \"mandatory_code\"),\n \"ITEM_EXAMPLE_CASE_NDB\": (\"ndb_item_examples\", \"case\"),\n \"ITEM_EXAMPLE_DETAIL_NDB\": (\"ndb_item_examples\", \"detail\"),\n \"ITEM_RANGE_MAXIMUM_NDB\": (\"ndb_item_range\", \"maximum\"),\n \"ITEM_RANGE_MINIMUM_NDB\": (\"ndb_item_range\", \"minimum\"),\n \"CATEGORY_EXAMPLE_CASE_NDB\": (\"ndb_category_examples\", \"case\"),\n \"CATEGORY_EXAMPLE_DETAIL_NDB\": (\"ndb_category_examples\", \"detail\"),\n \"CATEGORY_DESCRIPTION_NDB\": (\"ndb_category_description\", \"description\"),\n #\n \"DATA_TYPE_CODE_PDBX\": (\"pdbx_item_type\", \"code\"),\n \"ITEM_DESCRIPTION_PDBX\": (\"pdbx_item_description\", \"description\"),\n \"ENUMERATION_VALUE_PDBX\": (\"pdbx_item_enumeration\", \"value\"),\n \"ENUMERATION_DETAIL_PDBX\": (\"pdbx_item_enumeration\", \"detail\"),\n \"ENUMERATION_TYPE_UNITS_PDBX\": (\"pdbx_item_enumeration\", \"type_units_code\"),\n \"ENUMERATION_DETAIL_BRIEF_PDBX\": (\"pdbx_item_enumeration\", \"detail_brief\"),\n \"ITEM_MANDATORY_CODE_PDBX\": (\"pdbx_item\", \"mandatory_code\"),\n \"ITEM_EXAMPLE_CASE_PDBX\": (\"pdbx_item_examples\", \"case\"),\n \"ITEM_EXAMPLE_DETAIL_PDBX\": (\"pdbx_item_examples\", \"detail\"),\n \"ITEM_RANGE_MAXIMUM_PDBX\": (\"pdbx_item_range\", \"maximum\"),\n \"ITEM_RANGE_MINIMUM_PDBX\": (\"pdbx_item_range\", \"minimum\"),\n \"CATEGORY_EXAMPLE_CASE_PDBX\": (\"pdbx_category_examples\", \"case\"),\n \"CATEGORY_EXAMPLE_DETAIL_PDBX\": (\"pdbx_category_examples\", \"detail\"),\n \"CATEGORY_DESCRIPTION_PDBX\": (\"pdbx_category_description\", \"description\"),\n #\n \"CATEGORY_CONTEXT\": (\"pdbx_category_context\", \"type\"),\n \"CATEGORY_GROUP\": (\"category_group\", \"id\"),\n \"ITEM_CONTEXT\": (\"pdbx_item_context\", \"type\"),\n \"ENUMERATION_CLOSED_FLAG\": (\"pdbx_item_enumeration_details\", \"closed_flag\"),\n #\n \"ITEM_RELATED_FUNCTION_CODE\": (\"item_related\", \"function_code\"),\n \"ITEM_RELATED_RELATED_NAME\": (\"item_related\", \"related_name\"),\n \"ITEM_ALIAS_ALIAS_NAME\": (\"item_aliases\", \"alias_name\"),\n \"ITEM_ALIAS_DICTIONARY\": (\"item_aliases\", \"dictionary\"),\n \"ITEM_ALIAS_VERSION\": (\"item_aliases\", \"version\"),\n \"ITEM_DEPENDENT_DEPENDENT_NAME\": (\"item_dependent\", \"dependent_name\"),\n \"ITEM_SUB_CATEGORY_ID\": (\"item_sub_category\", \"id\"),\n \"ITEM_SUB_CATEGORY_LABEL\": (\"item_sub_category\", \"pdbx_label\"),\n \"ITEM_TYPE_CONDITIONS_CODE\": (\"item_type_conditions\", \"code\"),\n #\n \"ITEM_VALUE_CONDITION_DEPENDENT_NAME\": (\"pdbx_item_value_condition\", \"dependent_item_name\"),\n #\n \"ITEM_LINKED_PDBX_ID\": (\"pdbx_item_linked\", \"id\"),\n \"ITEM_LINKED_PDBX_CONDITION_ID\": (\"pdbx_item_linked\", \"condition_id\"),\n \"ITEM_LINKED_PDBX_PARENT_NAME\": (\"pdbx_item_linked\", \"parent_name\"),\n \"ITEM_LINKED_PDBX_CHILD_NAME\": (\"pdbx_item_linked\", \"child_name\"),\n #\n \"ITEM_LINKED_PDBX_CONDITION_CHILD_NAME\": (\"pdbx_item_linked\", \"condition_child_name\"),\n \"ITEM_LINKED_PDBX_CONDITION_CHILD_VALUE\": (\"pdbx_item_linked\", \"condition_child_value\"),\n \"ITEM_LINKED_PDBX_CONDITION_CHILD_TARGET_NAME\": (\"pdbx_item_linked\", \"condition_child_target_name\"),\n \"ITEM_LINKED_PDBX_CONDITION_CHILD_CMP_OP\": (\"pdbx_item_linked\", \"condition_child_cmp_op\"),\n \"ITEM_LINKED_PDBX_CONDITION_LOG_OP\": (\"pdbx_item_linked\", \"condition_log_op\"),\n }\n #\n self.__methodDict = OrderedDict()\n self.__methodIndex = OrderedDict()\n #\n self.__makeIndex()\n self.__getMethods()\n #\n self.__fullParentD, self.__fullChildD = self.__makeFullParentChildDictionaries()\n #\n #\n self.__dataBlockDictList = []\n self.__dictionaryDictList = []\n #\n self.__subCategoryDict = OrderedDict()\n self.__categoryGroupDict = OrderedDict()\n self.__groupIndex = False\n self.__groupChildIndex = OrderedDict()\n #\n # Data sections -\n #\n self.__dictionaryHistoryList = []\n self.__itemUnitsDict = OrderedDict()\n self.__itemUnitsConversionList = []\n self.__itemLinkedGroupDict = OrderedDict()\n self.__itemLinkedGroupItemDict = OrderedDict()\n #\n self.__dictionaryIncludeDict = OrderedDict()\n self.__categoryIncludeDict = OrderedDict()\n self.__itemIncludeDict = OrderedDict()\n #\n self.__dictionaryComponentList = []\n self.__dictionaryComponentHistoryDict = OrderedDict()\n #\n self.__itemValueConditionDict = OrderedDict()\n self.__compOpDict = OrderedDict()\n #\n self.__getDataSections()\n #\n\n def testCache(self):\n return len(self.__containerList) > 0\n\n #\n # Methods for data sections --\n #\n\n def getItemValueConditionDict(self):\n try:\n return self.__itemValueConditionDict if self.__itemValueConditionDict else {}\n except Exception:\n return {}\n\n def getComparisonOperators(self):\n try:\n return list(self.__compOpDict.keys()) if self.__compOpDict else []\n except Exception:\n return []\n\n def getComparisonOperatorDict(self):\n try:\n return self.__compOpDict if self.__compOpDict else {}\n except Exception:\n return {}\n\n #\n def getDictionaryVersion(self):\n try:\n return \",\".join([str(tD[\"version\"]) for tD in self.__dictionaryDictList])\n except Exception:\n return None\n\n def getDictionaryTitle(self):\n try:\n return \",\".join([str(tD[\"title\"]) for tD in self.__dictionaryDictList])\n except Exception:\n return None\n\n def getDictionaryUpdate(self, order=\"reverse\"):\n \"\"\"Get details from the first/last history element.\"\"\"\n try:\n if order == \"reverse\":\n tD = self.__dictionaryHistoryList[-1]\n else:\n tD = self.__dictionaryHistoryList[0]\n\n return tD[\"update\"]\n\n except Exception:\n return None\n\n def getDictionaryRevisionCount(self):\n \"\"\"Get the count of revision history records.\"\"\"\n try:\n return len(self.__dictionaryHistoryList)\n except Exception:\n return 0\n\n def getDictionaryHistory(self, order=\"reverse\"):\n \"\"\"Returns the revision history as a list of tuples [(version,update,revisionText,dictionary),...]\"\"\"\n oL = []\n try:\n if order == \"reverse\":\n for tD in reversed(self.__dictionaryHistoryList):\n oL.append((tD[\"version\"], tD[\"update\"], tD[\"revision\"], tD[\"dictionary\"]))\n else:\n for tD in self.__dictionaryHistoryList:\n oL.append((tD[\"version\"], tD[\"update\"], tD[\"revision\"], tD[\"dictionary\"]))\n except Exception:\n pass\n return oL\n\n #\n def getDictionaryComponentDetails(self):\n \"\"\"Returns the component dictionary list as tuples [(version,title,dictionary_component_id),...]\"\"\"\n oL = []\n try:\n for tD in self.__dictionaryComponentList:\n oL.append((tD[\"version\"], tD[\"title\"], tD[\"dictionary_component_id\"]))\n except Exception:\n pass\n return oL\n\n def getDictionaryComponentCount(self):\n \"\"\"Get the count of dictionary components.\"\"\"\n try:\n return len(self.__dictionaryComponentList)\n except Exception:\n return 0\n\n def getDictionaryComponents(self):\n \"\"\"Get the list of dictionary components.\"\"\"\n try:\n return list(self.__dictionaryComponentHistoryDict.keys())\n except Exception:\n return []\n\n def getDictionaryComponentHistory(self, dictionaryComponentId, order=\"reverse\"):\n \"\"\"Returns the revision history as a list of tuples [(version,update,revisionText,dictionary),...]\"\"\"\n oL = []\n try:\n if order == \"reverse\":\n for tD in reversed(self.__dictionaryComponentHistoryDict[dictionaryComponentId]):\n oL.append((tD[\"version\"], tD[\"update\"], tD[\"revision\"], tD[\"dictionary_component_id\"]))\n else:\n for tD in self.__dictionaryComponentHistoryDict[dictionaryComponentId]:\n oL.append((tD[\"version\"], tD[\"update\"], tD[\"revision\"], tD[\"dictionary_component_id\"]))\n except Exception:\n pass\n return oL\n\n #\n def __makeCategoryGroupIndex(self):\n catNameList = self.getCategoryList()\n # add categories in group to self.__categoryGroupDict[<groupName>]['categories']\n for catName in catNameList:\n groupNameList = self.getCategoryGroupList(catName)\n # logger.info(\"Category %s group list %r\\n\" % (catName,groupNameList))\n for groupName in groupNameList:\n if groupName not in self.__categoryGroupDict:\n # handle undefined category group ?\n tD = OrderedDict()\n tD[\"description\"] = None\n tD[\"parent_id\"] = None\n tD[\"categories\"] = []\n self.__categoryGroupDict[groupName] = tD\n self.__categoryGroupDict[groupName][\"categories\"].append(catName)\n #\n for groupName in self.__categoryGroupDict:\n # logger.info(\"Group %s count %r\\n\" % (groupName, len(self.__categoryGroupDict[groupName]['categories'])))\n if \"categories\" in self.__categoryGroupDict[groupName]:\n self.__categoryGroupDict[groupName][\"categories\"].sort()\n self.__groupChildIndex = OrderedDict()\n for groupName, gD in self.__categoryGroupDict.items():\n if \"parent\" in gD:\n self.__groupChildIndex.setdefault(gD[\"parent\"], []).append(groupName)\n #\n self.__groupIndex = True\n\n #\n def getCategoryGroupDescription(self, groupName):\n try:\n return self.__categoryGroupDict[groupName][\"description\"]\n except Exception:\n return None\n\n def getCategoryGroupParent(self, groupName):\n try:\n return self.__categoryGroupDict[groupName][\"parent_id\"]\n except Exception:\n return None\n\n def getCategoryGroupChildGroups(self, parentGroupName):\n try:\n return self.__groupChildIndex[parentGroupName]\n except Exception:\n return []\n\n def getCategoryGroupCategories(self, groupName, followChildren=False):\n try:\n if not self.__groupIndex:\n self.__makeCategoryGroupIndex()\n #\n if followChildren:\n cL = []\n grpL = [groupName]\n grpL.extend(self.getCategoryGroupChildGroups(groupName))\n for grp in grpL:\n cL.extend(self.__categoryGroupDict[grp][\"categories\"] if grp in self.__categoryGroupDict else [])\n return sorted(set(cL))\n else:\n return self.__categoryGroupDict[groupName][\"categories\"] if groupName in self.__categoryGroupDict else []\n #\n except Exception:\n logger.exception(\"DictionaryApi.getCategoryGroupCategories failed for group %s\", groupName)\n return []\n\n def getCategoryGroups(self):\n try:\n kL = self.__categoryGroupDict.keys()\n return kL\n except Exception:\n return []\n\n #\n def getParentCategories(self, categoryName):\n itemNameList = self.getItemNameList(categoryName)\n parentCategories = set()\n for itemName in itemNameList:\n categoryName = CifName.categoryPart(itemName)\n attributeName = CifName.attributePart(itemName)\n parentItemList = self.getFullParentList(categoryName, attributeName)\n for parentItem in parentItemList:\n parentCategoryName = CifName.categoryPart(parentItem)\n parentCategories.add(parentCategoryName)\n return list(parentCategories)\n\n def getChildCategories(self, categoryName):\n itemNameList = self.getItemNameList(categoryName)\n childCategories = set()\n for itemName in itemNameList:\n categoryName = CifName.categoryPart(itemName)\n attributeName = CifName.attributePart(itemName)\n childItemList = self.getFullChildList(categoryName, attributeName)\n for childItem in childItemList:\n childCategoryName = CifName.categoryPart(childItem)\n childCategories.add(childCategoryName)\n return list(childCategories)\n\n #\n def definitionExists(self, definitionName):\n if definitionName in self.__definitionIndex:\n return True\n return False\n\n def getTypeConditionsCode(self, category, attribute):\n return self.__get(\"ITEM_TYPE_CONDITIONS_CODE\", category, attribute)\n\n def getItemDependentNameList(self, category, attribute):\n return self.__getList(\"ITEM_DEPENDENT_DEPENDENT_NAME\", category, attribute)\n\n def getItemValueConditionDependentList(self, category, attribute):\n return self.__getList(\"ITEM_VALUE_CONDITION_DEPENDENT_NAME\", category, attribute)\n\n def getItemSubCategoryIdList(self, category, attribute):\n return self.__getList(\"ITEM_SUB_CATEGORY_ID\", category, attribute)\n\n def getItemSubCategoryLabelList(self, category, attribute):\n return self.__getList(\"ITEM_SUB_CATEGORY_LABEL\", category, attribute)\n\n def getItemSubCategoryList(self, category, attribute):\n aL = []\n\n itemName = CifName.itemName(category, attribute)\n\n obL = self.__definitionIndex[itemName] if itemName in self.__definitionIndex else None\n for ob in obL:\n tObj = ob.getObj(self.__enumD[\"ITEM_SUB_CATEGORY_ID\"][0])\n if tObj is not None:\n atId = self.__enumD[\"ITEM_SUB_CATEGORY_ID\"][1]\n atLabel = self.__enumD[\"ITEM_SUB_CATEGORY_LABEL\"][1]\n for row in tObj.getRowList():\n # logger.info(\"subcategories for %s row is %r\" % (itemName, row))\n idVal = row[tObj.getIndex(atId)] if tObj.hasAttribute(atId) else None\n labVal = row[tObj.getIndex(atLabel)] if tObj.hasAttribute(atLabel) else None\n aL.append((idVal, labVal))\n return aL\n\n def getItemAliasList(self, category, attribute):\n aNL = self.__getListAll(\"ITEM_ALIAS_ALIAS_NAME\", category, attribute)\n aDL = self.__getListAll(\"ITEM_ALIAS_DICTIONARY\", category, attribute)\n aVL = self.__getListAll(\"ITEM_ALIAS_VERSION\", category, attribute)\n aL = []\n for aN, aD, aV in zip(aNL, aDL, aVL):\n aL.append((aN, aD, aV))\n return aL\n\n def getEnumListWithDetail(self, category, attribute):\n eVL = self.__getListAll(\"ENUMERATION_VALUE\", category, attribute)\n eDL = self.__getListAll(\"ENUMERATION_DETAIL\", category, attribute)\n rL = []\n dD = {}\n if len(eVL) == len(eDL):\n for eV, eD in zip(eVL, eDL):\n if not eD or eD in [\".\", \"?\"]:\n dD[eV] = (eV, None)\n else:\n dD[eV] = (eV, eD)\n else:\n for eV in eVL:\n dD[eV] = (eV, None)\n #\n for ky in sorted(dD.keys()):\n rL.append(dD[ky])\n return rL\n\n def getEnumListAltWithFullDetails(self, category, attribute):\n rL = []\n dD = {}\n try:\n eVL = self.__getListAll(\"ENUMERATION_VALUE_PDBX\", category, attribute)\n eDL = self.__getListAll(\"ENUMERATION_DETAIL_PDBX\", category, attribute)\n eBL = self.__getListAll(\"ENUMERATION_DETAIL_BRIEF_PDBX\", category, attribute)\n eUL = self.__getListAll(\"ENUMERATION_TYPE_UNITS_PDBX\", category, attribute)\n rL = []\n dD = {}\n for eV, eD, eB, eU in zip_longest(eVL, eDL, eBL, eUL):\n oL = [v if v and v not in [\".\", \"?\"] else None for v in [eV, eD, eB, eU]]\n dD[eV] = tuple(oL)\n for ky in sorted(dD.keys()):\n rL.append(dD[ky])\n if rL:\n return rL\n #\n eVL = self.__getListAll(\"ENUMERATION_VALUE\", category, attribute)\n eDL = self.__getListAll(\"ENUMERATION_DETAIL\", category, attribute)\n eBL = self.__getListAll(\"ENUMERATION_DETAIL_BRIEF\", category, attribute)\n eUL = self.__getListAll(\"ENUMERATION_TYPE_UNITS\", category, attribute)\n rL = []\n dD = {}\n for eV, eD, eB, eU in zip_longest(eVL, eDL, eBL, eUL):\n oL = [v if v and v not in [\".\", \"?\"] else None for v in [eV, eD, eB, eU]]\n dD[eV] = tuple(oL)\n for ky in sorted(dD.keys()):\n rL.append(dD[ky])\n except Exception as e:\n logger.exception(\"Failing dD %r rL %r with %s\", dD, rL, str(e))\n return rL\n\n def getEnumListWithFullDetails(self, category, attribute):\n rL = []\n dD = {}\n try:\n eVL = self.__getListAll(\"ENUMERATION_VALUE\", category, attribute)\n eDL = self.__getListAll(\"ENUMERATION_DETAIL\", category, attribute)\n eBL = self.__getListAll(\"ENUMERATION_DETAIL_BRIEF\", category, attribute)\n eUL = self.__getListAll(\"ENUMERATION_TYPE_UNITS\", category, attribute)\n #\n for eV, eD, eB, eU in zip_longest(eVL, eDL, eBL, eUL):\n oL = [v if v and v not in [\".\", \"?\"] else None for v in [eV, eD, eB, eU]]\n dD[eV] = tuple(oL)\n for ky in sorted(dD.keys()):\n rL.append(dD[ky])\n except Exception as e:\n logger.info(\"eVL %r\", eVL)\n logger.info(\"eDL %r\", eDL)\n logger.info(\"eBL %r\", eBL)\n logger.info(\"eUL %r\", eUL)\n logger.exception(\"Failing category %s attribute %s dD %r rL %r with %s\", category, attribute, dD, rL, str(e))\n return rL\n\n def getEnumListAltWithDetail(self, category, attribute):\n eVL = self.__getListAll(\"ENUMERATION_VALUE_PDBX\", category, attribute)\n eDL = self.__getListAll(\"ENUMERATION_DETAIL_PDBX\", category, attribute)\n\n rL = []\n dD = {}\n if len(eVL) == len(eDL):\n for eV, eD in zip(eVL, eDL):\n if not eD or eD in [\".\", \"?\"]:\n dD[eV] = (eV, None)\n else:\n dD[eV] = (eV, eD)\n else:\n for eV in eVL:\n dD[eV] = (eV, None)\n #\n for ky in sorted(dD.keys()):\n rL.append(dD[ky])\n #\n if not rL:\n return self.getEnumListWithDetail(category, attribute)\n else:\n return rL\n\n def getItemRelatedList(self, category, attribute):\n rNL = self.__getListAll(\"ITEM_RELATED_RELATED_NAME\", category, attribute)\n rFL = self.__getListAll(\"ITEM_RELATED_FUNCTION_CODE\", category, attribute)\n rL = []\n for rN, rF in zip(rNL, rFL):\n rL.append((rN, rF))\n return rL\n\n def getTypeCode(self, category, attribute):\n return self.__get(\"DATA_TYPE_CODE\", category, attribute, followAncestors=True)\n\n def getTypeCodeAlt(self, category, attribute, fallBack=True):\n v = self.getTypeCodePdbx(category, attribute)\n if v is None:\n v = self.getTypeCodeNdb(category, attribute)\n if fallBack and v is None:\n v = self.getTypeCode(category, attribute)\n return v\n\n def getTypeCodeNdb(self, category, attribute):\n return self.__get(\"DATA_TYPE_CODE_NDB\", category, attribute, followAncestors=False)\n\n def getTypeCodePdbx(self, category, attribute):\n return self.__get(\"DATA_TYPE_CODE_PDBX\", category, attribute, followAncestors=False)\n\n def getDefaultValue(self, category, attribute):\n return self.__get(\"ITEM_DEFAULT_VALUE\", category, attribute)\n\n def getMandatoryCode(self, category, attribute):\n return self.__get(\"ITEM_MANDATORY_CODE\", category, attribute)\n\n def getMandatoryCodeAlt(self, category, attribute, fallBack=True):\n v = self.getMandatoryCodePdbx(category, attribute)\n if v is None:\n v = self.getMandatoryCodeNdb(category, attribute)\n if fallBack and v is None:\n v = self.getMandatoryCode(category, attribute)\n return v\n\n def getMandatoryCodeNdb(self, category, attribute):\n return self.__get(\"ITEM_MANDATORY_CODE_NDB\", category, attribute)\n\n def getMandatoryCodePdbx(self, category, attribute):\n return self.__get(\"ITEM_MANDATORY_CODE_PDBX\", category, attribute)\n\n def getTypeRegex(self, category, attribute):\n code = self.getTypeCode(category, attribute)\n if code in self.__typesDict:\n return self.__typesDict[code][1]\n return None\n\n def getTypeRegexAlt(self, category, attribute, fallBack=True):\n v = self.getTypeRegexPdbx(category, attribute)\n if v is None:\n v = self.getTypeRegexNdb(category, attribute)\n if fallBack and v is None:\n v = self.getTypeRegex(category, attribute)\n return v\n\n def getTypeRegexNdb(self, category, attribute):\n code = self.getTypeCodeNdb(category, attribute)\n if code in self.__typesDict:\n return self.__typesDict[code][1]\n return None\n\n def getTypeRegexPdbx(self, category, attribute):\n code = self.getTypeCodePdbx(category, attribute)\n if code in self.__typesDict:\n return self.__typesDict[code][1]\n return None\n\n def getTypePrimitive(self, category, attribute):\n code = self.getTypeCode(category, attribute)\n if code in self.__typesDict:\n return self.__typesDict[code][0]\n return None\n\n def getTypeDetail(self, category, attribute):\n code = self.getTypeCode(category, attribute)\n if code in self.__typesDict:\n return self.__typesDict[code][2]\n return None\n\n def getContextList(self, category, attribute):\n return self.__getList(\"ITEM_CONTEXT\", category, attribute)\n\n def getCategoryContextList(self, category):\n return self.__getList(\"CATEGORY_CONTEXT\", category, attribute=None)\n\n def getEnumList(self, category, attribute, sortFlag=True):\n if sortFlag:\n return self.__getList(\"ENUMERATION_VALUE\", category, attribute)\n else:\n return self.__getListAll(\"ENUMERATION_VALUE\", category, attribute)\n\n def getEnumListAlt(self, category, attribute, fallBack=True, sortFlag=True):\n vL = self.getEnumListPdbx(category, attribute, sortFlag=sortFlag)\n if not vL:\n vL = self.getEnumListNdb(category, attribute, sortFlag=sortFlag)\n if fallBack and not vL:\n vL = self.getEnumList(category, attribute, sortFlag=sortFlag)\n return vL\n\n def getEnumListNdb(self, category, attribute, sortFlag=True):\n if sortFlag:\n return self.__getList(\"ENUMERATION_VALUE_NDB\", category, attribute)\n else:\n return self.__getListAll(\"ENUMERATION_VALUE_NDB\", category, attribute)\n\n def getEnumListPdbx(self, category, attribute, sortFlag=True):\n if sortFlag:\n return self.__getList(\"ENUMERATION_VALUE_PDBX\", category, attribute)\n else:\n return self.__getListAll(\"ENUMERATION_VALUE_PDBX\", category, attribute)\n\n def isEnumerated(self, category, attribute):\n return len(self.__getList(\"ENUMERATION_VALUE\", category, attribute)) > 0\n\n def isEnumeratedAlt(self, category, attribute, fallBack=True):\n eC = len(self.__getList(\"ENUMERATION_VALUE_PDBX\", category, attribute))\n if eC == 0:\n eC = len(self.__getList(\"ENUMERATION_VALUE_NDB\", category, attribute))\n if fallBack and (eC == 0):\n eC = len(self.__getList(\"ENUMERATION_VALUE\", category, attribute))\n return eC > 0\n\n def getEnumerationClosedFlag(self, category, attribute):\n return self.__get(\"ENUMERATION_CLOSED_FLAG\", category, attribute)\n\n def getUltimateParent(self, category, attribute):\n \"\"\"Return the first ultimate parent item for the input item.\"\"\"\n # pL=self.__getList('ITEM_LINKED_PARENT',category,attribute)\n pL = self.getFullParentList(category, attribute)\n itemName = CifName.itemName(category, attribute)\n while pL and (pL[0] != itemName):\n attN = CifName.attributePart(pL[0])\n catN = CifName.categoryPart(pL[0])\n itemName = pL[0]\n pL = self.getFullParentList(catN, attN)\n # pL=self.__getList('ITEM_LINKED_PARENT',catN,attN)\n return itemName\n\n def getParentList(self, category, attribute, stripSelfParent=False):\n if stripSelfParent:\n itemName = CifName.itemName(category, attribute)\n pL = self.__getList(\"ITEM_LINKED_PARENT\", category, attribute)\n if pL:\n try:\n pL.remove(itemName)\n except Exception:\n pass\n return pL\n else:\n return self.__getList(\"ITEM_LINKED_PARENT\", category, attribute)\n\n def getChildList(self, category, attribute):\n return self.__getList(\"ITEM_LINKED_CHILD\", category, attribute)\n\n def getFullChildList(self, category, attribute):\n try:\n itemName = CifName.itemName(category, attribute)\n return self.__fullChildD[itemName]\n except Exception:\n return []\n\n def getFullDescendentList(self, category, attribute):\n itemNameL = []\n try:\n itemName = CifName.itemName(category, attribute)\n itemNameL = self.__fullChildD[itemName] if itemName in self.__fullChildD else []\n itemNameL = list(set(itemNameL))\n if itemNameL:\n begLen = 0\n endLen = 1\n #\n while endLen > begLen:\n begLen = len(itemNameL)\n for itemName in itemNameL:\n if itemName in self.__fullChildD:\n itemNameL.extend(self.__fullChildD[itemName])\n itemNameL = list(set(itemNameL))\n endLen = len(itemNameL)\n\n except Exception as e:\n logger.exception(\"Failing for %s %s with %s\", category, attribute, str(e))\n return itemNameL\n\n def getFullParentList(self, category, attribute, stripSelfParent=False):\n try:\n itemName = CifName.itemName(category, attribute)\n pL = self.__fullParentD[itemName]\n if stripSelfParent:\n if pL:\n try:\n pL.remove(itemName)\n except Exception:\n pass\n return pL\n else:\n return pL\n except Exception:\n return []\n\n def getUnits(self, category, attribute):\n return self.__get(\"ITEM_UNITS\", category, attribute)\n\n def getImplicitList(self):\n iL = []\n for name, dL in self.__definitionIndex.items():\n for dD in dL:\n dType = dD.getType()\n if dType == \"definition\" and dD.isAttribute():\n catN = CifName.categoryPart(name)\n attN = CifName.attributePart(name)\n if self.__get(\"ITEM_MANDATORY_CODE\", catN, attN) == \"implicit\":\n if name not in iL:\n iL.append(name)\n return iL\n\n def getDescription(self, category, attribute):\n return self.__get(\"ITEM_DESCRIPTION\", category, attribute)\n\n def getDescriptionAlt(self, category, attribute, fallBack=True):\n v = self.getDescriptionPdbx(category, attribute)\n if v is None:\n v = self.getDescriptionNdb(category, attribute)\n if fallBack and v is None:\n v = self.getDescription(category, attribute)\n return v\n\n def getDescriptionNdb(self, category, attribute):\n return self.__get(\"ITEM_DESCRIPTION_NDB\", category, attribute)\n\n def getDescriptionPdbx(self, category, attribute):\n return self.__get(\"ITEM_DESCRIPTION_PDBX\", category, attribute)\n\n def getExampleList(self, category, attribute):\n exCL = self.__getListAll(\"ITEM_EXAMPLE_CASE\", category, attribute)\n exDL = self.__getListAll(\"ITEM_EXAMPLE_DETAIL\", category, attribute)\n exL = []\n if len(exCL) == len(exDL):\n for exC, exD in zip(exCL, exDL):\n exL.append((exC, exD))\n else:\n for exC in exCL:\n exL.append((exC, None))\n return exL\n\n def getExampleListAlt(self, category, attribute, fallBack=True):\n vL = self.getExampleListPdbx(category, attribute)\n if not vL:\n vL = self.getExampleListNdb(category, attribute)\n if fallBack and not vL:\n vL = self.getExampleList(category, attribute)\n return vL\n\n def getExampleListNdb(self, category, attribute):\n exCL = self.__getListAll(\"ITEM_EXAMPLE_CASE_NDB\", category, attribute)\n exDL = self.__getListAll(\"ITEM_EXAMPLE_DETAIL_NDB\", category, attribute)\n exL = []\n if len(exCL) == len(exDL):\n for exC, exD in zip(exCL, exDL):\n exL.append((exC, exD))\n else:\n for exC in exCL:\n exL.append((exC, None))\n return exL\n\n def getExampleListPdbx(self, category, attribute):\n exCL = self.__getListAll(\"ITEM_EXAMPLE_CASE_PDBX\", category, attribute)\n exDL = self.__getListAll(\"ITEM_EXAMPLE_DETAIL_PDBX\", category, attribute)\n exL = []\n if len(exCL) == len(exDL):\n for exC, exD in zip(exCL, exDL):\n exL.append((exC, exD))\n else:\n for exC in exCL:\n exL.append((exC, None))\n return exL\n\n def getBoundaryList(self, category, attribute):\n minL = self.__getListAll(\"ITEM_RANGE_MINIMUM\", category, attribute)\n maxL = self.__getListAll(\"ITEM_RANGE_MAXIMUM\", category, attribute)\n bL = []\n for vMin, vMax in zip(minL, maxL):\n bL.append((vMin, vMax))\n return bL\n\n def getBoundaryListAlt(self, category, attribute, fallBack=True):\n vL = self.getBoundaryListPdbx(category, attribute)\n if not vL:\n vL = self.getBoundaryListNdb(category, attribute)\n if fallBack and not vL:\n vL = self.getBoundaryList(category, attribute)\n return vL\n\n def getBoundaryListNdb(self, category, attribute):\n minL = self.__getListAll(\"ITEM_RANGE_MINIMUM_NDB\", category, attribute)\n maxL = self.__getListAll(\"ITEM_RANGE_MAXIMUM_NDB\", category, attribute)\n bL = []\n for vMin, vMax in zip(minL, maxL):\n bL.append((vMin, vMax))\n #\n return bL\n\n def getBoundaryListPdbx(self, category, attribute):\n minL = self.__getListAll(\"ITEM_RANGE_MINIMUM_PDBX\", category, attribute)\n maxL = self.__getListAll(\"ITEM_RANGE_MAXIMUM_PDBX\", category, attribute)\n bL = []\n for vMin, vMax in zip(minL, maxL):\n bL.append((vMin, vMax))\n #\n return bL\n\n def getCategoryKeyList(self, category):\n return self.__getList(\"CATEGORY_KEY_ITEMS\", category, attribute=None)\n\n def getCategoryGroupList(self, category):\n return self.__getList(\"CATEGORY_GROUP\", category, attribute=None)\n\n def getCategoryMandatoryCode(self, category):\n return self.__get(\"CATEGORY_MANDATORY_CODE\", category, attribute=None)\n\n def getCategoryDescription(self, category):\n return self.__get(\"CATEGORY_DESCRIPTION\", category, attribute=None)\n\n def getCategoryNxMappingDetails(self, category):\n return self.__get(\"CATEGORY_NX_MAPPING_DETAILS\", category, attribute=None)\n\n def getCategoryDescriptionAlt(self, category, fallBack=True):\n v = self.getCategoryDescriptionPdbx(category)\n if v is None:\n v = self.getCategoryDescriptionNdb(category)\n if fallBack and v is None:\n v = self.getCategoryDescription(category)\n return v\n\n def getCategoryDescriptionNdb(self, category):\n val = self.__get(\"CATEGORY_DESCRIPTION_NDB\", category, attribute=None)\n return val\n\n def getCategoryDescriptionPdbx(self, category):\n val = self.__get(\"CATEGORY_DESCRIPTION_PDBX\", category, attribute=None)\n return val\n\n def getCategoryExampleList(self, category):\n exCL = self.__getListAll(\"CATEGORY_EXAMPLE_CASE\", category, attribute=None)\n exDL = self.__getListAll(\"CATEGORY_EXAMPLE_DETAIL\", category, attribute=None)\n exL = []\n if len(exCL) == len(exDL):\n for exC, exD in zip(exCL, exDL):\n exL.append((exC, exD))\n else:\n for exC in exCL:\n exL.append((exC, None))\n return exL\n\n def getCategoryExampleListAlt(self, category, fallBack=True):\n vL = self.getCategoryExampleListPdbx(category)\n if not vL:\n vL = self.getCategoryExampleListNdb(category)\n if fallBack and not vL:\n vL = self.getCategoryExampleList(category)\n return vL\n\n def getCategoryExampleListNdb(self, category):\n exCL = self.__getListAll(\"CATEGORY_EXAMPLE_CASE_NDB\", category, attribute=None)\n exDL = self.__getListAll(\"CATEGORY_EXAMPLE_DETAIL_NDB\", category, attribute=None)\n exL = []\n if len(exCL) == len(exDL):\n for exC, exD in zip(exCL, exDL):\n exL.append((exC, exD))\n else:\n for exC in exCL:\n exL.append((exC, None))\n return exL\n\n def getCategoryExampleListPdbx(self, category):\n exCL = self.__getListAll(\"CATEGORY_EXAMPLE_CASE_PDBX\", category, attribute=None)\n exDL = self.__getListAll(\"CATEGORY_EXAMPLE_DETAIL_PDBX\", category, attribute=None)\n exL = []\n if len(exCL) == len(exDL):\n for exC, exD in zip(exCL, exDL):\n exL.append((exC, exD))\n else:\n for exC in exCL:\n exL.append((exC, None))\n\n return exL\n\n def getParentDictionary(self):\n \"\"\"Create a dictionary of parents relations accross all definnitions\n as {child : [parent, parent,...]\n\n Exclude self parents.\n \"\"\"\n parentD = {}\n pAtN = self.__enumD[\"ITEM_LINKED_PARENT\"][1]\n cAtN = self.__enumD[\"ITEM_LINKED_CHILD\"][1]\n\n for dObj in self.__containerList:\n dc = dObj.getObj(self.__enumD[\"ITEM_LINKED_PARENT\"][0])\n if dc is not None:\n idxP = dc.getIndex(pAtN)\n idxC = dc.getIndex(cAtN)\n for row in dc.getRowList():\n pVal = row[idxP]\n cVal = row[idxC]\n if pVal == cVal:\n continue\n if cVal not in parentD:\n parentD[cVal] = []\n parentD[cVal].append(pVal)\n #\n return parentD\n\n def getItemLinkedConditions(self):\n \"\"\"Create a dictionary of conditional item link relationships.\n\n Returns:\n (dict): {{parent_name, child_name}: [{\"id\": , \"condition_id\": , \"condition_child_name\": , \"condition_child_value\": ,\n \"condition_child_cmp_op\": , \"condition_log_op\": ,}, {},...]}\n\n Example:\n ```text\n loop_\n _pdbx_item_linked.id\n _pdbx_item_linked.condition_id\n _pdbx_item_linked.parent_name\n _pdbx_item_linked.child_name\n #\n _pdbx_item_linked.condition_child_name\n _pdbx_item_linked.condition_child_value\n _pdbx_item_linked.condition_child_cmp_op\n _pdbx_item_linked.condition_child_target_name\n _pdbx_item_linked.condition_child_log_op\n 1 1 '_entity_poly_seq.num' '_atom_site.label_seq_id' '_atom_site.label_entity_id' . 'eq' '_entity.id' .\n 2 1 '_entity_poly_seq.num' '_atom_site.label_seq_id' '_entity.type' 'polymer' 'eq' . 'and'\n ```\n\n \"\"\"\n rD = OrderedDict()\n try:\n for ob in self.__containerList:\n if ob.getType() == \"data\":\n continue\n tl = ob.getObj(self.__enumD[\"ITEM_LINKED_PDBX_ID\"][0])\n if tl is not None:\n for row in tl.getRowList():\n if (\n tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_ID\"][1])\n and tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_ID\"][1])\n and tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CHILD_NAME\"][1])\n and tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_PARENT_NAME\"][1])\n ):\n tD = OrderedDict()\n tD[\"id\"] = row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_ID\"][1])]\n tD[\"condition_id\"] = row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_ID\"][1])]\n parentName = row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_PARENT_NAME\"][1])]\n childName = row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CHILD_NAME\"][1])]\n #\n tD[\"condition_child_name\"] = (\n row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_NAME\"][1])]\n if tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_NAME\"][1])\n else None\n )\n tD[\"condition_child_value\"] = (\n row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_VALUE\"][1])]\n if tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_VALUE\"][1])\n else None\n )\n tD[\"condition_child_cmp_op\"] = (\n row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_CMP_OP\"][1])]\n if tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_CMP_OP\"][1])\n else None\n )\n tD[\"condition_child_target_name\"] = (\n row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_TARGET_NAME\"][1])]\n if tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_TARGET_NAME\"][1])\n else None\n )\n tD[\"condition_log_op\"] = (\n 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\n )\n #\n rD.setdefault((parentName, childName), []).append(tD)\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n\n return rD\n\n def __makeFullParentChildDictionaries(self):\n \"\"\"Create a dictionaries of full parent/child relations accross all definnitions\n\n as fullParentD[child]=[parent,parent,...]\n and fullChildD[parent]=[child,child,...]\n\n Exclude self parents.\n \"\"\"\n fullParentD = {}\n fullChildD = {}\n pAtN = self.__enumD[\"ITEM_LINKED_PARENT\"][1]\n cAtN = self.__enumD[\"ITEM_LINKED_CHILD\"][1]\n\n for dObj in self.__containerList:\n # logger.info(\"\\n\\nSearching object %s\\n\" % dObj.getName())\n dc = dObj.getObj(self.__enumD[\"ITEM_LINKED_PARENT\"][0])\n if dc is not None:\n idxP = dc.getIndex(pAtN)\n idxC = dc.getIndex(cAtN)\n for row in dc.getRowList():\n pVal = row[idxP]\n cVal = row[idxC]\n # logger.info(\"%s found parent %s child %s \\n\" % (dObj.getName(),pVal,cVal))\n if pVal == cVal:\n continue\n if cVal not in fullParentD:\n fullParentD[cVal] = []\n fullParentD[cVal].append(pVal)\n #\n if pVal not in fullChildD:\n fullChildD[pVal] = []\n fullChildD[pVal].append(cVal)\n\n #\n return fullParentD, fullChildD\n\n #\n def __get(self, enumCode, category, attribute=None, followAncestors=False):\n \"\"\"Return the last occurrence of the input dictionary metadata. If the value\n for the input category/attribute is null/missing then optionally check for\n an ancestor value.\n \"\"\"\n v0 = self.__getValue(enumCode, category, attribute)\n if not followAncestors:\n return v0\n else:\n if (v0 is None) or (not v0) or (v0 in [\".\", \"?\"]):\n pItem = self.getUltimateParent(category, attribute)\n if (pItem is not None) and pItem and (pItem != CifName.itemName(category, attribute)):\n logger.debug(\"Reassigning enum code %s category %s attribute %s to parent %r\", enumCode, category, attribute, pItem)\n return self.__getValue(enumCode, CifName.categoryPart(pItem), CifName.attributePart(pItem))\n return v0\n\n #\n def __getValue(self, enumCode, category, attribute=None):\n \"\"\"Returns the last occurrence of the input dictionary metadata (enumCode) for the input category/attribute\n encountered in the list of objects stored at the indicated definition index.\n\n \"\"\"\n eS = None\n if enumCode not in self.__enumD:\n return eS\n\n if attribute is not None:\n nm = \"_\" + category + \".\" + attribute\n else:\n nm = category\n\n if nm in self.__definitionIndex:\n dObjL = self.__definitionIndex[nm]\n for dObj in dObjL:\n dc = dObj.getObj(self.__enumD[enumCode][0])\n if dc is not None:\n atN = self.__enumD[enumCode][1]\n rL = dc.getRowList()\n if rL:\n row = rL[0]\n if atN is not None:\n if dc.hasAttribute(atN):\n eS = row[dc.getIndex(atN)]\n else:\n eS = [rv for rv in row]\n return eS\n\n def __getList(self, enumCode, category, attribute=None):\n \"\"\"Return the list of unique values\"\"\"\n return list(set(self.__getListAll(enumCode, category, attribute)))\n\n def __getListAll(self, enumCode, category, attribute=None):\n \"\"\"Return a list of all values\"\"\"\n eL = []\n if enumCode not in self.__enumD:\n return eL\n\n if attribute is not None:\n nm = \"_\" + category + \".\" + attribute\n else:\n nm = category\n\n if nm in self.__definitionIndex:\n dObjL = self.__definitionIndex[nm]\n for dObj in dObjL:\n dc = dObj.getObj(self.__enumD[enumCode][0])\n if dc is not None:\n atN = self.__enumD[enumCode][1]\n for row in dc.getRowList():\n if atN is not None:\n if dc.hasAttribute(atN):\n eL.append(row[dc.getIndex(atN)])\n else:\n eL = [rv for rv in row]\n\n return eL\n\n def getMethodIndex(self):\n return self.__methodIndex\n\n def __makeIndex(self):\n \"\"\"Create indices of definitions, categories and items.\"\"\"\n iD = OrderedDict()\n for dD in self.__containerList:\n name = dD.getName()\n dType = dD.getType()\n #\n if name not in self.__fullIndex:\n self.__fullIndex[name] = []\n self.__fullIndex[name].append(dD)\n #\n if dType == \"definition\" and dD.isCategory():\n if name not in self.__catNameIndex:\n self.__catNameIndex[name] = []\n if name not in self.__catNameItemIndex:\n self.__catNameItemIndex[name] = []\n if name not in self.__definitionIndex:\n self.__definitionIndex[name] = []\n self.__definitionIndex[name].append(dD)\n\n elif dType == \"definition\" and dD.isAttribute():\n catN = CifName.categoryPart(name)\n attN = CifName.attributePart(name)\n if catN not in self.__catNameItemIndex:\n self.__catNameItemIndex[catN] = []\n if name not in self.__catNameItemIndex:\n self.__catNameItemIndex[catN].append(name)\n\n if catN not in self.__catNameIndex:\n self.__catNameIndex[catN] = []\n if attN not in self.__catNameIndex[catN]:\n self.__catNameIndex[catN].append(attN)\n if name not in self.__definitionIndex:\n self.__definitionIndex[name] = []\n self.__definitionIndex[name].append(dD)\n iD[name] = name\n elif dType == \"data\":\n for nm in dD.getObjNameList():\n if nm not in self.__dataIndex:\n self.__dataIndex[nm] = dD.getObj(nm)\n else:\n pass\n #\n self.__itemNameList = list(iD.keys())\n\n def getDefinitionIndex(self):\n return self.__definitionIndex\n\n def getFullIndex(self):\n return self.__fullIndex\n\n def getMethod(self, mId):\n if mId in self.__methodDict:\n return self.__methodDict[mId]\n else:\n return None\n\n def getCategoryList(self):\n return list(self.__catNameIndex.keys())\n\n def getCategoryIndex(self):\n return self.__catNameIndex\n\n def getAttributeNameList(self, category):\n try:\n return self.__catNameIndex[category]\n except Exception:\n pass\n return []\n\n def getItemNameList(self, category):\n try:\n return self.__catNameItemIndex[category]\n except Exception:\n pass\n return []\n\n def getSubCategoryDescription(self, subCategoryName):\n if subCategoryName in self.__subCategoryDict:\n return self.__subCategoryDict[subCategoryName]\n else:\n return \"\"\n\n def __getMethods(self):\n self.__methodDict = OrderedDict()\n self.__methodIndex = OrderedDict()\n for ob in self.__containerList:\n if ob.getType() == \"data\":\n ml = ob.getObj(\"method_list\")\n if ml is not None:\n # Use row order as priority\n for ii, row in enumerate(ml.getRowList(), 1):\n if ml.hasAttribute(\"id\") and ml.hasAttribute(\"code\") and ml.hasAttribute(\"language\") and ml.hasAttribute(\"implementation_source\"):\n tInline = row[ml.getIndex(\"inline\")] if ml.hasAttribute(\"inline\") else None\n tImpl = row[ml.getIndex(\"implementation\")] if ml.hasAttribute(\"implementation\") else None\n mth = MethodDefinition(\n row[ml.getIndex(\"id\")], row[ml.getIndex(\"code\")], row[ml.getIndex(\"language\")], tInline, ii, tImpl, row[ml.getIndex(\"implementation_source\")]\n )\n self.__methodDict[row[ml.getIndex(\"id\")]] = mth\n\n ml = ob.getObj(\"datablock_methods\")\n if ml is not None:\n for row in ml.getRowList():\n if ml.hasAttribute(\"method_id\"):\n # mth = MethodReference(row[ml.getIndex('method_id')], 'datablock', ob.getName(), None)\n mth = MethodReference(row[ml.getIndex(\"method_id\")], \"datablock\", None, None)\n if ob.getName() in self.__methodIndex:\n self.__methodIndex[ob.getName()].append(mth)\n else:\n self.__methodIndex[ob.getName()] = []\n self.__methodIndex[ob.getName()].append(mth)\n elif ob.getType() == \"definition\":\n mi = ob.getObj(\"category_methods\")\n if mi is not None:\n for row in mi.getRowList():\n if mi.hasAttribute(\"method_id\"):\n mth = MethodReference(row[mi.getIndex(\"method_id\")], \"category\", ob.getName(), None)\n if ob.getName() in self.__methodIndex:\n self.__methodIndex[ob.getName()].append(mth)\n else:\n self.__methodIndex[ob.getName()] = []\n self.__methodIndex[ob.getName()].append(mth)\n mi = ob.getObj(\"item_methods\")\n if mi is not None:\n for row in mi.getRowList():\n if mi.hasAttribute(\"method_id\"):\n mth = MethodReference(row[mi.getIndex(\"method_id\")], \"attribute\", CifName.categoryPart(ob.getName()), CifName.attributePart(ob.getName()))\n if ob.getName() in self.__methodIndex:\n self.__methodIndex[ob.getName()].append(mth)\n else:\n self.__methodIndex[ob.getName()] = []\n self.__methodIndex[ob.getName()].append(mth)\n else:\n pass\n return self.__methodIndex\n\n def dumpCategoryIndex(self, fh=sys.stdout):\n for k, vL in self.__catNameIndex.items():\n uvL = list(set(vL))\n fh.write(\"Category: %s has %d attributes\\n\" % (k, len(uvL)))\n for v in sorted(uvL):\n fh.write(\" Attribute: %s\\n\" % v)\n\n def dumpMethods(self, fh=sys.stdout):\n for k, vL in self.__methodIndex.items():\n fh.write(\"Method index key: %s length %d\\n\" % (k, len(vL)))\n for v in vL:\n v.printIt(fh)\n #\n fh.write(\"Inline method details\\n\")\n for k, vL in self.__methodIndex.items():\n fh.write(\"\\n------------------------------------\\n\")\n fh.write(\"Method index key: %s\\n\" % k)\n for v in vL:\n fh.write(\"Method ID: %r\\n\" % v.getId())\n if self.getMethod(v.getId()):\n fh.write(\"%r\" % v)\n # fh.write(\"Method text: %s\\n\" % self.getMethod(v.getId()).getInline())\n else:\n fh.write(\"Missing method for %r\" % v.getId())\n\n def dumpEnumFeatures(self, fh=sys.stdout):\n for k, vL in self.__catNameIndex.items():\n uvL = list(set(vL))\n for v in sorted(uvL):\n itL = self.getEnumList(k, v)\n if itL:\n fh.write(\"-----------------------------------------------\\n\")\n fh.write(\" Category : %s\\n\" % k)\n fh.write(\" Attribute: %s\\n\" % v)\n fh.write(\" Description: \\n%s\\n\" % self.getDescription(k, v))\n fh.write(\" Type: %s\\n\" % self.getTypeCode(k, v))\n fh.write(\" Primitive type: %s\\n\" % self.getTypePrimitive(k, v))\n fh.write(\" Regex type: %s\\n\" % self.getTypeRegex(k, v))\n fh.write(\" Enum list length %d\\n\" % len(itL))\n for it in itL:\n fh.write(\" Enum: %s\\n\" % it)\n\n def dumpFeatures(self, fh=sys.stdout):\n for k, vL in self.__catNameIndex.items():\n uvL = list(set(vL))\n fh.write(\"-----------------------------------------------\\n\")\n fh.write(\"Category: %s has %d attributes\\n\" % (k, len(uvL)))\n fh.write(\" Category description: %s\\n\" % self.getCategoryDescription(k))\n fh.write(\" Alt category description: %s\\n\" % self.getCategoryDescriptionAlt(k))\n\n fh.write(\" Category context: %s\\n\" % self.getCategoryContextList(k))\n\n ctL = self.getCategoryExampleList(k)\n if ctL:\n fh.write(\" Category example list length %d\\n\" % len(ctL))\n for ct1, ct2 in ctL:\n fh.write(\" Example case: %s\\n\" % ct1)\n fh.write(\" Example detail: %s\\n\" % ct2)\n\n ctL = self.getCategoryExampleListAlt(k)\n if ctL:\n fh.write(\" Alt category example list length %d\\n\" % len(ctL))\n for ct1, ct2 in ctL:\n fh.write(\" Alt example case: %s\\n\" % ct1)\n fh.write(\" Alt example detail: %s\\n\" % ct2)\n\n for v in sorted(uvL):\n fh.write(\" Attribute: %s\\n\" % v)\n fh.write(\" Description: %s\\n\" % self.getDescription(k, v))\n fh.write(\" Alt description: %s\\n\" % self.getDescriptionAlt(k, v))\n fh.write(\" Type: %s\\n\" % self.getTypeCode(k, v))\n fh.write(\" Alt Type: %s\\n\" % self.getTypeCodeAlt(k, v))\n fh.write(\" Primitive type: %s\\n\" % self.getTypePrimitive(k, v))\n fh.write(\" Regex type: %s\\n\" % self.getTypeRegex(k, v))\n fh.write(\" Context: %s\\n\" % self.getContextList(k, v))\n #\n fh.write(\" Type conditions: %s\\n\" % self.getTypeConditionsCode(k, v))\n fh.write(\" Subcategories: %s\\n\" % self.getItemSubCategoryIdList(k, v))\n #\n itL = self.getEnumList(k, v)\n if itL:\n fh.write(\" Enum list length %d\\n\" % len(itL))\n for it in itL:\n fh.write(\" Enum: %s\\n\" % it)\n\n itL = self.getParentList(k, v)\n if itL:\n fh.write(\" Parent list length %d\\n\" % len(itL))\n for it in itL:\n fh.write(\" Parent: %s\\n\" % it)\n itL = self.getChildList(k, v)\n if itL:\n fh.write(\" Child list length %d\\n\" % len(itL))\n for it in itL:\n fh.write(\" Child: %s\\n\" % it)\n\n itL = self.getExampleList(k, v)\n if itL:\n fh.write(\" Example list length %d\\n\" % len(itL))\n for it1, it2 in itL:\n fh.write(\" Example case: %s\\n\" % it1)\n fh.write(\" Example detail: %s\\n\" % it2)\n\n itL = self.getBoundaryList(k, v)\n if itL:\n fh.write(\" Boundary list length %d\\n\" % len(itL))\n for (it1, it2) in itL:\n fh.write(\" Boundary condition (min,max): (%s,%s)\\n\" % (it1, it2))\n\n itL = self.getEnumListAlt(k, v)\n if itL:\n fh.write(\" Alt enum list length %d\\n\" % len(itL))\n for it in itL:\n fh.write(\" Alt enum: %s\\n\" % it)\n\n itL = self.getExampleListAlt(k, v)\n if itL:\n fh.write(\" Alt example list length %d\\n\" % len(itL))\n for it1, it2 in itL:\n fh.write(\" Alt example case: %s\\n\" % it1)\n fh.write(\" Alt example detail: %s\\n\" % it2)\n\n itL = self.getBoundaryListAlt(k, v)\n if itL:\n fh.write(\" Alt boundary list length %d\\n\" % len(itL))\n for (it1, it2) in itL:\n fh.write(\" Alt boundary condition (min,max): (%s,%s)\\n\" % (it1, it2))\n\n itL = self.getItemRelatedList(k, v)\n if itL:\n fh.write(\" Related name list length %d\\n\" % len(itL))\n for (it1, it2) in itL:\n fh.write(\" Related item name %s function code %s\\n\" % (it1, it2))\n\n itL = self.getItemAliasList(k, v)\n if itL:\n fh.write(\" Alias name list length %d\\n\" % len(itL))\n for (it1, it2, it3) in itL:\n fh.write(\" Alias name %s dictionary %s version %s\\n\" % (it1, it2, it3))\n\n itL = self.getItemDependentNameList(k, v)\n if itL:\n fh.write(\" Dependent name list length %d\\n\" % len(itL))\n for it1 in itL:\n fh.write(\" Dependent item name %s\\n\" % it1)\n\n def dumpDataSections(self, fh=sys.stdout):\n fh.write(\"Datablock: %r\\n\" % list(self.__dataBlockDictList))\n fh.write(\"Dictionary: %r\\n\" % list(self.__dictionaryDictList))\n fh.write(\"Dictionary History: %r\\n\" % self.__dictionaryHistoryList)\n fh.write(\"Subcategories: %r\\n\" % list(self.__subCategoryDict.items()))\n fh.write(\"Category groups: %r\\n\" % list(self.__categoryGroupDict.items()))\n fh.write(\"Item units: %r\\n\" % list(self.__itemUnitsDict.items()))\n fh.write(\"Item units conversions: %r \\n\" % self.__itemUnitsConversionList)\n fh.write(\"Item linked groups: %r\\n\" % list(self.__itemLinkedGroupDict.items()))\n fh.write(\"Item linked group item list: %r\\n\" % list(self.__itemLinkedGroupItemDict.items()))\n\n def dumpItemLinkedGroups(self, fh=sys.stdout):\n for categoryId, lgList in self.__itemLinkedGroupDict.items():\n for lg in lgList:\n if (categoryId, lg[1]) in self.__itemLinkedGroupItemDict:\n fh.write(\" Category %s linked group %s:\\n\" % (categoryId, lg[1]))\n lgIList = self.__itemLinkedGroupItemDict[(categoryId, lg[1])]\n for lgI in lgIList:\n fh.write(\" group %s --- child item %s parent item %s\\n\" % (lg[1], lgI[0], lgI[1]))\n\n def __addItemLinkToDef(self, dObj, parentName, childName):\n \"\"\"Add the input link relationship to the input definition object.\"\"\"\n if dObj.exists(\"item_linked\"):\n # update in place --\n cObj = dObj.getObj(\"item_linked\")\n iFound = False\n idxP = cObj.getIndex(\"parent_name\")\n idxC = cObj.getIndex(\"child_name\")\n for row in cObj.getRowList():\n if parentName == row[idxP] and childName == row[idxC]:\n iFound = True\n break\n if not iFound:\n nRows = cObj.getRowCount()\n cObj.setValue(childName, \"child_name\", nRows)\n cObj.setValue(parentName, \"parent_name\", nRows)\n logger.debug(\"Appending item link in category %s\", dObj.getName())\n return True\n else:\n # create new category and append to input object\n cObj = DataCategory(\"item_linked\", attributeNameList=[\"child_name\", \"parent_name\"])\n cObj.append([childName, parentName])\n dObj.append(cObj)\n logger.debug(\"Created new item link in category %s\", dObj.getName())\n return True\n\n def __expandLoopedDefinitions(self):\n \"\"\"Handle definitions containing looped item and item_linked categories --\"\"\"\n fullIndex = OrderedDict()\n for dD in self.__containerList:\n name = dD.getName()\n if name not in fullIndex:\n fullIndex[name] = []\n fullIndex[name].append(dD)\n\n for name, dObjL in fullIndex.items():\n if dObjL:\n ob = dObjL[0]\n if (ob.getType() == \"definition\") and ob.exists(\"item_linked\"):\n cObj = ob.getObj(\"item_linked\")\n if cObj.getRowCount() > 0:\n idxP = cObj.getIndex(\"parent_name\")\n idxC = cObj.getIndex(\"child_name\")\n itemName = ob.getName()\n logger.debug(\"Current target item %s\", itemName)\n cObjNext = DataCategory(\"item_linked\", attributeNameList=[\"child_name\", \"parent_name\"])\n #\n # Distribute the data for each row --\n iChanges = 0\n for row in cObj.getRowList():\n #\n parentItemName = row[idxP]\n childItemName = row[idxC]\n if parentItemName == childItemName:\n continue\n if childItemName != itemName:\n iChanges += 1\n if childItemName in fullIndex:\n #\n # Add this p/c link to the child definition -\n #\n self.__addItemLinkToDef(fullIndex[childItemName][0], parentItemName, childItemName)\n else:\n # error missing child definition object.\n logger.warning(\"Missing child item %s\", childItemName)\n else:\n cObjNext.append([row[idxC], row[idxP]])\n if cObjNext.getRowCount() > 0:\n ob.replace(cObjNext)\n else:\n ob.remove(\"item_linked\")\n\n def __consolidateDefinitions(self):\n \"\"\"Consolidate definition attributes into a single save frame section per definition.\"\"\"\n fullIndex = OrderedDict()\n for dD in self.__containerList:\n name = dD.getName()\n fullIndex.setdefault(name, []).append(dD)\n\n # preserve the original order of sections -\n #\n nList = []\n for dObj in self.__containerList:\n nm = dObj.getName()\n if nm not in nList:\n nList.append(nm)\n #\n for name, dObjL in fullIndex.items():\n if len(dObjL) > 1:\n for dD in dObjL[1:]:\n xList = dD.getObjNameList()\n for nm in xList:\n if nm not in dObjL[0].getObjNameList():\n logger.debug(\"Adding %s to %s\", nm, name)\n catObj = dD.getObj(nm)\n dObjL[0].append(catObj)\n elif self.__replaceDefinition:\n logger.debug(\"Replacing dictionary %s in %s\", nm, name)\n catObj = dD.getObj(nm)\n dObjL[0].replace(catObj)\n\n # create a new list of consolidated objects in original list order\n dList = []\n for nm in nList:\n if nm in fullIndex:\n dl = fullIndex[nm]\n dList.append(dl[0])\n else:\n logger.info(\"+DictionaryApi().__consolidate() missing object name %s\", nm)\n # update lists\n self.__containerList = dList\n\n def getDataTypeList(self):\n \"\"\"Return list of tuples containing ('code','primitive_code','construct','detail' )\"\"\"\n rowList = []\n for code in sorted(self.__typesDict.keys()):\n tup = self.__typesDict[code]\n rowList.append((code, tup[0], tup[1], tup[2]))\n return rowList\n\n def getSubCategoryList(self):\n \"\"\"Return list of tuples containing ('id', 'description')\"\"\"\n rowList = []\n for tId in sorted(self.__subCategoryDict.keys()):\n description = self.__subCategoryDict[tId]\n rowList.append((tId, description))\n return rowList\n\n def getUnitsList(self):\n \"\"\"Return list of tuples containing ('id', 'description')\"\"\"\n rowList = []\n for tId in sorted(self.__itemUnitsDict.keys()):\n description = self.__itemUnitsDict[tId]\n rowList.append((tId, description))\n return rowList\n\n def getUnitsConversionList(self):\n \"\"\"Return list of tuples containing ('from_code','to_code','operator','factor')\"\"\"\n return self.__itemUnitsConversionList\n\n def __getDataSections(self):\n \"\"\" \"\"\"\n for ob in self.__containerList:\n\n if ob.getType() == \"data\":\n logger.debug(\"Adding data sections from container name %s type %s\", ob.getName(), ob.getType())\n # add detail to data type tuple\n tl = ob.getObj(\"item_type_list\")\n if tl is not None:\n for row in tl.getRowList():\n if tl.hasAttribute(\"code\") and tl.hasAttribute(\"primitive_code\") and tl.hasAttribute(\"construct\") and tl.hasAttribute(\"detail\"):\n self.__typesDict[row[tl.getIndex(\"code\")]] = (row[tl.getIndex(\"primitive_code\")], row[tl.getIndex(\"construct\")], row[tl.getIndex(\"detail\")])\n\n tl = ob.getObj(\"datablock\")\n if tl is not None:\n rL = tl.getRowList()\n if rL:\n if tl.hasAttribute(\"id\") and tl.hasAttribute(\"description\"):\n tD = OrderedDict()\n row = rL[0]\n tD[\"id\"] = row[tl.getIndex(\"id\")]\n tD[\"description\"] = row[tl.getIndex(\"description\")]\n self.__dataBlockDictList.append(tD)\n\n tl = ob.getObj(\"dictionary\")\n if tl is not None:\n rL = tl.getRowList()\n if rL:\n tD = OrderedDict()\n row = rL[0]\n if tl.hasAttribute(\"datablock_id\"):\n tD[\"datablock_id\"] = row[tl.getIndex(\"datablock_id\")]\n if tl.hasAttribute(\"title\"):\n tD[\"title\"] = row[tl.getIndex(\"title\")]\n if tl.hasAttribute(\"version\"):\n tD[\"version\"] = row[tl.getIndex(\"version\")]\n self.__dictionaryDictList.append(tD)\n tl = ob.getObj(\"dictionary_history\")\n if tl is not None:\n # history as a list of dictionaries -\n dName = ob.getName()\n for row in tl.getRowList():\n if tl.hasAttribute(\"version\") and tl.hasAttribute(\"revision\") and tl.hasAttribute(\"update\"):\n tD = OrderedDict()\n tD[\"version\"] = row[tl.getIndex(\"version\")]\n tD[\"revision\"] = row[tl.getIndex(\"revision\")]\n tD[\"update\"] = row[tl.getIndex(\"update\")]\n tD[\"dictionary\"] = dName\n self.__dictionaryHistoryList.append(tD)\n\n # JDW\n tl = ob.getObj(\"pdbx_include_dictionary\")\n if tl is not None:\n for row in tl.getRowList():\n tD = OrderedDict()\n if tl.hasAttribute(\"dictionary_id\"):\n tD[\"dictionary_id\"] = row[tl.getIndex(\"dictionary_id\")]\n if tl.hasAttribute(\"dictionary_locator\"):\n tD[\"dictionary_locator\"] = row[tl.getIndex(\"dictionary_locator\")]\n if tl.hasAttribute(\"include_mode\"):\n tD[\"include_mode\"] = row[tl.getIndex(\"include_mode\")]\n if tl.hasAttribute(\"dictionary_namespace\"):\n tD[\"dictionary_namespace_prefix\"] = row[tl.getIndex(\"dictionary_namespace_prefix\")]\n if tl.hasAttribute(\"dictionary_namespace_replace\"):\n tD[\"dictionary_namespace_prefix\"] = row[tl.getIndex(\"dictionary_namespace_prefix_replace\")]\n #\n self.__dictionaryIncludeDict[tD[\"dictionary_id\"]] = tD\n #\n tl = ob.getObj(\"pdbx_include_category\")\n if tl is not None:\n for row in tl.getRowList():\n tD = OrderedDict()\n if tl.hasAttribute(\"dictionary_id\"):\n tD[\"dictionary_id\"] = row[tl.getIndex(\"dictionary_id\")]\n if tl.hasAttribute(\"category_id\"):\n tD[\"category_id\"] = row[tl.getIndex(\"category_id\")]\n if tl.hasAttribute(\"include_as_category_id\"):\n tD[\"include_as_category_id\"] = row[tl.getIndex(\"include_as_category_id\")]\n if tl.hasAttribute(\"include_mode\"):\n tD[\"include_mode\"] = row[tl.getIndex(\"include_mode\")]\n #\n self.__categoryIncludeDict.setdefault(tD[\"dictionary_id\"], {}).setdefault(tD[\"category_id\"], tD)\n tl = ob.getObj(\"pdbx_include_item\")\n if tl is not None:\n for row in tl.getRowList():\n tD = OrderedDict()\n if tl.hasAttribute(\"dictionary_id\"):\n tD[\"dictionary_id\"] = row[tl.getIndex(\"dictionary_id\")]\n if tl.hasAttribute(\"item_name\"):\n tD[\"item_name\"] = row[tl.getIndex(\"item_name\")]\n if tl.hasAttribute(\"include_as_item_name\"):\n tD[\"include_as_item_name\"] = row[tl.getIndex(\"include_as_item_name\")]\n if tl.hasAttribute(\"include_mode\"):\n tD[\"include_mode\"] = row[tl.getIndex(\"include_mode\")]\n #\n categoryId = CifName.categoryPart(tD[\"item_name\"])\n self.__itemIncludeDict.setdefault(tD[\"dictionary_id\"], {}).setdefault(categoryId, {}).setdefault(tD[\"item_name\"], tD)\n\n tl = ob.getObj(\"dictionary_history\")\n if tl is not None:\n # history as a list of dictionaries -\n dName = ob.getName()\n for row in tl.getRowList():\n if tl.hasAttribute(\"version\") and tl.hasAttribute(\"revision\") and tl.hasAttribute(\"update\"):\n tD = OrderedDict()\n tD[\"version\"] = row[tl.getIndex(\"version\")]\n tD[\"revision\"] = row[tl.getIndex(\"revision\")]\n tD[\"update\"] = row[tl.getIndex(\"update\")]\n tD[\"dictionary\"] = dName\n self.__dictionaryHistoryList.append(tD)\n #\n tl = ob.getObj(\"pdbx_dictionary_component\")\n if tl is not None:\n for row in tl.getRowList():\n tD = OrderedDict()\n if tl.hasAttribute(\"dictionary_component_id\"):\n tD[\"dictionary_component_id\"] = row[tl.getIndex(\"dictionary_component_id\")]\n if tl.hasAttribute(\"title\"):\n tD[\"title\"] = row[tl.getIndex(\"title\")]\n if tl.hasAttribute(\"version\"):\n tD[\"version\"] = row[tl.getIndex(\"version\")]\n self.__dictionaryComponentList.append(tD)\n\n tl = ob.getObj(\"pdbx_dictionary_component_history\")\n if tl is not None:\n for row in tl.getRowList():\n if tl.hasAttribute(\"version\") and tl.hasAttribute(\"revision\") and tl.hasAttribute(\"update\"):\n tD = OrderedDict()\n tD[\"version\"] = row[tl.getIndex(\"version\")]\n tD[\"revision\"] = row[tl.getIndex(\"revision\")]\n tD[\"update\"] = row[tl.getIndex(\"update\")]\n tD[\"dictionary_component_id\"] = row[tl.getIndex(\"dictionary_component_id\")]\n self.__dictionaryComponentHistoryDict.setdefault(tD[\"dictionary_component_id\"], []).append(tD)\n\n # JDW\n tl = ob.getObj(\"sub_category\")\n if tl is not None:\n # subcategories as a dictionary by id\n self.__subCategoryDict = OrderedDict()\n for row in tl.getRowList():\n if tl.hasAttribute(\"id\") and tl.hasAttribute(\"description\"):\n self.__subCategoryDict[row[tl.getIndex(\"id\")]] = row[tl.getIndex(\"description\")]\n\n tl = ob.getObj(\"category_group_list\")\n if tl is not None:\n # category groups as a dictionary by id of tuples\n self.__categoryGroupDict = OrderedDict()\n for row in tl.getRowList():\n if tl.hasAttribute(\"id\") and tl.hasAttribute(\"description\") and tl.hasAttribute(\"parent_id\"):\n tD = OrderedDict()\n tD[\"description\"] = row[tl.getIndex(\"description\")]\n tD[\"parent_id\"] = row[tl.getIndex(\"parent_id\")]\n tD[\"categories\"] = []\n self.__categoryGroupDict[row[tl.getIndex(\"id\")]] = tD\n\n tl = ob.getObj(\"item_units_list\")\n if tl is not None:\n # units as a dictionary by code\n self.__itemUnitsDict = OrderedDict()\n for row in tl.getRowList():\n if tl.hasAttribute(\"code\") and tl.hasAttribute(\"detail\"):\n self.__itemUnitsDict[row[tl.getIndex(\"code\")]] = row[tl.getIndex(\"detail\")]\n\n tl = ob.getObj(\"item_units_conversion\")\n if tl is not None:\n # units conversion as a simple list now\n self.__itemUnitsConversionList = []\n for row in tl.getRowList():\n if tl.hasAttribute(\"from_code\") and tl.hasAttribute(\"to_code\") and tl.hasAttribute(\"operator\") and tl.hasAttribute(\"factor\"):\n self.__itemUnitsConversionList.append((row[tl.getIndex(\"from_code\")], row[tl.getIndex(\"to_code\")], row[tl.getIndex(\"operator\")], row[tl.getIndex(\"factor\")]))\n\n tl = ob.getObj(\"pdbx_item_linked_group\")\n if tl is not None:\n # parent-child collections [category_id] -> [(1,...),(3,...),(4,...) ]\n self.__itemLinkedGroupDict = OrderedDict()\n for row in tl.getRowList():\n if (\n tl.hasAttribute(\"category_id\")\n and tl.hasAttribute(\"link_group_id\")\n and tl.hasAttribute(\"label\")\n and tl.hasAttribute(\"context\")\n and tl.hasAttribute(\"condition_id\")\n ):\n categoryId = row[tl.getIndex(\"category_id\")]\n if categoryId not in self.__itemLinkedGroupDict:\n self.__itemLinkedGroupDict[categoryId] = []\n self.__itemLinkedGroupDict[categoryId].append(\n (row[tl.getIndex(\"category_id\")], row[tl.getIndex(\"link_group_id\")], row[tl.getIndex(\"context\")], row[tl.getIndex(\"condition_id\")])\n )\n\n tl = ob.getObj(\"pdbx_item_linked_group_list\")\n if tl is not None:\n # parent-child collections [(category_id,link_group_id)] -> [(child_name,parent_name,parent_category),(,...),(,...) ]\n self.__itemLinkedGroupItemDict = OrderedDict()\n for row in tl.getRowList():\n if (\n tl.hasAttribute(\"child_category_id\")\n and tl.hasAttribute(\"link_group_id\")\n and tl.hasAttribute(\"child_name\")\n and tl.hasAttribute(\"parent_name\")\n and tl.hasAttribute(\"parent_category_id\")\n ):\n childCategoryId = row[tl.getIndex(\"child_category_id\")]\n linkGroupId = row[tl.getIndex(\"link_group_id\")]\n if (childCategoryId, linkGroupId) not in self.__itemLinkedGroupItemDict:\n self.__itemLinkedGroupItemDict[(childCategoryId, linkGroupId)] = []\n self.__itemLinkedGroupItemDict[(childCategoryId, linkGroupId)].append(\n (row[tl.getIndex(\"child_name\")], row[tl.getIndex(\"parent_name\")], row[tl.getIndex(\"parent_category_id\")])\n )\n #\n tl = ob.getObj(\"pdbx_item_value_condition_list\")\n if tl is not None:\n for row in tl.getRowList():\n if tl.hasAttribute(\"dependent_item_name\") and tl.hasAttribute(\"dependent_item_cmp_op\") and tl.hasAttribute(\"target_item_name\") and tl.hasAttribute(\"cond_id\"):\n tD = OrderedDict()\n tD[\"cond_id\"] = row[tl.getIndex(\"cond_id\")]\n tD[\"target_item_name\"] = row[tl.getIndex(\"target_item_name\")]\n tD[\"dependent_item_name\"] = row[tl.getIndex(\"dependent_item_name\")]\n tD[\"dependent_item_cmp_op\"] = row[tl.getIndex(\"dependent_item_cmp_op\")]\n tD[\"target_item_value\"] = row[tl.getIndex(\"target_item_value\")] if tl.hasAttribute(\"target_item_value\") else None\n tD[\"dependent_item_value\"] = row[tl.getIndex(\"dependent_item_value\")] if tl.hasAttribute(\"dependent_item_value\") else None\n tD[\"log_op\"] = row[tl.getIndex(\"log_op\")] if tl.hasAttribute(\"log_op\") else \"and\"\n self.__itemValueConditionDict.setdefault(tD[\"target_item_name\"], {}).setdefault(tD[\"dependent_item_name\"], []).append(tD)\n #\n tl = ob.getObj(\"pdbx_comparison_operator_list\")\n if tl is not None:\n for row in tl.getRowList():\n if tl.hasAttribute(\"code\") and tl.hasAttribute(\"description\"):\n tD = OrderedDict()\n tD[\"code\"] = row[tl.getIndex(\"code\")]\n tD[\"description\"] = row[tl.getIndex(\"description\")]\n self.__compOpDict[tD[\"code\"]] = tD[\"description\"]\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.__init__","title":"__init__(self, containerList, consolidate=True, expandItemLinked=False, replaceDefinition=False, **kwargs)
special
","text":"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):\n \"\"\"Return an instance of the mmCIF dictionary API.\n\n Args:\n containerList (list): list of definition or data containers holding dictionary content\n consolidate (bool, optional): consolidate dictionary attributes within a single definition. Defaults to True.\n expandItemLinked (bool, optional): distribute item and item linked attributes defined for the parent\n to child definitions. Defaults to False.\n replaceDefinition (bool, optional): when consolidating definitions in the case of multiple occurences of the same definition,\n attributes from the latter occurences replace prior definitions content. Defaults to False.\n \"\"\"\n _ = kwargs\n #\n self.__containerList = containerList\n self.__replaceDefinition = replaceDefinition\n #\n if consolidate:\n self.__consolidateDefinitions()\n #\n if expandItemLinked:\n self.__expandLoopedDefinitions()\n\n self.__fullIndex = OrderedDict()\n\n # ---\n #\n # Map category name to the unique list of attributes\n self.__catNameIndex = OrderedDict()\n # Map category name to the unique list of item names\n self.__catNameItemIndex = OrderedDict()\n # Full unique list of item names -\n self.__itemNameList = []\n #\n # Map dictionary objects names to definition containers -\n self.__definitionIndex = OrderedDict()\n #\n # data section/objects of the dictionary by category name -\n self.__dataIndex = OrderedDict()\n #\n # Map of types id->(regex,primitive_type)\n self.__typesDict = OrderedDict()\n #\n self.__enumD = {\n \"ENUMERATION_VALUE\": (\"item_enumeration\", \"value\"),\n \"ENUMERATION_DETAIL\": (\"item_enumeration\", \"detail\"),\n \"ENUMERATION_TYPE_UNITS\": (\"item_enumeration\", \"rcsb_type_units_code\"),\n \"ENUMERATION_DETAIL_BRIEF\": (\"item_enumeration\", \"rcsb_detail_brief\"),\n \"ENUMERATION_TUPLE\": (\"item_enumeration\", None),\n \"ITEM_LINKED_PARENT\": (\"item_linked\", \"parent_name\"),\n \"ITEM_LINKED_CHILD\": (\"item_linked\", \"child_name\"),\n \"DATA_TYPE_CODE\": (\"item_type\", \"code\"),\n \"DATA_TYPE_REGEX\": (\"item_type_list\", \"construct\"),\n \"DATA_TYPE_PRIMITIVE\": (\"item_type_list\", \"primitive_code\"),\n \"ITEM_NAME\": (\"item\", \"name\"),\n \"ITEM_CATEGORY_ID\": (\"item\", \"category_id\"),\n \"ITEM_MANDATORY_CODE\": (\"item\", \"mandatory_code\"),\n \"ITEM_DESCRIPTION\": (\"item_description\", \"description\"),\n \"ITEM_UNITS\": (\"item_units\", \"code\"),\n \"ITEM_DEFAULT_VALUE\": (\"item_default\", \"value\"),\n \"ITEM_EXAMPLE_CASE\": (\"item_examples\", \"case\"),\n \"ITEM_EXAMPLE_DETAIL\": (\"item_examples\", \"detail\"),\n \"ITEM_RANGE_MAXIMUM\": (\"item_range\", \"maximum\"),\n \"ITEM_RANGE_MINIMUM\": (\"item_range\", \"minimum\"),\n \"CATEGORY_KEY_ITEMS\": (\"category_key\", \"name\"),\n \"CATEGORY_EXAMPLE_CASE\": (\"category_examples\", \"case\"),\n \"CATEGORY_EXAMPLE_DETAIL\": (\"category_examples\", \"detail\"),\n \"CATEGORY_MANDATORY_CODE\": (\"category\", \"mandatory_code\"),\n \"CATEGORY_DESCRIPTION\": (\"category\", \"description\"),\n \"CATEGORY_NX_MAPPING_DETAILS\": (\"category\", \"NX_mapping_details\"),\n #\n \"DATA_TYPE_CODE_NDB\": (\"ndb_item_type\", \"code\"),\n \"ITEM_DESCRIPTION_NDB\": (\"ndb_item_description\", \"description\"),\n \"ENUMERATION_VALUE_NDB\": (\"ndb_item_enumeration\", \"value\"),\n \"ENUMERATION_DETAIL_NDB\": (\"ndb_item_enumeration\", \"detail\"),\n \"ITEM_MANDATORY_CODE_NDB\": (\"ndb_item\", \"mandatory_code\"),\n \"ITEM_EXAMPLE_CASE_NDB\": (\"ndb_item_examples\", \"case\"),\n \"ITEM_EXAMPLE_DETAIL_NDB\": (\"ndb_item_examples\", \"detail\"),\n \"ITEM_RANGE_MAXIMUM_NDB\": (\"ndb_item_range\", \"maximum\"),\n \"ITEM_RANGE_MINIMUM_NDB\": (\"ndb_item_range\", \"minimum\"),\n \"CATEGORY_EXAMPLE_CASE_NDB\": (\"ndb_category_examples\", \"case\"),\n \"CATEGORY_EXAMPLE_DETAIL_NDB\": (\"ndb_category_examples\", \"detail\"),\n \"CATEGORY_DESCRIPTION_NDB\": (\"ndb_category_description\", \"description\"),\n #\n \"DATA_TYPE_CODE_PDBX\": (\"pdbx_item_type\", \"code\"),\n \"ITEM_DESCRIPTION_PDBX\": (\"pdbx_item_description\", \"description\"),\n \"ENUMERATION_VALUE_PDBX\": (\"pdbx_item_enumeration\", \"value\"),\n \"ENUMERATION_DETAIL_PDBX\": (\"pdbx_item_enumeration\", \"detail\"),\n \"ENUMERATION_TYPE_UNITS_PDBX\": (\"pdbx_item_enumeration\", \"type_units_code\"),\n \"ENUMERATION_DETAIL_BRIEF_PDBX\": (\"pdbx_item_enumeration\", \"detail_brief\"),\n \"ITEM_MANDATORY_CODE_PDBX\": (\"pdbx_item\", \"mandatory_code\"),\n \"ITEM_EXAMPLE_CASE_PDBX\": (\"pdbx_item_examples\", \"case\"),\n \"ITEM_EXAMPLE_DETAIL_PDBX\": (\"pdbx_item_examples\", \"detail\"),\n \"ITEM_RANGE_MAXIMUM_PDBX\": (\"pdbx_item_range\", \"maximum\"),\n \"ITEM_RANGE_MINIMUM_PDBX\": (\"pdbx_item_range\", \"minimum\"),\n \"CATEGORY_EXAMPLE_CASE_PDBX\": (\"pdbx_category_examples\", \"case\"),\n \"CATEGORY_EXAMPLE_DETAIL_PDBX\": (\"pdbx_category_examples\", \"detail\"),\n \"CATEGORY_DESCRIPTION_PDBX\": (\"pdbx_category_description\", \"description\"),\n #\n \"CATEGORY_CONTEXT\": (\"pdbx_category_context\", \"type\"),\n \"CATEGORY_GROUP\": (\"category_group\", \"id\"),\n \"ITEM_CONTEXT\": (\"pdbx_item_context\", \"type\"),\n \"ENUMERATION_CLOSED_FLAG\": (\"pdbx_item_enumeration_details\", \"closed_flag\"),\n #\n \"ITEM_RELATED_FUNCTION_CODE\": (\"item_related\", \"function_code\"),\n \"ITEM_RELATED_RELATED_NAME\": (\"item_related\", \"related_name\"),\n \"ITEM_ALIAS_ALIAS_NAME\": (\"item_aliases\", \"alias_name\"),\n \"ITEM_ALIAS_DICTIONARY\": (\"item_aliases\", \"dictionary\"),\n \"ITEM_ALIAS_VERSION\": (\"item_aliases\", \"version\"),\n \"ITEM_DEPENDENT_DEPENDENT_NAME\": (\"item_dependent\", \"dependent_name\"),\n \"ITEM_SUB_CATEGORY_ID\": (\"item_sub_category\", \"id\"),\n \"ITEM_SUB_CATEGORY_LABEL\": (\"item_sub_category\", \"pdbx_label\"),\n \"ITEM_TYPE_CONDITIONS_CODE\": (\"item_type_conditions\", \"code\"),\n #\n \"ITEM_VALUE_CONDITION_DEPENDENT_NAME\": (\"pdbx_item_value_condition\", \"dependent_item_name\"),\n #\n \"ITEM_LINKED_PDBX_ID\": (\"pdbx_item_linked\", \"id\"),\n \"ITEM_LINKED_PDBX_CONDITION_ID\": (\"pdbx_item_linked\", \"condition_id\"),\n \"ITEM_LINKED_PDBX_PARENT_NAME\": (\"pdbx_item_linked\", \"parent_name\"),\n \"ITEM_LINKED_PDBX_CHILD_NAME\": (\"pdbx_item_linked\", \"child_name\"),\n #\n \"ITEM_LINKED_PDBX_CONDITION_CHILD_NAME\": (\"pdbx_item_linked\", \"condition_child_name\"),\n \"ITEM_LINKED_PDBX_CONDITION_CHILD_VALUE\": (\"pdbx_item_linked\", \"condition_child_value\"),\n \"ITEM_LINKED_PDBX_CONDITION_CHILD_TARGET_NAME\": (\"pdbx_item_linked\", \"condition_child_target_name\"),\n \"ITEM_LINKED_PDBX_CONDITION_CHILD_CMP_OP\": (\"pdbx_item_linked\", \"condition_child_cmp_op\"),\n \"ITEM_LINKED_PDBX_CONDITION_LOG_OP\": (\"pdbx_item_linked\", \"condition_log_op\"),\n }\n #\n self.__methodDict = OrderedDict()\n self.__methodIndex = OrderedDict()\n #\n self.__makeIndex()\n self.__getMethods()\n #\n self.__fullParentD, self.__fullChildD = self.__makeFullParentChildDictionaries()\n #\n #\n self.__dataBlockDictList = []\n self.__dictionaryDictList = []\n #\n self.__subCategoryDict = OrderedDict()\n self.__categoryGroupDict = OrderedDict()\n self.__groupIndex = False\n self.__groupChildIndex = OrderedDict()\n #\n # Data sections -\n #\n self.__dictionaryHistoryList = []\n self.__itemUnitsDict = OrderedDict()\n self.__itemUnitsConversionList = []\n self.__itemLinkedGroupDict = OrderedDict()\n self.__itemLinkedGroupItemDict = OrderedDict()\n #\n self.__dictionaryIncludeDict = OrderedDict()\n self.__categoryIncludeDict = OrderedDict()\n self.__itemIncludeDict = OrderedDict()\n #\n self.__dictionaryComponentList = []\n self.__dictionaryComponentHistoryDict = OrderedDict()\n #\n self.__itemValueConditionDict = OrderedDict()\n self.__compOpDict = OrderedDict()\n #\n self.__getDataSections()\n #\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getDataTypeList","title":"getDataTypeList(self)
","text":"Return list of tuples containing ('code','primitive_code','construct','detail' )
Source code in mmcif/api/DictionaryApi.py
def getDataTypeList(self):\n \"\"\"Return list of tuples containing ('code','primitive_code','construct','detail' )\"\"\"\n rowList = []\n for code in sorted(self.__typesDict.keys()):\n tup = self.__typesDict[code]\n rowList.append((code, tup[0], tup[1], tup[2]))\n return rowList\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getDictionaryComponentCount","title":"getDictionaryComponentCount(self)
","text":"Get the count of dictionary components.
Source code in mmcif/api/DictionaryApi.py
def getDictionaryComponentCount(self):\n \"\"\"Get the count of dictionary components.\"\"\"\n try:\n return len(self.__dictionaryComponentList)\n except Exception:\n return 0\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getDictionaryComponentDetails","title":"getDictionaryComponentDetails(self)
","text":"Returns the component dictionary list as tuples [(version,title,dictionary_component_id),...]
Source code in mmcif/api/DictionaryApi.py
def getDictionaryComponentDetails(self):\n \"\"\"Returns the component dictionary list as tuples [(version,title,dictionary_component_id),...]\"\"\"\n oL = []\n try:\n for tD in self.__dictionaryComponentList:\n oL.append((tD[\"version\"], tD[\"title\"], tD[\"dictionary_component_id\"]))\n except Exception:\n pass\n return oL\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getDictionaryComponentHistory","title":"getDictionaryComponentHistory(self, dictionaryComponentId, order='reverse')
","text":"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\"):\n \"\"\"Returns the revision history as a list of tuples [(version,update,revisionText,dictionary),...]\"\"\"\n oL = []\n try:\n if order == \"reverse\":\n for tD in reversed(self.__dictionaryComponentHistoryDict[dictionaryComponentId]):\n oL.append((tD[\"version\"], tD[\"update\"], tD[\"revision\"], tD[\"dictionary_component_id\"]))\n else:\n for tD in self.__dictionaryComponentHistoryDict[dictionaryComponentId]:\n oL.append((tD[\"version\"], tD[\"update\"], tD[\"revision\"], tD[\"dictionary_component_id\"]))\n except Exception:\n pass\n return oL\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getDictionaryComponents","title":"getDictionaryComponents(self)
","text":"Get the list of dictionary components.
Source code in mmcif/api/DictionaryApi.py
def getDictionaryComponents(self):\n \"\"\"Get the list of dictionary components.\"\"\"\n try:\n return list(self.__dictionaryComponentHistoryDict.keys())\n except Exception:\n return []\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getDictionaryHistory","title":"getDictionaryHistory(self, order='reverse')
","text":"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\"):\n \"\"\"Returns the revision history as a list of tuples [(version,update,revisionText,dictionary),...]\"\"\"\n oL = []\n try:\n if order == \"reverse\":\n for tD in reversed(self.__dictionaryHistoryList):\n oL.append((tD[\"version\"], tD[\"update\"], tD[\"revision\"], tD[\"dictionary\"]))\n else:\n for tD in self.__dictionaryHistoryList:\n oL.append((tD[\"version\"], tD[\"update\"], tD[\"revision\"], tD[\"dictionary\"]))\n except Exception:\n pass\n return oL\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getDictionaryRevisionCount","title":"getDictionaryRevisionCount(self)
","text":"Get the count of revision history records.
Source code in mmcif/api/DictionaryApi.py
def getDictionaryRevisionCount(self):\n \"\"\"Get the count of revision history records.\"\"\"\n try:\n return len(self.__dictionaryHistoryList)\n except Exception:\n return 0\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getDictionaryUpdate","title":"getDictionaryUpdate(self, order='reverse')
","text":"Get details from the first/last history element.
Source code in mmcif/api/DictionaryApi.py
def getDictionaryUpdate(self, order=\"reverse\"):\n \"\"\"Get details from the first/last history element.\"\"\"\n try:\n if order == \"reverse\":\n tD = self.__dictionaryHistoryList[-1]\n else:\n tD = self.__dictionaryHistoryList[0]\n\n return tD[\"update\"]\n\n except Exception:\n return None\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getItemLinkedConditions","title":"getItemLinkedConditions(self)
","text":"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_\n _pdbx_item_linked.id\n _pdbx_item_linked.condition_id\n _pdbx_item_linked.parent_name\n _pdbx_item_linked.child_name\n #\n _pdbx_item_linked.condition_child_name\n _pdbx_item_linked.condition_child_value\n _pdbx_item_linked.condition_child_cmp_op\n _pdbx_item_linked.condition_child_target_name\n _pdbx_item_linked.condition_child_log_op\n 1 1 '_entity_poly_seq.num' '_atom_site.label_seq_id' '_atom_site.label_entity_id' . 'eq' '_entity.id' .\n 2 1 '_entity_poly_seq.num' '_atom_site.label_seq_id' '_entity.type' 'polymer' 'eq' . 'and'\n
Source code in mmcif/api/DictionaryApi.py
def getItemLinkedConditions(self):\n \"\"\"Create a dictionary of conditional item link relationships.\n\n Returns:\n (dict): {{parent_name, child_name}: [{\"id\": , \"condition_id\": , \"condition_child_name\": , \"condition_child_value\": ,\n \"condition_child_cmp_op\": , \"condition_log_op\": ,}, {},...]}\n\n Example:\n ```text\n loop_\n _pdbx_item_linked.id\n _pdbx_item_linked.condition_id\n _pdbx_item_linked.parent_name\n _pdbx_item_linked.child_name\n #\n _pdbx_item_linked.condition_child_name\n _pdbx_item_linked.condition_child_value\n _pdbx_item_linked.condition_child_cmp_op\n _pdbx_item_linked.condition_child_target_name\n _pdbx_item_linked.condition_child_log_op\n 1 1 '_entity_poly_seq.num' '_atom_site.label_seq_id' '_atom_site.label_entity_id' . 'eq' '_entity.id' .\n 2 1 '_entity_poly_seq.num' '_atom_site.label_seq_id' '_entity.type' 'polymer' 'eq' . 'and'\n ```\n\n \"\"\"\n rD = OrderedDict()\n try:\n for ob in self.__containerList:\n if ob.getType() == \"data\":\n continue\n tl = ob.getObj(self.__enumD[\"ITEM_LINKED_PDBX_ID\"][0])\n if tl is not None:\n for row in tl.getRowList():\n if (\n tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_ID\"][1])\n and tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_ID\"][1])\n and tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CHILD_NAME\"][1])\n and tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_PARENT_NAME\"][1])\n ):\n tD = OrderedDict()\n tD[\"id\"] = row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_ID\"][1])]\n tD[\"condition_id\"] = row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_ID\"][1])]\n parentName = row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_PARENT_NAME\"][1])]\n childName = row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CHILD_NAME\"][1])]\n #\n tD[\"condition_child_name\"] = (\n row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_NAME\"][1])]\n if tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_NAME\"][1])\n else None\n )\n tD[\"condition_child_value\"] = (\n row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_VALUE\"][1])]\n if tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_VALUE\"][1])\n else None\n )\n tD[\"condition_child_cmp_op\"] = (\n row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_CMP_OP\"][1])]\n if tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_CMP_OP\"][1])\n else None\n )\n tD[\"condition_child_target_name\"] = (\n row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_TARGET_NAME\"][1])]\n if tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_TARGET_NAME\"][1])\n else None\n )\n tD[\"condition_log_op\"] = (\n 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\n )\n #\n rD.setdefault((parentName, childName), []).append(tD)\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n\n return rD\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getParentDictionary","title":"getParentDictionary(self)
","text":"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):\n \"\"\"Create a dictionary of parents relations accross all definnitions\n as {child : [parent, parent,...]\n\n Exclude self parents.\n \"\"\"\n parentD = {}\n pAtN = self.__enumD[\"ITEM_LINKED_PARENT\"][1]\n cAtN = self.__enumD[\"ITEM_LINKED_CHILD\"][1]\n\n for dObj in self.__containerList:\n dc = dObj.getObj(self.__enumD[\"ITEM_LINKED_PARENT\"][0])\n if dc is not None:\n idxP = dc.getIndex(pAtN)\n idxC = dc.getIndex(cAtN)\n for row in dc.getRowList():\n pVal = row[idxP]\n cVal = row[idxC]\n if pVal == cVal:\n continue\n if cVal not in parentD:\n parentD[cVal] = []\n parentD[cVal].append(pVal)\n #\n return parentD\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getSubCategoryList","title":"getSubCategoryList(self)
","text":"Return list of tuples containing ('id', 'description')
Source code in mmcif/api/DictionaryApi.py
def getSubCategoryList(self):\n \"\"\"Return list of tuples containing ('id', 'description')\"\"\"\n rowList = []\n for tId in sorted(self.__subCategoryDict.keys()):\n description = self.__subCategoryDict[tId]\n rowList.append((tId, description))\n return rowList\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getUltimateParent","title":"getUltimateParent(self, category, attribute)
","text":"Return the first ultimate parent item for the input item.
Source code in mmcif/api/DictionaryApi.py
def getUltimateParent(self, category, attribute):\n \"\"\"Return the first ultimate parent item for the input item.\"\"\"\n # pL=self.__getList('ITEM_LINKED_PARENT',category,attribute)\n pL = self.getFullParentList(category, attribute)\n itemName = CifName.itemName(category, attribute)\n while pL and (pL[0] != itemName):\n attN = CifName.attributePart(pL[0])\n catN = CifName.categoryPart(pL[0])\n itemName = pL[0]\n pL = self.getFullParentList(catN, attN)\n # pL=self.__getList('ITEM_LINKED_PARENT',catN,attN)\n return itemName\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getUnitsConversionList","title":"getUnitsConversionList(self)
","text":"Return list of tuples containing ('from_code','to_code','operator','factor')
Source code in mmcif/api/DictionaryApi.py
def getUnitsConversionList(self):\n \"\"\"Return list of tuples containing ('from_code','to_code','operator','factor')\"\"\"\n return self.__itemUnitsConversionList\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getUnitsList","title":"getUnitsList(self)
","text":"Return list of tuples containing ('id', 'description')
Source code in mmcif/api/DictionaryApi.py
def getUnitsList(self):\n \"\"\"Return list of tuples containing ('id', 'description')\"\"\"\n rowList = []\n for tId in sorted(self.__itemUnitsDict.keys()):\n description = self.__itemUnitsDict[tId]\n rowList.append((tId, description))\n return rowList\n
"},{"location":"api_reference/DictionaryInclude/","title":"DictionaryInclude","text":"Source code in mmcif/api/DictionaryInclude.py
class DictionaryInclude(object):\n def __init__(self, **kwargs):\n #\n self.__itemNameRelatives = [\n \"_item.name\",\n \"_item_examples.name\",\n \"_ndb_item_description.name\",\n \"_item_related.name\",\n \"_category_key.name\",\n \"_item_structure.name\",\n \"_item_methods.name\",\n \"_item_aliases.name\",\n \"_item_dependent.dependent_name\",\n \"_item_default.name\",\n \"_pdbx_item_examples.name\",\n \"_item_units.name\",\n \"_item_related.related_name\",\n \"_item_description.name\",\n \"_item_dependent.name\",\n \"_item_range.name\",\n \"_item_sub_category.name\",\n \"_pdbx_item_range.name\",\n \"_pdbx_item_linked.condition_child_name\",\n \"_ndb_item_examples.name\",\n \"_pdbx_item_value_condition.item_name\",\n \"_ndb_item_range.name\",\n \"_item_linked.child_name\",\n \"_pdbx_item_description.name\",\n \"_pdbx_item_context.item_name\",\n \"_pdbx_item_enumeration_details.name\",\n \"_pdbx_item_linked_group_list.child_name\",\n \"_pdbx_item_linked_group_list.parent_name\",\n \"_pdbx_item_value_condition_list.target_item_name\",\n \"_ndb_item_enumeration.name\",\n \"_pdbx_item_linked.child_name\",\n \"_pdbx_item_value_condition.dependent_item_name\",\n \"_pdbx_item_enumeration.name\",\n \"_item_linked.parent_name\",\n \"_pdbx_item_value_condition_list.dependent_item_name\",\n \"_item_type.name\",\n \"_item_type_conditions.name\",\n \"_pdbx_item_linked.parent_name\",\n \"_item_enumeration.name\",\n ]\n self.__categoryIdRelatives = [\n \"_category.id\",\n \"_category_key.id\",\n \"_pdbx_item_linked_group.category_id\",\n \"_pdbx_category_examples.id\",\n \"_item.category_id\",\n \"_pdbx_category_context.category_id\",\n \"_pdbx_item_linked_group_list.parent_category_id\",\n \"_category_group.category_id\",\n \"_pdbx_category_description.id\",\n \"_ndb_category_examples.id\",\n \"_category_examples.id\",\n \"_category_methods.category_id\",\n \"_ndb_category_description.id\",\n \"_pdbx_item_linked_group_list.child_category_id\",\n ]\n #\n self.__cwd = os.getcwd()\n self.__dirPath = kwargs.get(\"dirPath\", os.getcwd())\n logger.info(\"Local dictionary include path relative to %s\", self.__dirPath)\n self.__dirStack = []\n self.__locatorIndexD = {}\n\n def processIncludedContent(self, containerList, cleanup=False):\n \"\"\"Process any dictionary, category or item include instructions in any data containers in the\n input list of dictionary data and definition containers.\n\n Args:\n containerList (list): list of input PdbxContainer data or definition container objects\n cleanup (bool, optional): flag to remove generator category objects after parsing (default: False)\n\n Returns:\n (list): list of data and definition containers incorporating included content\n\n Examples:\n ```python\n pathDdlIncludeDictionary = \"mmcif_ddl-generator.dic\"\n myIo = IoAdapter(raiseExceptions=True)\n containerList = myIo.readFile(inputFilePath=pathDdlIncludeDictionary)\n logger.info(\"Starting container list length (%d)\", len(containerList))\n dIncl = DictionaryInclude()\n inclL = dIncl.processIncludedContent(containerList)\n logger.info(\"Processed included container length (%d)\", len(inclL))\n ```\n\n \"\"\"\n includeD = self.__getIncludeInstructions(containerList, cleanup=cleanup)\n includeContentD = self.__fetchIncludedContent(includeD, cleanup=cleanup)\n return self.__addIncludedContent(containerList, includeContentD)\n\n def __addIncludedContent(self, containerList, includeContentD):\n \"\"\"Incorporate included content described in the input dictionary of include instructions produced by\n internal method __getIncludeInstructions().\n\n Args:\n containerList (list): list of input PdbxContainer data or definition container objects\n includeContentD (dict): {\"dictionaryIncludeDict\": {dictionary_id: {...include details...}},\n \"categoryIncludeDict\": {dictionary_id: {category_id: {...include details... }}},\n \"itemIncludeDict\": {dictionary_id: {category_id: {itemName: {...include details...}}}}\n }\n\n Returns:\n (list): list of data and definition containers incorporating included content\n \"\"\"\n # Index the current container list...\n cD = OrderedDict()\n datablockName = \"unnamed_1\"\n for container in containerList:\n if container.getType() == \"data\":\n datablockName = container.getName()\n # Handle potentially unconsolidated definitions --\n cD.setdefault(datablockName, OrderedDict()).setdefault(container.getName(), []).append(container)\n #\n #\n for datablockName in cD:\n if datablockName in includeContentD:\n if \"replace\" in includeContentD[datablockName]:\n # Organize the replacements by name\n replaceDefinitionD = OrderedDict()\n replaceDataD = OrderedDict()\n for container in includeContentD[datablockName][\"replace\"]:\n if container.getType() == \"definition\":\n replaceDefinitionD.setdefault(container.getName(), []).append(container)\n else:\n replaceDataD.setdefault(datablockName, []).append(container)\n #\n for rN, rL in replaceDefinitionD.items():\n if rN in cD[datablockName]:\n cD[datablockName][rN] = rL\n # replace data sections in the base container\n baseContainer = cD[datablockName][datablockName][0]\n for rN, containerL in replaceDataD.items():\n for container in containerL:\n for nm in container.getObjNameList():\n obj = container.getObj(nm)\n baseContainer.replace(obj)\n #\n if \"extend\" in includeContentD[datablockName]:\n extendDataD = OrderedDict()\n for container in includeContentD[datablockName][\"extend\"]:\n if container.getType() == \"definition\":\n cD.setdefault(datablockName, OrderedDict()).setdefault(container.getName(), []).append(container)\n else:\n extendDataD.setdefault(datablockName, []).append(container)\n # extend data sections in the base container\n baseContainer = cD[datablockName][datablockName][0]\n for rN, containerL in extendDataD.items():\n for container in containerL:\n for nm in container.getObjNameList():\n obj = container.getObj(nm)\n if baseContainer.exists(nm):\n baseObj = baseContainer.getObj(nm)\n for ii in range(obj.getRowCount()):\n rowD = obj.getRowAttributeDict(ii)\n baseObj.append(rowD)\n else:\n baseContainer.append(obj)\n #\n # Unwind the container index\n #\n fullL = []\n for datablockName in cD:\n for cL in cD[datablockName].values():\n fullL.extend(cL)\n #\n return fullL\n\n def __getIncludeInstructions(self, containerList, cleanup=False):\n \"\"\"Extract include instructions from categories pdbx_include_dictionary, pdbx_include_category, and pdbx_include_item.\n\n Args:\n containerList (list): list of input PdbxContainer data or definition container objects\n cleanup (optional, bool): flag to remove generator category objects after parsing (default: False)\n\n Returns:\n A dictionary containing the dictionary, category and and item level include details.\n For example,\n\n ```python\n {\n \"dictionaryIncludeDict\": {dictionary_id: {...include details...}},\n \"categoryIncludeDict\": {dictionary_id: {category_id: {...include details... }}},\n \"itemIncludeDict\": {dictionary_id: {category_id: {itemName: {...include details...}}}},\n }\n ```\n\n\n \"\"\"\n includeD = OrderedDict()\n try:\n unNamed = 1\n for container in containerList:\n if container.getType() == \"data\":\n dictionaryIncludeDict = OrderedDict()\n categoryIncludeDict = OrderedDict()\n itemIncludeDict = OrderedDict()\n if container.getName():\n datablockName = container.getName()\n else:\n datablockName = str(unNamed)\n unNamed += 1\n logger.debug(\"Adding data sections from container name %s type %s\", datablockName, container.getType())\n tl = container.getObj(\"pdbx_include_dictionary\")\n if tl is not None:\n for row in tl.getRowList():\n tD = OrderedDict()\n for atName in [\"dictionary_id\", \"dictionary_locator\", \"include_mode\", \"dictionary_namespace_prefix\", \"dictionary_namespace_prefix_replace\"]:\n tD[atName] = row[tl.getIndex(atName)] if tl.hasAttribute(atName) else None\n dictionaryIncludeDict[tD[\"dictionary_id\"]] = tD\n #\n tl = container.getObj(\"pdbx_include_category\")\n if tl is not None:\n for row in tl.getRowList():\n tD = OrderedDict()\n for atName in [\"dictionary_id\", \"category_id\", \"include_as_category_id\", \"include_mode\"]:\n tD[atName] = row[tl.getIndex(atName)] if tl.hasAttribute(atName) else None\n categoryIncludeDict.setdefault(tD[\"dictionary_id\"], {}).setdefault(tD[\"category_id\"], tD)\n #\n tl = container.getObj(\"pdbx_include_item\")\n if tl is not None:\n for row in tl.getRowList():\n tD = OrderedDict()\n for atName in [\"dictionary_id\", \"item_name\", \"include_as_item_name\", \"include_mode\"]:\n tD[atName] = row[tl.getIndex(atName)] if tl.hasAttribute(atName) else None\n categoryId = CifName.categoryPart(tD[\"item_name\"])\n itemIncludeDict.setdefault(tD[\"dictionary_id\"], {}).setdefault(categoryId, {}).setdefault(tD[\"item_name\"], tD)\n if cleanup:\n for catName in [\"pdbx_include_dictionary\", \"pdbx_include_category\", \"pdbx_include_item\"]:\n if container.exists(catName):\n container.remove(catName)\n #\n includeD[datablockName] = {\n \"dictionaryIncludeDict\": dictionaryIncludeDict,\n \"categoryIncludeDict\": categoryIncludeDict,\n \"itemIncludeDict\": itemIncludeDict,\n }\n except Exception as e:\n logger.exception(\"Include processing failing with %s\", str(e))\n return includeD\n\n def __fetchIncludedContent(self, includeD, cleanup=False):\n \"\"\"Fetch included content following the instructions encoded in the input data structure.\n\n Args:\n includeD (dict): {\"dictionaryIncludeDict\": {dictionary_id: {...include details...}},\n \"categoryIncludeDict\": {dictionary_id: {category_id: {...include details... }}},\n \"itemIncludeDict\": {dictionary_id: {category_id: {itemName: {...include details...}}}},\n }\n cleanup (optional, bool): flag to remove generator category objects after parsing (default: false)\n\n Returns:\n (dict): {datablockName: {\"extend\": [container,...], \"replace\": [container, ...]}, ... }\n\n \"\"\"\n\n includeDataD = {}\n try:\n for datablockName, inclD in includeD.items():\n cL = []\n for dictName, iD in inclD[\"dictionaryIncludeDict\"].items():\n locator = iD[\"dictionary_locator\"]\n if locator in self.__locatorIndexD:\n logger.info(\"Skipping redundant include for %r at %r\", dictName, locator)\n continue\n self.__locatorIndexD[locator] = dictName\n #\n # --- Fetch the dictionary component -\n #\n updateStack = self.__isLocal(locator)\n if updateStack:\n if not self.__dirStack:\n # top-level include case\n self.__dirStack.append(os.path.abspath(self.__dirPath))\n\n # embedded include case (push directory containing the locator)\n if not os.path.isabs(locator):\n # handle the relative path case -\n locator = os.path.abspath(os.path.join(self.__dirStack[-1], locator))\n logger.debug(\"modified local relative locator is %r\", locator)\n self.__dirStack.append(os.path.dirname(locator))\n logger.debug(\"dirStack (%d) top %r\", len(self.__dirStack), self.__dirStack[-1])\n containerList = self.processIncludedContent(self.__fetchLocator(locator), cleanup=cleanup)\n if updateStack:\n # restore stack context\n self.__dirStack.pop()\n #\n nsPrefix = iD[\"dictionary_namespace_prefix\"]\n nsPrefixReplace = iD[\"dictionary_namespace_prefix_replace\"]\n dictInclMode = iD[\"include_mode\"]\n dataIncludeMode = iD[\"data_include_mode\"] if \"data_include_mode\" in iD else \"extend\"\n catInclD = inclD[\"categoryIncludeDict\"][dictName] if dictName in inclD[\"categoryIncludeDict\"] else None\n itemInclD = inclD[\"itemIncludeDict\"][dictName] if dictName in inclD[\"itemIncludeDict\"] else None\n #\n # Do data sections first.\n for container in containerList:\n if container.getType() == \"data\":\n logger.debug(\"Including data container %r with %r\", container.getName(), container.getObjNameList())\n cL.append((container, dataIncludeMode))\n #\n if catInclD or itemInclD:\n # Process only explicitly included categories/items in the dictionary component\n if catInclD:\n for container in containerList:\n if container.getType() == \"data\":\n continue\n cName = container.getName()\n catName = cName if container.isCategory() else CifName.categoryPart(cName)\n #\n if catName in catInclD:\n if container.isAttribute() and itemInclD and catName in itemInclD and cName in itemInclD[catName]:\n inclMode = itemInclD[catName][cName][\"include_mode\"] if itemInclD[catName][cName][\"include_mode\"] else dictInclMode\n cL.append((self.__renameItem(container, itemInclD[catName][cName][\"include_as_item_name\"]), inclMode))\n else:\n inclMode = catInclD[catName][\"include_mode\"] if catInclD[catName][\"include_mode\"] else dictInclMode\n cL.append((self.__renameCategory(container, catInclD[catName][\"include_as_category_id\"]), inclMode))\n elif itemInclD:\n # Process only explicitly included items exclusive of explicitly included categories in the dictionary component\n for container in containerList:\n if container.getType() == \"data\":\n continue\n cName = container.getName()\n catName = cName if container.isCategory() else CifName.categoryPart(cName)\n #\n if container.isAttribute() and catName in itemInclD and cName in itemInclD[catName]:\n inclMode = itemInclD[catName][cName][\"include_mode\"] if itemInclD[catName][cName][\"include_mode\"] else dictInclMode\n cL.append((self.__renameItem(container, itemInclD[catName][cName][\"include_as_item_name\"]), inclMode))\n else:\n # Process the full content of the dictionary component\n for container in containerList:\n if container.getType() == \"data\":\n continue\n cName = container.getName()\n catName = cName if container.isCategory() else CifName.categoryPart(cName)\n #\n if container.isAttribute():\n newName = self.__substituteItemPrefix(cName, nsPrefix, nsPrefixReplace)\n cL.append((self.__renameItem(container, newName), dictInclMode))\n else:\n newName = self.__substituteCategoryPrefix(catName, nsPrefix, nsPrefixReplace)\n cL.append((self.__renameCategory(container, newName), dictInclMode))\n #\n for container, inclMode in cL:\n if inclMode == \"replace\":\n includeDataD.setdefault(datablockName, {}).setdefault(\"replace\", []).append(container)\n elif inclMode == \"extend\":\n logger.debug(\"%r extending with %r\", datablockName, container.getName())\n includeDataD.setdefault(datablockName, {}).setdefault(\"extend\", []).append(container)\n #\n for nm in includeDataD:\n numReplace = len(includeDataD[nm][\"replace\"]) if \"replace\" in includeDataD[nm] else 0\n numExtend = len(includeDataD[nm][\"extend\"]) if \"extend\" in includeDataD[nm] else 0\n logger.debug(\"includeDataD %s replace (%d) extend (%d)\", nm, numReplace, numExtend)\n #\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n\n return includeDataD\n\n def __isLocal(self, locator):\n try:\n locSp = urlsplit(locator)\n return locSp.scheme in [\"\", \"file\"]\n except Exception as e:\n logger.error(\"Bad include file path (%r) : %s\", locator, str(e))\n return False\n\n def __fetchLocator(self, locator, **kwargs):\n \"\"\"\"\"\"\n try:\n # Locate non-absolute paths relative to the dictionary incude file\n if self.__isLocal(locator) and not os.path.isabs(locator):\n logger.info(\"locator is %r\", locator)\n logger.info(\"dirStack (%d) top %r\", len(self.__dirStack), self.__dirStack[-1])\n locator = os.path.abspath(os.path.relpath(locator, start=self.__dirStack[-1]))\n #\n containerList = []\n workPath = kwargs.get(\"workPath\", None)\n enforceAscii = kwargs.get(\"enforceAscii\", False)\n raiseExceptions = kwargs.get(\"raiseExceptions\", True)\n useCharRefs = kwargs.get(\"useCharRefs\", True)\n #\n myIo = IoAdapterPy(raiseExceptions=raiseExceptions, useCharRefs=useCharRefs)\n containerList = myIo.readFile(locator, enforceAscii=enforceAscii, outDirPath=workPath)\n logger.info(\"Fetched %r dictionary container length (%d)\", locator, len(containerList) if containerList else 0)\n logger.debug(\"%r\", [container.getName() for container in containerList])\n except Exception as e:\n logger.exception(\"Failing for %s with %s\", locator, str(e))\n return containerList\n\n def __substituteCategoryPrefix(self, catName, curPrefix, newPrefix):\n return catName.replace(curPrefix, newPrefix, 1) if catName and catName.startswith(curPrefix) else catName\n\n def __substituteItemPrefix(self, itemName, curPrefix, newPrefix):\n atName = CifName.attributePart(itemName)\n atName = atName.replace(curPrefix, newPrefix, 1) if atName and atName.startswith(curPrefix) else atName\n catName = CifName.categoryPart(itemName)\n catName = catName.replace(curPrefix, newPrefix, 1) if atName and catName.startswith(curPrefix) else catName\n return CifName.itemName(catName, atName)\n\n def __renameItem(self, container, newItemName):\n if not container and not container.isAttribute() or not newItemName:\n return container\n #\n itemNameCur = container.getName()\n if itemNameCur == newItemName:\n return container\n #\n try:\n for item in self.__itemNameRelatives:\n catName = CifName.categoryPart(item)\n if container.exists(catName):\n cObj = container.getObj(catName)\n atName = CifName.attributePart(item)\n if cObj.hasAttribute(atName):\n for iRow in range(cObj.getRowCount()):\n curVal = cObj.getValue(atName, iRow)\n if curVal == itemNameCur:\n cObj.setValue(newItemName, atName, iRow)\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n return container\n\n def __renameCategory(self, container, newCategoryName):\n if not container and not container.isCategory() or not newCategoryName:\n return container\n #\n catNameCur = container.getName()\n if catNameCur == newCategoryName:\n return container\n try:\n for item in self.__categoryIdRelatives:\n catName = CifName.categoryPart(item)\n if container.exists(catName):\n cObj = container.getObj(catName)\n atName = CifName.attributePart(item)\n if cObj.hasAttribute(atName):\n for iRow in range(cObj.getRowCount()):\n testVal = cObj.getValue(atName, iRow)\n if testVal == catNameCur:\n cObj.setValue(newCategoryName, atName, iRow)\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n return container\n
"},{"location":"api_reference/DictionaryInclude/#mmcif.api.DictionaryInclude.DictionaryInclude.processIncludedContent","title":"processIncludedContent(self, containerList, cleanup=False)
","text":"Process any dictionary, category or item include instructions in any data containers in the input list of dictionary data and definition containers.
Parameters:
Name Type Description Default containerList
list
list of input PdbxContainer data or definition container objects
required cleanup
bool
flag to remove generator category objects after parsing (default: False)
False
Returns:
Type Description (list)
list of data and definition containers incorporating included content
Examples:
pathDdlIncludeDictionary = \"mmcif_ddl-generator.dic\"\nmyIo = IoAdapter(raiseExceptions=True)\ncontainerList = myIo.readFile(inputFilePath=pathDdlIncludeDictionary)\nlogger.info(\"Starting container list length (%d)\", len(containerList))\ndIncl = DictionaryInclude()\ninclL = dIncl.processIncludedContent(containerList)\nlogger.info(\"Processed included container length (%d)\", len(inclL))\n
Source code in mmcif/api/DictionaryInclude.py
def processIncludedContent(self, containerList, cleanup=False):\n \"\"\"Process any dictionary, category or item include instructions in any data containers in the\n input list of dictionary data and definition containers.\n\n Args:\n containerList (list): list of input PdbxContainer data or definition container objects\n cleanup (bool, optional): flag to remove generator category objects after parsing (default: False)\n\n Returns:\n (list): list of data and definition containers incorporating included content\n\n Examples:\n ```python\n pathDdlIncludeDictionary = \"mmcif_ddl-generator.dic\"\n myIo = IoAdapter(raiseExceptions=True)\n containerList = myIo.readFile(inputFilePath=pathDdlIncludeDictionary)\n logger.info(\"Starting container list length (%d)\", len(containerList))\n dIncl = DictionaryInclude()\n inclL = dIncl.processIncludedContent(containerList)\n logger.info(\"Processed included container length (%d)\", len(inclL))\n ```\n\n \"\"\"\n includeD = self.__getIncludeInstructions(containerList, cleanup=cleanup)\n includeContentD = self.__fetchIncludedContent(includeD, cleanup=cleanup)\n return self.__addIncludedContent(containerList, includeContentD)\n
"},{"location":"api_reference/IoAdapterBase/","title":"IoAdapterBase","text":"Base class presenting essential mmCIF I/O methods.
Source code in mmcif/io/IoAdapterBase.py
class IoAdapterBase(object):\n \"\"\"Base class presenting essential mmCIF I/O methods.\"\"\"\n\n def __init__(self, *args, **kwargs):\n \"\"\"General options controlling I/O method operations:\n\n Args:\n raiseExceptions (bool, optional): Flag to indicate that API errors should generate exceptions (True) or catch and log errors (default=False)\n maxInputLineLength (int, optional): Default maximum input line length (default=4096)\n useCharRefs (bool, optional): Replace non-ascii characters with XML Character References (default=True)\n readEncodingErrors (str, optional): treatment of encoding errors at read time (default='ignore')\n timing (bool, optional): log timing details for parsing and processing steps (default=False)\n verbose (bool,optional): log verbose output from wrapped libraries\n\n \"\"\"\n _ = args\n self._raiseExceptions = kwargs.get(\"raiseExceptions\", False)\n self._maxInputLineLength = kwargs.get(\"maxInputLineLength\", 4096)\n self._useCharRefs = kwargs.get(\"useCharRefs\", True)\n self.__logFilePath = None\n self._debug = kwargs.get(\"debug\", False)\n self._timing = kwargs.get(\"timing\", False)\n self._verbose = kwargs.get(\"verbose\", True)\n self._readEncodingErrors = kwargs.get(\"readEncodingErrors\", \"ignore\")\n\n def readFile(self, *args, **kwargs):\n \"\"\"Read file method. (abstract)\n\n Args:\n inputFilePath (string): Input file path/uri\n kw: optional key-value arguments\n\n Returns:\n list of DataContainer Objects: list of data or definition container objects\n \"\"\"\n raise NotImplementedError(\"To be implemented in subclass\")\n\n def writeFile(self, outputFilePath, containerList, **kwargs):\n \"\"\"Write file method - (abstract)\n\n Args:\n outputFilePath (string): output file path\n containerList (list of DataContainer objects): list of data or definition containers objects for output\n\n Returns:\n bool: Completion status\n \"\"\"\n raise NotImplementedError(\"To be implemented in subclass\")\n\n def getReadDiags(self):\n \"\"\"Return any diagnostics from the last read operation. (abstract)\"\"\"\n raise NotImplementedError(\"To be implemented in subclass\")\n\n def _setContainerProperties(self, containerList, **kwargs):\n try:\n for container in containerList:\n for kw in kwargs:\n container.setProp(kw, kwargs[kw])\n except Exception:\n return False\n\n def _getTimeStamp(self):\n utcnow = datetime.datetime.utcnow()\n ts = utcnow.strftime(\"%Y-%m-%d:%H:%M:%S\")\n return ts\n\n def _getCategoryNameList(self, container, lastInOrder=None, selectOrder=None):\n \"\"\"Return an ordered list of categories in the input container subject to\n input category name lists.\n\n Args:\n container (DataContainer object): Input DataContainer object\n lastInOrder (list): names of categories to be shifted to the end of the container.\n selectOrder (list): preferred order of category names\n\n Returns:\n catNameList: list: augmented category list or full list (default)\n \"\"\"\n catNameList = []\n if lastInOrder:\n objNameList = container.getObjNameList()\n lastList = []\n for nm in objNameList:\n if nm in lastInOrder:\n lastList.append(nm)\n continue\n catNameList.append(nm)\n catNameList.extend(lastList)\n elif selectOrder:\n for nm in selectOrder:\n if container.exists(nm):\n catNameList.append(nm)\n else:\n catNameList = container.getObjNameList()\n\n return catNameList\n\n def _setLogFilePath(self, filePath):\n \"\"\"Set the log file path.\"\"\"\n self.__logFilePath = filePath\n\n def _getLogFilePath(self):\n \"\"\"Return current log file path.\"\"\"\n return self.__logFilePath\n\n def _appendToLog(self, stList):\n \"\"\"Append input string list to the current log file -\"\"\"\n if not self.__logFilePath:\n return False\n try:\n with open(self.__logFilePath, \"a\") as ofh:\n ofh.write(\"%s\\n\" % \"\\n\".join(stList))\n return True\n except Exception as e:\n logger.debug(\"Failing with %s\", str(e))\n return True\n\n def _logError(self, msg):\n \"\"\"Convenience method to log error messages and optionally raise general exceptions (PdbxError).\"\"\"\n self._appendToLog([msg])\n if self._raiseExceptions:\n raise PdbxError(msg)\n else:\n logger.error(msg)\n\n def _readLogRecords(self):\n \"\"\"Return the contents of the current log file as list of strings.\"\"\"\n diagL = []\n try:\n with open(self.__logFilePath, \"r\") as ifh:\n for line in ifh:\n diagL.append(line[:-1])\n except Exception as e:\n msg = \"No logfile found %s (%s)\" % (self.__logFilePath, str(e))\n diagL.append(msg)\n logger.debug(msg)\n\n return diagL\n\n def __getDiscriminator(self):\n \"\"\"Internal method returning a string which can discriminate among default file names -\"\"\"\n return str(time.time() * 10000).replace(\".\", \"_\")\n\n def _chooseTemporaryPath(self, filePath, outDirPath=None):\n \"\"\"Select a path for temporary files in the priority order\n outDirpath, directory containing the input filePath, current working directory,\n dynamically created temporary directory.\n\n These choices harmonize various legacy api behaviors.\n \"\"\"\n if outDirPath:\n return outDirPath\n #\n for oPath in [os.path.dirname(filePath), \".\", tempfile.gettempdir()]:\n if os.access(oPath, os.W_OK):\n return oPath\n\n def _getDefaultFileName(self, filePath, fileType=\"cif-parser\", fileExt=\"log\", outDirPath=None, verify=True):\n \"\"\"Return default file path for the target input file subject to input attributes and the output path.\"\"\"\n returnFilePath = None\n try:\n _, fn = os.path.split(filePath)\n bn, _ = os.path.splitext(fn)\n #\n ft = fileType if fileType else \"temp\"\n fex = fileExt if fileExt else \"tmp\"\n #\n sf = \"_\" + ft + \"_P\" + self.__getDiscriminator() + \".\" + fex\n #\n # pth = outDirPath if outDirPath else '.'\n pth = self._chooseTemporaryPath(filePath, outDirPath=outDirPath)\n #\n if verify:\n # test if pth is actually writable ? Throw exception otherwise -\n #\n testfile = tempfile.TemporaryFile(dir=pth)\n testfile.close()\n #\n returnFilePath = os.path.join(pth, bn + sf)\n except Exception as e:\n if self._raiseExceptions:\n raise e\n else:\n logger.error(\"Failed creating default filename for %s type %s with %s\", filePath, fileType, str(e))\n\n return returnFilePath\n\n def _fileExists(self, filePath):\n \"\"\"Verify that input file path exists and is readable.\"\"\"\n try:\n if not os.access(filePath, os.R_OK):\n msg = \"Missing file %r\" % filePath\n self._appendToLog([msg])\n logger.error(msg)\n #\n if self._raiseExceptions:\n raise PdbxError(msg)\n return False\n else:\n logger.debug(\"Reading from file path %s\", filePath)\n return True\n except Exception as e:\n msg = \"File check error for %r with %s \" % (filePath, str(e))\n self._appendToLog([msg])\n if self._raiseExceptions:\n raise PdbxError(msg)\n else:\n logger.error(msg)\n return False\n\n def _cleanupFile(self, test, filePath):\n \"\"\"Remove the input file path subject to the input test condition.\"\"\"\n try:\n if test:\n os.remove(filePath)\n except Exception:\n pass\n\n def _toAscii(self, inputFilePath, outputFilePath, chunkSize=5000, encodingErrors=\"ignore\", readEncodingErrors=\"ignore\"):\n \"\"\"Encode input file to Ascii and write this to the target output file. Handle encoding\n errors according to the input settting ('ignore', 'escape', 'xmlcharrefreplace').\n \"\"\"\n try:\n startTime = time.time()\n chunk = []\n with io.open(inputFilePath, \"r\", encoding=\"utf-8\", errors=readEncodingErrors) as ifh, io.open(outputFilePath, \"w\", encoding=\"ascii\") as ofh:\n for line in ifh:\n # chunk.append(line.encode('ascii', 'xmlcharrefreplace').decode('ascii'))\n chunk.append(line.encode(\"ascii\", encodingErrors).decode(\"ascii\"))\n if len(chunk) == chunkSize:\n ofh.writelines(chunk)\n chunk = []\n ofh.writelines(chunk)\n if self._timing:\n stepTime1 = time.time()\n logger.info(\"Timing text file %s encoded to as ascii in %.4f seconds\", inputFilePath, stepTime1 - startTime)\n return True\n except Exception as e:\n msg = \"Failing text ascii encoding for %s with %s\" % (inputFilePath, str(e))\n self._appendToLog([msg])\n logger.error(msg)\n if self._raiseExceptions:\n raise PdbxError(msg)\n #\n return False\n\n def _uncompress(self, inputFilePath, outputDir):\n \"\"\"Uncompress the input file if the path name has a recognized compression type file extension.file\n\n Return the file name of the uncompressed file (in outDir) or the original input file path.\n\n \"\"\"\n try:\n startTime = time.time()\n _, fn = os.path.split(inputFilePath)\n bn, _ = os.path.splitext(fn)\n outputFilePath = os.path.join(outputDir, bn)\n if inputFilePath.endswith(\".gz\"):\n with gzip.open(inputFilePath, mode=\"rb\") as inpF:\n with io.open(outputFilePath, \"wb\") as outF:\n shutil.copyfileobj(inpF, outF)\n elif inputFilePath.endswith(\".bz2\"):\n with bz2.open(inputFilePath, mode=\"rb\") as inpF:\n with io.open(outputFilePath, \"wb\") as outF:\n shutil.copyfileobj(inpF, outF)\n # elif inputFilePath.endswith(\".xz\"):\n # with lzma.open(inputFilePath, mode=\"rb\") as inpF:\n # with io.open(outputFilePath, \"wb\") as outF:\n # shutil.copyfileobj(inpF, outF)\n elif inputFilePath.endswith(\".zip\"):\n with zipfile.ZipFile(inputFilePath, mode=\"rb\") as inpF:\n with io.open(outputFilePath, \"wb\") as outF:\n shutil.copyfileobj(inpF, outF)\n else:\n outputFilePath = inputFilePath\n if self._timing:\n stepTime1 = time.time()\n logger.info(\"Timing text file %s uncompressed in %.4f seconds\", inputFilePath, stepTime1 - startTime)\n #\n except Exception as e:\n msg = \"Failing uncompress for file %s with %s\" % (inputFilePath, str(e))\n self._appendToLog([msg])\n logger.exception(msg)\n if self._raiseExceptions:\n raise PdbxError(msg)\n\n logger.debug(\"Returning file path %r\", outputFilePath)\n return outputFilePath\n
"},{"location":"api_reference/IoAdapterBase/#mmcif.io.IoAdapterBase.IoAdapterBase.__init__","title":"__init__(self, *args, **kwargs)
special
","text":"General options controlling I/O method operations:
Parameters:
Name Type Description Default raiseExceptions
bool
Flag to indicate that API errors should generate exceptions (True) or catch and log errors (default=False)
required maxInputLineLength
int
Default maximum input line length (default=4096)
required useCharRefs
bool
Replace non-ascii characters with XML Character References (default=True)
required readEncodingErrors
str
treatment of encoding errors at read time (default='ignore')
required timing
bool
log timing details for parsing and processing steps (default=False)
required verbose
bool,optional
log verbose output from wrapped libraries
required Source code in mmcif/io/IoAdapterBase.py
def __init__(self, *args, **kwargs):\n \"\"\"General options controlling I/O method operations:\n\n Args:\n raiseExceptions (bool, optional): Flag to indicate that API errors should generate exceptions (True) or catch and log errors (default=False)\n maxInputLineLength (int, optional): Default maximum input line length (default=4096)\n useCharRefs (bool, optional): Replace non-ascii characters with XML Character References (default=True)\n readEncodingErrors (str, optional): treatment of encoding errors at read time (default='ignore')\n timing (bool, optional): log timing details for parsing and processing steps (default=False)\n verbose (bool,optional): log verbose output from wrapped libraries\n\n \"\"\"\n _ = args\n self._raiseExceptions = kwargs.get(\"raiseExceptions\", False)\n self._maxInputLineLength = kwargs.get(\"maxInputLineLength\", 4096)\n self._useCharRefs = kwargs.get(\"useCharRefs\", True)\n self.__logFilePath = None\n self._debug = kwargs.get(\"debug\", False)\n self._timing = kwargs.get(\"timing\", False)\n self._verbose = kwargs.get(\"verbose\", True)\n self._readEncodingErrors = kwargs.get(\"readEncodingErrors\", \"ignore\")\n
"},{"location":"api_reference/IoAdapterBase/#mmcif.io.IoAdapterBase.IoAdapterBase.getReadDiags","title":"getReadDiags(self)
","text":"Return any diagnostics from the last read operation. (abstract)
Source code in mmcif/io/IoAdapterBase.py
def getReadDiags(self):\n \"\"\"Return any diagnostics from the last read operation. (abstract)\"\"\"\n raise NotImplementedError(\"To be implemented in subclass\")\n
"},{"location":"api_reference/IoAdapterBase/#mmcif.io.IoAdapterBase.IoAdapterBase.readFile","title":"readFile(self, *args, **kwargs)
","text":"Read file method. (abstract)
Args: inputFilePath (string): Input file path/uri kw: optional key-value arguments
Returns:
Type Description list of DataContainer Objects
list of data or definition container objects
Source code in mmcif/io/IoAdapterBase.py
def readFile(self, *args, **kwargs):\n \"\"\"Read file method. (abstract)\n\n Args:\n inputFilePath (string): Input file path/uri\n kw: optional key-value arguments\n\n Returns:\n list of DataContainer Objects: list of data or definition container objects\n \"\"\"\n raise NotImplementedError(\"To be implemented in subclass\")\n
"},{"location":"api_reference/IoAdapterBase/#mmcif.io.IoAdapterBase.IoAdapterBase.writeFile","title":"writeFile(self, outputFilePath, containerList, **kwargs)
","text":"Write file method - (abstract)
Parameters:
Name Type Description Default outputFilePath
string
output file path
required containerList
list of DataContainer objects
list of data or definition containers objects for output
required Returns:
Type Description bool
Completion status
Source code in mmcif/io/IoAdapterBase.py
def writeFile(self, outputFilePath, containerList, **kwargs):\n \"\"\"Write file method - (abstract)\n\n Args:\n outputFilePath (string): output file path\n containerList (list of DataContainer objects): list of data or definition containers objects for output\n\n Returns:\n bool: Completion status\n \"\"\"\n raise NotImplementedError(\"To be implemented in subclass\")\n
"},{"location":"api_reference/IoAdapterCore/","title":"IoAdapterCore","text":"Adapter between Python mmCIF API and Pybind11 wrappers for the PDB C++ Core mmCIF Library.
Source code in mmcif/io/IoAdapterCore.py
class IoAdapterCore(IoAdapterBase):\n \"\"\"Adapter between Python mmCIF API and Pybind11 wrappers for the PDB C++ Core mmCIF Library.\"\"\"\n\n # def __init__(self, *args, **kwargs):\n # super(IoAdapterCore, self).__init__(*args, **kwargs)\n # pylint: disable=arguments-differ\n def readFile(self, inputFilePath, enforceAscii=True, selectList=None, excludeFlag=False, logFilePath=None, outDirPath=None, cleanUp=True, **kwargs):\n \"\"\"Parse the data blocks in the input mmCIF format data file into list of DataContainers(). The data category content within each data block\n is stored a collection of DataCategory objects within each DataContainer.\n\n Args:\n inputFilePath (string): Input file path\n enforceAscii (bool, optional): Flag to requiring pre-filtering operation to convert input file to ASCII encoding. See encoding error options.\n selectList (List, optional): List of data category names to be extracted or excluded from the input file (default: select/extract)\n excludeFlag (bool, optional): Flag to indicate selectList should be treated as an exclusion list\n logFilePath (string, optional): Log file path (if not provided this will be derived from the input file.)\n outDirPath (string, optional): Path for translated/reencoded files and default logfiles.\n cleanUp (bool, optional): Flag to automatically remove logs and temporary files on exit.\n **kwargs: Placeholder for missing keyword arguments.\n\n Returns:\n List of DataContainers: Contents of input file parsed into a list of DataContainer objects.\n \"\"\"\n if kwargs:\n logger.warning(\"Unsupported keyword arguments %s\", kwargs.keys())\n asciiFilePath = None\n filePath = str(inputFilePath)\n # oPath = outDirPath if outDirPath else '.'\n oPath = self._chooseTemporaryPath(inputFilePath, outDirPath=outDirPath)\n try:\n #\n lPath = logFilePath\n if not lPath:\n lPath = self._getDefaultFileName(filePath, fileType=\"cif-parser-log\", outDirPath=oPath)\n #\n self._setLogFilePath(lPath)\n #\n if not self._fileExists(filePath):\n return []\n #\n filePath = self._uncompress(filePath, oPath)\n tPath = filePath\n if enforceAscii:\n asciiFilePath = self._getDefaultFileName(filePath, fileType=\"cif-parser-ascii\", fileExt=\"cif\", outDirPath=oPath)\n encodingErrors = \"xmlcharrefreplace\" if self._useCharRefs else \"ignore\"\n logger.debug(\"Filtering input file to %s using encoding errors as %s\", asciiFilePath, encodingErrors)\n ok = self._toAscii(filePath, asciiFilePath, chunkSize=5000, encodingErrors=encodingErrors, readEncodingErrors=self._readEncodingErrors)\n if ok:\n tPath = asciiFilePath\n #\n readDef = None\n if selectList is not None and selectList:\n readDef = self.__getSelectionDef(selectList, excludeFlag)\n #\n containerL, _ = self.__readData(tPath, readDef=readDef, cleanUp=cleanUp, logFilePath=lPath, maxLineLength=self._maxInputLineLength)\n #\n if cleanUp:\n self._cleanupFile(asciiFilePath, asciiFilePath)\n self._cleanupFile(filePath != str(inputFilePath), filePath)\n self._setContainerProperties(containerL, locator=str(inputFilePath), load_date=self._getTimeStamp(), uid=uuid.uuid4().hex)\n #\n return containerL\n except (PdbxError, PdbxSyntaxError) as ex:\n self._cleanupFile(asciiFilePath and cleanUp, asciiFilePath)\n if self._raiseExceptions:\n raise_from(ex, None)\n # raise ex from None\n except Exception as e:\n self._cleanupFile(asciiFilePath and cleanUp, asciiFilePath)\n msg = \"Failing read for %s with %s\" % (filePath, str(e))\n self._logError(msg)\n\n return []\n\n def getReadDiags(self):\n \"\"\"Recover the diagnostics for the previous readFile() operation.readFile\n\n Returns:\n list of strings: List of parsing and processing diagnostics from last readFile() operation\n \"\"\"\n return self._readLogRecords()\n\n def __getSelectionDef(self, selectList, excludeFlag):\n \"\"\"Internal method to package selection/exclusion list for the C++ parser library.\n\n Returns:\n CifFileReadDef() object: object prepared for parsing library\n \"\"\"\n try:\n readDef = CifFileReadDef()\n if excludeFlag:\n readDef.SetCategoryList(selectList, PdbxType.D)\n else:\n readDef.SetCategoryList(selectList, PdbxType.A)\n return readDef\n except Exception as e:\n msg = \"Failing read selection with %s\" % str(e)\n self._logError(msg)\n return None\n\n def __processReadLogFile(self, inputFilePath):\n \"\"\"Internal method to process logfiles and either log errors or raise exceptions (See: Class PdbxExceptions).\n The behavior is controlled by the class attribute _raiseExcetions.\n\n Returns:\n list of strings: List of records in the input log file\n \"\"\"\n diagL = self._readLogRecords()\n #\n if diagL:\n numErrors = 0\n numSyntaxErrors = 0\n numWarnings = 0\n for diag in diagL:\n if \"ERROR\" in diag:\n numErrors += 1\n if \"WARN\" in diag:\n numWarnings += 1\n if \"syntax\" in diag.lower():\n numSyntaxErrors += 1\n #\n logger.debug(\"%s syntax errors %d warnings %d all errors %d\", inputFilePath, numSyntaxErrors, numWarnings, numErrors)\n #\n if numSyntaxErrors and self._raiseExceptions:\n raise PdbxSyntaxError(\"%s syntax errors %d all errors %d\" % (inputFilePath, numSyntaxErrors, numErrors))\n elif numErrors and self._raiseExceptions:\n raise PdbxError(\"%s error count is %d\" % (inputFilePath, numErrors))\n elif numErrors:\n logger.error(\"%s syntax errors %d all errors %d\", inputFilePath, numSyntaxErrors, numErrors)\n if numWarnings:\n logger.warning(\"%s warnings %d\", inputFilePath, numWarnings)\n\n return diagL\n\n def __processContent(self, cifFileObj):\n \"\"\"Internal method to transfer parsed data from the wrapped input C++ CifFile object into\n the list of Python DataContainer objects.\n\n Args:\n cifFileObj (wrapped CifFile object): Wrapped input C++ CifFile object\n\n Returns:\n list of DataContainer objects: List of Python DataContainer objects\n\n \"\"\"\n containerList = []\n containerNameList = []\n try:\n # ----- Repackage the data content ----\n #\n containerList = []\n containerNameList = []\n containerNameList = list(cifFileObj.GetBlockNames(containerNameList))\n for containerName in containerNameList:\n #\n aContainer = DataContainer(containerName)\n #\n block = cifFileObj.GetBlock(containerName)\n tableNameList = []\n tableNameList = list(block.GetTableNames(tableNameList))\n\n for tableName in tableNameList:\n table = block.GetTable(tableName)\n attributeNameList = list(table.GetColumnNames())\n numRows = table.GetNumRows()\n rowList = []\n for iRow in range(0, numRows):\n row = table.GetRow(iRow)\n # row = table.GetRow(iRow).decode('unicode_escape').encode('utf-8')\n # row = [p.encode('ascii', 'xmlcharrefreplace') for p in table.GetRow(iRow)]\n rowList.append(list(row))\n aCategory = DataCategory(tableName, attributeNameList, rowList, copyInputData=False, raiseExceptions=self._raiseExceptions)\n aContainer.append(aCategory)\n containerList.append(aContainer)\n except Exception as e:\n msg = \"Failing packaging with %s\" % str(e)\n self._logError(msg)\n\n return containerList\n\n def __readData(self, inputFilePath, readDef=None, maxLineLength=1024, logFilePath=None, cleanUp=False):\n \"\"\"Internal method to read input file and return data as a list of DataContainer objects.\n readDef optionally contains a selection of data categories to be returned. Diagnostics\n will be written to logFilePath (persisted if cleanuUp=False).\n\n Args:\n inputFilePath (string): input file path\n readDef (CifFileReadDef object, optional): wrapped CifFileReadDef() object\n maxLineLength (int, optional): Maximum supported line length on input\n logFilePath (string, optional): Log file path\n cleanUp (bool, optional): Flag to remove temporary files on exit\n\n Returns:\n Tuple of lists : DataContainer List, Diagnostics (string) List\n\n \"\"\"\n #\n startTime = time.time()\n containerList = []\n diagL = []\n try:\n if readDef:\n cifFileObj = ParseCifSelective(inputFilePath, readDef, verbose=self._verbose, intCaseSense=0, maxLineLength=maxLineLength, nullValue=\"?\", parseLogFileName=logFilePath)\n else:\n cifFileObj = ParseCifSimple(inputFilePath, verbose=self._verbose, intCaseSense=0, maxLineLength=maxLineLength, nullValue=\"?\", parseLogFileName=logFilePath)\n #\n # --- Process/Handle read errors ----\n #\n diagL = self.__processReadLogFile(inputFilePath)\n logger.debug(\"Diagnostic count %d values %r\", len(diagL), diagL)\n #\n if self._timing:\n stepTime1 = time.time()\n logger.info(\"Timing parsed %r in %.4f seconds\", inputFilePath, stepTime1 - startTime)\n #\n containerList = self.__processContent(cifFileObj)\n #\n self._cleanupFile(cleanUp, logFilePath)\n if self._timing:\n stepTime2 = time.time()\n logger.info(\"Timing api load in %.4f seconds read time %.4f seconds\", stepTime2 - stepTime1, stepTime2 - startTime)\n #\n return containerList, diagL\n except (PdbxError, PdbxSyntaxError) as ex:\n self._cleanupFile(cleanUp, logFilePath)\n if self._raiseExceptions:\n raise_from(ex, None)\n except Exception as e:\n self._cleanupFile(cleanUp, logFilePath)\n msg = \"Failing read for %s with %s\" % (inputFilePath, str(e))\n self._logError(msg)\n\n return containerList, diagL\n\n def writeFile(self, outputFilePath, containerList=None, doubleQuotingFlag=False, maxLineLength=900, enforceAscii=True, lastInOrder=None, selectOrder=None, **kwargs):\n \"\"\"Write input list of data containers to the specified output file path in mmCIF format.\n\n Args:\n outputFilePath (string): output file path\n containerList (list DataContainer objects, optional):\n maxLineLength (int, optional): Maximum length of output line (content is wrapped beyond this length)\n enforceAscii (bool, optional): Filter output (not implemented - content must be ascii compatible on input)\n lastInOrder (list of category names, optional): Move data categories in this list to end of each data block\n selectOrder (list of category names, optional): Write only data categories on this list.\n **kwargs: Placeholder for unsupported key value pairs\n\n Returns:\n bool: Completion status\n\n\n \"\"\"\n _ = enforceAscii\n lastInOrder = lastInOrder if lastInOrder else [\"pdbx_nonpoly_scheme\", \"pdbx_poly_seq_scheme\", \"atom_site\", \"atom_site_anisotrop\"]\n containerL = containerList if containerList else []\n if kwargs:\n logger.warning(\"Unsupported keyword arguments %s\", kwargs.keys())\n try:\n startTime = time.time()\n logger.debug(\"write container length %d\", len(containerL))\n # (CifFile args: placeholder, verbose: bool, caseSense: Char::eCompareType, maxLineLength: int, nullValue: str)\n cF = CifFile(True, self._verbose, 0, maxLineLength, \"?\")\n for container in containerL:\n containerName = container.getName()\n logger.debug(\"writing container %s\", containerName)\n cF.AddBlock(containerName)\n block = cF.GetBlock(containerName)\n #\n # objNameList = container.getObjNameList()\n # logger.debug(\"write category length %d\\n\" % len(objNameList))\n #\n # Reorder/Filter - container object list-\n objNameList = container.filterObjectNameList(lastInOrder=lastInOrder, selectOrder=selectOrder)\n logger.debug(\"write category names %r\", objNameList)\n #\n for objName in objNameList:\n name, attributeNameList, rowList = container.getObj(objName).get()\n table = block.AddTable(name)\n for attributeName in attributeNameList:\n table.AddColumn(attributeName)\n try:\n rLen = len(attributeNameList)\n for ii, row in enumerate(rowList):\n table.AddRow()\n table.FillRow(ii, [str(row[jj]) if row[jj] is not None else \"?\" for jj in range(0, rLen)])\n except Exception as e:\n logger.error(\"Exception for %s preparing category %r (%d) attributes %r for writing %s\", outputFilePath, name, len(rowList), attributeNameList, str(e))\n #\n block.WriteTable(table)\n #\n if self._timing:\n stepTime1 = time.time()\n logger.info(\"Timing %d container(s) api loaded in %.4f seconds\", len(containerL), stepTime1 - startTime)\n if self._debug:\n self.__dumpBlocks(cF)\n if doubleQuotingFlag:\n cF.SetQuoting(cF.eDOUBLE)\n #\n cF.Write(str(outputFilePath))\n if self._timing:\n stepTime2 = time.time()\n logger.info(\"Timing %d container(s) written in %.4f seconds total time %.4f\", len(containerList), stepTime2 - stepTime1, stepTime2 - startTime)\n return True\n\n except Exception as e:\n msg = \"Write failing for file %s with %s\" % (outputFilePath, str(e))\n self._logError(msg)\n return False\n\n def __dumpBlocks(self, cf):\n \"\"\"Internal method to log the contents of the input wrapped CifFile object.\n\n Args:\n cf (CifFile object): wrapped CifFile object.\n \"\"\"\n try:\n logger.info(\"cif file %r\", cf)\n blockNameList = []\n blockNameList = cf.GetBlockNames(blockNameList)\n #\n logger.info(\" block name list %r\", repr(blockNameList))\n for blockName in blockNameList:\n #\n block = cf.GetBlock(blockName)\n tableNameList = []\n tableNameList = list(block.GetTableNames(tableNameList))\n logger.info(\"tables name list %r\", repr(tableNameList))\n for tableName in tableNameList:\n logger.info(\"table name %r\", tableName)\n ok = block.IsTablePresent(tableName)\n logger.info(\"table present %r\", ok)\n table = block.GetTable(tableName)\n\n attributeNameList = list(table.GetColumnNames())\n logger.info(\"Attribute name list %r\", repr(attributeNameList))\n numRows = table.GetNumRows()\n logger.info(\"row length %r\", numRows)\n for iRow in range(0, numRows):\n row = table.GetRow(iRow)\n logger.info(\"Attribute name list %r\", row)\n except Exception as e:\n logger.exception(\"dump failing with %s\", str(e))\n
"},{"location":"api_reference/IoAdapterCore/#mmcif.io.IoAdapterCore.IoAdapterCore.getReadDiags","title":"getReadDiags(self)
","text":"Recover the diagnostics for the previous readFile() operation.readFile
Returns:
Type Description list of strings
List of parsing and processing diagnostics from last readFile() operation
Source code in mmcif/io/IoAdapterCore.py
def getReadDiags(self):\n \"\"\"Recover the diagnostics for the previous readFile() operation.readFile\n\n Returns:\n list of strings: List of parsing and processing diagnostics from last readFile() operation\n \"\"\"\n return self._readLogRecords()\n
"},{"location":"api_reference/IoAdapterCore/#mmcif.io.IoAdapterCore.IoAdapterCore.readFile","title":"readFile(self, inputFilePath, enforceAscii=True, selectList=None, excludeFlag=False, logFilePath=None, outDirPath=None, cleanUp=True, **kwargs)
","text":"Parse the data blocks in the input mmCIF format data file into list of DataContainers(). The data category content within each data block is stored a collection of DataCategory objects within each DataContainer.
Parameters:
Name Type Description Default inputFilePath
string
Input file path
required enforceAscii
bool
Flag to requiring pre-filtering operation to convert input file to ASCII encoding. See encoding error options.
True
selectList
List
List of data category names to be extracted or excluded from the input file (default: select/extract)
None
excludeFlag
bool
Flag to indicate selectList should be treated as an exclusion list
False
logFilePath
string
Log file path (if not provided this will be derived from the input file.)
None
outDirPath
string
Path for translated/reencoded files and default logfiles.
None
cleanUp
bool
Flag to automatically remove logs and temporary files on exit.
True
**kwargs
Placeholder for missing keyword arguments.
{}
Returns:
Type Description List of DataContainers
Contents of input file parsed into a list of DataContainer objects.
Source code in mmcif/io/IoAdapterCore.py
def readFile(self, inputFilePath, enforceAscii=True, selectList=None, excludeFlag=False, logFilePath=None, outDirPath=None, cleanUp=True, **kwargs):\n \"\"\"Parse the data blocks in the input mmCIF format data file into list of DataContainers(). The data category content within each data block\n is stored a collection of DataCategory objects within each DataContainer.\n\n Args:\n inputFilePath (string): Input file path\n enforceAscii (bool, optional): Flag to requiring pre-filtering operation to convert input file to ASCII encoding. See encoding error options.\n selectList (List, optional): List of data category names to be extracted or excluded from the input file (default: select/extract)\n excludeFlag (bool, optional): Flag to indicate selectList should be treated as an exclusion list\n logFilePath (string, optional): Log file path (if not provided this will be derived from the input file.)\n outDirPath (string, optional): Path for translated/reencoded files and default logfiles.\n cleanUp (bool, optional): Flag to automatically remove logs and temporary files on exit.\n **kwargs: Placeholder for missing keyword arguments.\n\n Returns:\n List of DataContainers: Contents of input file parsed into a list of DataContainer objects.\n \"\"\"\n if kwargs:\n logger.warning(\"Unsupported keyword arguments %s\", kwargs.keys())\n asciiFilePath = None\n filePath = str(inputFilePath)\n # oPath = outDirPath if outDirPath else '.'\n oPath = self._chooseTemporaryPath(inputFilePath, outDirPath=outDirPath)\n try:\n #\n lPath = logFilePath\n if not lPath:\n lPath = self._getDefaultFileName(filePath, fileType=\"cif-parser-log\", outDirPath=oPath)\n #\n self._setLogFilePath(lPath)\n #\n if not self._fileExists(filePath):\n return []\n #\n filePath = self._uncompress(filePath, oPath)\n tPath = filePath\n if enforceAscii:\n asciiFilePath = self._getDefaultFileName(filePath, fileType=\"cif-parser-ascii\", fileExt=\"cif\", outDirPath=oPath)\n encodingErrors = \"xmlcharrefreplace\" if self._useCharRefs else \"ignore\"\n logger.debug(\"Filtering input file to %s using encoding errors as %s\", asciiFilePath, encodingErrors)\n ok = self._toAscii(filePath, asciiFilePath, chunkSize=5000, encodingErrors=encodingErrors, readEncodingErrors=self._readEncodingErrors)\n if ok:\n tPath = asciiFilePath\n #\n readDef = None\n if selectList is not None and selectList:\n readDef = self.__getSelectionDef(selectList, excludeFlag)\n #\n containerL, _ = self.__readData(tPath, readDef=readDef, cleanUp=cleanUp, logFilePath=lPath, maxLineLength=self._maxInputLineLength)\n #\n if cleanUp:\n self._cleanupFile(asciiFilePath, asciiFilePath)\n self._cleanupFile(filePath != str(inputFilePath), filePath)\n self._setContainerProperties(containerL, locator=str(inputFilePath), load_date=self._getTimeStamp(), uid=uuid.uuid4().hex)\n #\n return containerL\n except (PdbxError, PdbxSyntaxError) as ex:\n self._cleanupFile(asciiFilePath and cleanUp, asciiFilePath)\n if self._raiseExceptions:\n raise_from(ex, None)\n # raise ex from None\n except Exception as e:\n self._cleanupFile(asciiFilePath and cleanUp, asciiFilePath)\n msg = \"Failing read for %s with %s\" % (filePath, str(e))\n self._logError(msg)\n\n return []\n
"},{"location":"api_reference/IoAdapterCore/#mmcif.io.IoAdapterCore.IoAdapterCore.writeFile","title":"writeFile(self, outputFilePath, containerList=None, doubleQuotingFlag=False, maxLineLength=900, enforceAscii=True, lastInOrder=None, selectOrder=None, **kwargs)
","text":"Write input list of data containers to the specified output file path in mmCIF format.
Parameters:
Name Type Description Default outputFilePath
string
output file path
required containerList
list DataContainer objects
None
maxLineLength
int
Maximum length of output line (content is wrapped beyond this length)
900
enforceAscii
bool
Filter output (not implemented - content must be ascii compatible on input)
True
lastInOrder
list of category names
Move data categories in this list to end of each data block
None
selectOrder
list of category names
Write only data categories on this list.
None
**kwargs
Placeholder for unsupported key value pairs
{}
Returns:
Type Description bool
Completion status
Source code in mmcif/io/IoAdapterCore.py
def writeFile(self, outputFilePath, containerList=None, doubleQuotingFlag=False, maxLineLength=900, enforceAscii=True, lastInOrder=None, selectOrder=None, **kwargs):\n \"\"\"Write input list of data containers to the specified output file path in mmCIF format.\n\n Args:\n outputFilePath (string): output file path\n containerList (list DataContainer objects, optional):\n maxLineLength (int, optional): Maximum length of output line (content is wrapped beyond this length)\n enforceAscii (bool, optional): Filter output (not implemented - content must be ascii compatible on input)\n lastInOrder (list of category names, optional): Move data categories in this list to end of each data block\n selectOrder (list of category names, optional): Write only data categories on this list.\n **kwargs: Placeholder for unsupported key value pairs\n\n Returns:\n bool: Completion status\n\n\n \"\"\"\n _ = enforceAscii\n lastInOrder = lastInOrder if lastInOrder else [\"pdbx_nonpoly_scheme\", \"pdbx_poly_seq_scheme\", \"atom_site\", \"atom_site_anisotrop\"]\n containerL = containerList if containerList else []\n if kwargs:\n logger.warning(\"Unsupported keyword arguments %s\", kwargs.keys())\n try:\n startTime = time.time()\n logger.debug(\"write container length %d\", len(containerL))\n # (CifFile args: placeholder, verbose: bool, caseSense: Char::eCompareType, maxLineLength: int, nullValue: str)\n cF = CifFile(True, self._verbose, 0, maxLineLength, \"?\")\n for container in containerL:\n containerName = container.getName()\n logger.debug(\"writing container %s\", containerName)\n cF.AddBlock(containerName)\n block = cF.GetBlock(containerName)\n #\n # objNameList = container.getObjNameList()\n # logger.debug(\"write category length %d\\n\" % len(objNameList))\n #\n # Reorder/Filter - container object list-\n objNameList = container.filterObjectNameList(lastInOrder=lastInOrder, selectOrder=selectOrder)\n logger.debug(\"write category names %r\", objNameList)\n #\n for objName in objNameList:\n name, attributeNameList, rowList = container.getObj(objName).get()\n table = block.AddTable(name)\n for attributeName in attributeNameList:\n table.AddColumn(attributeName)\n try:\n rLen = len(attributeNameList)\n for ii, row in enumerate(rowList):\n table.AddRow()\n table.FillRow(ii, [str(row[jj]) if row[jj] is not None else \"?\" for jj in range(0, rLen)])\n except Exception as e:\n logger.error(\"Exception for %s preparing category %r (%d) attributes %r for writing %s\", outputFilePath, name, len(rowList), attributeNameList, str(e))\n #\n block.WriteTable(table)\n #\n if self._timing:\n stepTime1 = time.time()\n logger.info(\"Timing %d container(s) api loaded in %.4f seconds\", len(containerL), stepTime1 - startTime)\n if self._debug:\n self.__dumpBlocks(cF)\n if doubleQuotingFlag:\n cF.SetQuoting(cF.eDOUBLE)\n #\n cF.Write(str(outputFilePath))\n if self._timing:\n stepTime2 = time.time()\n logger.info(\"Timing %d container(s) written in %.4f seconds total time %.4f\", len(containerList), stepTime2 - stepTime1, stepTime2 - startTime)\n return True\n\n except Exception as e:\n msg = \"Write failing for file %s with %s\" % (outputFilePath, str(e))\n self._logError(msg)\n return False\n
"},{"location":"api_reference/IoAdapterPy/","title":"IoAdapterPy","text":"Python implementation of IoAdapterBase class providing essential read and write methods for mmCIF data files -
Source code in mmcif/io/IoAdapterPy.py
class IoAdapterPy(IoAdapterBase):\n \"\"\"Python implementation of IoAdapterBase class providing essential read and write methods for mmCIF data files -\"\"\"\n\n # def __init__(self, *args, **kwargs):\n # super(IoAdapterPy, self).__init__(*args, **kwargs)\n # pylint: disable=arguments-differ\n def readFile(self, inputFilePath, enforceAscii=False, selectList=None, excludeFlag=False, logFilePath=None, outDirPath=None, cleanUp=False, **kwargs):\n \"\"\"Parse the data blocks in the input mmCIF format data file into list of data or definition containers. The data category content within\n each data block is stored a collection of DataCategory objects within each container.\n\n Args:\n inputFilePath (string): Input file path\n enforceAscii (bool, optional): Flag to requiring ASCII encoding. See encoding error options.\n selectList (List, optional): List of data category names to be extracted or excluded from the input file (default: select/extract)\n excludeFlag (bool, optional): Flag to indicate selectList should be treated as an exclusion list\n logFilePath (string, optional): Log file path (if not provided this will be derived from the input file.)\n outDirPath (string, optional): Path for translated/re-encoded files and default logfiles.\n cleanUp (bool, optional): Flag to automatically remove logs and temporary files on exit.\n timeout (float, optional): Timeout in seconds for fetching data from remote urls\n **kwargs: Placeholder for missing keyword arguments.\n\n Returns:\n List of DataContainers: Contents of input file parsed into a list of DataContainer objects.\n\n \"\"\"\n timeout = kwargs.pop(\"timeout\", None)\n\n if kwargs:\n logger.warning(\"Unsupported keyword arguments %s\", kwargs.keys())\n filePath = str(inputFilePath)\n # oPath = outDirPath if outDirPath else '.'\n oPath = self._chooseTemporaryPath(inputFilePath, outDirPath=outDirPath)\n containerList = []\n if enforceAscii:\n encoding = \"ascii\"\n else:\n encoding = \"utf-8\"\n try:\n #\n lPath = logFilePath\n if not lPath:\n lPath = self._getDefaultFileName(filePath, fileType=\"cif-parser-log\", outDirPath=oPath)\n #\n self._setLogFilePath(lPath)\n # ---\n if self.__isLocal(filePath) and not self._fileExists(filePath):\n return []\n #\n if sys.version_info[0] > 2:\n if self.__isLocal(filePath):\n filePath = self._uncompress(filePath, oPath)\n with open(filePath, \"r\", encoding=encoding, errors=self._readEncodingErrors) as ifh:\n pRd = PdbxReader(ifh)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n if filePath.endswith(\".gz\"):\n customHeader = {\"Accept-Encoding\": \"gzip\"}\n with closing(requests.get(filePath, headers=customHeader, timeout=timeout)) as ifh:\n if self._raiseExceptions:\n ifh.raise_for_status()\n gzit = gzip.GzipFile(fileobj=io.BytesIO(ifh.content))\n it = (line.decode(encoding, \"ignore\") for line in gzit)\n pRd = PdbxReader(it)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n with closing(requests.get(filePath, timeout=timeout)) as ifh:\n if self._raiseExceptions:\n ifh.raise_for_status()\n it = (line.decode(encoding, \"ignore\") + \"\\n\" for line in ifh.iter_lines())\n pRd = PdbxReader(it)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n if self.__isLocal(filePath):\n filePath = self._uncompress(filePath, oPath)\n if enforceAscii:\n with io.open(filePath, \"r\", encoding=encoding, errors=self._readEncodingErrors) as ifh:\n pRd = PdbxReader(ifh)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n with open(filePath, \"r\") as ifh:\n pRd = PdbxReader(ifh)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n if filePath.endswith(\".gz\"):\n customHeader = {\"Accept-Encoding\": \"gzip\"}\n with closing(requests.get(filePath, headers=customHeader, timeout=timeout)) as ifh:\n if self._raiseExceptions:\n ifh.raise_for_status()\n gzit = gzip.GzipFile(fileobj=io.BytesIO(ifh.content))\n it = (line.decode(encoding, \"ignore\") for line in gzit)\n pRd = PdbxReader(it)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n with closing(requests.get(filePath, timeout=timeout)) as ifh:\n if self._raiseExceptions:\n ifh.raise_for_status()\n it = (line.decode(encoding, \"ignore\") + \"\\n\" for line in ifh.iter_lines())\n pRd = PdbxReader(it)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n if cleanUp:\n self._cleanupFile(lPath, lPath)\n self._cleanupFile(filePath != str(inputFilePath), filePath)\n self._setContainerProperties(containerList, locator=str(inputFilePath), load_date=self._getTimeStamp(), uid=uuid.uuid4().hex)\n except (PdbxError, PdbxSyntaxError) as ex:\n msg = \"File %r with %s\" % (filePath, str(ex))\n self._appendToLog([msg])\n self._cleanupFile(lPath and cleanUp, lPath)\n if self._raiseExceptions:\n raise_from(ex, None)\n # raise ex from None\n except Exception as e:\n msg = \"File %r with %s\" % (filePath, str(e))\n self._appendToLog([msg])\n self._cleanupFile(lPath and cleanUp, lPath)\n if self._raiseExceptions:\n raise e\n else:\n logger.error(\"Failing read for %s with %s\", filePath, str(e))\n return containerList\n\n def getReadDiags(self):\n \"\"\"Return diagnostics from last readFile operation. This will NOT be an exhaustive list but\n rather the particular failure that raised a parsing exception.\n \"\"\"\n return self._readLogRecords()\n\n def writeFile(\n self,\n outputFilePath,\n containerList,\n maxLineLength=900,\n enforceAscii=True,\n lastInOrder=None,\n selectOrder=None,\n columnAlignFlag=True,\n useStopTokens=False,\n formattingStep=None,\n **kwargs\n ):\n \"\"\"Write input list of data containers to the specified output file path in mmCIF format.\n\n Args:\n outputFilePath (string): output file path\n containerList (list DataContainer objects, optional)\n maxLineLength (int, optional): Maximum length of output line (content is wrapped beyond this length)\n enforceAscii (bool, optional): Filter output (not implemented - content must be ascii compatible on input)\n lastInOrder (list of category names, optional): Move data categories in this list to end of each data block\n selectOrder (list of category names, optional): Write only data categories on this list.\n\n columnAlignFlag (bool, optional): Format the output in aligned columns (default=True) (Native Python Only)\n useStopTokens (bool, optional): Include terminating 'stop_' tokens at the end of mmCIF categories (loop_'s) (Native Python only)\n formattingStep (int, optional): The number row samples within each category used to estimate maximum column width for data alignment (Native Python only)\n **kwargs: Placeholder for unsupported key value pairs\n\n Returns:\n bool: Completion status\n\n\n \"\"\"\n lastInOrder = lastInOrder if lastInOrder else [\"pdbx_nonpoly_scheme\", \"pdbx_poly_seq_scheme\", \"atom_site\", \"atom_site_anisotrop\"]\n if kwargs:\n logger.warning(\"Unsupported keyword arguments %s\", kwargs.keys())\n try:\n if enforceAscii:\n encoding = \"ascii\"\n else:\n encoding = \"utf-8\"\n #\n if sys.version_info[0] > 2:\n with open(outputFilePath, \"w\", encoding=encoding) as ofh:\n self.__writeFile(\n ofh,\n containerList,\n maxLineLength=maxLineLength,\n columnAlignFlag=columnAlignFlag,\n lastInOrder=lastInOrder,\n selectOrder=selectOrder,\n useStopTokens=useStopTokens,\n formattingStep=formattingStep,\n enforceAscii=enforceAscii,\n cnvCharRefs=self._useCharRefs,\n )\n else:\n if enforceAscii:\n with io.open(outputFilePath, \"w\", encoding=encoding) as ofh:\n self.__writeFile(\n ofh,\n containerList,\n maxLineLength=maxLineLength,\n columnAlignFlag=columnAlignFlag,\n lastInOrder=lastInOrder,\n selectOrder=selectOrder,\n useStopTokens=useStopTokens,\n formattingStep=formattingStep,\n enforceAscii=enforceAscii,\n cnvCharRefs=self._useCharRefs,\n )\n else:\n with open(outputFilePath, \"wb\") as ofh:\n self.__writeFile(\n ofh,\n containerList,\n maxLineLength=maxLineLength,\n columnAlignFlag=columnAlignFlag,\n lastInOrder=lastInOrder,\n selectOrder=selectOrder,\n useStopTokens=useStopTokens,\n formattingStep=formattingStep,\n enforceAscii=enforceAscii,\n cnvCharRefs=self._useCharRefs,\n )\n return True\n except Exception as ex:\n if self._raiseExceptions:\n raise_from(ex, None)\n else:\n logger.exception(\"Failing write for %s with %s\", outputFilePath, str(ex))\n logger.error(\"Failing write for %s with %s\", outputFilePath, str(ex))\n\n return False\n\n def __writeFile(\n self,\n ofh,\n containerList,\n maxLineLength=900,\n columnAlignFlag=True,\n lastInOrder=None,\n selectOrder=None,\n useStopTokens=False,\n formattingStep=None,\n enforceAscii=False,\n cnvCharRefs=False,\n ):\n \"\"\"Internal method mapping arguments to PDBxWriter API.\"\"\"\n #\n pdbxW = PdbxWriter(ofh)\n pdbxW.setUseStopTokens(flag=useStopTokens)\n pdbxW.setMaxLineLength(numChars=maxLineLength)\n pdbxW.setAlignmentFlag(flag=columnAlignFlag)\n pdbxW.setRowPartition(numParts=formattingStep)\n pdbxW.setConvertCharRefs(flag=cnvCharRefs)\n pdbxW.setSetEnforceAscii(enforceAscii)\n pdbxW.write(containerList, lastInOrder=lastInOrder, selectOrder=selectOrder)\n\n def __isLocal(self, locator):\n try:\n locSp = urlsplit(locator)\n return locSp.scheme in [\"\", \"file\"]\n except Exception as e:\n logger.exception(\"For locator %r failing with %s\", locator, str(e))\n return None\n
"},{"location":"api_reference/IoAdapterPy/#mmcif.io.IoAdapterPy.IoAdapterPy.getReadDiags","title":"getReadDiags(self)
","text":"Return diagnostics from last readFile operation. This will NOT be an exhaustive list but rather the particular failure that raised a parsing exception.
Source code in mmcif/io/IoAdapterPy.py
def getReadDiags(self):\n \"\"\"Return diagnostics from last readFile operation. This will NOT be an exhaustive list but\n rather the particular failure that raised a parsing exception.\n \"\"\"\n return self._readLogRecords()\n
"},{"location":"api_reference/IoAdapterPy/#mmcif.io.IoAdapterPy.IoAdapterPy.readFile","title":"readFile(self, inputFilePath, enforceAscii=False, selectList=None, excludeFlag=False, logFilePath=None, outDirPath=None, cleanUp=False, **kwargs)
","text":"Parse the data blocks in the input mmCIF format data file into list of data or definition containers. The data category content within each data block is stored a collection of DataCategory objects within each container.
Parameters:
Name Type Description Default inputFilePath
string
Input file path
required enforceAscii
bool
Flag to requiring ASCII encoding. See encoding error options.
False
selectList
List
List of data category names to be extracted or excluded from the input file (default: select/extract)
None
excludeFlag
bool
Flag to indicate selectList should be treated as an exclusion list
False
logFilePath
string
Log file path (if not provided this will be derived from the input file.)
None
outDirPath
string
Path for translated/re-encoded files and default logfiles.
None
cleanUp
bool
Flag to automatically remove logs and temporary files on exit.
False
timeout
float
Timeout in seconds for fetching data from remote urls
required **kwargs
Placeholder for missing keyword arguments.
{}
Returns:
Type Description List of DataContainers
Contents of input file parsed into a list of DataContainer objects.
Source code in mmcif/io/IoAdapterPy.py
def readFile(self, inputFilePath, enforceAscii=False, selectList=None, excludeFlag=False, logFilePath=None, outDirPath=None, cleanUp=False, **kwargs):\n \"\"\"Parse the data blocks in the input mmCIF format data file into list of data or definition containers. The data category content within\n each data block is stored a collection of DataCategory objects within each container.\n\n Args:\n inputFilePath (string): Input file path\n enforceAscii (bool, optional): Flag to requiring ASCII encoding. See encoding error options.\n selectList (List, optional): List of data category names to be extracted or excluded from the input file (default: select/extract)\n excludeFlag (bool, optional): Flag to indicate selectList should be treated as an exclusion list\n logFilePath (string, optional): Log file path (if not provided this will be derived from the input file.)\n outDirPath (string, optional): Path for translated/re-encoded files and default logfiles.\n cleanUp (bool, optional): Flag to automatically remove logs and temporary files on exit.\n timeout (float, optional): Timeout in seconds for fetching data from remote urls\n **kwargs: Placeholder for missing keyword arguments.\n\n Returns:\n List of DataContainers: Contents of input file parsed into a list of DataContainer objects.\n\n \"\"\"\n timeout = kwargs.pop(\"timeout\", None)\n\n if kwargs:\n logger.warning(\"Unsupported keyword arguments %s\", kwargs.keys())\n filePath = str(inputFilePath)\n # oPath = outDirPath if outDirPath else '.'\n oPath = self._chooseTemporaryPath(inputFilePath, outDirPath=outDirPath)\n containerList = []\n if enforceAscii:\n encoding = \"ascii\"\n else:\n encoding = \"utf-8\"\n try:\n #\n lPath = logFilePath\n if not lPath:\n lPath = self._getDefaultFileName(filePath, fileType=\"cif-parser-log\", outDirPath=oPath)\n #\n self._setLogFilePath(lPath)\n # ---\n if self.__isLocal(filePath) and not self._fileExists(filePath):\n return []\n #\n if sys.version_info[0] > 2:\n if self.__isLocal(filePath):\n filePath = self._uncompress(filePath, oPath)\n with open(filePath, \"r\", encoding=encoding, errors=self._readEncodingErrors) as ifh:\n pRd = PdbxReader(ifh)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n if filePath.endswith(\".gz\"):\n customHeader = {\"Accept-Encoding\": \"gzip\"}\n with closing(requests.get(filePath, headers=customHeader, timeout=timeout)) as ifh:\n if self._raiseExceptions:\n ifh.raise_for_status()\n gzit = gzip.GzipFile(fileobj=io.BytesIO(ifh.content))\n it = (line.decode(encoding, \"ignore\") for line in gzit)\n pRd = PdbxReader(it)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n with closing(requests.get(filePath, timeout=timeout)) as ifh:\n if self._raiseExceptions:\n ifh.raise_for_status()\n it = (line.decode(encoding, \"ignore\") + \"\\n\" for line in ifh.iter_lines())\n pRd = PdbxReader(it)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n if self.__isLocal(filePath):\n filePath = self._uncompress(filePath, oPath)\n if enforceAscii:\n with io.open(filePath, \"r\", encoding=encoding, errors=self._readEncodingErrors) as ifh:\n pRd = PdbxReader(ifh)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n with open(filePath, \"r\") as ifh:\n pRd = PdbxReader(ifh)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n if filePath.endswith(\".gz\"):\n customHeader = {\"Accept-Encoding\": \"gzip\"}\n with closing(requests.get(filePath, headers=customHeader, timeout=timeout)) as ifh:\n if self._raiseExceptions:\n ifh.raise_for_status()\n gzit = gzip.GzipFile(fileobj=io.BytesIO(ifh.content))\n it = (line.decode(encoding, \"ignore\") for line in gzit)\n pRd = PdbxReader(it)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n with closing(requests.get(filePath, timeout=timeout)) as ifh:\n if self._raiseExceptions:\n ifh.raise_for_status()\n it = (line.decode(encoding, \"ignore\") + \"\\n\" for line in ifh.iter_lines())\n pRd = PdbxReader(it)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n if cleanUp:\n self._cleanupFile(lPath, lPath)\n self._cleanupFile(filePath != str(inputFilePath), filePath)\n self._setContainerProperties(containerList, locator=str(inputFilePath), load_date=self._getTimeStamp(), uid=uuid.uuid4().hex)\n except (PdbxError, PdbxSyntaxError) as ex:\n msg = \"File %r with %s\" % (filePath, str(ex))\n self._appendToLog([msg])\n self._cleanupFile(lPath and cleanUp, lPath)\n if self._raiseExceptions:\n raise_from(ex, None)\n # raise ex from None\n except Exception as e:\n msg = \"File %r with %s\" % (filePath, str(e))\n self._appendToLog([msg])\n self._cleanupFile(lPath and cleanUp, lPath)\n if self._raiseExceptions:\n raise e\n else:\n logger.error(\"Failing read for %s with %s\", filePath, str(e))\n return containerList\n
"},{"location":"api_reference/IoAdapterPy/#mmcif.io.IoAdapterPy.IoAdapterPy.writeFile","title":"writeFile(self, outputFilePath, containerList, maxLineLength=900, enforceAscii=True, lastInOrder=None, selectOrder=None, columnAlignFlag=True, useStopTokens=False, formattingStep=None, **kwargs)
","text":"Write input list of data containers to the specified output file path in mmCIF format.
Parameters:
Name Type Description Default outputFilePath
string
output file path
required maxLineLength
int
Maximum length of output line (content is wrapped beyond this length)
900
enforceAscii
bool
Filter output (not implemented - content must be ascii compatible on input)
True
lastInOrder
list of category names
Move data categories in this list to end of each data block
None
selectOrder
list of category names
Write only data categories on this list.
None
columnAlignFlag
bool
Format the output in aligned columns (default=True) (Native Python Only)
True
useStopTokens
bool
Include terminating 'stop_' tokens at the end of mmCIF categories (loop_'s) (Native Python only)
False
formattingStep
int
The number row samples within each category used to estimate maximum column width for data alignment (Native Python only)
None
**kwargs
Placeholder for unsupported key value pairs
{}
Returns:
Type Description bool
Completion status
Source code in mmcif/io/IoAdapterPy.py
def writeFile(\n self,\n outputFilePath,\n containerList,\n maxLineLength=900,\n enforceAscii=True,\n lastInOrder=None,\n selectOrder=None,\n columnAlignFlag=True,\n useStopTokens=False,\n formattingStep=None,\n **kwargs\n):\n \"\"\"Write input list of data containers to the specified output file path in mmCIF format.\n\n Args:\n outputFilePath (string): output file path\n containerList (list DataContainer objects, optional)\n maxLineLength (int, optional): Maximum length of output line (content is wrapped beyond this length)\n enforceAscii (bool, optional): Filter output (not implemented - content must be ascii compatible on input)\n lastInOrder (list of category names, optional): Move data categories in this list to end of each data block\n selectOrder (list of category names, optional): Write only data categories on this list.\n\n columnAlignFlag (bool, optional): Format the output in aligned columns (default=True) (Native Python Only)\n useStopTokens (bool, optional): Include terminating 'stop_' tokens at the end of mmCIF categories (loop_'s) (Native Python only)\n formattingStep (int, optional): The number row samples within each category used to estimate maximum column width for data alignment (Native Python only)\n **kwargs: Placeholder for unsupported key value pairs\n\n Returns:\n bool: Completion status\n\n\n \"\"\"\n lastInOrder = lastInOrder if lastInOrder else [\"pdbx_nonpoly_scheme\", \"pdbx_poly_seq_scheme\", \"atom_site\", \"atom_site_anisotrop\"]\n if kwargs:\n logger.warning(\"Unsupported keyword arguments %s\", kwargs.keys())\n try:\n if enforceAscii:\n encoding = \"ascii\"\n else:\n encoding = \"utf-8\"\n #\n if sys.version_info[0] > 2:\n with open(outputFilePath, \"w\", encoding=encoding) as ofh:\n self.__writeFile(\n ofh,\n containerList,\n maxLineLength=maxLineLength,\n columnAlignFlag=columnAlignFlag,\n lastInOrder=lastInOrder,\n selectOrder=selectOrder,\n useStopTokens=useStopTokens,\n formattingStep=formattingStep,\n enforceAscii=enforceAscii,\n cnvCharRefs=self._useCharRefs,\n )\n else:\n if enforceAscii:\n with io.open(outputFilePath, \"w\", encoding=encoding) as ofh:\n self.__writeFile(\n ofh,\n containerList,\n maxLineLength=maxLineLength,\n columnAlignFlag=columnAlignFlag,\n lastInOrder=lastInOrder,\n selectOrder=selectOrder,\n useStopTokens=useStopTokens,\n formattingStep=formattingStep,\n enforceAscii=enforceAscii,\n cnvCharRefs=self._useCharRefs,\n )\n else:\n with open(outputFilePath, \"wb\") as ofh:\n self.__writeFile(\n ofh,\n containerList,\n maxLineLength=maxLineLength,\n columnAlignFlag=columnAlignFlag,\n lastInOrder=lastInOrder,\n selectOrder=selectOrder,\n useStopTokens=useStopTokens,\n formattingStep=formattingStep,\n enforceAscii=enforceAscii,\n cnvCharRefs=self._useCharRefs,\n )\n return True\n except Exception as ex:\n if self._raiseExceptions:\n raise_from(ex, None)\n else:\n logger.exception(\"Failing write for %s with %s\", outputFilePath, str(ex))\n logger.error(\"Failing write for %s with %s\", outputFilePath, str(ex))\n\n return False\n
"},{"location":"api_reference/Method/","title":"Method","text":"Source code in mmcif/api/Method.py
class MethodDefinition(object):\n def __init__(self, methodId, code=\"calculate\", language=\"Python\", inline=None, priority=None, implementation=None, implementationSource=\"inline\"):\n self.methodId = methodId\n self.language = language\n self.code = code\n self.inline = inline\n self.priority = priority if priority else 1\n self.implementationSource = implementationSource\n self.implementation = implementation\n\n def getId(self):\n return self.methodId\n\n def getLanguage(self):\n return self.language\n\n def getCode(self):\n return self.code\n\n def getInline(self):\n return self.inline\n\n def getImplementation(self):\n return self.implementation\n\n def getImplementationSource(self):\n return self.implementationSource\n\n def getPriority(self):\n return self.priority\n\n def printIt(self, fh=sys.stdout):\n fh.write(\"------------- Method definition -------------\\n\")\n fh.write(\"Id: %s\\n\" % self.methodId)\n fh.write(\"Code: %s\\n\" % self.code)\n fh.write(\"Language: %s\\n\" % str(self.language))\n fh.write(\"Inline text: %s\\n\" % str(self.inline))\n fh.write(\"Implementation: %s\\n\" % str(self.implementation))\n fh.write(\"Implementation source: %s\\n\" % str(self.implementationSource))\n fh.write(\"Priority: %d\\n\" % self.priority)\n\n def __repr__(self):\n oL = []\n oL.append(\"\\n------------- Method definition -------------\")\n oL.append(\"Id: %s\" % self.methodId)\n oL.append(\"Code: %s\" % self.code)\n oL.append(\"Language: %s\" % str(self.language))\n oL.append(\"Inline text: %s\" % str(self.inline))\n oL.append(\"Implementation: %s\" % str(self.implementation))\n oL.append(\"Implementation source: %s\" % str(self.implementationSource))\n oL.append(\"Priority: %d\" % self.priority)\n return \"\\n\".join(oL)\n
Source code in mmcif/api/Method.py
class MethodReference(object):\n def __init__(self, methodId, mType=\"attribute\", category=None, attribute=None):\n self.methodId = methodId\n self.type = mType\n self.categoryName = category\n self.attributeName = attribute\n\n def getId(self):\n return self.methodId\n\n def getType(self):\n return self.type\n\n def getCategoryName(self):\n return self.categoryName\n\n def getAttributeName(self):\n return self.attributeName\n\n def printIt(self, fh=sys.stdout):\n fh.write(\"--------------- Method Reference -----------------\\n\")\n fh.write(\"Id: %s\\n\" % self.methodId)\n fh.write(\"Type: %s\\n\" % self.type)\n fh.write(\"Category name: %s\\n\" % str(self.categoryName))\n fh.write(\"Attribute name: %s\\n\" % str(self.attributeName))\n\n def __repr__(self):\n oL = []\n oL.append(\"--------------- Method Reference -----------------\")\n oL.append(\"Id: %s\" % self.methodId)\n oL.append(\"Type: %s\" % self.type)\n oL.append(\"Category name: %s\" % str(self.categoryName))\n oL.append(\"Attribute name: %s\" % str(self.attributeName))\n return \"\\n\".join(oL)\n
"},{"location":"api_reference/MethodUtils/","title":"MethodUtils","text":"Source code in mmcif/api/MethodUtils.py
class MethodUtils(object):\n def __init__(self, dictContainerList, verbose=False):\n #\n self.__verbose = verbose\n # list of dictionary data & definition containers\n self.__dictContainerList = dictContainerList\n self.__dApi = DictionaryApi(containerList=self.__dictContainerList, consolidate=True, verbose=self.__verbose)\n #\n # Target data container list\n self.__dataContainerList = []\n #\n\n def setDataContainerList(self, dataContainerList):\n self.__dataContainerList = dataContainerList\n\n def getDataContainerList(self):\n return self.__dataContainerList\n\n def getDictionary(self):\n return self.__dApi\n\n def getMethods(self):\n return self.__dApi.getMethodIndex()\n\n def getMethod(self, mId):\n return self.__dApi.getMethod(mId)\n\n def invokeMethods(self, fh=sys.stdout):\n _ = fh\n mI = self.__dApi.getMethodIndex()\n lenD = len(mI)\n i = 0\n for k, mRefL in mI.items():\n for mRef in mRefL:\n i += 1\n mId = mRef.getId()\n mType = mRef.getType()\n categoryName = mRef.getCategoryName()\n attributeName = mRef.getAttributeName()\n #\n logger.debug(\"\\n\")\n logger.debug(\"++++++++++++++++++--------------------\\n\")\n logger.debug(\"Invoking dictionary method on file object: %s (%d/%d)\", k, i, lenD)\n logger.debug(\" + Method id: %s\", mId)\n logger.debug(\" + Type: %s\", mType)\n logger.debug(\" + Category: %s\", categoryName)\n logger.debug(\" + Attribute: %s\", attributeName)\n #\n if mType == \"datablock\":\n logger.debug(\"Invoke datablock method %s\", mId)\n # self.invokeDataBlockMethod(type,self.__dApi.getMethod(id))\n # continue\n #\n for db in self.__dataContainerList:\n if mType == \"category\":\n if not db.exists(categoryName):\n dc = DataCategory(categoryName)\n db.append(dc)\n dObj = db.getObj(categoryName)\n dObj.invokeCategoryMethod(mType, self.__dApi.getMethod(mId), db)\n elif mType == \"attribute\":\n if not db.exists(categoryName):\n dc = DataCategory(categoryName)\n db.append(dc)\n dObj = db.getObj(categoryName)\n # logger.debug(\"invoke - %r %r %r %r\" % (attributeName, type, self.__dApi.getMethod(id), db))\n dObj.invokeAttributeMethod(attributeName, mType, self.__dApi.getMethod(mId), db)\n elif mType == \"datablock\":\n logger.debug(\"Invoke datablock method %s\", mId)\n db.invokeDataBlockMethod(mType, self.__dApi.getMethod(mId), db)\n else:\n pass\n\n def dumpMethods(self, fh=sys.stdout):\n self.__dApi.dumpMethods(fh)\n\n def dumpDictionary(self, fh=sys.stdout):\n lenD = len(self.__dictContainerList)\n fh.write(\"\\n--------------------------------------------\\n\")\n fh.write(\"\\n-----------DUMP DICTIONARY------------------\\n\")\n fh.write(\"Dictionary object list length is: %d\\n\" % lenD)\n i = 1\n for dObj in self.__dictContainerList:\n if dObj.getName():\n fh.write(\"\\n\")\n fh.write(\"++++++++++++++++++--------------------\\n\")\n fh.write(\"Dumping dictionary object named: %s (%d/%d)\\n\" % (dObj.getName(), i, lenD))\n dObj.printIt(fh)\n i += 1\n\n #\n\n def dumpDataFile(self, fh=sys.stdout):\n lenD = len(self.__dataContainerList)\n fh.write(\"\\n--------------------------------------------\\n\")\n fh.write(\"\\n-----------DUMP DATAFILE--------------------\\n\")\n fh.write(\"Data object list length is: %d\\n\" % lenD)\n i = 1\n for dObj in self.__dataContainerList:\n fh.write(\"\\n\")\n fh.write(\"++++++++++++++++++--------------------\\n\")\n fh.write(\"Dumping data file object named: %s (%d/%d)\\n\" % (dObj.getName(), i, lenD))\n dObj.printIt(fh)\n i += 1\n
"},{"location":"api_reference/PdbxContainers/","title":"PdbxContainers","text":"Container base class for data and definition objects.
Source code in mmcif/api/PdbxContainers.py
class ContainerBase(object):\n \"\"\"Container base class for data and definition objects.\"\"\"\n\n def __init__(self, name):\n # The enclosing scope of the data container (e.g. data_/save_)\n self.__name = name\n # List of category names within this container -\n self.__objNameList = []\n # dictionary of DataCategory objects keyed by category name.\n self.__objCatalog = {}\n # dictionary for properties of the container\n self.__propCatalog = {}\n self.__type = None\n\n def __eq__(self, other):\n if not isinstance(other, type(self)):\n return NotImplemented\n return (\n self.__name == other.getName()\n and self.__objNameList == other.getObjNameList()\n and self.__objCatalog == other.getObjCatalog()\n and self.__type == other.getType()\n and self.__propCatalog == other.getPropCatalog()\n )\n\n def __hash__(self):\n return hash((self.__name, tuple(self.__objNameList), self.__type, tuple(self.__objCatalog.items()), tuple(self.__propCatalog.items())))\n\n def getObjCatalog(self):\n return self.__objCatalog\n\n def getPropCatalog(self):\n return self.__propCatalog\n\n def setProp(self, propName, value):\n try:\n self.__propCatalog[propName] = value\n return True\n except Exception:\n return False\n\n def getProp(self, propName):\n try:\n return self.__propCatalog[propName]\n except Exception:\n return None\n\n def getType(self):\n return self.__type\n\n def setType(self, cType):\n self.__type = cType\n\n def getName(self):\n return self.__name\n\n def setName(self, name):\n self.__name = name\n\n def exists(self, name):\n if name in self.__objCatalog:\n return True\n else:\n return False\n\n def getObj(self, name):\n if name in self.__objCatalog:\n return self.__objCatalog[name]\n else:\n return None\n\n def getObjNameList(self):\n return self.__objNameList\n\n def append(self, obj):\n \"\"\"Add the input object to the current object catalog. An existing object\n of the same name will be overwritten.\n \"\"\"\n if obj.getName() is not None:\n if obj.getName() not in self.__objCatalog:\n # self.__objNameList is keeping track of object order here --\n self.__objNameList.append(obj.getName())\n self.__objCatalog[obj.getName()] = obj\n\n def replace(self, obj):\n \"\"\"Replace an existing object with the input object\"\"\"\n if (obj.getName() is not None) and (obj.getName() in self.__objCatalog):\n self.__objCatalog[obj.getName()] = obj\n\n def printIt(self, fh=sys.stdout, pType=\"brief\"):\n fh.write(\"+ %s container: %30s contains %4d categories\\n\" % (self.getType(), self.getName(), len(self.__objNameList)))\n for nm in self.__objNameList:\n fh.write(\"--------------------------------------------\\n\")\n fh.write(\"Data category: %s\\n\" % nm)\n if pType == \"brief\":\n self.__objCatalog[nm].printIt(fh)\n else:\n self.__objCatalog[nm].dumpIt(fh)\n\n def rename(self, curName, newName):\n \"\"\"Change the name of an object in place -\"\"\"\n try:\n i = self.__objNameList.index(curName)\n self.__objNameList[i] = newName\n self.__objCatalog[newName] = self.__objCatalog[curName]\n self.__objCatalog[newName].setName(newName)\n return True\n except Exception:\n return False\n\n def remove(self, curName):\n \"\"\"Remove object by name. Return True on success or False otherwise.\"\"\"\n try:\n if curName in self.__objCatalog:\n del self.__objCatalog[curName]\n i = self.__objNameList.index(curName)\n del self.__objNameList[i]\n return True\n else:\n return False\n except Exception:\n pass\n\n return False\n\n def merge(self, container):\n \"\"\"Merge the contents of the input container with the contents of the current container.\"\"\"\n try:\n objNameList = container.getObjNameList()\n for objName in objNameList:\n self.append(container.getObj(objName))\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n return False\n return True\n\n def filterObjectNameList(self, lastInOrder=None, selectOrder=None):\n \"\"\"Return an ordered list of categories in the input container subject to\n input -\n\n lastInOrder: list: categories to be shifted to the end of the container.\n selectOrder: list: ordered selection of container categories\n\n returns:\n filNameList: list: augmented category list or full list (default)\n \"\"\"\n filNameList = []\n if lastInOrder:\n objNameList = self.__objNameList\n lastList = []\n for nm in objNameList:\n if nm in lastInOrder:\n lastList.append(nm)\n continue\n filNameList.append(nm)\n filNameList.extend(lastList)\n elif selectOrder:\n for nm in selectOrder:\n if self.exists(nm):\n filNameList.append(nm)\n else:\n filNameList = self.__objNameList\n\n return filNameList\n\n def toJSON(self):\n return self.__objCatalog\n
Source code in mmcif/api/PdbxContainers.py
class DefinitionContainer(ContainerBase):\n def __init__(self, name):\n super(DefinitionContainer, self).__init__(name)\n self.setType(\"definition\")\n self.__globalFlag = False\n\n def isCategory(self):\n if self.exists(\"category\"):\n return True\n return False\n\n def isAttribute(self):\n if self.exists(\"item\"):\n return True\n return False\n\n def getGlobal(self):\n return self.__globalFlag\n\n def printIt(self, fh=sys.stdout, pType=\"brief\"):\n fh.write(\"Definition container: %30s contains %4d categories\\n\" % (self.getName(), len(self.getObjNameList())))\n if self.isCategory():\n fh.write(\"Definition type: category\\n\")\n elif self.isAttribute():\n fh.write(\"Definition type: item\\n\")\n else:\n fh.write(\"Definition type: undefined\\n\")\n\n for nm in self.getObjNameList():\n fh.write(\"--------------------------------------------\\n\")\n fh.write(\"Definition category: %s\\n\" % nm)\n if pType == \"brief\":\n self.getObj(nm).printIt(fh)\n else:\n self.getObj(nm).dumpId(fh)\n
Container class for DataCategory objects.
Source code in mmcif/api/PdbxContainers.py
class DataContainer(ContainerBase):\n \"\"\"Container class for DataCategory objects.\"\"\"\n\n def __init__(self, name):\n super(DataContainer, self).__init__(name)\n self.setType(\"data\")\n self.__globalFlag = False\n\n def invokeDataBlockMethod(self, mType, method, db):\n _ = mType\n _ = db\n # self.__currentRow = 1\n exec(method.getInline(), globals(), locals()) # pylint: disable=exec-used\n\n def setGlobal(self):\n self.__globalFlag = True\n\n def getGlobal(self):\n return self.__globalFlag\n
Source code in mmcif/api/PdbxContainers.py
class SaveFrameContainer(ContainerBase):\n def __init__(self, name):\n super(SaveFrameContainer, self).__init__(name)\n self.setType(\"definition\")\n
Class of utilities for CIF-style data names -
Source code in mmcif/api/PdbxContainers.py
class CifName(object):\n \"\"\"Class of utilities for CIF-style data names -\"\"\"\n\n def __init__(self):\n pass\n\n @staticmethod\n def categoryPart(name):\n tname = \"\"\n try:\n if name.startswith(\"_\"):\n tname = name[1:]\n else:\n tname = name\n\n i = tname.find(\".\")\n if i == -1:\n return tname\n else:\n return tname[:i]\n except Exception:\n return tname\n\n @staticmethod\n def attributePart(name):\n try:\n i = name.find(\".\")\n if i == -1:\n return None\n else:\n return name[i + 1 :]\n except Exception:\n return None\n\n @staticmethod\n def itemName(categoryName, attributeName):\n try:\n return \"_\" + str(categoryName) + \".\" + str(attributeName)\n except Exception:\n return None\n
"},{"location":"api_reference/PdbxContainers/#mmcif.api.PdbxContainers.ContainerBase.append","title":"append(self, obj)
","text":"Add the input object to the current object catalog. An existing object of the same name will be overwritten.
Source code in mmcif/api/PdbxContainers.py
def append(self, obj):\n \"\"\"Add the input object to the current object catalog. An existing object\n of the same name will be overwritten.\n \"\"\"\n if obj.getName() is not None:\n if obj.getName() not in self.__objCatalog:\n # self.__objNameList is keeping track of object order here --\n self.__objNameList.append(obj.getName())\n self.__objCatalog[obj.getName()] = obj\n
"},{"location":"api_reference/PdbxContainers/#mmcif.api.PdbxContainers.ContainerBase.filterObjectNameList","title":"filterObjectNameList(self, lastInOrder=None, selectOrder=None)
","text":"Return an ordered list of categories in the input container subject to input -
lastInOrder: list: categories to be shifted to the end of the container. selectOrder: list: ordered selection of container categories
Returns:
Type Description filNameList
list: augmented category list or full list (default)
Source code in mmcif/api/PdbxContainers.py
def filterObjectNameList(self, lastInOrder=None, selectOrder=None):\n \"\"\"Return an ordered list of categories in the input container subject to\n input -\n\n lastInOrder: list: categories to be shifted to the end of the container.\n selectOrder: list: ordered selection of container categories\n\n returns:\n filNameList: list: augmented category list or full list (default)\n \"\"\"\n filNameList = []\n if lastInOrder:\n objNameList = self.__objNameList\n lastList = []\n for nm in objNameList:\n if nm in lastInOrder:\n lastList.append(nm)\n continue\n filNameList.append(nm)\n filNameList.extend(lastList)\n elif selectOrder:\n for nm in selectOrder:\n if self.exists(nm):\n filNameList.append(nm)\n else:\n filNameList = self.__objNameList\n\n return filNameList\n
"},{"location":"api_reference/PdbxContainers/#mmcif.api.PdbxContainers.ContainerBase.merge","title":"merge(self, container)
","text":"Merge the contents of the input container with the contents of the current container.
Source code in mmcif/api/PdbxContainers.py
def merge(self, container):\n \"\"\"Merge the contents of the input container with the contents of the current container.\"\"\"\n try:\n objNameList = container.getObjNameList()\n for objName in objNameList:\n self.append(container.getObj(objName))\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n return False\n return True\n
"},{"location":"api_reference/PdbxContainers/#mmcif.api.PdbxContainers.ContainerBase.remove","title":"remove(self, curName)
","text":"Remove object by name. Return True on success or False otherwise.
Source code in mmcif/api/PdbxContainers.py
def remove(self, curName):\n \"\"\"Remove object by name. Return True on success or False otherwise.\"\"\"\n try:\n if curName in self.__objCatalog:\n del self.__objCatalog[curName]\n i = self.__objNameList.index(curName)\n del self.__objNameList[i]\n return True\n else:\n return False\n except Exception:\n pass\n\n return False\n
"},{"location":"api_reference/PdbxContainers/#mmcif.api.PdbxContainers.ContainerBase.rename","title":"rename(self, curName, newName)
","text":"Change the name of an object in place -
Source code in mmcif/api/PdbxContainers.py
def rename(self, curName, newName):\n \"\"\"Change the name of an object in place -\"\"\"\n try:\n i = self.__objNameList.index(curName)\n self.__objNameList[i] = newName\n self.__objCatalog[newName] = self.__objCatalog[curName]\n self.__objCatalog[newName].setName(newName)\n return True\n except Exception:\n return False\n
"},{"location":"api_reference/PdbxContainers/#mmcif.api.PdbxContainers.ContainerBase.replace","title":"replace(self, obj)
","text":"Replace an existing object with the input object
Source code in mmcif/api/PdbxContainers.py
def replace(self, obj):\n \"\"\"Replace an existing object with the input object\"\"\"\n if (obj.getName() is not None) and (obj.getName() in self.__objCatalog):\n self.__objCatalog[obj.getName()] = obj\n
"},{"location":"api_reference/PdbxExceptions/","title":"PdbxExceptions","text":"Class for catch general errors
Source code in mmcif/io/PdbxExceptions.py
class PdbxError(Exception):\n \"\"\"Class for catch general errors\"\"\"\n
Class for catching syntax errors
Source code in mmcif/io/PdbxExceptions.py
class PdbxSyntaxError(Exception):\n \"\"\"Class for catching syntax errors\"\"\"\n
"},{"location":"api_reference/PdbxReader/","title":"PdbxReader","text":"Utilities for reading mmCIF for data files and dictionaries.
Source code in mmcif/io/PdbxReader.py
class PdbxReader(object):\n \"\"\"Utilities for reading mmCIF for data files and dictionaries.\"\"\"\n\n def __init__(self, ifh):\n \"\"\"ifh - input file handle returned by open()\"\"\"\n #\n self.__curLineNumber = 0\n self.__ifh = ifh\n self.__stateDict = {\"data\": \"ST_DATA_CONTAINER\", \"loop\": \"ST_TABLE\", \"global\": \"ST_GLOBAL_CONTAINER\", \"save\": \"ST_DEFINITION\", \"stop\": \"ST_STOP\"}\n\n def read(self, containerList, selectList=None, excludeFlag=False):\n \"\"\"\n Appends to input list of definition and data containers.\n\n return\n\n \"\"\"\n sL = selectList if selectList else []\n catSelectD = {k: k for k in sL}\n self.__curLineNumber = 0\n try:\n self.__parser(self.__tokenizer(self.__ifh), containerList, categorySelectionD=catSelectD, excludeFlag=excludeFlag)\n except RuntimeError as e:\n # will be raised at the end of token iterator - not an error -\n logger.debug(\"Normal termination after reading %d lines with %s\", self.__curLineNumber, str(e))\n except StopIteration:\n # will be raised at the end of token iterator - not an error -\n logger.debug(\"Normal termination after reading %d lines\", self.__curLineNumber)\n except PdbxSyntaxError as e:\n logger.debug(\"Caught syntax exception at %d\", self.__curLineNumber)\n raise e\n except UnicodeDecodeError as e:\n logger.debug(\"Caught character encoding exception at %d with %s\", self.__curLineNumber, str(e))\n raise PdbxError(\"Character encoding error at line %d\" % self.__curLineNumber)\n except Exception as e:\n raise PdbxError(\"Failing at line %d with %s\" % (self.__curLineNumber, str(e)))\n else:\n raise PdbxError(\"Miscellaneous parsing error at line %d\" % self.__curLineNumber)\n\n def __allSelected(self, container, catSelectD):\n \"\"\"Test the input container for completeness relative to the input category selection dictionary.\"\"\"\n nl = -1\n if catSelectD:\n try:\n nl = container.getObjNameList()\n if len(nl) <= len(catSelectD):\n ok = False\n else:\n ok = True\n logger.debug(\"nl %d length catSelectD %d returning %r\", len(nl), len(catSelectD), ok)\n except Exception:\n ok = False\n else:\n ok = False\n return ok\n\n def __syntaxError(self, errText):\n msg = \" [Line: %d] %s\" % (self.__curLineNumber, errText)\n raise PdbxSyntaxError(msg)\n\n def __getContainerName(self, inWord):\n \"\"\"Returns the name of the data block or saveframe container\"\"\"\n return str(inWord[5:]).strip()\n\n def __getState(self, inWord):\n \"\"\"Identifies reserved syntax elements and assigns an associated state.\n\n on return: (reserved word, state)\n where -\n reserved word - is one of CIF syntax elements:\n data, loop, global, save, or stop\n state - the parser state required to process this next section.\n\n \"\"\"\n i = inWord.find(\"_\")\n if i == -1:\n return None, \"ST_UNKNOWN\"\n\n try:\n rWord = inWord[:i].lower()\n return rWord, self.__stateDict[rWord]\n except Exception:\n return None, \"ST_UNKNOWN\"\n\n def __parser(self, tokenizer, containerList, categorySelectionD=None, excludeFlag=False):\n \"\"\"Parser for PDBx data files and dictionaries.\n\n Input - tokenizer() reentrant method recognizing data item names (_category.attribute)\n quoted strings (single, double and multi-line semi-colon delimited), and unquoted\n strings.\n\n containerList - list-type container for data and definition objects parsed from\n from the input file.\n\n On return:\n The input containerList is appended with data and definition objects -\n \"\"\"\n catSelectD = categorySelectionD if categorySelectionD is not None else {}\n logger.debug(\"Exclude Flag %r Category selection %r\", excludeFlag, catSelectD)\n # Working container - data or definition\n curContainer = None\n # the last container of type data -\n previousDataContainer = None\n #\n # Working category container\n categoryIndex = {}\n curCategory = None\n #\n curRow = None\n state = None\n\n # Find the first reserved word and begin capturing data.\n #\n while True:\n curCatName, curAttName, curQuotedString, curWord = next(tokenizer)\n if curWord is None:\n continue\n reservedWord, state = self.__getState(curWord)\n if reservedWord is not None:\n break\n\n while True:\n #\n # Set the current state -\n #\n # At this point in the processing cycle we are expecting a token containing\n # either a '_category.attribute' or a reserved word.\n #\n if curCatName is not None:\n state = \"ST_KEY_VALUE_PAIR\"\n elif curWord is not None:\n reservedWord, state = self.__getState(curWord)\n else:\n self.__syntaxError(\"Miscellaneous syntax error\")\n return\n\n #\n # Process _category.attribute value assignments\n #\n if state == \"ST_KEY_VALUE_PAIR\":\n try:\n curCategory = categoryIndex[curCatName]\n except KeyError:\n # A new category is encountered - create a container and add a row\n curCategory = categoryIndex[curCatName] = DataCategory(curCatName)\n #\n # check if we have all of the selection\n if not excludeFlag and self.__allSelected(curContainer, catSelectD):\n return\n try:\n if catSelectD:\n if not excludeFlag and curCatName in catSelectD:\n curContainer.append(curCategory)\n elif excludeFlag and curCatName not in catSelectD:\n curContainer.append(curCategory)\n else:\n logger.debug(\"Skipped unselected/excluded category %s\", curCatName)\n else:\n curContainer.append(curCategory)\n except AttributeError:\n self.__syntaxError(\"Category cannot be added to data_ block\")\n return\n\n curRow = []\n curCategory.append(curRow)\n else:\n # Recover the existing row from the category\n try:\n # curRow = curCategory[0]\n curRow = curCategory.getRow(0)\n except IndexError:\n self.__syntaxError(\"Internal index error accessing category data\")\n return\n\n # Check for duplicate attributes and add attribute to table.\n if curAttName in curCategory.getAttributeList():\n self.__syntaxError(\"Duplicate attribute encountered in category\")\n return\n else:\n curCategory.appendAttribute(curAttName)\n\n # Get the data for this attribute from the next token\n tCat, _, curQuotedString, curWord = next(tokenizer)\n\n if tCat is not None or (curQuotedString is None and curWord is None):\n self.__syntaxError(\"Missing data for item _%s.%s\" % (curCatName, curAttName))\n\n if curWord is not None:\n #\n # Validation check token for misplaced reserved words -\n #\n reservedWord, state = self.__getState(curWord)\n if reservedWord is not None:\n self.__syntaxError(\"Unexpected reserved word: %s\" % (reservedWord))\n\n curRow.append(curWord)\n\n elif curQuotedString is not None:\n curRow.append(curQuotedString)\n\n else:\n self.__syntaxError(\"Missing value in item-value pair\")\n\n curCatName, curAttName, curQuotedString, curWord = next(tokenizer)\n continue\n\n #\n # Process a loop_ declaration and associated data -\n #\n elif state == \"ST_TABLE\":\n\n # The category name in the next curCatName,curAttName pair\n # defines the name of the category container.\n curCatName, curAttName, curQuotedString, curWord = next(tokenizer)\n\n if curCatName is None or curAttName is None:\n self.__syntaxError(\"Unexpected token in loop_ declaration\")\n return\n\n # Check for a previous category declaration.\n if curCatName in categoryIndex:\n self.__syntaxError(\"Duplicate category declaration in loop_\")\n return\n\n curCategory = DataCategory(curCatName)\n\n #\n # check if we have all of the selection\n if not excludeFlag and self.__allSelected(curContainer, catSelectD):\n return\n try:\n if catSelectD:\n if not excludeFlag and curCatName in catSelectD:\n curContainer.append(curCategory)\n elif excludeFlag and curCatName not in catSelectD:\n curContainer.append(curCategory)\n else:\n logger.debug(\"Skipped unselected/excluded category %s\", curCatName)\n else:\n curContainer.append(curCategory)\n except AttributeError:\n self.__syntaxError(\"loop_ declaration outside of data_ block or save_ frame\")\n return\n\n curCategory.appendAttribute(curAttName)\n\n # Read the rest of the loop_ declaration\n while True:\n curCatName, curAttName, curQuotedString, curWord = next(tokenizer)\n\n if curCatName is None:\n break\n\n if curCatName != curCategory.getName():\n self.__syntaxError(\"Changed category name in loop_ declaration\")\n return\n\n curCategory.appendAttribute(curAttName)\n\n # If the next token is a 'word', check it for any reserved words -\n if curWord is not None:\n reservedWord, state = self.__getState(curWord)\n if reservedWord is not None:\n if reservedWord == \"stop\":\n return\n else:\n self.__syntaxError(\"Unexpected reserved word after loop declaration: %s\" % (reservedWord))\n\n # Read the table of data for this loop_ -\n while True:\n curRow = []\n curCategory.append(curRow)\n\n for _ in curCategory.getAttributeList():\n if curWord is not None:\n curRow.append(curWord)\n elif curQuotedString is not None:\n curRow.append(curQuotedString)\n\n curCatName, curAttName, curQuotedString, curWord = next(tokenizer)\n\n # loop_ data processing ends if -\n\n # A new _category.attribute is encountered\n if curCatName is not None:\n break\n\n # A reserved word is encountered\n if curWord is not None:\n reservedWord, state = self.__getState(curWord)\n if reservedWord is not None:\n break\n\n continue\n\n elif state == \"ST_DEFINITION\":\n # Ignore trailing unnamed saveframe delimiters e.g. 'save'\n sName = self.__getContainerName(curWord)\n if sName:\n curContainer = DefinitionContainer(sName)\n containerList.append(curContainer)\n categoryIndex = {}\n curCategory = None\n else:\n # reset current container to the last data container\n curContainer = previousDataContainer\n\n curCatName, curAttName, curQuotedString, curWord = next(tokenizer)\n\n elif state == \"ST_DATA_CONTAINER\":\n #\n dName = self.__getContainerName(curWord)\n if not dName:\n dName = \"unidentified\"\n curContainer = DataContainer(dName)\n containerList.append(curContainer)\n categoryIndex = {}\n curCategory = None\n previousDataContainer = curContainer\n curCatName, curAttName, curQuotedString, curWord = next(tokenizer)\n\n elif state == \"ST_STOP\":\n ###\n # curCatName, curAttName, curQuotedString, curWord = tokenizer.next()\n continue\n\n elif state == \"ST_GLOBAL\":\n curContainer = DataContainer(\"blank-global\")\n curContainer.setGlobal()\n containerList.append(curContainer)\n categoryIndex = {}\n curCategory = None\n curCatName, curAttName, curQuotedString, curWord = next(tokenizer)\n\n elif state == \"ST_UNKNOWN\":\n self.__syntaxError(\"Unrecognized syntax element: \" + str(curWord))\n return\n\n def __tokenizer(self, ifh):\n \"\"\"Tokenizer method for the mmCIF syntax file -\n\n Each return/yield from this method returns information about\n the next token in the form of a tuple with the following structure.\n\n (category name, attribute name, quoted strings, words w/o quotes or white space)\n\n\n \"\"\"\n #\n # Regex definition for mmCIF syntax - semi-colon delimited strings are handled\n # outside of this regex.\n # Differentiated the regular expression to the better handle embedded quotes.\n #\n mmcifRe = re.compile(\n r\"(?:\"\n r\"(?:_(.+?)[.](\\S+))\"\n r\"|\" # _category.attribute\n r\"(?:['](.*?)(?:[']\\s|[']$))\"\n r\"|\" # single quoted strings\n r'(?:[\"](.*?)(?:[\"]\\s|[\"]$))'\n r\"|\" # double quoted strings\n r\"(?:\\s*#.*$)\"\n r\"|\" # comments (dumped)\n r\"(\\S+)\" # unquoted words\n r\")\"\n )\n\n fileIter = iter(ifh)\n\n # Tokenizer loop begins here ---\n while True:\n try:\n line = next(fileIter)\n self.__curLineNumber += 1\n\n # Dump comments\n if line.startswith(\"#\"):\n continue\n\n # Gobble up the entire semi-colon/multi-line delimited string and\n # and stuff this into the string slot in the return tuple\n #\n if line.startswith(\";\"):\n mlString = [line[1:]]\n while True:\n line = next(fileIter)\n self.__curLineNumber += 1\n if line.startswith(\";\"):\n break\n mlString.append(line)\n\n # remove trailing new-line that is part of the \\n; delimiter\n mlString[-1] = mlString[-1].rstrip()\n #\n yield (None, None, \"\".join(mlString), None)\n #\n # Need to process the remainder of the current line -\n line = line[1:]\n # continue\n\n # Apply regex to the current line consolidate the single/double\n # quoted within the quoted string category\n for it in mmcifRe.finditer(line):\n tgroups = it.groups()\n #\n if tgroups[4] is not None and tgroups[4].lower() == \"stop_\":\n continue\n if tgroups != (None, None, None, None, None):\n if tgroups[2] is not None:\n qs = tgroups[2]\n elif tgroups[3] is not None:\n qs = tgroups[3]\n else:\n qs = None\n groups = (tgroups[0], tgroups[1], qs, tgroups[4])\n yield groups\n except StopIteration:\n return\n
"},{"location":"api_reference/PdbxReader/#mmcif.io.PdbxReader.PdbxReader.__init__","title":"__init__(self, ifh)
special
","text":"ifh - input file handle returned by open()
Source code in mmcif/io/PdbxReader.py
def __init__(self, ifh):\n \"\"\"ifh - input file handle returned by open()\"\"\"\n #\n self.__curLineNumber = 0\n self.__ifh = ifh\n self.__stateDict = {\"data\": \"ST_DATA_CONTAINER\", \"loop\": \"ST_TABLE\", \"global\": \"ST_GLOBAL_CONTAINER\", \"save\": \"ST_DEFINITION\", \"stop\": \"ST_STOP\"}\n
"},{"location":"api_reference/PdbxReader/#mmcif.io.PdbxReader.PdbxReader.read","title":"read(self, containerList, selectList=None, excludeFlag=False)
","text":"Appends to input list of definition and data containers.
return
Source code in mmcif/io/PdbxReader.py
def read(self, containerList, selectList=None, excludeFlag=False):\n \"\"\"\n Appends to input list of definition and data containers.\n\n return\n\n \"\"\"\n sL = selectList if selectList else []\n catSelectD = {k: k for k in sL}\n self.__curLineNumber = 0\n try:\n self.__parser(self.__tokenizer(self.__ifh), containerList, categorySelectionD=catSelectD, excludeFlag=excludeFlag)\n except RuntimeError as e:\n # will be raised at the end of token iterator - not an error -\n logger.debug(\"Normal termination after reading %d lines with %s\", self.__curLineNumber, str(e))\n except StopIteration:\n # will be raised at the end of token iterator - not an error -\n logger.debug(\"Normal termination after reading %d lines\", self.__curLineNumber)\n except PdbxSyntaxError as e:\n logger.debug(\"Caught syntax exception at %d\", self.__curLineNumber)\n raise e\n except UnicodeDecodeError as e:\n logger.debug(\"Caught character encoding exception at %d with %s\", self.__curLineNumber, str(e))\n raise PdbxError(\"Character encoding error at line %d\" % self.__curLineNumber)\n except Exception as e:\n raise PdbxError(\"Failing at line %d with %s\" % (self.__curLineNumber, str(e)))\n else:\n raise PdbxError(\"Miscellaneous parsing error at line %d\" % self.__curLineNumber)\n
"},{"location":"api_reference/PdbxWriter/","title":"PdbxWriter","text":"Write mmCIF data files or dictionaries using the input container or container list.
Source code in mmcif/io/PdbxWriter.py
class PdbxWriter(object):\n\n \"\"\"Write mmCIF data files or dictionaries using the input container or container list.\"\"\"\n\n def __init__(self, ofh=sys.stdout):\n self.__ofh = ofh\n self.__containerList = []\n self.__maximumLineLength = 2048\n self.__spacing = 2\n self.__indentDefinition = 3\n self.__indentSpace = \" \" * self.__indentDefinition\n self.__doDefinitionIndent = False\n # Maximum number of rows checked for value length and format\n self.__rowPartition = None\n # Defaults to double quoting preference -\n self.__preferDoubleQuotes = True\n self.__useAlignedColumns = True\n self.__useStopTokens = False\n self.__cnvCharRefs = False\n #\n self.__enforceAscii = False\n self.__isPy3 = sys.version_info[0] == 3\n # if self.__isPy3:\n # self.__string_types = str\n # else:\n # self.__string_types = basestring\n\n def setSetEnforceAscii(self, boolVal):\n self.__enforceAscii = boolVal\n\n def setConvertCharRefs(self, flag):\n self.__cnvCharRefs = flag\n\n def setUseStopTokens(self, flag):\n self.__useStopTokens = flag\n\n def setMaxLineLength(self, numChars):\n self.__maximumLineLength = numChars\n\n def setAlignmentFlag(self, flag=True):\n self.__useAlignedColumns = flag\n\n def setPreferSingleQuotes(self):\n self.__preferDoubleQuotes = False\n\n def setPreferDoubleQuotes(self):\n self.__preferDoubleQuotes = True\n\n def setRowPartition(self, numParts):\n \"\"\"Maximum number of partitions used to format value length for column alignment\"\"\"\n self.__rowPartition = numParts\n\n def write(self, containerList, lastInOrder=None, selectOrder=None):\n self.__containerList = containerList\n for container in self.__containerList:\n self.writeContainer(container, lastInOrder=lastInOrder, selectOrder=selectOrder)\n\n def writeContainer(self, container, lastInOrder=None, selectOrder=None):\n indS = \" \" * self.__indentDefinition\n if container.getType() == \"definition\":\n self.__write(\"save_%s\" % container.getName())\n # self.__write(\"save_%s\\n\" % container.getName())\n self.__doDefinitionIndent = True\n # self.__write(indS + \"#\\n\")\n elif container.getType() == \"data\":\n if container.getGlobal():\n self.__write(\"global_\\n\")\n self.__doDefinitionIndent = False\n self.__write(\"\\n\")\n else:\n self.__write(\"data_%s\\n\" % container.getName())\n self.__doDefinitionIndent = False\n # self.__write(\"#\\n\")\n\n nmL = container.filterObjectNameList(lastInOrder=lastInOrder, selectOrder=selectOrder)\n for nm in nmL:\n obj = container.getObj(nm)\n objL = obj.getRowList()\n\n # Skip empty objects\n if not objL:\n continue\n\n # Item - value formattting\n elif len(objL) == 1:\n self.__writeItemValueFormat(obj)\n\n # Table formatting -\n elif objL and obj.getAttributeList():\n if self.__useAlignedColumns:\n self.__writeTableFormat(obj)\n else:\n self.__writeTable(obj)\n else:\n raise PdbxError(\"\")\n\n if self.__doDefinitionIndent:\n self.__write(indS + \"#\")\n else:\n self.__write(\"#\")\n\n # Add a trailing saveframe reserved word\n if container.getType() == \"definition\":\n self.__write(\"\\nsave_\\n\")\n self.__write(\"#\\n\")\n\n def __write(self, st):\n try:\n if self.__cnvCharRefs:\n self.__ofh.write(st.encode(\"ascii\", \"xmlcharrefreplace\").decode(\"ascii\"))\n elif not self.__isPy3:\n if self.__enforceAscii:\n self.__ofh.write(st.decode(\"ascii\"))\n else:\n self.__ofh.write(st)\n # self.__ofh.write(st.encode('utf-8').decode('utf-8'))\n else:\n self.__ofh.write(st)\n except Exception as e:\n logger.exception(\"write fails with %s for %r\", str(e), st)\n\n def __writeItemValueFormat(self, categoryObj):\n # indS = \" \" * self.__INDENT_DEFINITION\n myCategory = DataCategoryFormatted(categoryObj, preferDoubleQuotes=self.__preferDoubleQuotes)\n # Compute the maximum item name length within this category -\n attributeNameLengthMax = 0\n for attributeName in myCategory.getAttributeList():\n attributeNameLengthMax = max(attributeNameLengthMax, len(attributeName))\n itemNameLengthMax = self.__spacing + len(myCategory.getName()) + attributeNameLengthMax + 2\n #\n lineList = []\n # lineList.append(indS+\"#\\n\")\n lineList.append(\"\\n\")\n for attributeName, _ in myCategory.getAttributeListWithOrder():\n if self.__doDefinitionIndent:\n # - add indent --\n lineList.append(self.__indentSpace)\n\n itemName = \"_%s.%s\" % (myCategory.getName(), attributeName)\n lineList.append(itemName.ljust(itemNameLengthMax))\n\n lineList.append(myCategory.getValueFormatted(attributeName, 0))\n lineList.append(\"\\n\")\n\n self.__write(\"\".join(lineList))\n\n def __writeTableFormat(self, categoryObj):\n # indS = \" \" * self.__INDENT_DEFINITION\n myCategory = DataCategoryFormatted(categoryObj, preferDoubleQuotes=self.__preferDoubleQuotes)\n # Write the declaration of the loop_\n #\n lineList = []\n # lineList.append(indS + '#\\n')\n lineList.append(\"\\n\")\n if self.__doDefinitionIndent:\n lineList.append(self.__indentSpace)\n lineList.append(\"loop_\")\n for attributeName in myCategory.getAttributeList():\n lineList.append(\"\\n\")\n if self.__doDefinitionIndent:\n lineList.append(self.__indentSpace)\n itemName = \"_%s.%s\" % (myCategory.getName(), attributeName)\n lineList.append(itemName)\n self.__write(\"\".join(lineList))\n\n #\n # Write the data in tabular format -\n #\n # print myCategory.getName()\n # print myCategory.getAttributeList()\n\n # For speed make the following evaluation on a portion of the table\n if self.__rowPartition is not None:\n numSteps = max(1, myCategory.getRowCount() // self.__rowPartition)\n else:\n numSteps = 1\n\n formatTypeList, _ = myCategory.getFormatTypeList(steps=numSteps)\n maxLengthList = myCategory.getAttributeValueMaxLengthList(steps=numSteps)\n spacing = \" \" * self.__spacing\n #\n\n # print formatTypeList\n # print dataTypeList\n # print maxLengthList\n #\n for iRow in range(myCategory.getRowCount()):\n lineList = []\n lineList.append(\"\\n\")\n if self.__doDefinitionIndent:\n lineList.append(self.__indentSpace + \" \")\n\n for iAt in range(myCategory.getAttributeCount()):\n formatType = formatTypeList[iAt]\n maxLength = maxLengthList[iAt]\n\n if formatType == \"FT_UNQUOTED_STRING\" or formatType == \"FT_NULL_VALUE\":\n val = myCategory.getValueFormattedByIndex(iAt, iRow)\n lineList.append(val.ljust(maxLength))\n\n elif formatType == \"FT_NUMBER\":\n val = myCategory.getValueFormattedByIndex(iAt, iRow)\n lineList.append(val.rjust(maxLength))\n\n elif formatType == \"FT_QUOTED_STRING\":\n val = myCategory.getValueFormattedByIndex(iAt, iRow)\n # don't pad the last item in row condition\n if iAt == myCategory.getAttributeCount() - 1:\n lineList.append(val.ljust(len(val)))\n else:\n lineList.append(val.ljust(maxLength + 2))\n\n elif formatType == \"FT_MULTI_LINE_STRING\":\n val = myCategory.getValueFormattedByIndex(iAt, iRow)\n lineList.append(val)\n\n lineList.append(spacing)\n\n self.__write(\"\".join(lineList))\n self.__write(\"\\n\")\n if self.__useStopTokens:\n self.__write(\"stop_\\n\")\n\n def __writeTable(self, categoryObj, numSteps=5):\n indS = \" \" * self.__indentDefinition\n myCategory = DataCategoryFormatted(categoryObj, preferDoubleQuotes=self.__preferDoubleQuotes)\n # Write the declaration of the loop_\n #\n lineList = []\n lineList.append(indS + \"#\\n\")\n if self.__doDefinitionIndent:\n lineList.append(self.__indentSpace)\n lineList.append(\"loop_\")\n for attributeName in myCategory.getAttributeList():\n lineList.append(\"\\n\")\n if self.__doDefinitionIndent:\n lineList.append(self.__indentSpace)\n itemName = \"_%s.%s\" % (myCategory.getName(), attributeName)\n lineList.append(itemName)\n self.__write(\"\".join(lineList))\n\n #\n formatTypeList, _ = myCategory.getFormatTypeList(steps=numSteps)\n spacing = \" \" * self.__spacing\n #\n for iRow in range(myCategory.getRowCount()):\n lineList = []\n lineList.append(\"\\n\")\n if self.__doDefinitionIndent:\n lineList.append(self.__indentSpace + \" \")\n\n for iAt in range(myCategory.getAttributeCount()):\n formatType = formatTypeList[iAt]\n\n if formatType == \"FT_UNQUOTED_STRING\" or formatType == \"FT_NULL_VALUE\":\n val = myCategory.getValueFormattedByIndex(iAt, iRow)\n lineList.append(val)\n\n elif formatType == \"FT_NUMBER\":\n val = myCategory.getValueFormattedByIndex(iAt, iRow)\n lineList.append(val)\n\n elif formatType == \"FT_QUOTED_STRING\":\n val = myCategory.getValueFormattedByIndex(iAt, iRow)\n lineList.append(val)\n\n elif formatType == \"FT_MULTI_LINE_STRING\":\n val = myCategory.getValueFormattedByIndex(iAt, iRow)\n lineList.append(val)\n\n lineList.append(spacing)\n\n self.__write(\"\".join(lineList))\n self.__write(\"\\n\")\n if self.__useStopTokens:\n self.__write(\"stop_\\n\")\n
"},{"location":"api_reference/PdbxWriter/#mmcif.io.PdbxWriter.PdbxWriter.setRowPartition","title":"setRowPartition(self, numParts)
","text":"Maximum number of partitions used to format value length for column alignment
Source code in mmcif/io/PdbxWriter.py
def setRowPartition(self, numParts):\n \"\"\"Maximum number of partitions used to format value length for column alignment\"\"\"\n self.__rowPartition = numParts\n
"}]}
\ No newline at end of file
+{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"mmCIF Core Access Library","text":""},{"location":"#introduction","title":"Introduction","text":"This module includes a native Python mmCIF API for data files and dictionaries along with pybind11 wrappers for the PDB C++ Core mmCIF Library.
"},{"location":"#installation","title":"Installation","text":"Download the library source software from the project repository:
git clone --recurse-submodules https://github.com/rcsb/py-mmcif.git\n
Optionally, run test suite using the Tox test runner. The C++ library bindings have been tested on Centos 7/Ubuntu 20.04 Linux with GCC/G++ > 4.8.5 and MacOS (10.15) with > clang-900.0.39.2 using Python versions 2.7.18 and 3.9.4.
tox\n
Installation is via the program pip.
pip install mmcif\n\nor from the local repository:\n\npip install .\n
To generate API documentation using Sphinx:
cd scripts\n# Check Sphinx dependencies in the introductory comments to the following script.\n./initdocs.sh\n
A command-line script is provided as a preprocessor for modular dictionaries that include definition and data content using categories pdbx_include_dictionary, pdbx_include_category and pdbx_include_item.
build_dict_cli --help\nusage: build_dict_cli [-h] --op OP --input_dict_path INPUT_DICT_PATH [--output_dict_path OUTPUT_DICT_PATH] [--cleanup]\n\noptional arguments:\n -h, --help show this help message and exit\n --op OP Operation (build | get_version)\n --input_dict_path INPUT_DICT_PATH\n Path to dictionary generator file\n --output_dict_path OUTPUT_DICT_PATH\n Path to output dictionary text file\n --cleanup Remove include instruction categories after processing\n________________________________________________________________________________\n
"},{"location":"api_reference/BinaryCifReader/","title":"BinaryCifReader","text":"Reader methods for the binary CIF format.
Source code in mmcif/io/BinaryCifReader.py
class BinaryCifReader(object):\n \"\"\"Reader methods for the binary CIF format.\"\"\"\n\n def __init__(self, storeStringsAsBytes=False, defaultStringEncoding=\"utf-8\"):\n \"\"\"Create an instance of the binary CIF reader class.\n\n Args:\n storeStringsAsBytes (bool, optional): strings are stored as lists of bytes. Defaults to False.\n defaultStringEncoding (str, optional): default encoding for string data. Defaults to \"utf-8\".\n \"\"\"\n self.__storeStringsAsBytes = storeStringsAsBytes\n self.__defaultStringEncoding = defaultStringEncoding\n\n def deserialize(self, locator, timeout=None):\n \"\"\"Deserialize the input binary CIF file stored in the file/URL locator path.\n\n Args:\n locator (str): input file path or URL\n timeout (float): timeout for fetching a remote url\n\n Returns:\n list: list DataContainer objects\n \"\"\"\n cL = []\n try:\n if self.__isLocal(locator):\n with gzip.open(locator, mode=\"rb\") if locator[-3:] == \".gz\" else open(locator, \"rb\") as fh:\n cL = self.__deserialize(fh, storeStringsAsBytes=self.__storeStringsAsBytes)\n else:\n if locator.endswith(\".gz\"):\n customHeader = {\"Accept-Encoding\": \"gzip\"}\n with closing(requests.get(locator, headers=customHeader, timeout=timeout)) as fh:\n ufh = gzip.GzipFile(fileobj=io.BytesIO(fh.content))\n cL = self.__deserialize(ufh, storeStringsAsBytes=self.__storeStringsAsBytes)\n else:\n with closing(requests.get(locator, timeout=timeout)) as fh:\n cL = self.__deserialize(io.BytesIO(fh.content), storeStringsAsBytes=self.__storeStringsAsBytes)\n\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n return cL\n\n def __deserialize(self, fh, storeStringsAsBytes=False):\n cL = []\n try:\n dec = BinaryCifDecoders(storeStringsAsBytes=storeStringsAsBytes)\n bD = msgpack.unpack(fh)\n #\n logger.debug(\"bD.keys() %r\", bD.keys())\n logger.debug(\"bD['dataBlocks'] %s\", bD[self.__toBytes(\"dataBlocks\")])\n #\n for dataBlock in bD[self.__toBytes(\"dataBlocks\")]:\n header = self.__fromBytes(dataBlock[self.__toBytes(\"header\")]) if self.__toBytes(\"header\") in dataBlock else None\n logger.debug(\"header %r\", header)\n logger.debug(\"dataBlock %r\", dataBlock)\n #\n dc = DataContainer(header)\n categoryList = dataBlock[self.__toBytes(\"categories\")] if self.__toBytes(\"categories\") in dataBlock else []\n for category in categoryList:\n catName = self.__fromBytes(category[self.__toBytes(\"name\")])[1:]\n colList = category[self.__toBytes(\"columns\")]\n logger.debug(\"catName %r columns %r\", catName, colList)\n colD = OrderedDict()\n atNameList = []\n for col in colList:\n logger.debug(\"col.keys() %r\", col.keys())\n atName = self.__fromBytes(col[self.__toBytes(\"name\")])\n atData = col[self.__toBytes(\"data\")]\n logger.debug(\"atData encoding (%d) data (%d)\", len(atData[self.__toBytes(\"encoding\")]), len(atData[self.__toBytes(\"data\")]))\n atMask = col[self.__toBytes(\"mask\")]\n logger.debug(\"catName %r atName %r\", catName, atName)\n logger.debug(\" >atData.data %r\", atData[self.__toBytes(\"data\")])\n logger.debug(\" >atData.encoding (%d) %r\", len(atData[self.__toBytes(\"encoding\")]), atData[self.__toBytes(\"encoding\")])\n logger.debug(\" >mask %r\", atMask)\n tVal = dec.decode(col[self.__toBytes(\"data\")][self.__toBytes(\"data\")], col[self.__toBytes(\"data\")][self.__toBytes(\"encoding\")])\n if col[self.__toBytes(\"mask\")]:\n mVal = dec.decode(col[self.__toBytes(\"mask\")][self.__toBytes(\"data\")], col[self.__toBytes(\"mask\")][self.__toBytes(\"encoding\")])\n tVal = [\"?\" if m == 2 else \".\" if m == 1 else d for d, m in zip(tVal, mVal)]\n colD[atName] = tVal\n atNameList.append(atName)\n #\n cObj = DataCategory(catName, attributeNameList=atNameList)\n genL = [colGen for colGen in colD.values()]\n for row in zip(*genL):\n logger.debug(\"row %r\", row)\n cObj.append(row)\n #\n dc.append(cObj)\n cL.append(dc)\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n return cL\n\n def __isLocal(self, locator):\n \"\"\"Returns true if input string can be interpreted as a local file path.\n\n Args:\n locator (str): url or path string\n\n Returns:\n bool: True if locator is a local path\n \"\"\"\n try:\n locSp = urlsplit(locator)\n return locSp.scheme in [\"\", \"file\"]\n except Exception as e:\n logger.exception(\"For locator %r failing with %s\", locator, str(e))\n return None\n\n def __toBytes(self, strVal):\n \"\"\"Optional conversion of the input string to bytes according to the class setting (storeStringsAsBytes).\n\n Args:\n strVal (string): input string\n\n Returns:\n string or bytes: optionally converted string.\n \"\"\"\n try:\n return strVal.encode(self.__defaultStringEncoding) if self.__storeStringsAsBytes else strVal\n except (UnicodeDecodeError, AttributeError):\n logger.exception(\"Bad type for %r\", strVal)\n return strVal\n\n def __fromBytes(self, byteVal):\n \"\"\"Optional conversion of the input value according to the class setting (storeStringsAsBytes).\n\n Args:\n byteVal (string): input byte object\n\n Returns:\n string: optionally converted input value\n \"\"\"\n try:\n return byteVal.decode(self.__defaultStringEncoding) if self.__storeStringsAsBytes else byteVal\n except (UnicodeDecodeError, AttributeError):\n logger.exception(\"Bad type for %r\", byteVal)\n return byteVal\n
Column oriented Binary CIF decoders implementing StringArray, ByteArray, IntegerPacking, Delta, RunLength, FixedPoint, and IntervalQuantization from the BinaryCIF specification described in:
Sehnal D, Bittrich S, Velankar S, Koca J, Svobodova R, Burley SK, Rose AS. BinaryCIF and CIFTools-Lightweight, efficient and extensible macromolecular data management. PLoS Comput Biol. 2020 Oct 19;16(10):e1008247. doi: 10.1371/journal.pcbi.1008247. PMID: 33075050; PMCID: PMC7595629.
and in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
and from the I/HM Python implementation at https://github.com/ihmwg/python-ihm[summary]
Source code in mmcif/io/BinaryCifReader.py
class BinaryCifDecoders(object):\n \"\"\"Column oriented Binary CIF decoders implementing\n StringArray, ByteArray, IntegerPacking, Delta, RunLength,\n FixedPoint, and IntervalQuantization from the BinaryCIF\n specification described in:\n\n Sehnal D, Bittrich S, Velankar S, Koca J, Svobodova R, Burley SK, Rose AS.\n BinaryCIF and CIFTools-Lightweight, efficient and extensible macromolecular data management.\n PLoS Comput Biol. 2020 Oct 19;16(10):e1008247.\n doi: 10.1371/journal.pcbi.1008247. PMID: 33075050; PMCID: PMC7595629.\n\n and in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n and from the I/HM Python implementation at https://github.com/ihmwg/python-ihm[summary]\n\n \"\"\"\n\n bCifCodeTypeD = {1: \"integer_8\", 2: \"integer_16\", 3: \"integer_32\", 4: \"unsigned_integer_8\", 5: \"unsigned_integer_16\", 6: \"unsigned_integer_32\", 32: \"float_32\", 33: \"float_64\"}\n \"\"\"Binary CIF protocol internal data type codes to integer and float types\n \"\"\"\n bCifTypeD = {\n \"integer_8\": {\"struct_format_code\": \"b\", \"min\": -0x7F - 1, \"max\": 0x7F},\n \"integer_16\": {\"struct_format_code\": \"h\", \"min\": -0x7FFF - 1, \"max\": 0x7FFF},\n \"integer_32\": {\"struct_format_code\": \"i\", \"min\": -0x7FFFFFFF - 1, \"max\": 0x7FFFFFFF},\n \"unsigned_integer_8\": {\"struct_format_code\": \"B\", \"min\": 0, \"max\": 0xFF},\n \"unsigned_integer_16\": {\"struct_format_code\": \"H\", \"min\": 0, \"max\": 0xFFFF},\n \"unsigned_integer_32\": {\"struct_format_code\": \"I\", \"min\": 0, \"max\": 0xFFFFFFFF},\n \"float_32\": {\"struct_format_code\": \"f\", \"min\": 1.175494351e-38, \"max\": 3.402823466e38},\n \"float_64\": {\"struct_format_code\": \"d\", \"min\": 2.2250738585072014e-308, \"max\": 1.7976931348623158e308},\n }\n \"\"\"Binary CIF data type feature dictionary\n \"\"\"\n\n def __init__(self, storeStringsAsBytes=False, defaultStringEncoding=\"utf-8\", verbose=False):\n \"\"\"Create an instance of the binary CIF encoder class.\n\n Args:\n storeStringsAsBytes (bool, optional): express keys and strings as byte types otherwise follow the default encoding. Defaults to False.\n defaultStringEncoding (str, optional): default encoding for string types. Defaults to \"utf-8\".\n verbose(bool, optional): provide tracking of type conversion issues. Defaults to False.\n \"\"\"\n self.__storeStringsAsBytes = storeStringsAsBytes\n self.__defaultStringEncoding = defaultStringEncoding\n self.__verbose = verbose\n #\n self.__encodersMethodD = {\n \"StringArray\": self.stringArrayDecoder,\n \"ByteArray\": self.byteArrayDecoder,\n \"IntegerPacking\": self.integerPackingDecoder,\n \"Delta\": self.deltaDecoder,\n \"RunLength\": self.runLengthDecoder,\n \"FixedPoint\": self.fixedPointDecoder,\n \"IntervalQuantization\": self.intervalQuantizationDecoder,\n }\n\n def decode(self, colDataList, encodingDictList):\n \"\"\"Return the decoded input data column using the input list of encodings\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDictList (list): list of dictionary holding binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of column data\n \"\"\"\n for encoding in reversed(encodingDictList):\n encType = self.__fromBytes(encoding[self.__toBytes(\"kind\")])\n colDataList = self.__encodersMethodD[encType](colDataList, encoding)\n return colDataList\n\n def stringArrayDecoder(self, colDataList, encodingDict):\n \"\"\"Decode an array of strings stored as a concatenation of all unique\n strings, a list of offsets to construct the unique substrings, and indices into\n the offset array.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of string data\n \"\"\"\n offsetList = list(self.decode(encodingDict[self.__toBytes(\"offsets\")], encodingDict[self.__toBytes(\"offsetEncoding\")]))\n lookupIndexIt = self.decode(colDataList, encodingDict[self.__toBytes(\"dataEncoding\")])\n\n stringData = self.__fromBytes(encodingDict[self.__toBytes(\"stringData\")])\n uniqueStringList = []\n for iBegin, iEnd in zip(offsetList, offsetList[1:]):\n uniqueStringList.append(stringData[iBegin:iEnd])\n logger.debug(\"iBegin %d iEnd %d %r \", iBegin, iEnd, stringData[iBegin:iEnd])\n\n for ii in lookupIndexIt:\n yield uniqueStringList[ii] if ii >= 0 else None\n\n def byteArrayDecoder(self, colDataList, encodingDict):\n \"\"\"Decode input byte list into a list of integers/floats\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of integer/float data\n \"\"\"\n structKey = self.bCifCodeTypeD[encodingDict[self.__toBytes(\"type\")]]\n structFormatCode = self.bCifTypeD[structKey][\"struct_format_code\"]\n count = len(colDataList) // struct.calcsize(structFormatCode)\n # struct.unpack() format string for little-endian = < format_string code * counts\n return struct.unpack(\"<\" + structFormatCode * count, colDataList)\n\n def __unsignedDecode(self, colDataList, encodingDict):\n upperLimit = self.bCifTypeD[\"unsigned_integer_8\"][\"max\"] if encodingDict[self.__toBytes(\"byteCount\")] == 1 else self.bCifTypeD[\"unsigned_integer_16\"][\"max\"]\n ii = 0\n while ii < len(colDataList):\n value = 0\n tVal = colDataList[ii]\n while tVal == upperLimit:\n value += tVal\n ii += 1\n tVal = colDataList[ii]\n yield value + tVal\n ii += 1\n\n def __signedDecode(self, colDataList, encodingDict):\n upperLimit = self.bCifTypeD[\"integer_8\"][\"max\"] if encodingDict[self.__toBytes(\"byteCount\")] == 1 else self.bCifTypeD[\"integer_16\"][\"max\"]\n lowerLimit = self.bCifTypeD[\"integer_8\"][\"min\"] if encodingDict[self.__toBytes(\"byteCount\")] == 1 else self.bCifTypeD[\"integer_16\"][\"min\"]\n ii = 0\n while ii < len(colDataList):\n value = 0\n tVal = colDataList[ii]\n while tVal == upperLimit or tVal == lowerLimit:\n value += tVal\n ii += 1\n tVal = colDataList[ii]\n yield value + tVal\n ii += 1\n\n def integerPackingDecoder(self, colDataList, encodingDict):\n \"\"\"Decode a (32-bit) integer list packed into 8- or 16-bit values.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of integer data\n\n \"\"\"\n if encodingDict[self.__toBytes(\"isUnsigned\")]:\n return self.__unsignedDecode(colDataList, encodingDict)\n else:\n return self.__signedDecode(colDataList, encodingDict)\n\n def deltaDecoder(self, colDataList, encodingDict):\n \"\"\"Decode an integer list stored as a list of consecutive differences.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of integer data\n \"\"\"\n val = encodingDict[self.__toBytes(\"origin\")]\n for diff in colDataList:\n val += diff\n yield val\n\n def runLengthDecoder(self, colDataList, encodingDict):\n \"\"\"Decode an integer list stored as pairs of (value, number of repeats).\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of integer data\n \"\"\"\n _ = encodingDict\n colDataList = list(colDataList)\n for ii in range(0, len(colDataList), 2):\n for _ in range(colDataList[ii + 1]):\n yield colDataList[ii]\n\n def fixedPointDecoder(self, colDataList, encodingDict):\n \"\"\"Decode a floating point list stored as integers and a multiplicative factor.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of float data\n \"\"\"\n factor = float(encodingDict[self.__toBytes(\"factor\")])\n for val in colDataList:\n yield float(val) / factor\n\n def intervalQuantizationDecoder(self, colDataList, encodingDict):\n \"\"\"Decode a list of 32-bit integers quantized within a given interval into a list of floats.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of float data\n\n \"\"\"\n delta = float(encodingDict[self.__toBytes(\"max\")] - encodingDict[self.__toBytes(\"min\")]) / float(encodingDict[self.__toBytes(\"numSteps\")] - 1.0)\n minVal = encodingDict[self.__toBytes(\"min\")]\n for val in colDataList:\n yield minVal + delta * val\n\n def __toBytes(self, strVal):\n \"\"\"Optional conversion of the input string to bytes according to the class setting (storeStringsAsBytes).\n\n Args:\n strVal (string): input string\n\n Returns:\n string or bytes: optionally converted string.\n \"\"\"\n try:\n return strVal.encode(self.__defaultStringEncoding) if self.__storeStringsAsBytes else strVal\n except (UnicodeDecodeError, AttributeError):\n if self.__verbose:\n logger.exception(\"Bad type for %r\", strVal)\n return strVal\n\n def __fromBytes(self, byteVal):\n \"\"\"Optional conversion of the input value according to the class setting (storeStringsAsBytes).\n\n Args:\n byteVal (string): input byte object\n\n Returns:\n string: optionally converted input value\n \"\"\"\n try:\n return byteVal.decode(self.__defaultStringEncoding) if self.__storeStringsAsBytes else byteVal\n except (UnicodeDecodeError, AttributeError):\n if self.__verbose:\n logger.exception(\"Bad type for %r\", byteVal)\n return byteVal\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifReader.__init__","title":"__init__(self, storeStringsAsBytes=False, defaultStringEncoding='utf-8')
special
","text":"Create an instance of the binary CIF reader class.
Parameters:
Name Type Description Default storeStringsAsBytes
bool
strings are stored as lists of bytes. Defaults to False.
False
defaultStringEncoding
str
default encoding for string data. Defaults to \"utf-8\".
'utf-8'
Source code in mmcif/io/BinaryCifReader.py
def __init__(self, storeStringsAsBytes=False, defaultStringEncoding=\"utf-8\"):\n \"\"\"Create an instance of the binary CIF reader class.\n\n Args:\n storeStringsAsBytes (bool, optional): strings are stored as lists of bytes. Defaults to False.\n defaultStringEncoding (str, optional): default encoding for string data. Defaults to \"utf-8\".\n \"\"\"\n self.__storeStringsAsBytes = storeStringsAsBytes\n self.__defaultStringEncoding = defaultStringEncoding\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifReader.deserialize","title":"deserialize(self, locator, timeout=None)
","text":"Deserialize the input binary CIF file stored in the file/URL locator path.
Parameters:
Name Type Description Default locator
str
input file path or URL
required timeout
float
timeout for fetching a remote url
None
Returns:
Type Description list
list DataContainer objects
Source code in mmcif/io/BinaryCifReader.py
def deserialize(self, locator, timeout=None):\n \"\"\"Deserialize the input binary CIF file stored in the file/URL locator path.\n\n Args:\n locator (str): input file path or URL\n timeout (float): timeout for fetching a remote url\n\n Returns:\n list: list DataContainer objects\n \"\"\"\n cL = []\n try:\n if self.__isLocal(locator):\n with gzip.open(locator, mode=\"rb\") if locator[-3:] == \".gz\" else open(locator, \"rb\") as fh:\n cL = self.__deserialize(fh, storeStringsAsBytes=self.__storeStringsAsBytes)\n else:\n if locator.endswith(\".gz\"):\n customHeader = {\"Accept-Encoding\": \"gzip\"}\n with closing(requests.get(locator, headers=customHeader, timeout=timeout)) as fh:\n ufh = gzip.GzipFile(fileobj=io.BytesIO(fh.content))\n cL = self.__deserialize(ufh, storeStringsAsBytes=self.__storeStringsAsBytes)\n else:\n with closing(requests.get(locator, timeout=timeout)) as fh:\n cL = self.__deserialize(io.BytesIO(fh.content), storeStringsAsBytes=self.__storeStringsAsBytes)\n\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n return cL\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.bCifCodeTypeD","title":"bCifCodeTypeD
","text":"Binary CIF protocol internal data type codes to integer and float types
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.bCifTypeD","title":"bCifTypeD
","text":"Binary CIF data type feature dictionary
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.__init__","title":"__init__(self, storeStringsAsBytes=False, defaultStringEncoding='utf-8', verbose=False)
special
","text":"Create an instance of the binary CIF encoder class.
Parameters:
Name Type Description Default storeStringsAsBytes
bool
express keys and strings as byte types otherwise follow the default encoding. Defaults to False.
False
defaultStringEncoding
str
default encoding for string types. Defaults to \"utf-8\".
'utf-8'
verbose(bool,
optional
provide tracking of type conversion issues. Defaults to False.
required Source code in mmcif/io/BinaryCifReader.py
def __init__(self, storeStringsAsBytes=False, defaultStringEncoding=\"utf-8\", verbose=False):\n \"\"\"Create an instance of the binary CIF encoder class.\n\n Args:\n storeStringsAsBytes (bool, optional): express keys and strings as byte types otherwise follow the default encoding. Defaults to False.\n defaultStringEncoding (str, optional): default encoding for string types. Defaults to \"utf-8\".\n verbose(bool, optional): provide tracking of type conversion issues. Defaults to False.\n \"\"\"\n self.__storeStringsAsBytes = storeStringsAsBytes\n self.__defaultStringEncoding = defaultStringEncoding\n self.__verbose = verbose\n #\n self.__encodersMethodD = {\n \"StringArray\": self.stringArrayDecoder,\n \"ByteArray\": self.byteArrayDecoder,\n \"IntegerPacking\": self.integerPackingDecoder,\n \"Delta\": self.deltaDecoder,\n \"RunLength\": self.runLengthDecoder,\n \"FixedPoint\": self.fixedPointDecoder,\n \"IntervalQuantization\": self.intervalQuantizationDecoder,\n }\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.byteArrayDecoder","title":"byteArrayDecoder(self, colDataList, encodingDict)
","text":"Decode input byte list into a list of integers/floats
Parameters:
Name Type Description Default colDataList
list
column of data to be decoded
required encodingDict
dict
dictionary of binary CIF encoding details elements described in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
required Yields:
Type Description list
decoded list of integer/float data
Source code in mmcif/io/BinaryCifReader.py
def byteArrayDecoder(self, colDataList, encodingDict):\n \"\"\"Decode input byte list into a list of integers/floats\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of integer/float data\n \"\"\"\n structKey = self.bCifCodeTypeD[encodingDict[self.__toBytes(\"type\")]]\n structFormatCode = self.bCifTypeD[structKey][\"struct_format_code\"]\n count = len(colDataList) // struct.calcsize(structFormatCode)\n # struct.unpack() format string for little-endian = < format_string code * counts\n return struct.unpack(\"<\" + structFormatCode * count, colDataList)\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.decode","title":"decode(self, colDataList, encodingDictList)
","text":"Return the decoded input data column using the input list of encodings
Parameters:
Name Type Description Default colDataList
list
column of data to be decoded
required encodingDictList
list
list of dictionary holding binary CIF encoding details elements described in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
required Yields:
Type Description list
decoded list of column data
Source code in mmcif/io/BinaryCifReader.py
def decode(self, colDataList, encodingDictList):\n \"\"\"Return the decoded input data column using the input list of encodings\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDictList (list): list of dictionary holding binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of column data\n \"\"\"\n for encoding in reversed(encodingDictList):\n encType = self.__fromBytes(encoding[self.__toBytes(\"kind\")])\n colDataList = self.__encodersMethodD[encType](colDataList, encoding)\n return colDataList\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.deltaDecoder","title":"deltaDecoder(self, colDataList, encodingDict)
","text":"Decode an integer list stored as a list of consecutive differences.
Parameters:
Name Type Description Default colDataList
list
column of data to be decoded
required encodingDict
dict
dictionary of binary CIF encoding details elements described in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
required Yields:
Type Description list
decoded list of integer data
Source code in mmcif/io/BinaryCifReader.py
def deltaDecoder(self, colDataList, encodingDict):\n \"\"\"Decode an integer list stored as a list of consecutive differences.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of integer data\n \"\"\"\n val = encodingDict[self.__toBytes(\"origin\")]\n for diff in colDataList:\n val += diff\n yield val\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.fixedPointDecoder","title":"fixedPointDecoder(self, colDataList, encodingDict)
","text":"Decode a floating point list stored as integers and a multiplicative factor.
Parameters:
Name Type Description Default colDataList
list
column of data to be decoded
required encodingDict
dict
dictionary of binary CIF encoding details elements described in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
required Yields:
Type Description list
decoded list of float data
Source code in mmcif/io/BinaryCifReader.py
def fixedPointDecoder(self, colDataList, encodingDict):\n \"\"\"Decode a floating point list stored as integers and a multiplicative factor.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of float data\n \"\"\"\n factor = float(encodingDict[self.__toBytes(\"factor\")])\n for val in colDataList:\n yield float(val) / factor\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.integerPackingDecoder","title":"integerPackingDecoder(self, colDataList, encodingDict)
","text":"Decode a (32-bit) integer list packed into 8- or 16-bit values.
Parameters:
Name Type Description Default colDataList
list
column of data to be decoded
required encodingDict
dict
dictionary of binary CIF encoding details elements described in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
required Yields:
Type Description list
decoded list of integer data
Source code in mmcif/io/BinaryCifReader.py
def integerPackingDecoder(self, colDataList, encodingDict):\n \"\"\"Decode a (32-bit) integer list packed into 8- or 16-bit values.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of integer data\n\n \"\"\"\n if encodingDict[self.__toBytes(\"isUnsigned\")]:\n return self.__unsignedDecode(colDataList, encodingDict)\n else:\n return self.__signedDecode(colDataList, encodingDict)\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.intervalQuantizationDecoder","title":"intervalQuantizationDecoder(self, colDataList, encodingDict)
","text":"Decode a list of 32-bit integers quantized within a given interval into a list of floats.
Parameters:
Name Type Description Default colDataList
list
column of data to be decoded
required encodingDict
dict
dictionary of binary CIF encoding details elements described in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
required Yields:
Type Description list
decoded list of float data
Source code in mmcif/io/BinaryCifReader.py
def intervalQuantizationDecoder(self, colDataList, encodingDict):\n \"\"\"Decode a list of 32-bit integers quantized within a given interval into a list of floats.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of float data\n\n \"\"\"\n delta = float(encodingDict[self.__toBytes(\"max\")] - encodingDict[self.__toBytes(\"min\")]) / float(encodingDict[self.__toBytes(\"numSteps\")] - 1.0)\n minVal = encodingDict[self.__toBytes(\"min\")]\n for val in colDataList:\n yield minVal + delta * val\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.runLengthDecoder","title":"runLengthDecoder(self, colDataList, encodingDict)
","text":"Decode an integer list stored as pairs of (value, number of repeats).
Parameters:
Name Type Description Default colDataList
list
column of data to be decoded
required encodingDict
dict
dictionary of binary CIF encoding details elements described in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
required Yields:
Type Description list
decoded list of integer data
Source code in mmcif/io/BinaryCifReader.py
def runLengthDecoder(self, colDataList, encodingDict):\n \"\"\"Decode an integer list stored as pairs of (value, number of repeats).\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of integer data\n \"\"\"\n _ = encodingDict\n colDataList = list(colDataList)\n for ii in range(0, len(colDataList), 2):\n for _ in range(colDataList[ii + 1]):\n yield colDataList[ii]\n
"},{"location":"api_reference/BinaryCifReader/#mmcif.io.BinaryCifReader.BinaryCifDecoders.stringArrayDecoder","title":"stringArrayDecoder(self, colDataList, encodingDict)
","text":"Decode an array of strings stored as a concatenation of all unique strings, a list of offsets to construct the unique substrings, and indices into the offset array.
Parameters:
Name Type Description Default colDataList
list
column of data to be decoded
required encodingDict
dict
dictionary of binary CIF encoding details elements described in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
required Yields:
Type Description list
decoded list of string data
Source code in mmcif/io/BinaryCifReader.py
def stringArrayDecoder(self, colDataList, encodingDict):\n \"\"\"Decode an array of strings stored as a concatenation of all unique\n strings, a list of offsets to construct the unique substrings, and indices into\n the offset array.\n\n Args:\n colDataList (list): column of data to be decoded\n encodingDict (dict): dictionary of binary CIF encoding details\n elements described in the specification at\n https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n Yields:\n list: decoded list of string data\n \"\"\"\n offsetList = list(self.decode(encodingDict[self.__toBytes(\"offsets\")], encodingDict[self.__toBytes(\"offsetEncoding\")]))\n lookupIndexIt = self.decode(colDataList, encodingDict[self.__toBytes(\"dataEncoding\")])\n\n stringData = self.__fromBytes(encodingDict[self.__toBytes(\"stringData\")])\n uniqueStringList = []\n for iBegin, iEnd in zip(offsetList, offsetList[1:]):\n uniqueStringList.append(stringData[iBegin:iEnd])\n logger.debug(\"iBegin %d iEnd %d %r \", iBegin, iEnd, stringData[iBegin:iEnd])\n\n for ii in lookupIndexIt:\n yield uniqueStringList[ii] if ii >= 0 else None\n
"},{"location":"api_reference/BinaryCifWriter/","title":"BinaryCifWriter","text":"Writer methods for the binary CIF format.
Source code in mmcif/io/BinaryCifWriter.py
class BinaryCifWriter(object):\n \"\"\"Writer methods for the binary CIF format.\"\"\"\n\n def __init__(self, dictionaryApi, storeStringsAsBytes=False, defaultStringEncoding=\"utf-8\", applyTypes=True, useStringTypes=False, useFloat64=False, copyInputData=False):\n \"\"\"Create an instance of the binary CIF writer class.\n\n Args:\n dictionaryApi (object): DictionaryApi object instance\n storeStringsAsBytes (bool, optional): strings are stored as lists of bytes. Defaults to False.\n defaultStringEncoding (str, optional): default encoding for string data. Defaults to \"utf-8\".\n applyTypes (bool, optional): apply explicit data typing before encoding. Defaults to True.\n useStringTypes (bool, optional): assume all types are string. Defaults to False.\n useFloat64 (bool, optional): store floats with 64 bit precision. Defaults to False.\n copyInputData (bool, optional): make a new copy input data. Defaults to False.\n \"\"\"\n self.__version = \"0.01\"\n self.__storeStringsAsBytes = storeStringsAsBytes\n self.__defaultStringEncoding = defaultStringEncoding\n self.__applyTypes = applyTypes\n self.__useStringTypes = useStringTypes\n self.__useFloat64 = useFloat64\n self.__dApi = dictionaryApi\n self.__copyInputData = copyInputData\n\n def serialize(self, filePath, containerList):\n \"\"\"Serialize the input container list in binary CIF and store these data in the input file path.\n\n Args:\n filePath (str): output file path\n containerList (list): list of DataContainer objects\n \"\"\"\n try:\n blocks = []\n for container in containerList:\n name = container.getName()\n block = {self.__toBytes(\"header\"): self.__toBytes(name), self.__toBytes(\"categories\"): []}\n categories = block[self.__toBytes(\"categories\")]\n blocks.append(block)\n for catName in container.getObjNameList():\n cObj = container.getObj(catName)\n if self.__applyTypes:\n cObj = DataCategoryTyped(cObj, dictionaryApi=self.__dApi, copyInputData=self.__copyInputData)\n #\n rowCount = cObj.getRowCount()\n #\n cols = []\n for ii, atName in enumerate(cObj.getAttributeList()):\n colDataList = cObj.getColumn(ii)\n dataType = self.__getAttributeType(cObj, atName) if not self.__useStringTypes else \"string\"\n logger.debug(\"catName %r atName %r dataType %r\", catName, atName, dataType)\n colMaskDict, encodedColDataList, encodingDictL = self.__encodeColumnData(colDataList, dataType)\n cols.append(\n {\n self.__toBytes(\"name\"): self.__toBytes(atName),\n self.__toBytes(\"mask\"): colMaskDict,\n self.__toBytes(\"data\"): {self.__toBytes(\"data\"): encodedColDataList, self.__toBytes(\"encoding\"): encodingDictL},\n }\n )\n categories.append({self.__toBytes(\"name\"): self.__toBytes(\"_\" + catName), self.__toBytes(\"columns\"): cols, self.__toBytes(\"rowCount\"): rowCount})\n #\n data = {\n self.__toBytes(\"version\"): self.__toBytes(self.__version),\n self.__toBytes(\"encoder\"): self.__toBytes(\"python-mmcif library\"),\n self.__toBytes(\"dataBlocks\"): blocks,\n }\n with open(filePath, \"wb\") as ofh:\n msgpack.pack(data, ofh)\n return True\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n return False\n\n def __encodeColumnData(self, colDataList, dataType):\n colMaskDict = {}\n enc = BinaryCifEncoders(defaultStringEncoding=self.__defaultStringEncoding, storeStringsAsBytes=self.__storeStringsAsBytes, useFloat64=self.__useFloat64)\n #\n maskEncoderList = [\"Delta\", \"RunLength\", \"ByteArray\"]\n typeEncoderD = {\"string\": \"StringArrayMasked\", \"integer\": \"IntArrayMasked\", \"float\": \"FloatArrayMasked\"}\n colMaskList = enc.getMask(colDataList)\n dataEncType = typeEncoderD[dataType]\n colDataEncoded, colDataEncodingDictL = enc.encodeWithMask(colDataList, colMaskList, dataEncType)\n if colMaskList:\n maskEncoded, maskEncodingDictL = enc.encode(colMaskList, maskEncoderList, \"integer\")\n colMaskDict = {self.__toBytes(\"data\"): maskEncoded, self.__toBytes(\"encoding\"): maskEncodingDictL}\n return colMaskDict, colDataEncoded, colDataEncodingDictL\n\n def __toBytes(self, strVal):\n \"\"\"Optional conversion of the input string to bytes according to the class setting (storeStringsAsBytes).\n\n Args:\n strVal (string): input string\n\n Returns:\n string or bytes: optionally converted string.\n \"\"\"\n try:\n return strVal.encode(self.__defaultStringEncoding) if self.__storeStringsAsBytes else strVal\n except (UnicodeDecodeError, AttributeError):\n logger.exception(\"Bad type for %r\", strVal)\n return strVal\n\n def __getAttributeType(self, dObj, atName):\n \"\"\"Get attribute data type (string, integer, or float) and optionality\n\n Args:\n atName (str): attribute name\n\n Returns:\n (string): data type (string, integer or float)\n \"\"\"\n cifDataType = self.__dApi.getTypeCode(dObj.getName(), atName)\n cifPrimitiveType = self.__dApi.getTypePrimitive(dObj.getName(), atName)\n dataType = \"string\" if cifDataType is None else \"integer\" if \"int\" in cifDataType else \"float\" if cifPrimitiveType == \"numb\" else \"string\"\n return dataType\n
Column oriented Binary CIF encoders implementing StringArray, ByteArray, IntegerPacking, Delta, RunLength, and FixedPoint encoders from the BinaryCIF specification described in:
Sehnal D, Bittrich S, Velankar S, Koca J, Svobodova R, Burley SK, Rose AS. BinaryCIF and CIFTools-Lightweight, efficient and extensible macromolecular data management. PLoS Comput Biol. 2020 Oct 19;16(10):e1008247. doi: 10.1371/journal.pcbi.1008247. PMID: 33075050; PMCID: PMC7595629.
and in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md
and from the I/HM Python implementation at https://github.com/ihmwg/python-ihm
Source code in mmcif/io/BinaryCifWriter.py
class BinaryCifEncoders(object):\n \"\"\"Column oriented Binary CIF encoders implementing\n StringArray, ByteArray, IntegerPacking, Delta, RunLength,\n and FixedPoint encoders from the BinaryCIF specification described in:\n\n Sehnal D, Bittrich S, Velankar S, Koca J, Svobodova R, Burley SK, Rose AS.\n BinaryCIF and CIFTools-Lightweight, efficient and extensible macromolecular data management.\n PLoS Comput Biol. 2020 Oct 19;16(10):e1008247.\n doi: 10.1371/journal.pcbi.1008247. PMID: 33075050; PMCID: PMC7595629.\n\n and in the specification at https://github.com/molstar/BinaryCIF/blob/master/encoding.md\n\n and from the I/HM Python implementation at https://github.com/ihmwg/python-ihm\n\n \"\"\"\n\n def __init__(self, defaultStringEncoding=\"utf-8\", storeStringsAsBytes=True, useFloat64=False):\n \"\"\"Instantiate the binary CIF encoder class.\n\n Args:\n defaultStringEncoding (str, optional): default encoding for string data . Defaults to \"utf-8\".\n storeStringsAsBytes (bool, optional): strings are stored as bytes. Defaults to True.\n useFloat64 (bool, optional): store floats in 64 bit precision. Defaults to True.\n \"\"\"\n self.__unknown = [\".\", \"?\"]\n self.__defaultStringEncoding = defaultStringEncoding\n self.__storeStringsAsBytes = storeStringsAsBytes\n self.__useFloat64 = useFloat64\n self.__bCifTypeCodeD = {v: k for k, v in BinaryCifDecoders.bCifCodeTypeD.items()}\n\n def encode(self, colDataList, encodingTypeList, dataType):\n \"\"\"Encode the data using the input list of encoding types returning encoded data and encoding instructions.\n\n Args:\n colDataList (list): input data to be encoded\n encodingTypeList (list): list of encoding types (ByteArray, Delta, or RunLength)\n dataType (string): column input data type (string, integer, float)\n\n Returns:\n (list, list ): encoded data column, list of encoding instructions\n \"\"\"\n encodingDictL = []\n for encType in encodingTypeList:\n if encType == \"ByteArray\":\n colDataList, encDict = self.byteArrayEncoder(colDataList, dataType)\n elif encType == \"Delta\":\n colDataList, encDict = self.deltaEncoder(colDataList)\n elif encType == \"RunLength\":\n colDataList, encDict = self.runLengthEncoder(colDataList)\n else:\n logger.info(\"unsupported encoding %r\", encType)\n if encDict is not None:\n encodingDictL.append(encDict)\n return colDataList, encodingDictL\n\n def encodeWithMask(self, colDataList, colMaskList, encodingType):\n \"\"\"Encode the data using the input mask and encoding type returning encoded data and encoding instructions.\n\n Args:\n colDataList (string): input data column\n colMaskList (list): incompleteness mask for the input data column\n encodingType (string): encoding type to apply (StringArrayMask, IntArrayMasked, FloatArrayMasked)\n\n Returns:\n (list, list ): encoded data column, list of encoding instructions\n \"\"\"\n encodedColDataList = []\n encodingDictL = []\n if encodingType == \"StringArrayMasked\":\n encodedColDataList, encodingDictL = self.stringArrayMaskedEncoder(colDataList, colMaskList)\n elif encodingType == \"IntArrayMasked\":\n encodedColDataList, encodingDictL = self.intArrayMaskedEncoder(colDataList, colMaskList)\n elif encodingType == \"FloatArrayMasked\":\n encodedColDataList, encodingDictL = self.floatArrayMaskedEncoder(colDataList, colMaskList)\n else:\n logger.info(\"unsupported masked encoding %r\", encodingType)\n return encodedColDataList, encodingDictL\n\n def __getIntegerPackingType(self, colDataList):\n \"\"\"Determine the integer packing type of the input integer data list\"\"\"\n try:\n minV = min(colDataList)\n maxV = max(colDataList)\n if minV >= 0:\n # Unsigned types\n for typeName in [\"unsigned_integer_8\", \"unsigned_integer_16\", \"unsigned_integer_32\"]:\n byteArrayType = self.__bCifTypeCodeD[typeName]\n upperLimit = BinaryCifDecoders.bCifTypeD[typeName][\"max\"]\n if maxV <= upperLimit:\n return byteArrayType\n else:\n # Signed types\n for typeName in [\"integer_8\", \"integer_16\", \"integer_32\"]:\n byteArrayType = self.__bCifTypeCodeD[typeName]\n upperLimit = BinaryCifDecoders.bCifTypeD[typeName][\"max\"]\n lowerLimit = BinaryCifDecoders.bCifTypeD[typeName][\"min\"]\n if minV >= lowerLimit and maxV <= upperLimit:\n return byteArrayType\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n raise TypeError(\"Cannot determine interger packing type\")\n\n def byteArrayEncoder(self, colDataList, dataType):\n \"\"\"Encode integer or float list in a packed byte array.\n\n Args:\n data (list): list of integer or float data\n dataType (str): data type (integer|float)\n\n Returns:\n bytes: byte encoded packed data\n \"\"\"\n if dataType == \"float\":\n byteArrayType = self.__bCifTypeCodeD[\"float_64\"] if self.__useFloat64 else self.__bCifTypeCodeD[\"float_32\"]\n else:\n byteArrayType = self.__getIntegerPackingType(colDataList)\n encodingD = {self.__toBytes(\"kind\"): self.__toBytes(\"ByteArray\"), self.__toBytes(\"type\"): byteArrayType}\n fmt = BinaryCifDecoders.bCifTypeD[BinaryCifDecoders.bCifCodeTypeD[byteArrayType]][\"struct_format_code\"]\n # Data are encoded little-endian '<'\n return struct.pack(\"<\" + fmt * len(colDataList), *colDataList), encodingD\n\n def deltaEncoder(self, colDataList, minLen=40):\n \"\"\"Encode an integer list as a list of consecutive differences.\n\n Args:\n colDataList (list): list of integer data\n minLen (int, optional): minimum list length to apply encoder. Defaults to 40.\n\n Returns:\n list: delta encoded integer list\n \"\"\"\n if len(colDataList) <= minLen:\n return colDataList, None\n byteArrayType = self.__getIntegerPackingType(colDataList)\n encodingD = {self.__toBytes(\"kind\"): self.__toBytes(\"Delta\"), self.__toBytes(\"origin\"): colDataList[0], self.__toBytes(\"srcType\"): byteArrayType}\n encodedColDataList = [0] + [colDataList[i] - colDataList[i - 1] for i in range(1, len(colDataList))]\n return encodedColDataList, encodingD\n\n def runLengthEncoder(self, colDataList, minLen=40):\n \"\"\"Encode an integer array as pairs of (value, number of repeats)\n\n Args:\n colDataList (list): list of integer data\n minLen (int, optional): minimum list length to apply encoder. Defaults to 40.\n\n Returns:\n list: runlength encoded integer list\n \"\"\"\n\n if len(colDataList) <= minLen:\n return colDataList, None\n byteArrayType = self.__getIntegerPackingType(colDataList)\n encodingD = {self.__toBytes(\"kind\"): self.__toBytes(\"RunLength\"), self.__toBytes(\"srcType\"): byteArrayType, self.__toBytes(\"srcSize\"): len(colDataList)}\n encodedColDataList = []\n val = None\n repeat = 1\n for colVal in colDataList:\n if colVal != val:\n if val is not None:\n encodedColDataList.extend((val, repeat))\n val = colVal\n repeat = 1\n else:\n repeat += 1\n encodedColDataList.extend((val, repeat))\n # Check for any gains and possibly retreat\n if len(encodedColDataList) > len(colDataList):\n return colDataList, None\n else:\n return encodedColDataList, encodingD\n\n def stringArrayMaskedEncoder(self, colDataList, colMaskList):\n \"\"\"Encode the input data column (string) along with the incompleteness mask.\n\n Args:\n colDataList (list): input data column (string)\n colMaskList (list): incompleteness mask\n\n Returns:\n (list, list): encoded data column, list of encoding instructions\n \"\"\"\n integerEncoderList = [\"Delta\", \"RunLength\", \"ByteArray\"]\n uniqStringIndex = {} # keys are substrings, values indices\n uniqStringList = []\n indexList = []\n for i, strVal in enumerate(colDataList):\n if colMaskList is not None and colMaskList[i]:\n indexList.append(-1)\n else:\n tS = strVal\n tS = str(tS)\n if tS not in uniqStringIndex:\n uniqStringIndex[tS] = len(uniqStringIndex)\n uniqStringList.append(tS)\n indexList.append(uniqStringIndex[tS])\n offsetList = [0]\n runningLen = 0\n for tS in uniqStringList:\n runningLen += len(tS)\n offsetList.append(runningLen)\n\n encodedOffsetList, offsetEncodingDictL = self.encode(offsetList, integerEncoderList, \"integer\")\n encodedIndexList, indexEncodingDictL = self.encode(indexList, integerEncoderList, \"integer\")\n\n encodingDict = {\n self.__toBytes(\"kind\"): self.__toBytes(\"StringArray\"),\n self.__toBytes(\"dataEncoding\"): indexEncodingDictL,\n self.__toBytes(\"stringData\"): self.__toBytes(\"\".join(uniqStringList)),\n self.__toBytes(\"offsetEncoding\"): offsetEncodingDictL,\n self.__toBytes(\"offsets\"): encodedOffsetList,\n }\n return encodedIndexList, [encodingDict]\n\n def intArrayMaskedEncoder(self, colDataList, colMaskList):\n \"\"\"Encode the input data column (integer) along with the incompleteness mask.\n\n Args:\n colDataList (list): input data column (string)\n colMaskList (list): incompleteness mask\n\n Returns:\n (list, list): encoded data column, list of encoding instructions\n \"\"\"\n integerEncoderList = [\"Delta\", \"RunLength\", \"ByteArray\"]\n\n if colMaskList:\n maskedColDataList = [-1 if m else d for m, d in zip(colMaskList, colDataList)]\n else:\n maskedColDataList = colDataList\n encodedColDataList, encodingDictL = self.encode(maskedColDataList, integerEncoderList, \"integer\")\n return encodedColDataList, encodingDictL\n\n def floatArrayMaskedEncoder(self, colDataList, colMaskList):\n \"\"\"Encode the input data column (float) along with the incompleteness mask.\n\n Args:\n colDataList (list): input data column (string)\n colMaskList (list): incompleteness mask\n\n Returns:\n (list, list): encoded data column, list of encoding instructions\n \"\"\"\n floatEncoderList = [\"ByteArray\"]\n\n if colMaskList:\n maskedColDataList = [0.0 if m else d for m, d in zip(colMaskList, colDataList)]\n else:\n maskedColDataList = colDataList\n encodedColDataList, encodingDictL = self.encode(maskedColDataList, floatEncoderList, \"float\")\n return encodedColDataList, encodingDictL\n\n def getMask(self, colDataList):\n \"\"\"Create an incompleteness mask list identifying missing/omitted values in the input data column.\n The mask is assigned: 0 = Value is present, 1 = '.' (value not specified), and 2 = '?' (value unknown).\n\n Args:\n colDataList (list): input data column\n\n Returns:\n list or None: mask list or None if the column contains no missing values\n \"\"\"\n mask = None\n for ii, colVal in enumerate(colDataList):\n if colVal is not None and colVal not in self.__unknown:\n continue\n if not mask:\n mask = [0] * len(colDataList)\n mask[ii] = 2 if colVal is None or colVal == \"?\" else 1\n return mask\n\n def __toBytes(self, strVal):\n \"\"\"Optional conversion of the input string to bytes according to the class setting (storeStringsAsBytes).\n\n Args:\n strVal (string): input string\n\n Returns:\n string or bytes: optionally converted string.\n \"\"\"\n try:\n return strVal.encode(self.__defaultStringEncoding) if self.__storeStringsAsBytes else strVal\n except (UnicodeDecodeError, AttributeError):\n logger.exception(\"Bad type for %r\", strVal)\n return strVal\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifWriter.__init__","title":"__init__(self, dictionaryApi, storeStringsAsBytes=False, defaultStringEncoding='utf-8', applyTypes=True, useStringTypes=False, useFloat64=False, copyInputData=False)
special
","text":"Create an instance of the binary CIF writer class.
Parameters:
Name Type Description Default dictionaryApi
object
DictionaryApi object instance
required storeStringsAsBytes
bool
strings are stored as lists of bytes. Defaults to False.
False
defaultStringEncoding
str
default encoding for string data. Defaults to \"utf-8\".
'utf-8'
applyTypes
bool
apply explicit data typing before encoding. Defaults to True.
True
useStringTypes
bool
assume all types are string. Defaults to False.
False
useFloat64
bool
store floats with 64 bit precision. Defaults to False.
False
copyInputData
bool
make a new copy input data. Defaults to False.
False
Source code in mmcif/io/BinaryCifWriter.py
def __init__(self, dictionaryApi, storeStringsAsBytes=False, defaultStringEncoding=\"utf-8\", applyTypes=True, useStringTypes=False, useFloat64=False, copyInputData=False):\n \"\"\"Create an instance of the binary CIF writer class.\n\n Args:\n dictionaryApi (object): DictionaryApi object instance\n storeStringsAsBytes (bool, optional): strings are stored as lists of bytes. Defaults to False.\n defaultStringEncoding (str, optional): default encoding for string data. Defaults to \"utf-8\".\n applyTypes (bool, optional): apply explicit data typing before encoding. Defaults to True.\n useStringTypes (bool, optional): assume all types are string. Defaults to False.\n useFloat64 (bool, optional): store floats with 64 bit precision. Defaults to False.\n copyInputData (bool, optional): make a new copy input data. Defaults to False.\n \"\"\"\n self.__version = \"0.01\"\n self.__storeStringsAsBytes = storeStringsAsBytes\n self.__defaultStringEncoding = defaultStringEncoding\n self.__applyTypes = applyTypes\n self.__useStringTypes = useStringTypes\n self.__useFloat64 = useFloat64\n self.__dApi = dictionaryApi\n self.__copyInputData = copyInputData\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifWriter.serialize","title":"serialize(self, filePath, containerList)
","text":"Serialize the input container list in binary CIF and store these data in the input file path.
Parameters:
Name Type Description Default filePath
str
output file path
required containerList
list
list of DataContainer objects
required Source code in mmcif/io/BinaryCifWriter.py
def serialize(self, filePath, containerList):\n \"\"\"Serialize the input container list in binary CIF and store these data in the input file path.\n\n Args:\n filePath (str): output file path\n containerList (list): list of DataContainer objects\n \"\"\"\n try:\n blocks = []\n for container in containerList:\n name = container.getName()\n block = {self.__toBytes(\"header\"): self.__toBytes(name), self.__toBytes(\"categories\"): []}\n categories = block[self.__toBytes(\"categories\")]\n blocks.append(block)\n for catName in container.getObjNameList():\n cObj = container.getObj(catName)\n if self.__applyTypes:\n cObj = DataCategoryTyped(cObj, dictionaryApi=self.__dApi, copyInputData=self.__copyInputData)\n #\n rowCount = cObj.getRowCount()\n #\n cols = []\n for ii, atName in enumerate(cObj.getAttributeList()):\n colDataList = cObj.getColumn(ii)\n dataType = self.__getAttributeType(cObj, atName) if not self.__useStringTypes else \"string\"\n logger.debug(\"catName %r atName %r dataType %r\", catName, atName, dataType)\n colMaskDict, encodedColDataList, encodingDictL = self.__encodeColumnData(colDataList, dataType)\n cols.append(\n {\n self.__toBytes(\"name\"): self.__toBytes(atName),\n self.__toBytes(\"mask\"): colMaskDict,\n self.__toBytes(\"data\"): {self.__toBytes(\"data\"): encodedColDataList, self.__toBytes(\"encoding\"): encodingDictL},\n }\n )\n categories.append({self.__toBytes(\"name\"): self.__toBytes(\"_\" + catName), self.__toBytes(\"columns\"): cols, self.__toBytes(\"rowCount\"): rowCount})\n #\n data = {\n self.__toBytes(\"version\"): self.__toBytes(self.__version),\n self.__toBytes(\"encoder\"): self.__toBytes(\"python-mmcif library\"),\n self.__toBytes(\"dataBlocks\"): blocks,\n }\n with open(filePath, \"wb\") as ofh:\n msgpack.pack(data, ofh)\n return True\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n return False\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.__init__","title":"__init__(self, defaultStringEncoding='utf-8', storeStringsAsBytes=True, useFloat64=False)
special
","text":"Instantiate the binary CIF encoder class.
Parameters:
Name Type Description Default defaultStringEncoding
str
default encoding for string data . Defaults to \"utf-8\".
'utf-8'
storeStringsAsBytes
bool
strings are stored as bytes. Defaults to True.
True
useFloat64
bool
store floats in 64 bit precision. Defaults to True.
False
Source code in mmcif/io/BinaryCifWriter.py
def __init__(self, defaultStringEncoding=\"utf-8\", storeStringsAsBytes=True, useFloat64=False):\n \"\"\"Instantiate the binary CIF encoder class.\n\n Args:\n defaultStringEncoding (str, optional): default encoding for string data . Defaults to \"utf-8\".\n storeStringsAsBytes (bool, optional): strings are stored as bytes. Defaults to True.\n useFloat64 (bool, optional): store floats in 64 bit precision. Defaults to True.\n \"\"\"\n self.__unknown = [\".\", \"?\"]\n self.__defaultStringEncoding = defaultStringEncoding\n self.__storeStringsAsBytes = storeStringsAsBytes\n self.__useFloat64 = useFloat64\n self.__bCifTypeCodeD = {v: k for k, v in BinaryCifDecoders.bCifCodeTypeD.items()}\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.byteArrayEncoder","title":"byteArrayEncoder(self, colDataList, dataType)
","text":"Encode integer or float list in a packed byte array.
Parameters:
Name Type Description Default data
list
list of integer or float data
required dataType
str
data type (integer|float)
required Returns:
Type Description bytes
byte encoded packed data
Source code in mmcif/io/BinaryCifWriter.py
def byteArrayEncoder(self, colDataList, dataType):\n \"\"\"Encode integer or float list in a packed byte array.\n\n Args:\n data (list): list of integer or float data\n dataType (str): data type (integer|float)\n\n Returns:\n bytes: byte encoded packed data\n \"\"\"\n if dataType == \"float\":\n byteArrayType = self.__bCifTypeCodeD[\"float_64\"] if self.__useFloat64 else self.__bCifTypeCodeD[\"float_32\"]\n else:\n byteArrayType = self.__getIntegerPackingType(colDataList)\n encodingD = {self.__toBytes(\"kind\"): self.__toBytes(\"ByteArray\"), self.__toBytes(\"type\"): byteArrayType}\n fmt = BinaryCifDecoders.bCifTypeD[BinaryCifDecoders.bCifCodeTypeD[byteArrayType]][\"struct_format_code\"]\n # Data are encoded little-endian '<'\n return struct.pack(\"<\" + fmt * len(colDataList), *colDataList), encodingD\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.deltaEncoder","title":"deltaEncoder(self, colDataList, minLen=40)
","text":"Encode an integer list as a list of consecutive differences.
Parameters:
Name Type Description Default colDataList
list
list of integer data
required minLen
int
minimum list length to apply encoder. Defaults to 40.
40
Returns:
Type Description list
delta encoded integer list
Source code in mmcif/io/BinaryCifWriter.py
def deltaEncoder(self, colDataList, minLen=40):\n \"\"\"Encode an integer list as a list of consecutive differences.\n\n Args:\n colDataList (list): list of integer data\n minLen (int, optional): minimum list length to apply encoder. Defaults to 40.\n\n Returns:\n list: delta encoded integer list\n \"\"\"\n if len(colDataList) <= minLen:\n return colDataList, None\n byteArrayType = self.__getIntegerPackingType(colDataList)\n encodingD = {self.__toBytes(\"kind\"): self.__toBytes(\"Delta\"), self.__toBytes(\"origin\"): colDataList[0], self.__toBytes(\"srcType\"): byteArrayType}\n encodedColDataList = [0] + [colDataList[i] - colDataList[i - 1] for i in range(1, len(colDataList))]\n return encodedColDataList, encodingD\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.encode","title":"encode(self, colDataList, encodingTypeList, dataType)
","text":"Encode the data using the input list of encoding types returning encoded data and encoding instructions.
Parameters:
Name Type Description Default colDataList
list
input data to be encoded
required encodingTypeList
list
list of encoding types (ByteArray, Delta, or RunLength)
required dataType
string
column input data type (string, integer, float)
required Returns:
Type Description (list, list )
encoded data column, list of encoding instructions
Source code in mmcif/io/BinaryCifWriter.py
def encode(self, colDataList, encodingTypeList, dataType):\n \"\"\"Encode the data using the input list of encoding types returning encoded data and encoding instructions.\n\n Args:\n colDataList (list): input data to be encoded\n encodingTypeList (list): list of encoding types (ByteArray, Delta, or RunLength)\n dataType (string): column input data type (string, integer, float)\n\n Returns:\n (list, list ): encoded data column, list of encoding instructions\n \"\"\"\n encodingDictL = []\n for encType in encodingTypeList:\n if encType == \"ByteArray\":\n colDataList, encDict = self.byteArrayEncoder(colDataList, dataType)\n elif encType == \"Delta\":\n colDataList, encDict = self.deltaEncoder(colDataList)\n elif encType == \"RunLength\":\n colDataList, encDict = self.runLengthEncoder(colDataList)\n else:\n logger.info(\"unsupported encoding %r\", encType)\n if encDict is not None:\n encodingDictL.append(encDict)\n return colDataList, encodingDictL\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.encodeWithMask","title":"encodeWithMask(self, colDataList, colMaskList, encodingType)
","text":"Encode the data using the input mask and encoding type returning encoded data and encoding instructions.
Parameters:
Name Type Description Default colDataList
string
input data column
required colMaskList
list
incompleteness mask for the input data column
required encodingType
string
encoding type to apply (StringArrayMask, IntArrayMasked, FloatArrayMasked)
required Returns:
Type Description (list, list )
encoded data column, list of encoding instructions
Source code in mmcif/io/BinaryCifWriter.py
def encodeWithMask(self, colDataList, colMaskList, encodingType):\n \"\"\"Encode the data using the input mask and encoding type returning encoded data and encoding instructions.\n\n Args:\n colDataList (string): input data column\n colMaskList (list): incompleteness mask for the input data column\n encodingType (string): encoding type to apply (StringArrayMask, IntArrayMasked, FloatArrayMasked)\n\n Returns:\n (list, list ): encoded data column, list of encoding instructions\n \"\"\"\n encodedColDataList = []\n encodingDictL = []\n if encodingType == \"StringArrayMasked\":\n encodedColDataList, encodingDictL = self.stringArrayMaskedEncoder(colDataList, colMaskList)\n elif encodingType == \"IntArrayMasked\":\n encodedColDataList, encodingDictL = self.intArrayMaskedEncoder(colDataList, colMaskList)\n elif encodingType == \"FloatArrayMasked\":\n encodedColDataList, encodingDictL = self.floatArrayMaskedEncoder(colDataList, colMaskList)\n else:\n logger.info(\"unsupported masked encoding %r\", encodingType)\n return encodedColDataList, encodingDictL\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.floatArrayMaskedEncoder","title":"floatArrayMaskedEncoder(self, colDataList, colMaskList)
","text":"Encode the input data column (float) along with the incompleteness mask.
Parameters:
Name Type Description Default colDataList
list
input data column (string)
required colMaskList
list
incompleteness mask
required Returns:
Type Description (list, list)
encoded data column, list of encoding instructions
Source code in mmcif/io/BinaryCifWriter.py
def floatArrayMaskedEncoder(self, colDataList, colMaskList):\n \"\"\"Encode the input data column (float) along with the incompleteness mask.\n\n Args:\n colDataList (list): input data column (string)\n colMaskList (list): incompleteness mask\n\n Returns:\n (list, list): encoded data column, list of encoding instructions\n \"\"\"\n floatEncoderList = [\"ByteArray\"]\n\n if colMaskList:\n maskedColDataList = [0.0 if m else d for m, d in zip(colMaskList, colDataList)]\n else:\n maskedColDataList = colDataList\n encodedColDataList, encodingDictL = self.encode(maskedColDataList, floatEncoderList, \"float\")\n return encodedColDataList, encodingDictL\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.getMask","title":"getMask(self, colDataList)
","text":"Create an incompleteness mask list identifying missing/omitted values in the input data column. The mask is assigned: 0 = Value is present, 1 = '.' (value not specified), and 2 = '?' (value unknown).
Parameters:
Name Type Description Default colDataList
list
input data column
required Returns:
Type Description list or None
mask list or None if the column contains no missing values
Source code in mmcif/io/BinaryCifWriter.py
def getMask(self, colDataList):\n \"\"\"Create an incompleteness mask list identifying missing/omitted values in the input data column.\n The mask is assigned: 0 = Value is present, 1 = '.' (value not specified), and 2 = '?' (value unknown).\n\n Args:\n colDataList (list): input data column\n\n Returns:\n list or None: mask list or None if the column contains no missing values\n \"\"\"\n mask = None\n for ii, colVal in enumerate(colDataList):\n if colVal is not None and colVal not in self.__unknown:\n continue\n if not mask:\n mask = [0] * len(colDataList)\n mask[ii] = 2 if colVal is None or colVal == \"?\" else 1\n return mask\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.intArrayMaskedEncoder","title":"intArrayMaskedEncoder(self, colDataList, colMaskList)
","text":"Encode the input data column (integer) along with the incompleteness mask.
Parameters:
Name Type Description Default colDataList
list
input data column (string)
required colMaskList
list
incompleteness mask
required Returns:
Type Description (list, list)
encoded data column, list of encoding instructions
Source code in mmcif/io/BinaryCifWriter.py
def intArrayMaskedEncoder(self, colDataList, colMaskList):\n \"\"\"Encode the input data column (integer) along with the incompleteness mask.\n\n Args:\n colDataList (list): input data column (string)\n colMaskList (list): incompleteness mask\n\n Returns:\n (list, list): encoded data column, list of encoding instructions\n \"\"\"\n integerEncoderList = [\"Delta\", \"RunLength\", \"ByteArray\"]\n\n if colMaskList:\n maskedColDataList = [-1 if m else d for m, d in zip(colMaskList, colDataList)]\n else:\n maskedColDataList = colDataList\n encodedColDataList, encodingDictL = self.encode(maskedColDataList, integerEncoderList, \"integer\")\n return encodedColDataList, encodingDictL\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.runLengthEncoder","title":"runLengthEncoder(self, colDataList, minLen=40)
","text":"Encode an integer array as pairs of (value, number of repeats)
Parameters:
Name Type Description Default colDataList
list
list of integer data
required minLen
int
minimum list length to apply encoder. Defaults to 40.
40
Returns:
Type Description list
runlength encoded integer list
Source code in mmcif/io/BinaryCifWriter.py
def runLengthEncoder(self, colDataList, minLen=40):\n \"\"\"Encode an integer array as pairs of (value, number of repeats)\n\n Args:\n colDataList (list): list of integer data\n minLen (int, optional): minimum list length to apply encoder. Defaults to 40.\n\n Returns:\n list: runlength encoded integer list\n \"\"\"\n\n if len(colDataList) <= minLen:\n return colDataList, None\n byteArrayType = self.__getIntegerPackingType(colDataList)\n encodingD = {self.__toBytes(\"kind\"): self.__toBytes(\"RunLength\"), self.__toBytes(\"srcType\"): byteArrayType, self.__toBytes(\"srcSize\"): len(colDataList)}\n encodedColDataList = []\n val = None\n repeat = 1\n for colVal in colDataList:\n if colVal != val:\n if val is not None:\n encodedColDataList.extend((val, repeat))\n val = colVal\n repeat = 1\n else:\n repeat += 1\n encodedColDataList.extend((val, repeat))\n # Check for any gains and possibly retreat\n if len(encodedColDataList) > len(colDataList):\n return colDataList, None\n else:\n return encodedColDataList, encodingD\n
"},{"location":"api_reference/BinaryCifWriter/#mmcif.io.BinaryCifWriter.BinaryCifEncoders.stringArrayMaskedEncoder","title":"stringArrayMaskedEncoder(self, colDataList, colMaskList)
","text":"Encode the input data column (string) along with the incompleteness mask.
Parameters:
Name Type Description Default colDataList
list
input data column (string)
required colMaskList
list
incompleteness mask
required Returns:
Type Description (list, list)
encoded data column, list of encoding instructions
Source code in mmcif/io/BinaryCifWriter.py
def stringArrayMaskedEncoder(self, colDataList, colMaskList):\n \"\"\"Encode the input data column (string) along with the incompleteness mask.\n\n Args:\n colDataList (list): input data column (string)\n colMaskList (list): incompleteness mask\n\n Returns:\n (list, list): encoded data column, list of encoding instructions\n \"\"\"\n integerEncoderList = [\"Delta\", \"RunLength\", \"ByteArray\"]\n uniqStringIndex = {} # keys are substrings, values indices\n uniqStringList = []\n indexList = []\n for i, strVal in enumerate(colDataList):\n if colMaskList is not None and colMaskList[i]:\n indexList.append(-1)\n else:\n tS = strVal\n tS = str(tS)\n if tS not in uniqStringIndex:\n uniqStringIndex[tS] = len(uniqStringIndex)\n uniqStringList.append(tS)\n indexList.append(uniqStringIndex[tS])\n offsetList = [0]\n runningLen = 0\n for tS in uniqStringList:\n runningLen += len(tS)\n offsetList.append(runningLen)\n\n encodedOffsetList, offsetEncodingDictL = self.encode(offsetList, integerEncoderList, \"integer\")\n encodedIndexList, indexEncodingDictL = self.encode(indexList, integerEncoderList, \"integer\")\n\n encodingDict = {\n self.__toBytes(\"kind\"): self.__toBytes(\"StringArray\"),\n self.__toBytes(\"dataEncoding\"): indexEncodingDictL,\n self.__toBytes(\"stringData\"): self.__toBytes(\"\".join(uniqStringList)),\n self.__toBytes(\"offsetEncoding\"): offsetEncodingDictL,\n self.__toBytes(\"offsets\"): encodedOffsetList,\n }\n return encodedIndexList, [encodingDict]\n
"},{"location":"api_reference/CifFile/","title":"CifFile","text":"CifFile
New method prototype --
CifFile* ParseCifSimple(const std::string& fileName, const bool verbose = false, const unsigned int intCaseSense = 0, const unsigned int maxLineLength = CifFile::STD_CIF_LINE_LENGTH, const std::string& nullValue = CifString::UnknownValue, const std::string& parseLogFileName = std::string());
Source code in mmcif/io/CifFile.py
class CifFile(object):\n \"\"\"\n CifFile\n\n New method prototype --\n\n CifFile* ParseCifSimple(const std::string& fileName,\n const bool verbose = false,\n const unsigned int intCaseSense = 0,\n const unsigned int maxLineLength = CifFile::STD_CIF_LINE_LENGTH,\n const std::string& nullValue = CifString::UnknownValue,\n const std::string& parseLogFileName = std::string());\n\n \"\"\"\n\n def __init__(self, fileName, parseLogFileName=None):\n self.__fileName = fileName\n\n if parseLogFileName is None:\n self.__cifFile = ParseCifSimple(self.__fileName, False, 0, 255, \"?\", \"\")\n else:\n self.__cifFile = ParseCifSimple(self.__fileName, False, 0, 255, \"?\", parseLogFileName)\n\n def getCifFile(self):\n return self.__cifFile\n\n @classmethod\n def getFileExt(cls):\n return \"cif\"\n\n def write(self, fileName):\n self.__cifFile.Write(fileName)\n\n @classmethod\n def read(cls, fileName):\n return cls(fileName)\n
"},{"location":"api_reference/DataCategory/","title":"DataCategory","text":"Methods for creating, accessing, and formatting PDBx/mmCif data categories.
Source code in mmcif/api/DataCategory.py
class DataCategory(DataCategoryBase):\n \"\"\"Methods for creating, accessing, and formatting PDBx/mmCif data categories.\"\"\"\n\n def __init__(self, name, attributeNameList=None, rowList=None, raiseExceptions=True, copyInputData=True):\n \"\"\"Summary\n\n Args:\n name (str): Category name\n attributeNameList (None, optional): Initial attribute names\n rowList (None, optional): Initial category data organized in rows corresponding to the attribute name list\n raiseExceptions (bool, optional): Flag to control if expections are raised or handled internally\n copyInputData (bool, optional): Copy rather than reference input data\n \"\"\"\n super(DataCategory, self).__init__(name, attributeNameList, rowList, raiseExceptions=raiseExceptions, copyInputData=copyInputData)\n #\n self.__verbose = False\n self._currentRowIndex = 0\n self.__currentAttribute = None\n #\n\n def setVerboseMode(self, boolVal):\n self.__verbose = boolVal\n\n def getCurrentAttribute(self):\n return self.__currentAttribute\n\n def getRowIndex(self):\n return self._currentRowIndex\n\n def getFullRow(self, index):\n \"\"\"Return a full row based on the length of the the attribute list or a row initialized with missing values\"\"\"\n try:\n if len(self.data[index]) < self._numAttributes:\n for _ in range(self._numAttributes - len(self.data[index])):\n self.data[index].append(\"?\")\n return self.data[index]\n except Exception as e:\n logger.debug(\"Returning an empty row at %d (%s)\", index, str(e))\n return [\"?\" for ii in range(self._numAttributes)]\n\n def getAttributeListWithOrder(self):\n oL = []\n for ii, att in enumerate(self._attributeNameList):\n oL.append((att, ii))\n return oL\n\n def appendAttributeExtendRows(self, attributeName, defaultValue=\"?\"):\n attributeNameLC = attributeName.lower()\n if attributeNameLC in self._catalog:\n i = self._attributeNameList.index(self._catalog[attributeNameLC])\n self._attributeNameList[i] = attributeName\n self._catalog[attributeNameLC] = attributeName\n logger.info(\"Appending existing attribute %s\", attributeName)\n else:\n self._attributeNameList.append(attributeName)\n self._catalog[attributeNameLC] = attributeName\n # add a placeholder to any existing rows for the new attribute.\n if self.data:\n for row in self.data:\n row.append(defaultValue)\n #\n self._numAttributes = len(self._attributeNameList)\n return self._numAttributes\n\n def getValue(self, attributeName=None, rowIndex=None):\n if attributeName is None:\n attribute = self.__currentAttribute\n else:\n attribute = attributeName\n if rowIndex is None:\n rowI = self._currentRowIndex\n else:\n rowI = rowIndex\n\n if isinstance(attribute, self._stringTypes) and isinstance(rowI, int):\n try:\n return self.data[rowI][self._attributeNameList.index(attribute)]\n except IndexError:\n if self._raiseExceptions:\n raise IndexError\n if self._raiseExceptions:\n raise IndexError(attribute)\n else:\n return None\n\n def getValueOrDefault(self, attributeName=None, rowIndex=None, defaultValue=\"\"):\n \"\"\"Within the current category return the value of input attribute in the input rowIndex [0-based].\n\n On error or if the value missing or null return the default value. Empty values returned as is.\n\n Exceptions on for unknown attributeNames and out-of-range indices.\n \"\"\"\n if attributeName is None:\n attribute = self.__currentAttribute\n else:\n attribute = attributeName\n if rowIndex is None:\n rowI = self._currentRowIndex\n else:\n rowI = rowIndex\n\n if isinstance(attribute, self._stringTypes) and isinstance(rowI, int):\n try:\n tV = self.data[rowI][self._attributeNameList.index(attribute)]\n if (tV is None) or (tV in [\".\", \"?\"]):\n return defaultValue\n else:\n return tV\n except Exception as e:\n logger.debug(\"Failing attributeName %s rowIndex %r defaultValue %r with %s\", attributeName, rowIndex, defaultValue, str(e))\n # if self._raiseExceptions:\n # raise e\n # Returning default -- no exception\n else:\n if self._raiseExceptions:\n raise ValueError\n #\n return defaultValue\n\n def getFirstValueOrDefault(self, attributeNameList, rowIndex=0, defaultValue=\"\"):\n \"\"\"Return the value from the first non-null attribute found in the input attribute list\n from the row (rowIndex) in the current category object.\n \"\"\"\n try:\n for at in attributeNameList:\n if self.hasAttribute(at):\n tV = self.getValue(at, rowIndex)\n if (tV is None) or (tV in [\"\", \".\", \"?\"]):\n continue\n else:\n return tV\n except Exception as e:\n logger.debug(\"Failing with %s\", str(e))\n # if self._raiseExceptions:\n # raise e\n return defaultValue\n\n def setValue(self, value, attributeName=None, rowIndex=None):\n \"\"\"Set the value of an existing attribute. rowIndex values >=0, where\n the category will be extended in length as needed.\n \"\"\"\n if attributeName is None:\n attribute = self.__currentAttribute\n else:\n attribute = attributeName\n\n if rowIndex is None:\n rowI = self._currentRowIndex\n else:\n rowI = rowIndex\n\n if isinstance(attribute, self._stringTypes) and isinstance(rowI, int) and (rowI >= 0):\n try:\n ind = -2\n # if row index is out of range - add the rows -\n for ii in range(rowI + 1 - len(self.data)):\n self.data.append(self.__emptyRow())\n # self.data[rowI][attribute]=value\n ll = len(self.data[rowI])\n ind = self._attributeNameList.index(attribute)\n\n # extend the list if needed -\n if ind >= ll:\n self.data[rowI].extend([None for ii in range(ind - (ll - 1))])\n\n self.data[rowI][ind] = value\n return True\n except IndexError:\n if self.__verbose:\n logger.exception(\n \"DataCategory(setvalue) index error category %s attribute %s row index %d col %d rowlen %d value %r\",\n self._name,\n attribute,\n rowI,\n ind,\n len(self.data[rowI]),\n value,\n )\n logger.debug(\"DataCategory(setvalue) attribute %r length attribute list %d\", attribute, len(self._attributeNameList))\n for ii, aV in enumerate(self._attributeNameList):\n logger.debug(\"DataCategory(setvalue) %d attributeName %r\", ii, aV)\n if self._raiseExceptions:\n raise IndexError\n except ValueError:\n if self.__verbose:\n logger.exception(\"DataCategory(setvalue) value error category %s attribute %s row index %d value %r\", self._name, attribute, rowI, value)\n if self._raiseExceptions:\n raise ValueError\n else:\n if self._raiseExceptions:\n raise ValueError\n return False\n\n def __emptyRow(self):\n return [None for ii in range(len(self._attributeNameList))]\n\n def replaceValue(self, oldValue, newValue, attributeName):\n try:\n numReplace = 0\n if attributeName not in self._attributeNameList:\n return numReplace\n ind = self._attributeNameList.index(attributeName)\n for row in self.data:\n if row[ind] == oldValue:\n row[ind] = newValue\n numReplace += 1\n return numReplace\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return numReplace\n\n def replaceSubstring(self, oldValue, newValue, attributeName):\n try:\n numReplace = 0\n if attributeName not in self._attributeNameList:\n return numReplace\n ind = self._attributeNameList.index(attributeName)\n for row in self.data:\n val = row[ind]\n row[ind] = val.replace(oldValue, newValue)\n if val != row[ind]:\n numReplace += 1\n return numReplace\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return numReplace\n\n def selectIndices(self, attributeValue, attributeName):\n try:\n rL = []\n if attributeName not in self._attributeNameList:\n return rL\n ind = self._attributeNameList.index(attributeName)\n for ii, row in enumerate(self.data):\n if attributeValue == row[ind]:\n rL.append(ii)\n return rL\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return rL\n\n def selectIndicesFromList(self, attributeValueList, attributeNameList):\n rL = []\n try:\n indList = []\n for at in attributeNameList:\n indList.append(self._attributeNameList.index(at))\n indValList = list(zip(indList, attributeValueList))\n #\n numList = len(indValList)\n for ii, row in enumerate(self.data):\n nMatch = 0\n for ind, tVal in indValList:\n if tVal == row[ind]:\n nMatch += 1\n if nMatch == numList:\n rL.append(ii)\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection/index failure for values %r\", attributeValueList)\n if self._raiseExceptions:\n raise e\n\n return rL\n\n def selectValuesWhere(self, attributeName, attributeValueWhere, attributeNameWhere, returnCount=0):\n rL = []\n try:\n iCount = 0\n ind = self._attributeNameList.index(attributeName)\n indWhere = self._attributeNameList.index(attributeNameWhere)\n for row in self.data:\n if attributeValueWhere == row[indWhere]:\n rL.append(row[ind])\n iCount += 1\n if returnCount and (iCount >= returnCount):\n break\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return rL\n\n def selectValueListWhere(self, attributeNameList, attributeValueWhere, attributeNameWhere, returnCount=0):\n \"\"\"Return a list of lists containing the values of input attributeNameList\n satisfying the attribute value where condition.\n \"\"\"\n rL = []\n try:\n iCount = 0\n indList = []\n for at in attributeNameList:\n indList.append(self._attributeNameList.index(at))\n indWhere = self._attributeNameList.index(attributeNameWhere)\n for row in self.data:\n if attributeValueWhere == row[indWhere]:\n rL.append([row[jj] for jj in indList])\n iCount += 1\n if returnCount and (iCount >= returnCount):\n break\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return rL\n\n def selectValuesWhereConditions(self, attributeName, conditionsD, returnCount=0):\n rL = []\n try:\n iCount = 0\n ind = self._attributeNameList.index(attributeName)\n idxD = {k: self._attributeNameList.index(k) for k, v in conditionsD.items()}\n #\n #\n for row in self.data:\n ok = True\n for k, v in conditionsD.items():\n ok = (v == row[idxD[k]]) and ok\n if ok:\n rL.append(row[ind])\n iCount += 1\n if returnCount and (iCount >= returnCount):\n break\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return rL\n\n def countValuesWhereConditions(self, conditionsD):\n \"\"\"Count row instances subject to input equivalence conditions\n\n Args:\n conditionsD (dict): {'atName': value, ....}\n\n Raises:\n e: any failure\n\n Returns:\n int: count of instances satisfying input conditions\n \"\"\"\n try:\n iCount = 0\n idxD = {k: self._attributeNameList.index(k) for k, v in conditionsD.items()}\n #\n for row in self.data:\n ok = True\n for k, v in conditionsD.items():\n ok = (v == row[idxD[k]]) and ok\n if ok:\n iCount += 1\n\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return iCount\n\n def countValuesWhereOpConditions(self, conditionTupleList):\n \"\"\"Count row instances subject to input condition list\n\n Args:\n conditionTupleList (list): (attributeName, op, value) where (op = 'eq', 'gt(int)', 'lt(int)', 'in', 'ne', 'not in')\n\n Raises:\n e: any failure\n\n Returns:\n int: count of instances satisfying input conditions\n \"\"\"\n try:\n iCount = 0\n idxD = {atName: self._attributeNameList.index(atName) for (atName, op, value) in conditionTupleList}\n #\n for row in self.data:\n ok = True\n for (atName, op, v) in conditionTupleList:\n if op == \"eq\":\n ok = (v == row[idxD[atName]]) and ok\n elif op == \"ne\":\n ok = (v != row[idxD[atName]]) and ok\n elif op == \"lt(int)\":\n ok = (int(row[idxD[atName]]) < v) and ok\n elif op == \"gt(int)\":\n ok = (int(row[idxD[atName]]) > v) and ok\n elif op == \"in\":\n ok = (row[idxD[atName]] in v) and ok\n elif op == \"not in\":\n ok = (row[idxD[atName]] not in v) and ok\n if ok:\n iCount += 1\n\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return iCount\n\n #\n def getCombinationCounts(self, attributeList):\n \"\"\"Count the value occurrences of the input attributeList in the category.\n\n Args:\n attributeList (list): target list of attribute names\n\n Returns:\n\n cD[(attribute value, ... )] = count\n\n \"\"\"\n cD = {}\n try:\n idxL = [self._attributeNameList.index(atName) for atName in attributeList]\n #\n for row in self.data:\n ky = tuple([row[jj] for jj in idxL])\n cD[ky] = cD[ky] + 1 if ky in cD else 1\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return cD\n\n def getCombinationCountsWithConditions(self, attributeList, conditionTupleList):\n \"\"\"Count the value occurrences of the input attributeList in the category.\n\n Args:\n attributeList (list): target list of attribute names\n conditionTupleList (list): (attributeName, op, value) where (op = 'eq', 'gt(int)', 'lt(int)', 'in', 'ne', 'not in')\n\n Returns:\n\n cD[(attribute value, ... )] = count\n \"\"\"\n cD = {}\n try:\n idxL = [self._attributeNameList.index(atName) for atName in attributeList]\n idxD = {atName: self._attributeNameList.index(atName) for (atName, op, value) in conditionTupleList}\n #\n for row in self.data:\n ok = True\n for (atName, op, v) in conditionTupleList:\n if op == \"eq\":\n ok = (v == row[idxD[atName]]) and ok\n elif op == \"ne\":\n ok = (v != row[idxD[atName]]) and ok\n elif op == \"lt(int)\":\n ok = (int(row[idxD[atName]]) < v) and ok\n elif op == \"gt(int)\":\n ok = (int(row[idxD[atName]]) > v) and ok\n elif op == \"in\":\n ok = (row[idxD[atName]] in v) and ok\n elif op == \"not in\":\n ok = (row[idxD[atName]] not in v) and ok\n if ok:\n ky = tuple([row[jj] for jj in idxL])\n cD[ky] = cD[ky] + 1 if ky in cD else 1\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return cD\n\n def invokeAttributeMethod(self, attributeName, mType, method, db):\n _ = mType\n _ = db\n self._currentRowIndex = 0\n self.__currentAttribute = attributeName\n self.appendAttribute(attributeName)\n currentRowIndex = self._currentRowIndex # pylint: disable=possibly-unused-variable\n #\n ind = self._attributeNameList.index(attributeName)\n if not self.data:\n row = [None for ii in range(len(self._attributeNameList) * 2)]\n row[ind] = None\n self.data.append(row)\n\n for row in self.data:\n ll = len(row)\n if ind >= ll:\n row.extend([None for ii in range(2 * ind - ll)])\n row[ind] = None\n exec(method.getInline(), globals(), locals()) # pylint: disable=exec-used\n self._currentRowIndex += 1\n currentRowIndex = self._currentRowIndex\n\n def invokeCategoryMethod(self, mType, method, db):\n _ = mType\n _ = db\n self._currentRowIndex = 0\n exec(method.getInline(), globals(), locals()) # pylint: disable=exec-used\n\n def printIt(self, fh=sys.stdout):\n fh.write(\"--------------------------------------------\\n\")\n fh.write(\" Category: %s attribute list length: %d\\n\" % (self._name, len(self._attributeNameList)))\n for at in self._attributeNameList:\n fh.write(\" Category: %s attribute: %s\\n\" % (self._name, at))\n\n fh.write(\" Row value list length: %d\\n\" % len(self.data))\n #\n for row in self.data[:2]:\n #\n if len(row) == len(self._attributeNameList):\n for ii, v in enumerate(row):\n fh.write(\" %30s: %s ...\\n\" % (self._attributeNameList[ii], str(v)[:30]))\n else:\n fh.write(\"+WARNING - %s data length %d attribute name length %s mismatched\\n\" % (self._name, len(row), len(self._attributeNameList)))\n\n def dumpIt(self, fh=sys.stdout):\n fh.write(\"--------------------------------------------\\n\")\n fh.write(\" Category: %s attribute list length: %d\\n\" % (self._name, len(self._attributeNameList)))\n for at in self._attributeNameList:\n fh.write(\" Category: %s attribute: %s\\n\" % (self._name, at))\n\n fh.write(\" Value list length: %d\\n\" % len(self.data))\n for jj, row in enumerate(self.data):\n for ii, v in enumerate(row):\n fh.write(\"%4d %30s: %s\\n\" % (jj, self._attributeNameList[ii], v))\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.__init__","title":"__init__(self, name, attributeNameList=None, rowList=None, raiseExceptions=True, copyInputData=True)
special
","text":"Summary
Parameters:
Name Type Description Default name
str
Category name
required attributeNameList
None
Initial attribute names
None
rowList
None
Initial category data organized in rows corresponding to the attribute name list
None
raiseExceptions
bool
Flag to control if expections are raised or handled internally
True
copyInputData
bool
Copy rather than reference input data
True
Source code in mmcif/api/DataCategory.py
def __init__(self, name, attributeNameList=None, rowList=None, raiseExceptions=True, copyInputData=True):\n \"\"\"Summary\n\n Args:\n name (str): Category name\n attributeNameList (None, optional): Initial attribute names\n rowList (None, optional): Initial category data organized in rows corresponding to the attribute name list\n raiseExceptions (bool, optional): Flag to control if expections are raised or handled internally\n copyInputData (bool, optional): Copy rather than reference input data\n \"\"\"\n super(DataCategory, self).__init__(name, attributeNameList, rowList, raiseExceptions=raiseExceptions, copyInputData=copyInputData)\n #\n self.__verbose = False\n self._currentRowIndex = 0\n self.__currentAttribute = None\n #\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.countValuesWhereConditions","title":"countValuesWhereConditions(self, conditionsD)
","text":"Count row instances subject to input equivalence conditions
Parameters:
Name Type Description Default conditionsD
dict
{'atName': value, ....}
required Exceptions:
Type Description e
any failure
Returns:
Type Description int
count of instances satisfying input conditions
Source code in mmcif/api/DataCategory.py
def countValuesWhereConditions(self, conditionsD):\n \"\"\"Count row instances subject to input equivalence conditions\n\n Args:\n conditionsD (dict): {'atName': value, ....}\n\n Raises:\n e: any failure\n\n Returns:\n int: count of instances satisfying input conditions\n \"\"\"\n try:\n iCount = 0\n idxD = {k: self._attributeNameList.index(k) for k, v in conditionsD.items()}\n #\n for row in self.data:\n ok = True\n for k, v in conditionsD.items():\n ok = (v == row[idxD[k]]) and ok\n if ok:\n iCount += 1\n\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return iCount\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.countValuesWhereOpConditions","title":"countValuesWhereOpConditions(self, conditionTupleList)
","text":"Count row instances subject to input condition list
Parameters:
Name Type Description Default conditionTupleList
list
(attributeName, op, value) where (op = 'eq', 'gt(int)', 'lt(int)', 'in', 'ne', 'not in')
required Exceptions:
Type Description e
any failure
Returns:
Type Description int
count of instances satisfying input conditions
Source code in mmcif/api/DataCategory.py
def countValuesWhereOpConditions(self, conditionTupleList):\n \"\"\"Count row instances subject to input condition list\n\n Args:\n conditionTupleList (list): (attributeName, op, value) where (op = 'eq', 'gt(int)', 'lt(int)', 'in', 'ne', 'not in')\n\n Raises:\n e: any failure\n\n Returns:\n int: count of instances satisfying input conditions\n \"\"\"\n try:\n iCount = 0\n idxD = {atName: self._attributeNameList.index(atName) for (atName, op, value) in conditionTupleList}\n #\n for row in self.data:\n ok = True\n for (atName, op, v) in conditionTupleList:\n if op == \"eq\":\n ok = (v == row[idxD[atName]]) and ok\n elif op == \"ne\":\n ok = (v != row[idxD[atName]]) and ok\n elif op == \"lt(int)\":\n ok = (int(row[idxD[atName]]) < v) and ok\n elif op == \"gt(int)\":\n ok = (int(row[idxD[atName]]) > v) and ok\n elif op == \"in\":\n ok = (row[idxD[atName]] in v) and ok\n elif op == \"not in\":\n ok = (row[idxD[atName]] not in v) and ok\n if ok:\n iCount += 1\n\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return iCount\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.getCombinationCounts","title":"getCombinationCounts(self, attributeList)
","text":"Count the value occurrences of the input attributeList in the category.
Parameters:
Name Type Description Default attributeList
list
target list of attribute names
required Returns:
Type Description cD[(attribute value, ... )] = count
Source code in mmcif/api/DataCategory.py
def getCombinationCounts(self, attributeList):\n \"\"\"Count the value occurrences of the input attributeList in the category.\n\n Args:\n attributeList (list): target list of attribute names\n\n Returns:\n\n cD[(attribute value, ... )] = count\n\n \"\"\"\n cD = {}\n try:\n idxL = [self._attributeNameList.index(atName) for atName in attributeList]\n #\n for row in self.data:\n ky = tuple([row[jj] for jj in idxL])\n cD[ky] = cD[ky] + 1 if ky in cD else 1\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return cD\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.getCombinationCountsWithConditions","title":"getCombinationCountsWithConditions(self, attributeList, conditionTupleList)
","text":"Count the value occurrences of the input attributeList in the category.
Parameters:
Name Type Description Default attributeList
list
target list of attribute names
required conditionTupleList
list
(attributeName, op, value) where (op = 'eq', 'gt(int)', 'lt(int)', 'in', 'ne', 'not in')
required Returns:
Type Description cD[(attribute value, ... )] = count
Source code in mmcif/api/DataCategory.py
def getCombinationCountsWithConditions(self, attributeList, conditionTupleList):\n \"\"\"Count the value occurrences of the input attributeList in the category.\n\n Args:\n attributeList (list): target list of attribute names\n conditionTupleList (list): (attributeName, op, value) where (op = 'eq', 'gt(int)', 'lt(int)', 'in', 'ne', 'not in')\n\n Returns:\n\n cD[(attribute value, ... )] = count\n \"\"\"\n cD = {}\n try:\n idxL = [self._attributeNameList.index(atName) for atName in attributeList]\n idxD = {atName: self._attributeNameList.index(atName) for (atName, op, value) in conditionTupleList}\n #\n for row in self.data:\n ok = True\n for (atName, op, v) in conditionTupleList:\n if op == \"eq\":\n ok = (v == row[idxD[atName]]) and ok\n elif op == \"ne\":\n ok = (v != row[idxD[atName]]) and ok\n elif op == \"lt(int)\":\n ok = (int(row[idxD[atName]]) < v) and ok\n elif op == \"gt(int)\":\n ok = (int(row[idxD[atName]]) > v) and ok\n elif op == \"in\":\n ok = (row[idxD[atName]] in v) and ok\n elif op == \"not in\":\n ok = (row[idxD[atName]] not in v) and ok\n if ok:\n ky = tuple([row[jj] for jj in idxL])\n cD[ky] = cD[ky] + 1 if ky in cD else 1\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return cD\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.getFirstValueOrDefault","title":"getFirstValueOrDefault(self, attributeNameList, rowIndex=0, defaultValue='')
","text":"Return the value from the first non-null attribute found in the input attribute list from the row (rowIndex) in the current category object.
Source code in mmcif/api/DataCategory.py
def getFirstValueOrDefault(self, attributeNameList, rowIndex=0, defaultValue=\"\"):\n \"\"\"Return the value from the first non-null attribute found in the input attribute list\n from the row (rowIndex) in the current category object.\n \"\"\"\n try:\n for at in attributeNameList:\n if self.hasAttribute(at):\n tV = self.getValue(at, rowIndex)\n if (tV is None) or (tV in [\"\", \".\", \"?\"]):\n continue\n else:\n return tV\n except Exception as e:\n logger.debug(\"Failing with %s\", str(e))\n # if self._raiseExceptions:\n # raise e\n return defaultValue\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.getFullRow","title":"getFullRow(self, index)
","text":"Return a full row based on the length of the the attribute list or a row initialized with missing values
Source code in mmcif/api/DataCategory.py
def getFullRow(self, index):\n \"\"\"Return a full row based on the length of the the attribute list or a row initialized with missing values\"\"\"\n try:\n if len(self.data[index]) < self._numAttributes:\n for _ in range(self._numAttributes - len(self.data[index])):\n self.data[index].append(\"?\")\n return self.data[index]\n except Exception as e:\n logger.debug(\"Returning an empty row at %d (%s)\", index, str(e))\n return [\"?\" for ii in range(self._numAttributes)]\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.getValueOrDefault","title":"getValueOrDefault(self, attributeName=None, rowIndex=None, defaultValue='')
","text":"Within the current category return the value of input attribute in the input rowIndex [0-based].
On error or if the value missing or null return the default value. Empty values returned as is.
Exceptions on for unknown attributeNames and out-of-range indices.
Source code in mmcif/api/DataCategory.py
def getValueOrDefault(self, attributeName=None, rowIndex=None, defaultValue=\"\"):\n \"\"\"Within the current category return the value of input attribute in the input rowIndex [0-based].\n\n On error or if the value missing or null return the default value. Empty values returned as is.\n\n Exceptions on for unknown attributeNames and out-of-range indices.\n \"\"\"\n if attributeName is None:\n attribute = self.__currentAttribute\n else:\n attribute = attributeName\n if rowIndex is None:\n rowI = self._currentRowIndex\n else:\n rowI = rowIndex\n\n if isinstance(attribute, self._stringTypes) and isinstance(rowI, int):\n try:\n tV = self.data[rowI][self._attributeNameList.index(attribute)]\n if (tV is None) or (tV in [\".\", \"?\"]):\n return defaultValue\n else:\n return tV\n except Exception as e:\n logger.debug(\"Failing attributeName %s rowIndex %r defaultValue %r with %s\", attributeName, rowIndex, defaultValue, str(e))\n # if self._raiseExceptions:\n # raise e\n # Returning default -- no exception\n else:\n if self._raiseExceptions:\n raise ValueError\n #\n return defaultValue\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.selectValueListWhere","title":"selectValueListWhere(self, attributeNameList, attributeValueWhere, attributeNameWhere, returnCount=0)
","text":"Return a list of lists containing the values of input attributeNameList satisfying the attribute value where condition.
Source code in mmcif/api/DataCategory.py
def selectValueListWhere(self, attributeNameList, attributeValueWhere, attributeNameWhere, returnCount=0):\n \"\"\"Return a list of lists containing the values of input attributeNameList\n satisfying the attribute value where condition.\n \"\"\"\n rL = []\n try:\n iCount = 0\n indList = []\n for at in attributeNameList:\n indList.append(self._attributeNameList.index(at))\n indWhere = self._attributeNameList.index(attributeNameWhere)\n for row in self.data:\n if attributeValueWhere == row[indWhere]:\n rL.append([row[jj] for jj in indList])\n iCount += 1\n if returnCount and (iCount >= returnCount):\n break\n except Exception as e:\n if self.__verbose:\n logger.exception(\"Selection failure\")\n if self._raiseExceptions:\n raise e\n return rL\n
"},{"location":"api_reference/DataCategory/#mmcif.api.DataCategory.DataCategory.setValue","title":"setValue(self, value, attributeName=None, rowIndex=None)
","text":"Set the value of an existing attribute. rowIndex values >=0, where the category will be extended in length as needed.
Source code in mmcif/api/DataCategory.py
def setValue(self, value, attributeName=None, rowIndex=None):\n \"\"\"Set the value of an existing attribute. rowIndex values >=0, where\n the category will be extended in length as needed.\n \"\"\"\n if attributeName is None:\n attribute = self.__currentAttribute\n else:\n attribute = attributeName\n\n if rowIndex is None:\n rowI = self._currentRowIndex\n else:\n rowI = rowIndex\n\n if isinstance(attribute, self._stringTypes) and isinstance(rowI, int) and (rowI >= 0):\n try:\n ind = -2\n # if row index is out of range - add the rows -\n for ii in range(rowI + 1 - len(self.data)):\n self.data.append(self.__emptyRow())\n # self.data[rowI][attribute]=value\n ll = len(self.data[rowI])\n ind = self._attributeNameList.index(attribute)\n\n # extend the list if needed -\n if ind >= ll:\n self.data[rowI].extend([None for ii in range(ind - (ll - 1))])\n\n self.data[rowI][ind] = value\n return True\n except IndexError:\n if self.__verbose:\n logger.exception(\n \"DataCategory(setvalue) index error category %s attribute %s row index %d col %d rowlen %d value %r\",\n self._name,\n attribute,\n rowI,\n ind,\n len(self.data[rowI]),\n value,\n )\n logger.debug(\"DataCategory(setvalue) attribute %r length attribute list %d\", attribute, len(self._attributeNameList))\n for ii, aV in enumerate(self._attributeNameList):\n logger.debug(\"DataCategory(setvalue) %d attributeName %r\", ii, aV)\n if self._raiseExceptions:\n raise IndexError\n except ValueError:\n if self.__verbose:\n logger.exception(\"DataCategory(setvalue) value error category %s attribute %s row index %d value %r\", self._name, attribute, rowI, value)\n if self._raiseExceptions:\n raise ValueError\n else:\n if self._raiseExceptions:\n raise ValueError\n return False\n
"},{"location":"api_reference/DataCategoryBase/","title":"DataCategoryBase","text":"Base object definition for a data category -
This class subclasses UserList and implements many list-like features for row data managed by this class.
Source code in mmcif/api/DataCategoryBase.py
class DataCategoryBase(UserList):\n\n \"\"\"Base object definition for a data category -\n\n This class subclasses UserList and implements many list-like features for\n row data managed by this class.\n\n \"\"\"\n\n def __init__(self, name, attributeNameList=None, rowList=None, raiseExceptions=True, copyInputData=True):\n self._name = name\n if copyInputData:\n self._attributeNameList = copy.deepcopy(attributeNameList) if attributeNameList is not None else []\n # self.data = copy.deepcopy(rowList) if rowList is not None else []\n else:\n self._attributeNameList = attributeNameList if attributeNameList is not None else []\n # self.data = rowList if rowList is not None else []\n #\n # -------\n if rowList is None or (isinstance(rowList, list) and not rowList):\n self.data = []\n elif isinstance(rowList, list) and rowList:\n if isinstance(rowList[0], (list, tuple)):\n if copyInputData:\n self.data = copy.deepcopy(rowList) if rowList is not None else []\n else:\n self.data = rowList if rowList is not None else []\n\n elif isinstance(rowList[0], dict):\n rL = []\n for rowD in rowList:\n rL.append([rowD[k] if k in rowD else None for k in self._attributeNameList])\n if copyInputData:\n self.data = copy.deepcopy(rL)\n else:\n self.data = rL\n\n else:\n if raiseExceptions:\n raise ValueError\n else:\n logger.error(\"Initialization failure\")\n else:\n if raiseExceptions:\n raise ValueError\n else:\n logger.error(\"Initialization failure\")\n\n # -------\n #\n self._itemNameList = []\n self.__mappingType = \"DATA\"\n self._raiseExceptions = raiseExceptions\n self._copyInputData = copyInputData\n #\n super(DataCategoryBase, self).__init__(self.data)\n #\n # Derived class data -\n #\n self._catalog = {}\n self._numAttributes = 0\n #\n self._stringTypes = basestring\n self.__setup()\n\n def __setup(self):\n self._numAttributes = len(self._attributeNameList)\n self._catalog = {}\n for attributeName in self._attributeNameList:\n attributeNameLC = attributeName.lower()\n self._catalog[attributeNameLC] = attributeName\n self.__updateItemLabels()\n\n # Add append/extend methods to accept row lists and dictionaries -\n #\n\n def append(self, row):\n if isinstance(row, (list, tuple)):\n self.data.append(row)\n return True\n elif isinstance(row, dict):\n try:\n # -\n self.data.append([row[k] if k in row else None for k in self._attributeNameList])\n return False\n except Exception as e:\n if self._raiseExceptions:\n raise e\n else:\n logger.error(\"Row processing failing with %s\", str(e))\n else:\n if self._raiseExceptions:\n raise ValueError\n else:\n logger.error(\"Unsupported row type\")\n return False\n\n def extend(self, rowList):\n if isinstance(rowList, list) and rowList:\n if isinstance(rowList[0], (list, tuple)):\n if self._copyInputData:\n self.data.extend(copy.deepcopy(rowList))\n else:\n self.data.extend(rowList)\n return True\n elif isinstance(rowList[0], dict):\n rL = []\n for rowD in rowList:\n # -\n rL.append([rowD[k] if k in rowD else None for k in self._attributeNameList])\n if self._copyInputData:\n self.data.extend(copy.deepcopy(rL))\n else:\n self.data.extend(rL)\n return True\n else:\n if self._raiseExceptions:\n raise ValueError\n else:\n logger.error(\"unexpected row data type\")\n else:\n logger.error(\"unexpected input data type\")\n return False\n\n #\n # Setters/appenders\n #\n\n def setName(self, name):\n self._name = name\n\n def setRowList(self, rowList):\n if self._copyInputData:\n self.data = copy.deepcopy(rowList)\n else:\n self.data = rowList\n\n def setAttributeNameList(self, attributeNameList):\n if self._copyInputData:\n self._attributeNameList = copy.deepcopy(attributeNameList)\n else:\n self._attributeNameList = attributeNameList\n self.__setup()\n\n def appendAttribute(self, attributeName):\n attributeNameLC = attributeName.lower()\n if attributeNameLC in self._catalog:\n i = self._attributeNameList.index(self._catalog[attributeNameLC])\n self._attributeNameList[i] = attributeName\n self._catalog[attributeNameLC] = attributeName\n else:\n self._attributeNameList.append(attributeName)\n self._catalog[attributeNameLC] = attributeName\n #\n self._numAttributes = len(self._attributeNameList)\n return self._numAttributes\n\n def renameAttributes(self, mapDict):\n \"\"\"Rename attributes according to mapping information in the input mapping dictionary {oldName: newName}\"\"\"\n atL = []\n for atName in self._attributeNameList:\n atL.append(mapDict[atName] if atName in mapDict else atName)\n self._attributeNameList = atL\n self.__setup()\n return True\n\n ##\n # Getters\n ##\n def get(self):\n return (self._name, self._attributeNameList, self.data)\n\n def getName(self):\n return self._name\n\n def getAttributeList(self):\n return self._attributeNameList\n\n def getAttributeCount(self):\n return len(self._attributeNameList)\n\n def getAttributeIndex(self, attributeName):\n try:\n return self._attributeNameList.index(attributeName)\n except Exception as e:\n logger.debug(\"Fails for %s with %s\", attributeName, str(e))\n\n return -1\n\n def getAttributeIndexDict(self):\n rD = {}\n for ii, attributeName in enumerate(self._attributeNameList):\n rD[attributeName] = ii\n return rD\n\n def getIndex(self, attributeName):\n return self.getAttributeIndex(attributeName)\n\n def hasAttribute(self, attributeName):\n return attributeName in self._attributeNameList\n\n def getItemNameList(self):\n return self.__updateItemLabels()\n\n def getRowList(self):\n return self.data\n\n def getRowCount(self):\n return len(self.data)\n\n def getRow(self, index):\n try:\n return self.data[index]\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return []\n\n def getColumn(self, index):\n try:\n return [row[index] for row in self.data]\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return []\n\n def getRowAttributeDict(self, index):\n rD = {}\n try:\n for ii, v in enumerate(self.data[index]):\n rD[self._attributeNameList[ii]] = v\n return rD\n except Exception as e:\n if self._raiseExceptions:\n raise e\n\n return rD\n\n def getRowItemDict(self, index):\n rD = {}\n try:\n self.__updateItemLabels()\n for ii, v in enumerate(self.data[index]):\n rD[self._itemNameList[ii]] = v\n return rD\n except Exception as e:\n if self._raiseExceptions:\n raise e\n\n return rD\n\n def getAttributeValueList(self, attributeName):\n \"\"\"Return a list of attribute values.\"\"\"\n rL = []\n try:\n idx = self.getAttributeIndex(attributeName)\n rL = [row[idx] for row in self.data]\n return rL\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return rL\n\n def getAttributeUniqueValueList(self, attributeName):\n \"\"\"Return a sorted list of unique attribute values.\"\"\"\n rL = []\n try:\n rD = {}\n idx = self.getAttributeIndex(attributeName)\n rD = {row[idx]: True for row in self.data}\n return sorted(rD.keys())\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return rL\n\n def removeRow(self, index):\n try:\n del self.data[index]\n return True\n except Exception as e:\n if self._raiseExceptions:\n raise e\n\n return False\n\n def removeRows(self, indexList):\n try:\n iL = sorted(indexList, reverse=True)\n for i in iL:\n del self.data[i]\n return True\n except Exception as e:\n if self._raiseExceptions:\n raise e\n\n return False\n\n def removeDuplicateRows(self):\n \"\"\"Remove duplicate rows from the category\n\n Raises:\n e: any exception\n\n Returns:\n bool: True for success or False otherwise\n \"\"\"\n try:\n filteredL = []\n for row in self.data:\n if row not in filteredL:\n filteredL.append(row)\n self.data = filteredL\n return True\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return False\n\n def removeAttribute(self, attributeName):\n \"\"\"Remove the attribute from the attribute list along with any\n corresponding row data.\n \"\"\"\n idx = self.getAttributeIndex(attributeName)\n if idx != -1:\n try:\n del self._attributeNameList[idx]\n for row in self.data:\n try:\n del row[idx]\n except Exception:\n pass\n self.__setup()\n return True\n except Exception:\n return False\n\n ##\n ##\n ##\n def __updateItemLabels(self):\n \"\"\"Internal method to create mmCIF style item names for the current attribute\n list.\n \"\"\"\n self._itemNameList = []\n for atName in self._attributeNameList:\n self._itemNameList.append(\"_\" + str(self._name) + \".\" + atName)\n #\n return self._itemNameList\n\n def __alignLabels(self, row):\n \"\"\"Internal method which aligns the list of input attributes with row data.\n\n If there are fewer labels than data elements in a row, then placeholder labels\n are created (e.g. \"unlabeled_#\")\n\n \"\"\"\n if len(row) > len(self._attributeNameList):\n for i in range(len(self._attributeNameList), len(row) - 1):\n self._attributeNameList.insert(i, \"unlabeled_\" + str(i))\n if self.__mappingType == \"ITEM\":\n self.__updateItemLabels()\n\n def setMapping(self, mType):\n \"\"\"Controls the manner in which this class returns data when accessed by\n index or in the context of an iterator:\n\n DATA = list of row data elements as these were input. [default]\n\n ATTRIBUTE = row returned as a dictionary with attribute key\n\n ITEM = row returned as a dictionary with item key\n\n \"\"\"\n if mType in [\"DATA\", \"ATTRIBUTE\", \"ITEM\"]:\n self.__mappingType = mType\n return True\n else:\n return False\n\n def __str__(self):\n ans = \"name:%r\\nattrbuteList: %r\\nData: %r\\n\" % (self._name, self._attributeNameList, list(self.data))\n return ans\n\n def __repr__(self):\n return self.__class__.__name__ + \"(\" + str(self) + \")\"\n\n def __iter__(self):\n for dD in self.data:\n yield self.__applyMapping(dD)\n\n def __getitem__(self, idx):\n return self.__applyMapping(self.data[idx])\n\n def __setitem__(self, idx, value):\n dL = self.__extractMapping(value)\n self.data[idx] = dL\n\n def __applyMapping(self, dD):\n if self.__mappingType == \"DATA\":\n return dD\n elif self.__mappingType == \"ATTRIBUTE\":\n self.__alignLabels(dD)\n return dict(list(zip(self._attributeNameList, dD)))\n elif self.__mappingType == \"ITEM\":\n self.__alignLabels(dD)\n self.__updateItemLabels()\n return dict(list(zip(self._itemNameList, dD)))\n\n def __extractMapping(self, dD):\n try:\n if self.__mappingType == \"DATA\":\n return dD\n elif self.__mappingType == \"ATTRIBUTE\":\n rL = []\n for k, v in dD.items():\n rL.insert(self._attributeNameList.index(k), v)\n return rL\n elif self.__mappingType == \"ITEM\":\n rL = []\n for k, v in dD.items():\n rL.insert(self._itemNameList.index(k), v)\n return rL\n except Exception:\n if self._raiseExceptions:\n raise IndexError\n return None\n\n def cmpAttributeNames(self, dcObj):\n \"\"\"Compare the attributeNameList in current data category (dca) and input data category .\n\n Return: (current attributes not in dcObj), (attributes common to both), (attributes in dcObj not in current data category)\n \"\"\"\n sa = set(self.getAttributeList())\n sb = set(dcObj.getAttributeList())\n return tuple(sa - sb), tuple(sa & sb), tuple(sb - sa)\n\n def cmpAttributeValues(self, dcObj, ignoreOrder=True, **kwargs):\n \"\"\"Compare the values by attribute for current data category (dca) and input data category.\n The comparison is performed independently for the values of corresponding attributes.\n Length differences are treated inequality out of hand.\n\n Return: [(attributeName, values equal flag (bool)), (attributeName, values equal flag (bool), ...]\n \"\"\"\n rL = []\n try:\n _ = kwargs\n sa = set(self.getAttributeList())\n sb = set(dcObj.getAttributeList())\n atComList = list(sa & sb)\n #\n lenEq = self.getRowCount() == dcObj.getRowCount()\n for at in atComList:\n if lenEq:\n if ignoreOrder:\n same = sorted(self.getAttributeValueList(at)) == sorted(dcObj.getAttributeValueList(at))\n else:\n same = self.getAttributeValueList(at) == dcObj.getAttributeValueList(at)\n else:\n same = False\n rL.append((at, same))\n return rL\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return rL\n\n def __eq__(self, other):\n \"\"\"Override the default Equals behavior\"\"\"\n if isinstance(other, self.__class__):\n return self.__dict__ == other.__dict__\n return NotImplemented\n\n def __ne__(self, other):\n \"\"\"Define a non-equality test\"\"\"\n if isinstance(other, self.__class__):\n return not self.__eq__(other)\n return NotImplemented\n\n def __hash__(self):\n \"\"\"Override the default hash behavior (that returns the id or the object)\"\"\"\n # return hash(tuple(sorted(self.__dict__.items())))\n return hash((self._name, tuple(self._attributeNameList), tuple(tuple(x) for x in self.data)))\n\n #\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.__eq__","title":"__eq__(self, other)
special
","text":"Override the default Equals behavior
Source code in mmcif/api/DataCategoryBase.py
def __eq__(self, other):\n \"\"\"Override the default Equals behavior\"\"\"\n if isinstance(other, self.__class__):\n return self.__dict__ == other.__dict__\n return NotImplemented\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.__hash__","title":"__hash__(self)
special
","text":"Override the default hash behavior (that returns the id or the object)
Source code in mmcif/api/DataCategoryBase.py
def __hash__(self):\n \"\"\"Override the default hash behavior (that returns the id or the object)\"\"\"\n # return hash(tuple(sorted(self.__dict__.items())))\n return hash((self._name, tuple(self._attributeNameList), tuple(tuple(x) for x in self.data)))\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.__ne__","title":"__ne__(self, other)
special
","text":"Define a non-equality test
Source code in mmcif/api/DataCategoryBase.py
def __ne__(self, other):\n \"\"\"Define a non-equality test\"\"\"\n if isinstance(other, self.__class__):\n return not self.__eq__(other)\n return NotImplemented\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.append","title":"append(self, row)
","text":"S.append(value) -- append value to the end of the sequence
Source code in mmcif/api/DataCategoryBase.py
def append(self, row):\n if isinstance(row, (list, tuple)):\n self.data.append(row)\n return True\n elif isinstance(row, dict):\n try:\n # -\n self.data.append([row[k] if k in row else None for k in self._attributeNameList])\n return False\n except Exception as e:\n if self._raiseExceptions:\n raise e\n else:\n logger.error(\"Row processing failing with %s\", str(e))\n else:\n if self._raiseExceptions:\n raise ValueError\n else:\n logger.error(\"Unsupported row type\")\n return False\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.cmpAttributeNames","title":"cmpAttributeNames(self, dcObj)
","text":"Compare the attributeNameList in current data category (dca) and input data category .
Return: (current attributes not in dcObj), (attributes common to both), (attributes in dcObj not in current data category)
Source code in mmcif/api/DataCategoryBase.py
def cmpAttributeNames(self, dcObj):\n \"\"\"Compare the attributeNameList in current data category (dca) and input data category .\n\n Return: (current attributes not in dcObj), (attributes common to both), (attributes in dcObj not in current data category)\n \"\"\"\n sa = set(self.getAttributeList())\n sb = set(dcObj.getAttributeList())\n return tuple(sa - sb), tuple(sa & sb), tuple(sb - sa)\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.cmpAttributeValues","title":"cmpAttributeValues(self, dcObj, ignoreOrder=True, **kwargs)
","text":"Compare the values by attribute for current data category (dca) and input data category. The comparison is performed independently for the values of corresponding attributes. Length differences are treated inequality out of hand.
Return: [(attributeName, values equal flag (bool)), (attributeName, values equal flag (bool), ...]
Source code in mmcif/api/DataCategoryBase.py
def cmpAttributeValues(self, dcObj, ignoreOrder=True, **kwargs):\n \"\"\"Compare the values by attribute for current data category (dca) and input data category.\n The comparison is performed independently for the values of corresponding attributes.\n Length differences are treated inequality out of hand.\n\n Return: [(attributeName, values equal flag (bool)), (attributeName, values equal flag (bool), ...]\n \"\"\"\n rL = []\n try:\n _ = kwargs\n sa = set(self.getAttributeList())\n sb = set(dcObj.getAttributeList())\n atComList = list(sa & sb)\n #\n lenEq = self.getRowCount() == dcObj.getRowCount()\n for at in atComList:\n if lenEq:\n if ignoreOrder:\n same = sorted(self.getAttributeValueList(at)) == sorted(dcObj.getAttributeValueList(at))\n else:\n same = self.getAttributeValueList(at) == dcObj.getAttributeValueList(at)\n else:\n same = False\n rL.append((at, same))\n return rL\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return rL\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.extend","title":"extend(self, rowList)
","text":"S.extend(iterable) -- extend sequence by appending elements from the iterable
Source code in mmcif/api/DataCategoryBase.py
def extend(self, rowList):\n if isinstance(rowList, list) and rowList:\n if isinstance(rowList[0], (list, tuple)):\n if self._copyInputData:\n self.data.extend(copy.deepcopy(rowList))\n else:\n self.data.extend(rowList)\n return True\n elif isinstance(rowList[0], dict):\n rL = []\n for rowD in rowList:\n # -\n rL.append([rowD[k] if k in rowD else None for k in self._attributeNameList])\n if self._copyInputData:\n self.data.extend(copy.deepcopy(rL))\n else:\n self.data.extend(rL)\n return True\n else:\n if self._raiseExceptions:\n raise ValueError\n else:\n logger.error(\"unexpected row data type\")\n else:\n logger.error(\"unexpected input data type\")\n return False\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.getAttributeUniqueValueList","title":"getAttributeUniqueValueList(self, attributeName)
","text":"Return a sorted list of unique attribute values.
Source code in mmcif/api/DataCategoryBase.py
def getAttributeUniqueValueList(self, attributeName):\n \"\"\"Return a sorted list of unique attribute values.\"\"\"\n rL = []\n try:\n rD = {}\n idx = self.getAttributeIndex(attributeName)\n rD = {row[idx]: True for row in self.data}\n return sorted(rD.keys())\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return rL\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.getAttributeValueList","title":"getAttributeValueList(self, attributeName)
","text":"Return a list of attribute values.
Source code in mmcif/api/DataCategoryBase.py
def getAttributeValueList(self, attributeName):\n \"\"\"Return a list of attribute values.\"\"\"\n rL = []\n try:\n idx = self.getAttributeIndex(attributeName)\n rL = [row[idx] for row in self.data]\n return rL\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return rL\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.removeAttribute","title":"removeAttribute(self, attributeName)
","text":"Remove the attribute from the attribute list along with any corresponding row data.
Source code in mmcif/api/DataCategoryBase.py
def removeAttribute(self, attributeName):\n \"\"\"Remove the attribute from the attribute list along with any\n corresponding row data.\n \"\"\"\n idx = self.getAttributeIndex(attributeName)\n if idx != -1:\n try:\n del self._attributeNameList[idx]\n for row in self.data:\n try:\n del row[idx]\n except Exception:\n pass\n self.__setup()\n return True\n except Exception:\n return False\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.removeDuplicateRows","title":"removeDuplicateRows(self)
","text":"Remove duplicate rows from the category
Exceptions:
Type Description e
any exception
Returns:
Type Description bool
True for success or False otherwise
Source code in mmcif/api/DataCategoryBase.py
def removeDuplicateRows(self):\n \"\"\"Remove duplicate rows from the category\n\n Raises:\n e: any exception\n\n Returns:\n bool: True for success or False otherwise\n \"\"\"\n try:\n filteredL = []\n for row in self.data:\n if row not in filteredL:\n filteredL.append(row)\n self.data = filteredL\n return True\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return False\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.renameAttributes","title":"renameAttributes(self, mapDict)
","text":"Rename attributes according to mapping information in the input mapping dictionary {oldName: newName}
Source code in mmcif/api/DataCategoryBase.py
def renameAttributes(self, mapDict):\n \"\"\"Rename attributes according to mapping information in the input mapping dictionary {oldName: newName}\"\"\"\n atL = []\n for atName in self._attributeNameList:\n atL.append(mapDict[atName] if atName in mapDict else atName)\n self._attributeNameList = atL\n self.__setup()\n return True\n
"},{"location":"api_reference/DataCategoryBase/#mmcif.api.DataCategoryBase.DataCategoryBase.setMapping","title":"setMapping(self, mType)
","text":"Controls the manner in which this class returns data when accessed by index or in the context of an iterator:
DATA = list of row data elements as these were input. [default]
ATTRIBUTE = row returned as a dictionary with attribute key
ITEM = row returned as a dictionary with item key
Source code in mmcif/api/DataCategoryBase.py
def setMapping(self, mType):\n \"\"\"Controls the manner in which this class returns data when accessed by\n index or in the context of an iterator:\n\n DATA = list of row data elements as these were input. [default]\n\n ATTRIBUTE = row returned as a dictionary with attribute key\n\n ITEM = row returned as a dictionary with item key\n\n \"\"\"\n if mType in [\"DATA\", \"ATTRIBUTE\", \"ITEM\"]:\n self.__mappingType = mType\n return True\n else:\n return False\n
"},{"location":"api_reference/DataCategoryFormatted/","title":"DataCategoryFormatted","text":"A subclass of DataCategory including additional formatting methods.
Source code in mmcif/api/DataCategoryFormatted.py
class DataCategoryFormatted(DataCategory):\n \"\"\"A subclass of DataCategory including additional formatting methods.\"\"\"\n\n def __init__(self, dataCategoryObj, preferDoubleQuotes=True):\n self.__dcObj = dataCategoryObj\n super(DataCategoryFormatted, self).__init__(self.__dcObj.getName(), self.__dcObj.getAttributeList(), self.__dcObj.data)\n #\n self._currentRowIndex = 0\n self._currentAttribute = None\n #\n self.__avoidEmbeddedQuoting = False\n self.__preferDoubleQuotes = preferDoubleQuotes\n #\n # --------------------------------------------------------------------\n # any whitespace\n self.__wsRe = re.compile(r\"\\s\")\n # self.__wsAndQuotesRe=re.compile(r\"[\\s'\\\"]\")\n self.__wsAndQuotesRe = re.compile(r\"[\\s'\\\"#]\")\n # any newline or carriage control\n self.__nlRe = re.compile(r\"[\\n\\r]\")\n #\n # single quote\n self.__sqRe = re.compile(r\"[']\")\n #\n self.__sqWsRe = re.compile(r\"('\\s)|(\\s')\")\n\n # double quote\n self.__dqRe = re.compile(r'[\"]')\n self.__dqWsRe = re.compile(r'(\"\\s)|(\\s\")')\n #\n self.__intRe = re.compile(r\"^[0-9]+$\")\n self.__floatRe = re.compile(r\"^-?(([0-9]+)[.]?|([0-9]*[.][0-9]+))([(][0-9]+[)])?([eE][+-]?[0-9]+)?$\")\n #\n self.__dataTypeList = [\n \"DT_NULL_VALUE\",\n \"DT_INTEGER\",\n \"DT_FLOAT\",\n \"DT_UNQUOTED_STRING\",\n \"DT_ITEM_NAME\",\n \"DT_DOUBLE_QUOTED_STRING\",\n \"DT_SINGLE_QUOTED_STRING\",\n \"DT_MULTI_LINE_STRING\",\n ]\n self.__formatTypeList = [\n \"FT_NULL_VALUE\",\n \"FT_NUMBER\",\n \"FT_NUMBER\",\n \"FT_UNQUOTED_STRING\",\n \"FT_QUOTED_STRING\",\n \"FT_QUOTED_STRING\",\n \"FT_QUOTED_STRING\",\n \"FT_MULTI_LINE_STRING\",\n ]\n #\n # try:\n # basestring\n # except NameError:\n # basestring = str\n #\n # self.__string_types = basestring\n\n def __formatPdbx(self, inp):\n \"\"\"Format input data following PDBx quoting rules -\"\"\"\n try:\n if inp is None:\n return (\"?\", \"DT_NULL_VALUE\")\n\n # pure numerical values are returned as unquoted strings\n # if (isinstance(inp, int) or self.__intRe.search(str(inp))):\n #\n try:\n if isinstance(inp, int) or self.__intRe.search(inp):\n return ([str(inp)], \"DT_INTEGER\")\n except Exception:\n pass\n\n # if (isinstance(inp, float) or self.__floatRe.search(str(inp))):\n try:\n if isinstance(inp, float) or self.__floatRe.search(inp):\n return ([str(inp)], \"DT_FLOAT\")\n except Exception:\n pass\n\n # null value handling -\n\n if inp == \".\" or inp == \"?\":\n return ([inp], \"DT_NULL_VALUE\")\n\n if inp == \"\":\n return ([\".\"], \"DT_NULL_VALUE\")\n\n # Contains white space or quotes ?\n if not self.__wsAndQuotesRe.search(inp):\n # if inp.startswith(\"_\"):\n if inp[0] in [\"_\"]:\n return (self.__doubleQuotedList(inp), \"DT_ITEM_NAME\")\n elif inp[0] in [\"[\", \"]\", \"$\", \"#\", \";\"]:\n return (self.__doubleQuotedList(inp), \"DT_DOUBLE_QUOTED_STRING\")\n elif inp[:5].lower() in [\"data_\", \"loop_\", \"save_\", \"stop_\"]:\n return (self.__doubleQuotedList(inp), \"DT_DOUBLE_QUOTED_STRING\")\n else:\n return ([str(inp)], \"DT_UNQUOTED_STRING\")\n else:\n if self.__nlRe.search(inp):\n return (self.__semiColonQuotedList(inp), \"DT_MULTI_LINE_STRING\")\n else:\n if self.__preferDoubleQuotes:\n if self.__avoidEmbeddedQuoting:\n # change priority to choose double quoting where possible.\n if not self.__dqRe.search(inp) and not self.__sqWsRe.search(inp):\n return (self.__doubleQuotedList(inp), \"DT_DOUBLE_QUOTED_STRING\")\n elif not self.__sqRe.search(inp) and not self.__dqWsRe.search(inp):\n return (self.__singleQuotedList(inp), \"DT_SINGLE_QUOTED_STRING\")\n else:\n return (self.__semiColonQuotedList(inp), \"DT_MULTI_LINE_STRING\")\n else:\n # change priority to choose double quoting where possible.\n if not self.__dqRe.search(inp):\n return (self.__doubleQuotedList(inp), \"DT_DOUBLE_QUOTED_STRING\")\n elif not self.__sqRe.search(inp):\n return (self.__singleQuotedList(inp), \"DT_SINGLE_QUOTED_STRING\")\n else:\n return (self.__semiColonQuotedList(inp), \"DT_MULTI_LINE_STRING\")\n else:\n if self.__avoidEmbeddedQuoting:\n # change priority to choose double quoting where possible.\n if not self.__sqRe.search(inp) and not self.__dqWsRe.search(inp):\n return (self.__singleQuotedList(inp), \"DT_SINGLE_QUOTED_STRING\")\n elif not self.__dqRe.search(inp) and not self.__sqWsRe.search(inp):\n return (self.__doubleQuotedList(inp), \"DT_DOUBLE_QUOTED_STRING\")\n else:\n return (self.__semiColonQuotedList(inp), \"DT_MULTI_LINE_STRING\")\n else:\n # change priority to choose double quoting where possible.\n if not self.__sqRe.search(inp):\n return (self.__singleQuotedList(inp), \"DT_SINGLE_QUOTED_STRING\")\n elif not self.__dqRe.search(inp):\n return (self.__doubleQuotedList(inp), \"DT_DOUBLE_QUOTED_STRING\")\n else:\n return (self.__semiColonQuotedList(inp), \"DT_MULTI_LINE_STRING\")\n except Exception as e:\n logger.exception(\"Failing with %s on input %r %r\", str(e), inp, type(inp))\n\n return (\"?\", \"DT_NULL_VALUE\")\n\n def __dataTypePdbx(self, inp):\n \"\"\"Detect the PDBx data type -\"\"\"\n if inp is None:\n return \"DT_NULL_VALUE\"\n\n # pure numerical values are returned as unquoted strings\n # if isinstance(inp, int) or self.__intRe.search(str(inp)):\n if isinstance(inp, int) or (isinstance(inp, string_types) and self.__intRe.search(inp)):\n return \"DT_INTEGER\"\n\n # if isinstance(inp, float) or self.__floatRe.search(str(inp)):\n if isinstance(inp, float) or (isinstance(inp, string_types) and self.__floatRe.search(inp)):\n return \"DT_FLOAT\"\n\n # null value handling -\n\n if inp == \".\" or inp == \"?\":\n return \"DT_NULL_VALUE\"\n\n if inp == \"\":\n return \"DT_NULL_VALUE\"\n\n # Contains white space or quotes ?\n if not self.__wsAndQuotesRe.search(inp):\n if inp.startswith(\"_\"):\n return \"DT_ITEM_NAME\"\n else:\n return \"DT_UNQUOTED_STRING\"\n else:\n if self.__nlRe.search(inp):\n return \"DT_MULTI_LINE_STRING\"\n else:\n if self.__avoidEmbeddedQuoting:\n if not self.__sqRe.search(inp) and not self.__dqWsRe.search(inp):\n return \"DT_DOUBLE_QUOTED_STRING\"\n elif not self.__dqRe.search(inp) and not self.__sqWsRe.search(inp):\n return \"DT_SINGLE_QUOTED_STRING\"\n else:\n return \"DT_MULTI_LINE_STRING\"\n else:\n if not self.__sqRe.search(inp):\n return \"DT_DOUBLE_QUOTED_STRING\"\n elif not self.__dqRe.search(inp):\n return \"DT_SINGLE_QUOTED_STRING\"\n else:\n return \"DT_MULTI_LINE_STRING\"\n\n def __singleQuotedList(self, inp):\n ll = []\n ll.append(\"'\")\n ll.append(inp)\n ll.append(\"'\")\n return ll\n\n def __doubleQuotedList(self, inp):\n ll = []\n ll.append('\"')\n ll.append(inp)\n ll.append('\"')\n return ll\n\n def __semiColonQuotedList(self, inp):\n ll = []\n ll.append(\"\\n\")\n if inp[-1] == \"\\n\":\n ll.append(\";\")\n ll.append(inp)\n ll.append(\";\")\n ll.append(\"\\n\")\n else:\n ll.append(\";\")\n ll.append(inp)\n ll.append(\"\\n\")\n ll.append(\";\")\n ll.append(\"\\n\")\n\n return ll\n\n def getValueFormatted(self, attributeName=None, rowIndex=None):\n if attributeName is None:\n attribute = self._currentAttribute\n else:\n attribute = attributeName\n\n if rowIndex is None:\n rowI = self._currentRowIndex\n else:\n rowI = rowIndex\n\n if isinstance(attribute, self._stringTypes) and isinstance(rowI, int):\n try:\n fList, _ = self.__formatPdbx(self.data[rowI][self._attributeNameList.index(attribute)])\n return \"\".join(fList)\n except IndexError:\n logger.exception(\"attributeName %s rowI %r rowdata %r\", attributeName, rowI, self.data[rowI])\n raise IndexError\n except Exception as e:\n logger.exception(\" Failing with %s - AttributeName %s rowI %r rowdata %r\", str(e), attributeName, rowI, self.data[rowI])\n else:\n logger.error(\" Type error - AttributeName %r rowI %r rowdata %r\", attributeName, rowI, self.data[rowI])\n logger.error(\" Type error - string types %r\", self._stringTypes)\n raise TypeError(attribute)\n\n def getValueFormattedByIndex(self, attributeIndex, rowIndex):\n try:\n fList, _ = self.__formatPdbx(self.data[rowIndex][attributeIndex])\n return \"\".join(fList)\n except IndexError:\n logger.exception(\"attributeIndex %r rowIndex %r rowdata %r\", attributeIndex, rowIndex, self.data[rowIndex][attributeIndex])\n raise IndexError\n except Exception as e:\n logger.exception(\"Failing with %s - attributeIndex %r rowIndex %r rowdata %r\", str(e), attributeIndex, rowIndex, self.data[rowIndex][attributeIndex])\n raise e\n\n def getAttributeValueMaxLengthList(self, steps=1):\n mList = [0 for i in range(len(self._attributeNameList))]\n for row in self.data[::steps]:\n for indx in range(len(self._attributeNameList)):\n val = row[indx]\n if isinstance(val, self._stringTypes):\n tLen = len(val)\n else:\n tLen = len(str(val))\n\n mList[indx] = max(mList[indx], tLen)\n return mList\n\n def getFormatTypeList(self, steps=1):\n try:\n curFormatTypeList = []\n curDataTypeList = [\"DT_NULL_VALUE\" for i in range(len(self._attributeNameList))]\n for row in self.data[::steps]:\n for indx in range(len(self._attributeNameList)):\n val = row[indx]\n # print \"index \",indx,\" val \",val\n dType = self.__dataTypePdbx(val)\n dIndx = self.__dataTypeList.index(dType)\n # print \"d type\", dType, \" d type index \",dIndx\n\n cType = curDataTypeList[indx]\n cIndx = self.__dataTypeList.index(cType)\n cIndx = max(cIndx, dIndx)\n curDataTypeList[indx] = self.__dataTypeList[cIndx]\n\n # Map the format types to the data types\n curFormatTypeList = []\n for dt in curDataTypeList:\n ii = self.__dataTypeList.index(dt)\n curFormatTypeList.append(self.__formatTypeList[ii])\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n\n return curFormatTypeList, curDataTypeList\n
"},{"location":"api_reference/DataCategoryTyped/","title":"DataCategoryTyped","text":"A subclass of DataCategory with methods to apply explicit data typing.
Source code in mmcif/api/DataCategoryTyped.py
class DataCategoryTyped(DataCategory):\n \"\"\"A subclass of DataCategory with methods to apply explicit data typing.\"\"\"\n\n def __init__(\n self,\n dataCategoryObj,\n dictionaryApi=None,\n raiseExceptions=True,\n copyInputData=True,\n ignoreCastErrors=False,\n useCifUnknowns=True,\n missingValueString=None,\n missingValueInteger=None,\n missingValueFloat=None,\n ):\n \"\"\"A subclass of DataCategory with methods to apply explicit data typing.\n\n Args:\n dataCategoryObj (object): DataCategory object instance\n dictionaryApi (object, optional): instance of DictionaryApi class. Defaults to None.\n raiseExceptions (bool, optional): raise exceptions. Defaults to True.\n copyInputData (bool, optional): make a new copy input data. Defaults to True.\n ignoreCastErrors (bool, optional): ignore data processing cast errors. Defaults to False.\n useCifUnknowns (bool, optional): use CIF style missing values ('.' and '?'). Defaults to True.\n missingValueString (str, optional): missing string value . Defaults to None.\n missingValueInteger (integer, optional): missing integer value. Defaults to None.\n missingValueFloat (float, optional): missing float value. Defaults to None.\n \"\"\"\n self.__dcObj = dataCategoryObj\n super(DataCategoryTyped, self).__init__(\n self.__dcObj.getName(),\n self.__dcObj.getAttributeList(),\n self.__dcObj.data,\n raiseExceptions=raiseExceptions,\n copyInputData=copyInputData,\n )\n #\n self.__dApi = dictionaryApi\n self.__attributeTypeD = {}\n self.__castD = {\"integer\": int, \"float\": float, \"string\": str}\n self.__typesSet = self.applyTypes(\n ignoreCastErrors=ignoreCastErrors,\n useCifUnknowns=useCifUnknowns,\n missingValueString=missingValueString,\n missingValueInteger=missingValueInteger,\n missingValueFloat=missingValueFloat,\n )\n\n def applyTypes(self, ignoreCastErrors=False, useCifUnknowns=True, missingValueString=None, missingValueInteger=None, missingValueFloat=None):\n \"\"\"Cast data types (string, integer, float) in the current object based on dictionary type details.\n Missing values ('.' or '?') are set to None.\n\n Raises:\n e: any exception\n\n Returns:\n bool: True for success or False otherwise\n \"\"\"\n ok = False\n try:\n for ii, atName in enumerate(self.getAttributeList()):\n # colValL = self.getColumn(ii)\n dataType, isMandatory = self.__getAttributeInfo(atName)\n missingValue = missingValueInteger if dataType == \"integer\" else missingValueFloat if dataType in [\"integer\", \"float\"] else missingValueString\n missingValue = missingValue if not useCifUnknowns else \".\" if isMandatory else \"?\"\n for row in self.data:\n try:\n row[ii] = self.__castD[dataType](row[ii]) if row[ii] is not None and row[ii] not in [\".\", \"?\"] else missingValue\n except Exception as e:\n if not ignoreCastErrors:\n logger.error(\"Cast error %s %s (%s) %r %r\", self.getName(), atName, dataType, row[ii], str(e))\n row[ii] = missingValue\n #\n logger.debug(\"%s %s %r\", self.getName(), atName, [row[ii] for row in self.data])\n self.__attributeTypeD[atName] = dataType\n ok = True\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n if self._raiseExceptions:\n raise e\n return ok\n\n def getAttributeInfo(self, atName):\n \"\"\"Get attribute data type (string, integer, or float) and optionality\n\n Args:\n atName (str): attribute name\n\n Returns:\n (string, bool): data type (string, integer or float) and mandatory code\n \"\"\"\n try:\n dataType, mandatoryCode = self.__getAttributeInfo(atName)\n return dataType, mandatoryCode\n except Exception:\n return None, None\n\n def applyStringTypes(self):\n \"\"\"Cast data types to strings in the current object. Missing values are set to '?' and '.' for\n optional and mandatory attributes, respectively.\n\n Raises:\n e: any exception\n\n Returns:\n bool: True for success or False otherwise\n \"\"\"\n ok = False\n try:\n for ii, atName in enumerate(self.getAttributeList()):\n _, isMandatory = self.__getAttributeInfo(atName)\n dataType = \"string\"\n for row in self.data:\n if row[ii] is None or row[ii] in [\".\", \"?\"]:\n row[ii] = \".\" if isMandatory else \"?\"\n else:\n row[ii] = self.__castD[dataType](row[ii])\n #\n self.__attributeTypeD[atName] = dataType\n ok = True\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n if self._raiseExceptions:\n raise e\n return ok\n\n def cmpAttributeValues(self, dcObj, ignoreOrder=True, **kwargs):\n \"\"\"Compare the values by attribute for current typed data category (dca) and input data category.\n The comparison is performed for values of the attributes common to both objects. Length differences\n are treated inequality out of hand.\n\n Args:\n dcObj (object): DataCategory object\n ignoreOrder (bool, optional): ignore attribute order. Defaults to True.\n floatRelTolerance (float, optional): relative tolerance for float comparisons. Defaults to 1e-05.\n floatAbsTolerance (float, optional): absolute tolerance for float comparisons. Defaults to 1e-04.\n\n Raises:\n e: any exception\n\n Returns:\n list: [(attributeName, values equal/close flag (bool)), (attributeName, values equal/close flag (bool), ...]\n\n \"\"\"\n rL = []\n floatRelTolerance = kwargs.get(\"floatRelTolerance\", 1.0e-05)\n floatAbsTolerance = kwargs.get(\"floatAbsTolerance\", 1.0e-04)\n try:\n sa = set(self.getAttributeList())\n sb = set(dcObj.getAttributeList())\n atNameComList = list(sa & sb)\n #\n lenEq = self.getRowCount() == dcObj.getRowCount()\n if not lenEq:\n return [(atName, False) for atName in atNameComList]\n #\n for atName in atNameComList:\n dataType, _ = self.__getAttributeInfo(atName)\n if dataType in [\"string\", \"integer\"]:\n if ignoreOrder:\n same = sorted(self.getAttributeValueList(atName)) == sorted(dcObj.getAttributeValueList(atName))\n else:\n same = self.getAttributeValueList(atName) == dcObj.getAttributeValueList(atName)\n elif dataType in [\"float\"]:\n aVL = self.getAttributeValueList(atName)\n bVL = dcObj.getAttributeValueList(atName)\n if ignoreOrder:\n for aV, bV in zip(sorted(aVL), sorted(bVL)):\n same = self.__isClose(aV, bV, relTol=floatRelTolerance, absTol=floatAbsTolerance)\n if not same:\n break\n else:\n for aV, bV in zip(aVL, bVL):\n same = self.__isClose(aV, bV, relTol=floatRelTolerance, absTol=floatAbsTolerance)\n if not same:\n logger.info(\"%s %s (rel=%r) (abs=%r) %r (%r)\", self.getName(), atName, aV * floatRelTolerance, floatAbsTolerance, aV, abs(aV - bV))\n break\n rL.append((atName, same))\n #\n return rL\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return rL\n\n def __getAttributeInfo(self, atName):\n \"\"\"Get attribute data type (string, integer, or float) and optionality\n\n Args:\n atName (str): attribute name\n\n Returns:\n (string, bool): data type (string, integer or float) and mandatory code\n \"\"\"\n logger.debug(\"Working on cat %r, atName %r\", self.getName(), atName)\n cifDataType = self.__dApi.getTypeCode(self.getName(), atName)\n cifPrimitiveType = self.__dApi.getTypePrimitive(self.getName(), atName)\n isMandatory = self.__dApi.getMandatoryCode(self.getName(), atName) in [\"yes\", \"implicit\", \"implicit-ordinal\"]\n dataType = \"string\" if cifDataType is None else \"integer\" if \"int\" in cifDataType else \"float\" if cifPrimitiveType == \"numb\" else \"string\"\n return dataType, isMandatory\n\n def __isClose(self, aV, bV, relTol=1e-09, absTol=1e-06):\n if aV is None and bV is None:\n return True\n elif aV is not None and bV is not None and aV == bV:\n return True\n elif isinstance(aV, (float)) and isinstance(bV, (float)):\n return abs(aV - bV) <= max(relTol * max(abs(aV), abs(bV)), absTol)\n else:\n raise ValueError\n
"},{"location":"api_reference/DataCategoryTyped/#mmcif.api.DataCategoryTyped.DataCategoryTyped.__init__","title":"__init__(self, dataCategoryObj, dictionaryApi=None, raiseExceptions=True, copyInputData=True, ignoreCastErrors=False, useCifUnknowns=True, missingValueString=None, missingValueInteger=None, missingValueFloat=None)
special
","text":"A subclass of DataCategory with methods to apply explicit data typing.
Parameters:
Name Type Description Default dataCategoryObj
object
DataCategory object instance
required dictionaryApi
object
instance of DictionaryApi class. Defaults to None.
None
raiseExceptions
bool
raise exceptions. Defaults to True.
True
copyInputData
bool
make a new copy input data. Defaults to True.
True
ignoreCastErrors
bool
ignore data processing cast errors. Defaults to False.
False
useCifUnknowns
bool
use CIF style missing values ('.' and '?'). Defaults to True.
True
missingValueString
str
missing string value . Defaults to None.
None
missingValueInteger
integer
missing integer value. Defaults to None.
None
missingValueFloat
float
missing float value. Defaults to None.
None
Source code in mmcif/api/DataCategoryTyped.py
def __init__(\n self,\n dataCategoryObj,\n dictionaryApi=None,\n raiseExceptions=True,\n copyInputData=True,\n ignoreCastErrors=False,\n useCifUnknowns=True,\n missingValueString=None,\n missingValueInteger=None,\n missingValueFloat=None,\n):\n \"\"\"A subclass of DataCategory with methods to apply explicit data typing.\n\n Args:\n dataCategoryObj (object): DataCategory object instance\n dictionaryApi (object, optional): instance of DictionaryApi class. Defaults to None.\n raiseExceptions (bool, optional): raise exceptions. Defaults to True.\n copyInputData (bool, optional): make a new copy input data. Defaults to True.\n ignoreCastErrors (bool, optional): ignore data processing cast errors. Defaults to False.\n useCifUnknowns (bool, optional): use CIF style missing values ('.' and '?'). Defaults to True.\n missingValueString (str, optional): missing string value . Defaults to None.\n missingValueInteger (integer, optional): missing integer value. Defaults to None.\n missingValueFloat (float, optional): missing float value. Defaults to None.\n \"\"\"\n self.__dcObj = dataCategoryObj\n super(DataCategoryTyped, self).__init__(\n self.__dcObj.getName(),\n self.__dcObj.getAttributeList(),\n self.__dcObj.data,\n raiseExceptions=raiseExceptions,\n copyInputData=copyInputData,\n )\n #\n self.__dApi = dictionaryApi\n self.__attributeTypeD = {}\n self.__castD = {\"integer\": int, \"float\": float, \"string\": str}\n self.__typesSet = self.applyTypes(\n ignoreCastErrors=ignoreCastErrors,\n useCifUnknowns=useCifUnknowns,\n missingValueString=missingValueString,\n missingValueInteger=missingValueInteger,\n missingValueFloat=missingValueFloat,\n )\n
"},{"location":"api_reference/DataCategoryTyped/#mmcif.api.DataCategoryTyped.DataCategoryTyped.applyStringTypes","title":"applyStringTypes(self)
","text":"Cast data types to strings in the current object. Missing values are set to '?' and '.' for optional and mandatory attributes, respectively.
Exceptions:
Type Description e
any exception
Returns:
Type Description bool
True for success or False otherwise
Source code in mmcif/api/DataCategoryTyped.py
def applyStringTypes(self):\n \"\"\"Cast data types to strings in the current object. Missing values are set to '?' and '.' for\n optional and mandatory attributes, respectively.\n\n Raises:\n e: any exception\n\n Returns:\n bool: True for success or False otherwise\n \"\"\"\n ok = False\n try:\n for ii, atName in enumerate(self.getAttributeList()):\n _, isMandatory = self.__getAttributeInfo(atName)\n dataType = \"string\"\n for row in self.data:\n if row[ii] is None or row[ii] in [\".\", \"?\"]:\n row[ii] = \".\" if isMandatory else \"?\"\n else:\n row[ii] = self.__castD[dataType](row[ii])\n #\n self.__attributeTypeD[atName] = dataType\n ok = True\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n if self._raiseExceptions:\n raise e\n return ok\n
"},{"location":"api_reference/DataCategoryTyped/#mmcif.api.DataCategoryTyped.DataCategoryTyped.applyTypes","title":"applyTypes(self, ignoreCastErrors=False, useCifUnknowns=True, missingValueString=None, missingValueInteger=None, missingValueFloat=None)
","text":"Cast data types (string, integer, float) in the current object based on dictionary type details. Missing values ('.' or '?') are set to None.
Exceptions:
Type Description e
any exception
Returns:
Type Description bool
True for success or False otherwise
Source code in mmcif/api/DataCategoryTyped.py
def applyTypes(self, ignoreCastErrors=False, useCifUnknowns=True, missingValueString=None, missingValueInteger=None, missingValueFloat=None):\n \"\"\"Cast data types (string, integer, float) in the current object based on dictionary type details.\n Missing values ('.' or '?') are set to None.\n\n Raises:\n e: any exception\n\n Returns:\n bool: True for success or False otherwise\n \"\"\"\n ok = False\n try:\n for ii, atName in enumerate(self.getAttributeList()):\n # colValL = self.getColumn(ii)\n dataType, isMandatory = self.__getAttributeInfo(atName)\n missingValue = missingValueInteger if dataType == \"integer\" else missingValueFloat if dataType in [\"integer\", \"float\"] else missingValueString\n missingValue = missingValue if not useCifUnknowns else \".\" if isMandatory else \"?\"\n for row in self.data:\n try:\n row[ii] = self.__castD[dataType](row[ii]) if row[ii] is not None and row[ii] not in [\".\", \"?\"] else missingValue\n except Exception as e:\n if not ignoreCastErrors:\n logger.error(\"Cast error %s %s (%s) %r %r\", self.getName(), atName, dataType, row[ii], str(e))\n row[ii] = missingValue\n #\n logger.debug(\"%s %s %r\", self.getName(), atName, [row[ii] for row in self.data])\n self.__attributeTypeD[atName] = dataType\n ok = True\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n if self._raiseExceptions:\n raise e\n return ok\n
"},{"location":"api_reference/DataCategoryTyped/#mmcif.api.DataCategoryTyped.DataCategoryTyped.cmpAttributeValues","title":"cmpAttributeValues(self, dcObj, ignoreOrder=True, **kwargs)
","text":"Compare the values by attribute for current typed data category (dca) and input data category. The comparison is performed for values of the attributes common to both objects. Length differences are treated inequality out of hand.
Parameters:
Name Type Description Default dcObj
object
DataCategory object
required ignoreOrder
bool
ignore attribute order. Defaults to True.
True
floatRelTolerance
float
relative tolerance for float comparisons. Defaults to 1e-05.
required floatAbsTolerance
float
absolute tolerance for float comparisons. Defaults to 1e-04.
required Exceptions:
Type Description e
any exception
Returns:
Type Description list
[(attributeName, values equal/close flag (bool)), (attributeName, values equal/close flag (bool), ...]
Source code in mmcif/api/DataCategoryTyped.py
def cmpAttributeValues(self, dcObj, ignoreOrder=True, **kwargs):\n \"\"\"Compare the values by attribute for current typed data category (dca) and input data category.\n The comparison is performed for values of the attributes common to both objects. Length differences\n are treated inequality out of hand.\n\n Args:\n dcObj (object): DataCategory object\n ignoreOrder (bool, optional): ignore attribute order. Defaults to True.\n floatRelTolerance (float, optional): relative tolerance for float comparisons. Defaults to 1e-05.\n floatAbsTolerance (float, optional): absolute tolerance for float comparisons. Defaults to 1e-04.\n\n Raises:\n e: any exception\n\n Returns:\n list: [(attributeName, values equal/close flag (bool)), (attributeName, values equal/close flag (bool), ...]\n\n \"\"\"\n rL = []\n floatRelTolerance = kwargs.get(\"floatRelTolerance\", 1.0e-05)\n floatAbsTolerance = kwargs.get(\"floatAbsTolerance\", 1.0e-04)\n try:\n sa = set(self.getAttributeList())\n sb = set(dcObj.getAttributeList())\n atNameComList = list(sa & sb)\n #\n lenEq = self.getRowCount() == dcObj.getRowCount()\n if not lenEq:\n return [(atName, False) for atName in atNameComList]\n #\n for atName in atNameComList:\n dataType, _ = self.__getAttributeInfo(atName)\n if dataType in [\"string\", \"integer\"]:\n if ignoreOrder:\n same = sorted(self.getAttributeValueList(atName)) == sorted(dcObj.getAttributeValueList(atName))\n else:\n same = self.getAttributeValueList(atName) == dcObj.getAttributeValueList(atName)\n elif dataType in [\"float\"]:\n aVL = self.getAttributeValueList(atName)\n bVL = dcObj.getAttributeValueList(atName)\n if ignoreOrder:\n for aV, bV in zip(sorted(aVL), sorted(bVL)):\n same = self.__isClose(aV, bV, relTol=floatRelTolerance, absTol=floatAbsTolerance)\n if not same:\n break\n else:\n for aV, bV in zip(aVL, bVL):\n same = self.__isClose(aV, bV, relTol=floatRelTolerance, absTol=floatAbsTolerance)\n if not same:\n logger.info(\"%s %s (rel=%r) (abs=%r) %r (%r)\", self.getName(), atName, aV * floatRelTolerance, floatAbsTolerance, aV, abs(aV - bV))\n break\n rL.append((atName, same))\n #\n return rL\n except Exception as e:\n if self._raiseExceptions:\n raise e\n return rL\n
"},{"location":"api_reference/DataCategoryTyped/#mmcif.api.DataCategoryTyped.DataCategoryTyped.getAttributeInfo","title":"getAttributeInfo(self, atName)
","text":"Get attribute data type (string, integer, or float) and optionality
Parameters:
Name Type Description Default atName
str
attribute name
required Returns:
Type Description (string, bool)
data type (string, integer or float) and mandatory code
Source code in mmcif/api/DataCategoryTyped.py
def getAttributeInfo(self, atName):\n \"\"\"Get attribute data type (string, integer, or float) and optionality\n\n Args:\n atName (str): attribute name\n\n Returns:\n (string, bool): data type (string, integer or float) and mandatory code\n \"\"\"\n try:\n dataType, mandatoryCode = self.__getAttributeInfo(atName)\n return dataType, mandatoryCode\n except Exception:\n return None, None\n
"},{"location":"api_reference/DictMethodRunner/","title":"DictMethodRunner","text":"Manage the invocation of dictionary methods implemented as class methods.
Source code in mmcif/api/DictMethodRunner.py
class DictMethodRunner(object):\n \"\"\"Manage the invocation of dictionary methods implemented as class methods.\"\"\"\n\n def __init__(self, dictionaryApi, modulePathMap=None, **kwargs):\n \"\"\"Manage invocation of dictionary methods referenced in external modules.\n\n Arguments:\n dictionaryApi {object} -- instance of DictionaryApi() for dictionary with target method definitions\n\n Keyword Arguments:\n modulePathMap {dict str} -- mapping between dictionary module path and execution path (default: {None})\n cacheModuleFlag {bool} -- flag to cache module instances (defaullt: True)\n implentationSource {str} -- method implementation (default: 'reference')\n methodCodes (list str) -- filter methods by codes {default: ['calculation']}\n \"\"\"\n self.__dApi = dictionaryApi\n self.__modulePathMap = modulePathMap if modulePathMap else {}\n self.__cacheModuleFlag = kwargs.get(\"cacheModuleFlag\", True)\n methodCodes = kwargs.get(\"methodCodes\", [\"calculation\"])\n implementationSource = kwargs.get(\"implementationCodes\", \"reference\")\n #\n self.__kwargs = kwargs\n #\n # Preserve and reuse the module instances if caching is enabled\n self.__moduleCache = {}\n #\n self.__methodD = self.__getMethodInfo(implementationSource=implementationSource, methodCodes=methodCodes)\n logger.debug(\"Method index %r\", self.__methodD.items())\n\n def __getMethodInfo(self, implementationSource=\"reference\", methodCodes=None):\n \"\"\"Get method implementation with the input implementation source.\"\"\"\n catName = atName = mId = mType = methDef = None\n methodCodes = methodCodes if methodCodes else [\"calculation\"]\n methodD = {}\n try:\n methodIndex = self.__dApi.getMethodIndex()\n for _, mrL in methodIndex.items():\n for mr in mrL:\n mId = mr.getId()\n catName = mr.getCategoryName()\n atName = mr.getAttributeName()\n mType = mr.getType()\n if (catName, atName) not in methodD:\n methodD[(catName, atName)] = []\n methDef = self.__dApi.getMethod(mId)\n logger.debug(\"Category %s attribute %s mId %r type %r methDef %r\", catName, atName, mId, mType, methDef)\n mSource = methDef.getImplementationSource()\n mCode = methDef.getCode()\n if mSource == implementationSource and mCode in methodCodes:\n mPriority = methDef.getPriority()\n mLang = methDef.getLanguage()\n mImplement = methDef.getImplementation()\n dD = {\"METHOD_LANGUAGE\": mLang, \"METHOD_IMPLEMENT\": mImplement, \"METHOD_TYPE\": mType, \"METHOD_CODE\": mCode, \"METHOD_PRIORITY\": mPriority}\n methodD[(catName, atName)].append(dD)\n #\n except Exception as e:\n logger.exception(\"Failing for category %r attribute %r mId %r type %r methDef %r with %s\", catName, atName, mId, mType, methDef, str(e))\n\n ##\n logger.debug(\"Method dictionary %r\", methodD)\n return methodD\n\n def __invokeAttributeMethod(self, methodPath, dataContainer, catName, atName, **kwargs):\n \"\"\"Invoke the input attribute method\"\"\"\n ok = False\n try:\n modulePath, methodName = self.__methodPathSplit(methodPath)\n mObj = self.__getModuleInstance(modulePath, **kwargs)\n theMeth = getattr(mObj, methodName, None)\n ok = theMeth(dataContainer, catName, atName, **kwargs)\n except Exception as e:\n logger.exception(\"Failed invoking attribute %s %s method %r with %s\", catName, atName, methodPath, str(e))\n return ok\n\n def __invokeCategoryMethod(self, methodPath, dataContainer, catName, **kwargs):\n \"\"\"Invoke the input category method\"\"\"\n ok = False\n try:\n modulePath, methodName = self.__methodPathSplit(methodPath)\n mObj = self.__getModuleInstance(modulePath, **kwargs)\n theMeth = getattr(mObj, methodName, None)\n ok = theMeth(dataContainer, catName, **kwargs)\n except Exception as e:\n logger.exception(\"Failed invoking category %s method %r with %s\", catName, methodPath, str(e))\n return ok\n\n def __invokeDatablockMethod(self, methodPath, dataContainer, blockName, **kwargs):\n \"\"\"Invoke the input data block method\"\"\"\n ok = False\n try:\n modulePath, methodName = self.__methodPathSplit(methodPath)\n mObj = self.__getModuleInstance(modulePath, **kwargs)\n theMeth = getattr(mObj, methodName, None)\n ok = theMeth(dataContainer, blockName, **kwargs)\n except Exception as e:\n logger.exception(\"Failed invoking block %s method %r with %s\", blockName, methodPath, str(e))\n return ok\n\n def apply(self, dataContainer):\n \"\"\"Apply category, attribute and block level dictionary methods on the input data container.\"\"\"\n kwargs = self.__kwargs\n mTupL = self.__getCategoryMethods()\n logger.debug(\"Category methods %r\", mTupL)\n for catName, _, methodPath, _ in mTupL:\n self.__invokeCategoryMethod(methodPath, dataContainer, catName, **kwargs)\n\n mTupL = self.__getAttributeMethods()\n logger.debug(\"Attribute methods %r\", mTupL)\n for catName, atName, methodPath, _ in mTupL:\n self.__invokeAttributeMethod(methodPath, dataContainer, catName, atName, **kwargs)\n\n mTupL = self.__getDatablockMethods()\n logger.debug(\"Datablock methods %r\", mTupL)\n for _, _, methodPath, _ in mTupL:\n self.__invokeDatablockMethod(methodPath, dataContainer, dataContainer.getName(), **kwargs)\n\n return True\n\n def __getDatablockMethods(self):\n mL = []\n try:\n for (dictName, _), mDL in self.__methodD.items():\n for mD in mDL:\n if mD[\"METHOD_TYPE\"].lower() == \"datablock\":\n methodPath = mD[\"METHOD_IMPLEMENT\"]\n mL.append((dictName, None, methodPath, mD[\"METHOD_PRIORITY\"]))\n mL = sorted(mL, key=itemgetter(3))\n return mL\n except Exception as e:\n logger.exception(\"Failing dictName %s with %s\", dictName, str(e))\n return mL\n\n def __getCategoryMethods(self):\n mL = []\n try:\n for (catName, _), mDL in self.__methodD.items():\n for mD in mDL:\n if mD[\"METHOD_TYPE\"].lower() == \"category\":\n methodPath = mD[\"METHOD_IMPLEMENT\"]\n mL.append((catName, None, methodPath, mD[\"METHOD_PRIORITY\"]))\n mL = sorted(mL, key=itemgetter(3))\n return mL\n except Exception as e:\n logger.exception(\"Failing catName %r with %s\", catName, str(e))\n return mL\n\n def __getAttributeMethods(self):\n mL = []\n try:\n for (catName, atName), mDL in self.__methodD.items():\n for mD in mDL:\n if mD[\"METHOD_TYPE\"].lower() == \"attribute\":\n methodPath = mD[\"METHOD_IMPLEMENT\"]\n mL.append((catName, atName, methodPath, mD[\"METHOD_PRIORITY\"]))\n mL = sorted(mL, key=itemgetter(3))\n return mL\n except Exception as e:\n logger.exception(\"Failing catName %s atName %s with %s\", catName, atName, str(e))\n return mL\n\n def __methodPathSplit(self, methodPath):\n \"\"\"Extract module path and the method name from the input path. Optional\n remap the module path.\n\n Arguments:\n methodPath {str} -- implementation path from dictionary method definition\n\n Returns:\n {tuple str} -- module path, method name\n \"\"\"\n try:\n # Strip off any leading path of the module from the method path.\n mpL = str(methodPath).split(\".\")\n methodName = mpL[-1]\n tp = \".\".join(mpL[:-1])\n modulePath = self.__modulePathMap[tp] if tp in self.__modulePathMap else tp\n return modulePath, methodName\n except Exception as e:\n logger.error(\"Failing for method path %r with %s\", methodPath, str(e))\n return None, None\n\n def __getModuleInstance(self, modulePath, **kwargs):\n #\n if self.__cacheModuleFlag and modulePath in self.__moduleCache:\n return self.__moduleCache[modulePath]\n #\n mObj = None\n try:\n aMod = __import__(modulePath, globals(), locals(), [\"\"])\n sys.modules[modulePath] = aMod\n #\n # Strip off any leading path to the module before we instaniate the module object.\n mpL = str(modulePath).split(\".\")\n moduleName = mpL[-1]\n #\n # Add the internal dictionaryApi object instance as a kw option\n #\n kwargs[\"dictionaryApi\"] = self.__dApi\n mObj = getattr(aMod, moduleName)(**kwargs)\n self.__moduleCache[modulePath] = mObj\n\n except Exception as e:\n logger.error(\"Failing to instance helper %r with %s\", modulePath, str(e))\n return mObj\n
"},{"location":"api_reference/DictMethodRunner/#mmcif.api.DictMethodRunner.DictMethodRunner.__init__","title":"__init__(self, dictionaryApi, modulePathMap=None, **kwargs)
special
","text":"Manage invocation of dictionary methods referenced in external modules.
Keyword arguments:
Name Type Description modulePathMap
{dict str} -- mapping between dictionary module path and execution path (default
{None})
cacheModuleFlag
{bool} -- flag to cache module instances (defaullt
True)
implentationSource
{str} -- method implementation (default
'reference')
methodCodes
list str) -- filter methods by codes {default
['calculation']}
Source code in mmcif/api/DictMethodRunner.py
def __init__(self, dictionaryApi, modulePathMap=None, **kwargs):\n \"\"\"Manage invocation of dictionary methods referenced in external modules.\n\n Arguments:\n dictionaryApi {object} -- instance of DictionaryApi() for dictionary with target method definitions\n\n Keyword Arguments:\n modulePathMap {dict str} -- mapping between dictionary module path and execution path (default: {None})\n cacheModuleFlag {bool} -- flag to cache module instances (defaullt: True)\n implentationSource {str} -- method implementation (default: 'reference')\n methodCodes (list str) -- filter methods by codes {default: ['calculation']}\n \"\"\"\n self.__dApi = dictionaryApi\n self.__modulePathMap = modulePathMap if modulePathMap else {}\n self.__cacheModuleFlag = kwargs.get(\"cacheModuleFlag\", True)\n methodCodes = kwargs.get(\"methodCodes\", [\"calculation\"])\n implementationSource = kwargs.get(\"implementationCodes\", \"reference\")\n #\n self.__kwargs = kwargs\n #\n # Preserve and reuse the module instances if caching is enabled\n self.__moduleCache = {}\n #\n self.__methodD = self.__getMethodInfo(implementationSource=implementationSource, methodCodes=methodCodes)\n logger.debug(\"Method index %r\", self.__methodD.items())\n
"},{"location":"api_reference/DictMethodRunner/#mmcif.api.DictMethodRunner.DictMethodRunner.apply","title":"apply(self, dataContainer)
","text":"Apply category, attribute and block level dictionary methods on the input data container.
Source code in mmcif/api/DictMethodRunner.py
def apply(self, dataContainer):\n \"\"\"Apply category, attribute and block level dictionary methods on the input data container.\"\"\"\n kwargs = self.__kwargs\n mTupL = self.__getCategoryMethods()\n logger.debug(\"Category methods %r\", mTupL)\n for catName, _, methodPath, _ in mTupL:\n self.__invokeCategoryMethod(methodPath, dataContainer, catName, **kwargs)\n\n mTupL = self.__getAttributeMethods()\n logger.debug(\"Attribute methods %r\", mTupL)\n for catName, atName, methodPath, _ in mTupL:\n self.__invokeAttributeMethod(methodPath, dataContainer, catName, atName, **kwargs)\n\n mTupL = self.__getDatablockMethods()\n logger.debug(\"Datablock methods %r\", mTupL)\n for _, _, methodPath, _ in mTupL:\n self.__invokeDatablockMethod(methodPath, dataContainer, dataContainer.getName(), **kwargs)\n\n return True\n
"},{"location":"api_reference/DictionaryApi/","title":"DictionaryApi","text":"Source code in mmcif/api/DictionaryApi.py
class DictionaryApi(object):\n def __init__(self, containerList, consolidate=True, expandItemLinked=False, replaceDefinition=False, **kwargs):\n \"\"\"Return an instance of the mmCIF dictionary API.\n\n Args:\n containerList (list): list of definition or data containers holding dictionary content\n consolidate (bool, optional): consolidate dictionary attributes within a single definition. Defaults to True.\n expandItemLinked (bool, optional): distribute item and item linked attributes defined for the parent\n to child definitions. Defaults to False.\n replaceDefinition (bool, optional): when consolidating definitions in the case of multiple occurences of the same definition,\n attributes from the latter occurences replace prior definitions content. Defaults to False.\n \"\"\"\n _ = kwargs\n #\n self.__containerList = containerList\n self.__replaceDefinition = replaceDefinition\n #\n if consolidate:\n self.__consolidateDefinitions()\n #\n if expandItemLinked:\n self.__expandLoopedDefinitions()\n\n self.__fullIndex = OrderedDict()\n\n # ---\n #\n # Map category name to the unique list of attributes\n self.__catNameIndex = OrderedDict()\n # Map category name to the unique list of item names\n self.__catNameItemIndex = OrderedDict()\n # Full unique list of item names -\n self.__itemNameList = []\n #\n # Map dictionary objects names to definition containers -\n self.__definitionIndex = OrderedDict()\n #\n # data section/objects of the dictionary by category name -\n self.__dataIndex = OrderedDict()\n #\n # Map of types id->(regex,primitive_type)\n self.__typesDict = OrderedDict()\n #\n self.__enumD = {\n \"ENUMERATION_VALUE\": (\"item_enumeration\", \"value\"),\n \"ENUMERATION_DETAIL\": (\"item_enumeration\", \"detail\"),\n \"ENUMERATION_TYPE_UNITS\": (\"item_enumeration\", \"rcsb_type_units_code\"),\n \"ENUMERATION_DETAIL_BRIEF\": (\"item_enumeration\", \"rcsb_detail_brief\"),\n \"ENUMERATION_TUPLE\": (\"item_enumeration\", None),\n \"ITEM_LINKED_PARENT\": (\"item_linked\", \"parent_name\"),\n \"ITEM_LINKED_CHILD\": (\"item_linked\", \"child_name\"),\n \"DATA_TYPE_CODE\": (\"item_type\", \"code\"),\n \"DATA_TYPE_REGEX\": (\"item_type_list\", \"construct\"),\n \"DATA_TYPE_PRIMITIVE\": (\"item_type_list\", \"primitive_code\"),\n \"ITEM_NAME\": (\"item\", \"name\"),\n \"ITEM_CATEGORY_ID\": (\"item\", \"category_id\"),\n \"ITEM_MANDATORY_CODE\": (\"item\", \"mandatory_code\"),\n \"ITEM_DESCRIPTION\": (\"item_description\", \"description\"),\n \"ITEM_UNITS\": (\"item_units\", \"code\"),\n \"ITEM_DEFAULT_VALUE\": (\"item_default\", \"value\"),\n \"ITEM_EXAMPLE_CASE\": (\"item_examples\", \"case\"),\n \"ITEM_EXAMPLE_DETAIL\": (\"item_examples\", \"detail\"),\n \"ITEM_RANGE_MAXIMUM\": (\"item_range\", \"maximum\"),\n \"ITEM_RANGE_MINIMUM\": (\"item_range\", \"minimum\"),\n \"CATEGORY_KEY_ITEMS\": (\"category_key\", \"name\"),\n \"CATEGORY_EXAMPLE_CASE\": (\"category_examples\", \"case\"),\n \"CATEGORY_EXAMPLE_DETAIL\": (\"category_examples\", \"detail\"),\n \"CATEGORY_MANDATORY_CODE\": (\"category\", \"mandatory_code\"),\n \"CATEGORY_DESCRIPTION\": (\"category\", \"description\"),\n \"CATEGORY_NX_MAPPING_DETAILS\": (\"category\", \"NX_mapping_details\"),\n #\n \"DATA_TYPE_CODE_NDB\": (\"ndb_item_type\", \"code\"),\n \"ITEM_DESCRIPTION_NDB\": (\"ndb_item_description\", \"description\"),\n \"ENUMERATION_VALUE_NDB\": (\"ndb_item_enumeration\", \"value\"),\n \"ENUMERATION_DETAIL_NDB\": (\"ndb_item_enumeration\", \"detail\"),\n \"ITEM_MANDATORY_CODE_NDB\": (\"ndb_item\", \"mandatory_code\"),\n \"ITEM_EXAMPLE_CASE_NDB\": (\"ndb_item_examples\", \"case\"),\n \"ITEM_EXAMPLE_DETAIL_NDB\": (\"ndb_item_examples\", \"detail\"),\n \"ITEM_RANGE_MAXIMUM_NDB\": (\"ndb_item_range\", \"maximum\"),\n \"ITEM_RANGE_MINIMUM_NDB\": (\"ndb_item_range\", \"minimum\"),\n \"CATEGORY_EXAMPLE_CASE_NDB\": (\"ndb_category_examples\", \"case\"),\n \"CATEGORY_EXAMPLE_DETAIL_NDB\": (\"ndb_category_examples\", \"detail\"),\n \"CATEGORY_DESCRIPTION_NDB\": (\"ndb_category_description\", \"description\"),\n #\n \"DATA_TYPE_CODE_PDBX\": (\"pdbx_item_type\", \"code\"),\n \"ITEM_DESCRIPTION_PDBX\": (\"pdbx_item_description\", \"description\"),\n \"ENUMERATION_VALUE_PDBX\": (\"pdbx_item_enumeration\", \"value\"),\n \"ENUMERATION_DETAIL_PDBX\": (\"pdbx_item_enumeration\", \"detail\"),\n \"ENUMERATION_TYPE_UNITS_PDBX\": (\"pdbx_item_enumeration\", \"type_units_code\"),\n \"ENUMERATION_DETAIL_BRIEF_PDBX\": (\"pdbx_item_enumeration\", \"detail_brief\"),\n \"ITEM_MANDATORY_CODE_PDBX\": (\"pdbx_item\", \"mandatory_code\"),\n \"ITEM_EXAMPLE_CASE_PDBX\": (\"pdbx_item_examples\", \"case\"),\n \"ITEM_EXAMPLE_DETAIL_PDBX\": (\"pdbx_item_examples\", \"detail\"),\n \"ITEM_RANGE_MAXIMUM_PDBX\": (\"pdbx_item_range\", \"maximum\"),\n \"ITEM_RANGE_MINIMUM_PDBX\": (\"pdbx_item_range\", \"minimum\"),\n \"CATEGORY_EXAMPLE_CASE_PDBX\": (\"pdbx_category_examples\", \"case\"),\n \"CATEGORY_EXAMPLE_DETAIL_PDBX\": (\"pdbx_category_examples\", \"detail\"),\n \"CATEGORY_DESCRIPTION_PDBX\": (\"pdbx_category_description\", \"description\"),\n #\n \"CATEGORY_CONTEXT\": (\"pdbx_category_context\", \"type\"),\n \"CATEGORY_GROUP\": (\"category_group\", \"id\"),\n \"ITEM_CONTEXT\": (\"pdbx_item_context\", \"type\"),\n \"ENUMERATION_CLOSED_FLAG\": (\"pdbx_item_enumeration_details\", \"closed_flag\"),\n #\n \"ITEM_RELATED_FUNCTION_CODE\": (\"item_related\", \"function_code\"),\n \"ITEM_RELATED_RELATED_NAME\": (\"item_related\", \"related_name\"),\n \"ITEM_ALIAS_ALIAS_NAME\": (\"item_aliases\", \"alias_name\"),\n \"ITEM_ALIAS_DICTIONARY\": (\"item_aliases\", \"dictionary\"),\n \"ITEM_ALIAS_VERSION\": (\"item_aliases\", \"version\"),\n \"ITEM_DEPENDENT_DEPENDENT_NAME\": (\"item_dependent\", \"dependent_name\"),\n \"ITEM_SUB_CATEGORY_ID\": (\"item_sub_category\", \"id\"),\n \"ITEM_SUB_CATEGORY_LABEL\": (\"item_sub_category\", \"pdbx_label\"),\n \"ITEM_TYPE_CONDITIONS_CODE\": (\"item_type_conditions\", \"code\"),\n #\n \"ITEM_VALUE_CONDITION_DEPENDENT_NAME\": (\"pdbx_item_value_condition\", \"dependent_item_name\"),\n #\n \"ITEM_LINKED_PDBX_ID\": (\"pdbx_item_linked\", \"id\"),\n \"ITEM_LINKED_PDBX_CONDITION_ID\": (\"pdbx_item_linked\", \"condition_id\"),\n \"ITEM_LINKED_PDBX_PARENT_NAME\": (\"pdbx_item_linked\", \"parent_name\"),\n \"ITEM_LINKED_PDBX_CHILD_NAME\": (\"pdbx_item_linked\", \"child_name\"),\n #\n \"ITEM_LINKED_PDBX_CONDITION_CHILD_NAME\": (\"pdbx_item_linked\", \"condition_child_name\"),\n \"ITEM_LINKED_PDBX_CONDITION_CHILD_VALUE\": (\"pdbx_item_linked\", \"condition_child_value\"),\n \"ITEM_LINKED_PDBX_CONDITION_CHILD_TARGET_NAME\": (\"pdbx_item_linked\", \"condition_child_target_name\"),\n \"ITEM_LINKED_PDBX_CONDITION_CHILD_CMP_OP\": (\"pdbx_item_linked\", \"condition_child_cmp_op\"),\n \"ITEM_LINKED_PDBX_CONDITION_LOG_OP\": (\"pdbx_item_linked\", \"condition_log_op\"),\n }\n #\n self.__methodDict = OrderedDict()\n self.__methodIndex = OrderedDict()\n #\n self.__makeIndex()\n self.__getMethods()\n #\n self.__fullParentD, self.__fullChildD = self.__makeFullParentChildDictionaries()\n #\n #\n self.__dataBlockDictList = []\n self.__dictionaryDictList = []\n #\n self.__subCategoryDict = OrderedDict()\n self.__categoryGroupDict = OrderedDict()\n self.__groupIndex = False\n self.__groupChildIndex = OrderedDict()\n #\n # Data sections -\n #\n self.__dictionaryHistoryList = []\n self.__itemUnitsDict = OrderedDict()\n self.__itemUnitsConversionList = []\n self.__itemLinkedGroupDict = OrderedDict()\n self.__itemLinkedGroupItemDict = OrderedDict()\n #\n self.__dictionaryIncludeDict = OrderedDict()\n self.__categoryIncludeDict = OrderedDict()\n self.__itemIncludeDict = OrderedDict()\n #\n self.__dictionaryComponentList = []\n self.__dictionaryComponentHistoryDict = OrderedDict()\n #\n self.__itemValueConditionDict = OrderedDict()\n self.__compOpDict = OrderedDict()\n #\n self.__getDataSections()\n #\n\n def testCache(self):\n return len(self.__containerList) > 0\n\n #\n # Methods for data sections --\n #\n\n def getItemValueConditionDict(self):\n try:\n return self.__itemValueConditionDict if self.__itemValueConditionDict else {}\n except Exception:\n return {}\n\n def getComparisonOperators(self):\n try:\n return list(self.__compOpDict.keys()) if self.__compOpDict else []\n except Exception:\n return []\n\n def getComparisonOperatorDict(self):\n try:\n return self.__compOpDict if self.__compOpDict else {}\n except Exception:\n return {}\n\n #\n def getDictionaryVersion(self):\n try:\n return \",\".join([str(tD[\"version\"]) for tD in self.__dictionaryDictList])\n except Exception:\n return None\n\n def getDictionaryTitle(self):\n try:\n return \",\".join([str(tD[\"title\"]) for tD in self.__dictionaryDictList])\n except Exception:\n return None\n\n def getDictionaryUpdate(self, order=\"reverse\"):\n \"\"\"Get details from the first/last history element.\"\"\"\n try:\n if order == \"reverse\":\n tD = self.__dictionaryHistoryList[-1]\n else:\n tD = self.__dictionaryHistoryList[0]\n\n return tD[\"update\"]\n\n except Exception:\n return None\n\n def getDictionaryRevisionCount(self):\n \"\"\"Get the count of revision history records.\"\"\"\n try:\n return len(self.__dictionaryHistoryList)\n except Exception:\n return 0\n\n def getDictionaryHistory(self, order=\"reverse\"):\n \"\"\"Returns the revision history as a list of tuples [(version,update,revisionText,dictionary),...]\"\"\"\n oL = []\n try:\n if order == \"reverse\":\n for tD in reversed(self.__dictionaryHistoryList):\n oL.append((tD[\"version\"], tD[\"update\"], tD[\"revision\"], tD[\"dictionary\"]))\n else:\n for tD in self.__dictionaryHistoryList:\n oL.append((tD[\"version\"], tD[\"update\"], tD[\"revision\"], tD[\"dictionary\"]))\n except Exception:\n pass\n return oL\n\n #\n def getDictionaryComponentDetails(self):\n \"\"\"Returns the component dictionary list as tuples [(version,title,dictionary_component_id),...]\"\"\"\n oL = []\n try:\n for tD in self.__dictionaryComponentList:\n oL.append((tD[\"version\"], tD[\"title\"], tD[\"dictionary_component_id\"]))\n except Exception:\n pass\n return oL\n\n def getDictionaryComponentCount(self):\n \"\"\"Get the count of dictionary components.\"\"\"\n try:\n return len(self.__dictionaryComponentList)\n except Exception:\n return 0\n\n def getDictionaryComponents(self):\n \"\"\"Get the list of dictionary components.\"\"\"\n try:\n return list(self.__dictionaryComponentHistoryDict.keys())\n except Exception:\n return []\n\n def getDictionaryComponentHistory(self, dictionaryComponentId, order=\"reverse\"):\n \"\"\"Returns the revision history as a list of tuples [(version,update,revisionText,dictionary),...]\"\"\"\n oL = []\n try:\n if order == \"reverse\":\n for tD in reversed(self.__dictionaryComponentHistoryDict[dictionaryComponentId]):\n oL.append((tD[\"version\"], tD[\"update\"], tD[\"revision\"], tD[\"dictionary_component_id\"]))\n else:\n for tD in self.__dictionaryComponentHistoryDict[dictionaryComponentId]:\n oL.append((tD[\"version\"], tD[\"update\"], tD[\"revision\"], tD[\"dictionary_component_id\"]))\n except Exception:\n pass\n return oL\n\n #\n def __makeCategoryGroupIndex(self):\n catNameList = self.getCategoryList()\n # add categories in group to self.__categoryGroupDict[<groupName>]['categories']\n for catName in catNameList:\n groupNameList = self.getCategoryGroupList(catName)\n # logger.info(\"Category %s group list %r\\n\" % (catName,groupNameList))\n for groupName in groupNameList:\n if groupName not in self.__categoryGroupDict:\n # handle undefined category group ?\n tD = OrderedDict()\n tD[\"description\"] = None\n tD[\"parent_id\"] = None\n tD[\"categories\"] = []\n self.__categoryGroupDict[groupName] = tD\n self.__categoryGroupDict[groupName][\"categories\"].append(catName)\n #\n for groupName in self.__categoryGroupDict:\n # logger.info(\"Group %s count %r\\n\" % (groupName, len(self.__categoryGroupDict[groupName]['categories'])))\n if \"categories\" in self.__categoryGroupDict[groupName]:\n self.__categoryGroupDict[groupName][\"categories\"].sort()\n self.__groupChildIndex = OrderedDict()\n for groupName, gD in self.__categoryGroupDict.items():\n if \"parent\" in gD:\n self.__groupChildIndex.setdefault(gD[\"parent\"], []).append(groupName)\n #\n self.__groupIndex = True\n\n #\n def getCategoryGroupDescription(self, groupName):\n try:\n return self.__categoryGroupDict[groupName][\"description\"]\n except Exception:\n return None\n\n def getCategoryGroupParent(self, groupName):\n try:\n return self.__categoryGroupDict[groupName][\"parent_id\"]\n except Exception:\n return None\n\n def getCategoryGroupChildGroups(self, parentGroupName):\n try:\n return self.__groupChildIndex[parentGroupName]\n except Exception:\n return []\n\n def getCategoryGroupCategories(self, groupName, followChildren=False):\n try:\n if not self.__groupIndex:\n self.__makeCategoryGroupIndex()\n #\n if followChildren:\n cL = []\n grpL = [groupName]\n grpL.extend(self.getCategoryGroupChildGroups(groupName))\n for grp in grpL:\n cL.extend(self.__categoryGroupDict[grp][\"categories\"] if grp in self.__categoryGroupDict else [])\n return sorted(set(cL))\n else:\n return self.__categoryGroupDict[groupName][\"categories\"] if groupName in self.__categoryGroupDict else []\n #\n except Exception:\n logger.exception(\"DictionaryApi.getCategoryGroupCategories failed for group %s\", groupName)\n return []\n\n def getCategoryGroups(self):\n try:\n kL = self.__categoryGroupDict.keys()\n return kL\n except Exception:\n return []\n\n #\n def getParentCategories(self, categoryName):\n itemNameList = self.getItemNameList(categoryName)\n parentCategories = set()\n for itemName in itemNameList:\n categoryName = CifName.categoryPart(itemName)\n attributeName = CifName.attributePart(itemName)\n parentItemList = self.getFullParentList(categoryName, attributeName)\n for parentItem in parentItemList:\n parentCategoryName = CifName.categoryPart(parentItem)\n parentCategories.add(parentCategoryName)\n return list(parentCategories)\n\n def getChildCategories(self, categoryName):\n itemNameList = self.getItemNameList(categoryName)\n childCategories = set()\n for itemName in itemNameList:\n categoryName = CifName.categoryPart(itemName)\n attributeName = CifName.attributePart(itemName)\n childItemList = self.getFullChildList(categoryName, attributeName)\n for childItem in childItemList:\n childCategoryName = CifName.categoryPart(childItem)\n childCategories.add(childCategoryName)\n return list(childCategories)\n\n #\n def definitionExists(self, definitionName):\n if definitionName in self.__definitionIndex:\n return True\n return False\n\n def getTypeConditionsCode(self, category, attribute):\n return self.__get(\"ITEM_TYPE_CONDITIONS_CODE\", category, attribute)\n\n def getItemDependentNameList(self, category, attribute):\n return self.__getList(\"ITEM_DEPENDENT_DEPENDENT_NAME\", category, attribute)\n\n def getItemValueConditionDependentList(self, category, attribute):\n return self.__getList(\"ITEM_VALUE_CONDITION_DEPENDENT_NAME\", category, attribute)\n\n def getItemSubCategoryIdList(self, category, attribute):\n return self.__getList(\"ITEM_SUB_CATEGORY_ID\", category, attribute)\n\n def getItemSubCategoryLabelList(self, category, attribute):\n return self.__getList(\"ITEM_SUB_CATEGORY_LABEL\", category, attribute)\n\n def getItemSubCategoryList(self, category, attribute):\n aL = []\n\n itemName = CifName.itemName(category, attribute)\n\n obL = self.__definitionIndex[itemName] if itemName in self.__definitionIndex else None\n for ob in obL:\n tObj = ob.getObj(self.__enumD[\"ITEM_SUB_CATEGORY_ID\"][0])\n if tObj is not None:\n atId = self.__enumD[\"ITEM_SUB_CATEGORY_ID\"][1]\n atLabel = self.__enumD[\"ITEM_SUB_CATEGORY_LABEL\"][1]\n for row in tObj.getRowList():\n # logger.info(\"subcategories for %s row is %r\" % (itemName, row))\n idVal = row[tObj.getIndex(atId)] if tObj.hasAttribute(atId) else None\n labVal = row[tObj.getIndex(atLabel)] if tObj.hasAttribute(atLabel) else None\n aL.append((idVal, labVal))\n return aL\n\n def getItemAliasList(self, category, attribute):\n aNL = self.__getListAll(\"ITEM_ALIAS_ALIAS_NAME\", category, attribute)\n aDL = self.__getListAll(\"ITEM_ALIAS_DICTIONARY\", category, attribute)\n aVL = self.__getListAll(\"ITEM_ALIAS_VERSION\", category, attribute)\n aL = []\n for aN, aD, aV in zip(aNL, aDL, aVL):\n aL.append((aN, aD, aV))\n return aL\n\n def getEnumListWithDetail(self, category, attribute):\n eVL = self.__getListAll(\"ENUMERATION_VALUE\", category, attribute)\n eDL = self.__getListAll(\"ENUMERATION_DETAIL\", category, attribute)\n rL = []\n dD = {}\n if len(eVL) == len(eDL):\n for eV, eD in zip(eVL, eDL):\n if not eD or eD in [\".\", \"?\"]:\n dD[eV] = (eV, None)\n else:\n dD[eV] = (eV, eD)\n else:\n for eV in eVL:\n dD[eV] = (eV, None)\n #\n for ky in sorted(dD.keys()):\n rL.append(dD[ky])\n return rL\n\n def getEnumListAltWithFullDetails(self, category, attribute):\n rL = []\n dD = {}\n try:\n eVL = self.__getListAll(\"ENUMERATION_VALUE_PDBX\", category, attribute)\n eDL = self.__getListAll(\"ENUMERATION_DETAIL_PDBX\", category, attribute)\n eBL = self.__getListAll(\"ENUMERATION_DETAIL_BRIEF_PDBX\", category, attribute)\n eUL = self.__getListAll(\"ENUMERATION_TYPE_UNITS_PDBX\", category, attribute)\n rL = []\n dD = {}\n for eV, eD, eB, eU in zip_longest(eVL, eDL, eBL, eUL):\n oL = [v if v and v not in [\".\", \"?\"] else None for v in [eV, eD, eB, eU]]\n dD[eV] = tuple(oL)\n for ky in sorted(dD.keys()):\n rL.append(dD[ky])\n if rL:\n return rL\n #\n eVL = self.__getListAll(\"ENUMERATION_VALUE\", category, attribute)\n eDL = self.__getListAll(\"ENUMERATION_DETAIL\", category, attribute)\n eBL = self.__getListAll(\"ENUMERATION_DETAIL_BRIEF\", category, attribute)\n eUL = self.__getListAll(\"ENUMERATION_TYPE_UNITS\", category, attribute)\n rL = []\n dD = {}\n for eV, eD, eB, eU in zip_longest(eVL, eDL, eBL, eUL):\n oL = [v if v and v not in [\".\", \"?\"] else None for v in [eV, eD, eB, eU]]\n dD[eV] = tuple(oL)\n for ky in sorted(dD.keys()):\n rL.append(dD[ky])\n except Exception as e:\n logger.exception(\"Failing dD %r rL %r with %s\", dD, rL, str(e))\n return rL\n\n def getEnumListWithFullDetails(self, category, attribute):\n rL = []\n dD = {}\n try:\n eVL = self.__getListAll(\"ENUMERATION_VALUE\", category, attribute)\n eDL = self.__getListAll(\"ENUMERATION_DETAIL\", category, attribute)\n eBL = self.__getListAll(\"ENUMERATION_DETAIL_BRIEF\", category, attribute)\n eUL = self.__getListAll(\"ENUMERATION_TYPE_UNITS\", category, attribute)\n #\n for eV, eD, eB, eU in zip_longest(eVL, eDL, eBL, eUL):\n oL = [v if v and v not in [\".\", \"?\"] else None for v in [eV, eD, eB, eU]]\n dD[eV] = tuple(oL)\n for ky in sorted(dD.keys()):\n rL.append(dD[ky])\n except Exception as e:\n logger.info(\"eVL %r\", eVL)\n logger.info(\"eDL %r\", eDL)\n logger.info(\"eBL %r\", eBL)\n logger.info(\"eUL %r\", eUL)\n logger.exception(\"Failing category %s attribute %s dD %r rL %r with %s\", category, attribute, dD, rL, str(e))\n return rL\n\n def getEnumListAltWithDetail(self, category, attribute):\n eVL = self.__getListAll(\"ENUMERATION_VALUE_PDBX\", category, attribute)\n eDL = self.__getListAll(\"ENUMERATION_DETAIL_PDBX\", category, attribute)\n\n rL = []\n dD = {}\n if len(eVL) == len(eDL):\n for eV, eD in zip(eVL, eDL):\n if not eD or eD in [\".\", \"?\"]:\n dD[eV] = (eV, None)\n else:\n dD[eV] = (eV, eD)\n else:\n for eV in eVL:\n dD[eV] = (eV, None)\n #\n for ky in sorted(dD.keys()):\n rL.append(dD[ky])\n #\n if not rL:\n return self.getEnumListWithDetail(category, attribute)\n else:\n return rL\n\n def getItemRelatedList(self, category, attribute):\n rNL = self.__getListAll(\"ITEM_RELATED_RELATED_NAME\", category, attribute)\n rFL = self.__getListAll(\"ITEM_RELATED_FUNCTION_CODE\", category, attribute)\n rL = []\n for rN, rF in zip(rNL, rFL):\n rL.append((rN, rF))\n return rL\n\n def getTypeCode(self, category, attribute):\n return self.__get(\"DATA_TYPE_CODE\", category, attribute, followAncestors=True)\n\n def getTypeCodeAlt(self, category, attribute, fallBack=True):\n v = self.getTypeCodePdbx(category, attribute)\n if v is None:\n v = self.getTypeCodeNdb(category, attribute)\n if fallBack and v is None:\n v = self.getTypeCode(category, attribute)\n return v\n\n def getTypeCodeNdb(self, category, attribute):\n return self.__get(\"DATA_TYPE_CODE_NDB\", category, attribute, followAncestors=False)\n\n def getTypeCodePdbx(self, category, attribute):\n return self.__get(\"DATA_TYPE_CODE_PDBX\", category, attribute, followAncestors=False)\n\n def getDefaultValue(self, category, attribute):\n return self.__get(\"ITEM_DEFAULT_VALUE\", category, attribute)\n\n def getMandatoryCode(self, category, attribute):\n return self.__get(\"ITEM_MANDATORY_CODE\", category, attribute)\n\n def getMandatoryCodeAlt(self, category, attribute, fallBack=True):\n v = self.getMandatoryCodePdbx(category, attribute)\n if v is None:\n v = self.getMandatoryCodeNdb(category, attribute)\n if fallBack and v is None:\n v = self.getMandatoryCode(category, attribute)\n return v\n\n def getMandatoryCodeNdb(self, category, attribute):\n return self.__get(\"ITEM_MANDATORY_CODE_NDB\", category, attribute)\n\n def getMandatoryCodePdbx(self, category, attribute):\n return self.__get(\"ITEM_MANDATORY_CODE_PDBX\", category, attribute)\n\n def getTypeRegex(self, category, attribute):\n code = self.getTypeCode(category, attribute)\n if code in self.__typesDict:\n return self.__typesDict[code][1]\n return None\n\n def getTypeRegexAlt(self, category, attribute, fallBack=True):\n v = self.getTypeRegexPdbx(category, attribute)\n if v is None:\n v = self.getTypeRegexNdb(category, attribute)\n if fallBack and v is None:\n v = self.getTypeRegex(category, attribute)\n return v\n\n def getTypeRegexNdb(self, category, attribute):\n code = self.getTypeCodeNdb(category, attribute)\n if code in self.__typesDict:\n return self.__typesDict[code][1]\n return None\n\n def getTypeRegexPdbx(self, category, attribute):\n code = self.getTypeCodePdbx(category, attribute)\n if code in self.__typesDict:\n return self.__typesDict[code][1]\n return None\n\n def getTypePrimitive(self, category, attribute):\n code = self.getTypeCode(category, attribute)\n if code in self.__typesDict:\n return self.__typesDict[code][0]\n return None\n\n def getTypeDetail(self, category, attribute):\n code = self.getTypeCode(category, attribute)\n if code in self.__typesDict:\n return self.__typesDict[code][2]\n return None\n\n def getContextList(self, category, attribute):\n return self.__getList(\"ITEM_CONTEXT\", category, attribute)\n\n def getCategoryContextList(self, category):\n return self.__getList(\"CATEGORY_CONTEXT\", category, attribute=None)\n\n def getEnumList(self, category, attribute, sortFlag=True):\n if sortFlag:\n return self.__getList(\"ENUMERATION_VALUE\", category, attribute)\n else:\n return self.__getListAll(\"ENUMERATION_VALUE\", category, attribute)\n\n def getEnumListAlt(self, category, attribute, fallBack=True, sortFlag=True):\n vL = self.getEnumListPdbx(category, attribute, sortFlag=sortFlag)\n if not vL:\n vL = self.getEnumListNdb(category, attribute, sortFlag=sortFlag)\n if fallBack and not vL:\n vL = self.getEnumList(category, attribute, sortFlag=sortFlag)\n return vL\n\n def getEnumListNdb(self, category, attribute, sortFlag=True):\n if sortFlag:\n return self.__getList(\"ENUMERATION_VALUE_NDB\", category, attribute)\n else:\n return self.__getListAll(\"ENUMERATION_VALUE_NDB\", category, attribute)\n\n def getEnumListPdbx(self, category, attribute, sortFlag=True):\n if sortFlag:\n return self.__getList(\"ENUMERATION_VALUE_PDBX\", category, attribute)\n else:\n return self.__getListAll(\"ENUMERATION_VALUE_PDBX\", category, attribute)\n\n def isEnumerated(self, category, attribute):\n return len(self.__getList(\"ENUMERATION_VALUE\", category, attribute)) > 0\n\n def isEnumeratedAlt(self, category, attribute, fallBack=True):\n eC = len(self.__getList(\"ENUMERATION_VALUE_PDBX\", category, attribute))\n if eC == 0:\n eC = len(self.__getList(\"ENUMERATION_VALUE_NDB\", category, attribute))\n if fallBack and (eC == 0):\n eC = len(self.__getList(\"ENUMERATION_VALUE\", category, attribute))\n return eC > 0\n\n def getEnumerationClosedFlag(self, category, attribute):\n return self.__get(\"ENUMERATION_CLOSED_FLAG\", category, attribute)\n\n def getUltimateParent(self, category, attribute):\n \"\"\"Return the first ultimate parent item for the input item.\"\"\"\n # pL=self.__getList('ITEM_LINKED_PARENT',category,attribute)\n pL = self.getFullParentList(category, attribute)\n itemName = CifName.itemName(category, attribute)\n while pL and (pL[0] != itemName):\n attN = CifName.attributePart(pL[0])\n catN = CifName.categoryPart(pL[0])\n itemName = pL[0]\n pL = self.getFullParentList(catN, attN)\n # pL=self.__getList('ITEM_LINKED_PARENT',catN,attN)\n return itemName\n\n def getParentList(self, category, attribute, stripSelfParent=False):\n if stripSelfParent:\n itemName = CifName.itemName(category, attribute)\n pL = self.__getList(\"ITEM_LINKED_PARENT\", category, attribute)\n if pL:\n try:\n pL.remove(itemName)\n except Exception:\n pass\n return pL\n else:\n return self.__getList(\"ITEM_LINKED_PARENT\", category, attribute)\n\n def getChildList(self, category, attribute):\n return self.__getList(\"ITEM_LINKED_CHILD\", category, attribute)\n\n def getFullChildList(self, category, attribute):\n try:\n itemName = CifName.itemName(category, attribute)\n return self.__fullChildD[itemName]\n except Exception:\n return []\n\n def getFullDescendentList(self, category, attribute):\n itemNameL = []\n try:\n itemName = CifName.itemName(category, attribute)\n itemNameL = self.__fullChildD[itemName] if itemName in self.__fullChildD else []\n itemNameL = list(set(itemNameL))\n if itemNameL:\n begLen = 0\n endLen = 1\n #\n while endLen > begLen:\n begLen = len(itemNameL)\n for itemName in itemNameL:\n if itemName in self.__fullChildD:\n itemNameL.extend(self.__fullChildD[itemName])\n itemNameL = list(set(itemNameL))\n endLen = len(itemNameL)\n\n except Exception as e:\n logger.exception(\"Failing for %s %s with %s\", category, attribute, str(e))\n return itemNameL\n\n def getFullParentList(self, category, attribute, stripSelfParent=False):\n try:\n itemName = CifName.itemName(category, attribute)\n pL = self.__fullParentD[itemName]\n if stripSelfParent:\n if pL:\n try:\n pL.remove(itemName)\n except Exception:\n pass\n return pL\n else:\n return pL\n except Exception:\n return []\n\n def getUnits(self, category, attribute):\n return self.__get(\"ITEM_UNITS\", category, attribute)\n\n def getImplicitList(self):\n iL = []\n for name, dL in self.__definitionIndex.items():\n for dD in dL:\n dType = dD.getType()\n if dType == \"definition\" and dD.isAttribute():\n catN = CifName.categoryPart(name)\n attN = CifName.attributePart(name)\n if self.__get(\"ITEM_MANDATORY_CODE\", catN, attN) == \"implicit\":\n if name not in iL:\n iL.append(name)\n return iL\n\n def getDescription(self, category, attribute):\n return self.__get(\"ITEM_DESCRIPTION\", category, attribute)\n\n def getDescriptionAlt(self, category, attribute, fallBack=True):\n v = self.getDescriptionPdbx(category, attribute)\n if v is None:\n v = self.getDescriptionNdb(category, attribute)\n if fallBack and v is None:\n v = self.getDescription(category, attribute)\n return v\n\n def getDescriptionNdb(self, category, attribute):\n return self.__get(\"ITEM_DESCRIPTION_NDB\", category, attribute)\n\n def getDescriptionPdbx(self, category, attribute):\n return self.__get(\"ITEM_DESCRIPTION_PDBX\", category, attribute)\n\n def getExampleList(self, category, attribute):\n exCL = self.__getListAll(\"ITEM_EXAMPLE_CASE\", category, attribute)\n exDL = self.__getListAll(\"ITEM_EXAMPLE_DETAIL\", category, attribute)\n exL = []\n if len(exCL) == len(exDL):\n for exC, exD in zip(exCL, exDL):\n exL.append((exC, exD))\n else:\n for exC in exCL:\n exL.append((exC, None))\n return exL\n\n def getExampleListAlt(self, category, attribute, fallBack=True):\n vL = self.getExampleListPdbx(category, attribute)\n if not vL:\n vL = self.getExampleListNdb(category, attribute)\n if fallBack and not vL:\n vL = self.getExampleList(category, attribute)\n return vL\n\n def getExampleListNdb(self, category, attribute):\n exCL = self.__getListAll(\"ITEM_EXAMPLE_CASE_NDB\", category, attribute)\n exDL = self.__getListAll(\"ITEM_EXAMPLE_DETAIL_NDB\", category, attribute)\n exL = []\n if len(exCL) == len(exDL):\n for exC, exD in zip(exCL, exDL):\n exL.append((exC, exD))\n else:\n for exC in exCL:\n exL.append((exC, None))\n return exL\n\n def getExampleListPdbx(self, category, attribute):\n exCL = self.__getListAll(\"ITEM_EXAMPLE_CASE_PDBX\", category, attribute)\n exDL = self.__getListAll(\"ITEM_EXAMPLE_DETAIL_PDBX\", category, attribute)\n exL = []\n if len(exCL) == len(exDL):\n for exC, exD in zip(exCL, exDL):\n exL.append((exC, exD))\n else:\n for exC in exCL:\n exL.append((exC, None))\n return exL\n\n def getBoundaryList(self, category, attribute):\n minL = self.__getListAll(\"ITEM_RANGE_MINIMUM\", category, attribute)\n maxL = self.__getListAll(\"ITEM_RANGE_MAXIMUM\", category, attribute)\n bL = []\n for vMin, vMax in zip(minL, maxL):\n bL.append((vMin, vMax))\n return bL\n\n def getBoundaryListAlt(self, category, attribute, fallBack=True):\n vL = self.getBoundaryListPdbx(category, attribute)\n if not vL:\n vL = self.getBoundaryListNdb(category, attribute)\n if fallBack and not vL:\n vL = self.getBoundaryList(category, attribute)\n return vL\n\n def getBoundaryListNdb(self, category, attribute):\n minL = self.__getListAll(\"ITEM_RANGE_MINIMUM_NDB\", category, attribute)\n maxL = self.__getListAll(\"ITEM_RANGE_MAXIMUM_NDB\", category, attribute)\n bL = []\n for vMin, vMax in zip(minL, maxL):\n bL.append((vMin, vMax))\n #\n return bL\n\n def getBoundaryListPdbx(self, category, attribute):\n minL = self.__getListAll(\"ITEM_RANGE_MINIMUM_PDBX\", category, attribute)\n maxL = self.__getListAll(\"ITEM_RANGE_MAXIMUM_PDBX\", category, attribute)\n bL = []\n for vMin, vMax in zip(minL, maxL):\n bL.append((vMin, vMax))\n #\n return bL\n\n def getCategoryKeyList(self, category):\n return self.__getList(\"CATEGORY_KEY_ITEMS\", category, attribute=None)\n\n def getCategoryGroupList(self, category):\n return self.__getList(\"CATEGORY_GROUP\", category, attribute=None)\n\n def getCategoryMandatoryCode(self, category):\n return self.__get(\"CATEGORY_MANDATORY_CODE\", category, attribute=None)\n\n def getCategoryDescription(self, category):\n return self.__get(\"CATEGORY_DESCRIPTION\", category, attribute=None)\n\n def getCategoryNxMappingDetails(self, category):\n return self.__get(\"CATEGORY_NX_MAPPING_DETAILS\", category, attribute=None)\n\n def getCategoryDescriptionAlt(self, category, fallBack=True):\n v = self.getCategoryDescriptionPdbx(category)\n if v is None:\n v = self.getCategoryDescriptionNdb(category)\n if fallBack and v is None:\n v = self.getCategoryDescription(category)\n return v\n\n def getCategoryDescriptionNdb(self, category):\n val = self.__get(\"CATEGORY_DESCRIPTION_NDB\", category, attribute=None)\n return val\n\n def getCategoryDescriptionPdbx(self, category):\n val = self.__get(\"CATEGORY_DESCRIPTION_PDBX\", category, attribute=None)\n return val\n\n def getCategoryExampleList(self, category):\n exCL = self.__getListAll(\"CATEGORY_EXAMPLE_CASE\", category, attribute=None)\n exDL = self.__getListAll(\"CATEGORY_EXAMPLE_DETAIL\", category, attribute=None)\n exL = []\n if len(exCL) == len(exDL):\n for exC, exD in zip(exCL, exDL):\n exL.append((exC, exD))\n else:\n for exC in exCL:\n exL.append((exC, None))\n return exL\n\n def getCategoryExampleListAlt(self, category, fallBack=True):\n vL = self.getCategoryExampleListPdbx(category)\n if not vL:\n vL = self.getCategoryExampleListNdb(category)\n if fallBack and not vL:\n vL = self.getCategoryExampleList(category)\n return vL\n\n def getCategoryExampleListNdb(self, category):\n exCL = self.__getListAll(\"CATEGORY_EXAMPLE_CASE_NDB\", category, attribute=None)\n exDL = self.__getListAll(\"CATEGORY_EXAMPLE_DETAIL_NDB\", category, attribute=None)\n exL = []\n if len(exCL) == len(exDL):\n for exC, exD in zip(exCL, exDL):\n exL.append((exC, exD))\n else:\n for exC in exCL:\n exL.append((exC, None))\n return exL\n\n def getCategoryExampleListPdbx(self, category):\n exCL = self.__getListAll(\"CATEGORY_EXAMPLE_CASE_PDBX\", category, attribute=None)\n exDL = self.__getListAll(\"CATEGORY_EXAMPLE_DETAIL_PDBX\", category, attribute=None)\n exL = []\n if len(exCL) == len(exDL):\n for exC, exD in zip(exCL, exDL):\n exL.append((exC, exD))\n else:\n for exC in exCL:\n exL.append((exC, None))\n\n return exL\n\n def getParentDictionary(self):\n \"\"\"Create a dictionary of parents relations accross all definnitions\n as {child : [parent, parent,...]\n\n Exclude self parents.\n \"\"\"\n parentD = {}\n pAtN = self.__enumD[\"ITEM_LINKED_PARENT\"][1]\n cAtN = self.__enumD[\"ITEM_LINKED_CHILD\"][1]\n\n for dObj in self.__containerList:\n dc = dObj.getObj(self.__enumD[\"ITEM_LINKED_PARENT\"][0])\n if dc is not None:\n idxP = dc.getIndex(pAtN)\n idxC = dc.getIndex(cAtN)\n for row in dc.getRowList():\n pVal = row[idxP]\n cVal = row[idxC]\n if pVal == cVal:\n continue\n if cVal not in parentD:\n parentD[cVal] = []\n parentD[cVal].append(pVal)\n #\n return parentD\n\n def getItemLinkedConditions(self):\n \"\"\"Create a dictionary of conditional item link relationships.\n\n Returns:\n (dict): {{parent_name, child_name}: [{\"id\": , \"condition_id\": , \"condition_child_name\": , \"condition_child_value\": ,\n \"condition_child_cmp_op\": , \"condition_log_op\": ,}, {},...]}\n\n Example:\n ```text\n loop_\n _pdbx_item_linked.id\n _pdbx_item_linked.condition_id\n _pdbx_item_linked.parent_name\n _pdbx_item_linked.child_name\n #\n _pdbx_item_linked.condition_child_name\n _pdbx_item_linked.condition_child_value\n _pdbx_item_linked.condition_child_cmp_op\n _pdbx_item_linked.condition_child_target_name\n _pdbx_item_linked.condition_child_log_op\n 1 1 '_entity_poly_seq.num' '_atom_site.label_seq_id' '_atom_site.label_entity_id' . 'eq' '_entity.id' .\n 2 1 '_entity_poly_seq.num' '_atom_site.label_seq_id' '_entity.type' 'polymer' 'eq' . 'and'\n ```\n\n \"\"\"\n rD = OrderedDict()\n try:\n for ob in self.__containerList:\n if ob.getType() == \"data\":\n continue\n tl = ob.getObj(self.__enumD[\"ITEM_LINKED_PDBX_ID\"][0])\n if tl is not None:\n for row in tl.getRowList():\n if (\n tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_ID\"][1])\n and tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_ID\"][1])\n and tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CHILD_NAME\"][1])\n and tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_PARENT_NAME\"][1])\n ):\n tD = OrderedDict()\n tD[\"id\"] = row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_ID\"][1])]\n tD[\"condition_id\"] = row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_ID\"][1])]\n parentName = row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_PARENT_NAME\"][1])]\n childName = row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CHILD_NAME\"][1])]\n #\n tD[\"condition_child_name\"] = (\n row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_NAME\"][1])]\n if tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_NAME\"][1])\n else None\n )\n tD[\"condition_child_value\"] = (\n row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_VALUE\"][1])]\n if tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_VALUE\"][1])\n else None\n )\n tD[\"condition_child_cmp_op\"] = (\n row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_CMP_OP\"][1])]\n if tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_CMP_OP\"][1])\n else None\n )\n tD[\"condition_child_target_name\"] = (\n row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_TARGET_NAME\"][1])]\n if tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_TARGET_NAME\"][1])\n else None\n )\n tD[\"condition_log_op\"] = (\n 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\n )\n #\n rD.setdefault((parentName, childName), []).append(tD)\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n\n return rD\n\n def __makeFullParentChildDictionaries(self):\n \"\"\"Create a dictionaries of full parent/child relations accross all definnitions\n\n as fullParentD[child]=[parent,parent,...]\n and fullChildD[parent]=[child,child,...]\n\n Exclude self parents.\n \"\"\"\n fullParentD = {}\n fullChildD = {}\n pAtN = self.__enumD[\"ITEM_LINKED_PARENT\"][1]\n cAtN = self.__enumD[\"ITEM_LINKED_CHILD\"][1]\n\n for dObj in self.__containerList:\n # logger.info(\"\\n\\nSearching object %s\\n\" % dObj.getName())\n dc = dObj.getObj(self.__enumD[\"ITEM_LINKED_PARENT\"][0])\n if dc is not None:\n idxP = dc.getIndex(pAtN)\n idxC = dc.getIndex(cAtN)\n for row in dc.getRowList():\n pVal = row[idxP]\n cVal = row[idxC]\n # logger.info(\"%s found parent %s child %s \\n\" % (dObj.getName(),pVal,cVal))\n if pVal == cVal:\n continue\n if cVal not in fullParentD:\n fullParentD[cVal] = []\n fullParentD[cVal].append(pVal)\n #\n if pVal not in fullChildD:\n fullChildD[pVal] = []\n fullChildD[pVal].append(cVal)\n\n #\n return fullParentD, fullChildD\n\n #\n def __get(self, enumCode, category, attribute=None, followAncestors=False):\n \"\"\"Return the last occurrence of the input dictionary metadata. If the value\n for the input category/attribute is null/missing then optionally check for\n an ancestor value.\n \"\"\"\n v0 = self.__getValue(enumCode, category, attribute)\n if not followAncestors:\n return v0\n else:\n if (v0 is None) or (not v0) or (v0 in [\".\", \"?\"]):\n pItem = self.getUltimateParent(category, attribute)\n if (pItem is not None) and pItem and (pItem != CifName.itemName(category, attribute)):\n logger.debug(\"Reassigning enum code %s category %s attribute %s to parent %r\", enumCode, category, attribute, pItem)\n return self.__getValue(enumCode, CifName.categoryPart(pItem), CifName.attributePart(pItem))\n return v0\n\n #\n def __getValue(self, enumCode, category, attribute=None):\n \"\"\"Returns the last occurrence of the input dictionary metadata (enumCode) for the input category/attribute\n encountered in the list of objects stored at the indicated definition index.\n\n \"\"\"\n eS = None\n if enumCode not in self.__enumD:\n return eS\n\n if attribute is not None:\n nm = \"_\" + category + \".\" + attribute\n else:\n nm = category\n\n if nm in self.__definitionIndex:\n dObjL = self.__definitionIndex[nm]\n for dObj in dObjL:\n dc = dObj.getObj(self.__enumD[enumCode][0])\n if dc is not None:\n atN = self.__enumD[enumCode][1]\n rL = dc.getRowList()\n if rL:\n row = rL[0]\n if atN is not None:\n if dc.hasAttribute(atN):\n eS = row[dc.getIndex(atN)]\n else:\n eS = [rv for rv in row]\n return eS\n\n def __getList(self, enumCode, category, attribute=None):\n \"\"\"Return the list of unique values\"\"\"\n return list(set(self.__getListAll(enumCode, category, attribute)))\n\n def __getListAll(self, enumCode, category, attribute=None):\n \"\"\"Return a list of all values\"\"\"\n eL = []\n if enumCode not in self.__enumD:\n return eL\n\n if attribute is not None:\n nm = \"_\" + category + \".\" + attribute\n else:\n nm = category\n\n if nm in self.__definitionIndex:\n dObjL = self.__definitionIndex[nm]\n for dObj in dObjL:\n dc = dObj.getObj(self.__enumD[enumCode][0])\n if dc is not None:\n atN = self.__enumD[enumCode][1]\n for row in dc.getRowList():\n if atN is not None:\n if dc.hasAttribute(atN):\n eL.append(row[dc.getIndex(atN)])\n else:\n eL = [rv for rv in row]\n\n return eL\n\n def getMethodIndex(self):\n return self.__methodIndex\n\n def __makeIndex(self):\n \"\"\"Create indices of definitions, categories and items.\"\"\"\n iD = OrderedDict()\n for dD in self.__containerList:\n name = dD.getName()\n dType = dD.getType()\n #\n if name not in self.__fullIndex:\n self.__fullIndex[name] = []\n self.__fullIndex[name].append(dD)\n #\n if dType == \"definition\" and dD.isCategory():\n if name not in self.__catNameIndex:\n self.__catNameIndex[name] = []\n if name not in self.__catNameItemIndex:\n self.__catNameItemIndex[name] = []\n if name not in self.__definitionIndex:\n self.__definitionIndex[name] = []\n self.__definitionIndex[name].append(dD)\n\n elif dType == \"definition\" and dD.isAttribute():\n catN = CifName.categoryPart(name)\n attN = CifName.attributePart(name)\n if catN not in self.__catNameItemIndex:\n self.__catNameItemIndex[catN] = []\n if name not in self.__catNameItemIndex:\n self.__catNameItemIndex[catN].append(name)\n\n if catN not in self.__catNameIndex:\n self.__catNameIndex[catN] = []\n if attN not in self.__catNameIndex[catN]:\n self.__catNameIndex[catN].append(attN)\n if name not in self.__definitionIndex:\n self.__definitionIndex[name] = []\n self.__definitionIndex[name].append(dD)\n iD[name] = name\n elif dType == \"data\":\n for nm in dD.getObjNameList():\n if nm not in self.__dataIndex:\n self.__dataIndex[nm] = dD.getObj(nm)\n else:\n pass\n #\n self.__itemNameList = list(iD.keys())\n\n def getDefinitionIndex(self):\n return self.__definitionIndex\n\n def getFullIndex(self):\n return self.__fullIndex\n\n def getMethod(self, mId):\n if mId in self.__methodDict:\n return self.__methodDict[mId]\n else:\n return None\n\n def getCategoryList(self):\n return list(self.__catNameIndex.keys())\n\n def getCategoryIndex(self):\n return self.__catNameIndex\n\n def getAttributeNameList(self, category):\n try:\n return self.__catNameIndex[category]\n except Exception:\n pass\n return []\n\n def getItemNameList(self, category):\n try:\n return self.__catNameItemIndex[category]\n except Exception:\n pass\n return []\n\n def getSubCategoryDescription(self, subCategoryName):\n if subCategoryName in self.__subCategoryDict:\n return self.__subCategoryDict[subCategoryName]\n else:\n return \"\"\n\n def __getMethods(self):\n self.__methodDict = OrderedDict()\n self.__methodIndex = OrderedDict()\n for ob in self.__containerList:\n if ob.getType() == \"data\":\n ml = ob.getObj(\"method_list\")\n if ml is not None:\n # Use row order as priority\n for ii, row in enumerate(ml.getRowList(), 1):\n if ml.hasAttribute(\"id\") and ml.hasAttribute(\"code\") and ml.hasAttribute(\"language\") and ml.hasAttribute(\"implementation_source\"):\n tInline = row[ml.getIndex(\"inline\")] if ml.hasAttribute(\"inline\") else None\n tImpl = row[ml.getIndex(\"implementation\")] if ml.hasAttribute(\"implementation\") else None\n mth = MethodDefinition(\n row[ml.getIndex(\"id\")], row[ml.getIndex(\"code\")], row[ml.getIndex(\"language\")], tInline, ii, tImpl, row[ml.getIndex(\"implementation_source\")]\n )\n self.__methodDict[row[ml.getIndex(\"id\")]] = mth\n\n ml = ob.getObj(\"datablock_methods\")\n if ml is not None:\n for row in ml.getRowList():\n if ml.hasAttribute(\"method_id\"):\n # mth = MethodReference(row[ml.getIndex('method_id')], 'datablock', ob.getName(), None)\n mth = MethodReference(row[ml.getIndex(\"method_id\")], \"datablock\", None, None)\n if ob.getName() in self.__methodIndex:\n self.__methodIndex[ob.getName()].append(mth)\n else:\n self.__methodIndex[ob.getName()] = []\n self.__methodIndex[ob.getName()].append(mth)\n elif ob.getType() == \"definition\":\n mi = ob.getObj(\"category_methods\")\n if mi is not None:\n for row in mi.getRowList():\n if mi.hasAttribute(\"method_id\"):\n mth = MethodReference(row[mi.getIndex(\"method_id\")], \"category\", ob.getName(), None)\n if ob.getName() in self.__methodIndex:\n self.__methodIndex[ob.getName()].append(mth)\n else:\n self.__methodIndex[ob.getName()] = []\n self.__methodIndex[ob.getName()].append(mth)\n mi = ob.getObj(\"item_methods\")\n if mi is not None:\n for row in mi.getRowList():\n if mi.hasAttribute(\"method_id\"):\n mth = MethodReference(row[mi.getIndex(\"method_id\")], \"attribute\", CifName.categoryPart(ob.getName()), CifName.attributePart(ob.getName()))\n if ob.getName() in self.__methodIndex:\n self.__methodIndex[ob.getName()].append(mth)\n else:\n self.__methodIndex[ob.getName()] = []\n self.__methodIndex[ob.getName()].append(mth)\n else:\n pass\n return self.__methodIndex\n\n def dumpCategoryIndex(self, fh=sys.stdout):\n for k, vL in self.__catNameIndex.items():\n uvL = list(set(vL))\n fh.write(\"Category: %s has %d attributes\\n\" % (k, len(uvL)))\n for v in sorted(uvL):\n fh.write(\" Attribute: %s\\n\" % v)\n\n def dumpMethods(self, fh=sys.stdout):\n for k, vL in self.__methodIndex.items():\n fh.write(\"Method index key: %s length %d\\n\" % (k, len(vL)))\n for v in vL:\n v.printIt(fh)\n #\n fh.write(\"Inline method details\\n\")\n for k, vL in self.__methodIndex.items():\n fh.write(\"\\n------------------------------------\\n\")\n fh.write(\"Method index key: %s\\n\" % k)\n for v in vL:\n fh.write(\"Method ID: %r\\n\" % v.getId())\n if self.getMethod(v.getId()):\n fh.write(\"%r\" % v)\n # fh.write(\"Method text: %s\\n\" % self.getMethod(v.getId()).getInline())\n else:\n fh.write(\"Missing method for %r\" % v.getId())\n\n def dumpEnumFeatures(self, fh=sys.stdout):\n for k, vL in self.__catNameIndex.items():\n uvL = list(set(vL))\n for v in sorted(uvL):\n itL = self.getEnumList(k, v)\n if itL:\n fh.write(\"-----------------------------------------------\\n\")\n fh.write(\" Category : %s\\n\" % k)\n fh.write(\" Attribute: %s\\n\" % v)\n fh.write(\" Description: \\n%s\\n\" % self.getDescription(k, v))\n fh.write(\" Type: %s\\n\" % self.getTypeCode(k, v))\n fh.write(\" Primitive type: %s\\n\" % self.getTypePrimitive(k, v))\n fh.write(\" Regex type: %s\\n\" % self.getTypeRegex(k, v))\n fh.write(\" Enum list length %d\\n\" % len(itL))\n for it in itL:\n fh.write(\" Enum: %s\\n\" % it)\n\n def dumpFeatures(self, fh=sys.stdout):\n for k, vL in self.__catNameIndex.items():\n uvL = list(set(vL))\n fh.write(\"-----------------------------------------------\\n\")\n fh.write(\"Category: %s has %d attributes\\n\" % (k, len(uvL)))\n fh.write(\" Category description: %s\\n\" % self.getCategoryDescription(k))\n fh.write(\" Alt category description: %s\\n\" % self.getCategoryDescriptionAlt(k))\n\n fh.write(\" Category context: %s\\n\" % self.getCategoryContextList(k))\n\n ctL = self.getCategoryExampleList(k)\n if ctL:\n fh.write(\" Category example list length %d\\n\" % len(ctL))\n for ct1, ct2 in ctL:\n fh.write(\" Example case: %s\\n\" % ct1)\n fh.write(\" Example detail: %s\\n\" % ct2)\n\n ctL = self.getCategoryExampleListAlt(k)\n if ctL:\n fh.write(\" Alt category example list length %d\\n\" % len(ctL))\n for ct1, ct2 in ctL:\n fh.write(\" Alt example case: %s\\n\" % ct1)\n fh.write(\" Alt example detail: %s\\n\" % ct2)\n\n for v in sorted(uvL):\n fh.write(\" Attribute: %s\\n\" % v)\n fh.write(\" Description: %s\\n\" % self.getDescription(k, v))\n fh.write(\" Alt description: %s\\n\" % self.getDescriptionAlt(k, v))\n fh.write(\" Type: %s\\n\" % self.getTypeCode(k, v))\n fh.write(\" Alt Type: %s\\n\" % self.getTypeCodeAlt(k, v))\n fh.write(\" Primitive type: %s\\n\" % self.getTypePrimitive(k, v))\n fh.write(\" Regex type: %s\\n\" % self.getTypeRegex(k, v))\n fh.write(\" Context: %s\\n\" % self.getContextList(k, v))\n #\n fh.write(\" Type conditions: %s\\n\" % self.getTypeConditionsCode(k, v))\n fh.write(\" Subcategories: %s\\n\" % self.getItemSubCategoryIdList(k, v))\n #\n itL = self.getEnumList(k, v)\n if itL:\n fh.write(\" Enum list length %d\\n\" % len(itL))\n for it in itL:\n fh.write(\" Enum: %s\\n\" % it)\n\n itL = self.getParentList(k, v)\n if itL:\n fh.write(\" Parent list length %d\\n\" % len(itL))\n for it in itL:\n fh.write(\" Parent: %s\\n\" % it)\n itL = self.getChildList(k, v)\n if itL:\n fh.write(\" Child list length %d\\n\" % len(itL))\n for it in itL:\n fh.write(\" Child: %s\\n\" % it)\n\n itL = self.getExampleList(k, v)\n if itL:\n fh.write(\" Example list length %d\\n\" % len(itL))\n for it1, it2 in itL:\n fh.write(\" Example case: %s\\n\" % it1)\n fh.write(\" Example detail: %s\\n\" % it2)\n\n itL = self.getBoundaryList(k, v)\n if itL:\n fh.write(\" Boundary list length %d\\n\" % len(itL))\n for (it1, it2) in itL:\n fh.write(\" Boundary condition (min,max): (%s,%s)\\n\" % (it1, it2))\n\n itL = self.getEnumListAlt(k, v)\n if itL:\n fh.write(\" Alt enum list length %d\\n\" % len(itL))\n for it in itL:\n fh.write(\" Alt enum: %s\\n\" % it)\n\n itL = self.getExampleListAlt(k, v)\n if itL:\n fh.write(\" Alt example list length %d\\n\" % len(itL))\n for it1, it2 in itL:\n fh.write(\" Alt example case: %s\\n\" % it1)\n fh.write(\" Alt example detail: %s\\n\" % it2)\n\n itL = self.getBoundaryListAlt(k, v)\n if itL:\n fh.write(\" Alt boundary list length %d\\n\" % len(itL))\n for (it1, it2) in itL:\n fh.write(\" Alt boundary condition (min,max): (%s,%s)\\n\" % (it1, it2))\n\n itL = self.getItemRelatedList(k, v)\n if itL:\n fh.write(\" Related name list length %d\\n\" % len(itL))\n for (it1, it2) in itL:\n fh.write(\" Related item name %s function code %s\\n\" % (it1, it2))\n\n itL = self.getItemAliasList(k, v)\n if itL:\n fh.write(\" Alias name list length %d\\n\" % len(itL))\n for (it1, it2, it3) in itL:\n fh.write(\" Alias name %s dictionary %s version %s\\n\" % (it1, it2, it3))\n\n itL = self.getItemDependentNameList(k, v)\n if itL:\n fh.write(\" Dependent name list length %d\\n\" % len(itL))\n for it1 in itL:\n fh.write(\" Dependent item name %s\\n\" % it1)\n\n def dumpDataSections(self, fh=sys.stdout):\n fh.write(\"Datablock: %r\\n\" % list(self.__dataBlockDictList))\n fh.write(\"Dictionary: %r\\n\" % list(self.__dictionaryDictList))\n fh.write(\"Dictionary History: %r\\n\" % self.__dictionaryHistoryList)\n fh.write(\"Subcategories: %r\\n\" % list(self.__subCategoryDict.items()))\n fh.write(\"Category groups: %r\\n\" % list(self.__categoryGroupDict.items()))\n fh.write(\"Item units: %r\\n\" % list(self.__itemUnitsDict.items()))\n fh.write(\"Item units conversions: %r \\n\" % self.__itemUnitsConversionList)\n fh.write(\"Item linked groups: %r\\n\" % list(self.__itemLinkedGroupDict.items()))\n fh.write(\"Item linked group item list: %r\\n\" % list(self.__itemLinkedGroupItemDict.items()))\n\n def dumpItemLinkedGroups(self, fh=sys.stdout):\n for categoryId, lgList in self.__itemLinkedGroupDict.items():\n for lg in lgList:\n if (categoryId, lg[1]) in self.__itemLinkedGroupItemDict:\n fh.write(\" Category %s linked group %s:\\n\" % (categoryId, lg[1]))\n lgIList = self.__itemLinkedGroupItemDict[(categoryId, lg[1])]\n for lgI in lgIList:\n fh.write(\" group %s --- child item %s parent item %s\\n\" % (lg[1], lgI[0], lgI[1]))\n\n def __addItemLinkToDef(self, dObj, parentName, childName):\n \"\"\"Add the input link relationship to the input definition object.\"\"\"\n if dObj.exists(\"item_linked\"):\n # update in place --\n cObj = dObj.getObj(\"item_linked\")\n iFound = False\n idxP = cObj.getIndex(\"parent_name\")\n idxC = cObj.getIndex(\"child_name\")\n for row in cObj.getRowList():\n if parentName == row[idxP] and childName == row[idxC]:\n iFound = True\n break\n if not iFound:\n nRows = cObj.getRowCount()\n cObj.setValue(childName, \"child_name\", nRows)\n cObj.setValue(parentName, \"parent_name\", nRows)\n logger.debug(\"Appending item link in category %s\", dObj.getName())\n return True\n else:\n # create new category and append to input object\n cObj = DataCategory(\"item_linked\", attributeNameList=[\"child_name\", \"parent_name\"])\n cObj.append([childName, parentName])\n dObj.append(cObj)\n logger.debug(\"Created new item link in category %s\", dObj.getName())\n return True\n\n def __expandLoopedDefinitions(self):\n \"\"\"Handle definitions containing looped item and item_linked categories --\"\"\"\n fullIndex = OrderedDict()\n for dD in self.__containerList:\n name = dD.getName()\n if name not in fullIndex:\n fullIndex[name] = []\n fullIndex[name].append(dD)\n\n for name, dObjL in fullIndex.items():\n if dObjL:\n ob = dObjL[0]\n if (ob.getType() == \"definition\") and ob.exists(\"item_linked\"):\n cObj = ob.getObj(\"item_linked\")\n if cObj.getRowCount() > 0:\n idxP = cObj.getIndex(\"parent_name\")\n idxC = cObj.getIndex(\"child_name\")\n itemName = ob.getName()\n logger.debug(\"Current target item %s\", itemName)\n cObjNext = DataCategory(\"item_linked\", attributeNameList=[\"child_name\", \"parent_name\"])\n #\n # Distribute the data for each row --\n iChanges = 0\n for row in cObj.getRowList():\n #\n parentItemName = row[idxP]\n childItemName = row[idxC]\n if parentItemName == childItemName:\n continue\n if childItemName != itemName:\n iChanges += 1\n if childItemName in fullIndex:\n #\n # Add this p/c link to the child definition -\n #\n self.__addItemLinkToDef(fullIndex[childItemName][0], parentItemName, childItemName)\n else:\n # error missing child definition object.\n logger.warning(\"Missing child item %s\", childItemName)\n else:\n cObjNext.append([row[idxC], row[idxP]])\n if cObjNext.getRowCount() > 0:\n ob.replace(cObjNext)\n else:\n ob.remove(\"item_linked\")\n\n def __consolidateDefinitions(self):\n \"\"\"Consolidate definition attributes into a single save frame section per definition.\"\"\"\n fullIndex = OrderedDict()\n for dD in self.__containerList:\n name = dD.getName()\n fullIndex.setdefault(name, []).append(dD)\n\n # preserve the original order of sections -\n #\n nList = []\n for dObj in self.__containerList:\n nm = dObj.getName()\n if nm not in nList:\n nList.append(nm)\n #\n for name, dObjL in fullIndex.items():\n if len(dObjL) > 1:\n for dD in dObjL[1:]:\n xList = dD.getObjNameList()\n for nm in xList:\n if nm not in dObjL[0].getObjNameList():\n logger.debug(\"Adding %s to %s\", nm, name)\n catObj = dD.getObj(nm)\n dObjL[0].append(catObj)\n elif self.__replaceDefinition:\n logger.debug(\"Replacing dictionary %s in %s\", nm, name)\n catObj = dD.getObj(nm)\n dObjL[0].replace(catObj)\n\n # create a new list of consolidated objects in original list order\n dList = []\n for nm in nList:\n if nm in fullIndex:\n dl = fullIndex[nm]\n dList.append(dl[0])\n else:\n logger.info(\"+DictionaryApi().__consolidate() missing object name %s\", nm)\n # update lists\n self.__containerList = dList\n\n def getDataTypeList(self):\n \"\"\"Return list of tuples containing ('code','primitive_code','construct','detail' )\"\"\"\n rowList = []\n for code in sorted(self.__typesDict.keys()):\n tup = self.__typesDict[code]\n rowList.append((code, tup[0], tup[1], tup[2]))\n return rowList\n\n def getSubCategoryList(self):\n \"\"\"Return list of tuples containing ('id', 'description')\"\"\"\n rowList = []\n for tId in sorted(self.__subCategoryDict.keys()):\n description = self.__subCategoryDict[tId]\n rowList.append((tId, description))\n return rowList\n\n def getUnitsList(self):\n \"\"\"Return list of tuples containing ('id', 'description')\"\"\"\n rowList = []\n for tId in sorted(self.__itemUnitsDict.keys()):\n description = self.__itemUnitsDict[tId]\n rowList.append((tId, description))\n return rowList\n\n def getUnitsConversionList(self):\n \"\"\"Return list of tuples containing ('from_code','to_code','operator','factor')\"\"\"\n return self.__itemUnitsConversionList\n\n def __getDataSections(self):\n \"\"\" \"\"\"\n for ob in self.__containerList:\n\n if ob.getType() == \"data\":\n logger.debug(\"Adding data sections from container name %s type %s\", ob.getName(), ob.getType())\n # add detail to data type tuple\n tl = ob.getObj(\"item_type_list\")\n if tl is not None:\n for row in tl.getRowList():\n if tl.hasAttribute(\"code\") and tl.hasAttribute(\"primitive_code\") and tl.hasAttribute(\"construct\") and tl.hasAttribute(\"detail\"):\n self.__typesDict[row[tl.getIndex(\"code\")]] = (row[tl.getIndex(\"primitive_code\")], row[tl.getIndex(\"construct\")], row[tl.getIndex(\"detail\")])\n\n tl = ob.getObj(\"datablock\")\n if tl is not None:\n rL = tl.getRowList()\n if rL:\n if tl.hasAttribute(\"id\") and tl.hasAttribute(\"description\"):\n tD = OrderedDict()\n row = rL[0]\n tD[\"id\"] = row[tl.getIndex(\"id\")]\n tD[\"description\"] = row[tl.getIndex(\"description\")]\n self.__dataBlockDictList.append(tD)\n\n tl = ob.getObj(\"dictionary\")\n if tl is not None:\n rL = tl.getRowList()\n if rL:\n tD = OrderedDict()\n row = rL[0]\n if tl.hasAttribute(\"datablock_id\"):\n tD[\"datablock_id\"] = row[tl.getIndex(\"datablock_id\")]\n if tl.hasAttribute(\"title\"):\n tD[\"title\"] = row[tl.getIndex(\"title\")]\n if tl.hasAttribute(\"version\"):\n tD[\"version\"] = row[tl.getIndex(\"version\")]\n self.__dictionaryDictList.append(tD)\n tl = ob.getObj(\"dictionary_history\")\n if tl is not None:\n # history as a list of dictionaries -\n dName = ob.getName()\n for row in tl.getRowList():\n if tl.hasAttribute(\"version\") and tl.hasAttribute(\"revision\") and tl.hasAttribute(\"update\"):\n tD = OrderedDict()\n tD[\"version\"] = row[tl.getIndex(\"version\")]\n tD[\"revision\"] = row[tl.getIndex(\"revision\")]\n tD[\"update\"] = row[tl.getIndex(\"update\")]\n tD[\"dictionary\"] = dName\n self.__dictionaryHistoryList.append(tD)\n\n # JDW\n tl = ob.getObj(\"pdbx_include_dictionary\")\n if tl is not None:\n for row in tl.getRowList():\n tD = OrderedDict()\n if tl.hasAttribute(\"dictionary_id\"):\n tD[\"dictionary_id\"] = row[tl.getIndex(\"dictionary_id\")]\n if tl.hasAttribute(\"dictionary_locator\"):\n tD[\"dictionary_locator\"] = row[tl.getIndex(\"dictionary_locator\")]\n if tl.hasAttribute(\"include_mode\"):\n tD[\"include_mode\"] = row[tl.getIndex(\"include_mode\")]\n if tl.hasAttribute(\"dictionary_namespace\"):\n tD[\"dictionary_namespace_prefix\"] = row[tl.getIndex(\"dictionary_namespace_prefix\")]\n if tl.hasAttribute(\"dictionary_namespace_replace\"):\n tD[\"dictionary_namespace_prefix\"] = row[tl.getIndex(\"dictionary_namespace_prefix_replace\")]\n #\n self.__dictionaryIncludeDict[tD[\"dictionary_id\"]] = tD\n #\n tl = ob.getObj(\"pdbx_include_category\")\n if tl is not None:\n for row in tl.getRowList():\n tD = OrderedDict()\n if tl.hasAttribute(\"dictionary_id\"):\n tD[\"dictionary_id\"] = row[tl.getIndex(\"dictionary_id\")]\n if tl.hasAttribute(\"category_id\"):\n tD[\"category_id\"] = row[tl.getIndex(\"category_id\")]\n if tl.hasAttribute(\"include_as_category_id\"):\n tD[\"include_as_category_id\"] = row[tl.getIndex(\"include_as_category_id\")]\n if tl.hasAttribute(\"include_mode\"):\n tD[\"include_mode\"] = row[tl.getIndex(\"include_mode\")]\n #\n self.__categoryIncludeDict.setdefault(tD[\"dictionary_id\"], {}).setdefault(tD[\"category_id\"], tD)\n tl = ob.getObj(\"pdbx_include_item\")\n if tl is not None:\n for row in tl.getRowList():\n tD = OrderedDict()\n if tl.hasAttribute(\"dictionary_id\"):\n tD[\"dictionary_id\"] = row[tl.getIndex(\"dictionary_id\")]\n if tl.hasAttribute(\"item_name\"):\n tD[\"item_name\"] = row[tl.getIndex(\"item_name\")]\n if tl.hasAttribute(\"include_as_item_name\"):\n tD[\"include_as_item_name\"] = row[tl.getIndex(\"include_as_item_name\")]\n if tl.hasAttribute(\"include_mode\"):\n tD[\"include_mode\"] = row[tl.getIndex(\"include_mode\")]\n #\n categoryId = CifName.categoryPart(tD[\"item_name\"])\n self.__itemIncludeDict.setdefault(tD[\"dictionary_id\"], {}).setdefault(categoryId, {}).setdefault(tD[\"item_name\"], tD)\n\n tl = ob.getObj(\"dictionary_history\")\n if tl is not None:\n # history as a list of dictionaries -\n dName = ob.getName()\n for row in tl.getRowList():\n if tl.hasAttribute(\"version\") and tl.hasAttribute(\"revision\") and tl.hasAttribute(\"update\"):\n tD = OrderedDict()\n tD[\"version\"] = row[tl.getIndex(\"version\")]\n tD[\"revision\"] = row[tl.getIndex(\"revision\")]\n tD[\"update\"] = row[tl.getIndex(\"update\")]\n tD[\"dictionary\"] = dName\n self.__dictionaryHistoryList.append(tD)\n #\n tl = ob.getObj(\"pdbx_dictionary_component\")\n if tl is not None:\n for row in tl.getRowList():\n tD = OrderedDict()\n if tl.hasAttribute(\"dictionary_component_id\"):\n tD[\"dictionary_component_id\"] = row[tl.getIndex(\"dictionary_component_id\")]\n if tl.hasAttribute(\"title\"):\n tD[\"title\"] = row[tl.getIndex(\"title\")]\n if tl.hasAttribute(\"version\"):\n tD[\"version\"] = row[tl.getIndex(\"version\")]\n self.__dictionaryComponentList.append(tD)\n\n tl = ob.getObj(\"pdbx_dictionary_component_history\")\n if tl is not None:\n for row in tl.getRowList():\n if tl.hasAttribute(\"version\") and tl.hasAttribute(\"revision\") and tl.hasAttribute(\"update\"):\n tD = OrderedDict()\n tD[\"version\"] = row[tl.getIndex(\"version\")]\n tD[\"revision\"] = row[tl.getIndex(\"revision\")]\n tD[\"update\"] = row[tl.getIndex(\"update\")]\n tD[\"dictionary_component_id\"] = row[tl.getIndex(\"dictionary_component_id\")]\n self.__dictionaryComponentHistoryDict.setdefault(tD[\"dictionary_component_id\"], []).append(tD)\n\n # JDW\n tl = ob.getObj(\"sub_category\")\n if tl is not None:\n # subcategories as a dictionary by id\n self.__subCategoryDict = OrderedDict()\n for row in tl.getRowList():\n if tl.hasAttribute(\"id\") and tl.hasAttribute(\"description\"):\n self.__subCategoryDict[row[tl.getIndex(\"id\")]] = row[tl.getIndex(\"description\")]\n\n tl = ob.getObj(\"category_group_list\")\n if tl is not None:\n # category groups as a dictionary by id of tuples\n self.__categoryGroupDict = OrderedDict()\n for row in tl.getRowList():\n if tl.hasAttribute(\"id\") and tl.hasAttribute(\"description\") and tl.hasAttribute(\"parent_id\"):\n tD = OrderedDict()\n tD[\"description\"] = row[tl.getIndex(\"description\")]\n tD[\"parent_id\"] = row[tl.getIndex(\"parent_id\")]\n tD[\"categories\"] = []\n self.__categoryGroupDict[row[tl.getIndex(\"id\")]] = tD\n\n tl = ob.getObj(\"item_units_list\")\n if tl is not None:\n # units as a dictionary by code\n self.__itemUnitsDict = OrderedDict()\n for row in tl.getRowList():\n if tl.hasAttribute(\"code\") and tl.hasAttribute(\"detail\"):\n self.__itemUnitsDict[row[tl.getIndex(\"code\")]] = row[tl.getIndex(\"detail\")]\n\n tl = ob.getObj(\"item_units_conversion\")\n if tl is not None:\n # units conversion as a simple list now\n self.__itemUnitsConversionList = []\n for row in tl.getRowList():\n if tl.hasAttribute(\"from_code\") and tl.hasAttribute(\"to_code\") and tl.hasAttribute(\"operator\") and tl.hasAttribute(\"factor\"):\n self.__itemUnitsConversionList.append((row[tl.getIndex(\"from_code\")], row[tl.getIndex(\"to_code\")], row[tl.getIndex(\"operator\")], row[tl.getIndex(\"factor\")]))\n\n tl = ob.getObj(\"pdbx_item_linked_group\")\n if tl is not None:\n # parent-child collections [category_id] -> [(1,...),(3,...),(4,...) ]\n self.__itemLinkedGroupDict = OrderedDict()\n for row in tl.getRowList():\n if (\n tl.hasAttribute(\"category_id\")\n and tl.hasAttribute(\"link_group_id\")\n and tl.hasAttribute(\"label\")\n and tl.hasAttribute(\"context\")\n and tl.hasAttribute(\"condition_id\")\n ):\n categoryId = row[tl.getIndex(\"category_id\")]\n if categoryId not in self.__itemLinkedGroupDict:\n self.__itemLinkedGroupDict[categoryId] = []\n self.__itemLinkedGroupDict[categoryId].append(\n (row[tl.getIndex(\"category_id\")], row[tl.getIndex(\"link_group_id\")], row[tl.getIndex(\"context\")], row[tl.getIndex(\"condition_id\")])\n )\n\n tl = ob.getObj(\"pdbx_item_linked_group_list\")\n if tl is not None:\n # parent-child collections [(category_id,link_group_id)] -> [(child_name,parent_name,parent_category),(,...),(,...) ]\n self.__itemLinkedGroupItemDict = OrderedDict()\n for row in tl.getRowList():\n if (\n tl.hasAttribute(\"child_category_id\")\n and tl.hasAttribute(\"link_group_id\")\n and tl.hasAttribute(\"child_name\")\n and tl.hasAttribute(\"parent_name\")\n and tl.hasAttribute(\"parent_category_id\")\n ):\n childCategoryId = row[tl.getIndex(\"child_category_id\")]\n linkGroupId = row[tl.getIndex(\"link_group_id\")]\n if (childCategoryId, linkGroupId) not in self.__itemLinkedGroupItemDict:\n self.__itemLinkedGroupItemDict[(childCategoryId, linkGroupId)] = []\n self.__itemLinkedGroupItemDict[(childCategoryId, linkGroupId)].append(\n (row[tl.getIndex(\"child_name\")], row[tl.getIndex(\"parent_name\")], row[tl.getIndex(\"parent_category_id\")])\n )\n #\n tl = ob.getObj(\"pdbx_item_value_condition_list\")\n if tl is not None:\n for row in tl.getRowList():\n if tl.hasAttribute(\"dependent_item_name\") and tl.hasAttribute(\"dependent_item_cmp_op\") and tl.hasAttribute(\"target_item_name\") and tl.hasAttribute(\"cond_id\"):\n tD = OrderedDict()\n tD[\"cond_id\"] = row[tl.getIndex(\"cond_id\")]\n tD[\"target_item_name\"] = row[tl.getIndex(\"target_item_name\")]\n tD[\"dependent_item_name\"] = row[tl.getIndex(\"dependent_item_name\")]\n tD[\"dependent_item_cmp_op\"] = row[tl.getIndex(\"dependent_item_cmp_op\")]\n tD[\"target_item_value\"] = row[tl.getIndex(\"target_item_value\")] if tl.hasAttribute(\"target_item_value\") else None\n tD[\"dependent_item_value\"] = row[tl.getIndex(\"dependent_item_value\")] if tl.hasAttribute(\"dependent_item_value\") else None\n tD[\"log_op\"] = row[tl.getIndex(\"log_op\")] if tl.hasAttribute(\"log_op\") else \"and\"\n self.__itemValueConditionDict.setdefault(tD[\"target_item_name\"], {}).setdefault(tD[\"dependent_item_name\"], []).append(tD)\n #\n tl = ob.getObj(\"pdbx_comparison_operator_list\")\n if tl is not None:\n for row in tl.getRowList():\n if tl.hasAttribute(\"code\") and tl.hasAttribute(\"description\"):\n tD = OrderedDict()\n tD[\"code\"] = row[tl.getIndex(\"code\")]\n tD[\"description\"] = row[tl.getIndex(\"description\")]\n self.__compOpDict[tD[\"code\"]] = tD[\"description\"]\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.__init__","title":"__init__(self, containerList, consolidate=True, expandItemLinked=False, replaceDefinition=False, **kwargs)
special
","text":"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):\n \"\"\"Return an instance of the mmCIF dictionary API.\n\n Args:\n containerList (list): list of definition or data containers holding dictionary content\n consolidate (bool, optional): consolidate dictionary attributes within a single definition. Defaults to True.\n expandItemLinked (bool, optional): distribute item and item linked attributes defined for the parent\n to child definitions. Defaults to False.\n replaceDefinition (bool, optional): when consolidating definitions in the case of multiple occurences of the same definition,\n attributes from the latter occurences replace prior definitions content. Defaults to False.\n \"\"\"\n _ = kwargs\n #\n self.__containerList = containerList\n self.__replaceDefinition = replaceDefinition\n #\n if consolidate:\n self.__consolidateDefinitions()\n #\n if expandItemLinked:\n self.__expandLoopedDefinitions()\n\n self.__fullIndex = OrderedDict()\n\n # ---\n #\n # Map category name to the unique list of attributes\n self.__catNameIndex = OrderedDict()\n # Map category name to the unique list of item names\n self.__catNameItemIndex = OrderedDict()\n # Full unique list of item names -\n self.__itemNameList = []\n #\n # Map dictionary objects names to definition containers -\n self.__definitionIndex = OrderedDict()\n #\n # data section/objects of the dictionary by category name -\n self.__dataIndex = OrderedDict()\n #\n # Map of types id->(regex,primitive_type)\n self.__typesDict = OrderedDict()\n #\n self.__enumD = {\n \"ENUMERATION_VALUE\": (\"item_enumeration\", \"value\"),\n \"ENUMERATION_DETAIL\": (\"item_enumeration\", \"detail\"),\n \"ENUMERATION_TYPE_UNITS\": (\"item_enumeration\", \"rcsb_type_units_code\"),\n \"ENUMERATION_DETAIL_BRIEF\": (\"item_enumeration\", \"rcsb_detail_brief\"),\n \"ENUMERATION_TUPLE\": (\"item_enumeration\", None),\n \"ITEM_LINKED_PARENT\": (\"item_linked\", \"parent_name\"),\n \"ITEM_LINKED_CHILD\": (\"item_linked\", \"child_name\"),\n \"DATA_TYPE_CODE\": (\"item_type\", \"code\"),\n \"DATA_TYPE_REGEX\": (\"item_type_list\", \"construct\"),\n \"DATA_TYPE_PRIMITIVE\": (\"item_type_list\", \"primitive_code\"),\n \"ITEM_NAME\": (\"item\", \"name\"),\n \"ITEM_CATEGORY_ID\": (\"item\", \"category_id\"),\n \"ITEM_MANDATORY_CODE\": (\"item\", \"mandatory_code\"),\n \"ITEM_DESCRIPTION\": (\"item_description\", \"description\"),\n \"ITEM_UNITS\": (\"item_units\", \"code\"),\n \"ITEM_DEFAULT_VALUE\": (\"item_default\", \"value\"),\n \"ITEM_EXAMPLE_CASE\": (\"item_examples\", \"case\"),\n \"ITEM_EXAMPLE_DETAIL\": (\"item_examples\", \"detail\"),\n \"ITEM_RANGE_MAXIMUM\": (\"item_range\", \"maximum\"),\n \"ITEM_RANGE_MINIMUM\": (\"item_range\", \"minimum\"),\n \"CATEGORY_KEY_ITEMS\": (\"category_key\", \"name\"),\n \"CATEGORY_EXAMPLE_CASE\": (\"category_examples\", \"case\"),\n \"CATEGORY_EXAMPLE_DETAIL\": (\"category_examples\", \"detail\"),\n \"CATEGORY_MANDATORY_CODE\": (\"category\", \"mandatory_code\"),\n \"CATEGORY_DESCRIPTION\": (\"category\", \"description\"),\n \"CATEGORY_NX_MAPPING_DETAILS\": (\"category\", \"NX_mapping_details\"),\n #\n \"DATA_TYPE_CODE_NDB\": (\"ndb_item_type\", \"code\"),\n \"ITEM_DESCRIPTION_NDB\": (\"ndb_item_description\", \"description\"),\n \"ENUMERATION_VALUE_NDB\": (\"ndb_item_enumeration\", \"value\"),\n \"ENUMERATION_DETAIL_NDB\": (\"ndb_item_enumeration\", \"detail\"),\n \"ITEM_MANDATORY_CODE_NDB\": (\"ndb_item\", \"mandatory_code\"),\n \"ITEM_EXAMPLE_CASE_NDB\": (\"ndb_item_examples\", \"case\"),\n \"ITEM_EXAMPLE_DETAIL_NDB\": (\"ndb_item_examples\", \"detail\"),\n \"ITEM_RANGE_MAXIMUM_NDB\": (\"ndb_item_range\", \"maximum\"),\n \"ITEM_RANGE_MINIMUM_NDB\": (\"ndb_item_range\", \"minimum\"),\n \"CATEGORY_EXAMPLE_CASE_NDB\": (\"ndb_category_examples\", \"case\"),\n \"CATEGORY_EXAMPLE_DETAIL_NDB\": (\"ndb_category_examples\", \"detail\"),\n \"CATEGORY_DESCRIPTION_NDB\": (\"ndb_category_description\", \"description\"),\n #\n \"DATA_TYPE_CODE_PDBX\": (\"pdbx_item_type\", \"code\"),\n \"ITEM_DESCRIPTION_PDBX\": (\"pdbx_item_description\", \"description\"),\n \"ENUMERATION_VALUE_PDBX\": (\"pdbx_item_enumeration\", \"value\"),\n \"ENUMERATION_DETAIL_PDBX\": (\"pdbx_item_enumeration\", \"detail\"),\n \"ENUMERATION_TYPE_UNITS_PDBX\": (\"pdbx_item_enumeration\", \"type_units_code\"),\n \"ENUMERATION_DETAIL_BRIEF_PDBX\": (\"pdbx_item_enumeration\", \"detail_brief\"),\n \"ITEM_MANDATORY_CODE_PDBX\": (\"pdbx_item\", \"mandatory_code\"),\n \"ITEM_EXAMPLE_CASE_PDBX\": (\"pdbx_item_examples\", \"case\"),\n \"ITEM_EXAMPLE_DETAIL_PDBX\": (\"pdbx_item_examples\", \"detail\"),\n \"ITEM_RANGE_MAXIMUM_PDBX\": (\"pdbx_item_range\", \"maximum\"),\n \"ITEM_RANGE_MINIMUM_PDBX\": (\"pdbx_item_range\", \"minimum\"),\n \"CATEGORY_EXAMPLE_CASE_PDBX\": (\"pdbx_category_examples\", \"case\"),\n \"CATEGORY_EXAMPLE_DETAIL_PDBX\": (\"pdbx_category_examples\", \"detail\"),\n \"CATEGORY_DESCRIPTION_PDBX\": (\"pdbx_category_description\", \"description\"),\n #\n \"CATEGORY_CONTEXT\": (\"pdbx_category_context\", \"type\"),\n \"CATEGORY_GROUP\": (\"category_group\", \"id\"),\n \"ITEM_CONTEXT\": (\"pdbx_item_context\", \"type\"),\n \"ENUMERATION_CLOSED_FLAG\": (\"pdbx_item_enumeration_details\", \"closed_flag\"),\n #\n \"ITEM_RELATED_FUNCTION_CODE\": (\"item_related\", \"function_code\"),\n \"ITEM_RELATED_RELATED_NAME\": (\"item_related\", \"related_name\"),\n \"ITEM_ALIAS_ALIAS_NAME\": (\"item_aliases\", \"alias_name\"),\n \"ITEM_ALIAS_DICTIONARY\": (\"item_aliases\", \"dictionary\"),\n \"ITEM_ALIAS_VERSION\": (\"item_aliases\", \"version\"),\n \"ITEM_DEPENDENT_DEPENDENT_NAME\": (\"item_dependent\", \"dependent_name\"),\n \"ITEM_SUB_CATEGORY_ID\": (\"item_sub_category\", \"id\"),\n \"ITEM_SUB_CATEGORY_LABEL\": (\"item_sub_category\", \"pdbx_label\"),\n \"ITEM_TYPE_CONDITIONS_CODE\": (\"item_type_conditions\", \"code\"),\n #\n \"ITEM_VALUE_CONDITION_DEPENDENT_NAME\": (\"pdbx_item_value_condition\", \"dependent_item_name\"),\n #\n \"ITEM_LINKED_PDBX_ID\": (\"pdbx_item_linked\", \"id\"),\n \"ITEM_LINKED_PDBX_CONDITION_ID\": (\"pdbx_item_linked\", \"condition_id\"),\n \"ITEM_LINKED_PDBX_PARENT_NAME\": (\"pdbx_item_linked\", \"parent_name\"),\n \"ITEM_LINKED_PDBX_CHILD_NAME\": (\"pdbx_item_linked\", \"child_name\"),\n #\n \"ITEM_LINKED_PDBX_CONDITION_CHILD_NAME\": (\"pdbx_item_linked\", \"condition_child_name\"),\n \"ITEM_LINKED_PDBX_CONDITION_CHILD_VALUE\": (\"pdbx_item_linked\", \"condition_child_value\"),\n \"ITEM_LINKED_PDBX_CONDITION_CHILD_TARGET_NAME\": (\"pdbx_item_linked\", \"condition_child_target_name\"),\n \"ITEM_LINKED_PDBX_CONDITION_CHILD_CMP_OP\": (\"pdbx_item_linked\", \"condition_child_cmp_op\"),\n \"ITEM_LINKED_PDBX_CONDITION_LOG_OP\": (\"pdbx_item_linked\", \"condition_log_op\"),\n }\n #\n self.__methodDict = OrderedDict()\n self.__methodIndex = OrderedDict()\n #\n self.__makeIndex()\n self.__getMethods()\n #\n self.__fullParentD, self.__fullChildD = self.__makeFullParentChildDictionaries()\n #\n #\n self.__dataBlockDictList = []\n self.__dictionaryDictList = []\n #\n self.__subCategoryDict = OrderedDict()\n self.__categoryGroupDict = OrderedDict()\n self.__groupIndex = False\n self.__groupChildIndex = OrderedDict()\n #\n # Data sections -\n #\n self.__dictionaryHistoryList = []\n self.__itemUnitsDict = OrderedDict()\n self.__itemUnitsConversionList = []\n self.__itemLinkedGroupDict = OrderedDict()\n self.__itemLinkedGroupItemDict = OrderedDict()\n #\n self.__dictionaryIncludeDict = OrderedDict()\n self.__categoryIncludeDict = OrderedDict()\n self.__itemIncludeDict = OrderedDict()\n #\n self.__dictionaryComponentList = []\n self.__dictionaryComponentHistoryDict = OrderedDict()\n #\n self.__itemValueConditionDict = OrderedDict()\n self.__compOpDict = OrderedDict()\n #\n self.__getDataSections()\n #\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getDataTypeList","title":"getDataTypeList(self)
","text":"Return list of tuples containing ('code','primitive_code','construct','detail' )
Source code in mmcif/api/DictionaryApi.py
def getDataTypeList(self):\n \"\"\"Return list of tuples containing ('code','primitive_code','construct','detail' )\"\"\"\n rowList = []\n for code in sorted(self.__typesDict.keys()):\n tup = self.__typesDict[code]\n rowList.append((code, tup[0], tup[1], tup[2]))\n return rowList\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getDictionaryComponentCount","title":"getDictionaryComponentCount(self)
","text":"Get the count of dictionary components.
Source code in mmcif/api/DictionaryApi.py
def getDictionaryComponentCount(self):\n \"\"\"Get the count of dictionary components.\"\"\"\n try:\n return len(self.__dictionaryComponentList)\n except Exception:\n return 0\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getDictionaryComponentDetails","title":"getDictionaryComponentDetails(self)
","text":"Returns the component dictionary list as tuples [(version,title,dictionary_component_id),...]
Source code in mmcif/api/DictionaryApi.py
def getDictionaryComponentDetails(self):\n \"\"\"Returns the component dictionary list as tuples [(version,title,dictionary_component_id),...]\"\"\"\n oL = []\n try:\n for tD in self.__dictionaryComponentList:\n oL.append((tD[\"version\"], tD[\"title\"], tD[\"dictionary_component_id\"]))\n except Exception:\n pass\n return oL\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getDictionaryComponentHistory","title":"getDictionaryComponentHistory(self, dictionaryComponentId, order='reverse')
","text":"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\"):\n \"\"\"Returns the revision history as a list of tuples [(version,update,revisionText,dictionary),...]\"\"\"\n oL = []\n try:\n if order == \"reverse\":\n for tD in reversed(self.__dictionaryComponentHistoryDict[dictionaryComponentId]):\n oL.append((tD[\"version\"], tD[\"update\"], tD[\"revision\"], tD[\"dictionary_component_id\"]))\n else:\n for tD in self.__dictionaryComponentHistoryDict[dictionaryComponentId]:\n oL.append((tD[\"version\"], tD[\"update\"], tD[\"revision\"], tD[\"dictionary_component_id\"]))\n except Exception:\n pass\n return oL\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getDictionaryComponents","title":"getDictionaryComponents(self)
","text":"Get the list of dictionary components.
Source code in mmcif/api/DictionaryApi.py
def getDictionaryComponents(self):\n \"\"\"Get the list of dictionary components.\"\"\"\n try:\n return list(self.__dictionaryComponentHistoryDict.keys())\n except Exception:\n return []\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getDictionaryHistory","title":"getDictionaryHistory(self, order='reverse')
","text":"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\"):\n \"\"\"Returns the revision history as a list of tuples [(version,update,revisionText,dictionary),...]\"\"\"\n oL = []\n try:\n if order == \"reverse\":\n for tD in reversed(self.__dictionaryHistoryList):\n oL.append((tD[\"version\"], tD[\"update\"], tD[\"revision\"], tD[\"dictionary\"]))\n else:\n for tD in self.__dictionaryHistoryList:\n oL.append((tD[\"version\"], tD[\"update\"], tD[\"revision\"], tD[\"dictionary\"]))\n except Exception:\n pass\n return oL\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getDictionaryRevisionCount","title":"getDictionaryRevisionCount(self)
","text":"Get the count of revision history records.
Source code in mmcif/api/DictionaryApi.py
def getDictionaryRevisionCount(self):\n \"\"\"Get the count of revision history records.\"\"\"\n try:\n return len(self.__dictionaryHistoryList)\n except Exception:\n return 0\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getDictionaryUpdate","title":"getDictionaryUpdate(self, order='reverse')
","text":"Get details from the first/last history element.
Source code in mmcif/api/DictionaryApi.py
def getDictionaryUpdate(self, order=\"reverse\"):\n \"\"\"Get details from the first/last history element.\"\"\"\n try:\n if order == \"reverse\":\n tD = self.__dictionaryHistoryList[-1]\n else:\n tD = self.__dictionaryHistoryList[0]\n\n return tD[\"update\"]\n\n except Exception:\n return None\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getItemLinkedConditions","title":"getItemLinkedConditions(self)
","text":"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_\n _pdbx_item_linked.id\n _pdbx_item_linked.condition_id\n _pdbx_item_linked.parent_name\n _pdbx_item_linked.child_name\n #\n _pdbx_item_linked.condition_child_name\n _pdbx_item_linked.condition_child_value\n _pdbx_item_linked.condition_child_cmp_op\n _pdbx_item_linked.condition_child_target_name\n _pdbx_item_linked.condition_child_log_op\n 1 1 '_entity_poly_seq.num' '_atom_site.label_seq_id' '_atom_site.label_entity_id' . 'eq' '_entity.id' .\n 2 1 '_entity_poly_seq.num' '_atom_site.label_seq_id' '_entity.type' 'polymer' 'eq' . 'and'\n
Source code in mmcif/api/DictionaryApi.py
def getItemLinkedConditions(self):\n \"\"\"Create a dictionary of conditional item link relationships.\n\n Returns:\n (dict): {{parent_name, child_name}: [{\"id\": , \"condition_id\": , \"condition_child_name\": , \"condition_child_value\": ,\n \"condition_child_cmp_op\": , \"condition_log_op\": ,}, {},...]}\n\n Example:\n ```text\n loop_\n _pdbx_item_linked.id\n _pdbx_item_linked.condition_id\n _pdbx_item_linked.parent_name\n _pdbx_item_linked.child_name\n #\n _pdbx_item_linked.condition_child_name\n _pdbx_item_linked.condition_child_value\n _pdbx_item_linked.condition_child_cmp_op\n _pdbx_item_linked.condition_child_target_name\n _pdbx_item_linked.condition_child_log_op\n 1 1 '_entity_poly_seq.num' '_atom_site.label_seq_id' '_atom_site.label_entity_id' . 'eq' '_entity.id' .\n 2 1 '_entity_poly_seq.num' '_atom_site.label_seq_id' '_entity.type' 'polymer' 'eq' . 'and'\n ```\n\n \"\"\"\n rD = OrderedDict()\n try:\n for ob in self.__containerList:\n if ob.getType() == \"data\":\n continue\n tl = ob.getObj(self.__enumD[\"ITEM_LINKED_PDBX_ID\"][0])\n if tl is not None:\n for row in tl.getRowList():\n if (\n tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_ID\"][1])\n and tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_ID\"][1])\n and tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CHILD_NAME\"][1])\n and tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_PARENT_NAME\"][1])\n ):\n tD = OrderedDict()\n tD[\"id\"] = row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_ID\"][1])]\n tD[\"condition_id\"] = row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_ID\"][1])]\n parentName = row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_PARENT_NAME\"][1])]\n childName = row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CHILD_NAME\"][1])]\n #\n tD[\"condition_child_name\"] = (\n row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_NAME\"][1])]\n if tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_NAME\"][1])\n else None\n )\n tD[\"condition_child_value\"] = (\n row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_VALUE\"][1])]\n if tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_VALUE\"][1])\n else None\n )\n tD[\"condition_child_cmp_op\"] = (\n row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_CMP_OP\"][1])]\n if tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_CMP_OP\"][1])\n else None\n )\n tD[\"condition_child_target_name\"] = (\n row[tl.getIndex(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_TARGET_NAME\"][1])]\n if tl.hasAttribute(self.__enumD[\"ITEM_LINKED_PDBX_CONDITION_CHILD_TARGET_NAME\"][1])\n else None\n )\n tD[\"condition_log_op\"] = (\n 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\n )\n #\n rD.setdefault((parentName, childName), []).append(tD)\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n\n return rD\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getParentDictionary","title":"getParentDictionary(self)
","text":"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):\n \"\"\"Create a dictionary of parents relations accross all definnitions\n as {child : [parent, parent,...]\n\n Exclude self parents.\n \"\"\"\n parentD = {}\n pAtN = self.__enumD[\"ITEM_LINKED_PARENT\"][1]\n cAtN = self.__enumD[\"ITEM_LINKED_CHILD\"][1]\n\n for dObj in self.__containerList:\n dc = dObj.getObj(self.__enumD[\"ITEM_LINKED_PARENT\"][0])\n if dc is not None:\n idxP = dc.getIndex(pAtN)\n idxC = dc.getIndex(cAtN)\n for row in dc.getRowList():\n pVal = row[idxP]\n cVal = row[idxC]\n if pVal == cVal:\n continue\n if cVal not in parentD:\n parentD[cVal] = []\n parentD[cVal].append(pVal)\n #\n return parentD\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getSubCategoryList","title":"getSubCategoryList(self)
","text":"Return list of tuples containing ('id', 'description')
Source code in mmcif/api/DictionaryApi.py
def getSubCategoryList(self):\n \"\"\"Return list of tuples containing ('id', 'description')\"\"\"\n rowList = []\n for tId in sorted(self.__subCategoryDict.keys()):\n description = self.__subCategoryDict[tId]\n rowList.append((tId, description))\n return rowList\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getUltimateParent","title":"getUltimateParent(self, category, attribute)
","text":"Return the first ultimate parent item for the input item.
Source code in mmcif/api/DictionaryApi.py
def getUltimateParent(self, category, attribute):\n \"\"\"Return the first ultimate parent item for the input item.\"\"\"\n # pL=self.__getList('ITEM_LINKED_PARENT',category,attribute)\n pL = self.getFullParentList(category, attribute)\n itemName = CifName.itemName(category, attribute)\n while pL and (pL[0] != itemName):\n attN = CifName.attributePart(pL[0])\n catN = CifName.categoryPart(pL[0])\n itemName = pL[0]\n pL = self.getFullParentList(catN, attN)\n # pL=self.__getList('ITEM_LINKED_PARENT',catN,attN)\n return itemName\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getUnitsConversionList","title":"getUnitsConversionList(self)
","text":"Return list of tuples containing ('from_code','to_code','operator','factor')
Source code in mmcif/api/DictionaryApi.py
def getUnitsConversionList(self):\n \"\"\"Return list of tuples containing ('from_code','to_code','operator','factor')\"\"\"\n return self.__itemUnitsConversionList\n
"},{"location":"api_reference/DictionaryApi/#mmcif.api.DictionaryApi.DictionaryApi.getUnitsList","title":"getUnitsList(self)
","text":"Return list of tuples containing ('id', 'description')
Source code in mmcif/api/DictionaryApi.py
def getUnitsList(self):\n \"\"\"Return list of tuples containing ('id', 'description')\"\"\"\n rowList = []\n for tId in sorted(self.__itemUnitsDict.keys()):\n description = self.__itemUnitsDict[tId]\n rowList.append((tId, description))\n return rowList\n
"},{"location":"api_reference/DictionaryInclude/","title":"DictionaryInclude","text":"Source code in mmcif/api/DictionaryInclude.py
class DictionaryInclude(object):\n def __init__(self, **kwargs):\n #\n self.__itemNameRelatives = [\n \"_item.name\",\n \"_item_examples.name\",\n \"_ndb_item_description.name\",\n \"_item_related.name\",\n \"_category_key.name\",\n \"_item_structure.name\",\n \"_item_methods.name\",\n \"_item_aliases.name\",\n \"_item_dependent.dependent_name\",\n \"_item_default.name\",\n \"_pdbx_item_examples.name\",\n \"_item_units.name\",\n \"_item_related.related_name\",\n \"_item_description.name\",\n \"_item_dependent.name\",\n \"_item_range.name\",\n \"_item_sub_category.name\",\n \"_pdbx_item_range.name\",\n \"_pdbx_item_linked.condition_child_name\",\n \"_ndb_item_examples.name\",\n \"_pdbx_item_value_condition.item_name\",\n \"_ndb_item_range.name\",\n \"_item_linked.child_name\",\n \"_pdbx_item_description.name\",\n \"_pdbx_item_context.item_name\",\n \"_pdbx_item_enumeration_details.name\",\n \"_pdbx_item_linked_group_list.child_name\",\n \"_pdbx_item_linked_group_list.parent_name\",\n \"_pdbx_item_value_condition_list.target_item_name\",\n \"_ndb_item_enumeration.name\",\n \"_pdbx_item_linked.child_name\",\n \"_pdbx_item_value_condition.dependent_item_name\",\n \"_pdbx_item_enumeration.name\",\n \"_item_linked.parent_name\",\n \"_pdbx_item_value_condition_list.dependent_item_name\",\n \"_item_type.name\",\n \"_item_type_conditions.name\",\n \"_pdbx_item_linked.parent_name\",\n \"_item_enumeration.name\",\n ]\n self.__categoryIdRelatives = [\n \"_category.id\",\n \"_category_key.id\",\n \"_pdbx_item_linked_group.category_id\",\n \"_pdbx_category_examples.id\",\n \"_item.category_id\",\n \"_pdbx_category_context.category_id\",\n \"_pdbx_item_linked_group_list.parent_category_id\",\n \"_category_group.category_id\",\n \"_pdbx_category_description.id\",\n \"_ndb_category_examples.id\",\n \"_category_examples.id\",\n \"_category_methods.category_id\",\n \"_ndb_category_description.id\",\n \"_pdbx_item_linked_group_list.child_category_id\",\n ]\n #\n self.__cwd = os.getcwd()\n self.__dirPath = kwargs.get(\"dirPath\", os.getcwd())\n logger.info(\"Local dictionary include path relative to %s\", self.__dirPath)\n self.__dirStack = []\n self.__locatorIndexD = {}\n\n def processIncludedContent(self, containerList, cleanup=False):\n \"\"\"Process any dictionary, category or item include instructions in any data containers in the\n input list of dictionary data and definition containers.\n\n Args:\n containerList (list): list of input PdbxContainer data or definition container objects\n cleanup (bool, optional): flag to remove generator category objects after parsing (default: False)\n\n Returns:\n (list): list of data and definition containers incorporating included content\n\n Examples:\n ```python\n pathDdlIncludeDictionary = \"mmcif_ddl-generator.dic\"\n myIo = IoAdapter(raiseExceptions=True)\n containerList = myIo.readFile(inputFilePath=pathDdlIncludeDictionary)\n logger.info(\"Starting container list length (%d)\", len(containerList))\n dIncl = DictionaryInclude()\n inclL = dIncl.processIncludedContent(containerList)\n logger.info(\"Processed included container length (%d)\", len(inclL))\n ```\n\n \"\"\"\n includeD = self.__getIncludeInstructions(containerList, cleanup=cleanup)\n includeContentD = self.__fetchIncludedContent(includeD, cleanup=cleanup)\n return self.__addIncludedContent(containerList, includeContentD)\n\n def __addIncludedContent(self, containerList, includeContentD):\n \"\"\"Incorporate included content described in the input dictionary of include instructions produced by\n internal method __getIncludeInstructions().\n\n Args:\n containerList (list): list of input PdbxContainer data or definition container objects\n includeContentD (dict): {\"dictionaryIncludeDict\": {dictionary_id: {...include details...}},\n \"categoryIncludeDict\": {dictionary_id: {category_id: {...include details... }}},\n \"itemIncludeDict\": {dictionary_id: {category_id: {itemName: {...include details...}}}}\n }\n\n Returns:\n (list): list of data and definition containers incorporating included content\n \"\"\"\n # Index the current container list...\n cD = OrderedDict()\n datablockName = \"unnamed_1\"\n for container in containerList:\n if container.getType() == \"data\":\n datablockName = container.getName()\n # Handle potentially unconsolidated definitions --\n cD.setdefault(datablockName, OrderedDict()).setdefault(container.getName(), []).append(container)\n #\n #\n for datablockName in cD:\n if datablockName in includeContentD:\n if \"replace\" in includeContentD[datablockName]:\n # Organize the replacements by name\n replaceDefinitionD = OrderedDict()\n replaceDataD = OrderedDict()\n for container in includeContentD[datablockName][\"replace\"]:\n if container.getType() == \"definition\":\n replaceDefinitionD.setdefault(container.getName(), []).append(container)\n else:\n replaceDataD.setdefault(datablockName, []).append(container)\n #\n for rN, rL in replaceDefinitionD.items():\n if rN in cD[datablockName]:\n cD[datablockName][rN] = rL\n # replace data sections in the base container\n baseContainer = cD[datablockName][datablockName][0]\n for rN, containerL in replaceDataD.items():\n for container in containerL:\n for nm in container.getObjNameList():\n obj = container.getObj(nm)\n baseContainer.replace(obj)\n #\n if \"extend\" in includeContentD[datablockName]:\n extendDataD = OrderedDict()\n for container in includeContentD[datablockName][\"extend\"]:\n if container.getType() == \"definition\":\n cD.setdefault(datablockName, OrderedDict()).setdefault(container.getName(), []).append(container)\n else:\n extendDataD.setdefault(datablockName, []).append(container)\n # extend data sections in the base container\n baseContainer = cD[datablockName][datablockName][0]\n for rN, containerL in extendDataD.items():\n for container in containerL:\n for nm in container.getObjNameList():\n obj = container.getObj(nm)\n if baseContainer.exists(nm):\n baseObj = baseContainer.getObj(nm)\n for ii in range(obj.getRowCount()):\n rowD = obj.getRowAttributeDict(ii)\n baseObj.append(rowD)\n else:\n baseContainer.append(obj)\n #\n # Unwind the container index\n #\n fullL = []\n for datablockName in cD:\n for cL in cD[datablockName].values():\n fullL.extend(cL)\n #\n return fullL\n\n def __getIncludeInstructions(self, containerList, cleanup=False):\n \"\"\"Extract include instructions from categories pdbx_include_dictionary, pdbx_include_category, and pdbx_include_item.\n\n Args:\n containerList (list): list of input PdbxContainer data or definition container objects\n cleanup (optional, bool): flag to remove generator category objects after parsing (default: False)\n\n Returns:\n A dictionary containing the dictionary, category and and item level include details.\n For example,\n\n ```python\n {\n \"dictionaryIncludeDict\": {dictionary_id: {...include details...}},\n \"categoryIncludeDict\": {dictionary_id: {category_id: {...include details... }}},\n \"itemIncludeDict\": {dictionary_id: {category_id: {itemName: {...include details...}}}},\n }\n ```\n\n\n \"\"\"\n includeD = OrderedDict()\n try:\n unNamed = 1\n for container in containerList:\n if container.getType() == \"data\":\n dictionaryIncludeDict = OrderedDict()\n categoryIncludeDict = OrderedDict()\n itemIncludeDict = OrderedDict()\n if container.getName():\n datablockName = container.getName()\n else:\n datablockName = str(unNamed)\n unNamed += 1\n logger.debug(\"Adding data sections from container name %s type %s\", datablockName, container.getType())\n tl = container.getObj(\"pdbx_include_dictionary\")\n if tl is not None:\n for row in tl.getRowList():\n tD = OrderedDict()\n for atName in [\"dictionary_id\", \"dictionary_locator\", \"include_mode\", \"dictionary_namespace_prefix\", \"dictionary_namespace_prefix_replace\"]:\n tD[atName] = row[tl.getIndex(atName)] if tl.hasAttribute(atName) else None\n dictionaryIncludeDict[tD[\"dictionary_id\"]] = tD\n #\n tl = container.getObj(\"pdbx_include_category\")\n if tl is not None:\n for row in tl.getRowList():\n tD = OrderedDict()\n for atName in [\"dictionary_id\", \"category_id\", \"include_as_category_id\", \"include_mode\"]:\n tD[atName] = row[tl.getIndex(atName)] if tl.hasAttribute(atName) else None\n categoryIncludeDict.setdefault(tD[\"dictionary_id\"], {}).setdefault(tD[\"category_id\"], tD)\n #\n tl = container.getObj(\"pdbx_include_item\")\n if tl is not None:\n for row in tl.getRowList():\n tD = OrderedDict()\n for atName in [\"dictionary_id\", \"item_name\", \"include_as_item_name\", \"include_mode\"]:\n tD[atName] = row[tl.getIndex(atName)] if tl.hasAttribute(atName) else None\n categoryId = CifName.categoryPart(tD[\"item_name\"])\n itemIncludeDict.setdefault(tD[\"dictionary_id\"], {}).setdefault(categoryId, {}).setdefault(tD[\"item_name\"], tD)\n if cleanup:\n for catName in [\"pdbx_include_dictionary\", \"pdbx_include_category\", \"pdbx_include_item\"]:\n if container.exists(catName):\n container.remove(catName)\n #\n includeD[datablockName] = {\n \"dictionaryIncludeDict\": dictionaryIncludeDict,\n \"categoryIncludeDict\": categoryIncludeDict,\n \"itemIncludeDict\": itemIncludeDict,\n }\n except Exception as e:\n logger.exception(\"Include processing failing with %s\", str(e))\n return includeD\n\n def __fetchIncludedContent(self, includeD, cleanup=False):\n \"\"\"Fetch included content following the instructions encoded in the input data structure.\n\n Args:\n includeD (dict): {\"dictionaryIncludeDict\": {dictionary_id: {...include details...}},\n \"categoryIncludeDict\": {dictionary_id: {category_id: {...include details... }}},\n \"itemIncludeDict\": {dictionary_id: {category_id: {itemName: {...include details...}}}},\n }\n cleanup (optional, bool): flag to remove generator category objects after parsing (default: false)\n\n Returns:\n (dict): {datablockName: {\"extend\": [container,...], \"replace\": [container, ...]}, ... }\n\n \"\"\"\n\n includeDataD = {}\n try:\n for datablockName, inclD in includeD.items():\n cL = []\n for dictName, iD in inclD[\"dictionaryIncludeDict\"].items():\n locator = iD[\"dictionary_locator\"]\n if locator in self.__locatorIndexD:\n logger.info(\"Skipping redundant include for %r at %r\", dictName, locator)\n continue\n self.__locatorIndexD[locator] = dictName\n #\n # --- Fetch the dictionary component -\n #\n updateStack = self.__isLocal(locator)\n if updateStack:\n if not self.__dirStack:\n # top-level include case\n self.__dirStack.append(os.path.abspath(self.__dirPath))\n\n # embedded include case (push directory containing the locator)\n if not os.path.isabs(locator):\n # handle the relative path case -\n locator = os.path.abspath(os.path.join(self.__dirStack[-1], locator))\n logger.debug(\"modified local relative locator is %r\", locator)\n self.__dirStack.append(os.path.dirname(locator))\n logger.debug(\"dirStack (%d) top %r\", len(self.__dirStack), self.__dirStack[-1])\n containerList = self.processIncludedContent(self.__fetchLocator(locator), cleanup=cleanup)\n if updateStack:\n # restore stack context\n self.__dirStack.pop()\n #\n nsPrefix = iD[\"dictionary_namespace_prefix\"]\n nsPrefixReplace = iD[\"dictionary_namespace_prefix_replace\"]\n dictInclMode = iD[\"include_mode\"]\n dataIncludeMode = iD[\"data_include_mode\"] if \"data_include_mode\" in iD else \"extend\"\n catInclD = inclD[\"categoryIncludeDict\"][dictName] if dictName in inclD[\"categoryIncludeDict\"] else None\n itemInclD = inclD[\"itemIncludeDict\"][dictName] if dictName in inclD[\"itemIncludeDict\"] else None\n #\n # Do data sections first.\n for container in containerList:\n if container.getType() == \"data\":\n logger.debug(\"Including data container %r with %r\", container.getName(), container.getObjNameList())\n cL.append((container, dataIncludeMode))\n #\n if catInclD or itemInclD:\n # Process only explicitly included categories/items in the dictionary component\n if catInclD:\n for container in containerList:\n if container.getType() == \"data\":\n continue\n cName = container.getName()\n catName = cName if container.isCategory() else CifName.categoryPart(cName)\n #\n if catName in catInclD:\n if container.isAttribute() and itemInclD and catName in itemInclD and cName in itemInclD[catName]:\n inclMode = itemInclD[catName][cName][\"include_mode\"] if itemInclD[catName][cName][\"include_mode\"] else dictInclMode\n cL.append((self.__renameItem(container, itemInclD[catName][cName][\"include_as_item_name\"]), inclMode))\n else:\n inclMode = catInclD[catName][\"include_mode\"] if catInclD[catName][\"include_mode\"] else dictInclMode\n cL.append((self.__renameCategory(container, catInclD[catName][\"include_as_category_id\"]), inclMode))\n elif itemInclD:\n # Process only explicitly included items exclusive of explicitly included categories in the dictionary component\n for container in containerList:\n if container.getType() == \"data\":\n continue\n cName = container.getName()\n catName = cName if container.isCategory() else CifName.categoryPart(cName)\n #\n if container.isAttribute() and catName in itemInclD and cName in itemInclD[catName]:\n inclMode = itemInclD[catName][cName][\"include_mode\"] if itemInclD[catName][cName][\"include_mode\"] else dictInclMode\n cL.append((self.__renameItem(container, itemInclD[catName][cName][\"include_as_item_name\"]), inclMode))\n else:\n # Process the full content of the dictionary component\n for container in containerList:\n if container.getType() == \"data\":\n continue\n cName = container.getName()\n catName = cName if container.isCategory() else CifName.categoryPart(cName)\n #\n if container.isAttribute():\n newName = self.__substituteItemPrefix(cName, nsPrefix, nsPrefixReplace)\n cL.append((self.__renameItem(container, newName), dictInclMode))\n else:\n newName = self.__substituteCategoryPrefix(catName, nsPrefix, nsPrefixReplace)\n cL.append((self.__renameCategory(container, newName), dictInclMode))\n #\n for container, inclMode in cL:\n if inclMode == \"replace\":\n includeDataD.setdefault(datablockName, {}).setdefault(\"replace\", []).append(container)\n elif inclMode == \"extend\":\n logger.debug(\"%r extending with %r\", datablockName, container.getName())\n includeDataD.setdefault(datablockName, {}).setdefault(\"extend\", []).append(container)\n #\n for nm in includeDataD:\n numReplace = len(includeDataD[nm][\"replace\"]) if \"replace\" in includeDataD[nm] else 0\n numExtend = len(includeDataD[nm][\"extend\"]) if \"extend\" in includeDataD[nm] else 0\n logger.debug(\"includeDataD %s replace (%d) extend (%d)\", nm, numReplace, numExtend)\n #\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n\n return includeDataD\n\n def __isLocal(self, locator):\n try:\n locSp = urlsplit(locator)\n return locSp.scheme in [\"\", \"file\"]\n except Exception as e:\n logger.error(\"Bad include file path (%r) : %s\", locator, str(e))\n return False\n\n def __fetchLocator(self, locator, **kwargs):\n \"\"\"\"\"\"\n try:\n # Locate non-absolute paths relative to the dictionary incude file\n if self.__isLocal(locator) and not os.path.isabs(locator):\n logger.info(\"locator is %r\", locator)\n logger.info(\"dirStack (%d) top %r\", len(self.__dirStack), self.__dirStack[-1])\n locator = os.path.abspath(os.path.relpath(locator, start=self.__dirStack[-1]))\n #\n containerList = []\n workPath = kwargs.get(\"workPath\", None)\n enforceAscii = kwargs.get(\"enforceAscii\", False)\n raiseExceptions = kwargs.get(\"raiseExceptions\", True)\n useCharRefs = kwargs.get(\"useCharRefs\", True)\n #\n myIo = IoAdapterPy(raiseExceptions=raiseExceptions, useCharRefs=useCharRefs)\n containerList = myIo.readFile(locator, enforceAscii=enforceAscii, outDirPath=workPath)\n logger.info(\"Fetched %r dictionary container length (%d)\", locator, len(containerList) if containerList else 0)\n logger.debug(\"%r\", [container.getName() for container in containerList])\n except Exception as e:\n logger.exception(\"Failing for %s with %s\", locator, str(e))\n return containerList\n\n def __substituteCategoryPrefix(self, catName, curPrefix, newPrefix):\n return catName.replace(curPrefix, newPrefix, 1) if catName and catName.startswith(curPrefix) else catName\n\n def __substituteItemPrefix(self, itemName, curPrefix, newPrefix):\n atName = CifName.attributePart(itemName)\n atName = atName.replace(curPrefix, newPrefix, 1) if atName and atName.startswith(curPrefix) else atName\n catName = CifName.categoryPart(itemName)\n catName = catName.replace(curPrefix, newPrefix, 1) if atName and catName.startswith(curPrefix) else catName\n return CifName.itemName(catName, atName)\n\n def __renameItem(self, container, newItemName):\n if not container and not container.isAttribute() or not newItemName:\n return container\n #\n itemNameCur = container.getName()\n if itemNameCur == newItemName:\n return container\n #\n try:\n for item in self.__itemNameRelatives:\n catName = CifName.categoryPart(item)\n if container.exists(catName):\n cObj = container.getObj(catName)\n atName = CifName.attributePart(item)\n if cObj.hasAttribute(atName):\n for iRow in range(cObj.getRowCount()):\n curVal = cObj.getValue(atName, iRow)\n if curVal == itemNameCur:\n cObj.setValue(newItemName, atName, iRow)\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n return container\n\n def __renameCategory(self, container, newCategoryName):\n if not container and not container.isCategory() or not newCategoryName:\n return container\n #\n catNameCur = container.getName()\n if catNameCur == newCategoryName:\n return container\n try:\n for item in self.__categoryIdRelatives:\n catName = CifName.categoryPart(item)\n if container.exists(catName):\n cObj = container.getObj(catName)\n atName = CifName.attributePart(item)\n if cObj.hasAttribute(atName):\n for iRow in range(cObj.getRowCount()):\n testVal = cObj.getValue(atName, iRow)\n if testVal == catNameCur:\n cObj.setValue(newCategoryName, atName, iRow)\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n return container\n
"},{"location":"api_reference/DictionaryInclude/#mmcif.api.DictionaryInclude.DictionaryInclude.processIncludedContent","title":"processIncludedContent(self, containerList, cleanup=False)
","text":"Process any dictionary, category or item include instructions in any data containers in the input list of dictionary data and definition containers.
Parameters:
Name Type Description Default containerList
list
list of input PdbxContainer data or definition container objects
required cleanup
bool
flag to remove generator category objects after parsing (default: False)
False
Returns:
Type Description (list)
list of data and definition containers incorporating included content
Examples:
pathDdlIncludeDictionary = \"mmcif_ddl-generator.dic\"\nmyIo = IoAdapter(raiseExceptions=True)\ncontainerList = myIo.readFile(inputFilePath=pathDdlIncludeDictionary)\nlogger.info(\"Starting container list length (%d)\", len(containerList))\ndIncl = DictionaryInclude()\ninclL = dIncl.processIncludedContent(containerList)\nlogger.info(\"Processed included container length (%d)\", len(inclL))\n
Source code in mmcif/api/DictionaryInclude.py
def processIncludedContent(self, containerList, cleanup=False):\n \"\"\"Process any dictionary, category or item include instructions in any data containers in the\n input list of dictionary data and definition containers.\n\n Args:\n containerList (list): list of input PdbxContainer data or definition container objects\n cleanup (bool, optional): flag to remove generator category objects after parsing (default: False)\n\n Returns:\n (list): list of data and definition containers incorporating included content\n\n Examples:\n ```python\n pathDdlIncludeDictionary = \"mmcif_ddl-generator.dic\"\n myIo = IoAdapter(raiseExceptions=True)\n containerList = myIo.readFile(inputFilePath=pathDdlIncludeDictionary)\n logger.info(\"Starting container list length (%d)\", len(containerList))\n dIncl = DictionaryInclude()\n inclL = dIncl.processIncludedContent(containerList)\n logger.info(\"Processed included container length (%d)\", len(inclL))\n ```\n\n \"\"\"\n includeD = self.__getIncludeInstructions(containerList, cleanup=cleanup)\n includeContentD = self.__fetchIncludedContent(includeD, cleanup=cleanup)\n return self.__addIncludedContent(containerList, includeContentD)\n
"},{"location":"api_reference/IoAdapterBase/","title":"IoAdapterBase","text":"Base class presenting essential mmCIF I/O methods.
Source code in mmcif/io/IoAdapterBase.py
class IoAdapterBase(object):\n \"\"\"Base class presenting essential mmCIF I/O methods.\"\"\"\n\n def __init__(self, *args, **kwargs):\n \"\"\"General options controlling I/O method operations:\n\n Args:\n raiseExceptions (bool, optional): Flag to indicate that API errors should generate exceptions (True) or catch and log errors (default=False)\n maxInputLineLength (int, optional): Default maximum input line length (default=4096)\n useCharRefs (bool, optional): Replace non-ascii characters with XML Character References (default=True)\n readEncodingErrors (str, optional): treatment of encoding errors at read time (default='ignore')\n timing (bool, optional): log timing details for parsing and processing steps (default=False)\n verbose (bool,optional): log verbose output from wrapped libraries\n\n \"\"\"\n _ = args\n self._raiseExceptions = kwargs.get(\"raiseExceptions\", False)\n self._maxInputLineLength = kwargs.get(\"maxInputLineLength\", 4096)\n self._useCharRefs = kwargs.get(\"useCharRefs\", True)\n self.__logFilePath = None\n self._debug = kwargs.get(\"debug\", False)\n self._timing = kwargs.get(\"timing\", False)\n self._verbose = kwargs.get(\"verbose\", True)\n self._readEncodingErrors = kwargs.get(\"readEncodingErrors\", \"ignore\")\n\n def readFile(self, *args, **kwargs):\n \"\"\"Read file method. (abstract)\n\n Args:\n inputFilePath (string): Input file path/uri\n kw: optional key-value arguments\n\n Returns:\n list of DataContainer Objects: list of data or definition container objects\n \"\"\"\n raise NotImplementedError(\"To be implemented in subclass\")\n\n def writeFile(self, outputFilePath, containerList, **kwargs):\n \"\"\"Write file method - (abstract)\n\n Args:\n outputFilePath (string): output file path\n containerList (list of DataContainer objects): list of data or definition containers objects for output\n\n Returns:\n bool: Completion status\n \"\"\"\n raise NotImplementedError(\"To be implemented in subclass\")\n\n def getReadDiags(self):\n \"\"\"Return any diagnostics from the last read operation. (abstract)\"\"\"\n raise NotImplementedError(\"To be implemented in subclass\")\n\n def _setContainerProperties(self, containerList, **kwargs):\n try:\n for container in containerList:\n for kw in kwargs:\n container.setProp(kw, kwargs[kw])\n except Exception:\n return False\n\n def _getTimeStamp(self):\n utcnow = datetime.datetime.utcnow()\n ts = utcnow.strftime(\"%Y-%m-%d:%H:%M:%S\")\n return ts\n\n def _getCategoryNameList(self, container, lastInOrder=None, selectOrder=None):\n \"\"\"Return an ordered list of categories in the input container subject to\n input category name lists.\n\n Args:\n container (DataContainer object): Input DataContainer object\n lastInOrder (list): names of categories to be shifted to the end of the container.\n selectOrder (list): preferred order of category names\n\n Returns:\n catNameList: list: augmented category list or full list (default)\n \"\"\"\n catNameList = []\n if lastInOrder:\n objNameList = container.getObjNameList()\n lastList = []\n for nm in objNameList:\n if nm in lastInOrder:\n lastList.append(nm)\n continue\n catNameList.append(nm)\n catNameList.extend(lastList)\n elif selectOrder:\n for nm in selectOrder:\n if container.exists(nm):\n catNameList.append(nm)\n else:\n catNameList = container.getObjNameList()\n\n return catNameList\n\n def _setLogFilePath(self, filePath):\n \"\"\"Set the log file path.\"\"\"\n self.__logFilePath = filePath\n\n def _getLogFilePath(self):\n \"\"\"Return current log file path.\"\"\"\n return self.__logFilePath\n\n def _appendToLog(self, stList):\n \"\"\"Append input string list to the current log file -\"\"\"\n if not self.__logFilePath:\n return False\n try:\n with open(self.__logFilePath, \"a\") as ofh:\n ofh.write(\"%s\\n\" % \"\\n\".join(stList))\n return True\n except Exception as e:\n logger.debug(\"Failing with %s\", str(e))\n return True\n\n def _logError(self, msg):\n \"\"\"Convenience method to log error messages and optionally raise general exceptions (PdbxError).\"\"\"\n self._appendToLog([msg])\n if self._raiseExceptions:\n raise PdbxError(msg)\n else:\n logger.error(msg)\n\n def _readLogRecords(self):\n \"\"\"Return the contents of the current log file as list of strings.\"\"\"\n diagL = []\n try:\n with open(self.__logFilePath, \"r\") as ifh:\n for line in ifh:\n diagL.append(line[:-1])\n except Exception as e:\n msg = \"No logfile found %s (%s)\" % (self.__logFilePath, str(e))\n diagL.append(msg)\n logger.debug(msg)\n\n return diagL\n\n def __getDiscriminator(self):\n \"\"\"Internal method returning a string which can discriminate among default file names -\"\"\"\n return str(time.time() * 10000).replace(\".\", \"_\")\n\n def _chooseTemporaryPath(self, filePath, outDirPath=None):\n \"\"\"Select a path for temporary files in the priority order\n outDirpath, directory containing the input filePath, current working directory,\n dynamically created temporary directory.\n\n These choices harmonize various legacy api behaviors.\n \"\"\"\n if outDirPath:\n return outDirPath\n #\n for oPath in [os.path.dirname(filePath), \".\", tempfile.gettempdir()]:\n if os.access(oPath, os.W_OK):\n return oPath\n\n def _getDefaultFileName(self, filePath, fileType=\"cif-parser\", fileExt=\"log\", outDirPath=None, verify=True):\n \"\"\"Return default file path for the target input file subject to input attributes and the output path.\"\"\"\n returnFilePath = None\n try:\n _, fn = os.path.split(filePath)\n bn, _ = os.path.splitext(fn)\n #\n ft = fileType if fileType else \"temp\"\n fex = fileExt if fileExt else \"tmp\"\n #\n sf = \"_\" + ft + \"_P\" + self.__getDiscriminator() + \".\" + fex\n #\n # pth = outDirPath if outDirPath else '.'\n pth = self._chooseTemporaryPath(filePath, outDirPath=outDirPath)\n #\n if verify:\n # test if pth is actually writable ? Throw exception otherwise -\n #\n testfile = tempfile.TemporaryFile(dir=pth)\n testfile.close()\n #\n returnFilePath = os.path.join(pth, bn + sf)\n except Exception as e:\n if self._raiseExceptions:\n raise e\n else:\n logger.error(\"Failed creating default filename for %s type %s with %s\", filePath, fileType, str(e))\n\n return returnFilePath\n\n def _fileExists(self, filePath):\n \"\"\"Verify that input file path exists and is readable.\"\"\"\n try:\n if not os.access(filePath, os.R_OK):\n msg = \"Missing file %r\" % filePath\n self._appendToLog([msg])\n logger.error(msg)\n #\n if self._raiseExceptions:\n raise PdbxError(msg)\n return False\n else:\n logger.debug(\"Reading from file path %s\", filePath)\n return True\n except Exception as e:\n msg = \"File check error for %r with %s \" % (filePath, str(e))\n self._appendToLog([msg])\n if self._raiseExceptions:\n raise PdbxError(msg)\n else:\n logger.error(msg)\n return False\n\n def _cleanupFile(self, test, filePath):\n \"\"\"Remove the input file path subject to the input test condition.\"\"\"\n try:\n if test:\n os.remove(filePath)\n except Exception:\n pass\n\n def _toAscii(self, inputFilePath, outputFilePath, chunkSize=5000, encodingErrors=\"ignore\", readEncodingErrors=\"ignore\"):\n \"\"\"Encode input file to Ascii and write this to the target output file. Handle encoding\n errors according to the input settting ('ignore', 'escape', 'xmlcharrefreplace').\n \"\"\"\n try:\n startTime = time.time()\n chunk = []\n with io.open(inputFilePath, \"r\", encoding=\"utf-8\", errors=readEncodingErrors) as ifh, io.open(outputFilePath, \"w\", encoding=\"ascii\") as ofh:\n for line in ifh:\n # chunk.append(line.encode('ascii', 'xmlcharrefreplace').decode('ascii'))\n chunk.append(line.encode(\"ascii\", encodingErrors).decode(\"ascii\"))\n if len(chunk) == chunkSize:\n ofh.writelines(chunk)\n chunk = []\n ofh.writelines(chunk)\n if self._timing:\n stepTime1 = time.time()\n logger.info(\"Timing text file %s encoded to as ascii in %.4f seconds\", inputFilePath, stepTime1 - startTime)\n return True\n except Exception as e:\n msg = \"Failing text ascii encoding for %s with %s\" % (inputFilePath, str(e))\n self._appendToLog([msg])\n logger.error(msg)\n if self._raiseExceptions:\n raise PdbxError(msg)\n #\n return False\n\n def _uncompress(self, inputFilePath, outputDir):\n \"\"\"Uncompress the input file if the path name has a recognized compression type file extension.file\n\n Return the file name of the uncompressed file (in outDir) or the original input file path.\n\n \"\"\"\n try:\n startTime = time.time()\n _, fn = os.path.split(inputFilePath)\n bn, _ = os.path.splitext(fn)\n outputFilePath = os.path.join(outputDir, bn)\n if inputFilePath.endswith(\".gz\"):\n with gzip.open(inputFilePath, mode=\"rb\") as inpF:\n with io.open(outputFilePath, \"wb\") as outF:\n shutil.copyfileobj(inpF, outF)\n elif inputFilePath.endswith(\".bz2\"):\n with bz2.open(inputFilePath, mode=\"rb\") as inpF:\n with io.open(outputFilePath, \"wb\") as outF:\n shutil.copyfileobj(inpF, outF)\n # elif inputFilePath.endswith(\".xz\"):\n # with lzma.open(inputFilePath, mode=\"rb\") as inpF:\n # with io.open(outputFilePath, \"wb\") as outF:\n # shutil.copyfileobj(inpF, outF)\n elif inputFilePath.endswith(\".zip\"):\n with zipfile.ZipFile(inputFilePath, mode=\"rb\") as inpF:\n with io.open(outputFilePath, \"wb\") as outF:\n shutil.copyfileobj(inpF, outF)\n else:\n outputFilePath = inputFilePath\n if self._timing:\n stepTime1 = time.time()\n logger.info(\"Timing text file %s uncompressed in %.4f seconds\", inputFilePath, stepTime1 - startTime)\n #\n except Exception as e:\n msg = \"Failing uncompress for file %s with %s\" % (inputFilePath, str(e))\n self._appendToLog([msg])\n logger.exception(msg)\n if self._raiseExceptions:\n raise PdbxError(msg)\n\n logger.debug(\"Returning file path %r\", outputFilePath)\n return outputFilePath\n
"},{"location":"api_reference/IoAdapterBase/#mmcif.io.IoAdapterBase.IoAdapterBase.__init__","title":"__init__(self, *args, **kwargs)
special
","text":"General options controlling I/O method operations:
Parameters:
Name Type Description Default raiseExceptions
bool
Flag to indicate that API errors should generate exceptions (True) or catch and log errors (default=False)
required maxInputLineLength
int
Default maximum input line length (default=4096)
required useCharRefs
bool
Replace non-ascii characters with XML Character References (default=True)
required readEncodingErrors
str
treatment of encoding errors at read time (default='ignore')
required timing
bool
log timing details for parsing and processing steps (default=False)
required verbose
bool,optional
log verbose output from wrapped libraries
required Source code in mmcif/io/IoAdapterBase.py
def __init__(self, *args, **kwargs):\n \"\"\"General options controlling I/O method operations:\n\n Args:\n raiseExceptions (bool, optional): Flag to indicate that API errors should generate exceptions (True) or catch and log errors (default=False)\n maxInputLineLength (int, optional): Default maximum input line length (default=4096)\n useCharRefs (bool, optional): Replace non-ascii characters with XML Character References (default=True)\n readEncodingErrors (str, optional): treatment of encoding errors at read time (default='ignore')\n timing (bool, optional): log timing details for parsing and processing steps (default=False)\n verbose (bool,optional): log verbose output from wrapped libraries\n\n \"\"\"\n _ = args\n self._raiseExceptions = kwargs.get(\"raiseExceptions\", False)\n self._maxInputLineLength = kwargs.get(\"maxInputLineLength\", 4096)\n self._useCharRefs = kwargs.get(\"useCharRefs\", True)\n self.__logFilePath = None\n self._debug = kwargs.get(\"debug\", False)\n self._timing = kwargs.get(\"timing\", False)\n self._verbose = kwargs.get(\"verbose\", True)\n self._readEncodingErrors = kwargs.get(\"readEncodingErrors\", \"ignore\")\n
"},{"location":"api_reference/IoAdapterBase/#mmcif.io.IoAdapterBase.IoAdapterBase.getReadDiags","title":"getReadDiags(self)
","text":"Return any diagnostics from the last read operation. (abstract)
Source code in mmcif/io/IoAdapterBase.py
def getReadDiags(self):\n \"\"\"Return any diagnostics from the last read operation. (abstract)\"\"\"\n raise NotImplementedError(\"To be implemented in subclass\")\n
"},{"location":"api_reference/IoAdapterBase/#mmcif.io.IoAdapterBase.IoAdapterBase.readFile","title":"readFile(self, *args, **kwargs)
","text":"Read file method. (abstract)
Args: inputFilePath (string): Input file path/uri kw: optional key-value arguments
Returns:
Type Description list of DataContainer Objects
list of data or definition container objects
Source code in mmcif/io/IoAdapterBase.py
def readFile(self, *args, **kwargs):\n \"\"\"Read file method. (abstract)\n\n Args:\n inputFilePath (string): Input file path/uri\n kw: optional key-value arguments\n\n Returns:\n list of DataContainer Objects: list of data or definition container objects\n \"\"\"\n raise NotImplementedError(\"To be implemented in subclass\")\n
"},{"location":"api_reference/IoAdapterBase/#mmcif.io.IoAdapterBase.IoAdapterBase.writeFile","title":"writeFile(self, outputFilePath, containerList, **kwargs)
","text":"Write file method - (abstract)
Parameters:
Name Type Description Default outputFilePath
string
output file path
required containerList
list of DataContainer objects
list of data or definition containers objects for output
required Returns:
Type Description bool
Completion status
Source code in mmcif/io/IoAdapterBase.py
def writeFile(self, outputFilePath, containerList, **kwargs):\n \"\"\"Write file method - (abstract)\n\n Args:\n outputFilePath (string): output file path\n containerList (list of DataContainer objects): list of data or definition containers objects for output\n\n Returns:\n bool: Completion status\n \"\"\"\n raise NotImplementedError(\"To be implemented in subclass\")\n
"},{"location":"api_reference/IoAdapterCore/","title":"IoAdapterCore","text":"Adapter between Python mmCIF API and Pybind11 wrappers for the PDB C++ Core mmCIF Library.
Source code in mmcif/io/IoAdapterCore.py
class IoAdapterCore(IoAdapterBase):\n \"\"\"Adapter between Python mmCIF API and Pybind11 wrappers for the PDB C++ Core mmCIF Library.\"\"\"\n\n # pylint: disable=arguments-differ\n def readFile(\n self,\n inputFilePath,\n enforceAscii=True,\n selectList=None,\n excludeFlag=False,\n logFilePath=None,\n outDirPath=None,\n cleanUp=True,\n fmt=\"mmcif\",\n **kwargs\n ):\n \"\"\"Parse the data blocks in the input mmCIF format data file into list of DataContainers(). The data category content within each data block\n is stored a collection of DataCategory objects within each DataContainer.\n\n Args:\n inputFilePath (string): Input file path\n enforceAscii (bool, optional): Flag to requiring pre-filtering operation to convert input file to ASCII encoding. See encoding error options.\n selectList (List, optional): List of data category names to be extracted or excluded from the input file (default: select/extract)\n excludeFlag (bool, optional): Flag to indicate selectList should be treated as an exclusion list\n logFilePath (string, optional): Log file path (if not provided this will be derived from the input file.)\n outDirPath (string, optional): Path for translated/reencoded files and default logfiles.\n cleanUp (bool, optional): Flag to automatically remove logs and temporary files on exit.\n fmt (string, optional): Format of input file (currently only supports \"mmcif\"). Defaults to \"mmcif\".\n\n **kwargs: Placeholder for missing keyword arguments.\n\n Returns:\n List of DataContainers: Contents of input file parsed into a list of DataContainer objects.\n \"\"\"\n if kwargs:\n logger.warning(\"Unsupported keyword arguments %s\", kwargs.keys())\n asciiFilePath = None\n filePath = str(inputFilePath)\n # oPath = outDirPath if outDirPath else '.'\n oPath = self._chooseTemporaryPath(inputFilePath, outDirPath=outDirPath)\n containerL = []\n try:\n #\n lPath = logFilePath\n if not lPath:\n lPath = self._getDefaultFileName(filePath, fileType=\"cif-parser-log\", outDirPath=oPath)\n #\n self._setLogFilePath(lPath)\n #\n if not self._fileExists(filePath):\n return []\n #\n fmt = fmt.lower()\n #\n if fmt == \"mmcif\":\n filePath = self._uncompress(filePath, oPath)\n tPath = filePath\n if enforceAscii:\n asciiFilePath = self._getDefaultFileName(filePath, fileType=\"cif-parser-ascii\", fileExt=\"cif\", outDirPath=oPath)\n encodingErrors = \"xmlcharrefreplace\" if self._useCharRefs else \"ignore\"\n logger.debug(\"Filtering input file to %s using encoding errors as %s\", asciiFilePath, encodingErrors)\n ok = self._toAscii(filePath, asciiFilePath, chunkSize=5000, encodingErrors=encodingErrors, readEncodingErrors=self._readEncodingErrors)\n if ok:\n tPath = asciiFilePath\n #\n readDef = None\n if selectList is not None and selectList:\n readDef = self.__getSelectionDef(selectList, excludeFlag)\n #\n containerL, _ = self.__readData(tPath, readDef=readDef, cleanUp=cleanUp, logFilePath=lPath, maxLineLength=self._maxInputLineLength)\n #\n if cleanUp:\n self._cleanupFile(asciiFilePath, asciiFilePath)\n self._cleanupFile(filePath != str(inputFilePath), filePath)\n self._setContainerProperties(containerL, locator=str(inputFilePath), load_date=self._getTimeStamp(), uid=uuid.uuid4().hex)\n #\n else:\n logger.error(\"Unsupported fmt %r. Currently only 'mmcif' is supported by IoAdapterCore. For 'bcif', use IoAdapterPy instead.\", fmt)\n #\n except (PdbxError, PdbxSyntaxError) as ex:\n self._cleanupFile(asciiFilePath and cleanUp, asciiFilePath)\n if self._raiseExceptions:\n raise_from(ex, None)\n # raise ex from None\n except Exception as e:\n self._cleanupFile(asciiFilePath and cleanUp, asciiFilePath)\n msg = \"Failing read for %s with %s\" % (filePath, str(e))\n self._logError(msg)\n\n return containerL\n\n def getReadDiags(self):\n \"\"\"Recover the diagnostics for the previous readFile() operation.readFile\n\n Returns:\n list of strings: List of parsing and processing diagnostics from last readFile() operation\n \"\"\"\n return self._readLogRecords()\n\n def __getSelectionDef(self, selectList, excludeFlag):\n \"\"\"Internal method to package selection/exclusion list for the C++ parser library.\n\n Returns:\n CifFileReadDef() object: object prepared for parsing library\n \"\"\"\n try:\n readDef = CifFileReadDef()\n if excludeFlag:\n readDef.SetCategoryList(selectList, PdbxType.D)\n else:\n readDef.SetCategoryList(selectList, PdbxType.A)\n return readDef\n except Exception as e:\n msg = \"Failing read selection with %s\" % str(e)\n self._logError(msg)\n return None\n\n def __processReadLogFile(self, inputFilePath):\n \"\"\"Internal method to process logfiles and either log errors or raise exceptions (See: Class PdbxExceptions).\n The behavior is controlled by the class attribute _raiseExcetions.\n\n Returns:\n list of strings: List of records in the input log file\n \"\"\"\n diagL = self._readLogRecords()\n #\n if diagL:\n numErrors = 0\n numSyntaxErrors = 0\n numWarnings = 0\n for diag in diagL:\n if \"ERROR\" in diag:\n numErrors += 1\n if \"WARN\" in diag:\n numWarnings += 1\n if \"syntax\" in diag.lower():\n numSyntaxErrors += 1\n #\n logger.debug(\"%s syntax errors %d warnings %d all errors %d\", inputFilePath, numSyntaxErrors, numWarnings, numErrors)\n #\n if numSyntaxErrors and self._raiseExceptions:\n raise PdbxSyntaxError(\"%s syntax errors %d all errors %d\" % (inputFilePath, numSyntaxErrors, numErrors))\n elif numErrors and self._raiseExceptions:\n raise PdbxError(\"%s error count is %d\" % (inputFilePath, numErrors))\n elif numErrors:\n logger.error(\"%s syntax errors %d all errors %d\", inputFilePath, numSyntaxErrors, numErrors)\n if numWarnings:\n logger.warning(\"%s warnings %d\", inputFilePath, numWarnings)\n\n return diagL\n\n def __processContent(self, cifFileObj):\n \"\"\"Internal method to transfer parsed data from the wrapped input C++ CifFile object into\n the list of Python DataContainer objects.\n\n Args:\n cifFileObj (wrapped CifFile object): Wrapped input C++ CifFile object\n\n Returns:\n list of DataContainer objects: List of Python DataContainer objects\n\n \"\"\"\n containerList = []\n containerNameList = []\n try:\n # ----- Repackage the data content ----\n #\n containerList = []\n containerNameList = []\n containerNameList = list(cifFileObj.GetBlockNames(containerNameList))\n for containerName in containerNameList:\n #\n aContainer = DataContainer(containerName)\n #\n block = cifFileObj.GetBlock(containerName)\n tableNameList = []\n tableNameList = list(block.GetTableNames(tableNameList))\n\n for tableName in tableNameList:\n table = block.GetTable(tableName)\n attributeNameList = list(table.GetColumnNames())\n numRows = table.GetNumRows()\n rowList = []\n for iRow in range(0, numRows):\n row = table.GetRow(iRow)\n # row = table.GetRow(iRow).decode('unicode_escape').encode('utf-8')\n # row = [p.encode('ascii', 'xmlcharrefreplace') for p in table.GetRow(iRow)]\n rowList.append(list(row))\n aCategory = DataCategory(tableName, attributeNameList, rowList, copyInputData=False, raiseExceptions=self._raiseExceptions)\n aContainer.append(aCategory)\n containerList.append(aContainer)\n except Exception as e:\n msg = \"Failing packaging with %s\" % str(e)\n self._logError(msg)\n\n return containerList\n\n def __readData(self, inputFilePath, readDef=None, maxLineLength=1024, logFilePath=None, cleanUp=False):\n \"\"\"Internal method to read input file and return data as a list of DataContainer objects.\n readDef optionally contains a selection of data categories to be returned. Diagnostics\n will be written to logFilePath (persisted if cleanuUp=False).\n\n Args:\n inputFilePath (string): input file path\n readDef (CifFileReadDef object, optional): wrapped CifFileReadDef() object\n maxLineLength (int, optional): Maximum supported line length on input\n logFilePath (string, optional): Log file path\n cleanUp (bool, optional): Flag to remove temporary files on exit\n\n Returns:\n Tuple of lists : DataContainer List, Diagnostics (string) List\n\n \"\"\"\n #\n startTime = time.time()\n containerList = []\n diagL = []\n try:\n if readDef:\n cifFileObj = ParseCifSelective(inputFilePath, readDef, verbose=self._verbose, intCaseSense=0, maxLineLength=maxLineLength, nullValue=\"?\", parseLogFileName=logFilePath)\n else:\n cifFileObj = ParseCifSimple(inputFilePath, verbose=self._verbose, intCaseSense=0, maxLineLength=maxLineLength, nullValue=\"?\", parseLogFileName=logFilePath)\n #\n # --- Process/Handle read errors ----\n #\n diagL = self.__processReadLogFile(inputFilePath)\n logger.debug(\"Diagnostic count %d values %r\", len(diagL), diagL)\n #\n if self._timing:\n stepTime1 = time.time()\n logger.info(\"Timing parsed %r in %.4f seconds\", inputFilePath, stepTime1 - startTime)\n #\n containerList = self.__processContent(cifFileObj)\n #\n self._cleanupFile(cleanUp, logFilePath)\n if self._timing:\n stepTime2 = time.time()\n logger.info(\"Timing api load in %.4f seconds read time %.4f seconds\", stepTime2 - stepTime1, stepTime2 - startTime)\n #\n return containerList, diagL\n except (PdbxError, PdbxSyntaxError) as ex:\n self._cleanupFile(cleanUp, logFilePath)\n if self._raiseExceptions:\n raise_from(ex, None)\n except Exception as e:\n self._cleanupFile(cleanUp, logFilePath)\n msg = \"Failing read for %s with %s\" % (inputFilePath, str(e))\n self._logError(msg)\n\n return containerList, diagL\n\n def writeFile(\n self,\n outputFilePath,\n containerList=None,\n doubleQuotingFlag=False,\n maxLineLength=900,\n enforceAscii=True,\n lastInOrder=None,\n selectOrder=None,\n fmt=\"mmcif\",\n **kwargs\n ):\n \"\"\"Write input list of data containers to the specified output file path in mmCIF format.\n\n Args:\n outputFilePath (string): output file path\n containerList (list DataContainer objects, optional):\n maxLineLength (int, optional): Maximum length of output line (content is wrapped beyond this length)\n enforceAscii (bool, optional): Filter output (not implemented - content must be ascii compatible on input)\n lastInOrder (list of category names, optional): Move data categories in this list to end of each data block\n selectOrder (list of category names, optional): Write only data categories on this list.\n fmt (string, optional): Format of input file (currently only supports \"mmcif\"). Defaults to \"mmcif\".\n\n **kwargs: Placeholder for unsupported key value pairs\n\n Returns:\n bool: Completion status\n\n \"\"\"\n _ = enforceAscii\n lastInOrder = lastInOrder if lastInOrder else [\"pdbx_nonpoly_scheme\", \"pdbx_poly_seq_scheme\", \"atom_site\", \"atom_site_anisotrop\"]\n containerL = containerList if containerList else []\n if kwargs:\n logger.warning(\"Unsupported keyword arguments %s\", kwargs.keys())\n try:\n startTime = time.time()\n logger.debug(\"write container length %d\", len(containerL))\n fmt = fmt.lower()\n #\n if fmt == \"mmcif\":\n # (CifFile args: placeholder, verbose: bool, caseSense: Char::eCompareType, maxLineLength: int, nullValue: str)\n cF = CifFile(True, self._verbose, 0, maxLineLength, \"?\")\n for container in containerL:\n containerName = container.getName()\n logger.debug(\"writing container %s\", containerName)\n cF.AddBlock(containerName)\n block = cF.GetBlock(containerName)\n #\n # objNameList = container.getObjNameList()\n # logger.debug(\"write category length %d\\n\" % len(objNameList))\n #\n # Reorder/Filter - container object list-\n objNameList = container.filterObjectNameList(lastInOrder=lastInOrder, selectOrder=selectOrder)\n logger.debug(\"write category names %r\", objNameList)\n #\n for objName in objNameList:\n name, attributeNameList, rowList = container.getObj(objName).get()\n table = block.AddTable(name)\n for attributeName in attributeNameList:\n table.AddColumn(attributeName)\n try:\n rLen = len(attributeNameList)\n for ii, row in enumerate(rowList):\n table.AddRow()\n table.FillRow(ii, [str(row[jj]) if row[jj] is not None else \"?\" for jj in range(0, rLen)])\n except Exception as e:\n logger.error(\"Exception for %s preparing category %r (%d) attributes %r for writing %s\", outputFilePath, name, len(rowList), attributeNameList, str(e))\n #\n block.WriteTable(table)\n #\n if self._timing:\n stepTime1 = time.time()\n logger.info(\"Timing %d container(s) api loaded in %.4f seconds\", len(containerL), stepTime1 - startTime)\n if self._debug:\n self.__dumpBlocks(cF)\n if doubleQuotingFlag:\n cF.SetQuoting(cF.eDOUBLE)\n #\n cF.Write(str(outputFilePath))\n #\n else:\n logger.error(\"Unsupported fmt %r. Currently only 'mmcif' is supported by IoAdapterCore. For 'bcif', use IoAdapterPy instead.\", fmt)\n return False\n #\n if self._timing:\n stepTime2 = time.time()\n logger.info(\"Timing %d container(s) written in %.4f seconds total time %.4f\", len(containerList), stepTime2 - stepTime1, stepTime2 - startTime)\n return True\n\n except Exception as e:\n msg = \"Write failing for file %s with %s\" % (outputFilePath, str(e))\n self._logError(msg)\n return False\n\n def __dumpBlocks(self, cf):\n \"\"\"Internal method to log the contents of the input wrapped CifFile object.\n\n Args:\n cf (CifFile object): wrapped CifFile object.\n \"\"\"\n try:\n logger.info(\"cif file %r\", cf)\n blockNameList = []\n blockNameList = cf.GetBlockNames(blockNameList)\n #\n logger.info(\" block name list %r\", repr(blockNameList))\n for blockName in blockNameList:\n #\n block = cf.GetBlock(blockName)\n tableNameList = []\n tableNameList = list(block.GetTableNames(tableNameList))\n logger.info(\"tables name list %r\", repr(tableNameList))\n for tableName in tableNameList:\n logger.info(\"table name %r\", tableName)\n ok = block.IsTablePresent(tableName)\n logger.info(\"table present %r\", ok)\n table = block.GetTable(tableName)\n\n attributeNameList = list(table.GetColumnNames())\n logger.info(\"Attribute name list %r\", repr(attributeNameList))\n numRows = table.GetNumRows()\n logger.info(\"row length %r\", numRows)\n for iRow in range(0, numRows):\n row = table.GetRow(iRow)\n logger.info(\"Attribute name list %r\", row)\n except Exception as e:\n logger.exception(\"dump failing with %s\", str(e))\n
"},{"location":"api_reference/IoAdapterCore/#mmcif.io.IoAdapterCore.IoAdapterCore.getReadDiags","title":"getReadDiags(self)
","text":"Recover the diagnostics for the previous readFile() operation.readFile
Returns:
Type Description list of strings
List of parsing and processing diagnostics from last readFile() operation
Source code in mmcif/io/IoAdapterCore.py
def getReadDiags(self):\n \"\"\"Recover the diagnostics for the previous readFile() operation.readFile\n\n Returns:\n list of strings: List of parsing and processing diagnostics from last readFile() operation\n \"\"\"\n return self._readLogRecords()\n
"},{"location":"api_reference/IoAdapterCore/#mmcif.io.IoAdapterCore.IoAdapterCore.readFile","title":"readFile(self, inputFilePath, enforceAscii=True, selectList=None, excludeFlag=False, logFilePath=None, outDirPath=None, cleanUp=True, fmt='mmcif', **kwargs)
","text":"Parse the data blocks in the input mmCIF format data file into list of DataContainers(). The data category content within each data block is stored a collection of DataCategory objects within each DataContainer.
Parameters:
Name Type Description Default inputFilePath
string
Input file path
required enforceAscii
bool
Flag to requiring pre-filtering operation to convert input file to ASCII encoding. See encoding error options.
True
selectList
List
List of data category names to be extracted or excluded from the input file (default: select/extract)
None
excludeFlag
bool
Flag to indicate selectList should be treated as an exclusion list
False
logFilePath
string
Log file path (if not provided this will be derived from the input file.)
None
outDirPath
string
Path for translated/reencoded files and default logfiles.
None
cleanUp
bool
Flag to automatically remove logs and temporary files on exit.
True
fmt
string
Format of input file (currently only supports \"mmcif\"). Defaults to \"mmcif\".
'mmcif'
**kwargs
Placeholder for missing keyword arguments.
{}
Returns:
Type Description List of DataContainers
Contents of input file parsed into a list of DataContainer objects.
Source code in mmcif/io/IoAdapterCore.py
def readFile(\n self,\n inputFilePath,\n enforceAscii=True,\n selectList=None,\n excludeFlag=False,\n logFilePath=None,\n outDirPath=None,\n cleanUp=True,\n fmt=\"mmcif\",\n **kwargs\n):\n \"\"\"Parse the data blocks in the input mmCIF format data file into list of DataContainers(). The data category content within each data block\n is stored a collection of DataCategory objects within each DataContainer.\n\n Args:\n inputFilePath (string): Input file path\n enforceAscii (bool, optional): Flag to requiring pre-filtering operation to convert input file to ASCII encoding. See encoding error options.\n selectList (List, optional): List of data category names to be extracted or excluded from the input file (default: select/extract)\n excludeFlag (bool, optional): Flag to indicate selectList should be treated as an exclusion list\n logFilePath (string, optional): Log file path (if not provided this will be derived from the input file.)\n outDirPath (string, optional): Path for translated/reencoded files and default logfiles.\n cleanUp (bool, optional): Flag to automatically remove logs and temporary files on exit.\n fmt (string, optional): Format of input file (currently only supports \"mmcif\"). Defaults to \"mmcif\".\n\n **kwargs: Placeholder for missing keyword arguments.\n\n Returns:\n List of DataContainers: Contents of input file parsed into a list of DataContainer objects.\n \"\"\"\n if kwargs:\n logger.warning(\"Unsupported keyword arguments %s\", kwargs.keys())\n asciiFilePath = None\n filePath = str(inputFilePath)\n # oPath = outDirPath if outDirPath else '.'\n oPath = self._chooseTemporaryPath(inputFilePath, outDirPath=outDirPath)\n containerL = []\n try:\n #\n lPath = logFilePath\n if not lPath:\n lPath = self._getDefaultFileName(filePath, fileType=\"cif-parser-log\", outDirPath=oPath)\n #\n self._setLogFilePath(lPath)\n #\n if not self._fileExists(filePath):\n return []\n #\n fmt = fmt.lower()\n #\n if fmt == \"mmcif\":\n filePath = self._uncompress(filePath, oPath)\n tPath = filePath\n if enforceAscii:\n asciiFilePath = self._getDefaultFileName(filePath, fileType=\"cif-parser-ascii\", fileExt=\"cif\", outDirPath=oPath)\n encodingErrors = \"xmlcharrefreplace\" if self._useCharRefs else \"ignore\"\n logger.debug(\"Filtering input file to %s using encoding errors as %s\", asciiFilePath, encodingErrors)\n ok = self._toAscii(filePath, asciiFilePath, chunkSize=5000, encodingErrors=encodingErrors, readEncodingErrors=self._readEncodingErrors)\n if ok:\n tPath = asciiFilePath\n #\n readDef = None\n if selectList is not None and selectList:\n readDef = self.__getSelectionDef(selectList, excludeFlag)\n #\n containerL, _ = self.__readData(tPath, readDef=readDef, cleanUp=cleanUp, logFilePath=lPath, maxLineLength=self._maxInputLineLength)\n #\n if cleanUp:\n self._cleanupFile(asciiFilePath, asciiFilePath)\n self._cleanupFile(filePath != str(inputFilePath), filePath)\n self._setContainerProperties(containerL, locator=str(inputFilePath), load_date=self._getTimeStamp(), uid=uuid.uuid4().hex)\n #\n else:\n logger.error(\"Unsupported fmt %r. Currently only 'mmcif' is supported by IoAdapterCore. For 'bcif', use IoAdapterPy instead.\", fmt)\n #\n except (PdbxError, PdbxSyntaxError) as ex:\n self._cleanupFile(asciiFilePath and cleanUp, asciiFilePath)\n if self._raiseExceptions:\n raise_from(ex, None)\n # raise ex from None\n except Exception as e:\n self._cleanupFile(asciiFilePath and cleanUp, asciiFilePath)\n msg = \"Failing read for %s with %s\" % (filePath, str(e))\n self._logError(msg)\n\n return containerL\n
"},{"location":"api_reference/IoAdapterCore/#mmcif.io.IoAdapterCore.IoAdapterCore.writeFile","title":"writeFile(self, outputFilePath, containerList=None, doubleQuotingFlag=False, maxLineLength=900, enforceAscii=True, lastInOrder=None, selectOrder=None, fmt='mmcif', **kwargs)
","text":"Write input list of data containers to the specified output file path in mmCIF format.
Parameters:
Name Type Description Default outputFilePath
string
output file path
required containerList
list DataContainer objects
None
maxLineLength
int
Maximum length of output line (content is wrapped beyond this length)
900
enforceAscii
bool
Filter output (not implemented - content must be ascii compatible on input)
True
lastInOrder
list of category names
Move data categories in this list to end of each data block
None
selectOrder
list of category names
Write only data categories on this list.
None
fmt
string
Format of input file (currently only supports \"mmcif\"). Defaults to \"mmcif\".
'mmcif'
**kwargs
Placeholder for unsupported key value pairs
{}
Returns:
Type Description bool
Completion status
Source code in mmcif/io/IoAdapterCore.py
def writeFile(\n self,\n outputFilePath,\n containerList=None,\n doubleQuotingFlag=False,\n maxLineLength=900,\n enforceAscii=True,\n lastInOrder=None,\n selectOrder=None,\n fmt=\"mmcif\",\n **kwargs\n):\n \"\"\"Write input list of data containers to the specified output file path in mmCIF format.\n\n Args:\n outputFilePath (string): output file path\n containerList (list DataContainer objects, optional):\n maxLineLength (int, optional): Maximum length of output line (content is wrapped beyond this length)\n enforceAscii (bool, optional): Filter output (not implemented - content must be ascii compatible on input)\n lastInOrder (list of category names, optional): Move data categories in this list to end of each data block\n selectOrder (list of category names, optional): Write only data categories on this list.\n fmt (string, optional): Format of input file (currently only supports \"mmcif\"). Defaults to \"mmcif\".\n\n **kwargs: Placeholder for unsupported key value pairs\n\n Returns:\n bool: Completion status\n\n \"\"\"\n _ = enforceAscii\n lastInOrder = lastInOrder if lastInOrder else [\"pdbx_nonpoly_scheme\", \"pdbx_poly_seq_scheme\", \"atom_site\", \"atom_site_anisotrop\"]\n containerL = containerList if containerList else []\n if kwargs:\n logger.warning(\"Unsupported keyword arguments %s\", kwargs.keys())\n try:\n startTime = time.time()\n logger.debug(\"write container length %d\", len(containerL))\n fmt = fmt.lower()\n #\n if fmt == \"mmcif\":\n # (CifFile args: placeholder, verbose: bool, caseSense: Char::eCompareType, maxLineLength: int, nullValue: str)\n cF = CifFile(True, self._verbose, 0, maxLineLength, \"?\")\n for container in containerL:\n containerName = container.getName()\n logger.debug(\"writing container %s\", containerName)\n cF.AddBlock(containerName)\n block = cF.GetBlock(containerName)\n #\n # objNameList = container.getObjNameList()\n # logger.debug(\"write category length %d\\n\" % len(objNameList))\n #\n # Reorder/Filter - container object list-\n objNameList = container.filterObjectNameList(lastInOrder=lastInOrder, selectOrder=selectOrder)\n logger.debug(\"write category names %r\", objNameList)\n #\n for objName in objNameList:\n name, attributeNameList, rowList = container.getObj(objName).get()\n table = block.AddTable(name)\n for attributeName in attributeNameList:\n table.AddColumn(attributeName)\n try:\n rLen = len(attributeNameList)\n for ii, row in enumerate(rowList):\n table.AddRow()\n table.FillRow(ii, [str(row[jj]) if row[jj] is not None else \"?\" for jj in range(0, rLen)])\n except Exception as e:\n logger.error(\"Exception for %s preparing category %r (%d) attributes %r for writing %s\", outputFilePath, name, len(rowList), attributeNameList, str(e))\n #\n block.WriteTable(table)\n #\n if self._timing:\n stepTime1 = time.time()\n logger.info(\"Timing %d container(s) api loaded in %.4f seconds\", len(containerL), stepTime1 - startTime)\n if self._debug:\n self.__dumpBlocks(cF)\n if doubleQuotingFlag:\n cF.SetQuoting(cF.eDOUBLE)\n #\n cF.Write(str(outputFilePath))\n #\n else:\n logger.error(\"Unsupported fmt %r. Currently only 'mmcif' is supported by IoAdapterCore. For 'bcif', use IoAdapterPy instead.\", fmt)\n return False\n #\n if self._timing:\n stepTime2 = time.time()\n logger.info(\"Timing %d container(s) written in %.4f seconds total time %.4f\", len(containerList), stepTime2 - stepTime1, stepTime2 - startTime)\n return True\n\n except Exception as e:\n msg = \"Write failing for file %s with %s\" % (outputFilePath, str(e))\n self._logError(msg)\n return False\n
"},{"location":"api_reference/IoAdapterPy/","title":"IoAdapterPy","text":"Python implementation of IoAdapterBase class providing essential read and write methods for mmCIF and BCIF data files -
Source code in mmcif/io/IoAdapterPy.py
class IoAdapterPy(IoAdapterBase):\n \"\"\"Python implementation of IoAdapterBase class providing essential read and write methods for mmCIF and BCIF data files -\"\"\"\n\n # pylint: disable=arguments-differ\n def readFile(\n self,\n inputFilePath,\n enforceAscii=False,\n selectList=None,\n excludeFlag=False,\n logFilePath=None,\n outDirPath=None,\n cleanUp=True,\n fmt=\"mmcif\",\n timeout=None,\n storeStringsAsBytes=False,\n defaultStringEncoding=\"utf-8\",\n **kwargs\n ):\n \"\"\"Parse the data blocks in the input mmCIF or BCIF format data file into list of data or definition containers. The data category\n content within each data block is stored a collection of DataCategory objects within each container.\n\n Args:\n inputFilePath (string): Input file path\n enforceAscii (bool, optional): Flag to require ASCII encoding when reading in 'mmcif' file. See encoding error options. Defaults to False.\n selectList (List, optional): List of data category names to be extracted or excluded from the input file (default: select/extract)\n excludeFlag (bool, optional): Flag to indicate selectList should be treated as an exclusion list\n logFilePath (string, optional): Log file path (if not provided this will be derived from the input file.)\n outDirPath (string, optional): Path for translated/re-encoded files and default logfiles.\n cleanUp (bool, optional): Flag to automatically remove logs and temporary files on exit.\n fmt (string, optional): Format of input file (either \"mmcif\" or \"bcif\"). Defaults to \"mmcif\".\n timeout (float, optional): Timeout in seconds for fetching data from remote urls\n\n # BCIF-specific args:\n storeStringsAsBytes (bool, optional): Strings are stored as lists of bytes (for BCIF files only). Defaults to False.\n defaultStringEncoding (str, optional): Default encoding for string data (for BCIF files only). Defaults to \"utf-8\".\n\n **kwargs: Placeholder for missing keyword arguments.\n\n Returns:\n List of DataContainers: Contents of input file parsed into a list of DataContainer objects.\n\n \"\"\"\n if kwargs:\n logger.warning(\"Unsupported keyword arguments %s\", kwargs.keys())\n filePath = str(inputFilePath)\n # oPath = outDirPath if outDirPath else '.'\n oPath = self._chooseTemporaryPath(inputFilePath, outDirPath=outDirPath)\n containerList = []\n if enforceAscii:\n encoding = \"ascii\"\n else:\n encoding = \"utf-8\"\n try:\n #\n lPath = logFilePath\n if not lPath:\n lPath = self._getDefaultFileName(filePath, fileType=\"cif-parser-log\", outDirPath=oPath)\n #\n self._setLogFilePath(lPath)\n # ---\n if self.__isLocal(filePath) and not self._fileExists(filePath):\n return []\n #\n fmt = fmt.lower()\n #\n if sys.version_info[0] > 2: # Check if using Python version higher than 2\n if fmt == \"mmcif\":\n if self.__isLocal(filePath):\n filePath = self._uncompress(filePath, oPath)\n with open(filePath, \"r\", encoding=encoding, errors=self._readEncodingErrors) as ifh:\n pRd = PdbxReader(ifh)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else: # handle files from the internet...\n if filePath.endswith(\".gz\"):\n customHeader = {\"Accept-Encoding\": \"gzip\"}\n with closing(requests.get(filePath, headers=customHeader, timeout=timeout)) as ifh:\n if self._raiseExceptions:\n ifh.raise_for_status()\n gzit = gzip.GzipFile(fileobj=io.BytesIO(ifh.content))\n it = (line.decode(encoding, \"ignore\") for line in gzit)\n pRd = PdbxReader(it)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n with closing(requests.get(filePath, timeout=timeout)) as ifh:\n if self._raiseExceptions:\n ifh.raise_for_status()\n it = (line.decode(encoding, \"ignore\") + \"\\n\" for line in ifh.iter_lines())\n pRd = PdbxReader(it)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n elif fmt == \"bcif\":\n # local vs. remote and gzip business is already done in BinaryCifReader\n bcifRd = BinaryCifReader(storeStringsAsBytes=storeStringsAsBytes, defaultStringEncoding=defaultStringEncoding)\n containerList = bcifRd.deserialize(filePath)\n else:\n logger.error(\"Unsupported fmt %r. Currently only supports 'mmcif' or 'bcif'.\", fmt)\n else:\n logger.warning(\"Support for Python 2 will be deprecated soon. Please use Python 3.\")\n if fmt == \"bcif\":\n logger.error(\"Support for BCIF reading only available in Python 3.\")\n elif fmt == \"mmcif\":\n if self.__isLocal(filePath):\n filePath = self._uncompress(filePath, oPath)\n if enforceAscii:\n with io.open(filePath, \"r\", encoding=encoding, errors=self._readEncodingErrors) as ifh:\n pRd = PdbxReader(ifh)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n with open(filePath, \"r\") as ifh:\n pRd = PdbxReader(ifh)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n if filePath.endswith(\".gz\"):\n customHeader = {\"Accept-Encoding\": \"gzip\"}\n with closing(requests.get(filePath, headers=customHeader, timeout=timeout)) as ifh:\n if self._raiseExceptions:\n ifh.raise_for_status()\n gzit = gzip.GzipFile(fileobj=io.BytesIO(ifh.content))\n it = (line.decode(encoding, \"ignore\") for line in gzit)\n pRd = PdbxReader(it)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n with closing(requests.get(filePath, timeout=timeout)) as ifh:\n if self._raiseExceptions:\n ifh.raise_for_status()\n it = (line.decode(encoding, \"ignore\") + \"\\n\" for line in ifh.iter_lines())\n pRd = PdbxReader(it)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n logger.error(\"Unsupported fmt %r for Python2 installation of mmcif.io.IoAdapterPy. Currently only 'mmcif' is supported. Upgrade to Python3 for 'bcif' support\", fmt)\n\n if cleanUp:\n self._cleanupFile(lPath, lPath)\n self._cleanupFile(filePath != str(inputFilePath), filePath)\n self._setContainerProperties(containerList, locator=str(inputFilePath), load_date=self._getTimeStamp(), uid=uuid.uuid4().hex)\n except (PdbxError, PdbxSyntaxError) as ex:\n msg = \"File %r with %s\" % (filePath, str(ex))\n self._appendToLog([msg])\n self._cleanupFile(lPath and cleanUp, lPath)\n if self._raiseExceptions:\n raise_from(ex, None)\n # raise ex from None\n except Exception as e:\n msg = \"File %r with %s\" % (filePath, str(e))\n self._appendToLog([msg])\n self._cleanupFile(lPath and cleanUp, lPath)\n if self._raiseExceptions:\n raise e\n else:\n logger.error(\"Failing read for %s with %s\", filePath, str(e))\n return containerList\n\n def getReadDiags(self):\n \"\"\"Return diagnostics from last readFile operation. This will NOT be an exhaustive list but\n rather the particular failure that raised a parsing exception.\n \"\"\"\n return self._readLogRecords()\n\n def writeFile(\n self,\n outputFilePath,\n containerList,\n maxLineLength=900,\n enforceAscii=True,\n lastInOrder=None,\n selectOrder=None,\n columnAlignFlag=True,\n useStopTokens=False,\n formattingStep=None,\n fmt=\"mmcif\",\n storeStringsAsBytes=False,\n defaultStringEncoding=\"utf-8\",\n applyTypes=True,\n dictionaryApi=None,\n useStringTypes=False,\n useFloat64=False,\n copyInputData=False,\n **kwargs\n ):\n \"\"\"Write input list of data containers to the specified output file path in mmCIF or BCIF format.\n\n Args:\n outputFilePath (string): output file path\n containerList (list DataContainer objects, optional)\n maxLineLength (int, optional): Maximum length of output line (content is wrapped beyond this length)\n enforceAscii (bool, optional): Enforce ASCII encoding when writing out 'mmcif' file. Defaults to True.\n lastInOrder (list of category names, optional): Move data categories in this list to end of each data block\n selectOrder (list of category names, optional): Write only data categories on this list.\n columnAlignFlag (bool, optional): Format the output in aligned columns (default=True) (Native Python Only)\n useStopTokens (bool, optional): Include terminating 'stop_' tokens at the end of mmCIF categories (loop_'s) (Native Python only)\n formattingStep (int, optional): The number row samples within each category used to estimate maximum column width for data alignment (Native Python only)\n fmt (string, optional): Format of output file (either \"mmcif\" or \"bcif\"). Defaults to \"mmcif\".\n\n # BCIF-specific args:\n storeStringsAsBytes (bool, optional): Strings are stored as lists of bytes (for BCIF files only). Defaults to False.\n defaultStringEncoding (str, optional): Default encoding for string data (for BCIF files only). Defaults to \"utf-8\".\n applyTypes (bool, optional): apply explicit data typing before encoding (for BCIF files only; requires dictionaryApi to be passed too). Defaults to True.\n dictionaryApi (object, optional): DictionaryApi object instance (needed for BCIF files, only when applyTypes is True). Defaults to None.\n useStringTypes (bool, optional): assume all types are string (for BCIF files only). Defaults to False.\n useFloat64 (bool, optional): store floats with 64 bit precision (for BCIF files only). Defaults to False.\n copyInputData (bool, optional): make a new copy input data (for BCIF files only). Defaults to False.\n\n **kwargs: Placeholder for unsupported key value pairs\n\n Returns:\n bool: Completion status\n\n \"\"\"\n lastInOrder = lastInOrder if lastInOrder else [\"pdbx_nonpoly_scheme\", \"pdbx_poly_seq_scheme\", \"atom_site\", \"atom_site_anisotrop\"]\n if kwargs:\n logger.warning(\"Unsupported keyword arguments %s\", kwargs.keys())\n try:\n if enforceAscii:\n encoding = \"ascii\"\n else:\n encoding = \"utf-8\"\n #\n fmt = fmt.lower()\n #\n if sys.version_info[0] > 2: # Check if using Python version higher than 2\n if fmt == \"mmcif\":\n with open(outputFilePath, \"w\", encoding=encoding) as ofh:\n self.__writeFile(\n ofh,\n containerList,\n maxLineLength=maxLineLength,\n columnAlignFlag=columnAlignFlag,\n lastInOrder=lastInOrder,\n selectOrder=selectOrder,\n useStopTokens=useStopTokens,\n formattingStep=formattingStep,\n enforceAscii=enforceAscii,\n cnvCharRefs=self._useCharRefs,\n )\n elif fmt == \"bcif\":\n bcifW = BinaryCifWriter(\n dictionaryApi=dictionaryApi,\n storeStringsAsBytes=storeStringsAsBytes,\n defaultStringEncoding=defaultStringEncoding,\n applyTypes=applyTypes,\n useStringTypes=useStringTypes,\n useFloat64=useFloat64,\n copyInputData=copyInputData,\n )\n bcifW.serialize(outputFilePath, containerList)\n else:\n logger.error(\"Unsupported fmt %r. Currently only supports 'mmcif' or 'bcif'.\", fmt)\n return False\n else:\n logger.warning(\"Support for Python 2 will be deprecated soon. Please use Python 3.\")\n if fmt == \"bcif\":\n logger.error(\"Support for BCIF writing only available in Python 3.\")\n return False\n elif fmt == \"mmcif\":\n if enforceAscii:\n with io.open(outputFilePath, \"w\", encoding=encoding) as ofh:\n self.__writeFile(\n ofh,\n containerList,\n maxLineLength=maxLineLength,\n columnAlignFlag=columnAlignFlag,\n lastInOrder=lastInOrder,\n selectOrder=selectOrder,\n useStopTokens=useStopTokens,\n formattingStep=formattingStep,\n enforceAscii=enforceAscii,\n cnvCharRefs=self._useCharRefs,\n )\n else:\n with open(outputFilePath, \"wb\") as ofh:\n self.__writeFile(\n ofh,\n containerList,\n maxLineLength=maxLineLength,\n columnAlignFlag=columnAlignFlag,\n lastInOrder=lastInOrder,\n selectOrder=selectOrder,\n useStopTokens=useStopTokens,\n formattingStep=formattingStep,\n enforceAscii=enforceAscii,\n cnvCharRefs=self._useCharRefs,\n )\n else:\n logger.error(\"Unsupported fmt %r for Python2 installation of mmcif.io.IoAdapterPy. Currently only 'mmcif' is supported. Upgrade to Python3 for 'bcif' support\", fmt)\n return False\n return True\n except Exception as ex:\n if self._raiseExceptions:\n raise_from(ex, None)\n else:\n logger.exception(\"Failing write for %s with %s\", outputFilePath, str(ex))\n logger.error(\"Failing write for %s with %s\", outputFilePath, str(ex))\n\n return False\n\n def __writeFile(\n self,\n ofh,\n containerList,\n maxLineLength=900,\n columnAlignFlag=True,\n lastInOrder=None,\n selectOrder=None,\n useStopTokens=False,\n formattingStep=None,\n enforceAscii=False,\n cnvCharRefs=False,\n ):\n \"\"\"Internal method mapping arguments to PDBxWriter API.\"\"\"\n #\n pdbxW = PdbxWriter(ofh)\n pdbxW.setUseStopTokens(flag=useStopTokens)\n pdbxW.setMaxLineLength(numChars=maxLineLength)\n pdbxW.setAlignmentFlag(flag=columnAlignFlag)\n pdbxW.setRowPartition(numParts=formattingStep)\n pdbxW.setConvertCharRefs(flag=cnvCharRefs)\n pdbxW.setSetEnforceAscii(enforceAscii)\n pdbxW.write(containerList, lastInOrder=lastInOrder, selectOrder=selectOrder)\n\n def __isLocal(self, locator):\n try:\n locSp = urlsplit(locator)\n return locSp.scheme in [\"\", \"file\"]\n except Exception as e:\n logger.exception(\"For locator %r failing with %s\", locator, str(e))\n return None\n
"},{"location":"api_reference/IoAdapterPy/#mmcif.io.IoAdapterPy.IoAdapterPy.getReadDiags","title":"getReadDiags(self)
","text":"Return diagnostics from last readFile operation. This will NOT be an exhaustive list but rather the particular failure that raised a parsing exception.
Source code in mmcif/io/IoAdapterPy.py
def getReadDiags(self):\n \"\"\"Return diagnostics from last readFile operation. This will NOT be an exhaustive list but\n rather the particular failure that raised a parsing exception.\n \"\"\"\n return self._readLogRecords()\n
"},{"location":"api_reference/IoAdapterPy/#mmcif.io.IoAdapterPy.IoAdapterPy.readFile","title":"readFile(self, inputFilePath, enforceAscii=False, selectList=None, excludeFlag=False, logFilePath=None, outDirPath=None, cleanUp=True, fmt='mmcif', timeout=None, storeStringsAsBytes=False, defaultStringEncoding='utf-8', **kwargs)
","text":"Parse the data blocks in the input mmCIF or BCIF format data file into list of data or definition containers. The data category content within each data block is stored a collection of DataCategory objects within each container.
Parameters:
Name Type Description Default inputFilePath
string
Input file path
required enforceAscii
bool
Flag to require ASCII encoding when reading in 'mmcif' file. See encoding error options. Defaults to False.
False
selectList
List
List of data category names to be extracted or excluded from the input file (default: select/extract)
None
excludeFlag
bool
Flag to indicate selectList should be treated as an exclusion list
False
logFilePath
string
Log file path (if not provided this will be derived from the input file.)
None
outDirPath
string
Path for translated/re-encoded files and default logfiles.
None
cleanUp
bool
Flag to automatically remove logs and temporary files on exit.
True
fmt
string
Format of input file (either \"mmcif\" or \"bcif\"). Defaults to \"mmcif\".
'mmcif'
timeout
float
Timeout in seconds for fetching data from remote urls
None
#
BCIF-specific args
required storeStringsAsBytes
bool
Strings are stored as lists of bytes (for BCIF files only). Defaults to False.
False
defaultStringEncoding
str
Default encoding for string data (for BCIF files only). Defaults to \"utf-8\".
'utf-8'
**kwargs
Placeholder for missing keyword arguments.
{}
Returns:
Type Description List of DataContainers
Contents of input file parsed into a list of DataContainer objects.
Source code in mmcif/io/IoAdapterPy.py
def readFile(\n self,\n inputFilePath,\n enforceAscii=False,\n selectList=None,\n excludeFlag=False,\n logFilePath=None,\n outDirPath=None,\n cleanUp=True,\n fmt=\"mmcif\",\n timeout=None,\n storeStringsAsBytes=False,\n defaultStringEncoding=\"utf-8\",\n **kwargs\n):\n \"\"\"Parse the data blocks in the input mmCIF or BCIF format data file into list of data or definition containers. The data category\n content within each data block is stored a collection of DataCategory objects within each container.\n\n Args:\n inputFilePath (string): Input file path\n enforceAscii (bool, optional): Flag to require ASCII encoding when reading in 'mmcif' file. See encoding error options. Defaults to False.\n selectList (List, optional): List of data category names to be extracted or excluded from the input file (default: select/extract)\n excludeFlag (bool, optional): Flag to indicate selectList should be treated as an exclusion list\n logFilePath (string, optional): Log file path (if not provided this will be derived from the input file.)\n outDirPath (string, optional): Path for translated/re-encoded files and default logfiles.\n cleanUp (bool, optional): Flag to automatically remove logs and temporary files on exit.\n fmt (string, optional): Format of input file (either \"mmcif\" or \"bcif\"). Defaults to \"mmcif\".\n timeout (float, optional): Timeout in seconds for fetching data from remote urls\n\n # BCIF-specific args:\n storeStringsAsBytes (bool, optional): Strings are stored as lists of bytes (for BCIF files only). Defaults to False.\n defaultStringEncoding (str, optional): Default encoding for string data (for BCIF files only). Defaults to \"utf-8\".\n\n **kwargs: Placeholder for missing keyword arguments.\n\n Returns:\n List of DataContainers: Contents of input file parsed into a list of DataContainer objects.\n\n \"\"\"\n if kwargs:\n logger.warning(\"Unsupported keyword arguments %s\", kwargs.keys())\n filePath = str(inputFilePath)\n # oPath = outDirPath if outDirPath else '.'\n oPath = self._chooseTemporaryPath(inputFilePath, outDirPath=outDirPath)\n containerList = []\n if enforceAscii:\n encoding = \"ascii\"\n else:\n encoding = \"utf-8\"\n try:\n #\n lPath = logFilePath\n if not lPath:\n lPath = self._getDefaultFileName(filePath, fileType=\"cif-parser-log\", outDirPath=oPath)\n #\n self._setLogFilePath(lPath)\n # ---\n if self.__isLocal(filePath) and not self._fileExists(filePath):\n return []\n #\n fmt = fmt.lower()\n #\n if sys.version_info[0] > 2: # Check if using Python version higher than 2\n if fmt == \"mmcif\":\n if self.__isLocal(filePath):\n filePath = self._uncompress(filePath, oPath)\n with open(filePath, \"r\", encoding=encoding, errors=self._readEncodingErrors) as ifh:\n pRd = PdbxReader(ifh)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else: # handle files from the internet...\n if filePath.endswith(\".gz\"):\n customHeader = {\"Accept-Encoding\": \"gzip\"}\n with closing(requests.get(filePath, headers=customHeader, timeout=timeout)) as ifh:\n if self._raiseExceptions:\n ifh.raise_for_status()\n gzit = gzip.GzipFile(fileobj=io.BytesIO(ifh.content))\n it = (line.decode(encoding, \"ignore\") for line in gzit)\n pRd = PdbxReader(it)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n with closing(requests.get(filePath, timeout=timeout)) as ifh:\n if self._raiseExceptions:\n ifh.raise_for_status()\n it = (line.decode(encoding, \"ignore\") + \"\\n\" for line in ifh.iter_lines())\n pRd = PdbxReader(it)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n elif fmt == \"bcif\":\n # local vs. remote and gzip business is already done in BinaryCifReader\n bcifRd = BinaryCifReader(storeStringsAsBytes=storeStringsAsBytes, defaultStringEncoding=defaultStringEncoding)\n containerList = bcifRd.deserialize(filePath)\n else:\n logger.error(\"Unsupported fmt %r. Currently only supports 'mmcif' or 'bcif'.\", fmt)\n else:\n logger.warning(\"Support for Python 2 will be deprecated soon. Please use Python 3.\")\n if fmt == \"bcif\":\n logger.error(\"Support for BCIF reading only available in Python 3.\")\n elif fmt == \"mmcif\":\n if self.__isLocal(filePath):\n filePath = self._uncompress(filePath, oPath)\n if enforceAscii:\n with io.open(filePath, \"r\", encoding=encoding, errors=self._readEncodingErrors) as ifh:\n pRd = PdbxReader(ifh)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n with open(filePath, \"r\") as ifh:\n pRd = PdbxReader(ifh)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n if filePath.endswith(\".gz\"):\n customHeader = {\"Accept-Encoding\": \"gzip\"}\n with closing(requests.get(filePath, headers=customHeader, timeout=timeout)) as ifh:\n if self._raiseExceptions:\n ifh.raise_for_status()\n gzit = gzip.GzipFile(fileobj=io.BytesIO(ifh.content))\n it = (line.decode(encoding, \"ignore\") for line in gzit)\n pRd = PdbxReader(it)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n with closing(requests.get(filePath, timeout=timeout)) as ifh:\n if self._raiseExceptions:\n ifh.raise_for_status()\n it = (line.decode(encoding, \"ignore\") + \"\\n\" for line in ifh.iter_lines())\n pRd = PdbxReader(it)\n pRd.read(containerList, selectList, excludeFlag=excludeFlag)\n else:\n logger.error(\"Unsupported fmt %r for Python2 installation of mmcif.io.IoAdapterPy. Currently only 'mmcif' is supported. Upgrade to Python3 for 'bcif' support\", fmt)\n\n if cleanUp:\n self._cleanupFile(lPath, lPath)\n self._cleanupFile(filePath != str(inputFilePath), filePath)\n self._setContainerProperties(containerList, locator=str(inputFilePath), load_date=self._getTimeStamp(), uid=uuid.uuid4().hex)\n except (PdbxError, PdbxSyntaxError) as ex:\n msg = \"File %r with %s\" % (filePath, str(ex))\n self._appendToLog([msg])\n self._cleanupFile(lPath and cleanUp, lPath)\n if self._raiseExceptions:\n raise_from(ex, None)\n # raise ex from None\n except Exception as e:\n msg = \"File %r with %s\" % (filePath, str(e))\n self._appendToLog([msg])\n self._cleanupFile(lPath and cleanUp, lPath)\n if self._raiseExceptions:\n raise e\n else:\n logger.error(\"Failing read for %s with %s\", filePath, str(e))\n return containerList\n
"},{"location":"api_reference/IoAdapterPy/#mmcif.io.IoAdapterPy.IoAdapterPy.writeFile","title":"writeFile(self, outputFilePath, containerList, maxLineLength=900, enforceAscii=True, lastInOrder=None, selectOrder=None, columnAlignFlag=True, useStopTokens=False, formattingStep=None, fmt='mmcif', storeStringsAsBytes=False, defaultStringEncoding='utf-8', applyTypes=True, dictionaryApi=None, useStringTypes=False, useFloat64=False, copyInputData=False, **kwargs)
","text":"Write input list of data containers to the specified output file path in mmCIF or BCIF format.
Parameters:
Name Type Description Default outputFilePath
string
output file path
required maxLineLength
int
Maximum length of output line (content is wrapped beyond this length)
900
enforceAscii
bool
Enforce ASCII encoding when writing out 'mmcif' file. Defaults to True.
True
lastInOrder
list of category names
Move data categories in this list to end of each data block
None
selectOrder
list of category names
Write only data categories on this list.
None
columnAlignFlag
bool
Format the output in aligned columns (default=True) (Native Python Only)
True
useStopTokens
bool
Include terminating 'stop_' tokens at the end of mmCIF categories (loop_'s) (Native Python only)
False
formattingStep
int
The number row samples within each category used to estimate maximum column width for data alignment (Native Python only)
None
fmt
string
Format of output file (either \"mmcif\" or \"bcif\"). Defaults to \"mmcif\".
'mmcif'
#
BCIF-specific args
required storeStringsAsBytes
bool
Strings are stored as lists of bytes (for BCIF files only). Defaults to False.
False
defaultStringEncoding
str
Default encoding for string data (for BCIF files only). Defaults to \"utf-8\".
'utf-8'
applyTypes
bool
apply explicit data typing before encoding (for BCIF files only; requires dictionaryApi to be passed too). Defaults to True.
True
dictionaryApi
object
DictionaryApi object instance (needed for BCIF files, only when applyTypes is True). Defaults to None.
None
useStringTypes
bool
assume all types are string (for BCIF files only). Defaults to False.
False
useFloat64
bool
store floats with 64 bit precision (for BCIF files only). Defaults to False.
False
copyInputData
bool
make a new copy input data (for BCIF files only). Defaults to False.
False
**kwargs
Placeholder for unsupported key value pairs
{}
Returns:
Type Description bool
Completion status
Source code in mmcif/io/IoAdapterPy.py
def writeFile(\n self,\n outputFilePath,\n containerList,\n maxLineLength=900,\n enforceAscii=True,\n lastInOrder=None,\n selectOrder=None,\n columnAlignFlag=True,\n useStopTokens=False,\n formattingStep=None,\n fmt=\"mmcif\",\n storeStringsAsBytes=False,\n defaultStringEncoding=\"utf-8\",\n applyTypes=True,\n dictionaryApi=None,\n useStringTypes=False,\n useFloat64=False,\n copyInputData=False,\n **kwargs\n):\n \"\"\"Write input list of data containers to the specified output file path in mmCIF or BCIF format.\n\n Args:\n outputFilePath (string): output file path\n containerList (list DataContainer objects, optional)\n maxLineLength (int, optional): Maximum length of output line (content is wrapped beyond this length)\n enforceAscii (bool, optional): Enforce ASCII encoding when writing out 'mmcif' file. Defaults to True.\n lastInOrder (list of category names, optional): Move data categories in this list to end of each data block\n selectOrder (list of category names, optional): Write only data categories on this list.\n columnAlignFlag (bool, optional): Format the output in aligned columns (default=True) (Native Python Only)\n useStopTokens (bool, optional): Include terminating 'stop_' tokens at the end of mmCIF categories (loop_'s) (Native Python only)\n formattingStep (int, optional): The number row samples within each category used to estimate maximum column width for data alignment (Native Python only)\n fmt (string, optional): Format of output file (either \"mmcif\" or \"bcif\"). Defaults to \"mmcif\".\n\n # BCIF-specific args:\n storeStringsAsBytes (bool, optional): Strings are stored as lists of bytes (for BCIF files only). Defaults to False.\n defaultStringEncoding (str, optional): Default encoding for string data (for BCIF files only). Defaults to \"utf-8\".\n applyTypes (bool, optional): apply explicit data typing before encoding (for BCIF files only; requires dictionaryApi to be passed too). Defaults to True.\n dictionaryApi (object, optional): DictionaryApi object instance (needed for BCIF files, only when applyTypes is True). Defaults to None.\n useStringTypes (bool, optional): assume all types are string (for BCIF files only). Defaults to False.\n useFloat64 (bool, optional): store floats with 64 bit precision (for BCIF files only). Defaults to False.\n copyInputData (bool, optional): make a new copy input data (for BCIF files only). Defaults to False.\n\n **kwargs: Placeholder for unsupported key value pairs\n\n Returns:\n bool: Completion status\n\n \"\"\"\n lastInOrder = lastInOrder if lastInOrder else [\"pdbx_nonpoly_scheme\", \"pdbx_poly_seq_scheme\", \"atom_site\", \"atom_site_anisotrop\"]\n if kwargs:\n logger.warning(\"Unsupported keyword arguments %s\", kwargs.keys())\n try:\n if enforceAscii:\n encoding = \"ascii\"\n else:\n encoding = \"utf-8\"\n #\n fmt = fmt.lower()\n #\n if sys.version_info[0] > 2: # Check if using Python version higher than 2\n if fmt == \"mmcif\":\n with open(outputFilePath, \"w\", encoding=encoding) as ofh:\n self.__writeFile(\n ofh,\n containerList,\n maxLineLength=maxLineLength,\n columnAlignFlag=columnAlignFlag,\n lastInOrder=lastInOrder,\n selectOrder=selectOrder,\n useStopTokens=useStopTokens,\n formattingStep=formattingStep,\n enforceAscii=enforceAscii,\n cnvCharRefs=self._useCharRefs,\n )\n elif fmt == \"bcif\":\n bcifW = BinaryCifWriter(\n dictionaryApi=dictionaryApi,\n storeStringsAsBytes=storeStringsAsBytes,\n defaultStringEncoding=defaultStringEncoding,\n applyTypes=applyTypes,\n useStringTypes=useStringTypes,\n useFloat64=useFloat64,\n copyInputData=copyInputData,\n )\n bcifW.serialize(outputFilePath, containerList)\n else:\n logger.error(\"Unsupported fmt %r. Currently only supports 'mmcif' or 'bcif'.\", fmt)\n return False\n else:\n logger.warning(\"Support for Python 2 will be deprecated soon. Please use Python 3.\")\n if fmt == \"bcif\":\n logger.error(\"Support for BCIF writing only available in Python 3.\")\n return False\n elif fmt == \"mmcif\":\n if enforceAscii:\n with io.open(outputFilePath, \"w\", encoding=encoding) as ofh:\n self.__writeFile(\n ofh,\n containerList,\n maxLineLength=maxLineLength,\n columnAlignFlag=columnAlignFlag,\n lastInOrder=lastInOrder,\n selectOrder=selectOrder,\n useStopTokens=useStopTokens,\n formattingStep=formattingStep,\n enforceAscii=enforceAscii,\n cnvCharRefs=self._useCharRefs,\n )\n else:\n with open(outputFilePath, \"wb\") as ofh:\n self.__writeFile(\n ofh,\n containerList,\n maxLineLength=maxLineLength,\n columnAlignFlag=columnAlignFlag,\n lastInOrder=lastInOrder,\n selectOrder=selectOrder,\n useStopTokens=useStopTokens,\n formattingStep=formattingStep,\n enforceAscii=enforceAscii,\n cnvCharRefs=self._useCharRefs,\n )\n else:\n logger.error(\"Unsupported fmt %r for Python2 installation of mmcif.io.IoAdapterPy. Currently only 'mmcif' is supported. Upgrade to Python3 for 'bcif' support\", fmt)\n return False\n return True\n except Exception as ex:\n if self._raiseExceptions:\n raise_from(ex, None)\n else:\n logger.exception(\"Failing write for %s with %s\", outputFilePath, str(ex))\n logger.error(\"Failing write for %s with %s\", outputFilePath, str(ex))\n\n return False\n
"},{"location":"api_reference/Method/","title":"Method","text":"Source code in mmcif/api/Method.py
class MethodDefinition(object):\n def __init__(self, methodId, code=\"calculate\", language=\"Python\", inline=None, priority=None, implementation=None, implementationSource=\"inline\"):\n self.methodId = methodId\n self.language = language\n self.code = code\n self.inline = inline\n self.priority = priority if priority else 1\n self.implementationSource = implementationSource\n self.implementation = implementation\n\n def getId(self):\n return self.methodId\n\n def getLanguage(self):\n return self.language\n\n def getCode(self):\n return self.code\n\n def getInline(self):\n return self.inline\n\n def getImplementation(self):\n return self.implementation\n\n def getImplementationSource(self):\n return self.implementationSource\n\n def getPriority(self):\n return self.priority\n\n def printIt(self, fh=sys.stdout):\n fh.write(\"------------- Method definition -------------\\n\")\n fh.write(\"Id: %s\\n\" % self.methodId)\n fh.write(\"Code: %s\\n\" % self.code)\n fh.write(\"Language: %s\\n\" % str(self.language))\n fh.write(\"Inline text: %s\\n\" % str(self.inline))\n fh.write(\"Implementation: %s\\n\" % str(self.implementation))\n fh.write(\"Implementation source: %s\\n\" % str(self.implementationSource))\n fh.write(\"Priority: %d\\n\" % self.priority)\n\n def __repr__(self):\n oL = []\n oL.append(\"\\n------------- Method definition -------------\")\n oL.append(\"Id: %s\" % self.methodId)\n oL.append(\"Code: %s\" % self.code)\n oL.append(\"Language: %s\" % str(self.language))\n oL.append(\"Inline text: %s\" % str(self.inline))\n oL.append(\"Implementation: %s\" % str(self.implementation))\n oL.append(\"Implementation source: %s\" % str(self.implementationSource))\n oL.append(\"Priority: %d\" % self.priority)\n return \"\\n\".join(oL)\n
Source code in mmcif/api/Method.py
class MethodReference(object):\n def __init__(self, methodId, mType=\"attribute\", category=None, attribute=None):\n self.methodId = methodId\n self.type = mType\n self.categoryName = category\n self.attributeName = attribute\n\n def getId(self):\n return self.methodId\n\n def getType(self):\n return self.type\n\n def getCategoryName(self):\n return self.categoryName\n\n def getAttributeName(self):\n return self.attributeName\n\n def printIt(self, fh=sys.stdout):\n fh.write(\"--------------- Method Reference -----------------\\n\")\n fh.write(\"Id: %s\\n\" % self.methodId)\n fh.write(\"Type: %s\\n\" % self.type)\n fh.write(\"Category name: %s\\n\" % str(self.categoryName))\n fh.write(\"Attribute name: %s\\n\" % str(self.attributeName))\n\n def __repr__(self):\n oL = []\n oL.append(\"--------------- Method Reference -----------------\")\n oL.append(\"Id: %s\" % self.methodId)\n oL.append(\"Type: %s\" % self.type)\n oL.append(\"Category name: %s\" % str(self.categoryName))\n oL.append(\"Attribute name: %s\" % str(self.attributeName))\n return \"\\n\".join(oL)\n
"},{"location":"api_reference/MethodUtils/","title":"MethodUtils","text":"Source code in mmcif/api/MethodUtils.py
class MethodUtils(object):\n def __init__(self, dictContainerList, verbose=False):\n #\n self.__verbose = verbose\n # list of dictionary data & definition containers\n self.__dictContainerList = dictContainerList\n self.__dApi = DictionaryApi(containerList=self.__dictContainerList, consolidate=True, verbose=self.__verbose)\n #\n # Target data container list\n self.__dataContainerList = []\n #\n\n def setDataContainerList(self, dataContainerList):\n self.__dataContainerList = dataContainerList\n\n def getDataContainerList(self):\n return self.__dataContainerList\n\n def getDictionary(self):\n return self.__dApi\n\n def getMethods(self):\n return self.__dApi.getMethodIndex()\n\n def getMethod(self, mId):\n return self.__dApi.getMethod(mId)\n\n def invokeMethods(self, fh=sys.stdout):\n _ = fh\n mI = self.__dApi.getMethodIndex()\n lenD = len(mI)\n i = 0\n for k, mRefL in mI.items():\n for mRef in mRefL:\n i += 1\n mId = mRef.getId()\n mType = mRef.getType()\n categoryName = mRef.getCategoryName()\n attributeName = mRef.getAttributeName()\n #\n logger.debug(\"\\n\")\n logger.debug(\"++++++++++++++++++--------------------\\n\")\n logger.debug(\"Invoking dictionary method on file object: %s (%d/%d)\", k, i, lenD)\n logger.debug(\" + Method id: %s\", mId)\n logger.debug(\" + Type: %s\", mType)\n logger.debug(\" + Category: %s\", categoryName)\n logger.debug(\" + Attribute: %s\", attributeName)\n #\n if mType == \"datablock\":\n logger.debug(\"Invoke datablock method %s\", mId)\n # self.invokeDataBlockMethod(type,self.__dApi.getMethod(id))\n # continue\n #\n for db in self.__dataContainerList:\n if mType == \"category\":\n if not db.exists(categoryName):\n dc = DataCategory(categoryName)\n db.append(dc)\n dObj = db.getObj(categoryName)\n dObj.invokeCategoryMethod(mType, self.__dApi.getMethod(mId), db)\n elif mType == \"attribute\":\n if not db.exists(categoryName):\n dc = DataCategory(categoryName)\n db.append(dc)\n dObj = db.getObj(categoryName)\n # logger.debug(\"invoke - %r %r %r %r\" % (attributeName, type, self.__dApi.getMethod(id), db))\n dObj.invokeAttributeMethod(attributeName, mType, self.__dApi.getMethod(mId), db)\n elif mType == \"datablock\":\n logger.debug(\"Invoke datablock method %s\", mId)\n db.invokeDataBlockMethod(mType, self.__dApi.getMethod(mId), db)\n else:\n pass\n\n def dumpMethods(self, fh=sys.stdout):\n self.__dApi.dumpMethods(fh)\n\n def dumpDictionary(self, fh=sys.stdout):\n lenD = len(self.__dictContainerList)\n fh.write(\"\\n--------------------------------------------\\n\")\n fh.write(\"\\n-----------DUMP DICTIONARY------------------\\n\")\n fh.write(\"Dictionary object list length is: %d\\n\" % lenD)\n i = 1\n for dObj in self.__dictContainerList:\n if dObj.getName():\n fh.write(\"\\n\")\n fh.write(\"++++++++++++++++++--------------------\\n\")\n fh.write(\"Dumping dictionary object named: %s (%d/%d)\\n\" % (dObj.getName(), i, lenD))\n dObj.printIt(fh)\n i += 1\n\n #\n\n def dumpDataFile(self, fh=sys.stdout):\n lenD = len(self.__dataContainerList)\n fh.write(\"\\n--------------------------------------------\\n\")\n fh.write(\"\\n-----------DUMP DATAFILE--------------------\\n\")\n fh.write(\"Data object list length is: %d\\n\" % lenD)\n i = 1\n for dObj in self.__dataContainerList:\n fh.write(\"\\n\")\n fh.write(\"++++++++++++++++++--------------------\\n\")\n fh.write(\"Dumping data file object named: %s (%d/%d)\\n\" % (dObj.getName(), i, lenD))\n dObj.printIt(fh)\n i += 1\n
"},{"location":"api_reference/PdbxContainers/","title":"PdbxContainers","text":"Container base class for data and definition objects.
Source code in mmcif/api/PdbxContainers.py
class ContainerBase(object):\n \"\"\"Container base class for data and definition objects.\"\"\"\n\n def __init__(self, name):\n # The enclosing scope of the data container (e.g. data_/save_)\n self.__name = name\n # List of category names within this container -\n self.__objNameList = []\n # dictionary of DataCategory objects keyed by category name.\n self.__objCatalog = {}\n # dictionary for properties of the container\n self.__propCatalog = {}\n self.__type = None\n\n def __eq__(self, other):\n if not isinstance(other, type(self)):\n return NotImplemented\n return (\n self.__name == other.getName()\n and self.__objNameList == other.getObjNameList()\n and self.__objCatalog == other.getObjCatalog()\n and self.__type == other.getType()\n and self.__propCatalog == other.getPropCatalog()\n )\n\n def __hash__(self):\n return hash((self.__name, tuple(self.__objNameList), self.__type, tuple(self.__objCatalog.items()), tuple(self.__propCatalog.items())))\n\n def getObjCatalog(self):\n return self.__objCatalog\n\n def getPropCatalog(self):\n return self.__propCatalog\n\n def setProp(self, propName, value):\n try:\n self.__propCatalog[propName] = value\n return True\n except Exception:\n return False\n\n def getProp(self, propName):\n try:\n return self.__propCatalog[propName]\n except Exception:\n return None\n\n def getType(self):\n return self.__type\n\n def setType(self, cType):\n self.__type = cType\n\n def getName(self):\n return self.__name\n\n def setName(self, name):\n self.__name = name\n\n def exists(self, name):\n if name in self.__objCatalog:\n return True\n else:\n return False\n\n def getObj(self, name):\n if name in self.__objCatalog:\n return self.__objCatalog[name]\n else:\n return None\n\n def getObjNameList(self):\n return self.__objNameList\n\n def append(self, obj):\n \"\"\"Add the input object to the current object catalog. An existing object\n of the same name will be overwritten.\n \"\"\"\n if obj.getName() is not None:\n if obj.getName() not in self.__objCatalog:\n # self.__objNameList is keeping track of object order here --\n self.__objNameList.append(obj.getName())\n self.__objCatalog[obj.getName()] = obj\n\n def replace(self, obj):\n \"\"\"Replace an existing object with the input object\"\"\"\n if (obj.getName() is not None) and (obj.getName() in self.__objCatalog):\n self.__objCatalog[obj.getName()] = obj\n\n def printIt(self, fh=sys.stdout, pType=\"brief\"):\n fh.write(\"+ %s container: %30s contains %4d categories\\n\" % (self.getType(), self.getName(), len(self.__objNameList)))\n for nm in self.__objNameList:\n fh.write(\"--------------------------------------------\\n\")\n fh.write(\"Data category: %s\\n\" % nm)\n if pType == \"brief\":\n self.__objCatalog[nm].printIt(fh)\n else:\n self.__objCatalog[nm].dumpIt(fh)\n\n def rename(self, curName, newName):\n \"\"\"Change the name of an object in place -\"\"\"\n try:\n i = self.__objNameList.index(curName)\n self.__objNameList[i] = newName\n self.__objCatalog[newName] = self.__objCatalog[curName]\n self.__objCatalog[newName].setName(newName)\n return True\n except Exception:\n return False\n\n def remove(self, curName):\n \"\"\"Remove object by name. Return True on success or False otherwise.\"\"\"\n try:\n if curName in self.__objCatalog:\n del self.__objCatalog[curName]\n i = self.__objNameList.index(curName)\n del self.__objNameList[i]\n return True\n else:\n return False\n except Exception:\n pass\n\n return False\n\n def merge(self, container):\n \"\"\"Merge the contents of the input container with the contents of the current container.\"\"\"\n try:\n objNameList = container.getObjNameList()\n for objName in objNameList:\n self.append(container.getObj(objName))\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n return False\n return True\n\n def filterObjectNameList(self, lastInOrder=None, selectOrder=None):\n \"\"\"Return an ordered list of categories in the input container subject to\n input -\n\n lastInOrder: list: categories to be shifted to the end of the container.\n selectOrder: list: ordered selection of container categories\n\n returns:\n filNameList: list: augmented category list or full list (default)\n \"\"\"\n filNameList = []\n if lastInOrder:\n objNameList = self.__objNameList\n lastList = []\n for nm in objNameList:\n if nm in lastInOrder:\n lastList.append(nm)\n continue\n filNameList.append(nm)\n filNameList.extend(lastList)\n elif selectOrder:\n for nm in selectOrder:\n if self.exists(nm):\n filNameList.append(nm)\n else:\n filNameList = self.__objNameList\n\n return filNameList\n\n def toJSON(self):\n return self.__objCatalog\n
Source code in mmcif/api/PdbxContainers.py
class DefinitionContainer(ContainerBase):\n def __init__(self, name):\n super(DefinitionContainer, self).__init__(name)\n self.setType(\"definition\")\n self.__globalFlag = False\n\n def isCategory(self):\n if self.exists(\"category\"):\n return True\n return False\n\n def isAttribute(self):\n if self.exists(\"item\"):\n return True\n return False\n\n def getGlobal(self):\n return self.__globalFlag\n\n def printIt(self, fh=sys.stdout, pType=\"brief\"):\n fh.write(\"Definition container: %30s contains %4d categories\\n\" % (self.getName(), len(self.getObjNameList())))\n if self.isCategory():\n fh.write(\"Definition type: category\\n\")\n elif self.isAttribute():\n fh.write(\"Definition type: item\\n\")\n else:\n fh.write(\"Definition type: undefined\\n\")\n\n for nm in self.getObjNameList():\n fh.write(\"--------------------------------------------\\n\")\n fh.write(\"Definition category: %s\\n\" % nm)\n if pType == \"brief\":\n self.getObj(nm).printIt(fh)\n else:\n self.getObj(nm).dumpId(fh)\n
Container class for DataCategory objects.
Source code in mmcif/api/PdbxContainers.py
class DataContainer(ContainerBase):\n \"\"\"Container class for DataCategory objects.\"\"\"\n\n def __init__(self, name):\n super(DataContainer, self).__init__(name)\n self.setType(\"data\")\n self.__globalFlag = False\n\n def invokeDataBlockMethod(self, mType, method, db):\n _ = mType\n _ = db\n # self.__currentRow = 1\n exec(method.getInline(), globals(), locals()) # pylint: disable=exec-used\n\n def setGlobal(self):\n self.__globalFlag = True\n\n def getGlobal(self):\n return self.__globalFlag\n
Source code in mmcif/api/PdbxContainers.py
class SaveFrameContainer(ContainerBase):\n def __init__(self, name):\n super(SaveFrameContainer, self).__init__(name)\n self.setType(\"definition\")\n
Class of utilities for CIF-style data names -
Source code in mmcif/api/PdbxContainers.py
class CifName(object):\n \"\"\"Class of utilities for CIF-style data names -\"\"\"\n\n def __init__(self):\n pass\n\n @staticmethod\n def categoryPart(name):\n tname = \"\"\n try:\n if name.startswith(\"_\"):\n tname = name[1:]\n else:\n tname = name\n\n i = tname.find(\".\")\n if i == -1:\n return tname\n else:\n return tname[:i]\n except Exception:\n return tname\n\n @staticmethod\n def attributePart(name):\n try:\n i = name.find(\".\")\n if i == -1:\n return None\n else:\n return name[i + 1 :]\n except Exception:\n return None\n\n @staticmethod\n def itemName(categoryName, attributeName):\n try:\n return \"_\" + str(categoryName) + \".\" + str(attributeName)\n except Exception:\n return None\n
"},{"location":"api_reference/PdbxContainers/#mmcif.api.PdbxContainers.ContainerBase.append","title":"append(self, obj)
","text":"Add the input object to the current object catalog. An existing object of the same name will be overwritten.
Source code in mmcif/api/PdbxContainers.py
def append(self, obj):\n \"\"\"Add the input object to the current object catalog. An existing object\n of the same name will be overwritten.\n \"\"\"\n if obj.getName() is not None:\n if obj.getName() not in self.__objCatalog:\n # self.__objNameList is keeping track of object order here --\n self.__objNameList.append(obj.getName())\n self.__objCatalog[obj.getName()] = obj\n
"},{"location":"api_reference/PdbxContainers/#mmcif.api.PdbxContainers.ContainerBase.filterObjectNameList","title":"filterObjectNameList(self, lastInOrder=None, selectOrder=None)
","text":"Return an ordered list of categories in the input container subject to input -
lastInOrder: list: categories to be shifted to the end of the container. selectOrder: list: ordered selection of container categories
Returns:
Type Description filNameList
list: augmented category list or full list (default)
Source code in mmcif/api/PdbxContainers.py
def filterObjectNameList(self, lastInOrder=None, selectOrder=None):\n \"\"\"Return an ordered list of categories in the input container subject to\n input -\n\n lastInOrder: list: categories to be shifted to the end of the container.\n selectOrder: list: ordered selection of container categories\n\n returns:\n filNameList: list: augmented category list or full list (default)\n \"\"\"\n filNameList = []\n if lastInOrder:\n objNameList = self.__objNameList\n lastList = []\n for nm in objNameList:\n if nm in lastInOrder:\n lastList.append(nm)\n continue\n filNameList.append(nm)\n filNameList.extend(lastList)\n elif selectOrder:\n for nm in selectOrder:\n if self.exists(nm):\n filNameList.append(nm)\n else:\n filNameList = self.__objNameList\n\n return filNameList\n
"},{"location":"api_reference/PdbxContainers/#mmcif.api.PdbxContainers.ContainerBase.merge","title":"merge(self, container)
","text":"Merge the contents of the input container with the contents of the current container.
Source code in mmcif/api/PdbxContainers.py
def merge(self, container):\n \"\"\"Merge the contents of the input container with the contents of the current container.\"\"\"\n try:\n objNameList = container.getObjNameList()\n for objName in objNameList:\n self.append(container.getObj(objName))\n except Exception as e:\n logger.exception(\"Failing with %s\", str(e))\n return False\n return True\n
"},{"location":"api_reference/PdbxContainers/#mmcif.api.PdbxContainers.ContainerBase.remove","title":"remove(self, curName)
","text":"Remove object by name. Return True on success or False otherwise.
Source code in mmcif/api/PdbxContainers.py
def remove(self, curName):\n \"\"\"Remove object by name. Return True on success or False otherwise.\"\"\"\n try:\n if curName in self.__objCatalog:\n del self.__objCatalog[curName]\n i = self.__objNameList.index(curName)\n del self.__objNameList[i]\n return True\n else:\n return False\n except Exception:\n pass\n\n return False\n
"},{"location":"api_reference/PdbxContainers/#mmcif.api.PdbxContainers.ContainerBase.rename","title":"rename(self, curName, newName)
","text":"Change the name of an object in place -
Source code in mmcif/api/PdbxContainers.py
def rename(self, curName, newName):\n \"\"\"Change the name of an object in place -\"\"\"\n try:\n i = self.__objNameList.index(curName)\n self.__objNameList[i] = newName\n self.__objCatalog[newName] = self.__objCatalog[curName]\n self.__objCatalog[newName].setName(newName)\n return True\n except Exception:\n return False\n
"},{"location":"api_reference/PdbxContainers/#mmcif.api.PdbxContainers.ContainerBase.replace","title":"replace(self, obj)
","text":"Replace an existing object with the input object
Source code in mmcif/api/PdbxContainers.py
def replace(self, obj):\n \"\"\"Replace an existing object with the input object\"\"\"\n if (obj.getName() is not None) and (obj.getName() in self.__objCatalog):\n self.__objCatalog[obj.getName()] = obj\n
"},{"location":"api_reference/PdbxExceptions/","title":"PdbxExceptions","text":"Class for catch general errors
Source code in mmcif/io/PdbxExceptions.py
class PdbxError(Exception):\n \"\"\"Class for catch general errors\"\"\"\n
Class for catching syntax errors
Source code in mmcif/io/PdbxExceptions.py
class PdbxSyntaxError(Exception):\n \"\"\"Class for catching syntax errors\"\"\"\n
"},{"location":"api_reference/PdbxReader/","title":"PdbxReader","text":"Utilities for reading mmCIF for data files and dictionaries.
Source code in mmcif/io/PdbxReader.py
class PdbxReader(object):\n \"\"\"Utilities for reading mmCIF for data files and dictionaries.\"\"\"\n\n def __init__(self, ifh):\n \"\"\"ifh - input file handle returned by open()\"\"\"\n #\n self.__curLineNumber = 0\n self.__ifh = ifh\n self.__stateDict = {\"data\": \"ST_DATA_CONTAINER\", \"loop\": \"ST_TABLE\", \"global\": \"ST_GLOBAL_CONTAINER\", \"save\": \"ST_DEFINITION\", \"stop\": \"ST_STOP\"}\n\n def read(self, containerList, selectList=None, excludeFlag=False):\n \"\"\"\n Appends to input list of definition and data containers.\n\n return\n\n \"\"\"\n sL = selectList if selectList else []\n catSelectD = {k: k for k in sL}\n self.__curLineNumber = 0\n try:\n self.__parser(self.__tokenizer(self.__ifh), containerList, categorySelectionD=catSelectD, excludeFlag=excludeFlag)\n except RuntimeError as e:\n # will be raised at the end of token iterator - not an error -\n logger.debug(\"Normal termination after reading %d lines with %s\", self.__curLineNumber, str(e))\n except StopIteration:\n # will be raised at the end of token iterator - not an error -\n logger.debug(\"Normal termination after reading %d lines\", self.__curLineNumber)\n except PdbxSyntaxError as e:\n logger.debug(\"Caught syntax exception at %d\", self.__curLineNumber)\n raise e\n except UnicodeDecodeError as e:\n logger.debug(\"Caught character encoding exception at %d with %s\", self.__curLineNumber, str(e))\n raise PdbxError(\"Character encoding error at line %d\" % self.__curLineNumber)\n except Exception as e:\n raise PdbxError(\"Failing at line %d with %s\" % (self.__curLineNumber, str(e)))\n else:\n raise PdbxError(\"Miscellaneous parsing error at line %d\" % self.__curLineNumber)\n\n def __allSelected(self, container, catSelectD):\n \"\"\"Test the input container for completeness relative to the input category selection dictionary.\"\"\"\n nl = -1\n if catSelectD:\n try:\n nl = container.getObjNameList()\n if len(nl) <= len(catSelectD):\n ok = False\n else:\n ok = True\n logger.debug(\"nl %d length catSelectD %d returning %r\", len(nl), len(catSelectD), ok)\n except Exception:\n ok = False\n else:\n ok = False\n return ok\n\n def __syntaxError(self, errText):\n msg = \" [Line: %d] %s\" % (self.__curLineNumber, errText)\n raise PdbxSyntaxError(msg)\n\n def __getContainerName(self, inWord):\n \"\"\"Returns the name of the data block or saveframe container\"\"\"\n return str(inWord[5:]).strip()\n\n def __getState(self, inWord):\n \"\"\"Identifies reserved syntax elements and assigns an associated state.\n\n on return: (reserved word, state)\n where -\n reserved word - is one of CIF syntax elements:\n data, loop, global, save, or stop\n state - the parser state required to process this next section.\n\n \"\"\"\n i = inWord.find(\"_\")\n if i == -1:\n return None, \"ST_UNKNOWN\"\n\n try:\n rWord = inWord[:i].lower()\n return rWord, self.__stateDict[rWord]\n except Exception:\n return None, \"ST_UNKNOWN\"\n\n def __parser(self, tokenizer, containerList, categorySelectionD=None, excludeFlag=False):\n \"\"\"Parser for PDBx data files and dictionaries.\n\n Input - tokenizer() reentrant method recognizing data item names (_category.attribute)\n quoted strings (single, double and multi-line semi-colon delimited), and unquoted\n strings.\n\n containerList - list-type container for data and definition objects parsed from\n from the input file.\n\n On return:\n The input containerList is appended with data and definition objects -\n \"\"\"\n catSelectD = categorySelectionD if categorySelectionD is not None else {}\n logger.debug(\"Exclude Flag %r Category selection %r\", excludeFlag, catSelectD)\n # Working container - data or definition\n curContainer = None\n # the last container of type data -\n previousDataContainer = None\n #\n # Working category container\n categoryIndex = {}\n curCategory = None\n #\n curRow = None\n state = None\n\n # Find the first reserved word and begin capturing data.\n #\n while True:\n curCatName, curAttName, curQuotedString, curWord = next(tokenizer)\n if curWord is None:\n continue\n reservedWord, state = self.__getState(curWord)\n if reservedWord is not None:\n break\n\n while True:\n #\n # Set the current state -\n #\n # At this point in the processing cycle we are expecting a token containing\n # either a '_category.attribute' or a reserved word.\n #\n if curCatName is not None:\n state = \"ST_KEY_VALUE_PAIR\"\n elif curWord is not None:\n reservedWord, state = self.__getState(curWord)\n else:\n self.__syntaxError(\"Miscellaneous syntax error\")\n return\n\n #\n # Process _category.attribute value assignments\n #\n if state == \"ST_KEY_VALUE_PAIR\":\n try:\n curCategory = categoryIndex[curCatName]\n except KeyError:\n # A new category is encountered - create a container and add a row\n curCategory = categoryIndex[curCatName] = DataCategory(curCatName)\n #\n # check if we have all of the selection\n if not excludeFlag and self.__allSelected(curContainer, catSelectD):\n return\n try:\n if catSelectD:\n if not excludeFlag and curCatName in catSelectD:\n curContainer.append(curCategory)\n elif excludeFlag and curCatName not in catSelectD:\n curContainer.append(curCategory)\n else:\n logger.debug(\"Skipped unselected/excluded category %s\", curCatName)\n else:\n curContainer.append(curCategory)\n except AttributeError:\n self.__syntaxError(\"Category cannot be added to data_ block\")\n return\n\n curRow = []\n curCategory.append(curRow)\n else:\n # Recover the existing row from the category\n try:\n # curRow = curCategory[0]\n curRow = curCategory.getRow(0)\n except IndexError:\n self.__syntaxError(\"Internal index error accessing category data\")\n return\n\n # Check for duplicate attributes and add attribute to table.\n if curAttName in curCategory.getAttributeList():\n self.__syntaxError(\"Duplicate attribute encountered in category\")\n return\n else:\n curCategory.appendAttribute(curAttName)\n\n # Get the data for this attribute from the next token\n tCat, _, curQuotedString, curWord = next(tokenizer)\n\n if tCat is not None or (curQuotedString is None and curWord is None):\n self.__syntaxError(\"Missing data for item _%s.%s\" % (curCatName, curAttName))\n\n if curWord is not None:\n #\n # Validation check token for misplaced reserved words -\n #\n reservedWord, state = self.__getState(curWord)\n if reservedWord is not None:\n self.__syntaxError(\"Unexpected reserved word: %s\" % (reservedWord))\n\n curRow.append(curWord)\n\n elif curQuotedString is not None:\n curRow.append(curQuotedString)\n\n else:\n self.__syntaxError(\"Missing value in item-value pair\")\n\n curCatName, curAttName, curQuotedString, curWord = next(tokenizer)\n continue\n\n #\n # Process a loop_ declaration and associated data -\n #\n elif state == \"ST_TABLE\":\n\n # The category name in the next curCatName,curAttName pair\n # defines the name of the category container.\n curCatName, curAttName, curQuotedString, curWord = next(tokenizer)\n\n if curCatName is None or curAttName is None:\n self.__syntaxError(\"Unexpected token in loop_ declaration\")\n return\n\n # Check for a previous category declaration.\n if curCatName in categoryIndex:\n self.__syntaxError(\"Duplicate category declaration in loop_\")\n return\n\n curCategory = DataCategory(curCatName)\n\n #\n # check if we have all of the selection\n if not excludeFlag and self.__allSelected(curContainer, catSelectD):\n return\n try:\n if catSelectD:\n if not excludeFlag and curCatName in catSelectD:\n curContainer.append(curCategory)\n elif excludeFlag and curCatName not in catSelectD:\n curContainer.append(curCategory)\n else:\n logger.debug(\"Skipped unselected/excluded category %s\", curCatName)\n else:\n curContainer.append(curCategory)\n except AttributeError:\n self.__syntaxError(\"loop_ declaration outside of data_ block or save_ frame\")\n return\n\n curCategory.appendAttribute(curAttName)\n\n # Read the rest of the loop_ declaration\n while True:\n curCatName, curAttName, curQuotedString, curWord = next(tokenizer)\n\n if curCatName is None:\n break\n\n if curCatName != curCategory.getName():\n self.__syntaxError(\"Changed category name in loop_ declaration\")\n return\n\n curCategory.appendAttribute(curAttName)\n\n # If the next token is a 'word', check it for any reserved words -\n if curWord is not None:\n reservedWord, state = self.__getState(curWord)\n if reservedWord is not None:\n if reservedWord == \"stop\":\n return\n else:\n self.__syntaxError(\"Unexpected reserved word after loop declaration: %s\" % (reservedWord))\n\n # Read the table of data for this loop_ -\n while True:\n curRow = []\n curCategory.append(curRow)\n\n for _ in curCategory.getAttributeList():\n if curWord is not None:\n curRow.append(curWord)\n elif curQuotedString is not None:\n curRow.append(curQuotedString)\n\n curCatName, curAttName, curQuotedString, curWord = next(tokenizer)\n\n # loop_ data processing ends if -\n\n # A new _category.attribute is encountered\n if curCatName is not None:\n break\n\n # A reserved word is encountered\n if curWord is not None:\n reservedWord, state = self.__getState(curWord)\n if reservedWord is not None:\n break\n\n continue\n\n elif state == \"ST_DEFINITION\":\n # Ignore trailing unnamed saveframe delimiters e.g. 'save'\n sName = self.__getContainerName(curWord)\n if sName:\n curContainer = DefinitionContainer(sName)\n containerList.append(curContainer)\n categoryIndex = {}\n curCategory = None\n else:\n # reset current container to the last data container\n curContainer = previousDataContainer\n\n curCatName, curAttName, curQuotedString, curWord = next(tokenizer)\n\n elif state == \"ST_DATA_CONTAINER\":\n #\n dName = self.__getContainerName(curWord)\n if not dName:\n dName = \"unidentified\"\n curContainer = DataContainer(dName)\n containerList.append(curContainer)\n categoryIndex = {}\n curCategory = None\n previousDataContainer = curContainer\n curCatName, curAttName, curQuotedString, curWord = next(tokenizer)\n\n elif state == \"ST_STOP\":\n ###\n # curCatName, curAttName, curQuotedString, curWord = tokenizer.next()\n continue\n\n elif state == \"ST_GLOBAL\":\n curContainer = DataContainer(\"blank-global\")\n curContainer.setGlobal()\n containerList.append(curContainer)\n categoryIndex = {}\n curCategory = None\n curCatName, curAttName, curQuotedString, curWord = next(tokenizer)\n\n elif state == \"ST_UNKNOWN\":\n self.__syntaxError(\"Unrecognized syntax element: \" + str(curWord))\n return\n\n def __tokenizer(self, ifh):\n \"\"\"Tokenizer method for the mmCIF syntax file -\n\n Each return/yield from this method returns information about\n the next token in the form of a tuple with the following structure.\n\n (category name, attribute name, quoted strings, words w/o quotes or white space)\n\n\n \"\"\"\n #\n # Regex definition for mmCIF syntax - semi-colon delimited strings are handled\n # outside of this regex.\n # Differentiated the regular expression to the better handle embedded quotes.\n #\n mmcifRe = re.compile(\n r\"(?:\"\n r\"(?:_(.+?)[.](\\S+))\"\n r\"|\" # _category.attribute\n r\"(?:['](.*?)(?:[']\\s|[']$))\"\n r\"|\" # single quoted strings\n r'(?:[\"](.*?)(?:[\"]\\s|[\"]$))'\n r\"|\" # double quoted strings\n r\"(?:\\s*#.*$)\"\n r\"|\" # comments (dumped)\n r\"(\\S+)\" # unquoted words\n r\")\"\n )\n\n fileIter = iter(ifh)\n\n # Tokenizer loop begins here ---\n while True:\n try:\n line = next(fileIter)\n self.__curLineNumber += 1\n\n # Dump comments\n if line.startswith(\"#\"):\n continue\n\n # Gobble up the entire semi-colon/multi-line delimited string and\n # and stuff this into the string slot in the return tuple\n #\n if line.startswith(\";\"):\n mlString = [line[1:]]\n while True:\n line = next(fileIter)\n self.__curLineNumber += 1\n if line.startswith(\";\"):\n break\n mlString.append(line)\n\n # remove trailing new-line that is part of the \\n; delimiter\n mlString[-1] = mlString[-1].rstrip()\n #\n yield (None, None, \"\".join(mlString), None)\n #\n # Need to process the remainder of the current line -\n line = line[1:]\n # continue\n\n # Apply regex to the current line consolidate the single/double\n # quoted within the quoted string category\n for it in mmcifRe.finditer(line):\n tgroups = it.groups()\n #\n if tgroups[4] is not None and tgroups[4].lower() == \"stop_\":\n continue\n if tgroups != (None, None, None, None, None):\n if tgroups[2] is not None:\n qs = tgroups[2]\n elif tgroups[3] is not None:\n qs = tgroups[3]\n else:\n qs = None\n groups = (tgroups[0], tgroups[1], qs, tgroups[4])\n yield groups\n except StopIteration:\n return\n
"},{"location":"api_reference/PdbxReader/#mmcif.io.PdbxReader.PdbxReader.__init__","title":"__init__(self, ifh)
special
","text":"ifh - input file handle returned by open()
Source code in mmcif/io/PdbxReader.py
def __init__(self, ifh):\n \"\"\"ifh - input file handle returned by open()\"\"\"\n #\n self.__curLineNumber = 0\n self.__ifh = ifh\n self.__stateDict = {\"data\": \"ST_DATA_CONTAINER\", \"loop\": \"ST_TABLE\", \"global\": \"ST_GLOBAL_CONTAINER\", \"save\": \"ST_DEFINITION\", \"stop\": \"ST_STOP\"}\n
"},{"location":"api_reference/PdbxReader/#mmcif.io.PdbxReader.PdbxReader.read","title":"read(self, containerList, selectList=None, excludeFlag=False)
","text":"Appends to input list of definition and data containers.
return
Source code in mmcif/io/PdbxReader.py
def read(self, containerList, selectList=None, excludeFlag=False):\n \"\"\"\n Appends to input list of definition and data containers.\n\n return\n\n \"\"\"\n sL = selectList if selectList else []\n catSelectD = {k: k for k in sL}\n self.__curLineNumber = 0\n try:\n self.__parser(self.__tokenizer(self.__ifh), containerList, categorySelectionD=catSelectD, excludeFlag=excludeFlag)\n except RuntimeError as e:\n # will be raised at the end of token iterator - not an error -\n logger.debug(\"Normal termination after reading %d lines with %s\", self.__curLineNumber, str(e))\n except StopIteration:\n # will be raised at the end of token iterator - not an error -\n logger.debug(\"Normal termination after reading %d lines\", self.__curLineNumber)\n except PdbxSyntaxError as e:\n logger.debug(\"Caught syntax exception at %d\", self.__curLineNumber)\n raise e\n except UnicodeDecodeError as e:\n logger.debug(\"Caught character encoding exception at %d with %s\", self.__curLineNumber, str(e))\n raise PdbxError(\"Character encoding error at line %d\" % self.__curLineNumber)\n except Exception as e:\n raise PdbxError(\"Failing at line %d with %s\" % (self.__curLineNumber, str(e)))\n else:\n raise PdbxError(\"Miscellaneous parsing error at line %d\" % self.__curLineNumber)\n
"},{"location":"api_reference/PdbxWriter/","title":"PdbxWriter","text":"Write mmCIF data files or dictionaries using the input container or container list.
Source code in mmcif/io/PdbxWriter.py
class PdbxWriter(object):\n\n \"\"\"Write mmCIF data files or dictionaries using the input container or container list.\"\"\"\n\n def __init__(self, ofh=sys.stdout):\n self.__ofh = ofh\n self.__containerList = []\n self.__maximumLineLength = 2048\n self.__spacing = 2\n self.__indentDefinition = 3\n self.__indentSpace = \" \" * self.__indentDefinition\n self.__doDefinitionIndent = False\n # Maximum number of rows checked for value length and format\n self.__rowPartition = None\n # Defaults to double quoting preference -\n self.__preferDoubleQuotes = True\n self.__useAlignedColumns = True\n self.__useStopTokens = False\n self.__cnvCharRefs = False\n #\n self.__enforceAscii = False\n self.__isPy3 = sys.version_info[0] == 3\n # if self.__isPy3:\n # self.__string_types = str\n # else:\n # self.__string_types = basestring\n\n def setSetEnforceAscii(self, boolVal):\n self.__enforceAscii = boolVal\n\n def setConvertCharRefs(self, flag):\n self.__cnvCharRefs = flag\n\n def setUseStopTokens(self, flag):\n self.__useStopTokens = flag\n\n def setMaxLineLength(self, numChars):\n self.__maximumLineLength = numChars\n\n def setAlignmentFlag(self, flag=True):\n self.__useAlignedColumns = flag\n\n def setPreferSingleQuotes(self):\n self.__preferDoubleQuotes = False\n\n def setPreferDoubleQuotes(self):\n self.__preferDoubleQuotes = True\n\n def setRowPartition(self, numParts):\n \"\"\"Maximum number of partitions used to format value length for column alignment\"\"\"\n self.__rowPartition = numParts\n\n def write(self, containerList, lastInOrder=None, selectOrder=None):\n self.__containerList = containerList\n for container in self.__containerList:\n self.writeContainer(container, lastInOrder=lastInOrder, selectOrder=selectOrder)\n\n def writeContainer(self, container, lastInOrder=None, selectOrder=None):\n indS = \" \" * self.__indentDefinition\n if container.getType() == \"definition\":\n self.__write(\"save_%s\" % container.getName())\n # self.__write(\"save_%s\\n\" % container.getName())\n self.__doDefinitionIndent = True\n # self.__write(indS + \"#\\n\")\n elif container.getType() == \"data\":\n if container.getGlobal():\n self.__write(\"global_\\n\")\n self.__doDefinitionIndent = False\n self.__write(\"\\n\")\n else:\n self.__write(\"data_%s\\n\" % container.getName())\n self.__doDefinitionIndent = False\n # self.__write(\"#\\n\")\n\n nmL = container.filterObjectNameList(lastInOrder=lastInOrder, selectOrder=selectOrder)\n for nm in nmL:\n obj = container.getObj(nm)\n objL = obj.getRowList()\n\n # Skip empty objects\n if not objL:\n continue\n\n # Item - value formattting\n elif len(objL) == 1:\n self.__writeItemValueFormat(obj)\n\n # Table formatting -\n elif objL and obj.getAttributeList():\n if self.__useAlignedColumns:\n self.__writeTableFormat(obj)\n else:\n self.__writeTable(obj)\n else:\n raise PdbxError(\"\")\n\n if self.__doDefinitionIndent:\n self.__write(indS + \"#\")\n else:\n self.__write(\"#\")\n\n # Add a trailing saveframe reserved word\n if container.getType() == \"definition\":\n self.__write(\"\\nsave_\\n\")\n self.__write(\"#\\n\")\n\n def __write(self, st):\n try:\n if self.__cnvCharRefs:\n self.__ofh.write(st.encode(\"ascii\", \"xmlcharrefreplace\").decode(\"ascii\"))\n elif not self.__isPy3:\n if self.__enforceAscii:\n self.__ofh.write(st.decode(\"ascii\"))\n else:\n self.__ofh.write(st)\n # self.__ofh.write(st.encode('utf-8').decode('utf-8'))\n else:\n self.__ofh.write(st)\n except Exception as e:\n logger.exception(\"write fails with %s for %r\", str(e), st)\n\n def __writeItemValueFormat(self, categoryObj):\n # indS = \" \" * self.__INDENT_DEFINITION\n myCategory = DataCategoryFormatted(categoryObj, preferDoubleQuotes=self.__preferDoubleQuotes)\n # Compute the maximum item name length within this category -\n attributeNameLengthMax = 0\n for attributeName in myCategory.getAttributeList():\n attributeNameLengthMax = max(attributeNameLengthMax, len(attributeName))\n itemNameLengthMax = self.__spacing + len(myCategory.getName()) + attributeNameLengthMax + 2\n #\n lineList = []\n # lineList.append(indS+\"#\\n\")\n lineList.append(\"\\n\")\n for attributeName, _ in myCategory.getAttributeListWithOrder():\n if self.__doDefinitionIndent:\n # - add indent --\n lineList.append(self.__indentSpace)\n\n itemName = \"_%s.%s\" % (myCategory.getName(), attributeName)\n lineList.append(itemName.ljust(itemNameLengthMax))\n\n lineList.append(myCategory.getValueFormatted(attributeName, 0))\n lineList.append(\"\\n\")\n\n self.__write(\"\".join(lineList))\n\n def __writeTableFormat(self, categoryObj):\n # indS = \" \" * self.__INDENT_DEFINITION\n myCategory = DataCategoryFormatted(categoryObj, preferDoubleQuotes=self.__preferDoubleQuotes)\n # Write the declaration of the loop_\n #\n lineList = []\n # lineList.append(indS + '#\\n')\n lineList.append(\"\\n\")\n if self.__doDefinitionIndent:\n lineList.append(self.__indentSpace)\n lineList.append(\"loop_\")\n for attributeName in myCategory.getAttributeList():\n lineList.append(\"\\n\")\n if self.__doDefinitionIndent:\n lineList.append(self.__indentSpace)\n itemName = \"_%s.%s\" % (myCategory.getName(), attributeName)\n lineList.append(itemName)\n self.__write(\"\".join(lineList))\n\n #\n # Write the data in tabular format -\n #\n # print myCategory.getName()\n # print myCategory.getAttributeList()\n\n # For speed make the following evaluation on a portion of the table\n if self.__rowPartition is not None:\n numSteps = max(1, myCategory.getRowCount() // self.__rowPartition)\n else:\n numSteps = 1\n\n formatTypeList, _ = myCategory.getFormatTypeList(steps=numSteps)\n maxLengthList = myCategory.getAttributeValueMaxLengthList(steps=numSteps)\n spacing = \" \" * self.__spacing\n #\n\n # print formatTypeList\n # print dataTypeList\n # print maxLengthList\n #\n for iRow in range(myCategory.getRowCount()):\n lineList = []\n lineList.append(\"\\n\")\n if self.__doDefinitionIndent:\n lineList.append(self.__indentSpace + \" \")\n\n for iAt in range(myCategory.getAttributeCount()):\n formatType = formatTypeList[iAt]\n maxLength = maxLengthList[iAt]\n\n if formatType == \"FT_UNQUOTED_STRING\" or formatType == \"FT_NULL_VALUE\":\n val = myCategory.getValueFormattedByIndex(iAt, iRow)\n lineList.append(val.ljust(maxLength))\n\n elif formatType == \"FT_NUMBER\":\n val = myCategory.getValueFormattedByIndex(iAt, iRow)\n lineList.append(val.rjust(maxLength))\n\n elif formatType == \"FT_QUOTED_STRING\":\n val = myCategory.getValueFormattedByIndex(iAt, iRow)\n # don't pad the last item in row condition\n if iAt == myCategory.getAttributeCount() - 1:\n lineList.append(val.ljust(len(val)))\n else:\n lineList.append(val.ljust(maxLength + 2))\n\n elif formatType == \"FT_MULTI_LINE_STRING\":\n val = myCategory.getValueFormattedByIndex(iAt, iRow)\n lineList.append(val)\n\n lineList.append(spacing)\n\n self.__write(\"\".join(lineList))\n self.__write(\"\\n\")\n if self.__useStopTokens:\n self.__write(\"stop_\\n\")\n\n def __writeTable(self, categoryObj, numSteps=5):\n indS = \" \" * self.__indentDefinition\n myCategory = DataCategoryFormatted(categoryObj, preferDoubleQuotes=self.__preferDoubleQuotes)\n # Write the declaration of the loop_\n #\n lineList = []\n lineList.append(indS + \"#\\n\")\n if self.__doDefinitionIndent:\n lineList.append(self.__indentSpace)\n lineList.append(\"loop_\")\n for attributeName in myCategory.getAttributeList():\n lineList.append(\"\\n\")\n if self.__doDefinitionIndent:\n lineList.append(self.__indentSpace)\n itemName = \"_%s.%s\" % (myCategory.getName(), attributeName)\n lineList.append(itemName)\n self.__write(\"\".join(lineList))\n\n #\n formatTypeList, _ = myCategory.getFormatTypeList(steps=numSteps)\n spacing = \" \" * self.__spacing\n #\n for iRow in range(myCategory.getRowCount()):\n lineList = []\n lineList.append(\"\\n\")\n if self.__doDefinitionIndent:\n lineList.append(self.__indentSpace + \" \")\n\n for iAt in range(myCategory.getAttributeCount()):\n formatType = formatTypeList[iAt]\n\n if formatType == \"FT_UNQUOTED_STRING\" or formatType == \"FT_NULL_VALUE\":\n val = myCategory.getValueFormattedByIndex(iAt, iRow)\n lineList.append(val)\n\n elif formatType == \"FT_NUMBER\":\n val = myCategory.getValueFormattedByIndex(iAt, iRow)\n lineList.append(val)\n\n elif formatType == \"FT_QUOTED_STRING\":\n val = myCategory.getValueFormattedByIndex(iAt, iRow)\n lineList.append(val)\n\n elif formatType == \"FT_MULTI_LINE_STRING\":\n val = myCategory.getValueFormattedByIndex(iAt, iRow)\n lineList.append(val)\n\n lineList.append(spacing)\n\n self.__write(\"\".join(lineList))\n self.__write(\"\\n\")\n if self.__useStopTokens:\n self.__write(\"stop_\\n\")\n
"},{"location":"api_reference/PdbxWriter/#mmcif.io.PdbxWriter.PdbxWriter.setRowPartition","title":"setRowPartition(self, numParts)
","text":"Maximum number of partitions used to format value length for column alignment
Source code in mmcif/io/PdbxWriter.py
def setRowPartition(self, numParts):\n \"\"\"Maximum number of partitions used to format value length for column alignment\"\"\"\n self.__rowPartition = numParts\n
"}]}
\ No newline at end of file
diff --git a/sitemap.xml b/sitemap.xml
index f6277520..a6a5656f 100644
--- a/sitemap.xml
+++ b/sitemap.xml
@@ -2,107 +2,107 @@
https://github.com/rcsb/py-mmcif/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/BinaryCifReader/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/BinaryCifWriter/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/CifFile/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/DataCategory/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/DataCategoryBase/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/DataCategoryFormatted/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/DataCategoryTyped/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/DictMethodRunner/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/DictionaryApi/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/DictionaryInclude/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/IoAdapterBase/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/IoAdapterCore/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/IoAdapterPy/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/Method/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/MethodUtils/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/PdbxContainers/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/PdbxExceptions/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/PdbxReader/
- 2023-12-03
+ 2023-12-06
daily
https://github.com/rcsb/py-mmcif/api_reference/PdbxWriter/
- 2023-12-03
+ 2023-12-06
daily
\ No newline at end of file
diff --git a/sitemap.xml.gz b/sitemap.xml.gz
index ee90f292ec27863c8e227f91ced7335ebab9e43e..ed1218ece6a30a00d4e1ce784329daf077120f00 100644
GIT binary patch
literal 381
zcmV-@0fPP?iwFo?sc>Zi|8r?{Wo=<_E_iKh0M(aGYr`-MhVT6qA@{^-2V)y)N}H|F
z!=RLw9fxZxiNRm9owfP*bJkLN-eDkLYztXD2>BH%7iT4tZ*X21Jx`~3ktU#-;X=3b
z^srxNPwAqXl)aN4LK2;|pQl|2_Jxqs>6CjBKvC;+<67cb7cZV%jikt*(`u5$H3qnx
zepe|CtHvlkhG|9U`eV+FB98eZu|uX56AdZJ=yv~#`k)N2X2t9wo6fT0F}hrBcW$hs
zx`oEUSH-E2LrLx|7aVfq`4btn;?qF`F6Ii*aIS==Zm31G1IoeSf@CLTGIfnaRW-|742(J*iM@mw1nsE9(13;XTNz>dm?
b3me&JFe3lgRPejSDY*Ipi)|#zH4gv)fgrnk
literal 380
zcmV-?0fYV@iwFqdfNW&~|8r?{Wo=<_E_iKh0M(aGYr`-MhVT0oA@{^-d)Y>s(q=34
zFes&E$Kl#aV(`~&XKnudoVJvncNoYQ+d>u(LVktH#aYSZ2b>p1&(ld>qzPzdxX|r9
zJ?z)nbGoRW%HBy2A&Jh~&(kgh`%1{^bjrO5ps4k^aV_zzix*FBMpEQ2Y4w!EH3qnz
zE~}J=Rbvz%!?YrF{V``o5y$+I*dbGjiH4M9bbEY7eNcv1(_%WyCey5#MVFiH!HsoP
zx6nBFt~eEPD9MB6ibL)^eq#asaz&Xv&A4Yg=?Ksh*k+@CHM79Q?MycQBq
zeZ0{?YZ{<6Za@jWq8?|q*TyLt0&tY{`@v!&7c6{0=nUWWS|gH^5j=M3D1}Qa5K?b6
zlRd}tK{sZ}sf`T>m8{&UYvT}7Z}D`VtB4@OJp>^=8s;rOo@=866;Y^hVZWal*ird#
aVIvz2M&$pR3NBlmf~#L+;E5qM4*&p-QM5+@