Exemple #1
0
def lonepair(xcc, lNH2):
    lps = {}
    for X, torsion1, torsion2 in lNH2:
        phi1 = fncs.dihedral(*(xcc[3 * at:3 * at + 3] for at in torsion1))
        phi2 = fncs.dihedral(*(xcc[3 * at:3 * at + 3] for at in torsion2))
        phi = tfh.lonepair_dihedrals_from_phis(phi1, phi2)
        lps[X] = phi
    return lps
Exemple #2
0
def assign_torsions(dcorr, graph1, graph2, xcc1, xcc2, symbols):
    '''
    only one at a time
    '''
    # number of non-assigned (initial)
    na_i = get_not_assigned(dcorr)
    # assignment based in proper torsions
    minad = float("inf")
    minnode1 = None
    minnode2 = None
    for node2, nodes1 in dcorr.items():
        if type(nodes1) == int: continue
        BC = None
        # check neighbors
        atA2, atB2, atC2, atD2 = node2, None, None, None
        for atB2 in graph2.neighbors(atA2):
            if type(dcorr[atB2]) != int: continue
            for atC2 in graph2.neighbors(atB2):
                if type(dcorr[atC2]) != int: continue
                for neigh in graph2.neighbors(atC2):
                    if type(dcorr[neigh]) != int: continue
                    if len(set([atA2, atB2, atC2, neigh])) != 4: continue
                    atD2 = neigh
                    break
                if atD2 is not None: break
            if atD2 is not None: break
        # torsion located?
        if atD2 is None: continue
        # Now, check A-B-C-D
        atoms2 = [atA2, atB2, atC2, atD2]
        xs2 = (xcc2[3 * at:3 * at + 3] for at in atoms2)
        angle2 = np.rad2deg(fncs.dihedral(*xs2)) % 360
        config2 = angle2 < 180
        # compare torsions
        for node1 in nodes1:
            atoms1 = [node1, dcorr[atB2], dcorr[atC2], dcorr[atD2]]
            xs1 = (xcc1[3 * at:3 * at + 3] for at in atoms1)
            angle1 = np.rad2deg(fncs.dihedral(*xs1))
            # difference
            ad = fncs.angular_dist(-angle2, angle1, u="deg")
            if ad < minad:
                minad = ad
                minnode1 = node1
                minnode2 = node2
    # Any new assignation to do??
    if minnode1 is None: return dcorr, na_i
    # assign
    dcorr[minnode2] = minnode1
    # number of non-assigned(final)
    dcorr, na_j = assign_check(dcorr)
    # return data
    if na_j != 0 and na_j != na_i:
        return assign_concatenate(dcorr, graph1, graph2)
    else:
        return assign_check(dcorr)
Exemple #3
0
def lonepair_dihedral_from_xs(xN, xH1, xH2, xB, xA):
    '''
    A-B-NH2
    return dihedral A-B-N-lp, lp being the lone pair
    '''
    # dihedral A-B-N-H1
    phi1 = fncs.dihedral(xA, xB, xN, xH1)
    # dihedral A-B-N-H2
    phi2 = fncs.dihedral(xA, xB, xN, xH2)
    # dihedral A-B-N-lp
    return lonepair_dihedrals_from_phis(phi1, phi2)
