1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """PCS-based system tests."""
24
25
26
27 from os import sep
28 from re import search
29 from tempfile import mkdtemp, mkstemp
30
31
32 from data_store import Relax_data_store; ds = Relax_data_store()
33 from pipe_control.mol_res_spin import count_spins, spin_loop
34 from status import Status; status = Status()
35 from test_suite.system_tests.base_classes import SystemTestCase
36
37
38 -class Pcs(SystemTestCase):
39 """Class for testing PCS operations."""
40
42 """Test the operation of the pcs.corr_plot user function."""
43
44
45 self.interpreter.pipe.create('orig', 'N-state')
46
47
48 dir = status.install_path + sep+'test_suite'+sep+'shared_data'+sep+'align_data'+sep
49
50
51 self.interpreter.sequence.read(file='pcs.txt', dir=dir, spin_name_col=1)
52 self.interpreter.sequence.display()
53
54
55 self.interpreter.pcs.read(align_id='tb', file='pcs.txt', dir=dir, spin_name_col=1, data_col=2)
56 self.interpreter.sequence.display()
57
58
59 for spin in spin_loop():
60 if hasattr(spin, 'pcs'):
61 if not hasattr(spin, 'pcs_bc'):
62 spin.pcs_bc = {}
63 spin.pcs_bc['tb'] = spin.pcs['tb']
64 if spin.pcs_bc['tb'] != None:
65 spin.pcs_bc['tb'] += 1.0
66
67
68 ds.tmpfile_handle, ds.tmpfile = mkstemp(suffix='.agr')
69 self.interpreter.pcs.corr_plot(format='grace', title='Test', subtitle='Test2', file=ds.tmpfile, dir=None, force=True)
70
71
72 real_contents = [
73 "@version 50121",
74 "@page size 842, 595",
75 "@with g0",
76 "@ world 0.0, 0.0, 2.0, 2.0",
77 "@ view 0.15, 0.15, 1.28, 0.85",
78 "@ title \"Test\"",
79 "@ subtitle \"Test2\"",
80 "@ xaxis label \"Back-calculated PCS (ppm)\"",
81 "@ xaxis label char size 1.00",
82 "@ xaxis tick major 1",
83 "@ xaxis tick major size 0.50",
84 "@ xaxis tick major linewidth 0.5",
85 "@ xaxis tick minor ticks 9",
86 "@ xaxis tick minor linewidth 0.5",
87 "@ xaxis tick minor size 0.25",
88 "@ xaxis ticklabel char size 0.70",
89 "@ yaxis label \"Measured PCS (ppm)\"",
90 "@ yaxis label char size 1.00",
91 "@ yaxis tick major 1",
92 "@ yaxis tick major size 0.50",
93 "@ yaxis tick major linewidth 0.5",
94 "@ yaxis tick minor ticks 9",
95 "@ yaxis tick minor linewidth 0.5",
96 "@ yaxis tick minor size 0.25",
97 "@ yaxis ticklabel char size 0.70",
98 "@ legend on",
99 "@ legend 1, 0.5",
100 "@ legend box fill pattern 1",
101 "@ legend char size 1.0",
102 "@ frame linewidth 0.5",
103 "@ s0 symbol 1",
104 "@ s0 symbol size 0.45",
105 "@ s0 symbol linewidth 0.5",
106 "@ s0 errorbar size 0.5",
107 "@ s0 errorbar linewidth 0.5",
108 "@ s0 errorbar riser linewidth 0.5",
109 "@ s0 line linestyle 2",
110 "@ s1 symbol 2",
111 "@ s1 symbol size 0.45",
112 "@ s1 symbol linewidth 0.5",
113 "@ s1 errorbar size 0.5",
114 "@ s1 errorbar linewidth 0.5",
115 "@ s1 errorbar riser linewidth 0.5",
116 "@ s1 line linestyle 0",
117 "@ s1 legend \"tb (None)\"",
118 "@target G0.S0",
119 "@type xy",
120 " -100.000000000000000 -100.000000000000000 \"0\"",
121 " 100.000000000000000 100.000000000000000 \"0\"",
122 "&",
123 "@target G0.S1",
124 "@type xy",
125 " 1.004000000000000 0.004000000000000 \"@C1\"",
126 " 1.008000000000000 0.008000000000000 \"@C2\"",
127 " 1.021000000000000 0.021000000000000 \"@C3\"",
128 " 1.029000000000000 0.029000000000000 \"@C4\"",
129 " 1.016000000000000 0.016000000000000 \"@C5\"",
130 " 1.010000000000000 0.010000000000000 \"@C6\"",
131 " 1.008000000000000 0.008000000000000 \"@H1\"",
132 " 1.003000000000000 0.003000000000000 \"@H2\"",
133 " 1.006000000000000 0.006000000000000 \"@H3\"",
134 " 1.003000000000000 0.003000000000000 \"@H4\"",
135 " 1.007000000000000 0.007000000000000 \"@H5\"",
136 " 1.005000000000000 0.005000000000000 \"@H6\"",
137 " 1.001000000000000 0.001000000000000 \"@H7\"",
138 " 1.070000000000000 0.070000000000000 \"@C7\"",
139 " 1.025000000000000 0.025000000000000 \"@C9\"",
140 " 1.098000000000000 0.098000000000000 \"@C10\"",
141 " 1.054000000000000 0.054000000000000 \"@C11\"",
142 " 1.075000000000000 0.075000000000000 \"@C12\"",
143 " 1.065000000000000 0.065000000000000 \"@H12\"",
144 " 1.070000000000000 0.070000000000000 \"@H14\"",
145 " 1.015000000000000 0.015000000000000 \"@H15\"",
146 " 1.098000000000000 0.098000000000000 \"@H16\"",
147 " 1.060000000000000 0.060000000000000 \"@H17\"",
148 " 1.120000000000000 0.120000000000000 \"@H18\"",
149 "&"
150 ]
151
152
153 print("\nChecking the Grace file contents.")
154 file = open(ds.tmpfile)
155 lines = file.readlines()
156 file.close()
157 self.assertEqual(len(real_contents), len(lines))
158 for i in range(len(lines)):
159 print(lines[i][:-1])
160 self.assertEqual(real_contents[i], lines[i][:-1])
161
162
164 """Test the creation of Grace plots of PCS data."""
165
166
167 self.interpreter.pipe.create('CaM N-dom', 'N-state')
168
169
170 self.interpreter.spin.create(spin_name='N', spin_num=1, res_name='Gly', res_num=3)
171 self.interpreter.spin.create(spin_name='H', spin_num=2, res_name='Gly', res_num=3)
172 self.interpreter.spin.create(spin_name='N', spin_num=3, res_name='Gly', res_num=4)
173 self.interpreter.spin.create(spin_name='H', spin_num=4, res_name='Gly', res_num=4)
174 self.interpreter.sequence.display()
175
176
177 self.interpreter.spin.element(element='N', spin_id='@N')
178 self.interpreter.spin.element(element='H', spin_id='@H')
179
180
181 dir = status.install_path + sep+'test_suite'+sep+'shared_data'+sep+'align_data'+sep
182
183
184 self.interpreter.pcs.read(align_id='dy', file='pcs_dy_200911.txt', dir=dir, res_num_col=1, data_col=2, error_col=4, spin_id='@N')
185 self.interpreter.pcs.read(align_id='dy', file='pcs_dy_200911.txt', dir=dir, res_num_col=1, data_col=3, error_col=4, spin_id='@H')
186
187
188 for spin in spin_loop():
189 spin.pcs_bc = {}
190 spin.pcs_bc['dy'] = spin.pcs['dy'] + 0.1
191
192
193 self.tmpdir = mkdtemp()
194 self.interpreter.pcs.corr_plot(format='grace', file='pcs_corr.agr', dir=self.tmpdir, force=True)
195
196
197 file = open(self.tmpdir+sep+'pcs_corr.agr')
198 lines = file.readlines()
199 file.close()
200
201
202 for i in range(len(lines)):
203 if search('G0.S0', lines[i]):
204 point1 = lines[i+2].split()
205 point2 = lines[i+3].split()
206 self.assertAlmostEqual(float(point1[0]), -100.0)
207 self.assertAlmostEqual(float(point1[1]), -100.0)
208 self.assertAlmostEqual(float(point2[0]), 100.0)
209 self.assertAlmostEqual(float(point2[1]), 100.0)
210
211
212 for i in range(len(lines)):
213 if search('G0.S1', lines[i]):
214 point1 = lines[i+2].split()
215 point2 = lines[i+3].split()
216 self.assertAlmostEqual(float(point1[0]), 0.917+0.1)
217 self.assertAlmostEqual(float(point1[1]), 0.917)
218 self.assertAlmostEqual(float(point1[2]), 0.1)
219 self.assertAlmostEqual(float(point2[0]), 1.131+0.1)
220 self.assertAlmostEqual(float(point2[1]), 1.131)
221 self.assertAlmostEqual(float(point2[2]), 0.1)
222
223
224 for i in range(len(lines)):
225 if search('G0.S2', lines[i]):
226 point1 = lines[i+2].split()
227 point2 = lines[i+3].split()
228 self.assertAlmostEqual(float(point1[0]), 0.843+0.1)
229 self.assertAlmostEqual(float(point1[1]), 0.843)
230 self.assertAlmostEqual(float(point1[2]), 0.1)
231 self.assertAlmostEqual(float(point2[0]), 1.279+0.1)
232 self.assertAlmostEqual(float(point2[1]), 1.279)
233 self.assertAlmostEqual(float(point2[2]), 0.1)
234
235
237 """Test the loading of PCS data from a file with different columns for each spin type."""
238
239
240 self.interpreter.pipe.create('CaM N-dom', 'N-state')
241
242
243 self.interpreter.spin.create(spin_name='N', spin_num=1, res_name='Gly', res_num=3)
244 self.interpreter.spin.create(spin_name='H', spin_num=2, res_name='Gly', res_num=3)
245 self.interpreter.spin.create(spin_name='N', spin_num=3, res_name='Gly', res_num=4)
246 self.interpreter.spin.create(spin_name='H', spin_num=4, res_name='Gly', res_num=4)
247 self.interpreter.sequence.display()
248
249
250 dir = status.install_path + sep+'test_suite'+sep+'shared_data'+sep+'align_data'+sep
251
252
253 self.interpreter.pcs.read(align_id='dy', file='pcs_dy_200911.txt', dir=dir, res_num_col=1, data_col=2, error_col=4, spin_id='@N')
254 self.interpreter.pcs.read(align_id='dy', file='pcs_dy_200911.txt', dir=dir, res_num_col=1, data_col=3, error_col=4, spin_id='@H')
255
256
257 pcs_data = {
258 ':3@N': 0.917,
259 ':3@H': 0.843,
260 ':4@N': 1.131,
261 ':4@H': 1.279,
262 }
263
264
265 print("\n")
266 for spin, spin_id in spin_loop(return_id=True):
267 print("Checking the PCS data of spin '%s'." % spin_id)
268 self.assertTrue(hasattr(spin, 'pcs'))
269 self.assertEqual(spin.pcs['dy'], pcs_data[spin_id])
270 self.assertEqual(spin.pcs_err['dy'], 0.1)
271
272
274 """Test the loading of PCS data from a file with different columns for each spin type."""
275
276
277 self.interpreter.pipe.create('CaM N-dom', 'N-state')
278
279
280 self.interpreter.spin.create(spin_name='N', spin_num=1, res_name='Gly', res_num=3, mol_name='CaM')
281 self.interpreter.spin.create(spin_name='H', spin_num=2, res_name='Gly', res_num=3, mol_name='CaM')
282 self.interpreter.spin.create(spin_name='N', spin_num=3, res_name='Gly', res_num=4, mol_name='CaM')
283 self.interpreter.spin.create(spin_name='H', spin_num=4, res_name='Gly', res_num=4, mol_name='CaM')
284 self.interpreter.sequence.display()
285
286
287 dir = status.install_path + sep+'test_suite'+sep+'shared_data'+sep+'align_data'+sep
288
289
290 self.interpreter.pcs.read(align_id='dy', file='pcs_dy_200911.txt', dir=dir, res_num_col=1, data_col=2, error_col=4, spin_id='@N')
291 self.interpreter.pcs.read(align_id='dy', file='pcs_dy_200911.txt', dir=dir, res_num_col=1, data_col=3, error_col=4, spin_id='@H')
292
293
294 pcs_data = {
295 '#CaM:3@N': 0.917,
296 '#CaM:3@H': 0.843,
297 '#CaM:4@N': 1.131,
298 '#CaM:4@H': 1.279,
299 }
300
301
302 print("\n")
303 for spin, spin_id in spin_loop(return_id=True):
304 print("Checking the PCS data of spin '%s'." % spin_id)
305 self.assertTrue(hasattr(spin, 'pcs'))
306 self.assertEqual(spin.pcs['dy'], pcs_data[spin_id])
307 self.assertEqual(spin.pcs_err['dy'], 0.1)
308
309
311 """Test the operation of the pcs.copy user function."""
312
313
314 self.interpreter.pipe.create('orig', 'N-state')
315
316
317 dir = status.install_path + sep+'test_suite'+sep+'shared_data'+sep+'align_data'+sep
318
319
320 self.interpreter.sequence.read(file='pcs.txt', dir=dir, spin_name_col=1)
321 self.interpreter.sequence.display()
322
323
324 self.interpreter.pcs.read(align_id='tb', file='pcs.txt', dir=dir, spin_name_col=1, data_col=2)
325 self.interpreter.sequence.display()
326
327
328 pcs = [0.004, 0.008, 0.021, 0.029, 0.016, 0.010, 0.008, 0.003, 0.006, 0.003, 0.007, 0.005, 0.001, 0.070, None, 0.025, 0.098, 0.054, 0.075, 0.065, None, 0.070, 0.015, 0.098, 0.060, 0.120]
329
330
331 self.interpreter.pipe.copy(pipe_from='orig', pipe_to='new')
332 self.interpreter.pipe.switch(pipe_name='new')
333
334
335 self.interpreter.pcs.delete()
336
337
338 self.interpreter.pcs.copy(pipe_from='orig', align_id='tb')
339
340
341 self.assertTrue(hasattr(cdp, 'align_ids'))
342 self.assertTrue('tb' in cdp.align_ids)
343 self.assertTrue(hasattr(cdp, 'pcs_ids'))
344 self.assertTrue('tb' in cdp.pcs_ids)
345 self.assertEqual(count_spins(), 26)
346 self.assertEqual(len(cdp.interatomic), 0)
347 i = 0
348 for spin in spin_loop():
349 self.assertEqual(pcs[i], spin.pcs['tb'])
350 i += 1
351
352
354 """Test the operation of the pcs.copy user function for two data pipes with different spin system."""
355
356
357 dir = status.install_path + sep+'test_suite'+sep+'shared_data'+sep+'align_data'+sep
358
359
360 pipes = ['orig', 'new']
361 delete = ['@C2', '@H17']
362 for i in range(2):
363
364 self.interpreter.pipe.create(pipes[i], 'N-state')
365
366
367 self.interpreter.sequence.read(file='pcs.txt', dir=dir, spin_name_col=1)
368
369
370 self.interpreter.spin.delete(delete[i])
371 self.interpreter.sequence.display()
372
373
374 self.interpreter.pipe.switch('orig')
375 self.interpreter.pcs.read(align_id='tb', file='pcs.txt', dir=dir, spin_name_col=1, data_col=2)
376
377
378 self.interpreter.pcs.copy(pipe_from='orig', pipe_to='new', align_id='tb')
379
380
381 pcs = [
382 [0.004, 0.021, 0.029, 0.016, 0.010, 0.008, 0.003, 0.006, 0.003, 0.007, 0.005, 0.001, 0.070, None, 0.025, 0.098, 0.054, 0.075, 0.065, None, 0.070, 0.015, 0.098, 0.060, 0.120],
383 [0.004, 0.008, 0.021, 0.029, 0.016, 0.010, 0.008, 0.003, 0.006, 0.003, 0.007, 0.005, 0.001, 0.070, None, 0.025, 0.098, 0.054, 0.075, 0.065, None, 0.070, 0.015, 0.098, 0.120]
384 ]
385 for i in range(2):
386 print("\nChecking data pipe '%s'." % pipes[i])
387 self.assertTrue(hasattr(ds[pipes[i]], 'align_ids'))
388 self.assertTrue('tb' in ds[pipes[i]].align_ids)
389 self.assertTrue(hasattr(ds[pipes[i]], 'pcs_ids'))
390 self.assertTrue('tb' in ds[pipes[i]].pcs_ids)
391 self.assertEqual(count_spins(), 25)
392 self.assertEqual(len(cdp.interatomic), 0)
393 j = 0
394 for spin in spin_loop(pipe=pipes[i]):
395
396 if i == 1 and j == 1:
397 self.assertTrue(not hasattr(spin, 'pcs'))
398 else:
399 if pcs[i][j] == None:
400 self.assertEqual(pcs[i][j], spin.pcs['tb'])
401 else:
402 self.assertAlmostEqual(pcs[i][j], spin.pcs['tb'])
403 j += 1
404
405
407 """Test the operation of the pcs.copy user function for back-calculated values."""
408
409
410 dir = status.install_path + sep+'test_suite'+sep+'shared_data'+sep+'align_data'+sep
411
412
413 pipes = ['orig', 'new']
414 delete = ['@C2', '@H17']
415 for i in range(2):
416
417 self.interpreter.pipe.create(pipes[i], 'N-state')
418
419
420 self.interpreter.sequence.read(file='pcs.txt', dir=dir, spin_name_col=1)
421
422
423 self.interpreter.spin.delete(delete[i])
424 self.interpreter.sequence.display()
425
426
427 self.interpreter.pipe.switch('orig')
428 self.interpreter.pcs.read(align_id='tb', file='pcs.txt', dir=dir, spin_name_col=1, data_col=2)
429
430
431 for spin in spin_loop():
432 if hasattr(spin, 'pcs'):
433 if not hasattr(spin, 'pcs_bc'):
434 spin.pcs_bc = {}
435 spin.pcs_bc['tb'] = spin.pcs['tb']
436 if spin.pcs_bc['tb'] != None:
437 spin.pcs_bc['tb'] += 1.0
438
439
440 self.interpreter.pcs.copy(pipe_from='orig', pipe_to='new', align_id='tb', back_calc=True)
441
442
443 pcs = [
444 [0.004, 0.021, 0.029, 0.016, 0.010, 0.008, 0.003, 0.006, 0.003, 0.007, 0.005, 0.001, 0.070, None, 0.025, 0.098, 0.054, 0.075, 0.065, None, 0.070, 0.015, 0.098, 0.060, 0.120],
445 [0.004, 0.008, 0.021, 0.029, 0.016, 0.010, 0.008, 0.003, 0.006, 0.003, 0.007, 0.005, 0.001, 0.070, None, 0.025, 0.098, 0.054, 0.075, 0.065, None, 0.070, 0.015, 0.098, 0.120]
446 ]
447 for i in range(2):
448 print("\nChecking data pipe '%s'." % pipes[i])
449 self.assertTrue(hasattr(ds[pipes[i]], 'align_ids'))
450 self.assertTrue('tb' in ds[pipes[i]].align_ids)
451 self.assertTrue(hasattr(ds[pipes[i]], 'pcs_ids'))
452 self.assertTrue('tb' in ds[pipes[i]].pcs_ids)
453 self.assertEqual(count_spins(), 25)
454 self.assertEqual(len(cdp.interatomic), 0)
455 j = 0
456 for spin in spin_loop(pipe=pipes[i]):
457
458 if i == 1 and j == 1:
459 self.assertTrue(not hasattr(spin, 'pcs'))
460 else:
461 if pcs[i][j] == None:
462 self.assertEqual(None, spin.pcs['tb'])
463 self.assertEqual(None, spin.pcs_bc['tb'])
464 else:
465 self.assertAlmostEqual(pcs[i][j], spin.pcs['tb'])
466 self.assertAlmostEqual(pcs[i][j]+1.0, spin.pcs_bc['tb'])
467 j += 1
468
469
471 """Test for the loading of some PCS data with the spin ID format."""
472
473
474 self.interpreter.pipe.create('test', 'N-state')
475
476
477 dir = status.install_path + sep+'test_suite'+sep+'shared_data'+sep+'align_data'+sep
478
479
480 self.interpreter.sequence.read(file='pcs.txt', dir=dir, spin_name_col=1)
481 self.interpreter.sequence.display()
482
483
484 self.interpreter.pcs.read(align_id='tb', file='pcs.txt', dir=dir, spin_name_col=1, data_col=2)
485 self.interpreter.sequence.display()
486
487
488 pcs = [0.004, 0.008, 0.021, 0.029, 0.016, 0.010, 0.008, 0.003, 0.006, 0.003, 0.007, 0.005, 0.001, 0.070, None, 0.025, 0.098, 0.054, 0.075, 0.065, None, 0.070, 0.015, 0.098, 0.060, 0.120]
489
490
491 self.assertEqual(count_spins(), 26)
492 self.assertEqual(len(cdp.interatomic), 0)
493 i = 0
494 for spin in spin_loop():
495 self.assertEqual(pcs[i], spin.pcs['tb'])
496 i += 1
497
498
500 """Test the operation of the pcs.structural_noise user function."""
501
502
503 state = status.install_path + sep+'test_suite'+sep+'shared_data'+sep+'saved_states'+sep+'pcs_structural_noise_test.bz2'
504
505
506 self.interpreter.state.load(state)
507
508
509 self.interpreter.pcs.structural_noise(rmsd=200.0, sim_num=100, file='devnull', dir=None, force=True)
510 self.interpreter.pcs.structural_noise(rmsd=0.2, sim_num=20000, file='devnull', dir=None, force=True)
511
512
513 pcs_struct_err = {
514 'Dy N-dom': 0.0253,
515 'Er N-dom': 0.0081,
516 'Tm N-dom': 0.0181,
517 'Tb N-dom': 0.0280
518 }
519 pcs_err = {
520 'Dy N-dom': 0.1031,
521 'Er N-dom': 0.1001,
522 'Tm N-dom': 0.1016,
523 'Tb N-dom': 0.1038
524 }
525
526
527 spin = cdp.mol[0].res[0].spin[0]
528
529
530 for id in ['Dy N-dom', 'Tb N-dom', 'Tm N-dom', 'Er N-dom']:
531 self.assertAlmostEqual(spin.pcs_struct_err[id], pcs_struct_err[id], 2)
532 self.assertAlmostEqual(spin.pcs_err[id], pcs_err[id], 2)
533