1
2
3
4
5 """Utility classes for loading, manipulating, and analyzing TLS parameters.
6 """
7 import re
8 import fpformat
9 import math
10
11 try:
12 import numpy
13 try:
14 from numpy.oldnumeric import linear_algebra as linalg
15 except ImportError:
16 from numpy.linalg import old as linalg
17 except ImportError:
18 import NumericCompat as numpy
19 from NumericCompat import linalg
20
21 import Constants
22 import ConsoleOutput
23 import AtomMath
24 import PDB
25 import Structure
26 import Viewer
27 import Gaussian
28 import Colors
29
30
31
32
33
35 """Base exception class for TLS module exceptions.
36 """
37 pass
38
39
40
41
42
48
49
51 """Description of one TLS Group.
52 """
54 self.name = ""
55 self.origin = None
56 self.range_list = []
57 self.T = None
58 self.L = None
59 self.S = None
60
62 """Sets the TLS group name.
63 """
64 self.name = name
65
67 """Sets the TLS group origin of calculations.
68 """
69 self.origin = numpy.array((x, y, z), float)
70
71 - def add_range(self, chain_id1, frag_id1, chain_id2, frag_id2, selection):
72 """Adds a segment of residues to the TLS group. Not too sure how to
73 handle segments which span chains, so assert on that condition.
74 """
75
76
77 self.range_list.append((chain_id1, frag_id1, chain_id2, frag_id2, selection))
78
79 - def set_T(self, t11, t22, t33, t12, t13, t23):
80 """Sets the T tensor from the component arguments. Units are in
81 square Angstroms.
82 """
83 self.T = numpy.array( [[t11, t12, t13],
84 [t12, t22, t23],
85 [t13, t23, t33]], float)
86
87 - def set_L(self, l11, l22, l33, l12, l13, l23):
88 """Sets the L tensor from the component arguments. Units are in
89 square Radians.
90 """
91 self.L = numpy.array( [[l11, l12, l13],
92 [l12, l22, l23],
93 [l13, l23, l33]], float)
94
95 - def set_L_deg2(self, l11, l22, l33, l12, l13, l23):
101
102 - def set_S(self, s2211, s1133, s12, s13, s23, s21, s31, s32):
103 """Sets the S tensor from the component arguments. Units are in
104 Radians*Angstroms. The trace of S is set to 0.0.
105 """
106 s22 = 2.0*(s2211)/3.0 + s1133/3.0
107 s11 = s22 - s2211
108 s33 = s11 - s1133
109
110 self.S = numpy.array([[s11, s12, s13],
111 [s21, s22, s23],
112 [s31, s32, s33]])
113
114 - def set_S_deg(self, s2211, s1133, s12, s13, s23, s21, s31, s32):
121
123 """Sets the TLSGroupDesc tensor values from the TLSGroup instance.
124 """
125 self.set_origin(
126 tls_group.origin[0],
127 tls_group.origin[1],
128 tls_group.origin[2])
129
130 self.set_T(
131 tls_group.T[0,0],
132 tls_group.T[1,1],
133 tls_group.T[2,2],
134 tls_group.T[0,1],
135 tls_group.T[0,2],
136 tls_group.T[1,2])
137
138 self.set_L(
139 tls_group.L[0,0],
140 tls_group.L[1,1],
141 tls_group.L[2,2],
142 tls_group.L[0,1],
143 tls_group.L[0,2],
144 tls_group.L[1,2])
145
146 self.set_S(
147 tls_group.S[1,1] - tls_group.S[0,0],
148 tls_group.S[0,0] - tls_group.S[2,2],
149 tls_group.S[0,1],
150 tls_group.S[0,2],
151 tls_group.S[1,2],
152 tls_group.S[1,0],
153 tls_group.S[2,0],
154 tls_group.S[2,1])
155
157 """Returns True if the T,L,S tensors are not set, or are set
158 with values of zero.
159 """
160 if self.T is None or self.L is None or self.S is None:
161 return True
162 return False
163
165 """Creates a name for the TLS group using the selected residue ranges.
166 """
167 listx = []
168 for (chain_id1, frag_id1, chain_id2, frag_id2, sel) in self.range_list:
169 listx.append("%s%s-%s%s %s" % (chain_id1, frag_id1, chain_id2, frag_id2, sel))
170 return ";".join(listx)
171
173 """Uses the TLS definition and the given Structure object to iterate
174 over all atoms which should be included in the TLS group according
175 to the range_list definitions.
176 """
177 for (chain_id1, frag_id1, chain_id2, frag_id2, sel) in self.range_list:
178
179
180
181 chain1 = struct.get_chain(chain_id1)
182 if chain1 is None:
183 ConsoleOutput.warning("iter_tls_atoms(): no chain id=%s" % (chain_id1))
184 continue
185
186 try:
187 seg = chain1[frag_id1:frag_id2]
188 except KeyError:
189 ConsoleOutput.warning(
190 "iter_tls_atoms():unable to find segment={%s..%s}" % (frag_id1, frag_id2))
191
192 for atm in seg.iter_all_atoms():
193 yield atm
194
196 """Creates a TLSGroup() object with the origin, T, L, and S tensors
197 set according to the TLS description.
198 """
199 tls_group = TLSGroup()
200
201 if self.name == "":
202 tls_group.name = self.calc_tls_name()
203 else:
204 tls_group.name = self.name
205
206 if self.origin is not None:
207 tls_group.set_origin(self.origin[0], self.origin[1], self.origin[2])
208
209 if self.T is not None:
210 tls_group.set_T(self.T[0,0], self.T[1,1], self.T[2,2],
211 self.T[0,1], self.T[0,2], self.T[1,2])
212
213 if self.L is not None:
214 tls_group.set_L(self.L[0,0], self.L[1,1], self.L[2,2],
215 self.L[0,1], self.L[0,2], self.L[1,2])
216
217 if self.S is not None:
218
219 tls_group.set_S(
220 self.S[1,1] - self.S[0,0],
221 self.S[0,0] - self.S[2,2],
222 self.S[0,1],
223 self.S[0,2],
224 self.S[1,2],
225 self.S[1,0],
226 self.S[2,0],
227 self.S[2,1])
228
229 return tls_group
230
232 """Creates a TLSGroup() object with the origin, T, L, and S tensors
233 set according to the TLS description, then add the Atoms to the
234 TLSGroup from the given argument Structure.
235 """
236 tls_group = self.construct_tls_group()
237
238 for atm in self.iter_atoms(struct):
239 tls_group.append(atm)
240
241 return tls_group
242
243
245 """Read/Write TLS files containing one or more TLSGroupDesc objects.
246 """
248 self.path = None
249 self.tls_desc_list = []
250 self.file_format = None
251
257
258 - def load(self, fil, path=None):
259 """Load TLS description file using the current TLSFileFormat instance.
260 """
261 assert self.file_format is not None
262 self.path = path
263 self.tls_desc_list = self.file_format.load(fil)
264
265 - def save(self, fil, path=None):
266 """Save TLS description file using the curent TLSFileFormat instance.
267 """
268 assert self.file_format is not None
269 self.path = path
270 self.file_format.save(fil, self.tls_desc_list)
271
273 """Returns a list of TLSGroup instances constructed from the
274 TLSGroupDesc instances contained in this class.
275 """
276 tls_group_list = []
277
278 for tls_desc in self.tls_desc_list:
279 tls_group = tls_desc.construct_tls_group(struct)
280 if tls_group is not None:
281 tls_group_list.append(tls_group)
282
283 return tls_group_list
284
286 """Returns a list of TLSGroup instances constructed from the Structure
287 instance argument and the TLSGroupDesc instances contained in this
288 class.
289 """
290 tls_group_list = []
291
292 for tls_desc in self.tls_desc_list:
293 tls_group = tls_desc.construct_tls_group_with_atoms(struct)
294 if tls_group is not None:
295 tls_group_list.append(tls_group)
296
297 return tls_group_list
298
299
323
324
626
627
807
808
918
919
920
921
1062
1063
1064
1065
1066
1067
1216
1217
1218
1219
1220
1221
1222
1224 """Solve an overdetermined TLS system by singular value decomposition.
1225 """
1226
1227 U, W, Vt = linalg.singular_value_decomposition(A, full_matrices=0)
1228
1229 V = numpy.transpose(Vt)
1230 Ut = numpy.transpose(U)
1231
1232
1233 cutoff = max(W) * 1E-10
1234
1235
1236 dim_W = len(W)
1237 Wi = numpy.zeros((dim_W, dim_W), float)
1238
1239 for i in range(dim_W):
1240 if W[i]>cutoff:
1241 Wi[i,i] = 1.0 / W[i]
1242 else:
1243
1244 Wi[i,i] = 0.0
1245
1246
1247 Utb = numpy.dot(Ut, b)
1248 WUtb = numpy.dot(Wi, Utb)
1249 x = numpy.dot(V, WUtb)
1250
1251 return x
1252
1254 """Calculate RMSD from a given MSD.
1255 """
1256 if msd < 0.0:
1257 return 0.0
1258 return math.sqrt(msd)
1259
1260
1261
1262
1263
1265 """Sets the six rows of vector b with the experimental/target anisotropic
1266 ADP values U starting at index b[i] and ending at b[i+6] with weight w.
1267 """
1268 b[i] = w * Uiso
1269
1271 """Sets the one row of matrix A starting at A[i,j] with the isotropic
1272 TLS model coefficients for an atom located at t position x, y, z with
1273 least-squares weight w. Matrix A is filled to coumn j+12.
1274 """
1275
1276 T, L11, L22, L33, L12, L13, L23, S1, S2, S3 = (
1277 j,1+j,2+j,3+j,4+j,5+j,6+j,7+j,8+j,9+j)
1278
1279
1280 UISO = i
1281
1282
1283 xx = x*x
1284 yy = y*y
1285 zz = z*z
1286
1287 xy = x*y
1288 xz = x*z
1289 yz = y*z
1290
1291 A[UISO, T] = w * 1.0
1292
1293 A[UISO, L11] = w * ((zz + yy) / 3.0)
1294 A[UISO, L22] = w * ((xx + zz) / 3.0)
1295 A[UISO, L33] = w * ((xx + yy) / 3.0)
1296
1297 A[UISO, L12] = w * ((-2.0 * xy) / 3.0)
1298 A[UISO, L13] = w * ((-2.0 * xz) / 3.0)
1299 A[UISO, L23] = w * ((-2.0 * yz) / 3.0)
1300
1301 A[UISO, S1] = w * (( 2.0 * z) / 3.0)
1302 A[UISO, S2] = w * (( 2.0 * y) / 3.0)
1303 A[UISO, S3] = w * (( 2.0 * x) / 3.0)
1304
1306 """Calculate the TLS predicted uiso from the isotropic TLS model for the
1307 atom at position.
1308 """
1309 x, y, z = position
1310
1311 xx = x*x
1312 yy = y*y
1313 zz = z*z
1314
1315
1316 u_tls = T + (
1317 L[0,0]*(zz+yy) + L[1,1]*(xx+zz) + L[2,2]*(xx+yy)
1318 - 2.0*L[0,1]*x*y - 2.0*L[0,2]*x*z - 2.0*L[1,2]*y*z
1319 + 2.0*S[0]*z + 2.0*S[1]*y + 2.0*S[2]*x) / 3.0
1320 return u_tls
1321
1323 """Iterates the pair (atom, u_iso)
1324 """
1325 for atm in atom_iter:
1326 yield atm, calc_itls_uiso(T, L, S, atm.position - O)
1327
1329 """iT is a single float; iL[3,3]; iS[3]
1330 """
1331
1332 T0 = numpy.array([[iT, 0.0, 0.0],
1333 [0.0, iT, 0.0],
1334 [0.0, 0.0, iT]], float)
1335
1336 L0 = iL.copy()
1337
1338 S0 = numpy.array([ [ 0.0, 0.0, iS[1]],
1339 [iS[0], 0.0, 0.0],
1340 [ 0.0, iS[2], 0.0] ], float)
1341
1342
1343
1344 LSMALL = 0.5 * Constants.DEG2RAD2
1345
1346 rdict = {}
1347
1348 rdict["T'"] = T0.copy()
1349 rdict["L'"] = L0.copy()
1350 rdict["S'"] = S0.copy()
1351
1352 rdict["rT'"] = T0.copy()
1353
1354 rdict["L1_eigen_val"] = 0.0
1355 rdict["L2_eigen_val"] = 0.0
1356 rdict["L3_eigen_val"] = 0.0
1357
1358 rdict["L1_rmsd"] = 0.0
1359 rdict["L2_rmsd"] = 0.0
1360 rdict["L3_rmsd"] = 0.0
1361
1362 rdict["L1_eigen_vec"] = numpy.zeros(3, float)
1363 rdict["L2_eigen_vec"] = numpy.zeros(3, float)
1364 rdict["L3_eigen_vec"] = numpy.zeros(3, float)
1365
1366 rdict["RHO"] = numpy.zeros(3, float)
1367 rdict["COR"] = origin
1368
1369 rdict["L1_rho"] = numpy.zeros(3, float)
1370 rdict["L2_rho"] = numpy.zeros(3, float)
1371 rdict["L3_rho"] = numpy.zeros(3, float)
1372
1373 rdict["L1_pitch"] = 0.0
1374 rdict["L2_pitch"] = 0.0
1375 rdict["L3_pitch"] = 0.0
1376
1377 rdict["Tr1_eigen_val"] = 0.0
1378 rdict["Tr2_eigen_val"] = 0.0
1379 rdict["Tr3_eigen_val"] = 0.0
1380
1381 rdict["Tr1_rmsd"] = 0.0
1382 rdict["Tr2_rmsd"] = 0.0
1383 rdict["Tr3_rmsd"] = 0.0
1384
1385
1386 (L_evals, RL) = linalg.eigenvectors(L0)
1387 L1, L2, L3 = L_evals
1388
1389 good_L_eigens = []
1390
1391 if numpy.allclose(L1, 0.0) or isinstance(L1, complex):
1392 L1 = 0.0
1393 else:
1394 good_L_eigens.append(0)
1395
1396 if numpy.allclose(L2, 0.0) or isinstance(L2, complex):
1397 L2 = 0.0
1398 else:
1399 good_L_eigens.append(1)
1400
1401 if numpy.allclose(L3, 0.0) or isinstance(L3, complex):
1402 L3 = 0.0
1403 else:
1404 good_L_eigens.append(2)
1405
1406
1407 if len(good_L_eigens) == 0:
1408 Tr1, Tr2, Tr3 = linalg.eigenvalues(T0)
1409
1410 if numpy.allclose(Tr1, 0.0) or isinstance(Tr1, complex):
1411 Tr1 = 0.0
1412 if numpy.allclose(Tr2, 0.0) or isinstance(Tr2, complex):
1413 Tr2 = 0.0
1414 if numpy.allclose(Tr3, 0.0) or isinstance(Tr3, complex):
1415 Tr3 = 0.0
1416
1417 rdict["Tr1_eigen_val"] = Tr1
1418 rdict["Tr2_eigen_val"] = Tr2
1419 rdict["Tr3_eigen_val"] = Tr3
1420
1421 rdict["Tr1_rmsd"] = calc_rmsd(Tr1)
1422 rdict["Tr2_rmsd"] = calc_rmsd(Tr2)
1423 rdict["Tr3_rmsd"] = calc_rmsd(Tr3)
1424 return rdict
1425
1426
1427 elif len(good_L_eigens) == 1:
1428 i = good_L_eigens[0]
1429 evec = RL[i]
1430
1431 RZt = numpy.transpose(AtomMath.rmatrixz(evec))
1432 xevec = numpy.dot(RZt, numpy.array([1.0, 0.0, 0.0], float))
1433 yevec = numpy.dot(RZt, numpy.array([0.0, 1.0, 0.0], float))
1434
1435 if i == 0:
1436 RL[1] = xevec
1437 RL[2] = yevec
1438 elif i == 1:
1439 RL[0] = xevec
1440 RL[2] = yevec
1441 elif i == 2:
1442 RL[0] = xevec
1443 RL[1] = yevec
1444
1445
1446 elif len(good_L_eigens) == 2:
1447 i = good_L_eigens[0]
1448 j = good_L_eigens[1]
1449
1450 xevec = AtomMath.normalize(numpy.cross(RL[i], RL[j]))
1451 for k in range(3):
1452 if k == i: continue
1453 if k == j: continue
1454 RL[k] = xevec
1455 break
1456
1457 rdict["L1_eigen_val"] = L1
1458 rdict["L2_eigen_val"] = L2
1459 rdict["L3_eigen_val"] = L3
1460
1461 rdict["L1_rmsd"] = calc_rmsd(L1)
1462 rdict["L2_rmsd"] = calc_rmsd(L2)
1463 rdict["L3_rmsd"] = calc_rmsd(L3)
1464
1465 rdict["L1_eigen_vec"] = RL[0].copy()
1466 rdict["L2_eigen_vec"] = RL[1].copy()
1467 rdict["L3_eigen_vec"] = RL[2].copy()
1468
1469
1470
1471
1472 if numpy.allclose(linalg.determinant(RL), -1.0):
1473 I = numpy.identity(3, float)
1474 I[0,0] = -1.0
1475 RL = numpy.dot(I, RL)
1476
1477 if not numpy.allclose(linalg.determinant(RL), 1.0):
1478 return rdict
1479
1480 RLt = numpy.transpose(RL)
1481
1482
1483 cL = numpy.dot(numpy.dot(RL, L0), RLt)
1484
1485
1486 cT = numpy.dot(numpy.dot(RL, T0), RLt)
1487
1488
1489 cS = numpy.dot(numpy.dot(RL, S0), RLt)
1490
1491
1492 L23 = L2 + L3
1493 L13 = L1 + L3
1494 L12 = L1 + L2
1495
1496
1497 if not numpy.allclose(L1, 0.0) and abs(L23)>LSMALL:
1498 crho1 = (cS[1,2] - cS[2,1]) / L23
1499 else:
1500 crho1 = 0.0
1501
1502 if not numpy.allclose(L2, 0.0) and abs(L13)>LSMALL:
1503 crho2 = (cS[2,0] - cS[0,2]) / L13
1504 else:
1505 crho2 = 0.0
1506
1507 if not numpy.allclose(L3, 0.0) and abs(L12)>LSMALL:
1508 crho3 = (cS[0,1] - cS[1,0]) / L12
1509 else:
1510 crho3 = 0.0
1511
1512 crho = numpy.array([crho1, crho2, crho3], float)
1513
1514
1515 rho = numpy.dot(RLt, crho)
1516 rdict["RHO"] = rho
1517 rdict["COR"] = origin + rho
1518
1519
1520 PRHO = numpy.array([ [ 0.0, rho[2], -rho[1]],
1521 [-rho[2], 0.0, rho[0]],
1522 [ rho[1], -rho[0], 0.0] ], float)
1523
1524
1525 cPRHO = numpy.array([ [ 0.0, crho[2], -crho[1]],
1526 [-crho[2], 0.0, crho[0]],
1527 [ crho[1], -crho[0], 0.0] ], float)
1528
1529
1530 cSt = numpy.transpose(cS)
1531 cPRHOt = numpy.transpose(cPRHO)
1532
1533
1534 cSp = cS + numpy.dot(cL, cPRHOt)
1535
1536
1537 cTp = cT + numpy.dot(cPRHO, cS) + numpy.dot(cSt, cPRHOt) + \
1538 numpy.dot(numpy.dot(cPRHO, cL), cPRHOt)
1539
1540
1541 PRHOt = numpy.transpose(PRHO)
1542 St = numpy.transpose(S0)
1543
1544
1545 Sp = S0 + numpy.dot(L0, PRHOt)
1546 rdict["S'"] = Sp
1547
1548
1549 Tp = T0 + numpy.dot(PRHO, S0) + numpy.dot(St, PRHOt) + \
1550 numpy.dot(numpy.dot(PRHO, L0), PRHOt)
1551 rdict["T'"] = Tp
1552
1553
1554
1555
1556
1557
1558 cL1rho = numpy.zeros(3, float)
1559 cL2rho = numpy.zeros(3, float)
1560 cL3rho = numpy.zeros(3, float)
1561
1562
1563 rdict["L1_rho"] = numpy.dot(RLt, cL1rho)
1564 rdict["L2_rho"] = numpy.dot(RLt, cL2rho)
1565 rdict["L3_rho"] = numpy.dot(RLt, cL3rho)
1566
1567
1568
1569 rdict["L1_pitch"] = 0.0
1570 rdict["L2_pitch"] = 0.0
1571 rdict["L3_pitch"] = 0.0
1572
1573
1574
1575
1576 Tiso = numpy.trace(Tp) / 3.0
1577 rdict["rT'"] = Tiso * numpy.identity(3, float)
1578
1579 rdict["Tr1_eigen_val"] = Tiso
1580 rdict["Tr2_eigen_val"] = Tiso
1581 rdict["Tr3_eigen_val"] = Tiso
1582
1583 rdict["Tr1_rmsd"] = calc_rmsd(Tiso)
1584 rdict["Tr2_rmsd"] = calc_rmsd(Tiso)
1585 rdict["Tr3_rmsd"] = calc_rmsd(Tiso)
1586
1587 return rdict
1588
1589
1590
1591
1592
1594 """Calculates s11, s22, s33 based on s22-s11 and s11-s33 using
1595 the constraint s11+s22+s33=0
1596 """
1597 s22 = 2.0*(s2211)/3.0 + s1133/3.0
1598 s11 = s22 - s2211
1599 s33 = s11 - s1133
1600 return s11, s22, s33
1601
1603 """Returns the calculated value for the anisotropic U tensor for
1604 the given position.
1605 """
1606 x, y, z = position
1607
1608 xx = x*x
1609 yy = y*y
1610 zz = z*z
1611
1612 xy = x*y
1613 yz = y*z
1614 xz = x*z
1615
1616 u11 = T[0,0] + L[1,1]*zz + L[2,2]*yy - 2.0*L[1,2]*yz + 2.0*S[1,0]*z - 2.0*S[2,0]*y
1617 u22 = T[1,1] + L[0,0]*zz + L[2,2]*xx - 2.0*L[2,0]*xz - 2.0*S[0,1]*z + 2.0*S[2,1]*x
1618 u33 = T[2,2] + L[0,0]*yy + L[1,1]*xx - 2.0*L[0,1]*xy - 2.0*S[1,2]*x + 2.0*S[0,2]*y
1619 u12 = T[0,1] - L[2,2]*xy + L[1,2]*xz + L[2,0]*yz - L[0,1]*zz - S[0,0]*z + S[1,1]*z + S[2,0]*x - S[2,1]*y
1620 u13 = T[0,2] - L[1,1]*xz + L[1,2]*xy - L[2,0]*yy + L[0,1]*yz + S[0,0]*y - S[2,2]*y + S[1,2]*z - S[1,0]*x
1621 u23 = T[1,2] - L[0,0]*yz - L[1,2]*xx + L[2,0]*xy + L[0,1]*xz - S[1,1]*x + S[2,2]*x + S[0,1]*y - S[0,2]*z
1622
1623 return numpy.array([[u11, u12, u13],
1624 [u12, u22, u23],
1625 [u13, u23, u33]], float)
1626
1628 """Returns the amount of rotational displacement from L for an atom at the
1629 given position.
1630 """
1631 Lrot = Gaussian.GAUSS3C[prob] * calc_rmsd(Lval)
1632 Lorigin = cor + Lrho
1633 D = AtomMath.dmatrixu(Lvec, Lrot)
1634
1635 drot = numpy.dot(D, position - Lorigin)
1636 dscw = (Lrot * Lpitch) * Lvec
1637
1638 return drot + dscw
1639
1641 """Sets the six rows of matrix A starting at A[i,j] with the TLS
1642 coefficients for an atom located at position x,y,z with least-squares
1643 weight w. Matrix A is filled to row i+6 and column j+20.
1644 """
1645
1646 T11, T22, T33, T12, T13, T23, L11, L22, L33, L12, L13, L23, \
1647 S1133, S2211, S12, S13, S23, S21, S31, S32 = (
1648 j,1+j,2+j,3+j,4+j,5+j,6+j,7+j,8+j,9+j,10+j,11+j,12+j,13+j,14+j,15+j,
1649 16+j,17+j,18+j,19+j)
1650
1651
1652 U11 = i
1653 U22 = U11 + 1
1654 U33 = U11 + 2
1655 U12 = U11 + 3
1656 U13 = U11 + 4
1657 U23 = U11 + 5
1658
1659
1660 xx = x*x
1661 yy = y*y
1662 zz = z*z
1663
1664 xy = x*y
1665 xz = x*z
1666 yz = y*z
1667
1668 A[U11, T11] = w * 1.0
1669 A[U11, L22] = w * zz
1670 A[U11, L33] = w * yy
1671 A[U11, L23] = w * -2.0 * yz
1672 A[U11, S31] = w * -2.0 * y
1673 A[U11, S21] = w * 2.0 * z
1674
1675 A[U22, T22] = w * 1.0
1676 A[U22, L11] = w * zz
1677 A[U22, L33] = w * xx
1678 A[U22, L13] = w * -2.0 * xz
1679 A[U22, S12] = w * -2.0 * z
1680 A[U22, S32] = w * 2.0 * x
1681
1682 A[U33, T33] = w * 1.0
1683 A[U33, L11] = w * yy
1684 A[U33, L22] = w * xx
1685 A[U33, L12] = w * -2.0 * xy
1686 A[U33, S23] = w * -2.0 * x
1687 A[U33, S13] = w * 2.0 * y
1688
1689 A[U12, T12] = w * 1.0
1690 A[U12, L33] = w * -xy
1691 A[U12, L23] = w * xz
1692 A[U12, L13] = w * yz
1693 A[U12, L12] = w * -zz
1694 A[U12, S2211] = w * z
1695 A[U12, S31] = w * x
1696 A[U12, S32] = w * -y
1697
1698 A[U13, T13] = w * 1.0
1699 A[U13, L22] = w * -xz
1700 A[U13, L23] = w * xy
1701 A[U13, L13] = w * -yy
1702 A[U13, L12] = w * yz
1703 A[U13, S1133] = w * y
1704 A[U13, S23] = w * z
1705 A[U13, S21] = w * -x
1706
1707 A[U23, T23] = w * 1.0
1708 A[U23, L11] = w * -yz
1709 A[U23, L23] = w * -xx
1710 A[U23, L13] = w * xy
1711 A[U23, L12] = w * xz
1712 A[U23, S2211] = w * -x
1713 A[U23, S1133] = w * -x
1714 A[U23, S12] = w * y
1715 A[U23, S13] = w * -z
1716
1717 -def set_TLS_b(b, i, u11, u22, u33, u12, u13, u23, w):
1718 """Sets the six rows of vector b with the experimental/target anisotropic
1719 ADP values U starting at index b[i] and ending at b[i+6] with weight w.
1720 """
1721 b[i] = w * u11
1722 b[i+1] = w * u22
1723 b[i+2] = w * u33
1724 b[i+3] = w * u12
1725 b[i+4] = w * u13
1726 b[i+5] = w * u23
1727
1729 """Perform a LSQ-TLS fit on the given AtomList. The TLS tensors
1730 are calculated at the given origin, with weights of weight_dict[atm].
1731 Return values are T, L, S, lsq_residual.
1732 """
1733
1734 num_atoms = len(atom_list)
1735 params = 20
1736
1737 A = numpy.zeros((num_atoms * 6, params), float)
1738 B = numpy.zeros(num_atoms * 6, float)
1739
1740 i = -1
1741 for atm in atom_list:
1742 i += 1
1743 iU11 = i * 6
1744
1745
1746 if weight_dict is not None:
1747 w = math.sqrt(weight_dict[atm])
1748 else:
1749 w = 1.0
1750
1751
1752 U = atm.get_U()
1753 set_TLS_b(B, iU11, U[0,0], U[1,1], U[2,2], U[0,1], U[0,2], U[1,2], w)
1754
1755
1756 x, y, z = atm.position - origin
1757 set_TLS_A(A, iU11, 0, x, y, z, w)
1758
1759
1760 X = solve_TLS_Ab(A, B)
1761
1762
1763 T11, T22, T33, T12, T13, T23, L11, L22, L33, L12, L13, L23, \
1764 S1133, S2211, S12, S13, S23, S21, S31, S32 = (
1765 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19)
1766
1767 T = numpy.array([ [ X[T11], X[T12], X[T13] ],
1768 [ X[T12], X[T22], X[T23] ],
1769 [ X[T13], X[T23], X[T33] ] ], float)
1770
1771 L = numpy.array([ [ X[L11], X[L12], X[L13] ],
1772 [ X[L12], X[L22], X[L23] ],
1773 [ X[L13], X[L23], X[L33] ] ], float)
1774
1775 s11, s22, s33 = calc_s11_s22_s33(X[S2211], X[S1133])
1776
1777 S = numpy.array([ [ s11, X[S12], X[S13] ],
1778 [ X[S21], s22, X[S23] ],
1779 [ X[S31], X[S32], s33 ] ], float)
1780
1781
1782 UTLS = numpy.dot(A, X)
1783 D = UTLS - B
1784 lsq_residual = numpy.dot(D, D)
1785
1786 return T, L, S, lsq_residual
1787
1789 """Calculate new tensors based on the center for reaction.
1790 This method returns a dictionary of the calculations:
1791
1792 T^: T tensor in the coordinate system of L
1793 L^: L tensor in the coordinate system of L
1794 S^: S tensor in the coordinate system of L
1795
1796 COR: Center of Reaction
1797
1798 T',S',L': T,L,S tensors in original coordinate system
1799 with the origin shifted to the center of reaction.
1800 """
1801
1802 LSMALL = 0.5 * Constants.DEG2RAD2
1803
1804 rdict = {}
1805
1806 rdict["T'"] = T0.copy()
1807 rdict["L'"] = L0.copy()
1808 rdict["S'"] = S0.copy()
1809
1810 rdict["rT'"] = T0.copy()
1811
1812 rdict["L1_eigen_val"] = 0.0
1813 rdict["L2_eigen_val"] = 0.0
1814 rdict["L3_eigen_val"] = 0.0
1815
1816 rdict["L1_rmsd"] = 0.0
1817 rdict["L2_rmsd"] = 0.0
1818 rdict["L3_rmsd"] = 0.0
1819
1820 rdict["L1_eigen_vec"] = numpy.zeros(3, float)
1821 rdict["L2_eigen_vec"] = numpy.zeros(3, float)
1822 rdict["L3_eigen_vec"] = numpy.zeros(3, float)
1823
1824 rdict["RHO"] = numpy.zeros(3, float)
1825 rdict["COR"] = origin
1826
1827 rdict["L1_rho"] = numpy.zeros(3, float)
1828 rdict["L2_rho"] = numpy.zeros(3, float)
1829 rdict["L3_rho"] = numpy.zeros(3, float)
1830
1831 rdict["L1_pitch"] = 0.0
1832 rdict["L2_pitch"] = 0.0
1833 rdict["L3_pitch"] = 0.0
1834
1835 rdict["Tr1_eigen_val"] = 0.0
1836 rdict["Tr2_eigen_val"] = 0.0
1837 rdict["Tr3_eigen_val"] = 0.0
1838
1839 rdict["Tr1_rmsd"] = 0.0
1840 rdict["Tr2_rmsd"] = 0.0
1841 rdict["Tr3_rmsd"] = 0.0
1842
1843
1844 (L_evals, RL) = linalg.eigenvectors(L0)
1845 L1, L2, L3 = L_evals
1846
1847 good_L_eigens = []
1848
1849 if numpy.allclose(L1, 0.0) or isinstance(L1, complex):
1850 L1 = 0.0
1851 else:
1852 good_L_eigens.append(0)
1853
1854 if numpy.allclose(L2, 0.0) or isinstance(L2, complex):
1855 L2 = 0.0
1856 else:
1857 good_L_eigens.append(1)
1858
1859 if numpy.allclose(L3, 0.0) or isinstance(L3, complex):
1860 L3 = 0.0
1861 else:
1862 good_L_eigens.append(2)
1863
1864
1865 if len(good_L_eigens) == 0:
1866 return rdict
1867
1868
1869 elif len(good_L_eigens) == 1:
1870 i = good_L_eigens[0]
1871 evec = RL[i]
1872
1873 RZt = numpy.transpose(AtomMath.rmatrixz(evec))
1874 xevec = numpy.dot(RZt, numpy.array([1.0, 0.0, 0.0], float))
1875 yevec = numpy.dot(RZt, numpy.array([0.0, 1.0, 0.0], float))
1876
1877 if i == 0:
1878 RL[1] = xevec
1879 RL[2] = yevec
1880 elif i == 1:
1881 RL[0] = xevec
1882 RL[2] = yevec
1883 elif i == 2:
1884 RL[0] = xevec
1885 RL[1] = yevec
1886
1887
1888 elif len(good_L_eigens) == 2:
1889 i = good_L_eigens[0]
1890 j = good_L_eigens[1]
1891
1892 xevec = AtomMath.normalize(numpy.cross(RL[i], RL[j]))
1893 for k in range(3):
1894 if k == i: continue
1895 if k == j: continue
1896 RL[k] = xevec
1897 break
1898
1899 rdict["L1_eigen_val"] = L1
1900 rdict["L2_eigen_val"] = L2
1901 rdict["L3_eigen_val"] = L3
1902
1903 rdict["L1_rmsd"] = calc_rmsd(L1)
1904 rdict["L2_rmsd"] = calc_rmsd(L2)
1905 rdict["L3_rmsd"] = calc_rmsd(L3)
1906
1907 rdict["L1_eigen_vec"] = RL[0].copy()
1908 rdict["L2_eigen_vec"] = RL[1].copy()
1909 rdict["L3_eigen_vec"] = RL[2].copy()
1910
1911
1912
1913
1914 if numpy.allclose(linalg.determinant(RL), -1.0):
1915 I = numpy.identity(3, float)
1916 I[0,0] = -1.0
1917 RL = numpy.dot(I, RL)
1918
1919 if not numpy.allclose(linalg.determinant(RL), 1.0):
1920 return rdict
1921
1922 RLt = numpy.transpose(RL)
1923
1924
1925 cL = numpy.dot(numpy.dot(RL, L0), RLt)
1926 rdict["L^"] = cL.copy()
1927
1928
1929 cT = numpy.dot(numpy.dot(RL, T0), RLt)
1930 rdict["T^"] = cT.copy()
1931
1932
1933 cS = numpy.dot(numpy.dot(RL, S0), RLt)
1934 rdict["S^"] = cS.copy()
1935
1936
1937 L23 = L2 + L3
1938 L13 = L1 + L3
1939 L12 = L1 + L2
1940
1941
1942 if not numpy.allclose(L1, 0.0) and abs(L23)>LSMALL:
1943 crho1 = (cS[1,2] - cS[2,1]) / L23
1944 else:
1945 crho1 = 0.0
1946
1947 if not numpy.allclose(L2, 0.0) and abs(L13)>LSMALL:
1948 crho2 = (cS[2,0] - cS[0,2]) / L13
1949 else:
1950 crho2 = 0.0
1951
1952 if not numpy.allclose(L3, 0.0) and abs(L12)>LSMALL:
1953 crho3 = (cS[0,1] - cS[1,0]) / L12
1954 else:
1955 crho3 = 0.0
1956
1957 crho = numpy.array([crho1, crho2, crho3], float)
1958 rdict["RHO^"] = crho.copy()
1959
1960
1961 rho = numpy.dot(RLt, crho)
1962 rdict["RHO"] = rho
1963 rdict["COR"] = origin + rho
1964
1965
1966 PRHO = numpy.array([ [ 0.0, rho[2], -rho[1]],
1967 [-rho[2], 0.0, rho[0]],
1968 [ rho[1], -rho[0], 0.0] ], float)
1969
1970
1971 cPRHO = numpy.array([ [ 0.0, crho[2], -crho[1]],
1972 [-crho[2], 0.0, crho[0]],
1973 [ crho[1], -crho[0], 0.0] ], float)
1974
1975
1976 cSt = numpy.transpose(cS)
1977 cPRHOt = numpy.transpose(cPRHO)
1978
1979 rdict["L'^"] = cL.copy()
1980
1981
1982 cSp = cS + numpy.dot(cL, cPRHOt)
1983 rdict["S'^"] = cSp.copy()
1984
1985
1986 cTp = cT + numpy.dot(cPRHO, cS) + numpy.dot(cSt, cPRHOt) +\
1987 numpy.dot(numpy.dot(cPRHO, cL), cPRHOt)
1988 rdict["T'^"] = cTp.copy()
1989
1990
1991 PRHOt = numpy.transpose(PRHO)
1992 St = numpy.transpose(S0)
1993
1994
1995 Sp = S0 + numpy.dot(L0, PRHOt)
1996 rdict["S'"] = Sp
1997
1998
1999 Tp = T0 + numpy.dot(PRHO, S0) + numpy.dot(St, PRHOt) +\
2000 numpy.dot(numpy.dot(PRHO, L0), PRHOt)
2001 rdict["T'"] = Tp
2002
2003
2004
2005
2006
2007 if abs(L1) > LSMALL:
2008 cL1rho = numpy.array([0.0, -cSp[0,2]/L1, cSp[0,1]/L1], float)
2009 else:
2010 cL1rho = numpy.zeros(3, float)
2011
2012
2013 if abs(L2) > LSMALL:
2014 cL2rho = numpy.array([cSp[1,2]/L2, 0.0, -cSp[1,0]/L2], float)
2015 else:
2016 cL2rho = numpy.zeros(3, float)
2017
2018
2019 if abs(L3) > LSMALL:
2020 cL3rho = numpy.array([-cSp[2,1]/L3, cSp[2,0]/L3, 0.0], float)
2021 else:
2022 cL3rho = numpy.zeros(3, float)
2023
2024
2025 rdict["L1_rho"] = numpy.dot(RLt, cL1rho)
2026 rdict["L2_rho"] = numpy.dot(RLt, cL2rho)
2027 rdict["L3_rho"] = numpy.dot(RLt, cL3rho)
2028
2029
2030 if abs(L1) > LSMALL:
2031 rdict["L1_pitch"] = cS[0,0]/L1
2032 else:
2033 rdict["L1_pitch"] = 0.0
2034
2035 if L2 > LSMALL:
2036 rdict["L2_pitch"] = cS[1,1]/L2
2037 else:
2038 rdict["L2_pitch"] = 0.0
2039
2040 if L3 > LSMALL:
2041 rdict["L3_pitch"] = cS[2,2]/L3
2042 else:
2043 rdict["L3_pitch"] = 0.0
2044
2045
2046 cTred = cT.copy()
2047
2048 for i in (0, 1, 2):
2049 for k in (0, 1, 2):
2050 if i == k:
2051 continue
2052 if abs(cL[k,k]) > LSMALL:
2053 cTred[i,i] -= (cS[k,i]**2) / cL[k,k]
2054
2055 for i in (0, 1, 2):
2056 for j in (0, 1, 2):
2057 for k in (0, 1, 2):
2058 if j == i:
2059 continue
2060 if abs(cL[k,k]) > LSMALL:
2061 cTred[i,j] -= (cS[k,i]*cS[k,j]) / cL[k,k]
2062
2063
2064
2065
2066 Tr = numpy.dot(numpy.dot(RLt, cTred), RL)
2067 rdict["rT'"] = Tr
2068
2069 Tr1, Tr2, Tr3 = linalg.eigenvalues(Tr)
2070
2071 if numpy.allclose(Tr1, 0.0) or isinstance(Tr1, complex):
2072 Tr1 = 0.0
2073 if numpy.allclose(Tr2, 0.0) or isinstance(Tr2, complex):
2074 Tr2 = 0.0
2075 if numpy.allclose(Tr3, 0.0) or isinstance(Tr3, complex):
2076 Tr3 = 0.0
2077
2078 rdict["Tr1_eigen_val"] = Tr1
2079 rdict["Tr2_eigen_val"] = Tr2
2080 rdict["Tr3_eigen_val"] = Tr3
2081
2082 rdict["Tr1_rmsd"] = calc_rmsd(Tr1)
2083 rdict["Tr2_rmsd"] = calc_rmsd(Tr2)
2084 rdict["Tr3_rmsd"] = calc_rmsd(Tr3)
2085
2086 return rdict
2087
2088
2089
2090
2091
2093 """Perform a LSQ-TLS fit on the given Segment object using
2094 the TLS model with amino acid side chains which can pivot
2095 about the CA atom. This model uses 20 TLS parameters and 6
2096 libration parameters per side chain.
2097 """
2098
2099 num_atoms = len(atom_list)
2100 params = 20 + num_atoms
2101
2102 A = numpy.zeros((num_atoms * 6, params), float)
2103 B = numpy.zeros(num_atoms * 6, float)
2104
2105 i = -1
2106 for atm in atom_list:
2107 i += 1
2108 iU11 = i * 6
2109
2110 if weight_dict is None:
2111 w = 1.0
2112 else:
2113 w = math.sqrt(weight_dict[atm])
2114
2115
2116 U = atm.get_U()
2117 assert numpy.trace(U) > 0.0
2118 set_TLS_b(B, iU11, U[0,0], U[1,1], U[2,2], U[0,1], U[0,2], U[1,2], w)
2119
2120
2121 x, y, z = atm.position - origin
2122 set_TLS_A(A, iU11, 0, x, y, z, w)
2123
2124
2125 A[iU11, 20+i] = 1.0
2126 A[iU11+1, 20+i] = 1.0
2127 A[iU11+2, 20+i] = 1.0
2128
2129
2130 X = solve_TLS_Ab(A, B)
2131
2132
2133 T11, T22, T33, T12, T13, T23, L11, L22, L33, L12, L13, L23, \
2134 S1133, S2211, S12, S13, S23, S21, S31, S32 = (
2135 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19)
2136
2137 T = numpy.array([ [ X[T11], X[T12], X[T13] ],
2138 [ X[T12], X[T22], X[T23] ],
2139 [ X[T13], X[T23], X[T33] ] ], float)
2140
2141 L = numpy.array([ [ X[L11], X[L12], X[L13] ],
2142 [ X[L12], X[L22], X[L23] ],
2143 [ X[L13], X[L23], X[L33] ] ], float)
2144
2145 s11, s22, s33 = calc_s11_s22_s33(X[S2211], X[S1133])
2146
2147 S = numpy.array([ [ s11, X[S12], X[S13] ],
2148 [ X[S21], s22, X[S23] ],
2149 [ X[S31], X[S32], s33 ] ], float)
2150
2151
2152 UTLS = numpy.dot(A, X)
2153 D = UTLS - B
2154 lsq_residual = numpy.dot(D, D)
2155
2156 rdict = {}
2157 rdict["T"] = T
2158 rdict["L"] = L
2159 rdict["S"] = S
2160 rdict["lsq_residual"] = lsq_residual
2161
2162 uiso_residual = {}
2163 i = 19
2164 for atm in atom_list:
2165 i += 1
2166 uiso_residual[atm] = X[i]
2167 rdict["uiso_residual"] = uiso_residual
2168
2169 return rdict
2170
2171
2172
2173
2174
2175 CA_PIVOT_ATOMS = {
2176 "GLY": None,
2177 "ALA": None,
2178 "VAL": "CA",
2179 "LEU": "CA",
2180 "ILE": "CA",
2181 "PRO": None,
2182 "PHE": "CA",
2183 "TYR": "CA",
2184 "TRP": "CA",
2185 "MET": "CA",
2186 "CYS": "CA",
2187 "SER": "CA",
2188 "THR": "CA",
2189 "ASP": "CA",
2190 "GLU": "CA",
2191 "HIS": "CA",
2192 "LYS": "CA",
2193 "ARG": "CA",
2194 "ASN": "CA",
2195 "GLN": "CA" }
2196
2198 """Sets coefficients of a L tensor in matrix A for an atom at position
2199 x,y,z and weight w. This starts at A[i,j] and ends at A[i+6,j+6]
2200 Using weight w.
2201 """
2202 L11, L22, L33, L12, L13, L23 = (j, j+1, j+2, j+3, j+4, j+5)
2203
2204
2205 U11 = i
2206 U22 = U11 + 1
2207 U33 = U11 + 2
2208 U12 = U11 + 3
2209 U13 = U11 + 4
2210 U23 = U11 + 5
2211
2212
2213 xx = x * x
2214 yy = y * y
2215 zz = z * z
2216
2217 xy = x * y
2218 xz = x * z
2219 yz = y * z
2220
2221 A[U11, L22] = w * zz
2222 A[U11, L33] = w * yy
2223 A[U11, L23] = w * -2.0 * yz
2224
2225 A[U22, L11] = w * zz
2226 A[U22, L33] = w * xx
2227 A[U22, L13] = w * -2.0 * xz
2228
2229 A[U33, L11] = w * yy
2230 A[U33, L22] = w * xx
2231 A[U33, L12] = w * -2.0 * xy
2232
2233 A[U12, L33] = w * -xy
2234 A[U12, L23] = w * xz
2235 A[U12, L13] = w * yz
2236 A[U12, L12] = w * -zz
2237
2238 A[U13, L22] = w * -xz
2239 A[U13, L23] = w * xy
2240 A[U13, L13] = w * -yy
2241 A[U13, L12] = w * yz
2242
2243 A[U23, L11] = w * -yz
2244 A[U23, L23] = w * -xx
2245 A[U23, L13] = w * xy
2246 A[U23, L12] = w * xz
2247
2249 """Perform a LSQ-TLS fit on the given Segment object using the TLS model
2250 with amino acid side chains which can pivot about the CA atom. This model
2251 uses 20 TLS parameters and 6 libration parameters per side chain.
2252 """
2253
2254 num_atoms = segment.count_atoms()
2255
2256
2257 num_pivot_frags = 0
2258 i = 20
2259 iL11p = {}
2260 for frag in segment.iter_fragments():
2261 if CA_PIVOT_ATOMS.get(frag.res_name) is not None:
2262 num_pivot_frags += 1
2263 iL11p[frag] = i
2264 i += 6
2265
2266 params = (6 * num_pivot_frags) + 20
2267
2268 A = numpy.zeros((num_atoms * 6, params), float)
2269 B = numpy.zeros(num_atoms * 6, float)
2270
2271 i = -1
2272 for atm in segment.iter_atoms():
2273 i += 1
2274 iU11 = i * 6
2275
2276
2277 U = atm.get_U()
2278 set_TLS_b(B, iU11,
2279 U[0,0], U[1,1], U[2,2], U[0,1], U[0,2], U[1,2],
2280 1.0)
2281
2282
2283 x, y, z = atm.position - origin
2284 set_TLS_A(A, iU11, 0, x, y, z, 1.0)
2285
2286
2287 frag = atm.get_fragment()
2288
2289 assert frag.is_amino_acid()
2290
2291 if frag.is_amino_acid():
2292 if atm.name in ["N", "CA", "C", "O"]:
2293 continue
2294
2295
2296 patom_name = CA_PIVOT_ATOMS.get(frag.res_name)
2297 if patom_name is not None:
2298 patm = frag.get_atom(patom_name)
2299 assert patm is not None
2300
2301 iL11 = iL11p[frag]
2302 xs, ys, zs = atm.position - patm.position
2303 set_L_A(A, iU11, iL11, xs, ys, zs, 1.0)
2304
2305
2306 X = solve_TLS_Ab(A, B)
2307
2308
2309 UTLS = numpy.dot(A, X)
2310 D = UTLS - B
2311 lsq_residual = numpy.dot(D, D)
2312
2313
2314
2315
2316 T11, T22, T33, T12, T13, T23, L11, L22, L33, L12, L13, L23, \
2317 S1133, S2211, S12, S13, S23, S21, S31, S32 = (
2318 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19)
2319
2320 T = numpy.array([ [ X[T11], X[T12], X[T13] ],
2321 [ X[T12], X[T22], X[T23] ],
2322 [ X[T13], X[T23], X[T33] ] ], float)
2323
2324 L = numpy.array([ [ X[L11], X[L12], X[L13] ],
2325 [ X[L12], X[L22], X[L23] ],
2326 [ X[L13], X[L23], X[L33] ] ], float)
2327
2328 s11, s22, s33 = calc_s11_s22_s33(X[S2211], X[S1133])
2329
2330 S = numpy.array([ [ s11, X[S12], X[S13] ],
2331 [ X[S21], s22, X[S23] ],
2332 [ X[S31], X[S32], s33 ] ], float)
2333
2334
2335 frag_L_dict = {}
2336 for frag in segment.iter_fragments():
2337 if not iL11p.has_key(frag):
2338 print "NO PIVOT: %s" % (frag)
2339 continue
2340
2341 iL11 = iL11p[frag]
2342 CA_L = numpy.array([ [ X[iL11], X[iL11+3], X[iL11+4] ],
2343 [ X[iL11+3], X[iL11+1], X[iL11+5] ],
2344 [ X[iL11+4], X[iL11+5], X[iL11+2] ] ], float)
2345
2346 frag_L_dict[frag] = CA_L
2347 eval = linalg.eigenvalues(CA_L) * Constants.RAD2DEG2
2348
2349 print "%s %s: %6.2f %6.2f %6.2f" % (
2350 frag.fragment_id, frag.res_name, eval[0],eval[1],eval[2])
2351
2352
2353 udict = {}
2354 i = -1
2355 for atm in segment.iter_atoms():
2356 i += 1
2357 iU11 = i * 6
2358
2359 U = numpy.array( ((UTLS[iU11], UTLS[iU11+3], UTLS[iU11+4]),
2360 (UTLS[iU11+3], UTLS[iU11+1], UTLS[iU11+5]),
2361 (UTLS[iU11+4], UTLS[iU11+5], UTLS[iU11+2])), float)
2362
2363 udict[atm] = U
2364
2365
2366 rdict = {}
2367
2368 rdict["T"] = T
2369 rdict["L"] = L
2370 rdict["S"] = S
2371
2372 rdict["lsq_residual"] = lsq_residual
2373
2374 rdict["num_atoms"] = num_atoms
2375 rdict["params"] = params
2376
2377 rdict["udict"] = udict
2378
2379 return rdict
2380
2381
2382
2383
2384
2386 """A subclass of AtomList implementing methods for performing TLS
2387 calculations on the contained Atom instances.
2388 """
2390 Structure.AtomList.__init__(self, *args)
2391
2392 self.name = ""
2393 self.origin = numpy.zeros(3, float)
2394 self.T = numpy.array([[0.0, 0.0, 0.0],
2395 [0.0, 0.0, 0.0],
2396 [0.0, 0.0, 0.0]], float)
2397 self.L = numpy.array([[0.0, 0.0, 0.0],
2398 [0.0, 0.0, 0.0],
2399 [0.0, 0.0, 0.0]], float)
2400 self.S = numpy.array([[0.0, 0.0, 0.0],
2401 [0.0, 0.0, 0.0],
2402 [0.0, 0.0, 0.0]], float)
2403
2405 tstr = "TLS %s\n" % (self.name)
2406
2407 tstr += "ORIGIN %f %f %f\n" % (
2408 self.origin[0], self.origin[1], self.origin[2])
2409
2410 tstr += "T %f %f %f %f %f %f\n" % (
2411 self.T[0,0], self.T[1,1], self.T[2,2], self.T[0,1], self.T[0,2],
2412 self.T[1,2])
2413
2414 tstr += "L %f %f %f %f %f %f\n" % (
2415 self.L[0,0], self.L[1,1], self.L[2,2], self.L[0,1], self.L[0,2],
2416 self.L[1,2])
2417
2418 tstr += "S %f %f %f %f %f %f %f %f\n" % (
2419 self.S[1,1]-self.S[0,0], self.S[0,0]-self.S[2,2], self.S[0,1],
2420 self.S[0,2], self.S[1,2], self.S[1,0], self.S[2,0], self.S[2,1])
2421
2422 return tstr
2423
2425 """Sets the x, y, z components of the TLS origin vector.
2426 """
2427 self.origin = numpy.array([x, y, z])
2428
2429 - def set_T(self, t11, t22, t33, t12, t13, t23):
2430 """Sets the components of the symmetric T tensor. Units in square
2431 Angstroms.
2432 """
2433 self.T = numpy.array([[t11, t12, t13],
2434 [t12, t22, t23],
2435 [t13, t23, t33]], float)
2436
2437 - def set_L(self, l11, l22, l33, l12, l13, l23):
2438 """Sets the components of the symmetric L tensor from arguments.
2439 Units should be in square radians.
2440 """
2441 self.L = numpy.array([[l11, l12, l13],
2442 [l12, l22, l23],
2443 [l13, l23, l33]], float)
2444
2445 - def set_S(self, s2211, s1133, s12, s13, s23, s21, s31, s32):
2446 """Sets the componets of the asymmetric S tenssor. The trace
2447 of the S tensor is set with the standard convention of
2448 the Trace(S) = 0. Units in Radians*Angstroms.
2449 """
2450 s11, s22, s33 = self.calc_s11_s22_s33(s2211, s1133)
2451 self.S = numpy.array([[s11, s12, s13],
2452 [s21, s22, s23],
2453 [s31, s32, s33]], float)
2454
2456 """Calculates s11, s22, s33 based on s22-s11 and s11-s33 using
2457 the constraint s11+s22+s33=0
2458 """
2459 s22 = 2.0*(s2211)/3.0 + s1133/3.0
2460 s11 = s22 - s2211
2461 s33 = s11 - s1133
2462 return s11, s22, s33
2463
2465 """Returns True if the T,L,S tensors are not set, or are set with
2466 values of zero.
2467 """
2468 if numpy.allclose(numpy.trace(self.T), 0.0) or numpy.allclose(numpy.trace(self.L), 0.0):
2469 return True
2470 return False
2471
2473 """Perform a least-squares fit of the atoms contained in self
2474 to the three TLS tensors: self.T, self.L, and self.S using the
2475 origin given by self.origin.
2476 """
2477 T, L, S, lsq_residual = calc_TLS_least_squares_fit(self, self.origin, weight_dict)
2478
2479 self.T = T
2480 self.L = L
2481 self.S = S
2482
2483 return lsq_residual
2484
2486 """Iterates over all the atoms in the TLS object, returning the 2-tuple
2487 (atm, U) where U is the calcuated U value from the current values of
2488 the TLS object's T,L,S, tensors and origin.
2489 """
2490 T = self.T
2491 L = self.L
2492 S = self.S
2493 o = self.origin
2494
2495 for atm in self:
2496 Utls = calc_Utls(T, L, S, atm.position - o)
2497 yield atm, Utls
2498
2500 """Returns the calc_COR() return information for this TLS Group.
2501 """
2502 return calc_TLS_center_of_reaction(self.T, self.L, self.S, self.origin)
2503
2505 """Shift the TLS group to the center of reaction.
2506 """
2507 cor_desc = self.calc_COR()
2508 self.T = cor_desc["T'"].copy()
2509 self.L = cor_desc["L'"].copy()
2510 self.S = cor_desc["S'"].copy()
2511 self.origin = cor_desc["COR"].copy()
2512
2513 return cor_desc
2514
2516 """Calculates a number of statistics about the TLS group tensors,
2517 goodness of fit, various parameter averages, center of reaction
2518 tensors, etc...
2519 """
2520 tls_info = self.calc_COR()
2521
2522
2523
2524
2525 tls_info["num_atoms"] = len(self)
2526
2527
2528 tls_info["exp_mean_temp_factor"] = self.calc_adv_temp_factor()
2529 tls_info["exp_mean_anisotropy"] = self.calc_adv_anisotropy()
2530
2531
2532 n = 0
2533 mean_max_tf = 0.0
2534 mean_tf = 0.0
2535 mean_aniso = 0.0
2536
2537 for atm, Utls in self.iter_atm_Utls():
2538 n += 1
2539
2540 evals = linalg.eigenvalues(Utls)
2541 max_ev = max(evals)
2542 min_ev = min(evals)
2543
2544 mean_max_tf += Constants.U2B * max_ev
2545 mean_tf += Constants.U2B * numpy.trace(Utls) / 3.0
2546 mean_aniso += AtomMath.calc_anisotropy(Utls)
2547
2548 tls_info["tls_mean_max_temp_factor"] = mean_max_tf / n
2549 tls_info["tls_mean_temp_factor"] = mean_tf / n
2550 tls_info["tls_mean_anisotropy"] = mean_aniso / n
2551
2552 return tls_info
2553
2554
2556 """Algorithm object for rigid body searches on Structure objects.
2557 """
2559 self.struct = struct
2560
2562 """This iterator yields a series of Segment objects of width seg_len.
2563 The start at the beginning Fragment of the Chain, and the start point
2564 walks the chain one Fragment at a time until there are not enough
2565 Fragments left to cut Segments of seg_width.
2566 """
2567 chain_len = len(chain)
2568
2569 for i in range(chain_len):
2570 start = i
2571 end = i + seg_len
2572
2573 if end > chain_len:
2574 break
2575
2576 yield chain[start:end]
2577
2579 use_side_chains = args.get("use_side_chains", True)
2580 include_hydrogens = args.get("include_hydrogens", False)
2581 include_frac_occupancy = args.get("include_frac_occupancy", False)
2582 include_single_bond = args.get("include_single_bond", True)
2583
2584
2585 if not include_frac_occupancy and atm.occupancy<1.0:
2586 return False
2587
2588
2589 if not include_hydrogens and atm.element=="H":
2590 return False
2591
2592
2593 if not use_side_chains and atm.name not in ("C", "N", "CA", "O"):
2594 return False
2595
2596
2597 if not include_single_bond and len(atm.bond_list)<=1:
2598 return False
2599
2600 return True
2601
2603 """Run the algorithm to fit TLS parameters to segments of the
2604 structure. This method has many options, which are outlined in
2605 the source code for the method. This returns a list of dictionaries
2606 containing statistics on each of the fit TLS groups, the residues
2607 involved, and the TLS object itself.
2608 """
2609 import copy
2610
2611
2612 chain_ids = args.get("chain_ids", None)
2613 origin = args.get("origin_of_calc")
2614 residue_width = args.get("residue_width", 6)
2615 use_side_chains = args.get("use_side_chains", True)
2616 include_hydrogens = args.get("include_hydrogens", False)
2617 include_frac_occupancy = args.get("include_frac_occupancy", False)
2618 include_single_bond = args.get("include_single_bond", True)
2619 calc_pivot_model = args.get("calc_pivot_model", False)
2620
2621
2622 for chain in self.struct.iter_chains():
2623
2624
2625 if chain_ids is not None and chain.chain_id not in chain_ids:
2626 continue
2627
2628
2629 if chain.count_amino_acids() < residue_width:
2630 continue
2631
2632 for segment in self.iter_segments(chain, residue_width):
2633 frag_id1 = segment[0].fragment_id
2634 frag_id2 = segment[-1].fragment_id
2635 name = "%s-%s" % (frag_id1, frag_id2)
2636 frag_id_cntr = segment[len(segment)/2].fragment_id
2637
2638
2639 pv_struct = Structure.Structure()
2640 pv_seg = Structure.Chain(chain_id=segment.chain_id,
2641 model_id=segment.model_id)
2642 pv_struct.add_chain(pv_seg)
2643
2644 tls_group = TLSGroup()
2645
2646
2647
2648 for atm in segment.iter_atoms():
2649 if self.atom_filter(atm, **args):
2650 tls_group.append(atm)
2651
2652 atm_cp = copy.deepcopy(atm)
2653 pv_seg.add_atom(atm_cp)
2654
2655
2656 if len(tls_group) < 20:
2657 tls_info = {
2658 "name": name,
2659 "chain_id": chain.chain_id,
2660 "frag_id1": frag_id1,
2661 "frag_id2": frag_id2,
2662 "frag_id_cntr": frag_id_cntr,
2663 "num_atoms": len(tls_group),
2664 "error": "Not Enough Atoms"}
2665 yield tls_info
2666 continue
2667
2668 tls_group.origin = tls_group.calc_centroid()
2669 lsq_residual = tls_group.calc_TLS_least_squares_fit()
2670 tls_group.shift_COR()
2671 tls_info = tls_group.calc_tls_info()
2672 tls_info["lsq_residual"] = lsq_residual
2673
2674
2675 if calc_pivot_model == True:
2676 rdict = calc_CB_pivot_TLS_least_squares_fit(pv_seg)
2677 tls_info["ca_pivot"] = rdict
2678
2679
2680 tls_info["name"] = name
2681 tls_info["chain_id"] = chain.chain_id
2682 tls_info["frag_id1"] = frag_id1
2683 tls_info["frag_id2"] = frag_id2
2684 tls_info["frag_id_cntr"] = frag_id_cntr
2685 tls_info["tls_group"] = tls_group
2686 tls_info["residues"] = segment
2687 tls_info["segment"] = segment
2688
2689
2690 yield tls_info
2691
2693 """Returns the list iterated by iter_fit_TLS_segments.
2694 """
2695 tls_info_list = []
2696 for tls_info in self.iter_fit_TLS_segments(**args):
2697 tls_info_list.append(tls_info)
2698 return tls_info_list
2699
2700
2701
2702
2703
2704
2706 """x in range 0.0->1.0
2707 """
2708 if x<=0.0:
2709 return (0.0, 0.0, 0.0)
2710
2711 r = math.sqrt(x)
2712 g = max(0.0, x**3)
2713 b = max(0.0, math.sin(2.0 * math.pi * x))
2714
2715 return (r, g, b)
2716
2718 """OpenGL visualizations of TLS group atoms.
2719 """
2725
2727 Viewer.GLAtomList.glo_install_properties(self)
2728
2729
2730 self.glo_add_property(
2731 { "name": "fan_visible",
2732 "desc": "Show COR-Backbone Fan",
2733 "catagory": "Show/Hide",
2734 "type": "boolean",
2735 "default": False,
2736 "action": "recompile" })
2737
2738 self.glo_add_property(
2739 { "name": "L1_animation_visible",
2740 "desc": "Show L<sub>1</sub> Screw Animation",
2741 "catagory": "Show/Hide",
2742 "type": "boolean",
2743 "default": True,
2744 "action": "redraw" })
2745 self.glo_add_property(
2746 { "name": "L2_animation_visible",
2747 "desc": "Show L<sub>2</sub> Screw Animation",
2748 "catagory": "Show/Hide",
2749 "type": "boolean",
2750 "default": True,
2751 "action": "redraw" })
2752 self.glo_add_property(
2753 { "name": "L3_animation_visible",
2754 "desc": "Show L<sub>3</sub> Screw Animation",
2755 "catagory": "Show/Hide",
2756 "type": "boolean",
2757 "default": True,
2758 "action": "redraw" })
2759
2760
2761 self.glo_add_property(
2762 { "name": "tls_color",
2763 "desc": "TLS Group Color",
2764 "catagory": "TLS",
2765 "type": "enum_string",
2766 "default": "Green",
2767 "enum_list": self.gldl_color_list,
2768 "action": "recompile" })
2769 self.glo_add_property(
2770 { "name": "fan_opacity",
2771 "desc": "COR-Backbone Fan Opacity",
2772 "catagory": "TLS",
2773 "type": "float",
2774 "range": Viewer.PROP_OPACITY_RANGE,
2775 "default": 1.0,
2776 "action": "recompile_fan" })
2777 self.glo_add_property(
2778 { "name": "L1_scale",
2779 "desc": "Scale L<sub>1</sub> Rotation",
2780 "catagory": "TLS",
2781 "type": "float",
2782 "default": 1.0,
2783 "action": "redraw" })
2784 self.glo_add_property(
2785 { "name": "L2_scale",
2786 "desc": "Scale L<sub>2</sub> Rotation",
2787 "catagory": "TLS",
2788 "type": "float",
2789 "default": 1.0,
2790 "action": "redraw" })
2791 self.glo_add_property(
2792 { "name": "L3_scale",
2793 "desc": "Scale L<sub>3</sub> Rotation",
2794 "catagory": "TLS",
2795 "type": "float",
2796 "default": 1.0,
2797 "action": "redraw" })
2798
2799
2800 self.glo_add_property(
2801 { "name": "COR",
2802 "desc": "TLS Center of Reaction",
2803 "catagory": "TLS Analysis",
2804 "read_only": True,
2805 "type": "numpy.array(3)",
2806 "default": numpy.zeros(3, float),
2807 "action": "recompile" })
2808 self.glo_add_property(
2809 { "name": "T",
2810 "desc": "T<sup>COR</sup> Tensor (A<sup>2</sup>)",
2811 "catagory": "TLS Analysis",
2812 "read_only": True,
2813 "type": "numpy.array(3,3)",
2814 "default": numpy.zeros((3,3), float),
2815 "action": "recompile" })
2816 self.glo_add_property(
2817 { "name": "rT",
2818 "desc": "T<sup>r</sup> Tensor (A<sup>2</sup>)",
2819 "catagory": "TLS Analysis",
2820 "read_only": True,
2821 "type": "numpy.array(3,3)",
2822 "default": numpy.zeros((3,3), float),
2823 "action": "recompile" })
2824 self.glo_add_property(
2825 { "name": "L",
2826 "desc": "L<sup>COR</sup> Tensor (DEG<sup>2</sup>)",
2827 "catagory": "TLS Analysis",
2828 "read_only": True,
2829 "type": "numpy.array(3,3)",
2830 "default": numpy.zeros((3,3), float),
2831 "action": "recompile" })
2832 self.glo_add_property(
2833 { "name": "S",
2834 "desc": "S<sup>COR</sup> Tensor (A*DEG)",
2835 "catagory": "TLS Analysis",
2836 "read_only": True,
2837 "type": "numpy.array(3,3)",
2838 "default": numpy.zeros((3,3), float),
2839 "action": "recompile" })
2840 self.glo_add_property(
2841 { "name": "L1_eigen_vec",
2842 "desc": "L<sub>1</sub> Eigen Vector",
2843 "catagory": "TLS Analysis",
2844 "read_only": True,
2845 "type": "numpy.array(3)",
2846 "default": numpy.zeros(3, float),
2847 "action": "recompile" })
2848 self.glo_add_property(
2849 { "name": "L2_eigen_vec",
2850 "desc": "L<sub>2</sub> Eigen Vector",
2851 "catagory": "TLS Analysis",
2852 "read_only": True,
2853 "type": "numpy.array(3)",
2854 "default": numpy.zeros(3, float),
2855 "action": "recompile" })
2856 self.glo_add_property(
2857 { "name": "L3_eigen_vec",
2858 "desc": "L<sub>3</sub> Eigen Vector",
2859 "catagory": "TLS Analysis",
2860 "read_only": True,
2861 "type": "numpy.array(3)",
2862 "default": numpy.zeros(3, float),
2863 "action": "recompile" })
2864 self.glo_add_property(
2865 { "name": "L1_eigen_val",
2866 "desc": "L<sub>1</sub> Eigen Value",
2867 "catagory": "TLS Analysis",
2868 "read_only": True,
2869 "type": "float",
2870 "default": 0.0,
2871 "action": "recompile" })
2872 self.glo_add_property(
2873 { "name": "L2_eigen_val",
2874 "desc": "L<sub>2</sub> Eigen Value",
2875 "catagory": "TLS Analysis",
2876 "read_only": True,
2877 "type": "float",
2878 "default": 0.0,
2879 "action": "recompile" })
2880 self.glo_add_property(
2881 { "name": "L3_eigen_val",
2882 "desc": "L<sub>3</sub> Eigen Value",
2883 "catagory": "TLS Analysis",
2884 "read_only": True,
2885 "type": "float",
2886 "default": 0.0,
2887 "action": "recompile" })
2888 self.glo_add_property(
2889 { "name": "L1_rho",
2890 "desc": "L<sub>1</sub> Position from COR",
2891 "catagory": "TLS Analysis",
2892 "read_only": True,
2893 "type": "numpy.array(3)",
2894 "default": numpy.zeros(3, float),
2895 "action": "recompile" })
2896 self.glo_add_property(
2897 { "name": "L2_rho",
2898 "desc": "L<sub>2</sub> Position from COR",
2899 "catagory": "TLS Analysis",
2900 "read_only": True,
2901 "type": "numpy.array(3)",
2902 "default": numpy.zeros(3, float),
2903 "action": "recompile" })
2904 self.glo_add_property(
2905 { "name": "L3_rho",
2906 "desc": "L<sub>3</sub> Position from COR",
2907 "catagory": "TLS Analysis",
2908 "read_only": True,
2909 "type": "numpy.array(3)",
2910 "default": numpy.zeros(3, float),
2911 "action": "recompile" })
2912 self.glo_add_property(
2913 { "name": "L1_pitch",
2914 "desc": "L<sub>1</sub> Screw Pitch (A/DEG)",
2915 "catagory": "TLS Analysis",
2916 "read_only": True,
2917 "type": "float",
2918 "default": 0.0,
2919 "action": "recompile" })
2920 self.glo_add_property(
2921 { "name": "L2_pitch",
2922 "desc": "L<sub>2</sub> Screw Pitch (A/DEG)",
2923 "catagory": "TLS Analysis",
2924 "read_only": True,
2925 "type": "float",
2926 "default": 0.0,
2927 "action": "recompile" })
2928 self.glo_add_property(
2929 { "name": "L3_pitch",
2930 "desc": "L<sub>3</sub> Screw Pitch (A/DEG)",
2931 "catagory": "TLS Analysis",
2932 "read_only": True,
2933 "type": "float",
2934 "default": 0.0,
2935 "action": "recompile" })
2936
2937
2938 self.glo_add_property(
2939 { "name": "both_phases",
2940 "desc": "Show Simultanius +/- Phases",
2941 "catagory": "TLS",
2942 "type": "boolean",
2943 "default": False,
2944 "action": "recompile" })
2945 self.glo_add_property(
2946 { "name": "L1_rot",
2947 "desc": "L<sub>1</sub> Rotation",
2948 "catagory": "TLS",
2949 "type": "float",
2950 "default": 0.0,
2951 "action": "redraw" })
2952 self.glo_add_property(
2953 { "name": "L2_rot",
2954 "desc": "L<sub>2</sub> Rotation",
2955 "catagory": "TLS",
2956 "type": "float",
2957 "default": 0.0,
2958 "action": "redraw" })
2959 self.glo_add_property(
2960 { "name": "L3_rot",
2961 "desc": "L<sub>3</sub> Rotation",
2962 "catagory": "TLS",
2963 "type": "float",
2964 "default": 0.0,
2965 "action": "redraw" })
2966
2976
2981
2983 """
2984 """
2985
2986
2987 zero_rot = False
2988
2989 if self.properties["both_phases"]==True:
2990 phase_tuple = (1.0, 0.66, 0.33, 0.0, -0.33, -0.66, -1.0)
2991 else:
2992 phase_tuple = (1.0,)
2993
2994 for Lx_axis, Lx_rho, Lx_pitch, Lx_rot, Lx_scale in (
2995 ("L1_eigen_vec", "L1_rho", "L1_pitch", "L1_rot", "L1_scale"),
2996 ("L2_eigen_vec", "L2_rho", "L2_pitch", "L2_rot", "L2_scale"),
2997 ("L3_eigen_vec", "L3_rho", "L3_pitch", "L3_rot", "L3_scale") ):
2998
2999 if Lx_axis=="L1_eigen_vec" and self.properties["L1_animation_visible"]==False:
3000 continue
3001 if Lx_axis=="L2_eigen_vec" and self.properties["L2_animation_visible"]==False:
3002 continue
3003 if Lx_axis=="L3_eigen_vec" and self.properties["L3_animation_visible"]==False:
3004 continue
3005
3006 for sign in phase_tuple:
3007 axis = self.properties[Lx_axis]
3008 rho = self.properties[Lx_rho]
3009 pitch = self.properties[Lx_pitch]
3010
3011 rot = sign * self.properties[Lx_rot] * self.properties[Lx_scale]
3012 screw = axis * (rot * pitch)
3013
3014 if numpy.allclose(rot, 0.0):
3015 if zero_rot:
3016 continue
3017 zero_rot = True
3018
3019 self.driver.glr_push_matrix()
3020
3021 self.driver.glr_translate(rho)
3022 self.driver.glr_rotate_axis(rot, axis)
3023 self.driver.glr_translate(-rho + screw)
3024 yield True
3025
3026 self.driver.glr_pop_matrix()
3027
3029 """
3030 """
3031 for atm in self.tls_group:
3032 yield atm
3033
3035 """Overrides the GLAtomList coloring behavior and just
3036 colors using the tls_color.
3037 """
3038 return self.gldl_property_color_rgbf("tls_color")
3039
3041 r, g, b = self.glal_calc_color(atom)
3042 dim = 0.8
3043 return (r*dim, g*dim, b*dim)
3048
3051
3053 """Always return the reduced T tensor.
3054 """
3055 return self.properties["rT"]
3056
3102
3103
3105 """Top level visualization object for a TLS group.
3106 """
3108 self.tls_group = args["tls_group"]
3109 self.tls_info = args["tls_info"]
3110 self.tls_name = args["tls_name"]
3111
3112 Viewer.GLDrawList.__init__(self)
3113 self.glo_set_properties_id("GLTLSGroup_%s" % (self.tls_name))
3114 self.glo_set_name(self.tls_name)
3115
3116
3117 self.gl_atom_list = GLTLSAtomList(
3118 tls_group = self.tls_group,
3119 trace = True,
3120 lines = False,
3121 fan_visible = False)
3122
3123 self.gl_atom_list.glo_set_name("TLS Atom Animation")
3124 self.gl_atom_list.glo_set_properties_id("gl_atom_list")
3125 self.glo_add_child(self.gl_atom_list)
3126
3127 self.glo_link_child_property(
3128 "symmetry", "gl_atom_list", "symmetry")
3129
3130 self.glo_link_child_property(
3131 "main_chain_visible", "gl_atom_list", "main_chain_visible")
3132 self.glo_link_child_property(
3133 "oatm_visible", "gl_atom_list", "oatm_visible")
3134 self.glo_link_child_property(
3135 "side_chain_visible", "gl_atom_list", "side_chain_visible")
3136 self.glo_link_child_property(
3137 "hetatm_visible", "gl_atom_list", "hetatm_visible")
3138 self.glo_link_child_property(
3139 "water_visible", "gl_atom_list", "water_visible")
3140 self.glo_link_child_property(
3141 "hydrogen_visible", "gl_atom_list", "hydrogen_visible")
3142
3143 self.glo_link_child_property(
3144 "tls_color", "gl_atom_list", "tls_color")
3145
3146 self.glo_link_child_property(
3147 "fan_visible", "gl_atom_list", "fan_visible")
3148 self.glo_link_child_property(
3149 "fan_opacity", "gl_atom_list", "fan_opacity")
3150 self.glo_link_child_property(
3151 "axes_rT", "gl_atom_list", "U")
3152 self.glo_link_child_property(
3153 "ellipse_rT", "gl_atom_list", "ellipse")
3154 self.glo_link_child_property(
3155 "rms_rT", "gl_atom_list", "rms")
3156
3157 self.glo_link_child_property(
3158 "adp_prob", "gl_atom_list", "adp_prob")
3159
3160 self.glo_link_child_property(
3161 "COR", "gl_atom_list", "origin")
3162 self.glo_link_child_property(
3163 "COR", "gl_atom_list", "atom_origin")
3164 self.glo_link_child_property(
3165 "COR", "gl_atom_list", "COR")
3166 self.glo_link_child_property(
3167 "T", "gl_atom_list", "T")
3168 self.glo_link_child_property(
3169 "rT", "gl_atom_list", "rT")
3170 self.glo_link_child_property(
3171 "L", "gl_atom_list", "L")
3172 self.glo_link_child_property(
3173 "S", "gl_atom_list", "S")
3174
3175 self.glo_link_child_property(
3176 "L1_eigen_vec", "gl_atom_list", "L1_eigen_vec")
3177 self.glo_link_child_property(
3178 "L2_eigen_vec", "gl_atom_list", "L2_eigen_vec")
3179 self.glo_link_child_property(
3180 "L3_eigen_vec", "gl_atom_list", "L3_eigen_vec")
3181
3182 self.glo_link_child_property(
3183 "L1_eigen_val", "gl_atom_list", "L1_eigen_val")
3184 self.glo_link_child_property(
3185 "L2_eigen_val", "gl_atom_list", "L2_eigen_val")
3186 self.glo_link_child_property(
3187 "L3_eigen_val", "gl_atom_list", "L3_eigen_val")
3188
3189 self.glo_link_child_property(
3190 "L1_rho", "gl_atom_list", "L1_rho")
3191 self.glo_link_child_property(
3192 "L2_rho", "gl_atom_list", "L2_rho")
3193 self.glo_link_child_property(
3194 "L3_rho", "gl_atom_list", "L3_rho")
3195
3196 self.glo_link_child_property(
3197 "L1_pitch", "gl_atom_list", "L1_pitch")
3198 self.glo_link_child_property(
3199 "L2_pitch", "gl_atom_list", "L2_pitch")
3200 self.glo_link_child_property(
3201 "L3_pitch", "gl_atom_list", "L3_pitch")
3202
3203 self.glo_link_child_property(
3204 "L1_rot", "gl_atom_list", "L1_rot")
3205 self.glo_link_child_property(
3206 "L2_rot", "gl_atom_list", "L2_rot")
3207 self.glo_link_child_property(
3208 "L3_rot", "gl_atom_list", "L3_rot")
3209
3210 self.glo_link_child_property(
3211 "both_phases", "gl_atom_list", "both_phases")
3212
3213
3214 self.glo_add_update_callback(self.tls_update_cb)
3215
3216 if not self.tls_group.is_null():
3217 self.glo_init_properties(
3218 COR = self.tls_info["COR"],
3219
3220 T = self.tls_info["T'"],
3221 rT = self.tls_info["rT'"],
3222 L = self.tls_info["L'"] * Constants.RAD2DEG2,
3223 S = self.tls_info["S'"] * Constants.RAD2DEG,
3224
3225 L1_eigen_vec = self.tls_info["L1_eigen_vec"],
3226 L2_eigen_vec = self.tls_info["L2_eigen_vec"],
3227 L3_eigen_vec = self.tls_info["L3_eigen_vec"],
3228
3229 L1_eigen_val = self.tls_info["L1_eigen_val"] * Constants.RAD2DEG2,
3230 L2_eigen_val = self.tls_info["L2_eigen_val"] * Constants.RAD2DEG2,
3231 L3_eigen_val = self.tls_info["L3_eigen_val"] * Constants.RAD2DEG2,
3232
3233 L1_rho = self.tls_info["L1_rho"],
3234 L2_rho = self.tls_info["L2_rho"],
3235 L3_rho = self.tls_info["L3_rho"],
3236
3237 L1_pitch = self.tls_info["L1_pitch"] * (1.0/Constants.RAD2DEG),
3238 L2_pitch = self.tls_info["L2_pitch"] * (1.0/Constants.RAD2DEG),
3239 L3_pitch = self.tls_info["L3_pitch"] * (1.0/Constants.RAD2DEG),
3240 **args)
3241 else:
3242 self.glo_init_properties(**args)
3243
3245 """Set a new TLSGroup.
3246 """
3247 self.tls_group = tls_group
3248
3249 if not self.tls_group.is_null():
3250 self.tls_info = self.tls_group.calc_tls_info()
3251
3252 self.properties.update(
3253 COR = self.tls_info["COR"],
3254 T = self.tls_info["T'"],
3255 Tr = self.tls_info["rT'"],
3256 L = self.tls_info["L'"] * Constants.RAD2DEG2,
3257 S = self.tls_info["S'"] * Constants.RAD2DEG,
3258
3259 L1_eigen_vec = self.tls_info["L1_eigen_vec"],
3260 L2_eigen_vec = self.tls_info["L2_eigen_vec"],
3261 L3_eigen_vec = self.tls_info["L3_eigen_vec"],
3262
3263 L1_eigen_val = self.tls_info["L1_eigen_val"] * Constants.RAD2DEG2,
3264 L2_eigen_val = self.tls_info["L2_eigen_val"] * Constants.RAD2DEG2,
3265 L3_eigen_val = self.tls_info["L3_eigen_val"] * Constants.RAD2DEG2,
3266
3267 L1_rho = self.tls_info["L1_rho"],
3268 L2_rho = self.tls_info["L2_rho"],
3269 L3_rho = self.tls_info["L3_rho"],
3270
3271 L1_pitch = self.tls_info["L1_pitch"] * (1.0/Constants.RAD2DEG),
3272 L2_pitch = self.tls_info["L2_pitch"] * (1.0/Constants.RAD2DEG),
3273 L3_pitch = self.tls_info["L3_pitch"] * (1.0/Constants.RAD2DEG) )
3274
3275 else:
3276 self.tls_info = None
3277
3278 self.properties.update(
3279 COR = Viewer.GLObject.PropertyDefault,
3280 T = Viewer.GLObject.PropertyDefault,
3281 Tr = Viewer.GLObject.PropertyDefault,
3282 L = Viewer.GLObject.PropertyDefault,
3283 S = Viewer.GLObject.PropertyDefault,
3284
3285 L1_eigen_vec = Viewer.GLObject.PropertyDefault,
3286 L2_eigen_vec = Viewer.GLObject.PropertyDefault,
3287 L3_eigen_vec = Viewer.GLObject.PropertyDefault,
3288
3289 L1_eigen_val = Viewer.GLObject.PropertyDefault,
3290 L2_eigen_val = Viewer.GLObject.PropertyDefault,
3291 L3_eigen_val = Viewer.GLObject.PropertyDefault,
3292
3293 L1_rho = Viewer.GLObject.PropertyDefault,
3294 L2_rho = Viewer.GLObject.PropertyDefault,
3295 L3_rho = Viewer.GLObject.PropertyDefault,
3296
3297 L1_pitch = Viewer.GLObject.PropertyDefault,
3298 L2_pitch = Viewer.GLObject.PropertyDefault,
3299 L3_pitch = Viewer.GLObject.PropertyDefault )
3300
3302 Viewer.GLDrawList.glo_install_properties(self)
3303
3304
3305 self.glo_add_property(
3306 { "name": "COR",
3307 "desc": "TLS Center of Reaction",
3308 "catagory": "TLS Analysis",
3309 "read_only": True,
3310 "type": "numpy.array(3)",
3311 "default": numpy.zeros(3, float),
3312 "action": "recompile" })
3313 self.glo_add_property(
3314 { "name": "COR_vector",
3315 "desc": "TLS Center of Reaction",
3316 "catagory": "TLS Analysis",
3317 "read_only": True,
3318 "type": "numpy.array(3)",
3319 "default": numpy.zeros(3, float),
3320 "action": "recompile" })
3321 self.glo_add_property(
3322 { "name": "T",
3323 "desc": "T<sup>COR</sup> Tensor (A<sup>2</sup>)",
3324 "catagory": "TLS Analysis",
3325 "read_only": True,
3326 "type": "numpy.array(3,3)",
3327 "default": numpy.zeros((3,3), float),
3328 "action": "recompile" })
3329 self.glo_add_property(
3330 { "name": "rT",
3331 "desc": "T<sup>r</sup> Tensor (A<sup>2</sup>)",
3332 "catagory": "TLS Analysis",
3333 "read_only": True,
3334 "type": "numpy.array(3,3)",
3335 "default": numpy.zeros((3,3), float),
3336 "action": "recompile" })
3337 self.glo_add_property(
3338 { "name": "L",
3339 "desc": "L<sup>COR</sup> Tensor (DEG<sup>2</sup>)",
3340 "catagory": "TLS Analysis",
3341 "read_only": True,
3342 "type": "numpy.array(3,3)",
3343 "default": numpy.zeros((3,3), float),
3344 "action": "recompile" })
3345 self.glo_add_property(
3346 { "name": "S",
3347 "desc": "S<sup>COR</sup> Tensor (A*DEG)",
3348 "catagory": "TLS Analysis",
3349 "read_only": True,
3350 "type": "numpy.array(3,3)",
3351 "default": numpy.zeros((3,3), float),
3352 "action": "recompile" })
3353 self.glo_add_property(
3354 { "name": "L1_eigen_vec",
3355 "desc": "L<sub>1</sub> Eigen Vector",
3356 "catagory": "TLS Analysis",
3357 "read_only": True,
3358 "type": "numpy.array(3)",
3359 "default": numpy.zeros(3, float),
3360 "action": "recompile" })
3361 self.glo_add_property(
3362 { "name": "L2_eigen_vec",
3363 "desc": "L<sub>2</sub> Eigen Vector",
3364 "catagory": "TLS Analysis",
3365 "read_only": True,
3366 "type": "numpy.array(3)",
3367 "default": numpy.zeros(3, float),
3368 "action": "recompile" })
3369 self.glo_add_property(
3370 { "name": "L3_eigen_vec",
3371 "desc": "L<sub>3</sub> Eigen Vector",
3372 "catagory": "TLS Analysis",
3373 "read_only": True,
3374 "type": "numpy.array(3)",
3375 "default": numpy.zeros(3, float),
3376 "action": "recompile" })
3377 self.glo_add_property(
3378 { "name": "L1_eigen_val",
3379 "desc": "L<sub>1</sub> Eigen Value",
3380 "catagory": "TLS Analysis",
3381 "read_only": True,
3382 "type": "float",
3383 "default": 0.0,
3384 "action": "recompile" })
3385 self.glo_add_property(
3386 { "name": "L2_eigen_val",
3387 "desc": "L<sub>2</sub> Eigen Value",
3388 "catagory": "TLS Analysis",
3389 "read_only": True,
3390 "type": "float",
3391 "default": 0.0,
3392 "action": "recompile" })
3393 self.glo_add_property(
3394 { "name": "L3_eigen_val",
3395 "desc": "L<sub>3</sub> Eigen Value",
3396 "catagory": "TLS Analysis",
3397 "read_only": True,
3398 "type": "float",
3399 "default": 0.0,
3400 "action": "recompile" })
3401 self.glo_add_property(
3402 { "name": "L1_rho",
3403 "desc": "L<sub>1</sub> Position from COR",
3404 "catagory": "TLS Analysis",
3405 "read_only": True,
3406 "type": "numpy.array(3)",
3407 "default": numpy.zeros(3, float),
3408 "action": "recompile" })
3409 self.glo_add_property(
3410 { "name": "L2_rho",
3411 "desc": "L<sub>2</sub> Position from COR",
3412 "catagory": "TLS Analysis",
3413 "read_only": True,
3414 "type": "numpy.array(3)",
3415 "default": numpy.zeros(3, float),
3416 "action": "recompile" })
3417 self.glo_add_property(
3418 { "name": "L3_rho",
3419 "desc": "L<sub>3</sub> Position from COR",
3420 "catagory": "TLS Analysis",
3421 "read_only": True,
3422 "type": "numpy.array(3)",
3423 "default": numpy.zeros(3, float),
3424 "action": "recompile" })
3425 self.glo_add_property(
3426 { "name": "L1_pitch",
3427 "desc": "L<sub>1</sub> Screw Pitch (A/DEG)",
3428 "catagory": "TLS Analysis",
3429 "read_only": True,
3430 "type": "float",
3431 "default": 0.0,
3432 "action": "recompile" })
3433 self.glo_add_property(
3434 { "name": "L2_pitch",
3435 "desc": "L<sub>2</sub> Screw Pitch (A/DEG)",
3436 "catagory": "TLS Analysis",
3437 "read_only": True,
3438 "type": "float",
3439 "default": 0.0,
3440 "action": "recompile" })
3441 self.glo_add_property(
3442 { "name": "L3_pitch",
3443 "desc": "L<sub>3</sub> Screw Pitch (A/DEG)",
3444 "catagory": "TLS Analysis",
3445 "read_only": True,
3446 "type": "float",
3447 "default": 0.0,
3448 "action": "recompile" })
3449 self.glo_add_property(
3450 { "name": "gof",
3451 "desc": "Goodness of Fit",
3452 "catagory": "TLS Analysis",
3453 "read_only": True,
3454 "type": "float",
3455 "default": 0.0,
3456 "action": "recompile" })
3457
3458
3459 self.glo_add_property(
3460 { "name": "symmetry",
3461 "desc": "Show Symmetry Equivelant",
3462 "catagory": "Show/Hide",
3463 "type": "boolean",
3464 "default": False,
3465 "action": "redraw" })
3466 self.glo_add_property(
3467 { "name": "main_chain_visible",
3468 "desc": "Show Main Chain Atoms",
3469 "catagory": "Show/Hide",
3470 "type": "boolean",
3471 "default": True,
3472 "action": ["recompile", "recalc_positions"] })
3473 self.glo_add_property(
3474 { "name": "oatm_visible",
3475 "desc": "Show Main Chain Carbonyl Atoms",
3476 "catagory": "Show/Hide",
3477 "type": "boolean",
3478 "default": True,
3479 "action": ["recompile", "recalc_positions"] })
3480 self.glo_add_property(
3481 { "name": "side_chain_visible",
3482 "desc": "Show Side Chain Atoms",
3483 "catagory": "Show/Hide",
3484 "type": "boolean",
3485 "default": True,
3486 "action": ["recompile", "recalc_positions"] })
3487 self.glo_add_property(
3488 { "name": "hetatm_visible",
3489 "desc": "Show Hetrogen Atoms",
3490 "catagory": "Show/Hide",
3491 "type": "boolean",
3492 "default": True,
3493 "action": ["recompile", "recalc_positions"] })
3494 self.glo_add_property(
3495 { "name": "water_visible",
3496 "desc": "Show Waters",
3497 "catagory": "Show/Hide",
3498 "type": "boolean",
3499 "default": False,
3500 "action": ["recompile", "recalc_positions"] })
3501 self.glo_add_property(
3502 { "name": "hydrogen_visible",
3503 "desc": "Show Hydrogens",
3504 "catagory": "Show/Hide",
3505 "type": "boolean",
3506 "default": False,
3507 "action": ["recompile", "recalc_positions"] })
3508 self.glo_add_property(
3509 { "name": "fan_visible",
3510 "desc": "Show COR-Backbone Fan",
3511 "catagory": "Show/Hide",
3512 "type": "boolean",
3513 "default": False,
3514 "action": "recompile" })
3515 self.glo_add_property(
3516 { "name": "TLS_visible",
3517 "desc": "Show TLS T<sup>r</sup> Ellipsoid/Screw Axes",
3518 "catagory": "Show/Hide",
3519 "type": "boolean",
3520 "default": True,
3521 "action": "recompile_tensors" })
3522 self.glo_add_property(
3523 { "name": "U",
3524 "desc": "Show U<sup>TLS</sup> Thermal Axes",
3525 "catagory": "Show/Hide",
3526 "type": "boolean",
3527 "default": False,
3528 "action": "recompile_Utls_axes" })
3529 self.glo_add_property(
3530 { "name": "ellipse",
3531 "desc": "Show U<sup>TLS</sup> Thermal Ellipsoids",
3532 "catagory": "Show/Hide",
3533 "type": "boolean",
3534 "default": False,
3535 "action": "recompile_Utls_ellipse" })
3536 self.glo_add_property(
3537 { "name": "rms",
3538 "desc": "Show U<sup>TLS</sup> Thermal Peanuts",
3539 "catagory": "Show/Hide",
3540 "type": "boolean",
3541 "default": False,
3542 "action": "recompile_Utls_rms" })
3543
3544 self.glo_add_property(
3545 { "name": "axes_rT",
3546 "desc": "Show T<sup>r</sup> Thermal Axes",
3547 "catagory": "Show/Hide",
3548 "type": "boolean",
3549 "default": False,
3550 "action": "redraw" })
3551 self.glo_add_property(
3552 { "name": "ellipse_rT",
3553 "desc": "Show T<sup>r</sup> Thermal Ellipsoids",
3554 "catagory": "Show/Hide",
3555 "type": "boolean",
3556 "default": False,
3557 "action": "redraw" })
3558 self.glo_add_property(
3559 { "name": "rms_rT",
3560 "desc": "Show T<sup>r</sup> Thermal Peanuts",
3561 "catagory": "Show/Hide",
3562 "type": "boolean",
3563 "default": False,
3564 "action": "recompile_Utls_rms" })
3565
3566 self.glo_add_property(
3567 { "name": "L1_visible",
3568 "desc": "Show Screw L1 Displacement Surface",
3569 "catagory": "Show/Hide",
3570 "type": "boolean",
3571 "default": False,
3572 "action": "recompile_surface" })
3573 self.glo_add_property(
3574 { "name": "L2_visible",
3575 "desc": "Show Screw L2 Displacement Surface",
3576 "catagory": "Show/Hide",
3577 "type": "boolean",
3578 "default": False,
3579 "action": "recompile_surface" })
3580 self.glo_add_property(
3581 { "name": "L3_visible",
3582 "desc": "Show Screw L3 Displacement Surface",
3583 "catagory": "Show/Hide",
3584 "type": "boolean",
3585 "default": False,
3586 "action": "recompile_surface" })
3587
3588
3589 self.glo_add_property(
3590 { "name": "add_biso",
3591 "desc": "Add Atom B<sup>ISO</sup> to U<sup>TLS</sup>",
3592 "catagory": "TLS",
3593 "type": "boolean",
3594 "default": False,
3595 "action": "recompile" })
3596 self.glo_add_property(
3597 { "name": "both_phases",
3598 "desc": "Show Simultanius +/- Phases",
3599 "catagory": "TLS",
3600 "type": "boolean",
3601 "default": False,
3602 "action": "recompile" })
3603 self.glo_add_property(
3604 { "name": "tls_color",
3605 "desc": "TLS Group Visualization Color",
3606 "catagory": "TLS",
3607 "type": "enum_string",
3608 "default": "Green",
3609 "enum_list": self.gldl_color_list,
3610 "action": ["redraw", "recompile"] })
3611 self.glo_add_property(
3612 { "name": "adp_prob",
3613 "desc": "Isoprobability Magnitude",
3614 "catagory": "TLS",
3615 "type": "integer",
3616 "range": Viewer.PROP_PROBABILTY_RANGE,
3617 "default": 50,
3618 "action": "recompile" })
3619 self.glo_add_property(
3620 { "name": "L_axis_scale",
3621 "desc": "Scale Screw Axis Length",
3622 "catagory": "TLS",
3623 "type": "float",
3624 "default": 5.00,
3625 "action": "recompile_tensors" })
3626 self.glo_add_property(
3627 { "name": "L_axis_radius",
3628 "desc": "Screw Axes Radius",
3629 "catagory": "TLS",
3630 "type": "float",
3631 "default": 0.4,
3632 "action": "recompile_tensors" })
3633 self.glo_add_property(
3634 { "name": "ellipse_opacity",
3635 "desc": "U<sup>TLS</sup> Thermal Ellipsoid Opacity",
3636 "catagory": "TLS",
3637 "type": "float",
3638 "range": Viewer.PROP_OPACITY_RANGE,
3639 "default": 1.0,
3640 "action": "recompile_Utls_ellipse" })
3641 self.glo_add_property(
3642 { "name": "rms_opacity",
3643 "desc": "U<sup>TLS</sup> Thermal Peanut Opacity",
3644 "catagory": "TLS",
3645 "type": "float",
3646 "range": Viewer.PROP_OPACITY_RANGE,
3647 "default": 1.0,
3648 "action": "recompile_Utls_rms" })
3649 self.glo_add_property(
3650 { "name": "surface_opacity",
3651 "desc": "Screw Surface Opacity",
3652 "catagory": "TLS",
3653 "type": "float",
3654 "range": Viewer.PROP_OPACITY_RANGE,
3655 "default": 1.0,
3656 "action": "recompile_surface" })
3657 self.glo_add_property(
3658 { "name": "fan_opacity",
3659 "desc": "COR-Backbone Fan Opacity",
3660 "catagory": "TLS",
3661 "type": "float",
3662 "range": Viewer.PROP_OPACITY_RANGE,
3663 "default": 1.0,
3664 "action": "recompile_fan" })
3665 self.glo_add_property(
3666 { "name": "time",
3667 "desc": "Simulation Time",
3668 "catagory": "TLS",
3669 "type": "float",
3670 "default": 0.0,
3671 "action": "redraw" })
3672 self.glo_add_property(
3673 { "name": "period",
3674 "desc": "Simulation Period",
3675 "catagory": "TLS",
3676 "type": "float",
3677 "default": 1.0,
3678 "action": "redraw" })
3679 self.glo_add_property(
3680 { "name": "amplitude",
3681 "desc": "Simulation Amplitude",
3682 "catagory": "TLS",
3683 "type": "float",
3684 "default": 1.0,
3685 "action": "redraw" })
3686 self.glo_add_property(
3687 { "name": "L1_rot",
3688 "desc": "L<sub>1</sub> Simulated Rotation (DEG)",
3689 "catagory": "TLS",
3690 "type": "float",
3691 "default": 0.0,
3692 "action": "redraw" })
3693 self.glo_add_property(
3694 { "name": "L2_rot",
3695 "desc": "L<sub>2</sub> Simulated Rotation (DEG)",
3696 "catagory": "TLS",
3697 "type": "float",
3698 "default": 0.0,
3699 "action": "redraw" })
3700 self.glo_add_property(
3701 { "name": "L3_rot",
3702 "desc": "L<sub>3</sub> Simulated Rotation (DEG)",
3703 "catagory": "TLS",
3704 "type": "float",
3705 "default": 0.0,
3706 "action": "redraw" })
3707
3709 self.gldl_draw_method_install(
3710 { "name": "tls_tensors",
3711 "func": self.draw_tensors,
3712 "transparent": False,
3713 "visible_property": "TLS_visible",
3714 "recompile_action": "recompile_tensors" })
3715 self.gldl_draw_method_install(
3716 { "name": "Utls_axes",
3717 "func": self.draw_Utls_axes,
3718 "transparent": False,
3719 "visible_property": "U",
3720 "recompile_action": "recompile_Utls_axes" })
3721 self.gldl_draw_method_install(
3722 { "name": "Utls_ellipse",
3723 "func": self.draw_Utls_ellipse,
3724 "visible_property": "ellipse",
3725 "opacity_property": "ellipse_opacity",
3726 "recompile_action": "recompile_Utls_ellipse" })
3727 self.gldl_draw_method_install(
3728 { "name": "Utls_rms",
3729 "func": self.draw_Utls_rms,
3730 "visible_property": "rms",
3731 "opacity_property": "rms_opacity",
3732 "recompile_action": "recompile_Utls_rms" })
3733 self.gldl_draw_method_install(
3734 { "name": "L1_surface",
3735 "func": self.draw_L1_surface,
3736 "visible_property": "L1_visible",
3737 "opacity_property": "surface_opacity",
3738 "recompile_action": "recompile_surface" })
3739 self.gldl_draw_method_install(
3740 { "name": "L2_surface",
3741 "func": self.draw_L2_surface,
3742 "visible_property": "L2_visible",
3743 "opacity_property": "surface_opacity",
3744 "recompile_action": "recompile_surface" })
3745 self.gldl_draw_method_install(
3746 { "name": "L3_surface",
3747 "func": self.draw_L3_surface,
3748 "visible_property": "L3_visible",
3749 "opacity_property": "surface_opacity",
3750 "recompile_action": "recompile_surface" })
3751
3753 if "time" in updates or "adp_prob" in updates:
3754 self.update_time()
3755
3757 """Changes the time of the TLS group simulating harmonic motion.
3758 """
3759 if self.tls_group.is_null():
3760 return
3761
3762
3763 sin_tm = math.sin(2.0 * math.pi * self.properties["period"] * self.properties["time"])
3764
3765
3766
3767 C = Gaussian.GAUSS3C[self.properties["adp_prob"]]
3768
3769 L1_rot = self.properties["amplitude"] * C * calc_rmsd(self.properties["L1_eigen_val"]) * sin_tm
3770 L2_rot = self.properties["amplitude"] * C * calc_rmsd(self.properties["L2_eigen_val"]) * sin_tm
3771 L3_rot = self.properties["amplitude"] * C * calc_rmsd(self.properties["L3_eigen_val"]) * sin_tm
3772
3773 self.glo_update_properties(L1_rot=L1_rot, L2_rot=L2_rot, L3_rot=L3_rot)
3774
3776 """Specialized draw list invokation to recycle the draw list for
3777 symmetry related copies. Cartesian versions of the symmetry rotation
3778 and translation operators are generated by GLStructure/UnitCell
3779 classes.
3780 """
3781 if self.properties["symmetry"]==False:
3782 yield True
3783
3784 else:
3785
3786 gl_struct = self.glo_get_glstructure()
3787 if gl_struct is None:
3788 yield True
3789
3790 else:
3791 for symop in gl_struct.iter_orth_symops():
3792 self.driver.glr_push_matrix()
3793 self.driver.glr_mult_matrix_Rt(symop.R, symop.t)
3794 yield True
3795 self.driver.glr_pop_matrix()
3796
3798 """Special atom iterator for the TLS drawing functions yields:
3799 atm, Utls
3800 """
3801 T = self.tls_group.T
3802 L = self.tls_group.L
3803 S = self.tls_group.S
3804 o = self.tls_group.origin
3805
3806 for atm, visible in self.gl_atom_list.glal_iter_atoms_filtered():
3807 if not visible:
3808 continue
3809
3810 Utls = calc_Utls(T, L, S, atm.position - o)
3811
3812 if self.properties["add_biso"] == True:
3813 if atm.temp_factor is not None:
3814 Utls = Utls + (Constants.B2U * atm.temp_factor * numpy.identity(3, float))
3815
3816 yield atm, Utls
3817
3819 """Draw tensor axis.
3820 """
3821 if self.tls_group.is_null():
3822 return
3823
3824 self.driver.glr_push_matrix()
3825
3826
3827 r, g, b = self.gldl_property_color_rgbf("tls_color")
3828
3829 self.driver.glr_translate(self.properties["COR"])
3830
3831
3832 self.driver.glr_set_material_rgb(0.5, 0.5, 0.5)
3833 vec = self.properties["COR_vector"]
3834 if AtomMath.length(vec) > 1.0:
3835 vec2 = 2.0 * vec
3836 self.driver.glr_axis(-vec2 / 2.0, vec2, self.properties["L_axis_radius"])
3837
3838 self.driver.glr_set_material_rgb(r, g, b)
3839
3840
3841 self.driver.glr_Uellipse((0.0,0.0,0.0), self.properties["rT"], self.properties["adp_prob"])
3842
3843
3844 L_scale = self.properties["L_axis_scale"]
3845
3846
3847 for Lx_eigen_val, Lx_eigen_vec, Lx_rho, Lx_pitch in [
3848 ("L1_eigen_val", "L1_eigen_vec", "L1_rho", "L1_pitch"),
3849 ("L2_eigen_val", "L2_eigen_vec", "L2_rho", "L2_pitch"),
3850 ("L3_eigen_val", "L3_eigen_vec", "L3_rho", "L3_pitch")]:
3851
3852 L_eigen_vec = self.properties[Lx_eigen_vec]
3853 L_eigen_val = self.properties[Lx_eigen_val]
3854 L_rho = self.properties[Lx_rho]
3855 L_pitch = self.properties[Lx_pitch]
3856
3857 C = Gaussian.GAUSS3C[self.properties["adp_prob"]]
3858 L_rot = C * (L_scale * calc_rmsd(L_eigen_val))
3859
3860 if L_eigen_val <= 0.0:
3861 continue
3862
3863 L_v = L_eigen_vec * L_rot
3864
3865
3866
3867 self.driver.glr_lighting_disable()
3868 self.driver.glr_line((0.0, 0.0, 0.0), L_rho)
3869
3870
3871 self.driver.glr_axis(L_rho - (0.5*L_v), L_v, self.properties["L_axis_radius"])
3872
3873
3874 L_screw_dis = L_eigen_vec * L_rot * L_pitch
3875
3876 self.driver.glr_axis(
3877 L_rho - (0.5 * L_screw_dis),
3878 L_screw_dis,
3879 1.5 * self.properties["L_axis_radius"])
3880
3881 self.driver.glr_pop_matrix()
3882
3884 """Render the anisotropic thremal axes calculated from the TLS
3885 model.
3886 """
3887 if self.tls_group.is_null():
3888 return
3889
3890 prob = self.properties["adp_prob"]
3891 rgbf = self.gldl_property_color_rgbf("tls_color")
3892
3893 glr_Uaxes = self.driver.glr_Uaxes
3894
3895 for atm, Utls in self.gltls_iter_atoms():
3896 glr_Uaxes(atm.position, Utls, prob, rgbf, 1.0)
3897
3914
3916 """Render the anisotropic thremal peanuts calculated from the TLS
3917 model.
3918 """
3919 if self.tls_group.is_null():
3920 return
3921
3922 r, g, b = self.gldl_property_color_rgbf("tls_color")
3923 a = self.properties["rms_opacity"]
3924 self.driver.glr_set_material_rgb(r, g, b, a)
3925
3926 for atm, Utls in self.gltls_iter_atoms():
3927 self.driver.glr_Urms(atm.position, Utls)
3928
3930 if self.tls_group.is_null():
3931 return
3932 self.draw_tls_surface(
3933 self.properties["L1_eigen_vec"],
3934 self.properties["L1_eigen_val"],
3935 self.properties["L1_rho"],
3936 self.properties["L1_pitch"])
3937
3939 if self.tls_group.is_null():
3940 return
3941 self.draw_tls_surface(
3942 self.properties["L2_eigen_vec"],
3943 self.properties["L2_eigen_val"],
3944 self.properties["L2_rho"],
3945 self.properties["L2_pitch"])
3946
3948 if self.tls_group.is_null():
3949 return
3950 self.draw_tls_surface(
3951 self.properties["L3_eigen_vec"],
3952 self.properties["L3_eigen_val"],
3953 self.properties["L3_rho"],
3954 self.properties["L3_pitch"])
3955
3957 """Draws the TLS probability surface for a single non-intersecting
3958 screw axis. Lx_eigen_val is the vaiance (mean square deviation MSD)
3959 of the rotation about the Lx_eigen_vec axis.
3960 """
3961
3962
3963
3964 bond_list = []
3965 in_dict = {}
3966
3967 for atm, Utls in self.gltls_iter_atoms():
3968 in_dict[atm] = True
3969
3970 for atm, Utls in self.gltls_iter_atoms():
3971 for bond in atm.iter_bonds():
3972 if in_dict.has_key(bond.get_partner(atm)):
3973 bond_list.append(bond)
3974
3975
3976 if numpy.allclose(Lx_eigen_val, 0.0):
3977 return
3978
3979 C = Gaussian.GAUSS3C[self.properties["adp_prob"]]
3980 Lx_s = C * calc_rmsd(Lx_eigen_val * Constants.DEG2RAD2)
3981 if numpy.allclose(Lx_s, 0.0):
3982 return
3983
3984 Lx_pitch = Lx_pitch * (1.0 / Constants.DEG2RAD)
3985 COR = self.properties["COR"]
3986 Lx_origin = COR + Lx_rho
3987 steps = 1
3988 rot_step = Lx_s / float(steps)
3989
3990 self.driver.glr_light_two_sides_enable()
3991 self.driver.glr_lighting_enable()
3992 self.driver.glr_normalize_enable()
3993
3994 r, g, b = self.gldl_property_color_rgbf("tls_color")
3995 a = self.properties["surface_opacity"]
3996 gam = 0.50
3997 self.driver.glr_set_material_rgba(r*gam, g*gam, b*gam, a)
3998
3999
4000 self.driver.glr_begin_quads()
4001
4002
4003 glr_normal = self.driver.glr_normal
4004 glr_vertex = self.driver.glr_vertex
4005
4006
4007 for step in range(steps):
4008 rot_start = rot_step * float(step)
4009 rot_end = rot_step * float(step + 1)
4010
4011 for sign in (-1.0, 1.0):
4012 rot1 = rot_start * sign
4013 rot2 = rot_end * sign
4014
4015 Rstep1 = AtomMath.rmatrixu(Lx_eigen_vec, rot1)
4016 Rstep2 = AtomMath.rmatrixu(Lx_eigen_vec, rot2)
4017
4018 screw1 = Lx_eigen_vec * (rot1 * Lx_pitch)
4019 screw2 = Lx_eigen_vec * (rot2 * Lx_pitch)
4020
4021 for bond in bond_list:
4022
4023 pos1 = bond.atom1.position - Lx_origin
4024 pos2 = bond.atom2.position - Lx_origin
4025
4026 v1 = numpy.dot(Rstep1, pos1) + screw1
4027 v2 = numpy.dot(Rstep2, pos1) + screw2
4028 v3 = numpy.dot(Rstep2, pos2) + screw2
4029 v4 = numpy.dot(Rstep1, pos2) + screw1
4030
4031
4032 glr_normal(numpy.cross(v2-v1, v4-v1))
4033
4034 glr_vertex(v1 + Lx_origin)
4035 glr_vertex(v2 + Lx_origin)
4036 glr_vertex(v3 + Lx_origin)
4037 glr_vertex(v4 + Lx_origin)
4038
4039 self.driver.glr_end()
4040 self.driver.glr_light_two_sides_disable()
4041 self.driver.glr_normalize_disable()
4042 self.driver.glr_lighting_disable()
4043
4045 """Collects a list of GLTLSGroup instances which are all in the
4046 same chain.
4047 """
4054
4056 Viewer.GLDrawList.glo_install_properties(self)
4057
4058
4059 self.glo_add_property(
4060 { "name": "symmetry",
4061 "desc": "Show Symmetry Equivelant",
4062 "catagory": "Show/Hide",
4063 "type": "boolean",
4064 "default": False,
4065 "action": "" })
4066 self.glo_add_property(
4067 { "name": "main_chain_visible",
4068 "desc": "Show Main Chain Atoms",
4069 "catagory": "Show/Hide",
4070 "type": "boolean",
4071 "default": True,
4072 "action": "" })
4073 self.glo_add_property(
4074 { "name": "oatm_visible",
4075 "desc": "Show Main Chain Carbonyl Atoms",
4076 "catagory": "Show/Hide",
4077 "type": "boolean",
4078 "default": True,
4079 "action": ["recompile", "recalc_positions"] })
4080 self.glo_add_property(
4081 { "name": "side_chain_visible",
4082 "desc": "Show Side Chain Atoms",
4083 "catagory": "Show/Hide",
4084 "type": "boolean",
4085 "default": True,
4086 "action": "" })
4087 self.glo_add_property(
4088 { "name": "hetatm_visible",
4089 "desc": "Show Hetrogen Atoms",
4090 "catagory": "Show/Hide",
4091 "type": "boolean",
4092 "default": True,
4093 "action": "" })
4094 self.glo_add_property(
4095 { "name": "water_visible",
4096 "desc": "Show Waters",
4097 "catagory": "Show/Hide",
4098 "type": "boolean",
4099 "default": False,
4100 "action": "" })
4101 self.glo_add_property(
4102 { "name": "hydrogen_visible",
4103 "desc": "Show Hydrogens",
4104 "catagory": "Show/Hide",
4105 "type": "boolean",
4106 "default": False,
4107 "action": "" })
4108 self.glo_add_property(
4109 { "name": "fan_visible",
4110 "desc": "Show COR-Backbone Fan",
4111 "catagory": "Show/Hide",
4112 "type": "boolean",
4113 "default": False,
4114 "action": "recompile" })
4115 self.glo_add_property(
4116 { "name": "TLS_visible",
4117 "desc": "Show TLS T<sup>r</sup> Ellipsoid/Screw Axes",
4118 "catagory": "Show/Hide",
4119 "type": "boolean",
4120 "default": True,
4121 "action": "" })
4122 self.glo_add_property(
4123 { "name": "U",
4124 "desc": "Show U<sup>TLS</sup> Thermal Axes",
4125 "catagory": "Show/Hide",
4126 "type": "boolean",
4127 "default": False,
4128 "action": "" })
4129 self.glo_add_property(
4130 { "name": "ellipse",
4131 "desc": "Show U<sup>TLS</sup> Thermal Ellipsoids",
4132 "catagory": "Show/Hide",
4133 "type": "boolean",
4134 "default": False,
4135 "action": "" })
4136 self.glo_add_property(
4137 { "name": "rms",
4138 "desc": "Show U<sup>TLS</sup> Thermal Peanuts",
4139 "catagory": "Show/Hide",
4140 "type": "boolean",
4141 "default": False,
4142 "action": "" })
4143 self.glo_add_property(
4144 { "name": "axes_rT",
4145 "desc": "Show T<sup>r</sup> Thermal Axes",
4146 "catagory": "Show/Hide",
4147 "type": "boolean",
4148 "default": False,
4149 "action": "" })
4150 self.glo_add_property(
4151 { "name": "ellipse_rT",
4152 "desc": "Show T<sup>r</sup> Thermal Ellipsoids",
4153 "catagory": "Show/Hide",
4154 "type": "boolean",
4155 "default": False,
4156 "action": "" })
4157 self.glo_add_property(
4158 { "name": "rms_rT",
4159 "desc": "Show T<sup>r</sup> Thermal Peanuts",
4160 "catagory": "Show/Hide",
4161 "type": "boolean",
4162 "default": False,
4163 "action": "" })
4164 self.glo_add_property(
4165 { "name": "L1_visible",
4166 "desc": "Show L<sub>1</sub> Screw Displacement Surface",
4167 "catagory": "Show/Hide",
4168 "type": "boolean",
4169 "default": False,
4170 "action": "" })
4171 self.glo_add_property(
4172 { "name": "L2_visible",
4173 "desc": "Show L<sub>2</sub> Screw Displacement Surface",
4174 "catagory": "Show/Hide",
4175 "type": "boolean",
4176 "default": False,
4177 "action": "" })
4178 self.glo_add_property(
4179 { "name": "L3_visible",
4180 "desc": "Show L<sub>3</sub> Screw Displacement Surface",
4181 "catagory": "Show/Hide",
4182 "type": "boolean",
4183 "default": False,
4184 "action": "" })
4185
4186
4187 self.glo_add_property(
4188 { "name": "add_biso",
4189 "desc": "Add Atom B<sup>ISO</sup> to U<sup>TLS</sup>",
4190 "catagory": "TLS",
4191 "type": "boolean",
4192 "default": False,
4193 "action": "" })
4194 self.glo_add_property(
4195 { "name": "both_phases",
4196 "desc": "Show Simultanius +/- Phases",
4197 "catagory": "TLS",
4198 "type": "boolean",
4199 "default": False,
4200 "action": "recompile" })
4201 self.glo_add_property(
4202 { "name": "adp_prob",
4203 "desc": "Isoprobability Magnitude",
4204 "catagory": "TLS",
4205 "type": "integer",
4206 "range": Viewer.PROP_PROBABILTY_RANGE,
4207 "default": 50,
4208 "action": "" })
4209
4210 self.glo_add_property(
4211 { "name": "L_axis_scale",
4212 "desc": "Scale Screw Axis Length",
4213 "catagory": "TLS",
4214 "type": "float",
4215 "default": 5.00,
4216 "action": "recompile_tensors" })
4217 self.glo_add_property(
4218 { "name": "L_axis_radius",
4219 "desc": "Screw Axes Radius",
4220 "catagory": "TLS",
4221 "type": "float",
4222 "default": 0.4,
4223 "action": "" })
4224 self.glo_add_property(
4225 { "name": "ellipse_opacity",
4226 "desc": "U<sup>TLS</sup> Thermal Ellipsoid Opacity",
4227 "catagory": "TLS",
4228 "type": "float",
4229 "range": Viewer.PROP_OPACITY_RANGE,
4230 "default": 1.0,
4231 "action": "" })
4232 self.glo_add_property(
4233 { "name": "rms_opacity",
4234 "desc": "U<sup>TLS</sup> Thermal Peanut Opacity",
4235 "catagory": "TLS",
4236 "type": "float",
4237 "range": Viewer.PROP_OPACITY_RANGE,
4238 "default": 1.0,
4239 "action": "" })
4240 self.glo_add_property(
4241 { "name": "surface_opacity",
4242 "desc": "Screw Displacement Surface Opacity",
4243 "catagory": "TLS",
4244 "type": "float",
4245 "range": Viewer.PROP_OPACITY_RANGE,
4246 "default": 1.0,
4247 "action": "" })
4248 self.glo_add_property(
4249 { "name": "fan_opacity",
4250 "desc": "COR-Backbone Fan Opacity",
4251 "catagory": "TLS",
4252 "type": "float",
4253 "range": Viewer.PROP_OPACITY_RANGE,
4254 "default": 1.0,
4255 "action": "recompile_fan" })
4256
4257
4258 self.glo_add_property(
4259 { "name": "color_method",
4260 "desc": "TLS Group Coloring Scheme",
4261 "catagory": "Macros",
4262 "type": "enum_string",
4263 "default": "Color by Group",
4264 "enum_list": ["Color By Group", "Color By Goodness of Fit"],
4265 "action": "recolor" })
4266 self.glo_add_property(
4267 { "name": "show_frac",
4268 "desc": "Show Fraction of Top Fitting Groups",
4269 "catagory": "Macros",
4270 "type": "integer",
4271 "range": "0-100,1",
4272 "default": 100,
4273 "action": "recolor" })
4274 self.glo_add_property(
4275 { "name": "style1",
4276 "desc": "Cool Visualization Style #1",
4277 "catagory": "Macros",
4278 "type": "boolean",
4279 "default": False,
4280 "action": "style1" })
4281
4283 if "recolor" in actions:
4284 if self.properties["color_method"]=="Color By Goodness of Fit":
4285 show_frac = float(self.properties["show_frac"] / 100.0)
4286 self.color_by_gof(show_frac)
4287 elif self.properties["color_method"]=="Color By Group":
4288 self.color_by_group()
4289
4290 if "style1" in actions and self.properties["style1"]==True:
4291 self.properties.update(style1=False)
4292 self.set_style1()
4293
4295 self.properties.update(
4296 L1_visible = True,
4297 L2_visible = True,
4298 L3_visible = True)
4299
4300 for gl_tls_group in self.glo_iter_children():
4301 gl_tls_group.properties.update(
4302 time = 0.25)
4303
4304 gl_tls_group.gl_atom_list.properties.update(
4305 trace = False,
4306 ball_stick = True,
4307 ball_radius = 0.075,
4308 stick_radius = 0.075)
4309
4326
4328 """Color TLS Groups by goodness-of-fit.
4329 """
4330 gof_list = []
4331
4332 for gl_tls_group in self.glo_iter_children():
4333 gof = gl_tls_group.properties["gof"]
4334 gof_list.append((gof, gl_tls_group))
4335
4336 if len(gof_list)==0:
4337 return
4338 elif len(gof_list)==1:
4339 return
4340
4341
4342
4343 gof_list.sort()
4344 gof_list.reverse()
4345
4346
4347 n = int(round(float(len(gof_list)) * show_frac))
4348 i = len(gof_list) - n
4349
4350
4351
4352 for j in range(i):
4353 gof, gl_tls_group = gof_list[j]
4354 gl_tls_group.properties.update(
4355 visible = False,
4356 tls_color = "gray")
4357
4358
4359 gof_list = gof_list[i:]
4360
4361 min_gof = gof_list[0][0]
4362 max_gof = gof_list[-1][0]
4363
4364
4365 gof_range = max_gof - min_gof
4366 if numpy.allclose(gof_range, 0.0):
4367 for gof, gl_tls_group in gof_list:
4368 gl_tls_group.properties.update(
4369 visible = True,
4370 tls_color = "gray")
4371 return
4372
4373 for gof, gl_tls_group in gof_list:
4374 goodness = 1.0 - (gof - min_gof) / gof_range
4375 tls_color = "%4.2f,%4.2f,%4.2f" % (goodness_color(goodness))
4376
4377
4378 gl_tls_group.properties.update(
4379 visible = True,
4380 tls_color = tls_color)
4381
4382
4383 gl_tls_group.gl_atom_list.properties.update(
4384 trace_radius = 0.3 + (goodness * 0.01))
4385
4387 self.glo_add_child(gl_tls_group)
4388
4389 child_id = gl_tls_group.glo_get_properties_id()
4390
4391 self.glo_link_child_property(
4392 "symmetry", child_id, "symmetry")
4393
4394 self.glo_link_child_property(
4395 "main_chain_visible", child_id, "main_chain_visible")
4396 self.glo_link_child_property(
4397 "oatm_visible", child_id, "oatm_visible")
4398 self.glo_link_child_property(
4399 "side_chain_visible", child_id, "side_chain_visible")
4400 self.glo_link_child_property(
4401 "hetatm_visible", child_id, "hetatm_visible")
4402 self.glo_link_child_property(
4403 "water_visible", child_id, "water_visible")
4404 self.glo_link_child_property(
4405 "hydrogen_visible", child_id, "hydrogen_visible")
4406
4407 self.glo_link_child_property(
4408 "fan_visible", child_id, "fan_visible")
4409 self.glo_link_child_property(
4410 "fan_opacity", child_id, "fan_opacity")
4411 self.glo_link_child_property(
4412 "TLS_visible", child_id, "TLS_visible")
4413
4414 self.glo_link_child_property(
4415 "U", child_id, "U")
4416 self.glo_link_child_property(
4417 "ellipse", child_id, "ellipse")
4418 self.glo_link_child_property(
4419 "rms", child_id, "rms")
4420
4421 self.glo_link_child_property(
4422 "axes_rT", child_id, "axes_rT")
4423 self.glo_link_child_property(
4424 "ellipse_rT", child_id, "ellipse_rT")
4425 self.glo_link_child_property(
4426 "rms_rT", child_id, "rms_rT")
4427
4428 self.glo_link_child_property(
4429 "L1_visible", child_id, "L1_visible")
4430 self.glo_link_child_property(
4431 "L2_visible", child_id, "L2_visible")
4432 self.glo_link_child_property(
4433 "L3_visible", child_id, "L3_visible")
4434 self.glo_link_child_property(
4435 "add_biso", child_id, "add_biso")
4436 self.glo_link_child_property(
4437 "both_phases", child_id, "both_phases")
4438 self.glo_link_child_property(
4439 "adp_prob", child_id, "adp_prob")
4440 self.glo_link_child_property(
4441 "L_axis_scale", child_id, "L_axis_scale")
4442 self.glo_link_child_property(
4443 "L_axis_radius", child_id, "L_axis_radius")
4444 self.glo_link_child_property(
4445 "ellipse_opacity", child_id, "ellipse_opacity")
4446 self.glo_link_child_property(
4447 "rms_opacity", child_id, "rms_opacity")
4448 self.glo_link_child_property(
4449 "surface_opacity", child_id, "surface_opacity")
4450
4451
4452 if self.properties["color_method"]=="Color By Goodness of Fit":
4453 show_frac = float(self.properties["show_frac"] / 100.0)
4454 self.color_by_gof(show_frac)
4455 else:
4456 self.color_by_group()
4457
4458
4459
4461 print "==============================================="
4462 print "TEST CASE 1: TLS Class"
4463 print
4464
4465 tls = TLSGroup()
4466 tls.name = "All protein"
4467 tls.set_origin(18.885, 49.302, 13.315)
4468 tls.set_T(0.0263, 0.0561, 0.0048, -0.0128, 0.0065, -0.0157)
4469 tls.set_L(0.9730, 5.1496, 0.8488, 0.2151,-0.1296, 0.0815)
4470 tls.set_S(0.0007, 0.0281, 0.0336, -0.0446,-0.2288, -0.0551,
4471 0.0487, 0.0163)
4472
4473 print tls
4474
4475 print "eigenvalues(T)"
4476 print linalg.eigenvalues(tls.T)
4477 print "eigenvalues(L)"
4478 print linalg.eigenvalues(tls.L)
4479
4480 print "==============================================="
4481
4482 print
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505 if __name__ == "__main__":
4506 test_module()
4507
4508
4509