Commit 5c646b02 authored by peastman's avatar peastman Committed by GitHub
Browse files

Merge pull request #1668 from peastman/bond

Created Bond class that can store bond type and order
parents b465c982 ebb7a083
......@@ -229,8 +229,8 @@ def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM,
def main():
if sys.version_info < (2, 6):
reportError("OpenMM requires Python 2.6 or better.")
if sys.version_info < (2, 7):
reportError("OpenMM requires Python 2.7 or better.")
if platform.system() == 'Darwin':
macVersion = [int(x) for x in platform.mac_ver()[0].split('.')]
if tuple(macVersion) < (10, 5):
......
......@@ -6,7 +6,7 @@ from __future__ import absolute_import
__docformat__ = "epytext en"
__author__ = "Peter Eastman"
__copyright__ = "Copyright 2015, Stanford University and Peter Eastman"
__copyright__ = "Copyright 2016, Stanford University and Peter Eastman"
__credits__ = []
__license__ = "MIT"
__maintainer__ = "Peter Eastman"
......@@ -44,3 +44,10 @@ PME = forcefield.PME
HBonds = forcefield.HBonds
AllBonds = forcefield.AllBonds
HAngles = forcefield.HAngles
Single = topology.Single
Double = topology.Double
Triple = topology.Triple
Aromatic = topology.Aromatic
Amide = topology.Amide
......@@ -36,6 +36,7 @@ from math import sqrt
from simtk.openmm.app import Topology
from simtk.openmm.app import PDBFile
from simtk.openmm.app.internal import amber_file_parser
from simtk.openmm.app.internal.singleton import Singleton
from . import forcefield as ff
from . import element as elem
import simtk.unit as u
......@@ -44,27 +45,27 @@ from simtk.openmm.app.internal.unitcell import computePeriodicBoxVectors
# Enumerated values for implicit solvent model
class HCT(object):
class HCT(Singleton):
def __repr__(self):
return 'HCT'
HCT = HCT()
class OBC1(object):
class OBC1(Singleton):
def __repr__(self):
return 'OBC1'
OBC1 = OBC1()
class OBC2(object):
class OBC2(Singleton):
def __repr__(self):
return 'OBC2'
OBC2 = OBC2()
class GBn(object):
class GBn(Singleton):
def __repr__(self):
return 'GBn'
GBn = GBn()
class GBn2(object):
class GBn2(Singleton):
def __repr__(self):
return 'GBn2'
GBn2 = GBn2()
......
......@@ -45,6 +45,7 @@ import simtk.openmm as mm
import simtk.unit as unit
from . import element as elem
from simtk.openmm.app import Topology
from simtk.openmm.app.internal.singleton import Singleton
def _convertParameterToNumber(param):
if unit.is_quantity(param):
......@@ -89,44 +90,44 @@ def _createFunctions(force, functions):
# Enumerated values for nonbonded method
class NoCutoff(object):
class NoCutoff(Singleton):
def __repr__(self):
return 'NoCutoff'
NoCutoff = NoCutoff()
class CutoffNonPeriodic(object):
class CutoffNonPeriodic(Singleton):
def __repr__(self):
return 'CutoffNonPeriodic'
CutoffNonPeriodic = CutoffNonPeriodic()
class CutoffPeriodic(object):
class CutoffPeriodic(Singleton):
def __repr__(self):
return 'CutoffPeriodic'
CutoffPeriodic = CutoffPeriodic()
class Ewald(object):
class Ewald(Singleton):
def __repr__(self):
return 'Ewald'
Ewald = Ewald()
class PME(object):
class PME(Singleton):
def __repr__(self):
return 'PME'
PME = PME()
# Enumerated values for constraint type
class HBonds(object):
class HBonds(Singleton):
def __repr__(self):
return 'HBonds'
HBonds = HBonds()
class AllBonds(object):
class AllBonds(Singleton):
def __repr__(self):
return 'AllBonds'
AllBonds = AllBonds()
class HAngles(object):
class HAngles(Singleton):
def __repr__(self):
return 'HAngles'
HAngles = HAngles()
......
"""
Creates a subclass for all classes intended to be a singleton. This
maintains the correctness of instance is instance even following
pickling/unpickling
"""
class Singleton(object):
_inst = None
def __new__(cls):
if cls._inst is None:
cls._inst = super(Singleton, cls).__new__(cls)
return cls._inst
def __reduce__(self):
return repr(self)
......@@ -6,7 +6,7 @@ Simbios, the NIH National Center for Physics-Based Simulation of
Biological Structures at Stanford, funded under the NIH Roadmap for
Medical Research, grant U54 GM072970. See https://simtk.org.
Portions copyright (c) 2012-2015 Stanford University and the Authors.
Portions copyright (c) 2012-2016 Stanford University and the Authors.
Authors: Peter Eastman
Contributors:
......@@ -32,12 +32,41 @@ from __future__ import absolute_import
__author__ = "Peter Eastman"
__version__ = "1.0"
from collections import namedtuple
import os
import xml.etree.ElementTree as etree
from simtk.openmm.vec3 import Vec3
from simtk.openmm.app.internal.singleton import Singleton
from simtk.unit import nanometers, sqrt, is_quantity
from copy import deepcopy
# Enumerated values for bond type
class Single(Singleton):
def __repr__(self):
return 'Single'
Single = Single()
class Double(Singleton):
def __repr__(self):
return 'Double'
Double = Double()
class Triple(Singleton):
def __repr__(self):
return 'Triple'
Triple = Triple()
class Aromatic(Singleton):
def __repr__(self):
return 'Aromatic'
Aromatic = Aromatic()
class Amide(Singleton):
def __repr__(self):
return 'Amide'
Amide = Amide()
class Topology(object):
"""Topology stores the topological information about a system.
......@@ -155,7 +184,7 @@ class Topology(object):
residue._atoms.append(atom)
return atom
def addBond(self, atom1, atom2):
def addBond(self, atom1, atom2, type=None, order=None):
"""Create a new bond and add it to the Topology.
Parameters
......@@ -164,8 +193,13 @@ class Topology(object):
The first Atom connected by the bond
atom2 : Atom
The second Atom connected by the bond
type : object=None
The type of bond to add. Allowed values are None, Single, Double, Triple,
Aromatic, or Amide.
order : int=None
The bond order, or None if it is not specified
"""
self._bonds.append((atom1, atom2))
self._bonds.append(Bond(atom1, atom2, type, order))
def chains(self):
"""Iterate over all Chains in the Topology."""
......@@ -387,7 +421,7 @@ class Residue(object):
return "<Residue %d (%s) of chain %d>" % (self.index, self.name, self.chain.index)
class Atom(object):
"""An Atom object represents a residue within a Topology."""
"""An Atom object represents an atom within a Topology."""
def __init__(self, name, element, index, residue, id):
"""Construct a new Atom. You should call addAtom() on the Topology instead of calling this directly."""
......@@ -404,3 +438,32 @@ class Atom(object):
def __repr__(self):
return "<Atom %d (%s) of chain %d residue %d (%s)>" % (self.index, self.name, self.residue.chain.index, self.residue.index, self.residue.name)
class Bond(namedtuple('Bond', ['atom1', 'atom2'])):
"""A Bond object represents a bond between two Atoms within a Topology.
This class extends tuple, and may be interpreted as a 2 element tuple of Atom objects.
It also has fields that can optionally be used to describe the bond order and type of bond."""
def __new__(cls, atom1, atom2, type=None, order=None):
"""Create a new Bond. You should call addBond() on the Topology instead of calling this directly."""
bond = super(Bond, cls).__new__(cls, atom1, atom2)
bond.type = type
bond.order = order
return bond
def __getnewargs__(self):
"Support for pickle protocol 2: http://docs.python.org/2/library/pickle.html#pickling-and-unpickling-normal-class-instances"
return self[0], self[1], self.type, self.order
def __deepcopy__(self, memo):
return Bond(self[0], self[1], self.type, self.order)
def __repr__(self):
s = "Bond(%s, %s" % (self[0], self[1])
if self.type is not None:
s = "%s, type=%s" % (s, self.type)
if self.order is not None:
s = "%s, order=%d" % (s, self.order)
s += ")"
return s
import pickle
import sys
import unittest
from simtk.openmm.app import *
......@@ -26,6 +27,14 @@ class TestTopology(unittest.TestCase):
"""Test getters for number of atoms, residues, chains."""
self.check_pdbfile('systems/1T2Y.pdb', 271, 25, 1)
def test_bondtype_singleton(self):
""" Tests that the bond types are really singletons """
self.assertIs(Single, pickle.loads(pickle.dumps(Single)))
self.assertIs(Double, pickle.loads(pickle.dumps(Double)))
self.assertIs(Triple, pickle.loads(pickle.dumps(Triple)))
self.assertIs(Aromatic, pickle.loads(pickle.dumps(Aromatic)))
self.assertIs(Amide, pickle.loads(pickle.dumps(Amide)))
def test_residue_bonds(self):
"""Test retrieving bonds for a residue produces expected results."""
# Create a test topology
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment