Package Pmv :: Module NucleicBases
[hide private]
[frames] | no frames]

Source Code for Module Pmv.NucleicBases

  1  # This module handles drawing of Nucleic Bases DNA and RNA 
  2  # Author: Sargis Dallakyan (sargis at scripps.edu) 
  3  # $Header: /opt/cvs/python/packages/share1.5/Pmv/NucleicBases.py,v 1.10 2007/05/31 19:56:55 sargis Exp $ 
  4  # $Date: 2007/05/31 19:56:55 $ 
  5  # $Id: NucleicBases.py,v 1.10 2007/05/31 19:56:55 sargis Exp $ 
  6  from DejaVu.IndexedPolygons import IndexedPolygons 
  7  from mglutil.math import crossProduct,norm 
  8  import Numeric, math 
  9  from copy import copy 
 10  from opengltk.OpenGL import GL,GLU 
 11   
12 -class Pyrimidine_old(IndexedPolygons):
13 """Used for drawing pyrimidines: Thymine Uracil Cytosine"""
14 - def __init__(self, name=None, color = (0,0,1), **kw):
15 self.vertices = [] 16 vertex = [-0.3,0, 0 ] #N1 - stating point 17 self.vertices.append(vertex) 18 vertex = [-1.16211294, 0.75792228, 0] #C2 19 self.vertices.append(vertex) 20 vertex = [-0.99117465, 2.13082724, 0] #N3 21 self.vertices.append(vertex) 22 vertex = [0,2.8, 0] #C4 23 self.vertices.append(vertex) 24 vertex = [ 1.37266396, 1.93267237,0] #C5 25 self.vertices.append(vertex) 26 vertex = [ 1.23479297, 0.59071168,0] #C6 27 self.vertices.append(vertex) 28 vertex = [0.3, 0, 0 ] #N1 - ending point 29 self.vertices.append(vertex) 30 31 #z + 0.3 part 32 vertex = [-0.3,0, 0.6 ] #N1 - stating point 33 self.vertices.append(vertex) 34 vertex = [-1.16211294, 0.75792228, 0.6] #C2 35 self.vertices.append(vertex) 36 vertex = [-0.99117465, 2.13082724, 0.6] #N3 37 self.vertices.append(vertex) 38 vertex = [0,2.8, 0.6] #C4 39 self.vertices.append(vertex) 40 vertex = [ 1.37266396, 1.93267237,0.6] #C5 41 self.vertices.append(vertex) 42 vertex = [ 1.23479297, 0.59071168,0.6] #C6 43 self.vertices.append(vertex) 44 vertex = [0.3, 0, 0.6 ] #N1 - ending point 45 self.vertices.append(vertex) 46 self.faces=[[0,1,5,6],[1,2,4,5],[1,2,3,4],[7,13,12,8],[8,12,11,9], 47 [8,11,10,9], [2,1,8,9], 48 [0,6,13,7],[1,0,7,8],[3,2,9,10],[4,3,10,11],[5,4,11,12], 49 [6,5,12,13]] 50 kw['vertices'] = self.vertices 51 kw['faces'] = self.faces 52 kw['shading'] = GL.GL_FLAT 53 kw['materials'] = (color,color,color,color,color,color,color, 54 color,color,color,color,color,color,color) 55 kw['inheritMaterial'] = False 56 apply( IndexedPolygons.__init__, (self, name, 0), kw )
57
58 -def make_purine(residue, height = 0.4, scale = 1.2):
59 """Creates vertices and normals for purines: Adenine Guanine""" 60 atoms = residue.atoms 61 N9 = Numeric.array(atoms.objectsFromString('N9')[0].coords) 62 C8 = Numeric.array(atoms.objectsFromString('C8')[0].coords) 63 N7 = Numeric.array(atoms.objectsFromString('N7')[0].coords) 64 C5 = Numeric.array(atoms.objectsFromString('C5')[0].coords) 65 C4 = Numeric.array(atoms.objectsFromString('C4')[0].coords) 66 C6 = Numeric.array(atoms.objectsFromString('C6')[0].coords) 67 N1 = Numeric.array(atoms.objectsFromString('N1')[0].coords) 68 C2 = Numeric.array(atoms.objectsFromString('C2')[0].coords) 69 N3 = Numeric.array(atoms.objectsFromString('N3')[0].coords) 70 N9_C8 = C8-N9 71 N9_C4 = C4-N9 72 C8_C4 = height*norm(C4-C8) 73 normal = height*Numeric.array(crossProduct(N9_C8, N9_C4, normal=True)) 74 #center1 = (N9+C8+N7+C4+C5)/5.0 75 #center2 = (C4+C5+C6+N1+C2+N3)/6.0 76 center2 = (C4+C5+C6+N1+C2+N3+N9+C8+N7)/9.0 77 center1 = center2 78 vertices = Numeric.zeros((20,3),Numeric.Float) 79 80 vertices[0] = scale*(C8 - normal - center1) + center1 81 vertices[1] = scale*(N7 - normal - center1) + center1 82 vertices[2] = scale*(C5 - normal - center2) + center2 83 vertices[3] = scale*(C4 - normal - center2) + center2 84 vertices[4] = scale*(C6 - normal - center2) + center2 85 vertices[5] = scale*(N1 - normal - center2) + center2 86 vertices[6] = scale*(C2 - normal - center2) + center2 87 vertices[7] = scale*(N3 - normal - center2) + center2 88 89 vertices[8] = scale*(C8 + normal - center1) + center1 90 vertices[9] = scale*(N7 + normal - center1) + center1 91 vertices[10] = scale*(C5 + normal - center2) + center2 92 vertices[11] = scale*(C4 + normal - center2) + center2 93 vertices[12] = scale*(C6 + normal - center2) + center2 94 vertices[13] = scale*(N1 + normal - center2) + center2 95 vertices[14] = scale*(C2 + normal - center2) + center2 96 vertices[15] = scale*(N3 + normal - center2) + center2 97 98 vertices[16] = scale*(N9 - C8_C4 - normal - center1) + center1 99 vertices[17] = scale*(N9 - C8_C4 + normal - center1) + center1 100 vertices[18] = scale*(N9 + C8_C4 + normal - center1) + center1 101 vertices[19] = scale*(N9 + C8_C4 - normal - center1) + center1 102 103 104 faces = Numeric.array([[19,3,2,1,0,16,16], 105 [17,8,9,10,11,18,18], 106 [3,7,6,5,4,2,2], 107 [10,12,13,14,15,11,11], 108 [16,0,8,17,17,17,17], [0,1,9,8,8,8,8], [1,2,10,9,9,9,9], 109 [2,4,12,10,10,10,10], 110 [4,5,13,12,12,12,12], [5,6,14,13,13,13,13], 111 [6,7,15,14,14,14,14], 112 [7,3,11,15,15,15,15], 113 [3,19,18,11,11,11,11] ]) 114 return vertices,faces
115
116 -def make_pyrimidine(residue, height = 0.4, scale = 1.2):
117 """Creates vertices and normals for pyrimidines:Thymine Uracil Cytosine""" 118 atoms = residue.atoms 119 N1 = Numeric.array(atoms.objectsFromString('N1')[0].coords) 120 C2 = Numeric.array(atoms.objectsFromString('C2')[0].coords) 121 N3 = Numeric.array(atoms.objectsFromString('N3')[0].coords) 122 C4 = Numeric.array(atoms.objectsFromString('C4')[0].coords) 123 C5 = Numeric.array(atoms.objectsFromString('C5')[0].coords) 124 C6 = Numeric.array(atoms.objectsFromString('C6')[0].coords) 125 N1_C2 = C2-N1 126 N1_C6 = C6-N1 127 C2_C6 = height*norm(C6-C2) 128 normal = height*Numeric.array(crossProduct(N1_C2, N1_C6, normal=True)) 129 center = (N1+C2+N3+C4+C5+C6)/6.0 130 vertices = Numeric.zeros((14,3),Numeric.Float) 131 vertices[0] = scale*(C2 - normal - center) + center 132 vertices[1] = scale*(N3 - normal - center) + center 133 vertices[2] = scale*(C4 - normal - center) + center 134 vertices[3] = scale*(C5 - normal - center) + center 135 vertices[4] = scale*(C6 - normal - center) + center 136 137 vertices[5] = scale*(C2 + normal - center) + center 138 vertices[6] = scale*(N3 + normal - center) + center 139 vertices[7] = scale*(C4 + normal - center) + center 140 vertices[8] = scale*(C5 + normal - center) + center 141 vertices[9] = scale*(C6 + normal - center) + center 142 vertices[10] = scale*(N1 - C2_C6 - normal - center) + center 143 vertices[11] = scale*(N1 - C2_C6 + normal - center) + center 144 vertices[12] = scale*(N1 + C2_C6 + normal - center) + center 145 vertices[13] = scale*(N1 + C2_C6 - normal - center) + center 146 147 faces = Numeric.array([[13,4,3,2,1,0,10], 148 [11,5,6,7,8,9,12], 149 [0,5,11,10,10,10,10], [1,6,5,0,0,0,0,], [2,7,6,1,1,1,1], 150 [3,8,7,2,2,2,2], [4,9,8,3,3,3,3], [13,12,9,4,4,4,4]]) 151 return vertices, faces
152
153 -def Add_Nucleic_Bases(g, properties = None):
154 """ 155 Adds Nucleic Bases to g. 156 g is a geometry created in Pmv.secondaryStructureCommands 157 properties is class that holds information about Nucleic Acids colors and size 158 """ 159 path3D = g.SS.exElt.path3D 160 residues = g.SS.residues 161 total_res = len(residues) 162 vertex_count = 0 163 vertices = [] 164 res_faces = [] 165 materials = [] 166 height_purine = height_pyrimidine = 0.4 167 168 if properties: 169 color_A = properties.color_A 170 color_G = properties.color_G 171 color_T = properties.color_T 172 color_C = properties.color_C 173 color_U = properties.color_U 174 scale_purine = properties.scale_purine 175 scale_pyrimidine = properties.scale_pyrimidine 176 height_purine = properties.height_purine 177 height_pyrimidine = properties.height_pyrimidine 178 179 else: 180 color_A = [1,0,0] 181 color_G = [0,0,1] 182 color_T = [0,1,0] 183 color_C = [1,1,0] 184 color_U = [1,0.5,0] 185 scale_purine = scale_pyrimidine = 1.3 186 height_purine = height_pyrimidine = 0.4 187 for i in range(total_res): 188 faces = [] 189 NA_type = residues[i].type.strip() 190 l_c = g.SS.exElt.getExtrudeProperties([residues[i]], 'colors', ) 191 if NA_type in ['A', 'G']: 192 base_vertices, base_faces = make_purine(residues[i], 193 height_purine, scale_purine) 194 pscale = scale_purine 195 if NA_type == 'A': 196 #28 = number of vertices for the base 20 + 8 197 materials.extend(28*[color_A]) 198 residues[i]._coil_colors = len(l_c)*[color_A] 199 elif NA_type == 'G': 200 materials.extend(28*[color_G]) 201 residues[i]._coil_colors = len(l_c)*[color_G] 202 connetct_to_base = Numeric.array(residues[i].atoms. 203 objectsFromString('N9')[0].coords) 204 else: 205 base_vertices, base_faces = make_pyrimidine(residues[i], 206 height_pyrimidine, scale_pyrimidine) 207 pscale = 0.9*scale_pyrimidine 208 if NA_type == 'T': 209 #22 = number of vertices for the base 14 + 8 210 materials.extend(22*[color_T]) 211 residues[i]._coil_colors = len(l_c)*[color_T] 212 elif NA_type == 'C': 213 materials.extend(22*[color_C]) 214 residues[i]._coil_colors = len(l_c)*[color_C] 215 elif NA_type == 'U': 216 materials.extend(22*[color_U]) 217 residues[i]._coil_colors = len(l_c)*[color_U] 218 connetct_to_base = Numeric.array(residues[i].atoms. 219 objectsFromString('N1')[0].coords) 220 vertices.extend(base_vertices.tolist()) 221 222 223 # v5 *-----------*v1 224 # /| /| 225 # / | / | 226 # / | / | 227 # v6*-----------*v2 | 228 # path-----|-- | | --|--->connetct_to_base 229 # | *-------|---*v0 230 # | /v4 | / 231 # | / | / 232 # |/ |/ 233 # *-----------* 234 # v7 v3 235 236 237 O4 = Numeric.array(residues[i].atoms.objectsFromString('O4\*')[0].coords) 238 C4 = Numeric.array(residues[i].atoms.objectsFromString('C4\*')[0].coords) 239 C1 = Numeric.array(residues[i].atoms.objectsFromString('C1\*')[0].coords) 240 C3 = Numeric.array(residues[i].atoms.objectsFromString('C3\*')[0].coords) 241 C2 = Numeric.array(residues[i].atoms.objectsFromString('C2\*')[0].coords) 242 243 #cent is a vector towards which bases are extruded 244 cent = C4 #this was a center of the sugar ring 245 246 #copy is needed were, otherwise base_vertices will get changed too 247 v_4 = copy(base_vertices[-4]); v_5 = copy(base_vertices[-3]) 248 v_6 = copy(base_vertices[-2]); v_7 = copy(base_vertices[-1]) 249 250 dist = (v_5+v_4+v_6+v_7)/4.0 - cent 251 if i == total_res - 1: 252 pathPoint = path3D[4*i] 253 else: 254 pathPoint = path3D[4*i+1] 255 256 #here we measure distance between backbone and last 4 vertices of bases 257 d_v = v_4 - pathPoint 258 distToV_4 = Numeric.innerproduct(d_v,d_v) 259 d_v = v_5 - pathPoint 260 distToV_5 = Numeric.innerproduct(d_v,d_v) 261 d_v = v_6 - pathPoint 262 distToV_6 = Numeric.innerproduct(d_v,d_v) 263 d_v = v_7 - pathPoint 264 distToV_7 = Numeric.innerproduct(d_v,d_v) 265 266 distList1 = [distToV_4,distToV_5,distToV_6,distToV_7] 267 distList2 = [distToV_4,distToV_5,distToV_6,distToV_7] 268 269 distList1.sort() 270 if pscale > 1: 271 pscale *= pscale 272 273 for enum in enumerate(distList2): 274 if enum[1] == distList1[0]: 275 distList2[enum[0]] = 0.1*pscale 276 elif enum[1] == distList1[1]: 277 distList2[enum[0]] = 0.1*pscale 278 elif enum[1] == distList1[2]: 279 distList2[enum[0]] = 0.5*pscale 280 elif enum[1] == distList1[3]: 281 distList2[enum[0]] = 0.5*pscale 282 283 284 #max_d = max([distToV_4,distToV_5,distToV_6,distToV_7]) 285 #dist needs to be scaled so that connection to the backbone wont be thin 286 287 288 289 v_4 = v_4 - distList2[0]*dist 290 vertices.append(v_4.tolist()) 291 292 v_5 = v_5 - distList2[1]*dist 293 vertices.append(v_5.tolist()) 294 295 v_6 = v_6 - distList2[2]*dist 296 vertices.append(v_6.tolist()) 297 298 v_7 = v_7 - distList2[3]*dist 299 vertices.append(v_7.tolist()) 300 301 p_1 = copy(v_4) 302 p_2 = copy(v_5) 303 p_3 = copy(v_6) 304 p_4 = copy(v_7) 305 dToBase = (p_1+p_2+p_3+p_4)/4. - pathPoint 306 307 p_1 = p_1 - dToBase 308 p_2 = p_2 - dToBase 309 p_3 = p_3 - dToBase 310 p_4 = p_4 - dToBase 311 312 #base_face are number from 0, we need to add vertex_count here 313 314 base_faces += vertex_count 315 faces.extend(base_faces.tolist()) 316 317 #now do the faces 318 len_base_vertices = len(base_vertices) 319 stem_start = vertex_count + len_base_vertices - 4 320 321 faces.append([stem_start + 1, stem_start + 5,stem_start + 4,stem_start, 322 stem_start,stem_start,stem_start]) 323 faces.append([stem_start+1, stem_start+2,stem_start + 6,stem_start + 5, 324 stem_start + 5,stem_start + 5,stem_start + 5]) 325 faces.append([stem_start, stem_start+4, stem_start + 7, stem_start + 3, 326 stem_start + 3,stem_start + 3,stem_start + 3]) 327 faces.append([stem_start+2, stem_start+3,stem_start + 7,stem_start + 6, 328 stem_start + 6,stem_start + 6,stem_start + 6]) 329 faces.append([stem_start+7, stem_start+4,stem_start + 5,stem_start + 6, 330 stem_start + 6,stem_start + 6,stem_start + 6]) 331 332 vertices.append(p_1.tolist()) 333 vertices.append(p_2.tolist()) 334 vertices.append(p_3.tolist()) 335 vertices.append(p_4.tolist()) 336 337 stem_start += 4 338 339 faces.append([stem_start + 1, stem_start + 5,stem_start + 4,stem_start, 340 stem_start,stem_start,stem_start]) 341 faces.append([stem_start+1, stem_start+2,stem_start + 6,stem_start + 5, 342 stem_start + 5,stem_start + 5,stem_start + 5]) 343 faces.append([stem_start, stem_start+4, stem_start + 7, stem_start + 3, 344 stem_start + 3,stem_start + 3,stem_start + 3]) 345 faces.append([stem_start+2, stem_start+3,stem_start + 7,stem_start + 6, 346 stem_start + 6,stem_start + 6,stem_start + 6]) 347 faces.append([stem_start+7, stem_start+4,stem_start + 5,stem_start + 6, 348 stem_start + 6,stem_start + 6,stem_start + 6]) 349 350 # #1-2-6-5 351 # faces.append([stem_start + 7, stem_start + 8,stem_start + 12,stem_start+11, 352 # stem_start+11,stem_start+11,stem_start+11]) 353 # #1-4-8-5 354 # faces.append([stem_start+7, stem_start+10,stem_start + 14,stem_start + 11, 355 # stem_start + 11,stem_start + 11,stem_start + 11]) 356 # #3-4-8-7 357 # faces.append([stem_start+9, stem_start+10, stem_start + 14, stem_start + 13, 358 # stem_start + 13,stem_start + 13,stem_start + 13]) 359 # #2-3-7-6 360 # faces.append([stem_start+8, stem_start+9,stem_start + 13,stem_start + 12, 361 # stem_start + 12,stem_start + 12,stem_start + 12]) 362 363 vertex_count = vertex_count + len_base_vertices + 8 364 residues[i]._base_faces = faces 365 366 faces = [] 367 for residue in residues: 368 faces.extend(residue._base_faces) 369 370 geom_bases = IndexedPolygons('Bases', vertices=vertices, faces=faces, 371 inheritShading = False,shading = GL.GL_FLAT, 372 materials = materials, inheritMaterial = False,) 373 # if self.vf.userpref['sharpColorBoundariesForMsms']['value'] == 'blur': 374 # geom_bases.Set(inheritSharpColorBoundaries=False, sharpColorBoundaries=False,) 375 376 return geom_bases
377 378 if __name__ == '__main__': 379 from DejaVu import Viewer 380 vi = Viewer() 381 from DejaVu import NucleicBases 382 b = NucleicBases.Pyrimidine_old('b') 383 vi.AddObject(b) 384 while(1): 385 vi.update() 386