####################################################################### BioSimSpace: Making biomolecular simulation a breeze!## Copyright: 2017-2024## Authors: Lester Hedges <lester.hedges@gmail.com>## BioSimSpace is free software: you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation, either version 3 of the License, or# (at your option) any later version.## BioSimSpace is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with BioSimSpace. If not, see <http://www.gnu.org/licenses/>.#####################################################################"""Functionality for streaming wrapped Sire objects."""__author__="Lester Hedges"__email__="lester.hedges@gmail.com"__all__=["save","load","getMetadata","getSireMetadata"]importosas_osfromsire.legacyimportMolas_SireMolfromsire.legacyimportSystemas_SireSystemfromsireimportstreamas_NewSireStreamfromsireimportsystemas_NewSireSystemfrom..import_isVerbosefrom.._ExceptionsimportStreamErroras_StreamErrorfrom.._SireWrappers._sire_wrapperimportSireWrapperas_SireWrapperfrom..import_SireWrappers
[docs]defsave(sire_object,filebase):""" Stream a wrapped Sire object to file. Parameters ---------- sire_object : :class:`System <BioSimSpace._SireWrappers.SireWrapper>` A wrapped Sire object. filebase : str The base name of the binary output file. """# Validate input.ifnotisinstance(sire_object,_SireWrapper)andnotisinstance(sire_object,_SireWrappers.SearchResult):raiseTypeError("'sire_object' must be of type 'BioSimSpace._SireWrappers.SireWrapper'.")iftype(filebase)isnotstr:raiseTypeError("'filebase' must be of type 'str'.")try:_add_metadata(sire_object)except:raise_StreamError("Unable to add metadata to streamed object!")try:ifisinstance(sire_object,_SireWrappers.System):_NewSireStream.save(_NewSireSystem.System(sire_object._sire_object),f"{filebase}.bss")else:_NewSireStream.save(sire_object._sire_object,f"{filebase}.bss")exceptExceptionase:msg=f"Failed to stream {sire_object} to file '{filebase}.bss'."if_isVerbose():raiseIOError(msg)fromeelse:raiseIOError(msg)fromNone
[docs]defload(file):""" Stream a wrapped Sire object from file. Parameters ---------- file : str The path to the binary file containing the streamed object. """# Validate input.ifnot_os.path.isfile(file):raiseTypeError(f"The binary file '{file}' doesn't exist!")# Try to load the object.try:# Stream from file.sire_object=_NewSireStream.load(file)# Construct the wrapped object.ifisinstance(sire_object,_NewSireSystem.System):return_SireWrappers.System(sire_object._system)elifisinstance(sire_object,_SireMol.Molecule):return_SireWrappers.Molecule(sire_object)elifisinstance(sire_object,_SireMol.MoleculeGroup):return_SireWrappers.Molecules(sire_object)elifisinstance(sire_object,_SireMol.Residue):return_SireWrappers.Residue(sire_object)elifisinstance(sire_object,_SireMol.Atom):return_SireWrappers.Atom(sire_object)elif"Selector"insire_object.__class__.__name__:return_SireWrappers.SearchResult(sire_object)else:raise_StreamError(f"Unable to stream object of type {type(sire_object)}.")exceptExceptionase:msg=f"Failed to stream {object} from file '{file}'."if_isVerbose():raiseIOError(msg)fromeelse:raiseIOError(msg)fromNone
defgetMetadata(file):""" Get the metadata from a stream file. Parameters ---------- file : str The path to a stream file. Returns ------- metadata : dict The metadata associated with the file. If none is present, then an empty dictionary will be returned. """ifnot_os.path.isfile(file):raiseValueError(f"Unable to locate stream file: {file}")try:metadata=_NewSireStream.get_data_header(file).property("bss_metadata")except:metadata={}returnmetadatadefgetSireMetadata(file):""" Get the Sire metadata from a stream file. Parameters ---------- file : str The path to a stream file. Returns ------- metadata : dict The Sire metadata associated with the file. If none is present, then an empty dictionary will be returned. """ifnot_os.path.isfile(file):raiseValueError(f"Unable to locate stream file: {file}")try:# Convert the header to a list of lines.header=_NewSireStream.get_data_header(file).toString().split("\n")# The overall metadata.metadata={}# The system specific metadata.system_data={}forlineinheader:# This is additional System data.ifline.startswith("* "):line=line.replace("*","")_,k,v=line.split(":",2)system_data[k.strip()]=v.strip()# This line contains data.elifline.startswith("* "):# Convert to a nicely formatted key:value record.line=line.replace("*","")k,v=line.split(":",1)# Handle the System key separately, since it contains multiple records.iflen(system_data)!=0:metadata["System"]=system_datasystem_data={}else:metadata[k.strip()]=v.strip()except:metadata={}returnmetadatadef_add_metadata(sire_object):""" Internal function to tag a Sire object with metadata. Parameters ---------- sire_object : :class:`System <BioSimSpace._SireWrappers.SireWrapper>` The wrapped Sire object to stream. Returns ------- metadata : dict The metadata associated with the object. """ifnotisinstance(sire_object,_SireWrapper)andnotisinstance(sire_object,_SireWrappers.SearchResult):raiseTypeError("'sire_object' must be of type 'BioSimSpace._SireWrappers.SireWrapper'.")fromsireimport__version__as_sire_versionfromsireimport__revisionid__as_sire_revisionidfrom..import_version# Work out the name of the Sandpit.try:sandpit=sire_object.__module__.split("Sandpit")[1].split(".")[1]except:sandpit="None"# Extract the BioSimSpace version and revision ID._bss_version=_version.get_versions()["version"].split("+")[0]_bss_revisionid=_version.get_versions()["full-revisionid"][0:7]# Create the object name.obj_name=f"{sire_object.__module__}.{sire_object.__class__.__name__}"# Generate the metadata.metadata={"bss_object":obj_name,"bss_version":_bss_version,"bss_revisionid":_bss_revisionid,"sire_version":_sire_version,"sire_revisionid":_sire_revisionid,"sandpit":sandpit,}# Apply the metadata to the global Sire stream header._NewSireStream.set_header_property("bss_metadata",metadata)returnmetadata