Exemple #4
0
def assign_cx3(dcorr, graph1, graph2, xcc1, xcc2, symbols):
    # number of non-assigned (initial)
    na_i = get_not_assigned(dcorr)
    # Assign in CX3 groups (CH3, CF3, CCl3, et cetera)
    for node2, nodes1 in dcorr.items():
        if type(nodes1) == int: continue
        if len(nodes1) != 3: continue
        neighbors2 = graph2.neighbors(node2)
        atC = neighbors2.pop()
        # check we have a C atom
        if len(neighbors2) != 0: continue
        if symbols[atC] != "C": continue
        # determine torsion X-C-B-A
        atA = None
        #print("*",node2+1,atC+1)
        for atB in graph2.neighbors(atC):
            if type(dcorr[atB]) != int: continue
            for neigh in graph2.neighbors(atB):
                if type(dcorr[neigh]) != int: continue
                if neigh == node2: continue
                if neigh == atC: continue
                atA = neigh
                #print(" ",atB+1,atA+1)
                break
            if atA is not None: break
        if atA is None: continue
        # calculate dihedral
        atoms2 = [node2, atC, atB, atA]
        #print([i+1 for i in atoms2])
        xs2 = (xcc2[3 * at:3 * at + 3] for at in atoms2)
        angle2 = np.rad2deg(fncs.dihedral(*xs2))
        # compare with the others
        minad = float("inf")
        minnode = None
        for node1 in nodes1:
            atoms1 = [node1, dcorr[atC], dcorr[atB], dcorr[atA]]
            xs1 = (xcc1[3 * at:3 * at + 3] for at in atoms1)
            angle1 = np.rad2deg(fncs.dihedral(*xs1))
            # difference
            ad = fncs.angular_dist(-angle2, angle1, u="deg")
            if ad < minad:
                minad = ad
                minnode = node1
        # apply
        dcorr[node2] = minnode
    # number of non-assigned(final)
    dcorr, na_j = assign_check(dcorr)
    # return data
    if na_j != 0 and na_j != na_i:
        return assign_concatenate(dcorr, graph1, graph2)
    else:
        return assign_check(dcorr)
Exemple #5
0
def assign_via_improper_case1(dcorr,graph_0,graph_t,xcc_0,xcc_t):
    '''
     C   D           correlation between A1, A2, ..., An
      \ /
  A1 - B - An        in this situation, B, C and D
      / \            are assigned so Ai-B-C-D improper
    A2  ...          torsion can be used
    '''
    # number of non-assigned (initial)
    na_i = get_num_of_not_assigned(dcorr)
    # Compare spatial organization (improper torsions)
    for node_t,nodes_0 in dcorr.items():
        if type(nodes_0) == int: continue
        # check neighbors
        atB2,atC2,atD2 = None,None,None
        for neigh in graph_t.neighbors(node_t):
            if type(dcorr[neigh]) != int: continue
            atB2,atC2,atD2 = neigh,None,None
            for nneigh in graph_t.neighbors(atB2):
               #print(node_t+1,neigh+1,nneigh+1)
                if nneigh == node_t: continue
                if type(dcorr[nneigh]) != int: continue
                if atC2 is None: atC2 = nneigh; continue
                if atD2 is None: atD2 = nneigh; break
            if atD2 is not None: break
        if atD2 is None: continue
        # now check spatial configuration
        atoms_t  = [node_t,atB2,atC2,atD2]
        xs_t     = (xcc_t[3*at:3*at+3] for at in atoms_t)
        angle_t  = np.rad2deg(fncs.dihedral(*xs_t))%360
        dcorr[node_t] = set([])
        # correlate to closest one
        mindist, minnode = float("inf"),None
        for node_0 in nodes_0:
            atoms_0  = [node_0,dcorr[atB2],dcorr[atC2],dcorr[atD2]]
            xs_0     = (xcc_0[3*at:3*at+3] for at in atoms_0)
            angle_0  = np.rad2deg(fncs.dihedral(*xs_0))%360
            dist     = fncs.angular_dist(angle_0,angle_t,u="deg")
            if dist < mindist:
                mindist = dist
                minnode = node_0
        dcorr[node_t] = minnode
        # break to avoid assign same node
        break
    # number of non-assigned(final)
    dcorr,na_j = assign_check(dcorr)
    # do again?
    if na_i != na_j and na_j != 0:
       dcorr = assign_via_improper_case1(dcorr,graph_0,graph_t,xcc_0,xcc_t)[0]
    # return data
    return assign_concatenate(dcorr,graph_0,graph_t)
