Ejemplo n.º 1
0
def create_molecular_graph(selected_nodes, parent=None):
    molecule = create_molecule(selected_nodes, parent)

    atom_indexes = dict((atom, i) for i, atom in enumerate(molecule.atoms))
    bonds = list(
        bond
        for bond in iter_bonds(selected_nodes)
        if bond.children[0].target in atom_indexes and bond.children[1].target in atom_indexes
    )
    pairs = [(atom_indexes[bond.children[0].target], atom_indexes[bond.children[1].target]) for bond in bonds]

    graph = MolecularGraph(pairs, molecule.numbers)
    graph.bonds = bonds
    graph.molecule = molecule
    return graph
Ejemplo n.º 2
0
    def __init__(self, dihedral, molecule=None, top_indexes=None, potential=None):
        """
           Arguments
            | ``dihedral`` -- the index of the atoms that define the dihedral
                              angle

           Optional arguments
            | ``molecule`` -- a molecule object. required when top_indexes is not
                              given
            | ``top_indexes`` -- a list of atom indexes involved in the rotor.
                                 required when molecule is not given
            | ``potential`` -- rotational potential info (if this is a hindered
                               rotor). must be a two-tuple containing the angles
                               and the corresponding energies.

        """
        self.dihedral = dihedral
        if top_indexes is None:
            # try to deduce the top indexes
            if molecule is None:
                raise ValueError("missing arguemt: top_indexes or molecule from which top_indexes can be derived")
            atom0, atom1 = dihedral[1:3]
            graph = MolecularGraph.from_geometry(molecule)
            half0, half1 = graph.get_halfs(atom0, atom1)
            if len(half1) > len(half0):
                top_indexes = half0
                top_indexes.discard(atom0)
            else:
                top_indexes = half1
                top_indexes.discard(atom1)
            top_indexes = tuple(top_indexes)
        self.top_indexes = top_indexes
        self.potential = potential
Ejemplo n.º 3
0
def create_molecular_graph(selected_nodes, parent=None):
    molecule = create_molecule(selected_nodes, parent)

    atom_indexes = dict((atom, i) for i, atom in enumerate(molecule.atoms))
    bonds = list(bond for bond in iter_bonds(selected_nodes)
                 if bond.children[0].target in atom_indexes
                 and bond.children[1].target in atom_indexes)
    pairs = [(
        atom_indexes[bond.children[0].target],
        atom_indexes[bond.children[1].target],
    ) for bond in bonds]

    graph = MolecularGraph(pairs, molecule.numbers)
    graph.bonds = bonds
    graph.molecule = molecule
    return graph
Ejemplo n.º 4
0
    def __init__(self,
                 dihedral,
                 molecule=None,
                 top_indexes=None,
                 potential=None):
        """
           Arguments
            | ``dihedral`` -- the index of the atoms that define the dihedral
                              angle

           Optional arguments
            | ``molecule`` -- a molecule object. required when top_indexes is not
                              given
            | ``top_indexes`` -- a list of atom indexes involved in the rotor.
                                 required when molecule is not given or when the
                                 top_indexes can not be derived automatically.
            | ``potential`` -- rotational potential info (if this is a hindered
                               rotor). must be a two-tuple containing the angles
                               and the corresponding energies.

        """
        self.dihedral = dihedral
        if top_indexes is None:
            # try to deduce the top indexes
            if molecule is None:
                raise ValueError(
                    "missing arguemt: top_indexes or molecule from which top_indexes can be derived"
                )
            atom0, atom1 = dihedral[1:3]
            graph = MolecularGraph.from_geometry(molecule)
            half0, half1 = graph.get_halfs(atom0, atom1)
            if (len(half0) + len(half1) !=
                    molecule.size) or len(half0) == 1 or len(half1) == 1:
                raise ValueError(
                    "The rotating top could not be assigned properly. Specify the top_indexes manually."
                )
            if len(half1) > len(half0):
                top_indexes = half0
                top_indexes.discard(atom0)
            else:
                top_indexes = half1
                top_indexes.discard(atom1)
            top_indexes = tuple(top_indexes)
        else:
            # check the sanity of the top indexes
            if not ((self.dihedral[0] in top_indexes) ^
                    (self.dihedral[3] in top_indexes)):
                raise ValueError(
                    'The top must contain either first or the last atom of the dihedral angle.'
                )
            if ((self.dihedral[1] in top_indexes) |
                (self.dihedral[2] in top_indexes)):
                raise ValueError(
                    'The top may not contain atoms from the central bond of the dihedral angle.'
                )
        self.top_indexes = top_indexes
        self.potential = potential
