Source code for polytop.Monomer

from __future__ import annotations
import copy
import json
from typing import Tuple, Union, List

from .Junction import Junction, Junctions
from .Polymer import Polymer
from .Bonds import Bond
from .Topology import Topology
    
[docs] class Monomer: """ Represents a monomer with its properties in a molecular system. :param topology: the Topology object used to create this Monomer. :type topology: Topology :param junctions: a list of Junction objects or Junctions object containing all Junctions which will be present in this Monomer. :type junctions: Union[Junctions, List[Junction]] """ def __init__(self, topology: Topology, junctions: Union[Junctions, List[Junction]]): """ Represents a monomer with its properties in a molecular system. :param topology: the Topology object used to create this Monomer. :type topology: Topology :param junctions: a list of Junction objects or Junctions object containing all Junctions which will be present in this Monomer. :type junctions: Union[Junctions, List[Junction]] """ self.topology = topology if isinstance(junctions, Junctions): self.junctions = junctions else: junctions_obj = Junctions() for junction in junctions: junctions_obj.add(junction) self.junctions = junctions_obj
[docs] @classmethod def from_Polymer(cls, polymer: Polymer) -> Monomer: """ Convert a Polymer object to a Monomer object. Useful for creating Polymeric branches of a set size and converting them back to a Monomer so that they can be polymerised onto another Polymer. :param polymer: a Polymer to convert. :type polymer: Polymer :raises ValueError: if the monomer atom in one of the Polymer's Junctions is not present. :raises ValueError: if the residue atom in one of the Polymer's Junctions is not present. :return: a new Monomer which has the same attributes (Topology and Junctions) as the provided Polymer. :rtype: Monomer """ topology_copy = polymer.topology.copy() junctions_copy = [] for junction in polymer.junctions: monomer_atom_id = junction.monomer_atom.atom_id residue_atom_id = junction.residue_atom.atom_id monomer_atom = topology_copy.get_atom(monomer_atom_id) residue_atom = topology_copy.get_atom(residue_atom_id) if monomer_atom is None: raise ValueError(f"Could not find atom {monomer_atom_id} for junction") if residue_atom is None: raise ValueError(f"Could not find atom {residue_atom_id} for junction") junctions_copy.append(Junction(monomer_atom, residue_atom, junction.name)) return cls(topology_copy, junctions_copy)
[docs] def copy(self) -> Monomer: """ Method to duplicate a Monomer, which leverages the Topology.copy() function. :raises ValueError: if the monomer atom in one of the Polymer's Junctions is not present. :raises ValueError: if the residue atom in one of the Polymer's Junctions is not present. :return: a new Monomer which has the same attributes as this Monomer. :rtype: Monomer """ new_topology = self.topology.copy() new_junctions = Junctions() for junction in self.junctions: monomer_atom_id = junction.monomer_atom.atom_id residue_atom_id = junction.residue_atom.atom_id monomer_atom = new_topology.get_atom(monomer_atom_id) residue_atom = new_topology.get_atom(residue_atom_id) if monomer_atom is None: raise ValueError(f"Could not find atom {monomer_atom_id}") if residue_atom is None: raise ValueError(f"Could not find atom {residue_atom_id}") new_junctions.add(Junction(monomer_atom, residue_atom, junction.name)) new_monomer = Monomer(new_topology, new_junctions) return new_monomer
[docs] def renumber_atoms(self, start: int): """ Renumber the ids of Atoms in the Topology starting from a given number. Each atom's new id number is equal to its current id number plus the value of start. E.g. an atom with and id of 1 renumbered with a start value of 10 will have a new id of 11. :param start: value that will be added to the atom's existing ids to renumber them. :type start: int """ self.topology.renumber_atoms(start)
[docs] def to_dict(self) -> dict: """ Convert this Monomer to a dictionary representation. The structure of the dictionary is as below: {"topology": self.topology.to_dict(), "junctions": self.junctions.to_dict()} :return: a dictionary containing references to the dictionary representations of this Monomer's Topology and Junctions attributes. :rtype: dict """ return{ "topology": self.topology.to_dict(), "junctions": self.junctions.to_dict() }
[docs] @classmethod def from_dict(cls, data: dict) -> Monomer: """ Create a new Monomer from a dictionary, such as that created with Monomer.to_dict(). The structure of the dictionary is as below: {"topology": self.topology.to_dict(), "junctions": self.junctions.to_dict()} :param data: dictionary containing data to make a Monomer, generate with 'to_dict()'. :type data: dict :return: a new Monomer :rtype: Monomer """ topology = Topology.from_dict(data["topology"]) atoms = topology.atoms junctions = Junctions.from_dict(data["junctions"], atoms) return cls(topology, junctions)
[docs] def save(self, file_path: str): """ Save and export the Monomer to a JSON text dump. :param file_path: path to and desired name of output file. :type file_path: str """ with open(file_path, "w") as f: json.dump(self.to_dict(), f)
[docs] @classmethod def load(cls, file_path: str) -> Monomer: """ Load a JSON text dump of a Monomer, generated with Monomer.save(), to a new Monomer. :param file_path: path to the Monomer JSON dictionary text dump file. :type file_path: str :return: a new Monomer :rtype: Monomer """ with open(file_path, "r") as f: data = json.load(f) return cls.from_dict(data)