Exemple #6
0
def assign_pyramid(dcorr,graph_0,graph_t,symbols_0,symbols_t,xcc_0,xcc_t):
    '''
     A1  B1    |    B2  A2    X1 --> X1 or X2?
      \ /            \ /
       X1      |      X2     Ai!=Bi!=Ci!=Di
      / \            / \     
     C1  D1    |    D2  C2   
    '''
    for X_t,nodes_0 in dcorr.items():
        if type(nodes_0) == int: continue
        if  len(nodes_0) !=  2 : continue
        neighbors_t = graph_t.neighbors(X_t)
        # number of neighbors
        nn_t = len(neighbors_t)
        if nn_t not in [3,4]: continue
        # check all neghbors are different
        nsymbols_t = len(set([symbols_t[idx] for idx in neighbors_t]))
        if nsymbols_t != nn_t: continue
        # sort neighbors by symbol
        neighbors_t = sorted(neighbors_t, key=lambda idx:symbols_t[idx])
        # dihedral A-B-C-D or X-A-B-C?
        if nn_t == 4: atoms_t = neighbors_t
        else        : atoms_t =  [X_t]+list(neighbors_t)
        # calculate dihedral
        xs_t     = (xcc_t[3*at:3*at+3] for at in atoms_t)
        angle_t  = np.rad2deg(fncs.dihedral(*xs_t))%360
        confi_t  = angle_t > 180
        # Check same distribution
        toremove = []
        for X_0 in nodes_0:
            neighbors_0 = graph_0.neighbors(X_0)
            nn_0 = len(neighbors_0)
            if nn_0 != nn_t: continue
            # assert they are different
            nsymbols_0 = len(set([symbols_0[idx] for idx in neighbors_0]))
            if nsymbols_0 != nn_0: continue
            # sort neighbors by symbol
            neighbors_0 = sorted(neighbors_0, key=lambda idx:symbols_0[idx])
            # dihedral A-B-C-D or X-A-B-C?
            if nn_0 == 4: atoms_0 = neighbors_0
            else        : atoms_0 =  [X_0]+list(neighbors_0)
            # calculate dihedral
            xs_0    = (xcc_0[3*at:3*at+3] for at in atoms_0)
            angle_0 = np.rad2deg(fncs.dihedral(*xs_0))%360
            confi_0 = angle_0 > 180
            if confi_0 != confi_t: toremove.append(X_0)
        # remove
        for X_0 in toremove: nodes_0.remove(X_0)
        dcorr[X_t] = nodes_0
    # return data
    return assign_concatenate(dcorr,graph_0,graph_t)
Exemple #7
0
def test_hsconstraints(lzmat, zmatvals, constr, which="hard"):
    if constr is None or len(constr) == 0: return True
    # the xcc
    xcc = None
    # check constraints
    for ic, icdomain in constr:
        if ic in zmatvals:
            icvalue = zmatvals[ic]
            if icvalue < 0.0: icvalue = icvalue % 360
        else:
            # Get atoms
            icatoms = [int(at) - 1 for at in ic.split("-")]
            nicatoms = len(icatoms)
            # Get xcc for each atom
            if xcc is None: xcc = intl.zmat2xcc(lzmat, zmatvals)
            xyzs = [fncs.xyz(xcc, at) for at in icatoms]
            # calculate value in xcc
            if nicatoms == 2: icvalue = fncs.distance(*xyzs) * ANGSTROM
            elif nicatoms == 3: icvalue = np.rad2deg(fncs.angle(*xyzs)) % 360
            elif nicatoms == 4:
                icvalue = np.rad2deg(fncs.dihedral(*xyzs)) % 360
            else:
                raise Exception
        # in domain?
        boolean = fncs.float_in_domain(icvalue, icdomain)
        if which == "hard" and boolean is False: return False
        if which == "soft" and boolean is True: return True
    # (hard) all of them are fulfilled
    if which == "hard": return True
    # (soft) all of them failed
    if which == "soft": return False
Exemple #8
0
def correct_NH2_inversion(lzmat, zmatvals, zmatatoms, lNH2):
    inversion = False
    if len(lNH2) != 0:
        # Create Cartesian coords
        xcc0 = intl.zmat2xcc(lzmat, zmatvals)
        # Check every NH2 group
        for HNRH_atoms, HNRH_value, HNRH_bool in lNH2:
            # check inversion
            cvalue, cbool = deal_with_HNRH(HNRH_atoms, xcc0)
            if HNRH_bool == cbool: continue
            # EXCHANGE HIDROGEN ATOMS!!
            inversion = True
            idxH1 = HNRH_atoms[0]
            idxH2 = HNRH_atoms[3]
            x1 = xcc0[3 * idxH1:3 * idxH1 + 3]
            x2 = xcc0[3 * idxH2:3 * idxH2 + 3]
            xcc0[3 * idxH1:3 * idxH1 + 3] = x2
            xcc0[3 * idxH2:3 * idxH2 + 3] = x1
            # recalculate zmatrix values (only those involving H1 or H2)
            for ic, atoms in zmatatoms.items():
                if not (idxH1 in atoms or idxH2 in atoms): continue
                xs = (xcc0[3 * at:3 * at + 3] for at in atoms)
                if len(atoms) == 2:
                    zmatvals[ic] = ANGSTROM * fncs.distance(*xs)
                if len(atoms) == 3: zmatvals[ic] = np.rad2deg(fncs.angle(*xs))
                if len(atoms) == 4:
                    zmatvals[ic] = np.rad2deg(fncs.dihedral(*xs))
    return zmatvals, inversion