Ejemplo n.º 5
0
def test_bias_pathdeviation_mof5():
    # Load the system
    fn_system = pkg_resources.resource_filename(
        __name__, '../../data/test/system_mof5.chk')
    system = System.from_file(fn_system)
    # Groups that define the COM
    atypes = set(
        ['C_B', 'C_B_BR_O', 'O_p', 'B_p', 'C_HTTP', 'C_O_BR_O', 'C_O'])
    graph = MolecularGraph(system.bonds, system.numbers)
    indices = graph.independent_vertices
    groups = []
    for layer in [0, 1]:
        groups.append([
            iatom for iatom in indices[layer]
            if system.get_ffatype(iatom) in atypes
        ])
    # Collective Variables
    cv0 = CVCOMProjection(system, groups, 0)
    cv1 = CVCOMProjection(system, groups, 1)
    # The path, rather random nonsense
    # This potential has a discontinuous derivative when there is a jump from
    # one nearest point on the path to the next. This can lead to failure of
    # the check_gpos_part and check_vtens_part tests when such a jump occurs
    # in the finite difference approximation. We avoid this by taking a rather
    # coarse path, so we are always close to the same point of the path.
    npoints = 20
    path = np.zeros((npoints, 3))
    path[:, 0] = np.cos(np.linspace(0, np.pi, npoints)) * 0.1
    path[:, 1] = np.sin(np.linspace(0, np.pi, npoints)) * -0.1
    path[:, 2] = 0.2 * path[:, 0] + path[:, 1]**2
    # Test without the harmonic restraint
    bias = PathDeviationBias([cv0, cv1], path, 0.0)
    part = ForcePartBias(system)
    part.add_term(bias)
    check_gpos_part(system, part)
    check_vtens_part(system, part)
    # Test without the harmonic restraint, closest point on path is starting
    # point of the path
    bias = PathDeviationBias([cv0, cv1], path[5:], 0.0)
    index, _, _ = bias.find_nearest_point(
        np.array([cv.compute() for cv in bias.cvs]))
    assert index == 0
    part = ForcePartBias(system)
    part.add_term(bias)
    check_gpos_part(system, part)
    check_vtens_part(system, part)
    # Test with the harmonic restraint
    bias = PathDeviationBias([cv0, cv1], path, 0.5)
    part = ForcePartBias(system)
    part.add_term(bias)
    check_gpos_part(system, part)
    check_vtens_part(system, part)
Ejemplo n.º 6
0
def get_precursor_model():
    m = XYZFile("test/input/mfi_precursor.xyz").get_molecule()
    mgraph = MolecularGraph.from_geometry(m)
    connect_masks = np.array([
        number == 8 and len(mgraph.neighbors[index]) == 1
        for index, number in enumerate(m.numbers)
    ], bool)
    radii = np.array([
        periodic[number].vdw_radius * {True: 0.3, False: 1.0}[connect_mask]
        for number, connect_mask in zip(m.numbers, connect_masks)
    ], float)
    radii += np.random.uniform(0, 0.1, radii.shape)
    return m.coordinates, connect_masks, radii
Ejemplo n.º 7
0
    def collect_molecules(self, parent, universe=None):
        Atom = context.application.plugins.get_node("Atom")
        Bond = context.application.plugins.get_node("Bond")
        Frame = context.application.plugins.get_node("Frame")


        if universe==None:
            universe = parent

        atom_to_index = {}
        atoms_extra = {}
        counter = 0
        numbers = []
        coordinates = []
        for child in parent.children:
            if isinstance(child, Atom):
                atom_to_index[child] = counter
                if len(child.extra) > 0:
                    atoms_extra[counter] = child.extra
                counter += 1
                numbers.append(child.number)
                coordinates.append(child.get_frame_relative_to(universe).t)

        if len(numbers) > 0:
            molecule = Molecule(numbers, coordinates, parent.name)
            molecule.extra = parent.extra
            molecule.atoms_extra = atoms_extra
            molecule.bonds_extra = {}

            pairs = set([])
            for child in parent.children:
                if isinstance(child, Bond):
                    atoms = child.get_targets()
                    pair = frozenset([atom_to_index[atoms[0]], atom_to_index[atoms[1]]])
                    if len(child.extra) > 0:
                        molecule.bonds_extra[pair] = child.extra
                    pairs.add(pair)
            if len(pairs) > 0:
                molecule.graph = MolecularGraph(pairs, molecule.numbers)
            else:
                molecule.graph = None

            result = [molecule]
        else:
            result = []

        for child in parent.children:
            if isinstance(child, Frame):
                result.extend(self.collect_molecules(child, universe))

        return result
