Esempio n. 1
0
def find_missing_bonds_by_projection(geom, hessian, bond_factor=2.0, bond_thresh=0.35,
                                     concerted_thresh=0.35, root=0):

    def array2set(arr):
        return set([tuple(_) for _ in arr])

    bonds_present = array2set(geom.internal.bond_indices)
    eigvals, eigvecs = np.linalg.eigh(hessian)

    # There are probably no bonds missing if there are no negative eigenvalues
    if sum(eigvals < 0) == 0:
        return list()

    trans_vec = eigvecs[:, root]

    c3d = geom.coords3d
    bond_vec_empty = np.zeros_like(c3d)
    unique_bonds = array2set(get_bond_sets(geom.atoms, c3d, bond_factor=bond_factor))
    unique_bonds -= bonds_present
    unique_bonds = np.array(list(unique_bonds))

    bond_vecs = list()
    concerted_vecs = list()
    for m, k in unique_bonds:
        displ = c3d[k] - c3d[m]
        displ /= np.linalg.norm(displ)

        # Bond
        bond = bond_vec_empty.copy()
        bond[k] = displ
        bond[m] = -displ
        bond_vecs.append(bond)

        # Concerted movement
        conc = bond_vec_empty.copy()
        conc[k] = displ
        conc[m] = displ
        concerted_vecs.append(conc)

    def reshape(arr):
        return np.array(arr).reshape(-1, trans_vec.size)
    bond_vecs = reshape(bond_vecs)
    concerted_vecs = reshape(concerted_vecs)

    def overlaps(arr):
        return np.abs(arr.dot(trans_vec))
    bond_ovlps = overlaps(bond_vecs)
    concerted_ovlps = overlaps(concerted_vecs)

    unique_bonds = np.array(unique_bonds)
    missing_bonds = unique_bonds[bond_ovlps > bond_thresh]
    missing_concerted = unique_bonds[concerted_ovlps > concerted_thresh]

    missing_inds = array2set(missing_bonds) | array2set(missing_concerted)
    return missing_inds
Esempio n. 2
0
def geom_to_graph(geom):
    G = nx.Graph()
    G.add_nodes_from([(i, {
        "atom": atom
    }) for i, atom in enumerate(geom.atoms)])
    bonds = get_bond_sets(geom.atoms, geom.coords3d)
    c3d = geom.coords3d
    lengths = [np.linalg.norm(c3d[i] - c3d[j]) for i, j in bonds]
    bonds_with_lengths = [(i, j, {
        "length": length,
    }) for (i, j), length in zip(bonds, lengths)]
    G.add_edges_from(bonds_with_lengths)

    return G
Esempio n. 3
0
def cap_fragment(atoms, coords, fragment, link_atom="H", g=0.709):
    coords3d = coords.reshape(-1, 3)

    fragment_set = set(fragment)

    # Determine bond(s) that connect fragment with the rest
    bonds = get_bond_sets(atoms, coords3d)
    bond_sets = [set(b) for b in bonds]

    # Find all bonds that involve one atom of model. These bonds
    # connect the model to the real geometry. We want to cap these
    # bonds.
    break_bonds = [b for b in bond_sets if len(b & fragment_set) == 1]

    # Put capping atoms at every bond to break.
    # The model fragment size corresponds to the length of the union of
    # the model set and the atoms in break_bonds.
    capped_frag = fragment_set.union(*break_bonds)
    capped_inds = list(sorted(capped_frag))

    # Index map between the new model geometry and the original indices
    # in the real geometry.
    atom_map = {
        model_ind: real_ind
        for real_ind, model_ind in zip(capped_inds, range(len(capped_inds)))
    }

    links = list()
    for bb in break_bonds:
        to_cap = bb - fragment_set
        assert len(to_cap) == 1
        ind = list(bb - to_cap)[0]
        parent_ind = tuple(to_cap)[0]
        if g is None:
            g = get_g_value(atoms[ind], atoms[parent_ind], link_atom)
        link = Link(ind=ind, parent_ind=parent_ind, atom=link_atom, g=g)
        links.append(link)

    return atom_map, links