Exemple #9
0
def deal_with_HNRH(HNRH_atoms, xcc):
    '''
    HNRH_atoms --> idxH1, idxN, idxR, idxH2
    idxH1: index for first H atom
    idxN : index for N atom
    idxR : index for R group
    idxH2: index for second H atom
    '''
    HNRH_value = fncs.dihedral(*(xcc[3 * at:3 * at + 3] for at in HNRH_atoms))
    HNRH_bool = np.rad2deg(HNRH_value) % 360 < 180
    return HNRH_value, HNRH_bool
Exemple #10
0
def assign_spatial(dcorr, graph1, graph2, xcc1, xcc2, symbols):
    # number of non-assigned (initial)
    na_i = get_not_assigned(dcorr)
    # Compare spatial organization (improper torsions)
    for node2, nodes1 in dcorr.items():
        if type(nodes1) == int: continue
        BC = None
        # check neighbors
        atB2, atC2, atD2 = None, None, None
        for neigh in graph2.neighbors(node2):
            if type(dcorr[neigh]) != int: continue
            atB2 = neigh
            atC2, atD2 = None, None
            for nneigh in graph2.neighbors(atB2):
                #print(node2+1,neigh+1,nneigh+1)
                if nneigh == node2: continue
                if type(dcorr[nneigh]) != int: continue
                if atC2 is None:
                    atC2 = nneigh
                    continue
                if atD2 is None:
                    atD2 = nneigh
                    break
            if atD2 is not None: break
            if atC2 is not None: BC = (atB2, atC2)
        # now check spatial configuration
        if atD2 is not None:
            atoms2 = [node2, atB2, atC2, atD2]
            xs2 = (xcc2[3 * at:3 * at + 3] for at in atoms2)
            angle2 = np.rad2deg(fncs.dihedral(*xs2)) % 360
            config2 = angle2 < 180
            dcorr[node2] = set([])
            #print("*",node2+1,[i+1 for i in atoms2],angle2)
            for node1 in nodes1:
                atoms1 = [node1, dcorr[atB2], dcorr[atC2], dcorr[atD2]]
                xs1 = (xcc1[3 * at:3 * at + 3] for at in atoms1)
                angle1 = np.rad2deg(fncs.dihedral(*xs1)) % 360
                config1 = angle1 < 180
                #print("*",node1+1,[i+1 for i in atoms1],angle1)
                if config1 == config2:
                    dcorr[node2].add(node1)
        #print()
        elif BC is not None and len(nodes1) == 2:
            atB2, atC2 = BC
            # look for the other node with same assigments in graph1
            node2a = node2
            node2b = None
            for node2_, nodes1_ in dcorr.items():
                if node2_ == node2a: continue
                if nodes1 != nodes1_: continue
                node2b = node2_
                break
            if node2b is None: continue
            # assert both nodes are connected to the same atoms!!
            if graph2.neighbors(node2a) != graph2.neighbors(node2b): continue
            # config in graph2
            atoms2 = [node2a, node2b, atB2, atC2]
            xs2 = (xcc2[3 * at:3 * at + 3] for at in atoms2)
            angle2 = np.rad2deg(fncs.dihedral(*xs2)) % 360
            config2 = angle2 < 180
            # config in graph1
            node1a, node1b = nodes1
            atoms1 = [node1a, node1b, dcorr[atB2], dcorr[atC2]]
            xs1 = (xcc1[3 * at:3 * at + 3] for at in atoms1)
            angle1 = np.rad2deg(fncs.dihedral(*xs1)) % 360
            config1 = angle1 < 180
            if config1 == config2:
                dcorr[node2a] = node1a
                dcorr[node2b] = node1b
            else:
                dcorr[node2a] = node1b
                dcorr[node2b] = node1a
    # number of non-assigned(final)
    dcorr, na_j = assign_check(dcorr)
    # return data
    if na_j != 0 and na_j != na_i:
        return assign_concatenate(dcorr, graph1, graph2)
    else:
        return assign_check(dcorr)
