Source code for sloth.mmcif.handler

from typing import Callable, Optional, List, Tuple, Union
from .parser import MMCIFParser
from .writer import MMCIFWriter
from .exporter import JSONExporter
from .importer import JSONImporter
from .models import MMCIFDataContainer, DataBlock, Category, DataSourceFormat


[docs] class MMCIFHandler: """A class to handle reading and writing mmCIF files with high-performance gemmi backend."""
[docs] def __init__(self): """Initialize the handler with gemmi backend for optimal performance.""" self._parser = None self._writer = None self._file_obj = None
[docs] def read( self, filename: str, categories: Optional[List[str]] = None ) -> MMCIFDataContainer: """ Parse an mmCIF file and returns a data container using gemmi's high-performance backend. :param filename: The name of the file to parse. :type filename: str :param categories: The categories to parse. If None, all categories are included. :type categories: Optional[List[str]] :return: The data container with lazy-loaded items. :rtype: MMCIFDataContainer """ self._parser = MMCIFParser( categories=categories, ) container = self._parser.parse(filename) return container
[docs] def write( self, mmcif: MMCIFDataContainer, filename: Optional[str] = None ) -> None: """ Writes a data container to a file using gemmi's high-performance backend. :param mmcif: The data container to write. :type mmcif: MMCIFDataContainer :param filename: Optional filename to write to. If not provided, uses pre-set file object. :type filename: Optional[str] :return: None """ self._writer = MMCIFWriter() if filename: # Write to specified filename with open(filename, 'w') as file_obj: self._writer.write(file_obj, mmcif) elif hasattr(self, "_file_obj") and self._file_obj: # Write to pre-set file object self._writer.write(self._file_obj, mmcif) else: raise IOError("No filename provided and file is not open for writing")
[docs] def export( self, mmcif: MMCIFDataContainer, file_path: Optional[str] = None, **kwargs ) -> Optional[str]: """ Export mmCIF data to JSON format. :param mmcif: The data container to export :type mmcif: MMCIFDataContainer :param file_path: Path to save the file (optional) :type file_path: Optional[str] :param kwargs: Additional options (e.g., indent, quiet) :return: String representation if no file_path provided, otherwise None :rtype: Optional[str] """ return self._export_json(mmcif, file_path, **kwargs)
[docs] def load( self, file_path: str, **kwargs ) -> MMCIFDataContainer: """ Import mmCIF data from JSON format. :param file_path: Path to the JSON file to import :type file_path: str :param kwargs: Additional options :return: An MMCIFDataContainer instance :rtype: MMCIFDataContainer """ return self._import_json(file_path, **kwargs)
# Private methods for specific format handling def _export_json( self, mmcif: MMCIFDataContainer, file_path: Optional[str], **kwargs ) -> Optional[str]: """Export to JSON format (always nested).""" denormalize = kwargs.get('denormalize', False) exporter = JSONExporter(quiet=kwargs.get('quiet', False), denormalize=denormalize) indent = kwargs.get('indent', None) return exporter.export_data(mmcif, file_path, indent) def _import_json( self, file_path: str, **kwargs ) -> MMCIFDataContainer: """Import from JSON format (assumes nested structure).""" importer = JSONImporter() container = importer.import_data(file_path) container.source_format = DataSourceFormat.JSON return container