def _rename_water_molecule(molecule): """Internal function to rename residues/atoms in a water molecule to match the naming conventions used by GROMACS. Parameters ---------- molecule : Sire.Mol.Molecule A Sire Molecule object. Returns ------- molecule : Sire.Mol.Molecule The updated Sire Molecule object. """ # Make the molecule editable. molecule = molecule.edit() # In GROMACS, all water molecules must be given the residue label "SOL". # We extract all of the waters from the system and relabel the # residues as appropriate. # # We need to work out what to do if existing water molecules don't contain # all of the required atoms, e.g. if we have crystal water oxygen sites # from a PDB file, or if the system is to be solvated with a 4- or 5-point # water model (where we need to add virtual sites). # Update the molecule with the new residue name. molecule = molecule.residue(_SireMol.ResIdx(0)) \ .rename(_SireMol.ResName("SOL")) \ .molecule() # Index for the hydrogen atoms. hydrogen_idx = 1 # Gromacs water models use HW1/HW2 for hydrogen atoms at OW for water. for atom in molecule.atoms(): try: # Hydrogen. if atom.property("element") == _SireMol.Element("H"): molecule = molecule.atom(atom.number()) \ .rename(_SireMol.AtomName("HW%d" % hydrogen_idx)) \ .molecule() hydrogen_idx += 1 # Oxygen. elif atom.property("element") == _SireMol.Element("O"): molecule = molecule.atom(atom.number()) \ .rename(_SireMol.AtomName("OW")) \ .molecule() # Otherwise, try to infer the element from the atom name. except: # Strip all digits from the name. name = "".join([x for x in atom.name().value() if not x.isdigit()]) # Remove any whitespace. name = name.replace(" ", "") # Try to infer the element. element = _SireMol.Element.biologicalElement(name) # Hydrogen. if element == _SireMol.Element("H"): molecule = molecule.atom(atom.number()) \ .rename(_SireMol.AtomName("HW%d" % hydrogen_idx)) \ .molecule() hydrogen_idx += 1 # Oxygen. elif element == _SireMol.Element("O"): molecule = molecule.atom(atom.number()) \ .rename(_SireMol.AtomName("OW")) \ .molecule() # Commit and return the updated molecule. return molecule.commit()
def _restrain_backbone(system): """Restrain protein backbone atoms. Parameters ---------- system : Sire.System.System A Sire molecular system. """ # Copy the original system. s = system # A list of amino acid name abbreviations. # Since we only want to restrain atoms in protein backbones, we compare # molecule residue names against this list in order to determine whether # the molecule is a protein. amino_acids = ["ALA", "CYS", "ASP", "GLU", "PHE", "GLY", "HIS", "ILE", "LYS", "LEU", "MET", "ASN", "PRO", "GLN", "ARG", "SER", "THR", "SEC", "VAL", "TRP", "TYR"] # Loop over all molecules by number. for n in s.molNums(): # Extract the molecule and make it editable. m = s.molecule(n).edit() # Initialise a list of protein residues. protein_residues = [] # Compare each residue name against the amino acid list. for res in m.residues(): # This residue is an amino acid. if res.name().value().upper() in amino_acids: protein_residues.append(res.index()) # Loop over all of the protein residues. for residx in protein_residues: # Loop over all of the atoms in the residue. for atom in m.residue(residx).atoms(): # Try to compare the atom element property against the list of # backbone atoms and set the "restrained" property if a match # is found. try: element = atom.property("element") if element == _SireMol.Element("CA") or \ element == _SireMol.Element("N") or \ element == _SireMol.Element("C") or \ element == _SireMol.Element("O"): m = m.atom(atom.index()).setProperty("restrained", 1.0).molecule() except: pass # Update the system. s.update(m.commit()) # Return the new system. return s