Exemple #11
0
 def dihedral(self, at1, at2, at3, at4):
     x1 = self._xcc[3 * at1:3 * at1 + 3]
     x2 = self._xcc[3 * at2:3 * at2 + 3]
     x3 = self._xcc[3 * at3:3 * at3 + 3]
     x4 = self._xcc[3 * at4:3 * at4 + 3]
     return fncs.dihedral(x1, x2, x3, x4)
Exemple #12
0
def assign_via_improper_case2(dcorr,graph_0,graph_t,xcc_0,xcc_t):
    '''
     C   D           correlation between A1 & A2
      \ /
       B             in this situation, B, C are
      / \            assigned, but D is not!
    A1  A2           Assignation is done via A1-B-C-A2
    '''
    # number of non-assigned (initial)
    na_i = get_num_of_not_assigned(dcorr)
    # Compare spatial organization (improper torsions)
    for node_t,nodes_0 in dcorr.items():
        if type(nodes_0) == int: continue
        if  len(nodes_0) !=  2 : continue
        BC = None
        # check neighbors
        atB2,atC2,atD2 = None,None,None
        for neigh in graph_t.neighbors(node_t):
            if type(dcorr[neigh]) != int: continue
            atB2,atC2,atD2 = neigh,None,None
            for nneigh in graph_t.neighbors(atB2):
               #print(node_t+1,neigh+1,nneigh+1)
                if nneigh == node_t: continue
                if type(dcorr[nneigh]) != int: continue
                if atC2 is None: atC2 = nneigh; continue
                if atD2 is None: atD2 = nneigh; break
            if atD2 is not None: break
            if atC2 is not None: BC = (atB2,atC2)
        # assert D is not assigned
        if atD2 is not None: continue
        # assert B and C are assigned
        if BC   is     None: continue
        # Unpack
        atB2,atC2 = BC
        # look for the other node with same assigments in graph_0
        node_ta = node_t
        node_tb = None
        for node_t_,nodes_0_ in dcorr.items():
            if node_t_ == node_ta : continue
            if nodes_0 != nodes_0_: continue
            node_tb = node_t_
            break
        if node_tb is None: continue
        # assert both nodes are connected to the same atoms!!
        if graph_t.neighbors(node_ta) != graph_t.neighbors(node_tb): continue
        # config in graph_t
        atoms2  = [node_ta,node_tb,atB2,atC2]
        xs2     = (xcc_t[3*at:3*at+3] for at in atoms2)
        angle2  = np.rad2deg(fncs.dihedral(*xs2))%360
        config2 = angle2 < 180
        # config in graph_0
        node_0a,node_0b = nodes_0
        atoms1 = [node_0a,node_0b,dcorr[atB2],dcorr[atC2]]
        xs1     = (xcc_0[3*at:3*at+3] for at in atoms1)
        angle1  = np.rad2deg(fncs.dihedral(*xs1))%360
        config1 = angle1 < 180
        if config1 == config2:
           dcorr[node_ta] = node_0a
           dcorr[node_tb] = node_0b
        else:
           dcorr[node_ta] = node_0b
           dcorr[node_tb] = node_0a
    # number of non-assigned(final)
    dcorr,na_j = assign_check(dcorr)
    # return data
    return assign_concatenate(dcorr,graph_0,graph_t)
Exemple #13
0
def xcc2vec(xcc, inpvars):
    phis = []
    for X in inpvars._ttorsions:
        xs = [xcc[3 * at:3 * at + 3] for at in inpvars._tatoms[X]]
        phis.append(np.rad2deg(fncs.dihedral(*xs)))
    return TorPESpoint(phis)