def GetOrientTransmat(self, biounit=False, target=False): cen = np.zeros((3,1)) cenlist = self.Centroid(biounit, target) cen[0:3] = [[cenlist[0]],[cenlist[1]],[cenlist[2]]] tmat = translation_matrix(-self.Centroid(biounit, target)) max = 0 farthestxyz = None for atom in self.IterAtoms(biounit, target): dist = np.sum((atom.xyz[0:3] - cen)**2) if dist > max: farthestxyz = atom.xyz[0:3] - cen max = dist firstrotax = np.cross(farthestxyz.transpose().tolist()[0], np.array([1,0,0])) firstrotang = np.arccos(np.dot(farthestxyz.transpose().tolist()[0], np.array([1,0,0]))/(np.sqrt(np.dot(farthestxyz.transpose().tolist()[0], farthestxyz.transpose().tolist()[0])))) firstrotmat = rotation_matrix(firstrotang, firstrotax, self.Centroid(biounit, target)) max = 0 firsttransmat = tmat.dot(firstrotmat) for atom in self.IterAtoms(biounit, target): dist = sum(firsttransmat.dot(atom.xyz)[1:3]**2) if dist > max: secfarthestyz = firsttransmat.dot(atom.xyz)[0:3] max = dist secfarthestyz[0] = 0 secondrotax = np.array([1,0,0]) secondrotang = np.arccos(np.dot(secfarthestyz.transpose().tolist()[0], np.array([0,1,0]))/np.sqrt(np.dot(secfarthestyz.transpose().tolist()[0],secfarthestyz.transpose().tolist()[0]))) secondrotmat = rotation_matrix(secondrotang, secondrotax, self.Centroid(biounit, target)) return secondrotmat.dot(firsttransmat)
def RotateSplit(self, angle, direction, point=None, biounit=False, ca=True): if point==None: point=[0,0,0] tmat = translation_matrix(point) newcentroid = np.array(point) + self.Centroid(biounit, ca) rotmat = rotation_matrix(angle, direction, newcentroid.tolist()) for atom in self.IterAtoms(biounit): atom.xyz = rotmat.dot(tmat.dot(atom.xyz))
def PairObjectiveSplit(self, other, angvecpnt, biounit=False, ca=True): tmat = translation_matrix(angvecpnt[4:7]) newcentroid = np.array(angvecpnt[4:7]) + self.Centroid(biounit, ca) rotmat = rotation_matrix(angvecpnt[0], angvecpnt[1:4], newcentroid.tolist()) sqdists = [] for atom in (atom for atom in self.IterAtoms(biounit, ca) if atom.pair!=None): sqdist = np.sum((atom.pair.xyz - rotmat.dot(tmat.dot(atom.xyz)))**2) if sqdist < 10000000: sqdists.append(sqdist) if len(sqdists) > 0: return np.sqrt(np.mean(sqdists)) else: return 99.0
def Objective(self, other, transrot, biounit=False, ca=True): now = time.time() mins = [] mat = rotation_matrix(transrot[5], (0,0,1), self.Centroid(biounit, ca)).dot(rotation_matrix(transrot[4], (0,1,0), self.Centroid(biounit, ca))).dot(rotation_matrix(transrot[3], (1,0,0), self.Centroid(biounit, ca))).dot(translation_matrix(transrot[0:3])) if self.counter % 10==0: oatoms = [oatom for oatom in other.IterAtoms(biounit,ca)] for satom in self.IterAtoms(biounit,ca): oatoms.sort(key=lambda atom: np.sum((atom.xyz - mat.dot(satom.xyz))**2)) satom.nearby = oatoms[:100] # satom_gen = self.IterAtoms(biounit,ca) # for i in range(20): # satom_gen.next() # test_satom = satom_gen.next() # print test_satom.resseq # for oatom in test_satom.nearby: # print oatom.resseq self.counter += 1 for satom in self.IterAtoms(biounit, ca): mins.append(np.min([np.sum((oatom.xyz - mat.dot(satom.xyz))**2) for oatom in satom.nearby])) print 'one objective took %f' % (time.time() - now) print transrot return np.sqrt(np.mean(mins))
def RotatePointMat(ang, pnt, seg1=None, seg2=None): '''returns 4x4 transformation matrix that will rotate by ang (in radians) about pnt. line segments seg1 and seg2 may optionally be specified in order to fix the axis of rotation as their cross product. each seg is a line segment represented by a list of two points. otherwise, rotation occurs about the z axis''' if seg1!=None and seg2!=None: vec1 = np.array(seg1[1]) - np.array(seg1[0]) vec2 = np.array(seg2[1]) - np.array(seg2[0]) if np.allclose(vec1,vec2): axis = (0,0,-1) else: axis = np.cross(vec1, vec2) else: axis = (0,0,-1) return rotation_matrix(ang, axis, point=pnt)
def UnbiasedObjective(self, other, angvecpnt, biounit=False, ca=True): mins = [] tmat = translation_matrix(angvecpnt[4:7]) newcentroid = np.array(angvecpnt[4:7]) + self.Centroid(biounit, ca) rotmat = rotation_matrix(angvecpnt[0], angvecpnt[1:4], newcentroid.tolist()) if self.counter % 5==0: oatoms = [oatom for oatom in other.IterAtoms(biounit,ca)] for satom in self.IterAtoms(biounit,ca): oatoms.sort(key=lambda atom: np.sum((atom.xyz - rotmat.dot(tmat.dot(satom.xyz)))**2)) satom.nearby = oatoms[:10] self.counter += 1 for satom in self.IterAtoms(biounit, ca): mins.append(np.min([np.sum((oatom.xyz - rotmat.dot(tmat.dot(satom.xyz)))**2) for oatom in satom.nearby])) return np.sqrt(np.mean(mins))
def OverlaySegMat(seg0, seg1): '''returns 4x4 transformation matrix that will overlay seg0 on seg1. each seg is a line segment represented by a list of two points''' vec0 = np.array(seg0[1]) - np.array(seg0[0]) vec1 = np.array(seg1[1]) - np.array(seg1[0]) axis = np.cross(vec0, vec1) if np.allclose([0,0,0],axis): axis = (0,0,1) if np.allclose(vec0,vec1): ang = 0 elif np.allclose(vec0,-vec1): ang = math.pi else: ang = np.arccos(np.dot(vec0, vec1)/(np.sqrt(np.dot(vec0, vec0))*np.sqrt(np.dot(vec1, vec1)))) # if np.isnan(ang): # ang = math.pi trans = np.array(seg1[0]) - np.array(seg0[0]) return translation_matrix(trans).dot(rotation_matrix(ang, axis, point=seg0[0]))
def RotateBiounit(self, trans, rot): mat = rotation_matrix(rot[2], (0,0,1), self.Centroid(biounit, ca)).dot(rotation_matrix(rot[1], (0,1,0), self.Centroid(biounit, ca))).dot(rotation_matrix(rot[0], (1,0,0), self.Centroid(biounit, ca))).dot(translation_matrix(trans[0:3])) for atom in self.IterAtoms(biounit=True): atom.xyz = mat.dot(atom.xyz)
def GetRotVecVec(vec1, vec2, point=None): rotang = np.arccos(np.dot(vec1, vec2)/(np.sqrt(np.dot(vec1, vec1))*np.sqrt(np.dot(vec2, vec2)))) rotax = np.cross(vec1, vec2) return rotation_matrix(rotang, rotax, point)
def Rotate(self, angle, direction, point=None, biounit=False, target=False): mat = rotation_matrix(angle, direction, point) for atom in self.IterAtoms(biounit, target): atom.xyz = mat.dot(atom.xyz)
def PairObjective(self, other, angvecpnt, biounit=False, ca=True): mat = rotation_matrix(angvecpnt[0], angvecpnt[1:4], angvecpnt[4:7]) sqdists = [] for atom in self.IterAtoms(biounit, ca): sqdists.append(np.sum((atom.pair.xyz - mat.dot(atom.xyz))**2)) return np.sqrt(np.mean(sqdists))