Source code for sire.convert

__all__ = [
    "biosimspace_to_sire",
    "gemmi_to_sire",
    "openmm_to_sire",
    "rdkit_to_sire",
    "sire_to_biosimspace",
    "sire_to_gemmi",
    "sire_to_rdkit",
    "sire_to_openmm",
    "supported_formats",
    "to",
    "to_biosimspace",
    "to_rdkit",
    "to_openmm",
    "to_sire",
]

from .. import use_new_api as _use_new_api

_use_new_api()

# Importing the openmm sub-module so that it autocompletes when used
from . import openmm  # noqa: F401


def _to_selectormol(obj):
    from ..mol import SelectorMol

    if hasattr(obj, "molecules"):
        return obj.molecules()
    elif isinstance(obj, list):
        mols = []

        for o in obj:
            mols.append(_to_selectormol(o))

        return SelectorMol(mols)
    else:
        return SelectorMol(obj)


[docs] def supported_formats(): """ Return the current supported object formats for conversion """ from ..legacy.Convert import supported_formats as _supported_formats return _supported_formats()
[docs] def to(obj, format: str = "sire", map=None): """ Convert the passed object from its current object format to the specified object format (default "sire"). Typically this will be converting from, e.g. a BioSimSpace, OpenMM or rdkit molecule to a sire molecule (or from a list of molecules to a SelectorMol). Args: obj: The input object to convert format: str (default "sire") The format to convert to map: The property map to use for the conversion """ format = format.lower() if format == "sire": return to_sire(obj, map=map) elif format == "rdkit": return to_rdkit(obj, map=map) elif format == "gemmi": return to_gemmi(obj, map=map) elif format == "biosimspace": return to_biosimspace(obj, map=map) elif format == "openmm": return to_openmm(obj, map=map) else: raise ValueError( f"Cannot convert {obj} as the format '{format}' is " "not recognised." )
[docs] def to_sire(obj, map=None): """ Convert the passed object from its current object format to a sire object format. Typically this will be converting from, e.g. an openmm or rdkit molecule to a sire molecule (or from a list of molecules to a SelectorMol). """ if "sire" in str(type(obj)): # already a sire object? return obj if not isinstance(obj, list): obj = [obj] # create lists of objects of the same type (in the same order) typed_objs = [] last_type = None def _to_type(o): t = str(type(o)) if "sire" in t: return "sire" elif "BioSimSpace" in t or "biosimspace" in t: return "biosimspace" elif "rdkit" in t: return "rdkit" elif "openmm" in t: return "openmm" elif "gemmi" in t: return "gemmi" else: raise TypeError( f"Cannot convert '{o}' as it is of unrecognised type {type(o)}" ) # sort all the objects into lists of types (preserving the order) for o in obj: t = _to_type(o) if t != last_type: last_type = t typed_objs.append((t, [])) typed_objs[-1][1].append(o) converted = [] from ..system import System for typ in typed_objs: c = None if typ[0] == "sire": c = typ[1] elif typ[0] == "biosimspace": c = biosimspace_to_sire(typ[1], map=map) elif typ[0] == "rdkit": c = rdkit_to_sire(typ[1], map=map) elif typ[0] == "openmm": c = openmm_to_sire(typ[1], map=map) elif typ[0] == "gemmi": c = gemmi_to_sire(typ[1], map=map) else: raise TypeError(f"Unrecognised type {typ[0]}") if not isinstance(c, System): c = c.molecules() converted.append(c) if len(converted) == 0: return None elif len(converted) == 1: mols = converted[0] else: mols = converted[0] for i in range(1, len(converted)): mols += converted[i] if isinstance(mols, System): return mols elif len(mols) == 1: return mols[0] else: return mols
[docs] def to_biosimspace(obj, map=None): """ Convert the passed object from its current object format to a BioSimSpace object format. """ return sire_to_biosimspace(to_sire(obj, map=map), map=map)
[docs] def to_rdkit(obj, map=None): """ Convert the passed object from its current object format to a rdkit object format. """ return sire_to_rdkit(to_sire(obj, map=map), map=map)
def to_gemmi(obj, map=None): """ Convert the passed object from its current object format to a gemmi object format. """ return sire_to_gemmi(to_sire(obj, map=map), map=map)
[docs] def to_openmm(obj, map=None): """ Convert the passed object from its current object format to an openmm object format. """ return sire_to_openmm(to_sire(obj, map=map), map=map)
[docs] def biosimspace_to_sire(obj, map=None): """ Convert the passed BioSimSpace object (either a Molecule or list of Molecules) to a sire equivalent """ from ..system import System if isinstance(obj, list): if len(obj) == 0: return None elif len(obj) == 1: return biosimspace_to_sire(obj[0], map=map) else: converted = biosimspace_to_sire(obj[0], map=map) if System.is_system(converted): converted = System(converted) if converted is not None: converted = converted.molecules() for o in obj[1:]: c = biosimspace_to_sire(o, map=map) if converted is None and c is not None: converted = c.molecules() elif c is not None: converted += c.molecules() if converted is None: return None elif len(converted) == 1: return converted[0] else: return converted else: if not hasattr(obj, "_sire_object"): raise TypeError( f"The object {obj} of type {type(obj)} does not look like a " "supported BioSimSpace object that can be converted to a " "sire object. Supported objects are Molecule." ) obj = obj._sire_object if System.is_system(obj): return System(obj) obj = obj.molecules() if obj.num_molecules() == 1: return obj[0] elif obj.num_molecules() == 0: return None else: return obj
_BSS = None
[docs] def sire_to_biosimspace(obj, map=None): """ Convert the passed sire object (either a molecule or list of molecules) to a BioSimSpace equivalent """ import sys if "BioSimSpace" not in sys.modules: raise ModuleNotFoundError( "BioSimSpace is not available. Please make sure you have " "imported BioSimSpace before `sire`, e.g. have run " "`import BioSimSpace as BSS` in your script before " "importing sire" ) global _BSS # Try to inspect the stack to work out the module from which this # function was called. try: frame = sys._getframe() for frame_idx in range(0, 3): frame = frame.f_back module = frame.f_globals["__name__"] except Exception: module = None # Was this function called from a BioSmSpace Sandpit? if module and module.startswith("BioSimSpace.Sandpit."): sandpit = ".".join(module.split(".")[0:3]) _BSS = sys.modules[sandpit] else: _BSS = sys.modules["BioSimSpace"] from ..system import System if isinstance(obj, System): return _BSS._SireWrappers.System(obj._system) obj = _to_selectormol(obj) converted = [] for mol in obj: converted.append(_BSS._SireWrappers.Molecule(mol)) if len(converted) == 0: return None elif len(converted) == 1: return converted[0] else: return converted
[docs] def openmm_to_sire(obj, map=None): """ Convert the passed OpenMM.System to the sire equivalent """ if not isinstance(obj, list): obj = [obj] try: from ..legacy.Convert import openmm_to_sire as _openmm_to_sire except Exception: raise ModuleNotFoundError( "openmm is not available. Please install via " "'conda install -c conda-forge openmm'" ) from ..base import create_map results = [] map = create_map(map) for o in obj: results.append(_openmm_to_sire(o, map)) mols = _to_selectormol(results) if mols is None: return None mols = mols.molecules() if len(mols) == 1: return mols[0] else: return mols
[docs] def sire_to_openmm(obj, map=None): """ Convert the passed sire object (either a molecule or list of molecules) to an OpenMM equivalent """ # will eventually support System too... from ..system import System from ..base import create_map map = create_map(map) if System.is_system(obj): # bring in system-level properties if not map.specified("space"): map.set("space", obj.space()) if not map.specified("time"): map.set("time", obj.time()) obj = _to_selectormol(obj) try: from ..legacy.Convert import sire_to_openmm as _sire_to_openmm except Exception: raise ModuleNotFoundError( "openmm is not available. Please install via " "'conda install -c conda-forge openmm'" ) mols = _sire_to_openmm(obj, map=map) return mols
[docs] def rdkit_to_sire(obj, map=None): """ Convert the passed rdkit object (either a molecule or list of molecules) to the sire equivalent """ if not isinstance(obj, list): obj = [obj] try: from ..legacy.Convert import rdkit_to_sire as _rdkit_to_sire except Exception: raise ModuleNotFoundError( "rdkit is not available. Please install via " "'conda install -c conda-forge rdkit'" ) from ..base import create_map mols = _rdkit_to_sire(obj, map=create_map(map)) if mols is None: return None mols = mols.molecules() if len(mols) == 1: return mols[0] else: return mols
[docs] def sire_to_rdkit(obj, map=None): """ Convert the passed sire object (either a molecule or list of molecules) to a rdkit equivalent """ obj = _to_selectormol(obj) # Now convert to an rdkit object try: from ..legacy.Convert import sire_to_rdkit as _sire_to_rdkit except Exception: raise ModuleNotFoundError( "rdkit is not available. Please install via " "'conda install -c conda-forge rdkit'" ) from ..base import create_map mols = _sire_to_rdkit(obj, map=create_map(map)) if mols is None: return None elif len(mols) == 1: return mols[0] else: return mols
[docs] def gemmi_to_sire(obj, map=None): """ Convert the passed gemmi Structure to the sire equivalent """ try: from ..legacy.Convert import gemmi_to_sire as _gemmi_to_sire except Exception: raise ModuleNotFoundError( "gemmi is not available. Please install via " "'conda install -c conda-forge gemmi'" ) from ..base import create_map map = create_map(map) if not isinstance(obj, list): obj = [obj] results = [] from ..system import System for o in obj: s = System(_gemmi_to_sire(o, map=map)) if hasattr(o, "_sire_metadata"): metadata = o._sire_metadata() if metadata is not None: s.set_property("metadata", metadata) results.append(s) if len(results) == 1: return results[0] else: return results
_gemmi_metadata = {} def _find_sire_gemmi_metadata(obj): """ Find the sire metadata associated with the passed gemmi object """ global _gemmi_metadata if obj in _gemmi_metadata: return _gemmi_metadata[obj] else: return None
[docs] def sire_to_gemmi(obj, map=None): """ Convert the passed sire object to a gemmi structure """ try: from ..legacy.Convert import sire_to_gemmi as _sire_to_gemmi except Exception: raise ModuleNotFoundError( "rdkit is not available. Please install via " "'conda install -c conda-forge rdkit'" ) if not isinstance(obj, list): obj = [obj] from ..system import System from ..base import create_map map = create_map(map) result = [] for o in obj: if System.is_system(o): try: o = o._system except Exception: pass else: s = System() s.add(_to_selectormol(o)) o = s._system if o.contains_property("metadata"): metadata = o.property("metadata") else: metadata = None g = _sire_to_gemmi(o, map=map) if metadata is not None: # add metadata to the gemmi structure. We have to use # this convoluted way of doing it as gemmi doesn't # allow us to add arbitrary metadata to the structure # and the class is not extensible (can't be monkey patched) global _gemmi_metadata _gemmi_metadata[g] = metadata g.__class__._sire_metadata = _find_sire_gemmi_metadata result.append(g) if len(result) == 1: return result[0] else: return result