diff --git a/topology/core/topology.py b/topology/core/topology.py index 673b32b42..c83a58018 100644 --- a/topology/core/topology.py +++ b/topology/core/topology.py @@ -1,8 +1,14 @@ import numpy as np import unyt as u +import warnings from topology.core.connection import Connection from topology.core.bond import Bond +from topology.core.angle import Angle +from topology.core.potential import Potential +from topology.core.bond_type import BondType +from topology.core.angle_type import AngleType +from topology.exceptions import TopologyError class Topology(object): @@ -17,11 +23,15 @@ def __init__(self, name="Topology", box=None): if name is not None: self._name = name self._box = box - self._site_list = list() - self._connection_list = list() + self._sites = list() + self._connections = list() + self._bonds = list() + self._angles = list() - def add_site(self, site): - self._site_list.append(site) + self._atom_types = list() + self._connection_types = list() + self._bond_types = list() + self._angle_types = list() @property def name(self): @@ -39,41 +49,188 @@ def box(self): def box(self, box): self._box = box - @property - def n_sites(self): - return len(self._site_list) - def positions(self): xyz = np.empty(shape=(self.n_sites, 3)) * u.nm - for i, site in enumerate(self.site_list): + for i, site in enumerate(self.sites): xyz[i, :] = site.position return xyz - @property - def site_list(self): - return self._site_list + def add_site(self, site): + if site in self.sites: + warnings.warn("Redundantly adding Site {}".format(site)) + self._sites.append(site) + self.update_atom_types() + + def add_connection(self, connection): + if connection in self.connections: + warnings.warn("Redundantly adding Connection {}".format(connection)) + + if connection.connection_members[0] not in self.sites: + self.add_site(connection.connection_members[0]) + if connection.connection_members[1] not in self.sites: + self.add_site(connection.connection_members[1]) + + self._connections.append(connection) + + #self.update_connections() Do we need to call this? Code should work either way + self.update_connection_types() + if isinstance(connection, Bond): + self.update_bonds() + self.update_bond_types() + elif isinstance(connection, Angle): + self.update_angles() + self.update_angle_types() @property - def connection_list(self): - return self._connection_list + def n_sites(self): + return len(self.sites) @property def n_connections(self): - return len(self._connection_list) + return len(self.connections) @property def n_bonds(self): - return len([b for b in self.connection_list if isinstance(b, Bond)]) + return len(self.bonds) - def add_connection(self, connection): - self._connection_list.append(connection) - - def update_connection_list(self): - for site in self.site_list: - for neighbor in site.connections: - temp_connection = Connection(site, neighbor, update=False) - if temp_connection not in self.connection_list: - self.add_connection(Connection(site, neighbor, update=True)) + @property + def n_angles(self): + return len(self.angles) + + @property + def sites(self): + return self._sites + + @property + def connections(self): + return self._connections + + @property + def bonds(self): + return self._bonds + + @property + def angles(self): + return self._angles + + @property + def atom_types(self): + return self._atom_types + + @property + def connection_types(self): + return self._connection_types + + @property + def bond_types(self): + return self._bond_types + + @property + def angle_types(self): + return self._angle_types + + @property + def atom_type_expressions(self): + return list(set([atype.expression for atype in self.atom_types])) + + @property + def connection_type_expressions(self): + return list(set([contype.expression for contype in self.connection_types])) + + @property + def bond_type_expressions(self): + return list(set([btype.expression for btype in self.bond_types])) + + @property + def angle_type_expressions(self): + return list(set([atype.expression for atype in self.angle_types])) + + def update_top(self): + """ Update the entire topology's attributes + + Notes + ----- + Will update: sites, connections, bonds, angles, + atom_types, connectiontypes, bondtypes, angletypes + """ + self.update_sites() + self.update_connections() + self.update_bonds() + self.update_angles() + + self.update_atom_types() + self.update_connection_types() + self.update_bond_types() + self.update_angle_types() + + def update_sites(self): + """ (Is this necessary?) + Update site list based on the connection members """ + for connection in self.connections: + for con_member in connection.connection_members: + if con_member not in self.sites: + self.add_site(con_member) + + def update_connections(self): + """ Update connection list based on the site list """ + #self._connections = [] + for site in self.sites: + for connection in site.connections: + if connection not in self.connections: + self.add_connection(connection) + + def update_bonds(self): + """ Rebuild the bond list by filtering through connection list """ + self._bonds = [b for b in self.connections if isinstance(b, Bond)] + + def update_angles(self): + """ Rebuild the angle list by filtering through connection list """ + self._angles = [a for a in self.connections if isinstance(a, Angle)] + + def update_atom_types(self): + """ Update the atom types based on the site list """ + #self._atom_types = [] + for site in self.sites: + if site.atom_type is None: + warnings.warn("Site {} detected with no AtomType".format(site)) + elif site.atom_type not in self.atom_types: + self.atom_types.append(site.atom_type) + + def update_connection_types(self): + """ Update the connection types based on the connection list """ + #self._connection_types = [] + for c in self.connections: + if c.connection_type is None: + warnings.warn("Non-parametrized Connection {} detected".format(c)) + elif not isinstance(c.connection_type, Potential): + raise TopologyError("Non-Potential {} found " + "in Connection {}".format(c.connection_type, c)) + elif c.connection_type not in self.connection_types: + self.connection_types.append(c.connection_type) + + def update_bond_types(self): + """ Update the bond types based on the bond list """ + #self._bond_types = [] + for b in self.bonds: + if b.connection_type is None: + warnings.warn("Non-parametrized Bond {} detected".format(b)) + elif not isinstance(b.connection_type, BondType): + raise TopologyError("Non-BondType {} found in Bond {}".format( + b.connection_type, b)) + elif b.connection_type not in self.bond_types: + self.bond_types.append(b.connection_type) + + def update_angle_types(self): + """ Update the angle types based on the angle list """ + #self._angle_types = [] + for a in self.angles: + if a.connection_type is None: + warnings.warn("Non-parametrized Angle {} detected".format(a)) + elif not isinstance(a.connection_type, AngleType): + raise TopologyError("Non-AngleType {} found in Angle {}".format( + a.connection_type, a)) + elif a.connection_type not in self.angle_types: + self.angle_types.append(a.connection_type) def __repr__(self): descr = list('<') diff --git a/topology/external/convert_mbuild.py b/topology/external/convert_mbuild.py index d45a00d52..39e251800 100644 --- a/topology/external/convert_mbuild.py +++ b/topology/external/convert_mbuild.py @@ -40,12 +40,12 @@ def to_mbuild(topology): compound.name = topology.name particle_map = dict() - for site in topology.site_list: + for site in topology.sites: particle = mb.Compound(name=site.name, pos=site.position[0]) particle_map[site] = particle compound.add(particle) - for connect in topology.connection_list: + for connect in topology.connections: if isinstance(connect, Bond): compound.add_bond(( particle_map[connect.connection_members[0]], diff --git a/topology/external/convert_openmm.py b/topology/external/convert_openmm.py index b9af1c855..68e2b84c7 100644 --- a/topology/external/convert_openmm.py +++ b/topology/external/convert_openmm.py @@ -32,7 +32,7 @@ def to_openmm(topology, openmm_object='topology'): residue = openmm_top.addResidue(name='RES', chain=chain) - for site in topology.site_list: + for site in topology.sites: openmm_top.addAtom(name=site.name, element=site.element.name, residue=residue) diff --git a/topology/external/convert_parmed.py b/topology/external/convert_parmed.py index 1e5c8578f..f5fa80379 100644 --- a/topology/external/convert_parmed.py +++ b/topology/external/convert_parmed.py @@ -2,37 +2,32 @@ import parmed as pmd import unyt as u -from topology.core.topology import Topology -from topology.core.site import Site -from topology.core.atom_type import AtomType -from topology.core.bond import Bond -from topology.core.bond_type import BondType -from topology.core.box import Box +import topology as topo def from_parmed(structure): msg = ("Provided argument that is not a Parmed Structure") assert isinstance(structure, pmd.Structure), msg - top = Topology(name=structure.title) + top = topo.Topology(name=structure.title) site_map = dict() for atom in structure.atoms: if isinstance(atom.atom_type, pmd.AtomType): - atom_type = AtomType( + atom_type = topo.AtomType( name=atom.atom_type.name, charge=atom.atom_type.charge * u.elementary_charge, parameters={ 'sigma': (atom.sigma * u.angstrom).in_units(u.nm), 'epsilon': atom.epsilon * u.Unit('kcal / mol') }) - site = Site( + site = topo.Site( name=atom.name, charge=atom.charge * u.elementary_charge, position=([atom.xx, atom.xy, atom.xz] * u.angstrom).in_units( u.nm), atom_type=atom_type) else: - site = Site( + site = topo.Site( name=atom.name, charge=atom.charge * u.elementary_charge, position=([atom.xx, atom.xy, atom.xz] * u.angstrom).in_units( @@ -43,7 +38,7 @@ def from_parmed(structure): if np.all(structure.box): # This is if we choose for topology to have abox - top.box = Box( + top.box = topo.Box( (structure.box[0:3] * u.angstrom).in_units(u.nm), angles=u.degree * structure.box[3:6]) @@ -52,23 +47,43 @@ def from_parmed(structure): # to Bond if isinstance(bond.type, pmd.BondType): bond_params = { - 'k': (2 * bond.type.k * u.Unit('kcal / (angstrom**2 * mol)')), + 'k': (2 * bond.type.k * u.Unit('kcal / (nm**2 * mol)')), 'r_eq': (bond.type.req * u.angstrom).in_units(u.nm) } - new_connection_type = BondType(parameters=bond_params) - top_connection = Bond(connection_members=[site_map[bond.atom1], + new_connection_type = topo.BondType(parameters=bond_params) + top_connection = topo.Bond(connection_members=[site_map[bond.atom1], site_map[bond.atom2]], connection_type=new_connection_type) # No bond parameters, make Connection with no connection_type else: - top_connection = Bond(connection_members=[site_map[bond.atom1], + top_connection = topo.Bond(connection_members=[site_map[bond.atom1], site_map[bond.atom2]], connection_type=None) top.add_connection(top_connection) - # TODO: Angles + for angle in structure.angles: + # Generate angle parameters for AngleType that gets passed + # to Angle + if isinstance(angle.type, pmd.AngleType): + angle_params = { + 'k': (2 * angle.type.k * u.Unit('kcal / (rad**2 * mol)')), + 'theta_eq': (angle.type.theteq * u.degree) + } + new_connection_type = topo.AngleType(parameters=angle_params) + top_connection = topo.Angle(connection_members=[site_map[angle.atom1], + site_map[angle.atom2], site_map[angle.atom3]], + connection_type=new_connection_type) + + # No bond parameters, make Connection with no connection_type + else: + top_connection = topo.Angle(connection_members=[site_map[angle.atom1], + site_map[angle.atom2], site_map[angle.atom3]], + connection_type=None) + + top.add_connection(top_connection) + # TODO: Dihedrals diff --git a/topology/formats/gro.py b/topology/formats/gro.py index e44b53f7a..2a8d9b9bd 100644 --- a/topology/formats/gro.py +++ b/topology/formats/gro.py @@ -65,7 +65,7 @@ def write_gro(top, filename): top.name if top.name is not None else '', str(datetime.datetime.now()))) out_file.write('{:d}\n'.format(top.n_sites)) - for idx, site in enumerate(top.site_list): + for idx, site in enumerate(top.sites): warnings.warn('Residue information is not currently ' 'stored or written to GRO files.', NotYetImplementedWarning) diff --git a/topology/formats/gsd.py b/topology/formats/gsd.py index be7b8f34d..dca620cf0 100644 --- a/topology/formats/gsd.py +++ b/topology/formats/gsd.py @@ -62,7 +62,7 @@ def write_gsd(top, """ - xyz = u.unyt_array([site.position for site in top.site_list]) + xyz = u.unyt_array([site.position for site in top.sites]) if shift_coords: warnings.warn("Shifting coordinates to [-L/2, L/2]") xyz = coord_shift(xyz, top.box) @@ -116,7 +116,7 @@ def _write_particle_information(gsd_file, top, xyz, ref_distance, ref_mass, types = [ site.name if site.atom_type is None else site.atom_type.name - for site in top.site_list + for site in top.sites ] unique_types = list(set(types)) @@ -128,11 +128,11 @@ def _write_particle_information(gsd_file, top, xyz, ref_distance, ref_mass, typeids = np.array([unique_types.index(t) for t in types]) gsd_file.particles.typeid = typeids - masses = np.array([site.mass for site in top.site_list]) + masses = np.array([site.mass for site in top.sites]) masses[masses == 0] = 1.0 gsd_file.particles.mass = masses / ref_mass - charges = np.array([site.charge for site in top.site_list]) + charges = np.array([site.charge for site in top.sites]) e0 = u.physical_constants.eps_0.in_units( u.elementary_charge**2 / u.Unit('kcal*angstrom/mol')) ''' @@ -195,7 +195,7 @@ def _write_bond_information(gsd_file, top): warnings.warn("{} bonds detected".format(top.n_bonds)) unique_bond_types = set() - for bond in top.connection_list: + for bond in top.connections: if isinstance(bond, Bond): t1, t2 = bond.connection_members[0].atom_type, bond.connection_members[1].atom_type if t1 is None or t2 is None: @@ -211,7 +211,7 @@ def _write_bond_information(gsd_file, top): bond_typeids = [] bond_groups = [] - for bond in top.connection_list: + for bond in top.bonds: if isinstance(bond, Bond): t1, t2 = bond.connection_members[0].atom_type, bond.connection_members[1].atom_type if t1 is None or t2 is None: @@ -220,8 +220,8 @@ def _write_bond_information(gsd_file, top): bond_type = ('-'.join((t1.name, t2.name))) bond_typeids.append(unique_bond_types.index(bond_type)) - bond_groups.append((top.site_list.index(bond.connection_members[0]), - top.site_list.index(bond.connection_members[1]))) + bond_groups.append((top.sites.index(bond.connection_members[0]), + top.sites.index(bond.connection_members[1]))) gsd_file.bonds.typeid = bond_typeids gsd_file.bonds.group = bond_groups diff --git a/topology/formats/lammpsdata.py b/topology/formats/lammpsdata.py index e33797994..dfd80fb4f 100644 --- a/topology/formats/lammpsdata.py +++ b/topology/formats/lammpsdata.py @@ -48,12 +48,12 @@ def write_lammpsdata(topology, filename, atom_style='full'): xyz = list() types = list() - for site in topology.site_list: + for site in topology.sites: xyz.append([site.position[0],site.position[1],site.position[2]]) types.append(site.atom_type.name) forcefield = True - if topology.site_list[0].atom_type.name in ['', None]: + if topology.sites[0].atom_type.name in ['', None]: forcefield = False box = topology.box @@ -78,7 +78,7 @@ def write_lammpsdata(topology, filename, atom_style='full'): data.write('{} written by topology at {}\n\n'.format( topology.name if topology.name is not None else '', str(datetime.datetime.now()))) - data.write('{:d} atoms\n'.format(len(topology.site_list))) + data.write('{:d} atoms\n'.format(len(topology.sites))) if atom_style in ['full', 'molecular']: if bonds != 0: data.write('{:} bonds\n'.format(len(bonds))) @@ -150,7 +150,7 @@ def write_lammpsdata(topology, filename, atom_style='full'): xy.value, xz.value, yz.value)) # Mass data - masses = [site.atom_type.mass for site in topology.site_list] + masses = [site.atom_type.mass for site in topology.sites] mass_dict = dict([(unique_types.index(atom_type)+1,mass) for atom_type,mass in zip(types,masses)]) data.write('\nMasses\n\n') @@ -160,8 +160,8 @@ def write_lammpsdata(topology, filename, atom_style='full'): mass.in_units(u.g/u.mol).value, unique_types[atom_type-1])) if forcefield: - sigmas = [site.atom_type.parameters['sigma'] for site in topology.site_list] - epsilons = [site.atom_type.parameters['epsilon'] for site in topology.site_list] + sigmas = [site.atom_type.parameters['sigma'] for site in topology.sites] + epsilons = [site.atom_type.parameters['epsilon'] for site in topology.sites] sigma_dict = dict([(unique_types.index(atom_type)+1,sigma) for atom_type,sigma in zip(types,sigmas)]) epsilon_dict = dict([(unique_types.index(atom_type)+1,epsilon) for atom_type,epsilon in zip(types,epsilons)]) diff --git a/topology/formats/xyz.py b/topology/formats/xyz.py index d69b817e0..097059033 100644 --- a/topology/formats/xyz.py +++ b/topology/formats/xyz.py @@ -43,7 +43,7 @@ def write_xyz(top, filename): top.name, filename, str(datetime.datetime.now()))) - for idx, site in enumerate(top.site_list): + for idx, site in enumerate(top.sites): # TODO: Better handling of element guessing and site naming if site.element is not None: tmp_name = site.element.symbol diff --git a/topology/tests/test_convert_parmed.py b/topology/tests/test_convert_parmed.py index 67bad61ce..41b0a8fec 100644 --- a/topology/tests/test_convert_parmed.py +++ b/topology/tests/test_convert_parmed.py @@ -11,12 +11,12 @@ class TestConvertParmEd(BaseTest): def test_from_parmed_basic(self, angles): struc = pmd.load_file(get_fn('ethane.mol2'), structure=True) top = from_parmed(struc) - for site in top.site_list: + for site in top.sites: assert site.atom_type is None - for connection in top.connection_list: + for connection in top.connections: assert connection.connection_type is None assert top.n_sites == 8 - assert top.n_connections == 7 + assert top.n_bonds == 7 assert top.box is not None lengths = u.nm * [0.714, 0.7938, 0.6646] @@ -27,13 +27,15 @@ def test_from_parmed_parametrized_structure(self, angles): struc = pmd.load_file(get_fn('ethane.top'), xyz=get_fn('ethane.gro')) top = from_parmed(struc) assert top.n_sites == 8 - assert top.n_connections == 7 + assert top.n_bonds == 7 + assert top.n_angles == 12 + assert top.n_connections == 19 - for site in top.site_list: + for site in top.sites: assert site.atom_type is not None assert site.charge is not None - for connection in top.connection_list: + for connection in top.connections: assert connection.connection_type is not None assert top.box is not None diff --git a/topology/tests/test_openmm.py b/topology/tests/test_openmm.py index bbd2bb1d1..6fa7eba24 100644 --- a/topology/tests/test_openmm.py +++ b/topology/tests/test_openmm.py @@ -17,7 +17,7 @@ def test_openmm_topology(self, topology_site): def test_n_atoms(self, topology_site): top = topology_site(sites=10) - n_topology_sites = len(top.site_list) + n_topology_sites = len(top.sites) modeller = to_openmm(top, openmm_object='modeller') n_modeller_atoms = len([i for i in modeller.topology.atoms()]) @@ -25,7 +25,7 @@ def test_n_atoms(self, topology_site): def test_box_dims(self, topology_site): top = topology_site(sites=10) - n_topology_sites = len(top.site_list) + n_topology_sites = len(top.sites) omm_top = to_openmm(top) topology_lengths = top.box.lengths omm_lengths = omm_top.getUnitCellDimensions() @@ -34,7 +34,7 @@ def test_box_dims(self, topology_site): def test_particle_positions(self, topology_site): top = topology_site() - top.site_list[0].position = (1,1,1) * u.nanometer + top.sites[0].position = (1,1,1) * u.nanometer omm_top = to_openmm(top, openmm_object='modeller') assert np.allclose(omm_top.positions._value, top.positions().value) @@ -43,7 +43,7 @@ def test_position_units(self, topology_site): top = topology_site(sites=10) top.box = Box(lengths=[1,1,1]) - n_topology_sites = len(top.site_list) + n_topology_sites = len(top.sites) omm_top = to_openmm(top, openmm_object='modeller') assert isinstance(omm_top.positions.unit, type(simtk.unit.nanometer)) diff --git a/topology/tests/test_topology.py b/topology/tests/test_topology.py index 94c258520..ccc4fe3c9 100644 --- a/topology/tests/test_topology.py +++ b/topology/tests/test_topology.py @@ -2,10 +2,8 @@ import pytest import unyt as u -from topology.core.topology import Topology -from topology.core.site import Site -from topology.core.bond import Bond -from topology.core.box import Box +from topology import * + from topology.tests.base_test import BaseTest from topology.testing.utils import allclose @@ -34,7 +32,7 @@ def test_add_connection(self): top.add_site(site2) - assert len(top.connection_list) == 1 + assert len(top.connections) == 1 def test_add_box(self): top = Topology() @@ -50,9 +48,154 @@ def test_positions_dtype(self): site1 = Site(name='site1') top.add_site(site1) - assert set([type(site.position) for site in top.site_list]) == {u.unyt_array} - assert set([site.position.units for site in top.site_list]) == {u.nm} + assert set([type(site.position) for site in top.sites]) == {u.unyt_array} + assert set([site.position.units for site in top.sites]) == {u.nm} assert top.positions().dtype == float assert top.positions().units == u.nm assert isinstance(top.positions(), u.unyt_array) + + def test_top_update(self): + top = Topology() + top.update_top() + assert top.n_sites == 0 + assert len(top.atom_types) == 0 + assert len(top.atom_type_expressions) == 0 + assert top.n_connections == 0 + assert len(top.connection_types) == 0 + assert len(top.connection_type_expressions) == 0 + + atomtype = AtomType() + site1 = Site(name='site1', atom_type=atomtype) + top.add_site(site1) + site2 = Site(name='site2', atom_type=atomtype) + top.add_site(site2) + assert top.n_sites == 2 + #assert len(top.atom_types) == 0 + #assert len(top.atom_type_expressions) == 0 + #assert top.n_connections == 0 + #assert len(top.connection_types) == 0 + #assert len(top.connection_type_expressions) == 0 + #top.update_atom_types() + #assert top.n_sites == 2 + assert len(top.atom_types) == 1 + assert len(top.atom_type_expressions) == 1 + assert top.n_connections == 0 + assert len(top.connection_types) == 0 + assert len(top.connection_type_expressions) == 0 + + + ctype = BondType() + connection_12 = Bond(connection_members=[site1, site2], + connection_type=ctype) + top.add_connection(connection_12) + #assert top.n_sites == 2 + #assert len(top.atom_types) == 1 + #assert len(top.atom_type_expressions) == 1 + #assert top.n_connections == 1 + #assert len(top.connection_types) == 0 + #assert len(top.connection_type_expressions) == 0 + #top.update_connection_types() + assert top.n_sites == 2 + assert len(top.atom_types) == 1 + assert len(top.atom_type_expressions) == 1 + assert top.n_connections == 1 + assert len(top.connection_types) == 1 + assert len(top.connection_type_expressions) == 1 + + site1.atom_type = AtomType(expression='sigma*epsilon') + assert top.n_sites == 2 + assert len(top.atom_types) == 1 + assert len(top.atom_type_expressions) == 1 + assert top.n_connections == 1 + assert len(top.connection_types) == 1 + assert len(top.connection_type_expressions) == 1 + top.update_atom_types() + assert top.n_sites == 2 + assert len(top.atom_types) == 2 + assert len(top.atom_type_expressions) == 2 + assert top.n_connections == 1 + assert len(top.connection_types) == 1 + assert len(top.connection_type_expressions) == 1 + + def test_atomtype_update(self): + top = Topology() + + assert top.n_sites == 0 + assert top.n_bonds == 0 + assert top.n_connections == 0 + + atype1 = AtomType(expression='sigma + epsilon') + atype2 = AtomType(expression='sigma * epsilon') + site1 = Site('a', atom_type=atype1) + site2 = Site('b', atom_type=atype2) + top.add_site(site1) + top.add_site(site2) + #assert top.n_sites == 2 + #assert len(top.atom_types) == 0 + #assert len(top.atom_type_expressions) == 0 + + #top.update_atom_types() + assert top.n_sites == 2 + assert len(top.atom_types) == 2 + assert len(top.atom_type_expressions) == 2 + + def test_bond_bondtype_update(self): + top = Topology() + + atype1 = AtomType(expression='sigma + epsilon') + atype2 = AtomType(expression='sigma * epsilon') + site1 = Site('a', atom_type=atype1) + site2 = Site('b', atom_type=atype2) + btype = BondType() + bond = Bond(connection_members=[site1, site2], connection_type=btype) + top.add_site(site1) + top.add_site(site2) + top.add_connection(bond) + + #assert top.n_connections == 1 + #assert top.n_bonds == 0 + #assert len(top.bond_types) == 0 + #assert len(top.bond_type_expressions) == 0 + + #top.update_bond_list() + #assert top.n_bonds == 1 + #assert len(top.bond_types) == 0 + #assert len(top.bond_type_expressions) == 0 + + #top.update_bond_types() + assert top.n_bonds == 1 + assert len(top.bond_types) == 1 + assert len(top.bond_type_expressions) == 1 + + def test_angle_angletype_update(self): + top = Topology() + + atype1 = AtomType(expression='sigma + epsilon') + atype2 = AtomType(expression='sigma * epsilon') + site1 = Site('a', atom_type=atype1) + site2 = Site('b', atom_type=atype2) + site3 = Site('c', atom_type=atype2) + atype = AngleType() + angle = Angle(connection_members=[site1, site2, site3], connection_type=atype) + top.add_site(site1) + top.add_site(site2) + top.add_site(site3) + top.add_connection(angle) + + #assert top.n_connections == 1 + #assert top.n_angles == 0 + #assert len(top.angle_types) == 0 + #assert len(top.angle_type_expressions) == 0 + + #top.update_angle_list() + #assert top.n_angles == 1 + #assert len(top.angle_types) == 0 + #assert len(top.angle_type_expressions) == 0 + + #top.update_angle_types() + assert top.n_angles == 1 + assert len(top.angle_types) == 1 + assert len(top.angle_type_expressions) == 1 + assert len(top.atom_type_expressions) == 2 + diff --git a/topology/tests/test_xyz.py b/topology/tests/test_xyz.py index 7307c7d1f..fd6a635d0 100644 --- a/topology/tests/test_xyz.py +++ b/topology/tests/test_xyz.py @@ -11,15 +11,15 @@ def test_read_xyz(self): top = read_xyz(get_fn('ethane.xyz')) assert top.n_sites == 8 assert top.n_connections == 0 - assert set([type(site.position) for site in top.site_list]) == {u.unyt_array} - assert set([site.position.units for site in top.site_list]) == {u.nm} + assert set([type(site.position) for site in top.sites]) == {u.unyt_array} + assert set([site.position.units for site in top.sites]) == {u.nm} top = read_xyz(get_fn('cu_block.xyz')) assert top.n_sites == 108 assert top.n_connections == 0 - assert set([type(site.position) for site in top.site_list]) == {u.unyt_array} - assert set([site.position.units for site in top.site_list]) == {u.nm} + assert set([type(site.position) for site in top.sites]) == {u.unyt_array} + assert set([site.position.units for site in top.sites]) == {u.nm} def test_wrong_n_atoms(self): with pytest.raises(ValueError):