Ejemplo n.º 8
0
    def __init__(self, dihedral, molecule=None, top_indexes=None, potential=None):
        """
           Arguments
            | ``dihedral`` -- the index of the atoms that define the dihedral
                              angle

           Optional arguments
            | ``molecule`` -- a molecule object. required when top_indexes is not
                              given
            | ``top_indexes`` -- a list of atom indexes involved in the rotor.
                                 required when molecule is not given or when the
                                 top_indexes can not be derived automatically.
            | ``potential`` -- rotational potential info (if this is a hindered
                               rotor). must be a two-tuple containing the angles
                               and the corresponding energies.

        """
        self.dihedral = dihedral
        if top_indexes is None:
            # try to deduce the top indexes
            if molecule is None:
                raise ValueError("missing arguemt: top_indexes or molecule from which top_indexes can be derived")
            atom0, atom1 = dihedral[1:3]
            graph = MolecularGraph.from_geometry(molecule)
            half0, half1 = graph.get_halfs(atom0, atom1)
            if (len(half0) + len(half1) != molecule.size) or len(half0) == 1 or len(half1) == 1:
                raise ValueError("The rotating top could not be assigned properly. Specify the top_indexes manually.")
            if len(half1) > len(half0):
                top_indexes = half0
                top_indexes.discard(atom0)
            else:
                top_indexes = half1
                top_indexes.discard(atom1)
            top_indexes = tuple(top_indexes)
        else:
            # check the sanity of the top indexes
            if not ((self.dihedral[0] in top_indexes) ^ (self.dihedral[3] in top_indexes)):
                raise ValueError('The top must contain either first or the last atom of the dihedral angle.')
            if ((self.dihedral[1] in top_indexes) | (self.dihedral[2] in top_indexes)):
                raise ValueError('The top may not contain atoms from the central bond of the dihedral angle.')
        self.top_indexes = top_indexes
        self.potential = potential
Ejemplo n.º 9
0
    def read_from_file(cls, filename):
        """Construct a Molecule object from a previously saved checkpoint file

           Arguments:
            | ``filename`` -- the file to load from

           Usage::

             >>> mol = Molecule.read_from_file("mol.chk")

        """
        from tamkin.io.internal import load_chk
        # load the file
        data = load_chk(filename)
        # check the names of the fields:
        mandatory_fields = set([
            "numbers", "coordinates", "masses", "energy", "gradient", "hessian"
        ])
        if not set(data.iterkeys()).issuperset(mandatory_fields):
            raise IOError(
                "The Checkpoint file does not contain the mandatory fields.")
        # take the mandatory fields
        constructor_args = {}
        for mfield in mandatory_fields:
            constructor_args[mfield] = data[mfield]
        # take the optional arguments if present
        opt_fields = [
            "multiplicity", "symmetry_number", "periodic", "title", "symbols"
        ]
        for ofield in opt_fields:
            if ofield in data:
                constructor_args[ofield] = data[ofield]
        # take the special optional arguments that need conversion
        if "edges" in data:
            graph = MolecularGraph(data["edges"], data["numbers"])
            constructor_args["graph"] = graph
        if "cell_vectors" in data:
            unit_cell = UnitCell(data["cell_vectors"], data.get("cell_active"))
            constructor_args["unit_cell"] = unit_cell
        # construct the molecule object
        return Molecule(**constructor_args)
Ejemplo n.º 10
0
def test_cvcomprojection_mof5():
    # Load the system
    fn_system = pkg_resources.resource_filename(
        __name__, '../../data/test/system_mof5.chk')
    system = System.from_file(fn_system)
    # Groups that define the COM
    atypes = set(
        ['C_B', 'C_B_BR_O', 'O_p', 'B_p', 'C_HTTP', 'C_O_BR_O', 'C_O'])
    graph = MolecularGraph(system.bonds, system.numbers)
    indices = graph.independent_vertices
    groups = []
    for layer in [0, 1]:
        groups.append([
            iatom for iatom in indices[layer]
            if system.get_ffatype(iatom) in atypes
        ])
    # Compute the COMs explicitly
    coms = [(system.pos[group] * system.masses[group].reshape(
        (-1, 1))).sum(axis=0) / system.masses[group].sum() for group in groups]
    relcom = coms[1] - coms[0]
    # Loop over different projections
    for index in range(3):
        # Compute using the CollectiveVariable
        cv = CVCOMProjection(system, groups, index)
        value = cv.compute()
        # Compute the projection vector
        a, b, c = system.cell.rvecs[0], system.cell.rvecs[
            1], system.cell.rvecs[2]
        if index == 0:
            u = a.copy()
        elif index == 1:
            u = np.cross(np.cross(a, b), a)
        elif index == 2:
            u = np.cross(a, b)
        u /= np.linalg.norm(u)
        cv_ref = np.dot(relcom, u)
        assert np.abs(cv_ref - value) < 1e-3
        # Check derivatives
        check_gpos_cv_fd(cv)
        check_vtens_cv_fd(cv)