def cluster(parametersobject): number_of_orientations = parametersobject.parameterdic['Number_of_orientations'] skip = parametersobject.parameterdic['Skip_initial_frames'] data = [] f_framelist = open('analysis/frames_read.txt', 'w+') framelist = [] for i in range(1, 1+number_of_orientations): with open('analysis/coord_matrix_'+str(i).zfill(3)+'.txt', 'r') as f: l = f.readlines() data.extend([[float(p) for p in line.strip().split()[1:10]] for line in l[skip:]]) f_framelist.write(str(len(l))+'\n') framelist.append(len(l)-skip) f_framelist.close() ms = MeanShift(n_jobs = -2, cluster_all = True) ms.fit(data) labels = ms.labels_ names, numbers = np.unique(labels, return_counts = True) cluster_centers = ms.cluster_centers_ fout = open('analysis/clusters.txt', 'w+') fout.write('label\tcount\ttheta\tphi\ttheta_x\ttheta_y\ttheta_z\tx\ty\tz\tR[0][0]\tR[0][1]\tR[0][2]\tR[1][0]\tR[1][1]\tR[1][2]\tR[2][0]\tR[2][1]\tR[2][2]\n') phi = 0 for i, line in enumerate(cluster_centers): R = [_[:] for _ in [[]]*9] x, y, z = line[0], line[1], line[2] R[0] = line[3:6] R[1] = line[6:9] R[2] = np.cross(R[0], R[1]) V = Vector(x, y, z) if V.norm() > 1e-6: theta = V.angle(Vector(0,0,1)) norm = np.sqrt(x*x + y*y) if norm > 1e-6: phi = np.arctan2(y,x) #otherwise phi isn't updated and the previous value is copied. Keeps it from jumping near the poles. else: theta = 0.0 theta_x = np.arctan2(R[2][1], R[2][2]) theta_y = np.arctan2(-R[2][0], np.sqrt(R[2][1]*R[2][1]+R[2][2]*R[2][2])) theta_z = np.arctan2(R[1][0], R[0][0]) fout.write(str(names[i])+'\t'+str(numbers[i])+'\t') fout.write(str(theta)+'\t'+str(phi)+'\t') fout.write(str(theta_x)+'\t'+str(theta_y)+'\t'+str(theta_z)+'\t') for value in line: fout.write(str(value)+'\t') fout.write(str(R[2][0])+'\t'+str(R[2][1])+'\t'+str(R[2][2])+'\t') fout.write('\n') fout.close() n_clusters_ = len(np.unique(labels)) print("Number of estimated clusters:", n_clusters_) classification = open('analysis/frame_cluster_types.txt', 'w+') frame_counter = 0 framelist_counter = 0 for label in labels: if frame_counter<framelist[framelist_counter]: classification.write(str(label)+'\t') frame_counter+=1 else: framelist_counter+=1 classification.write('\n'+str(label)+'\t') frame_counter=1 '''
def from4atoms(OA, OB, OC, OD, u, v, l, m, accept_no_solution=True): u = pi - u v = pi - v a = OA - OC b = OB - OD ddiff = OC - OD + a - b # (BA) = (B-A) x = a.norm() * l * cos(u) y = b.norm() * m * cos(v) rx = x ry = y - b * ddiff r1 = a r2 = b if(abs(r1[0]) < 0.000001): if(abs(r2[0]) < 0.000001): print "WARNING: r1 = r2 = 0.0" # Swap rows tmp = r1 r1 = r2 r2 = tmp tmp = rx ry = rx rx = tmp # Reduce the matrix factor = r1[0] r1 = r1 / factor rx = rx / factor factor = r2[0] r2 = r2 - (r1 ** factor) ry = ry - rx * factor factor = r2[1] r2 = r2 / factor ry = ry / factor factor = r1[1] r1 = r1 - r2 ** factor rx = rx - ry * factor # Make solution space vectors alpha = r1[2] beta = r2[2] gamma = rx delta = ry u = Vector(-alpha,-beta,1.0) v = Vector(gamma, delta, 0) # Solve quadratic equation for norm of c acoef = (u.norm())**2 bcoef = 2*(u*v) ccoef = (v.norm())**2 - l**2 disc = bcoef**2 - 4*acoef*ccoef if(disc < 0.0): # This is the sick case where we can't find _any_ solution if not accept_no_solution: raise ValueError, "from4atoms: no solution found (disc=%f)" % disc else: disc = 0 x1 = (-bcoef - sqrt(disc))/(2*acoef) x2 = (-bcoef + sqrt(disc))/(2*acoef) # Create the two c-vectors c1 = u ** x1 + v c2 = u ** x2 + v # The two candidate E-poitns E1 = OA + c1 E2 = OA + c2 # The two candidate d-vectors d1 = E1 - OB d2 = E2 - OB # Pick the one with smallest norm difference d1norm = d1.norm() d2norm = d2.norm() diff1 = abs(d1norm - m) diff2 = abs(d2norm - m) if(diff1 < diff2): return E1 else: return E2