def _snapEndPointHorizontalOrVertical(self): """ Snap the second endpoint of the line (and thus the whole line) to the screen horizontal or vertical vectors. @return: The new endPoint2 i.e. the moving endpoint of the rubberband line . This value may be same as previous or snapped so that line is horizontal or vertical depending upon the angle it makes with the horizontal and vertical. @rtype: B{A} """ up = self.glpane.up down = self.glpane.down left = self.glpane.left right = self.glpane.right endPoint2 = self.endPoint2 snapVector = V(0, 0, 0) currentLineVector = norm(self.endPoint2 - self.endPoint1) theta_horizontal = angleBetween(right, currentLineVector) theta_vertical = angleBetween(up, currentLineVector) theta_horizontal_old = theta_horizontal theta_vertical_old = theta_vertical if theta_horizontal != 90.0: theta_horizontal = min(theta_horizontal, (180.0 - theta_horizontal)) if theta_vertical != 90.0: theta_vertical = min(theta_vertical, 180.0 - theta_vertical) theta = min(theta_horizontal, theta_vertical) if theta <= 2.0 and theta != 0.0: self._snapOn = True if theta == theta_horizontal: self._snapType = 'HORIZONTAL' if theta_horizontal == theta_horizontal_old: snapVector = right else: snapVector = left elif theta == theta_vertical: self._snapType = 'VERTICAL' if theta_vertical == theta_vertical_old: snapVector = up else: snapVector = down endPoint2 = self.endPoint1 + \ vlen(self.endPoint1 - self.endPoint2)*snapVector else: self._snapOn = False return endPoint2
def get_dihedral(self): """ Returns the dihedral between two atoms (nuclei) """ wx = self.atoms[0].posn()-self.atoms[1].posn() yx = self.atoms[2].posn()-self.atoms[1].posn() xy = -yx zy = self.atoms[3].posn()-self.atoms[2].posn() u = cross(wx, yx) v = cross(xy, zy) if dot(zy, u) < 0: # angles go from -180 to 180, wware 051101 return -angleBetween(u, v) # use new acos(dot) func, wware 051103 else: return angleBetween(u, v)
def get_dihedral(self): """ Returns the dihedral between two atoms (nuclei) """ wx = self.atoms[0].posn() - self.atoms[1].posn() yx = self.atoms[2].posn() - self.atoms[1].posn() xy = -yx zy = self.atoms[3].posn() - self.atoms[2].posn() u = cross(wx, yx) v = cross(xy, zy) if dot(zy, u) < 0: # angles go from -180 to 180, wware 051101 return -angleBetween(u, v) # use new acos(dot) func, wware 051103 else: return angleBetween(u, v)
def get_angle(self): """ Returns the angle between two atoms (nuclei) """ v01 = self.atoms[0].posn() - self.atoms[1].posn() v21 = self.atoms[2].posn() - self.atoms[1].posn() return angleBetween(v01, v21)
def get_angle(self): """ Returns the angle between two atoms (nuclei) """ v01 = self.atoms[0].posn()-self.atoms[1].posn() v21 = self.atoms[2].posn()-self.atoms[1].posn() return angleBetween(v01, v21)
def _snapEndPointToStandardAxis(self): """ Snap the second endpoint of the line so that it lies on the nearest axis vector. (if its close enough) . This functions keeps the uses the current rubberband line vector and just extends the second end point so that it lies at the intersection of the nearest axis vector and the rcurrent rubberband line vector. @return: The new endPoint2 i.e. the moving endpoint of the rubberband line . This value may be same as previous or snapped to lie on the nearest axis (if one exists) @rtype: B{A} """ x_axis = V(1, 0, 0) y_axis = V(0, 1, 0) z_axis = V(0, 0, 1) endPoint2 = self.endPoint2 currentLineVector = norm(self.endPoint2 - self.endPoint1) theta_x = angleBetween(x_axis, self.endPoint2) theta_y = angleBetween(y_axis, self.endPoint2) theta_z = angleBetween(z_axis, self.endPoint2) theta_x = min(theta_x, (180 - theta_x)) theta_y = min(theta_y, (180 - theta_y)) theta_z = min(theta_z, (180 - theta_z)) theta = min(theta_x, theta_y, theta_z) if theta < 2.0: if theta == theta_x: self._standardAxisVectorForDrawingSnapReference = x_axis elif theta == theta_y: self._standardAxisVectorForDrawingSnapReference = y_axis elif theta == theta_z: self._standardAxisVectorForDrawingSnapReference = z_axis endPoint2 = ptonline(self.endPoint2, V(0, 0, 0), self._standardAxisVectorForDrawingSnapReference) else: self._standardAxisVectorForDrawingSnapReference = None return endPoint2
def _snapEndPointToStandardAxis(self): """ Snap the second endpoint of the line so that it lies on the nearest axis vector. (if its close enough) . This functions keeps the uses the current rubberband line vector and just extends the second end point so that it lies at the intersection of the nearest axis vector and the rcurrent rubberband line vector. @return: The new endPoint2 i.e. the moving endpoint of the rubberband line . This value may be same as previous or snapped to lie on the nearest axis (if one exists) @rtype: B{A} """ x_axis = V(1, 0, 0) y_axis = V(0, 1, 0) z_axis = V(0, 0, 1) endPoint2 = self.endPoint2 currentLineVector = norm(self.endPoint2 - self.endPoint1) theta_x = angleBetween(x_axis, self.endPoint2) theta_y = angleBetween(y_axis, self.endPoint2) theta_z = angleBetween(z_axis, self.endPoint2) theta_x = min(theta_x, (180 - theta_x)) theta_y = min(theta_y, (180 - theta_y)) theta_z = min(theta_z, (180 - theta_z)) theta = min(theta_x, theta_y, theta_z) if theta < 2.0: if theta == theta_x: self._standardAxisVectorForDrawingSnapReference = x_axis elif theta == theta_y: self._standardAxisVectorForDrawingSnapReference = y_axis elif theta == theta_z: self._standardAxisVectorForDrawingSnapReference = z_axis endPoint2 = ptonline( self.endPoint2, V(0, 0, 0), self._standardAxisVectorForDrawingSnapReference) else: self._standardAxisVectorForDrawingSnapReference = None return endPoint2
def _orient(self, cntChunk, pt1, pt2): """ Orients the CNT I{cntChunk} based on two points. I{pt1} is the first endpoint (origin) of the nanotube. The vector I{pt1}, I{pt2} defines the direction and central axis of the nanotube. @param pt1: The starting endpoint (origin) of the nanotube. @type pt1: L{V} @param pt2: The second point of a vector defining the direction and central axis of the nanotube. @type pt2: L{V} """ a = V(0.0, 0.0, -1.0) # <a> is the unit vector pointing down the center axis of the default # DNA structure which is aligned along the Z axis. bLine = pt2 - pt1 bLength = vlen(bLine) b = bLine / bLength # <b> is the unit vector parallel to the line (i.e. pt1, pt2). axis = cross(a, b) # <axis> is the axis of rotation. theta = angleBetween(a, b) # <theta> is the angle (in degress) to rotate about <axis>. scalar = bLength * 0.5 rawOffset = b * scalar if 0: # Debugging code. print "" print "uVector a = ", a print "uVector b = ", b print "cross(a,b) =", axis print "theta =", theta print "cntRise =", self.getCntRise() print "# of cells =", self.getNumberOfCells() print "scalar =", scalar print "rawOffset =", rawOffset if theta == 0.0 or theta == 180.0: axis = V(0, 1, 0) # print "Now cross(a,b) =", axis rot = (pi / 180.0) * theta # Convert to radians qrot = Q(axis, rot) # Quat for rotation delta. # Move and rotate the nanotube into final orientation. cntChunk.move( qrot.rot(cntChunk.center) - cntChunk.center + rawOffset + pt1) cntChunk.rot(qrot) # Bruce suggested I add this. It works here, but not if its # before move() and rot() above. Mark 2008-04-11 cntChunk.full_inval_and_update() return
def _orient(self, cntChunk, pt1, pt2): """ Orients the CNT I{cntChunk} based on two points. I{pt1} is the first endpoint (origin) of the nanotube. The vector I{pt1}, I{pt2} defines the direction and central axis of the nanotube. @param pt1: The starting endpoint (origin) of the nanotube. @type pt1: L{V} @param pt2: The second point of a vector defining the direction and central axis of the nanotube. @type pt2: L{V} """ a = V(0.0, 0.0, -1.0) # <a> is the unit vector pointing down the center axis of the default # DNA structure which is aligned along the Z axis. bLine = pt2 - pt1 bLength = vlen(bLine) b = bLine/bLength # <b> is the unit vector parallel to the line (i.e. pt1, pt2). axis = cross(a, b) # <axis> is the axis of rotation. theta = angleBetween(a, b) # <theta> is the angle (in degress) to rotate about <axis>. scalar = bLength * 0.5 rawOffset = b * scalar if 0: # Debugging code. print "" print "uVector a = ", a print "uVector b = ", b print "cross(a,b) =", axis print "theta =", theta print "cntRise =", self.getCntRise() print "# of cells =", self.getNumberOfCells() print "scalar =", scalar print "rawOffset =", rawOffset if theta == 0.0 or theta == 180.0: axis = V(0, 1, 0) # print "Now cross(a,b) =", axis rot = (pi / 180.0) * theta # Convert to radians qrot = Q(axis, rot) # Quat for rotation delta. # Move and rotate the nanotube into final orientation. cntChunk.move(qrot.rot(cntChunk.center) - cntChunk.center + rawOffset + pt1) cntChunk.rot(qrot) # Bruce suggested I add this. It works here, but not if its # before move() and rot() above. Mark 2008-04-11 cntChunk.full_inval_and_update() return
def _orientRawDnaGroup(self, rawDnaGroup, pt1, pt2): """ Orients the raw DNA group based on two endpoints. @param rawDnaGroup: The raw DNA group created by make(). @type rawDnaGroup: L{Group} @param pt1: The first endpoint of the DNA strand. @type pt1: L{V} @param pt2: The second endpoint of the DNA strand. @type pt2: L{V} @attention: Only works for PAM5 models. """ a = V(0.0, 0.0, -1.0) # <a> is the unit vector pointing down the center axis of the default # rawDnaGroup structure which is aligned along the Z axis. bLine = pt2 - pt1 bLength = vlen(bLine) b = bLine/bLength # <b> is the unit vector parallel to the line (i.e. pt1, pt2). axis = cross(a, b) # <axis> is the axis of rotation. theta = angleBetween(a, b) # <theta> is the angle (in degress) to rotate about <axis>. scalar = self.dna.getBaseRise() * self.getSequenceLength() * 0.5 rawOffset = b * scalar if 0: # Debugging code. print "" print "uVector a = ", a print "uVector b = ", b print "cross(a,b) =", axis print "theta =", theta print "baserise =", self.dna.getBaseRise() print "seqLength =", self.getSequenceLength() print "scalar =", scalar print "rawOffset =", rawOffset if theta == 0.0 or theta == 180.0: axis = V(0, 1, 0) # print "Now cross(a,b) =", axis rot = (pi / 180.0) * theta # Convert to radians qrot = Q(axis, rot) # Quat for rotation delta. # Move and rotate the base chunks into final orientation. for m in rawDnaGroup.members: m.move(qrot.rot(m.center) - m.center + rawOffset + pt1) m.rot(qrot)
def _are_crossover_atompairs(self, atomPair1, atomPair2, orthogonal_vector): """ """ atm1, neighbor1 = atomPair1 center_1 = (atm1.posn() + neighbor1.posn()) / 2.0 atm2, neighbor2 = atomPair2 center_2 = (atm2.posn() + neighbor2.posn()) / 2.0 distance = vlen(center_1 - center_2) if distance > MAX_DISTANCE_BETWEEN_CROSSOVER_SITES: return False, distance, () #@NOTE: In self._filter_neighbor_atompairs() where we create the #atompairlists, we make sure that the atoms are ordered in +ve bond_direction #Below, we just check the relative direction of atoms. #@@@@@METHOD TO BE WRITTEN FURTHER centerVec = center_1 - center_2 if self.graphicsMode.DEBUG_DRAW_AVERAGE_CENTER_PAIRS_OF_POTENTIAL_CROSSOVERS: self._DEBUG_avg_center_pairs_of_potential_crossovers.append( (center_1, center_2)) theta = angleBetween(orthogonal_vector, centerVec) if dot(centerVec, orthogonal_vector) < 1: theta = 180.0 - theta if abs( theta ) > MAX_ANGLE_BET_PLANE_NORMAL_AND_AVG_CENTER_VECTOR_OF_CROSSOVER_PAIRS: return False, distance, () crossoverPairs = (atm1, neighbor1, atm2, neighbor2) for a in crossoverPairs: if not self._final_crossover_atoms_dict.has_key(id(a)): self._final_crossover_atoms_dict[id(a)] = a #important to sort this to create a unique id. Makes sure that same #crossover pairs are not added to the self.final_crossover_pairs_dict crossoverPairs_id = self._create_crossoverPairs_id(crossoverPairs) if not self.final_crossover_pairs_dict.has_key(crossoverPairs_id): self._final_avg_center_pairs_for_crossovers_dict[ crossoverPairs_id] = (center_1, center_2) self.final_crossover_pairs_dict[crossoverPairs_id] = crossoverPairs return True, distance, crossoverPairs
def _orient(self, chunk, pt1, pt2): """ Orients the Peptide I{chunk} based on two points. I{pt1} is the first endpoint (origin) of the Peptide. The vector I{pt1}, I{pt2} defines the direction and central axis of the Peptide. piotr 080801: I copied this method from Nanotube Builder. @param pt1: The starting endpoint (origin) of the Peptide. @type pt1: L{V} @param pt2: The second point of a vector defining the direction and central axis of the Peptide. @type pt2: L{V} """ a = V(0.0, 0.0, -1.0) # <a> is the unit vector pointing down the center axis of the default # structure which is aligned along the Z axis. bLine = pt2 - pt1 bLength = vlen(bLine) if bLength == 0: return b = bLine / bLength # <b> is the unit vector parallel to the line (i.e. pt1, pt2). axis = cross(a, b) # <axis> is the axis of rotation. theta = angleBetween(a, b) # <theta> is the angle (in degress) to rotate about <axis>. scalar = bLength * 0.5 rawOffset = b * scalar if theta == 0.0 or theta == 180.0: axis = V(0, 1, 0) # print "Now cross(a,b) =", axis rot = (pi / 180.0) * theta # Convert to radians qrot = Q(axis, rot) # Quat for rotation delta. # Move and rotate the Peptide into final orientation. chunk.move(-chunk.center) chunk.rot(qrot) # Bruce suggested I add this. It works here, but not if its # before move() and rot() above. Mark 2008-04-11 chunk.full_inval_and_update() return
def _are_crossover_atompairs(self, atomPair1, atomPair2, orthogonal_vector): """ """ atm1, neighbor1 = atomPair1 center_1 = (atm1.posn() + neighbor1.posn())/2.0 atm2, neighbor2 = atomPair2 center_2 = (atm2.posn() + neighbor2.posn())/2.0 distance = vlen(center_1 - center_2) if distance > MAX_DISTANCE_BETWEEN_CROSSOVER_SITES: return False, distance, () #@NOTE: In self._filter_neighbor_atompairs() where we create the #atompairlists, we make sure that the atoms are ordered in +ve bond_direction #Below, we just check the relative direction of atoms. #@@@@@METHOD TO BE WRITTEN FURTHER centerVec = center_1 - center_2 if self.graphicsMode.DEBUG_DRAW_AVERAGE_CENTER_PAIRS_OF_POTENTIAL_CROSSOVERS: self._DEBUG_avg_center_pairs_of_potential_crossovers.append((center_1, center_2)) theta = angleBetween(orthogonal_vector, centerVec) if dot(centerVec, orthogonal_vector) < 1: theta = 180.0 - theta if abs(theta) > MAX_ANGLE_BET_PLANE_NORMAL_AND_AVG_CENTER_VECTOR_OF_CROSSOVER_PAIRS: return False, distance, () crossoverPairs = (atm1, neighbor1, atm2, neighbor2) for a in crossoverPairs: if not self._final_crossover_atoms_dict.has_key(id(a)): self._final_crossover_atoms_dict[id(a)] = a #important to sort this to create a unique id. Makes sure that same #crossover pairs are not added to the self.final_crossover_pairs_dict crossoverPairs_id = self._create_crossoverPairs_id(crossoverPairs) if not self.final_crossover_pairs_dict.has_key(crossoverPairs_id): self._final_avg_center_pairs_for_crossovers_dict[crossoverPairs_id] = (center_1, center_2) self.final_crossover_pairs_dict[crossoverPairs_id] = crossoverPairs return True, distance, crossoverPairs
def get_angle_made_with_screen_right(self, vec): """ Returns the angle (in degrees) between screen right direction and the given vector. It returns positive angles (between 0 and 180 degrees) if the vector lies in first or second quadrants (i.e. points more up than down on the screen). Otherwise the angle returned is negative. """ #Ninad 2008-04-17: This method was added AFTER rattlesnake rc2. #bruce 080912 bugfix: don't give theta the wrong sign when # dot(vec, self.up) < 0 and dot(vec, self.right) == 0. vec = norm(vec) theta = angleBetween(vec, self.right) if dot(vec, self.up) < 0: theta = - theta return theta
def get_angle_made_with_screen_right(self, vec): """ Returns the angle (in degrees) between screen right direction and the given vector. It returns positive angles (between 0 and 180 degrees) if the vector lies in first or second quadrants (i.e. points more up than down on the screen). Otherwise the angle returned is negative. """ #Ninad 2008-04-17: This method was added AFTER rattlesnake rc2. #bruce 080912 bugfix: don't give theta the wrong sign when # dot(vec, self.up) < 0 and dot(vec, self.right) == 0. vec = norm(vec) theta = angleBetween(vec, self.right) if dot(vec, self.up) < 0: theta = -theta return theta
def updateControlPoints_EXPERIMENTAL(self, hdl, hdl_NewPt): """ Experimental stuff in this method. Not used anywhere. Ignore """ movedHandle = hdl handle_NewPt = hdl_NewPt if len(self.handles) > 1: self.controlPoints = [] if movedHandle in self.handles[1:-1]: for h in self.handles: self.controlPoints.append(h.center) else: offsetVector = handle_NewPt - movedHandle.center movedHandle.center = handle_NewPt for h in self.handles[1:-1]: vect = movedHandle.center - h.center theta = angleBetween( vect, offsetVector) theta = theta*pi/180.0 offsetVecForHandle = offsetVector / cos(theta) ##offsetVecForHandle = offsetVector* len(vect)/len(offsetVector) h.center += offsetVecForHandle for h in self.handles: self.controlPoints.append(h.center) if 0: oldCenter = V(0.0, 0.0, 0.0) for h in self.handles: oldCenter += h.center oldCenter /= len(self.handles) movedHandle.center = handle_NewPt newCenter = V(0.0, 0.0, 0.0) for h in self.handles: newCenter += h.center newCenter /= len(self.handles) for h in self.handles: if h in self.handles[1:-1]: h.center += newCenter - oldCenter self.controlPoints.append(h.center)