def is_same(self, point, eps): for idx in range(self._dim): args = (self._fvec[idx], point._fvec[idx]) kwargs = {"u": "deg", "limit": self._cycle[idx]} diff1D = fncs.angular_dist(*args, **kwargs) if diff1D > eps: return False return True
def abs_diff(self, point): diff = [None for idx in range(self._dim)] for idx in range(self._dim): args = (self._fvec[idx], point._fvec[idx]) kwargs = {"u": "deg", "limit": self._cycle[idx]} diff[idx] = fncs.angular_dist(*args, **kwargs) return diff
def distance_if_smaller(self, point, ref=float("inf")): refe2 = ref**2 dist2 = 0.0 for idx in range(self._dim): args = (self._fvec[idx], point._fvec[idx]) kwargs = {"u": "deg", "limit": self._cycle[idx]} dist2 += fncs.angular_dist(*args, **kwargs)**2 if dist2 > refe2: return float("inf") return dist2**0.5
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)
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)
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)