1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 from copy import deepcopy
25 from math import pi
26 from numpy import float64, array, identity, transpose, zeros
27 from re import match, search
28 from string import replace, split
29 import sys
30 from warnings import warn
31
32
33 import arg_check
34 from data.diff_tensor import DiffTensorSimList
35 from float import isNaN, isInf
36 from generic_fns import diffusion_tensor, pipes, relax_data, sequence
37 from generic_fns.mol_res_spin import convert_from_global_index, count_spins, exists_mol_res_spin_data, find_index, return_spin, return_spin_from_index, spin_index_loop, spin_loop
38 from maths_fns.mf import Mf
39 from minfx.generic import generic_minimise
40 import specific_fns
41 from relax_errors import RelaxError, RelaxFuncSetupError, RelaxInfError, RelaxInvalidDataError, RelaxLenError, RelaxNaNError, RelaxNoModelError, RelaxNoPdbError, RelaxNoResError, RelaxNoSequenceError, RelaxNoSpinSpecError, RelaxNoTensorError, RelaxNoValueError, RelaxNoVectorsError, RelaxNucleusError, RelaxTensorError
42 from relax_warnings import RelaxDeselectWarning
43
44
45
47 """Class containing functions specific to model-free analysis."""
48
49 - def _are_mf_params_set(self, spin):
50 """Test if the model-free parameter values are set.
51
52 @param spin: The spin container object.
53 @type spin: SpinContainer instance
54 @return: The name of the first parameter in the parameter list in which the
55 corresponding parameter value is None. If all parameters are set, then None
56 is returned.
57 @rtype: str or None
58 """
59
60
61 if spin.select == 0:
62 return
63
64
65 for j in xrange(len(spin.params)):
66
67 if spin.params[j] == 'local_tm' and spin.local_tm == None:
68 return spin.params[j]
69
70
71 elif spin.params[j] == 's2' and spin.s2 == None:
72 return spin.params[j]
73
74
75 elif spin.params[j] == 's2f' and spin.s2f == None:
76 return spin.params[j]
77
78
79 elif spin.params[j] == 's2s' and spin.s2s == None:
80 return spin.params[j]
81
82
83 elif spin.params[j] == 'te' and spin.te == None:
84 return spin.params[j]
85
86
87 elif spin.params[j] == 'tf' and spin.tf == None:
88 return spin.params[j]
89
90
91 elif spin.params[j] == 'ts' and spin.ts == None:
92 return spin.params[j]
93
94
95 elif spin.params[j] == 'rex' and spin.rex == None:
96 return spin.params[j]
97
98
99 elif spin.params[j] == 'r' and spin.r == None:
100 return spin.params[j]
101
102
103 elif spin.params[j] == 'csa' and spin.csa == None:
104 return spin.params[j]
105
106
107 - def _assemble_param_names(self, model_type, spin_id=None):
108 """Function for assembling a list of all the model parameter names.
109
110 @param model_type: The model-free model type. This must be one of 'mf', 'local_tm',
111 'diff', or 'all'.
112 @type model_type: str
113 @param spin_id: The spin identification string.
114 @type spin_id: str
115 @return: A list containing all the parameters of the model-free model.
116 @rtype: list of str
117 """
118
119
120 param_names = []
121
122
123 if model_type == 'diff' or model_type == 'all':
124
125 if cdp.diff_tensor.type == 'sphere':
126 param_names.append('tm')
127
128
129 elif cdp.diff_tensor.type == 'spheroid':
130 param_names.append('tm')
131 param_names.append('Da')
132 param_names.append('theta')
133 param_names.append('phi')
134
135
136 elif cdp.diff_tensor.type == 'ellipsoid':
137 param_names.append('tm')
138 param_names.append('Da')
139 param_names.append('Dr')
140 param_names.append('alpha')
141 param_names.append('beta')
142 param_names.append('gamma')
143
144
145 if model_type != 'diff':
146
147 for spin in spin_loop(spin_id):
148
149 if not spin.select:
150 continue
151
152
153 param_names = param_names + spin.params
154
155
156 return param_names
157
158
159 - def _assemble_param_vector(self, spin=None, spin_id=None, sim_index=None, model_type=None):
160 """Assemble the model-free parameter vector (as numpy array).
161
162 If the spin argument is supplied, then the spin_id argument will be ignored.
163
164 @keyword spin: The spin data container.
165 @type spin: SpinContainer instance
166 @keyword spin_id: The spin identification string.
167 @type spin_id: str
168 @keyword sim_index: The optional MC simulation index.
169 @type sim_index: int
170 @keyword model_type: The optional model type, one of 'all', 'diff', 'mf', or 'local_tm'.
171 @type model_type: str or None
172 @return: An array of the parameter values of the model-free model.
173 @rtype: numpy array
174 """
175
176
177 param_vector = []
178
179
180 if not model_type:
181 model_type = self._determine_model_type()
182
183
184 if model_type == 'diff' or model_type == 'all':
185
186 if sim_index == None:
187
188 if cdp.diff_tensor.type == 'sphere':
189 param_vector.append(cdp.diff_tensor.tm)
190
191
192 elif cdp.diff_tensor.type == 'spheroid':
193 param_vector.append(cdp.diff_tensor.tm)
194 param_vector.append(cdp.diff_tensor.Da)
195 param_vector.append(cdp.diff_tensor.theta)
196 param_vector.append(cdp.diff_tensor.phi)
197
198
199 elif cdp.diff_tensor.type == 'ellipsoid':
200 param_vector.append(cdp.diff_tensor.tm)
201 param_vector.append(cdp.diff_tensor.Da)
202 param_vector.append(cdp.diff_tensor.Dr)
203 param_vector.append(cdp.diff_tensor.alpha)
204 param_vector.append(cdp.diff_tensor.beta)
205 param_vector.append(cdp.diff_tensor.gamma)
206
207
208 else:
209
210 if cdp.diff_tensor.type == 'sphere':
211 param_vector.append(cdp.diff_tensor.tm_sim[sim_index])
212
213
214 elif cdp.diff_tensor.type == 'spheroid':
215 param_vector.append(cdp.diff_tensor.tm_sim[sim_index])
216 param_vector.append(cdp.diff_tensor.Da_sim[sim_index])
217 param_vector.append(cdp.diff_tensor.theta_sim[sim_index])
218 param_vector.append(cdp.diff_tensor.phi_sim[sim_index])
219
220
221 elif cdp.diff_tensor.type == 'ellipsoid':
222 param_vector.append(cdp.diff_tensor.tm_sim[sim_index])
223 param_vector.append(cdp.diff_tensor.Da_sim[sim_index])
224 param_vector.append(cdp.diff_tensor.Dr_sim[sim_index])
225 param_vector.append(cdp.diff_tensor.alpha_sim[sim_index])
226 param_vector.append(cdp.diff_tensor.beta_sim[sim_index])
227 param_vector.append(cdp.diff_tensor.gamma_sim[sim_index])
228
229
230 if model_type != 'diff':
231
232 if spin:
233 loop = [spin]
234 else:
235 loop = spin_loop(spin_id)
236
237
238 for spin in loop:
239
240 if not spin.select:
241 continue
242
243
244 for i in xrange(len(spin.params)):
245
246 if spin.params[i] == 'local_tm':
247 if sim_index == None:
248 param_vector.append(spin.local_tm)
249 else:
250 param_vector.append(spin.local_tm_sim[sim_index])
251
252
253 elif spin.params[i] == 's2':
254 if sim_index == None:
255 param_vector.append(spin.s2)
256 else:
257 param_vector.append(spin.s2_sim[sim_index])
258
259
260 elif spin.params[i] == 's2f':
261 if sim_index == None:
262 param_vector.append(spin.s2f)
263 else:
264 param_vector.append(spin.s2f_sim[sim_index])
265
266
267 elif spin.params[i] == 's2s':
268 if sim_index == None:
269 param_vector.append(spin.s2s)
270 else:
271 param_vector.append(spin.s2s_sim[sim_index])
272
273
274 elif spin.params[i] == 'te':
275 if sim_index == None:
276 param_vector.append(spin.te)
277 else:
278 param_vector.append(spin.te_sim[sim_index])
279
280
281 elif spin.params[i] == 'tf':
282 if sim_index == None:
283 param_vector.append(spin.tf)
284 else:
285 param_vector.append(spin.tf_sim[sim_index])
286
287
288 elif spin.params[i] == 'ts':
289 if sim_index == None:
290 param_vector.append(spin.ts)
291 else:
292 param_vector.append(spin.ts_sim[sim_index])
293
294
295 elif spin.params[i] == 'rex':
296 if sim_index == None:
297 param_vector.append(spin.rex)
298 else:
299 param_vector.append(spin.rex_sim[sim_index])
300
301
302 elif spin.params[i] == 'r':
303 if sim_index == None:
304 param_vector.append(spin.r)
305 else:
306 param_vector.append(spin.r_sim[sim_index])
307
308
309 elif spin.params[i] == 'csa':
310 if sim_index == None:
311 param_vector.append(spin.csa)
312 else:
313 param_vector.append(spin.csa_sim[sim_index])
314
315
316 else:
317 raise RelaxError("Unknown parameter.")
318
319
320 for i in xrange(len(param_vector)):
321 if param_vector[i] == None:
322 param_vector[i] = 0.0
323
324
325 return array(param_vector, float64)
326
327
328 - def _assemble_scaling_matrix(self, num_params, model_type=None, spin=None, spin_id=None, scaling=True):
329 """Create and return the scaling matrix.
330
331 If the spin argument is supplied, then the spin_id argument will be ignored.
332
333 @param num_params: The number of parameters in the model.
334 @type num_params: int
335 @keyword model_type: The model type, one of 'all', 'diff', 'mf', or 'local_tm'.
336 @type model_type: str
337 @keyword spin: The spin data container.
338 @type spin: SpinContainer instance
339 @keyword spin_id: The spin identification string.
340 @type spin_id: str
341 @return: The diagonal and square scaling matrix.
342 @rtype: numpy diagonal matrix
343 """
344
345
346 if num_params == 0:
347 scaling_matrix = zeros((0, 0), float64)
348 else:
349 scaling_matrix = identity(num_params, float64)
350 i = 0
351
352
353 if not scaling:
354 return scaling_matrix
355
356
357 ti_scaling = 1e-12
358
359
360 if model_type == 'diff' or model_type == 'all':
361
362 if cdp.diff_tensor.type == 'sphere':
363
364 scaling_matrix[i, i] = ti_scaling
365
366
367 i = i + 1
368
369
370 elif cdp.diff_tensor.type == 'spheroid':
371
372 scaling_matrix[i, i] = ti_scaling
373 scaling_matrix[i+1, i+1] = 1e7
374 scaling_matrix[i+2, i+2] = 1.0
375 scaling_matrix[i+3, i+3] = 1.0
376
377
378 i = i + 4
379
380
381 elif cdp.diff_tensor.type == 'ellipsoid':
382
383 scaling_matrix[i, i] = ti_scaling
384 scaling_matrix[i+1, i+1] = 1e7
385 scaling_matrix[i+2, i+2] = 1.0
386 scaling_matrix[i+3, i+3] = 1.0
387 scaling_matrix[i+4, i+4] = 1.0
388 scaling_matrix[i+5, i+5] = 1.0
389
390
391 i = i + 6
392
393
394 if model_type != 'diff':
395
396 if spin:
397 loop = [spin]
398 else:
399 loop = spin_loop(spin_id)
400
401
402 for spin in loop:
403
404 if not spin.select:
405 continue
406
407
408 for k in xrange(len(spin.params)):
409
410 if spin.params[k] == 'local_tm' or search('^t', spin.params[k]):
411 scaling_matrix[i, i] = ti_scaling
412
413
414 elif spin.params[k] == 'rex':
415 scaling_matrix[i, i] = 1.0 / (2.0 * pi * cdp.frq[cdp.ri_ids[0]]) ** 2
416
417
418 elif spin.params[k] == 'r':
419 scaling_matrix[i, i] = 1e-10
420
421
422 elif spin.params[k] == 'csa':
423 scaling_matrix[i, i] = 1e-4
424
425
426 i = i + 1
427
428
429 return scaling_matrix
430
431
432 - def back_calc_ri(self, spin_index=None, ri_id=None, ri_type=None, frq=None):
433 """Back-calculation of relaxation data from the model-free parameter values.
434
435 @keyword spin_index: The global spin index.
436 @type spin_index: int
437 @keyword ri_id: The relaxation data ID string.
438 @type ri_id: str
439 @keyword ri_type: The relaxation data type.
440 @type ri_type: str
441 @keyword frq: The field strength.
442 @type frq: float
443 @return: The back calculated relaxation data value corresponding to the index.
444 @rtype: float
445 """
446
447
448 spin, spin_id = return_spin_from_index(global_index=spin_index, return_spin_id=True)
449
450
451 if hasattr(cdp, 'diff_tensor') and (cdp.diff_tensor.type == 'spheroid' or cdp.diff_tensor.type == 'ellipsoid') and (not hasattr(spin, 'xh_vect') or spin.xh_vect == None):
452 warn(RelaxDeselectWarning(spin_id, 'missing structural data'))
453 return
454
455
456 value = self.minimise(min_algor='back_calc', min_options=(spin_index, ri_id, ri_type, frq))
457
458
459 return value
460
461
462 - def _compare_objects(self, object_from, object_to, pipe_from, pipe_to):
463 """Compare the contents of the two objects and raise RelaxErrors if they are not the same.
464
465 @param object_from: The first object.
466 @type object_from: any object
467 @param object_to: The second object.
468 @type object_to: any object
469 @param pipe_from: The name of the data pipe containing the first object.
470 @type pipe_from: str
471 @param pipe_to: The name of the data pipe containing the second object.
472 @type pipe_to: str
473 """
474
475
476 for data_name in dir(object_from):
477
478 if search('^_', data_name) or data_name in list(object_from.__class__.__dict__.keys()) or (hasattr(object_from.__class__, '__bases__') and len(object_from.__class__.__bases__) and data_name in list(object_from.__class__.__bases__[0].__dict__.keys())):
479 continue
480
481
482 if data_name in ['structural_data']:
483 continue
484
485
486 data_from = None
487 if hasattr(object_from, data_name):
488 data_from = getattr(object_from, data_name)
489
490
491 if data_from and not hasattr(object_to, data_name):
492 raise RelaxError("The structural object " + repr(data_name) + " of the " + repr(pipe_from) + " data pipe is not located in the " + repr(pipe_to) + " data pipe.")
493 elif data_from:
494 data_to = getattr(object_to, data_name)
495 else:
496 continue
497
498
499 if data_from != data_to:
500 raise RelaxError("The object " + repr(data_name) + " is not consistent between the pipes " + repr(pipe_from) + " and " + repr(pipe_to) + ".")
501
502
504 """Calculate and return the Rex conversion factor.
505
506 @return: The Rex conversion factor.
507 @rtype: float
508 """
509
510
511 return 1.0 / (2.0 * pi * cdp.frq[cdp.ri_ids[0]])**2
512
513
514 - def _create_model(self, model=None, equation=None, params=None, spin_id=None):
515 """Function for creating a custom model-free model.
516
517 @param model: The name of the model.
518 @type model: str
519 @param equation: The equation type to use. The 3 allowed types are: 'mf_orig' for the original model-free equations with parameters {s2, te}; 'mf_ext' for the extended model-free equations with parameters {s2f, tf, s2, ts}; and 'mf_ext2' for the extended model-free equations with parameters {s2f, tf, s2s, ts}.
520 @type equation: str
521 @param params: A list of the parameters to include in the model. The allowed parameter names includes those for the equation type as well as chemical exchange 'rex', the bond length 'r', and the chemical shift anisotropy 'csa'.
522 @type params: list of str
523 @param spin_id: The spin identification string.
524 @type spin_id: str
525 """
526
527
528 pipes.test()
529
530
531 function_type = pipes.get_type()
532 if function_type != 'mf':
533 raise RelaxFuncSetupError(specific_fns.get_string(function_type))
534
535
536 if not exists_mol_res_spin_data():
537 raise RelaxNoSequenceError
538
539
540 valid_types = ['mf_orig', 'mf_ext', 'mf_ext2']
541 if not equation in valid_types:
542 raise RelaxError("The model-free equation type argument " + repr(equation) + " is invalid and should be one of " + repr(valid_types) + ".")
543
544
545 s2, te, s2f, tf, s2s, ts, rex, csa, r = 0, 0, 0, 0, 0, 0, 0, 0, 0
546 for i in xrange(len(params)):
547
548 invalid_param = 0
549
550
551 if params[i] == 's2':
552
553 if s2:
554 invalid_param = 1
555 s2 = 1
556
557
558 s2s_flag = 0
559 for j in xrange(len(params)):
560 if params[j] == 's2s':
561 s2s_flag = 1
562 if s2s_flag:
563 invalid_param = 1
564
565
566 elif params[i] == 'te':
567
568 if equation == 'mf_ext' or te:
569 invalid_param = 1
570 te = 1
571
572
573 s2_flag = 0
574 for j in xrange(len(params)):
575 if params[j] == 's2':
576 s2_flag = 1
577 if not s2_flag:
578 invalid_param = 1
579
580
581 elif params[i] == 's2f':
582
583 if equation == 'mf_orig' or s2f:
584 invalid_param = 1
585 s2f = 1
586
587
588 elif params[i] == 's2s':
589
590 if equation == 'mf_orig' or s2s:
591 invalid_param = 1
592 s2s = 1
593
594
595 elif params[i] == 'tf':
596
597 if equation == 'mf_orig' or tf:
598 invalid_param = 1
599 tf = 1
600
601
602 s2f_flag = 0
603 for j in xrange(len(params)):
604 if params[j] == 's2f':
605 s2f_flag = 1
606 if not s2f_flag:
607 invalid_param = 1
608
609
610 elif params[i] == 'ts':
611
612 if equation == 'mf_orig' or ts:
613 invalid_param = 1
614 ts = 1
615
616
617 flag = 0
618 for j in xrange(len(params)):
619 if params[j] == 's2' or params[j] == 's2f':
620 flag = 1
621 if not flag:
622 invalid_param = 1
623
624
625 elif params[i] == 'rex':
626 if rex:
627 invalid_param = 1
628 rex = 1
629
630
631 elif params[i] == 'r':
632 if r:
633 invalid_param = 1
634 r = 1
635
636
637 elif params[i] == 'csa':
638 if csa:
639 invalid_param = 1
640 csa = 1
641
642
643 else:
644 raise RelaxError("The parameter " + params[i] + " is not supported.")
645
646
647 if invalid_param:
648 raise RelaxError("The parameter array " + repr(params) + " contains an invalid combination of parameters.")
649
650
651 self._model_setup(model, equation, params, spin_id)
652
653
655 """Delete all the model-free data."""
656
657
658 pipes.test()
659
660
661 function_type = pipes.get_type()
662 if function_type != 'mf':
663 raise RelaxFuncSetupError(specific_fns.setup.get_string(function_type))
664
665
666 if not exists_mol_res_spin_data():
667 raise RelaxNoSequenceError
668
669
670 names = self.data_names()
671
672
673 for spin in spin_loop():
674
675 for name in names:
676
677 if not hasattr(spin, name):
678 continue
679
680
681 delattr(spin, name)
682
683
685 """Determine the global model type.
686
687 @return: The name of the model type, which will be one of 'all', 'diff', 'mf', or 'local_tm'. If all parameters are fixed (and no spins selected), None is returned.
688 @rtype: str or None
689 """
690
691
692 if not exists_mol_res_spin_data():
693 raise RelaxNoSequenceError
694
695
696 local_tm = False
697 for spin in spin_loop():
698
699 if not hasattr(spin, 'params') or not spin.params:
700 continue
701
702
703 if not local_tm and 'local_tm' in spin.params:
704 local_tm = True
705
706
707 elif local_tm and not 'local_tm' in spin.params:
708 raise RelaxError("All residues must either have a local tm parameter or not.")
709
710
711 mf_all_fixed = True
712 mf_all_deselected = True
713 for spin in spin_loop():
714
715 if not spin.select:
716 continue
717
718
719 mf_all_deselected = False
720
721
722 if not hasattr(spin, 'fixed'):
723 mf_all_fixed = False
724 break
725 if not spin.fixed:
726 mf_all_fixed = False
727 break
728
729
730 if mf_all_deselected:
731
732 if not hasattr(cdp, 'diff_tensor') or cdp.diff_tensor.fixed:
733 return None
734
735 return 'diff'
736
737
738 if local_tm:
739 return 'local_tm'
740
741
742 if not diffusion_tensor.diff_data_exists():
743
744 for spin in spin_loop():
745 if hasattr(spin, 'local_tm') and spin.local_tm != None and not 'local_tm' in spin.params:
746 raise RelaxError("The local tm value is set but not located in the model parameter list.")
747
748
749 raise RelaxNoTensorError('diffusion')
750
751
752 if mf_all_fixed:
753
754 if cdp.diff_tensor.fixed:
755 return None
756
757 return 'diff'
758
759
760 if cdp.diff_tensor.fixed:
761 return 'mf'
762
763
764 else:
765 return 'all'
766
767
768 - def _model_map(self, model):
769 """Return the equation name and parameter list corresponding to the given model.
770
771 @param model: The model-free model.
772 @type model: str
773 @return: The equation type (either 'mf_orig' or 'mf_ext') and the model-free parameter list corresponding to the model.
774 @rtype: str, list
775 """
776
777
778 if model == 'm0':
779 equation = 'mf_orig'
780 params = []
781 elif model == 'm1':
782 equation = 'mf_orig'
783 params = ['s2']
784 elif model == 'm2':
785 equation = 'mf_orig'
786 params = ['s2', 'te']
787 elif model == 'm3':
788 equation = 'mf_orig'
789 params = ['s2', 'rex']
790 elif model == 'm4':
791 equation = 'mf_orig'
792 params = ['s2', 'te', 'rex']
793 elif model == 'm5':
794 equation = 'mf_ext'
795 params = ['s2f', 's2', 'ts']
796 elif model == 'm6':
797 equation = 'mf_ext'
798 params = ['s2f', 'tf', 's2', 'ts']
799 elif model == 'm7':
800 equation = 'mf_ext'
801 params = ['s2f', 's2', 'ts', 'rex']
802 elif model == 'm8':
803 equation = 'mf_ext'
804 params = ['s2f', 'tf', 's2', 'ts', 'rex']
805 elif model == 'm9':
806 equation = 'mf_orig'
807 params = ['rex']
808
809
810 elif model == 'm10':
811 equation = 'mf_orig'
812 params = ['csa']
813 elif model == 'm11':
814 equation = 'mf_orig'
815 params = ['csa', 's2']
816 elif model == 'm12':
817 equation = 'mf_orig'
818 params = ['csa', 's2', 'te']
819 elif model == 'm13':
820 equation = 'mf_orig'
821 params = ['csa', 's2', 'rex']
822 elif model == 'm14':
823 equation = 'mf_orig'
824 params = ['csa', 's2', 'te', 'rex']
825 elif model == 'm15':
826 equation = 'mf_ext'
827 params = ['csa', 's2f', 's2', 'ts']
828 elif model == 'm16':
829 equation = 'mf_ext'
830 params = ['csa', 's2f', 'tf', 's2', 'ts']
831 elif model == 'm17':
832 equation = 'mf_ext'
833 params = ['csa', 's2f', 's2', 'ts', 'rex']
834 elif model == 'm18':
835 equation = 'mf_ext'
836 params = ['csa', 's2f', 'tf', 's2', 'ts', 'rex']
837 elif model == 'm19':
838 equation = 'mf_orig'
839 params = ['csa', 'rex']
840
841
842 elif model == 'm20':
843 equation = 'mf_orig'
844 params = ['r']
845 elif model == 'm21':
846 equation = 'mf_orig'
847 params = ['r', 's2']
848 elif model == 'm22':
849 equation = 'mf_orig'
850 params = ['r', 's2', 'te']
851 elif model == 'm23':
852 equation = 'mf_orig'
853 params = ['r', 's2', 'rex']
854 elif model == 'm24':
855 equation = 'mf_orig'
856 params = ['r', 's2', 'te', 'rex']
857 elif model == 'm25':
858 equation = 'mf_ext'
859 params = ['r', 's2f', 's2', 'ts']
860 elif model == 'm26':
861 equation = 'mf_ext'
862 params = ['r', 's2f', 'tf', 's2', 'ts']
863 elif model == 'm27':
864 equation = 'mf_ext'
865 params = ['r', 's2f', 's2', 'ts', 'rex']
866 elif model == 'm28':
867 equation = 'mf_ext'
868 params = ['r', 's2f', 'tf', 's2', 'ts', 'rex']
869 elif model == 'm29':
870 equation = 'mf_orig'
871 params = ['r', 'rex']
872
873
874 elif model == 'm30':
875 equation = 'mf_orig'
876 params = ['r', 'csa']
877 elif model == 'm31':
878 equation = 'mf_orig'
879 params = ['r', 'csa', 's2']
880 elif model == 'm32':
881 equation = 'mf_orig'
882 params = ['r', 'csa', 's2', 'te']
883 elif model == 'm33':
884 equation = 'mf_orig'
885 params = ['r', 'csa', 's2', 'rex']
886 elif model == 'm34':
887 equation = 'mf_orig'
888 params = ['r', 'csa', 's2', 'te', 'rex']
889 elif model == 'm35':
890 equation = 'mf_ext'
891 params = ['r', 'csa', 's2f', 's2', 'ts']
892 elif model == 'm36':
893 equation = 'mf_ext'
894 params = ['r', 'csa', 's2f', 'tf', 's2', 'ts']
895 elif model == 'm37':
896 equation = 'mf_ext'
897 params = ['r', 'csa', 's2f', 's2', 'ts', 'rex']
898 elif model == 'm38':
899 equation = 'mf_ext'
900 params = ['r', 'csa', 's2f', 'tf', 's2', 'ts', 'rex']
901 elif model == 'm39':
902 equation = 'mf_orig'
903 params = ['r', 'csa', 'rex']
904
905
906
907
908
909
910 elif model == 'tm0':
911 equation = 'mf_orig'
912 params = ['local_tm']
913 elif model == 'tm1':
914 equation = 'mf_orig'
915 params = ['local_tm', 's2']
916 elif model == 'tm2':
917 equation = 'mf_orig'
918 params = ['local_tm', 's2', 'te']
919 elif model == 'tm3':
920 equation = 'mf_orig'
921 params = ['local_tm', 's2', 'rex']
922 elif model == 'tm4':
923 equation = 'mf_orig'
924 params = ['local_tm', 's2', 'te', 'rex']
925 elif model == 'tm5':
926 equation = 'mf_ext'
927 params = ['local_tm', 's2f', 's2', 'ts']
928 elif model == 'tm6':
929 equation = 'mf_ext'
930 params = ['local_tm', 's2f', 'tf', 's2', 'ts']
931 elif model == 'tm7':
932 equation = 'mf_ext'
933 params = ['local_tm', 's2f', 's2', 'ts', 'rex']
934 elif model == 'tm8':
935 equation = 'mf_ext'
936 params = ['local_tm', 's2f', 'tf', 's2', 'ts', 'rex']
937 elif model == 'tm9':
938 equation = 'mf_orig'
939 params = ['local_tm', 'rex']
940
941
942 elif model == 'tm10':
943 equation = 'mf_orig'
944 params = ['local_tm', 'csa']
945 elif model == 'tm11':
946 equation = 'mf_orig'
947 params = ['local_tm', 'csa', 's2']
948 elif model == 'tm12':
949 equation = 'mf_orig'
950 params = ['local_tm', 'csa', 's2', 'te']
951 elif model == 'tm13':
952 equation = 'mf_orig'
953 params = ['local_tm', 'csa', 's2', 'rex']
954 elif model == 'tm14':
955 equation = 'mf_orig'
956 params = ['local_tm', 'csa', 's2', 'te', 'rex']
957 elif model == 'tm15':
958 equation = 'mf_ext'
959 params = ['local_tm', 'csa', 's2f', 's2', 'ts']
960 elif model == 'tm16':
961 equation = 'mf_ext'
962 params = ['local_tm', 'csa', 's2f', 'tf', 's2', 'ts']
963 elif model == 'tm17':
964 equation = 'mf_ext'
965 params = ['local_tm', 'csa', 's2f', 's2', 'ts', 'rex']
966 elif model == 'tm18':
967 equation = 'mf_ext'
968 params = ['local_tm', 'csa', 's2f', 'tf', 's2', 'ts', 'rex']
969 elif model == 'tm19':
970 equation = 'mf_orig'
971 params = ['local_tm', 'csa', 'rex']
972
973
974 elif model == 'tm20':
975 equation = 'mf_orig'
976 params = ['local_tm', 'r']
977 elif model == 'tm21':
978 equation = 'mf_orig'
979 params = ['local_tm', 'r', 's2']
980 elif model == 'tm22':
981 equation = 'mf_orig'
982 params = ['local_tm', 'r', 's2', 'te']
983 elif model == 'tm23':
984 equation = 'mf_orig'
985 params = ['local_tm', 'r', 's2', 'rex']
986 elif model == 'tm24':
987 equation = 'mf_orig'
988 params = ['local_tm', 'r', 's2', 'te', 'rex']
989 elif model == 'tm25':
990 equation = 'mf_ext'
991 params = ['local_tm', 'r', 's2f', 's2', 'ts']
992 elif model == 'tm26':
993 equation = 'mf_ext'
994 params = ['local_tm', 'r', 's2f', 'tf', 's2', 'ts']
995 elif model == 'tm27':
996 equation = 'mf_ext'
997 params = ['local_tm', 'r', 's2f', 's2', 'ts', 'rex']
998 elif model == 'tm28':
999 equation = 'mf_ext'
1000 params = ['local_tm', 'r', 's2f', 'tf', 's2', 'ts', 'rex']
1001 elif model == 'tm29':
1002 equation = 'mf_orig'
1003 params = ['local_tm', 'r', 'rex']
1004
1005
1006 elif model == 'tm30':
1007 equation = 'mf_orig'
1008 params = ['local_tm', 'r', 'csa']
1009 elif model == 'tm31':
1010 equation = 'mf_orig'
1011 params = ['local_tm', 'r', 'csa', 's2']
1012 elif model == 'tm32':
1013 equation = 'mf_orig'
1014 params = ['local_tm', 'r', 'csa', 's2', 'te']
1015 elif model == 'tm33':
1016 equation = 'mf_orig'
1017 params = ['local_tm', 'r', 'csa', 's2', 'rex']
1018 elif model == 'tm34':
1019 equation = 'mf_orig'
1020 params = ['local_tm', 'r', 'csa', 's2', 'te', 'rex']
1021 elif model == 'tm35':
1022 equation = 'mf_ext'
1023 params = ['local_tm', 'r', 'csa', 's2f', 's2', 'ts']
1024 elif model == 'tm36':
1025 equation = 'mf_ext'
1026 params = ['local_tm', 'r', 'csa', 's2f', 'tf', 's2', 'ts']
1027 elif model == 'tm37':
1028 equation = 'mf_ext'
1029 params = ['local_tm', 'r', 'csa', 's2f', 's2', 'ts', 'rex']
1030 elif model == 'tm38':
1031 equation = 'mf_ext'
1032 params = ['local_tm', 'r', 'csa', 's2f', 'tf', 's2', 'ts', 'rex']
1033 elif model == 'tm39':
1034 equation = 'mf_orig'
1035 params = ['local_tm', 'r', 'csa', 'rex']
1036
1037
1038 else:
1039 raise RelaxError("The model '%s' is invalid." % model)
1040
1041
1042 return equation, params
1043
1044
1045 - def _model_setup(self, model=None, equation=None, params=None, spin_id=None):
1046 """Function for updating various data structures depending on the model selected.
1047
1048 @param model: The name of the model.
1049 @type model: str
1050 @param equation: The equation type to use. The 3 allowed types are: 'mf_orig' for the original model-free equations with parameters {s2, te}; 'mf_ext' for the extended model-free equations with parameters {s2f, tf, s2, ts}; and 'mf_ext2' for the extended model-free equations with parameters {s2f, tf, s2s, ts}.
1051 @type equation: str
1052 @param params: A list of the parameters to include in the model. The allowed parameter names includes those for the equation type as well as chemical exchange 'rex', the bond length 'r', and the chemical shift anisotropy 'csa'.
1053 @type params: list of str
1054 @param spin_id: The spin identification string.
1055 @type spin_id: str
1056 """
1057
1058
1059 if params:
1060 for param in params:
1061 if param == 'local_tm' and hasattr(pipes.get_pipe(), 'diff_tensor'):
1062 raise RelaxTensorError('diffusion')
1063
1064
1065 for spin in spin_loop(spin_id):
1066
1067 self.data_init(spin)
1068
1069
1070 spin.model = model
1071 spin.equation = equation
1072 spin.params = params
1073
1074
1075 - def _remove_tm(self, spin_id=None):
1076 """Remove local tm from the set of model-free parameters for the given spins.
1077
1078 @param spin_id: The spin identification string.
1079 @type spin_id: str or None
1080 """
1081
1082
1083 pipes.test()
1084
1085
1086 function_type = pipes.get_type()
1087 if function_type != 'mf':
1088 raise RelaxFuncSetupError(specific_fns.get_string(function_type))
1089
1090
1091 if not exists_mol_res_spin_data():
1092 raise RelaxNoSequenceError
1093
1094
1095 for spin in spin_loop(spin_id):
1096
1097 if not spin.select:
1098 continue
1099
1100
1101 if not hasattr(spin, 'params') or not 'local_tm' in spin.params:
1102 continue
1103
1104
1105 spin.params.remove('local_tm')
1106
1107
1108 if match('^tm', spin.model):
1109 spin.model = spin.model[1:]
1110
1111
1112 del spin.local_tm
1113
1114
1115 spin.chi2 = None
1116 spin.iter = None
1117 spin.f_count = None
1118 spin.g_count = None
1119 spin.h_count = None
1120 spin.warning = None
1121
1122
1123 cdp.chi2 = None
1124 cdp.iter = None
1125 cdp.f_count = None
1126 cdp.g_count = None
1127 cdp.h_count = None
1128 cdp.warning = None
1129
1130
1131 - def _select_model(self, model=None, spin_id=None):
1132 """Function for the selection of a preset model-free model.
1133
1134 @param model: The name of the model.
1135 @type model: str
1136 @param spin_id: The spin identification string.
1137 @type spin_id: str
1138 """
1139
1140
1141 pipes.test()
1142
1143
1144 function_type = pipes.get_type()
1145 if function_type != 'mf':
1146 raise RelaxFuncSetupError(specific_fns.get_string(function_type))
1147
1148
1149 if not exists_mol_res_spin_data():
1150 raise RelaxNoSequenceError
1151
1152
1153 equation, params = self._model_map(model)
1154
1155
1156 self._model_setup(model, equation, params, spin_id)
1157
1158
1159 - def _units_rex(self):
1160 """Return the units for the Rex parameter.
1161
1162 @return: The field strength dependent Rex units.
1163 @rtype: str
1164 """
1165
1166
1167 if not hasattr(cdp, 'frq_labels') or len(cdp.frq_labels) == 0:
1168 return ''
1169
1170
1171 return cdp.frq_labels[0] + ' MHz'
1172
1173
1174 - def create_mc_data(self, data_id=None):
1175 """Create the Monte Carlo Ri data.
1176
1177 @keyword data_id: The spin identification string, as yielded by the base_data_loop() generator method.
1178 @type data_id: str
1179 @return: The Monte Carlo simulation data.
1180 @rtype: list of floats
1181 """
1182
1183
1184 mc_data = []
1185
1186
1187 spin = return_spin(data_id)
1188 global_index = find_index(data_id)
1189
1190
1191 if not spin.select:
1192 return
1193
1194
1195 if not hasattr(spin, 'model') or not spin.model:
1196 raise RelaxNoModelError
1197
1198
1199 for ri_id in cdp.ri_ids:
1200
1201 value = self.back_calc_ri(spin_index=global_index, ri_id=ri_id, ri_type=cdp.ri_type[ri_id], frq=cdp.frq[ri_id])
1202
1203
1204 mc_data.append(value)
1205
1206
1207 return mc_data
1208
1209
1210 - def data_init(self, data_cont, sim=False):
1211 """Initialise the spin specific data structures.
1212
1213 @param data_cont: The spin data container.
1214 @type data_cont: SpinContainer instance
1215 @keyword sim: The Monte Carlo simulation flag, which if true will initialise the simulation data structure.
1216 @type sim: bool
1217 """
1218
1219
1220 data_names = self.data_names()
1221
1222
1223 for name in data_names:
1224
1225 if name in ['ri_data', 'ri_data_bc', 'ri_data_err']:
1226 continue
1227
1228
1229 list_data = [ 'params' ]
1230 if name in list_data:
1231 init_data = []
1232
1233
1234 init_data = None
1235
1236
1237 if not hasattr(data_cont, name):
1238 setattr(data_cont, name, init_data)
1239
1240
1241 - def data_names(self, set='all', error_names=False, sim_names=False):
1242 """Return a list of all spin container specific model-free object names.
1243
1244 Description
1245 ===========
1246
1247 The names are as follows:
1248
1249 - 'model', the model-free model name.
1250 - 'equation', the model-free equation type.
1251 - 'params', an array of the model-free parameter names associated with the model.
1252 - 's2', S2.
1253 - 's2f', S2f.
1254 - 's2s', S2s.
1255 - 'local_tm', local tm.
1256 - 'te', te.
1257 - 'tf', tf.
1258 - 'ts', ts.
1259 - 'rex', Rex.
1260 - 'r', bond length.
1261 - 'csa', CSA value.
1262 - 'nucleus', the heteronucleus type.
1263 - 'chi2', chi-squared value.
1264 - 'iter', iterations.
1265 - 'f_count', function count.
1266 - 'g_count', gradient count.
1267 - 'h_count', hessian count.
1268 - 'warning', minimisation warning.
1269
1270
1271 @keyword set: The set of object names to return. This can be set to 'all' for all
1272 names, to 'generic' for generic object names, 'params' for
1273 model-free parameter names, or to 'min' for minimisation specific
1274 object names.
1275 @type set: str
1276 @keyword error_names: A flag which if True will add the error object names as well.
1277 @type error_names: bool
1278 @keyword sim_names: A flag which if True will add the Monte Carlo simulation object
1279 names as well.
1280 @type sim_names: bool
1281 @return: The list of object names.
1282 @rtype: list of str
1283 """
1284
1285
1286 names = []
1287
1288
1289 if set == 'all' or set == 'generic':
1290 names.append('select')
1291 names.append('fixed')
1292 names.append('proton_type')
1293 names.append('heteronuc_type')
1294 names.append('attached_proton')
1295 names.append('nucleus')
1296 names.append('model')
1297 names.append('equation')
1298 names.append('params')
1299 names.append('xh_vect')
1300
1301
1302 if set == 'all' or set == 'params':
1303 names.append('s2')
1304 names.append('s2f')
1305 names.append('s2s')
1306 names.append('local_tm')
1307 names.append('te')
1308 names.append('tf')
1309 names.append('ts')
1310 names.append('rex')
1311 names.append('r')
1312 names.append('csa')
1313
1314
1315 if set == 'all' or set == 'min':
1316 names.append('chi2')
1317 names.append('iter')
1318 names.append('f_count')
1319 names.append('g_count')
1320 names.append('h_count')
1321 names.append('warning')
1322
1323
1324 if set == 'all':
1325 names = names + relax_data.get_data_names()
1326
1327
1328 if error_names and (set == 'all' or set == 'params'):
1329 names.append('s2_err')
1330 names.append('s2f_err')
1331 names.append('s2s_err')
1332 names.append('local_tm_err')
1333 names.append('te_err')
1334 names.append('tf_err')
1335 names.append('ts_err')
1336 names.append('rex_err')
1337 names.append('r_err')
1338 names.append('csa_err')
1339
1340
1341 if sim_names and (set == 'all' or set == 'params'):
1342 names.append('s2_sim')
1343 names.append('s2f_sim')
1344 names.append('s2s_sim')
1345 names.append('local_tm_sim')
1346 names.append('te_sim')
1347 names.append('tf_sim')
1348 names.append('ts_sim')
1349 names.append('rex_sim')
1350 names.append('r_sim')
1351 names.append('csa_sim')
1352
1353
1354 if sim_names and set == 'all':
1355 names = names + relax_data.get_data_names(sim_names=True)
1356
1357
1358 return names
1359
1360
1361 - def data_type(self, param=None):
1362 """Return the type of data, as a string, that the parameter should be.
1363
1364 @keyword param: The parameter name.
1365 @type param: list of str
1366 @return: The type of the parameter, as a string. I.e. 'int', 'float', 'str', 'bool', 'list of str', 'dict of bool', etc.
1367 @rtype: str
1368 """
1369
1370
1371 types = {
1372 'select': bool,
1373 'fixed': bool,
1374 'proton_type': str,
1375 'heteronuc_type': str,
1376 'attached_proton': str,
1377 'nucleus': str,
1378 'model': str,
1379 'equation': str,
1380 'params': [str],
1381 'xh_vect': [float],
1382 's2': float,
1383 's2f': float,
1384 's2s': float,
1385 'local_tm': float,
1386 'te': float,
1387 'tf': float,
1388 'ts': float,
1389 'rex': float,
1390 'r': float,
1391 'csa': float,
1392 'chi2': float,
1393 'iter': int,
1394 'f_count': int,
1395 'g_count': int,
1396 'h_count': int,
1397 'warning': str
1398 }
1399
1400
1401 if types.has_key(param):
1402 return types[param]
1403
1404
1405 default_value_doc = ["Model-free default values", """
1406 _______________________________________________________________________________________
1407 | | | |
1408 | Data type | Object name | Value |
1409 |_______________________________________|____________________|________________________|
1410 | | | |
1411 | Local tm | 'local_tm' | 10 * 1e-9 |
1412 | | | |
1413 | Order parameters S2, S2f, and S2s | 's2', 's2f', 's2s' | 0.8 |
1414 | | | |
1415 | Correlation time te | 'te' | 100 * 1e-12 |
1416 | | | |
1417 | Correlation time tf | 'tf' | 10 * 1e-12 |
1418 | | | |
1419 | Correlation time ts | 'ts' | 1000 * 1e-12 |
1420 | | | |
1421 | Chemical exchange relaxation | 'rex' | 0.0 |
1422 | | | |
1423 | Bond length | 'r' | 1.02 * 1e-10 |
1424 | | | |
1425 | CSA | 'csa' | -172 * 1e-6 |
1426 | | | |
1427 | Heteronucleus type | 'heteronuc_type' | '15N' |
1428 | | | |
1429 | Proton type | 'proton_type' | '1H' |
1430 |_______________________________________|____________________|________________________|
1431
1432 """]
1433
1434 - def default_value(self, param):
1435 """The default model-free parameter values.
1436
1437 @param param: The model-free parameter.
1438 @type param: str
1439 @return: The default value.
1440 @rtype: float
1441 """
1442
1443
1444 diff_val = diffusion_tensor.default_value(param)
1445 if diff_val != None:
1446 return diff_val
1447
1448
1449 return self.SPIN_PARAMS.get_default(param)
1450
1451
1452 - def deselect(self, model_info, sim_index=None):
1453 """Deselect models or simulations.
1454
1455 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices).
1456 @type model_info: int
1457 @keyword sim_index: The optional Monte Carlo simulation index. If None, then models will be deselected, otherwise the given simulation will.
1458 @type sim_index: None or int
1459 """
1460
1461
1462 model_type = self._determine_model_type()
1463
1464
1465 if model_type == 'mf' or model_type == 'local_tm':
1466
1467 spin = return_spin_from_index(model_info)
1468
1469
1470 if sim_index == None:
1471 spin.select = False
1472
1473
1474 else:
1475 spin.select_sim[sim_index] = False
1476
1477
1478 else:
1479
1480 if sim_index == None:
1481 raise RelaxError("Cannot deselect the global model.")
1482
1483
1484 else:
1485
1486 cdp.select_sim[sim_index] = False
1487
1488
1489 - def duplicate_data(self, pipe_from=None, pipe_to=None, model_info=None, global_stats=False, verbose=True):
1490 """Duplicate the data specific to a single model-free model.
1491
1492 @keyword pipe_from: The data pipe to copy the data from.
1493 @type pipe_from: str
1494 @keyword pipe_to: The data pipe to copy the data to.
1495 @type pipe_to: str
1496 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices).
1497 @type model_info: int
1498 @keyword global_stats: The global statistics flag.
1499 @type global_stats: bool
1500 @keyword verbose: A flag which if True will cause info about each spin to be printed out as the sequence is generated.
1501 @type verbose: bool
1502 """
1503
1504
1505 if model_info == None:
1506 raise RelaxError("The model_info argument cannot be None.")
1507
1508
1509 if not pipes.has_pipe(pipe_to):
1510 pipes.create(pipe_to, pipe_type='mf', switch=False)
1511
1512
1513 dp_from = pipes.get_pipe(pipe_from)
1514 dp_to = pipes.get_pipe(pipe_to)
1515
1516
1517 for data_name in dir(dp_from):
1518
1519 if data_name in ['diff_tensor', 'mol', 'structure']:
1520 continue
1521
1522
1523 if search('^_', data_name) or data_name in list(dp_from.__class__.__dict__.keys()):
1524 continue
1525
1526
1527 data_from = getattr(dp_from, data_name)
1528
1529
1530 if hasattr(dp_to, data_name):
1531
1532 data_to = getattr(dp_to, data_name)
1533
1534
1535 if data_from != data_to:
1536 raise RelaxError("The object " + repr(data_name) + " is not consistent between the pipes " + repr(pipe_from) + " and " + repr(pipe_to) + ".")
1537
1538
1539 continue
1540
1541
1542 setattr(dp_to, data_name, deepcopy(data_from))
1543
1544
1545 if hasattr(dp_from, 'diff_tensor'):
1546
1547 if not hasattr(dp_to, 'diff_tensor'):
1548 setattr(dp_to, 'diff_tensor', deepcopy(dp_from.diff_tensor))
1549
1550
1551 else:
1552
1553 for data_name in dp_from.diff_tensor.__mod_attr__:
1554
1555 data_from = None
1556 if hasattr(dp_from.diff_tensor, data_name):
1557 data_from = getattr(dp_from.diff_tensor, data_name)
1558
1559
1560 if data_from and not hasattr(dp_to.diff_tensor, data_name):
1561 raise RelaxError("The diffusion tensor object " + repr(data_name) + " of the " + repr(pipe_from) + " data pipe is not located in the " + repr(pipe_to) + " data pipe.")
1562 elif data_from:
1563 data_to = getattr(dp_to.diff_tensor, data_name)
1564 else:
1565 continue
1566
1567
1568 if data_from != data_to:
1569 raise RelaxError("The object " + repr(data_name) + " is not consistent between the pipes " + repr(pipe_from) + " and " + repr(pipe_to) + ".")
1570
1571
1572 if hasattr(dp_from, 'structure'):
1573
1574 if not hasattr(dp_to, 'structure'):
1575 setattr(dp_to, 'structure', deepcopy(dp_from.structure))
1576
1577
1578 else:
1579
1580 self._compare_objects(dp_from.structure, dp_to.structure, pipe_from, pipe_to)
1581
1582
1583 if len(dp_from.structure.structural_data) != len(dp_from.structure.structural_data):
1584 raise RelaxError("The number of structural models is not consistent between the pipes " + repr(pipe_from) + " and " + repr(pipe_to) + ".")
1585
1586
1587 for i in range(len(dp_from.structure.structural_data)):
1588
1589 model_from = dp_from.structure.structural_data[i]
1590 model_to = dp_to.structure.structural_data[i]
1591
1592
1593 if model_from.num != model_to.num:
1594 raise RelaxError("The structure models are not consistent between the pipes " + repr(pipe_from) + " and " + repr(pipe_to) + ".")
1595
1596
1597 if len(model_from.mol) != len(model_to.mol):
1598 raise RelaxError("The number of molecules is not consistent between the pipes " + repr(pipe_from) + " and " + repr(pipe_to) + ".")
1599
1600
1601 for mol_index in range(len(model_from.mol)):
1602
1603 self._compare_objects(model_from.mol[mol_index], model_to.mol[mol_index], pipe_from, pipe_to)
1604
1605
1606 if dp_from.mol.is_empty():
1607 return
1608
1609
1610 if dp_to.mol.is_empty():
1611 sequence.copy(pipe_from=pipe_from, pipe_to=pipe_to, preserve_select=True, verbose=verbose)
1612
1613
1614 pipes.switch(pipe_from)
1615 model_type = self._determine_model_type()
1616
1617
1618 if model_type == 'mf' or (model_type == 'local_tm' and not global_stats):
1619
1620 mol_index, res_index, spin_index = convert_from_global_index(global_index=model_info, pipe=pipe_from)
1621
1622
1623 dp_to.mol[mol_index].res[res_index].spin[spin_index] = deepcopy(dp_from.mol[mol_index].res[res_index].spin[spin_index])
1624
1625
1626 else:
1627
1628 dp_to.mol = deepcopy(dp_from.mol)
1629
1630
1631 eliminate_doc = [["Local tm model elimination rule", """
1632 The local tm, in some cases, may exceed the value expected for a global correlation time. Generally the tm value will be stuck at the upper limit defined for the parameter. These models are eliminated using the rule:
1633
1634 tm >= c
1635
1636 The default value of c is 50 ns, although this can be overridden by supplying the value (in seconds) as the first element of the args tuple.
1637 """],
1638 ["Internal correlation times {te, tf, ts} model elimination rules", """
1639 These parameters may experience the same problem as the local tm in that the model fails and the parameter value is stuck at the upper limit. These parameters are constrained using the formula (te, tf, ts <= 2tm). These failed models are eliminated using the rule:
1640
1641 te, tf, ts >= c . tm
1642
1643 The default value of c is 1.5. Because of round-off errors and the constraint algorithm, setting c to 2 will result in no models being eliminated as the minimised parameters will always be less than 2tm. The value can be changed by supplying the value as the second element of the tuple.
1644 """],
1645 ["Arguments", """
1646 The 'args' argument must be a tuple of length 2, the elements of which must be numbers. For example, to eliminate models which have a local tm value greater than 25 ns and models with internal correlation times greater than 1.5 times tm, set 'args' to (25 * 1e-9, 1.5).
1647 """]]
1648
1649 - def eliminate(self, name, value, model_info, args, sim=None):
1650 """Model-free model elimination, parameter by parameter.
1651
1652 @param name: The parameter name.
1653 @type name: str
1654 @param value: The parameter value.
1655 @type value: float
1656 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices).
1657 @type model_info: int
1658 @param args: The c1 and c2 elimination constant overrides.
1659 @type args: None or tuple of float
1660 @keyword sim: The Monte Carlo simulation index.
1661 @type sim: int
1662 @return: True if the model is to be eliminated, False otherwise.
1663 @rtype: bool
1664 """
1665
1666
1667 c1 = 50.0 * 1e-9
1668 c2 = 1.5
1669
1670
1671 if args != None:
1672 c1, c2 = args
1673
1674
1675 model_type = self._determine_model_type()
1676
1677
1678 if model_type != 'mf' and model_type != 'local_tm':
1679 raise RelaxError("Elimination of the global model is not yet supported.")
1680
1681
1682 spin, spin_id = return_spin_from_index(model_info, return_spin_id=True)
1683
1684
1685 if model_type == 'local_tm':
1686 tm = spin.local_tm
1687 else:
1688 tm = cdp.diff_tensor.tm
1689
1690
1691 if tm == None:
1692 return False
1693
1694
1695 if name == 'local_tm' and value >= c1:
1696 if sim == None:
1697 print(("Data pipe '%s': The local tm parameter of %.5g is greater than %.5g, eliminating spin system '%s'." % (pipes.cdp_name(), value, c1, spin_id)))
1698 else:
1699 print(("Data pipe '%s': The local tm parameter of %.5g is greater than %.5g, eliminating simulation %i of spin system '%s'." % (pipes.cdp_name(), value, c1, sim, spin_id)))
1700 return True
1701
1702
1703 if match('t[efs]', name) and value >= c2 * tm:
1704 if sim == None:
1705 print(("Data pipe '%s': The %s value of %.5g is greater than %.5g, eliminating spin system '%s'." % (pipes.cdp_name(), name, value, c2*tm, spin_id)))
1706 else:
1707 print(("Data pipe '%s': The %s value of %.5g is greater than %.5g, eliminating simulation %i of spin system '%s'." % (pipes.cdp_name(), name, value, c2*tm, sim, spin_id)))
1708 return True
1709
1710
1711 return False
1712
1713
1714 - def get_param_names(self, model_info=None):
1715 """Return a vector of parameter names.
1716
1717 @keyword model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices).
1718 @type model_info: int
1719 @return: The vector of parameter names.
1720 @rtype: list of str
1721 """
1722
1723
1724 model_type = self._determine_model_type()
1725
1726
1727 if model_type == 'mf' or model_type == 'local_tm':
1728
1729 spin, spin_id = return_spin_from_index(model_info, return_spin_id=True)
1730 else:
1731 spin_id = None
1732
1733
1734 return self._assemble_param_names(model_type, spin_id=spin_id)
1735
1736
1737 - def get_param_values(self, model_info=None, sim_index=None):
1738 """Return a vector of parameter values.
1739
1740 @keyword model_info: The model index from model_info(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices).
1741 @type model_info: int
1742 @keyword sim_index: The Monte Carlo simulation index.
1743 @type sim_index: int
1744 @return: The vector of parameter values.
1745 @rtype: list of str
1746 """
1747
1748
1749 for spin in spin_loop():
1750
1751 if not spin.select:
1752 continue
1753
1754
1755 if not spin.model:
1756 raise RelaxNoModelError
1757
1758
1759 model_type = self._determine_model_type()
1760
1761
1762 if model_type == 'mf' or model_type == 'local_tm':
1763 spin = return_spin_from_index(model_info)
1764 else:
1765 spin = None
1766
1767
1768 return self._assemble_param_vector(spin=spin, sim_index=sim_index, model_type=model_type)
1769
1770
1771 - def is_spin_param(self, name):
1772 """Determine whether the given parameter is spin specific.
1773
1774 Unless a diffusion parameter is encountered, this method will return true.
1775
1776 @param name: The name of the parameter.
1777 @type name: str
1778 @return: If the parameter is a diffusion parameter, False I returned. Otherwise True
1779 is returned.
1780 @rtype: bool
1781 """
1782
1783
1784 if diffusion_tensor.return_data_name(name):
1785 return False
1786
1787
1788 else:
1789 return True
1790
1791
1792 - def map_bounds(self, param, spin_id=None):
1793 """Create bounds for the OpenDX mapping function.
1794
1795 @param param: The name of the parameter to return the lower and upper bounds of.
1796 @type param: str
1797 @param spin_id: The spin identification string.
1798 @type spin_id: str
1799 @return: The upper and lower bounds of the parameter.
1800 @rtype: list of float
1801 """
1802
1803
1804 spin = return_spin(spin_id)
1805
1806
1807 if search('^s2', param):
1808 return [0.0, 1.0]
1809
1810
1811 elif search('^t', param) or param == 'local_tm':
1812 return [0.0, 1e-8]
1813
1814
1815 elif param == 'rex':
1816 return [0.0, 30.0 / (2.0 * pi * cdp.frq[cdp.ri_ids[0]])**2]
1817
1818
1819 elif param == 'r':
1820 return [1.0 * 1e-10, 1.1 * 1e-10]
1821
1822
1823 elif param == 'csa':
1824 return [-100 * 1e-6, -300 * 1e-6]
1825
1826
1827 - def model_desc(self, model_info):
1828 """Return a description of the model.
1829
1830 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices).
1831 @type model_info: int
1832 @return: The model description.
1833 @rtype: str
1834 """
1835
1836
1837 model_type = self._determine_model_type()
1838
1839
1840 if model_type == 'all':
1841 return "Global model - all diffusion tensor parameters and spin specific model-free parameters."
1842 elif model_type == 'diff':
1843 return "Diffusion tensor model."
1844
1845
1846 else:
1847
1848 spin, spin_id = return_spin_from_index(model_info, return_spin_id=True)
1849
1850
1851 return "Model-free model of spin '%s'." % spin_id
1852
1853
1854 - def model_loop(self):
1855 """Generator method for looping over the models (global or local).
1856
1857 If the model type is 'all' or 'diff', then this yields the single value of zero. Otherwise
1858 the global spin index is yielded.
1859
1860
1861 @return: The model index. This is zero for the global models or equal to the global spin
1862 index (which covers the molecule, residue, and spin indices).
1863 @rtype: int
1864 """
1865
1866
1867 model_type = self._determine_model_type()
1868
1869
1870 if model_type == 'all' or model_type == 'diff':
1871 yield 0
1872
1873
1874 else:
1875
1876 global_index = -1
1877 for spin in spin_loop():
1878
1879 global_index = global_index + 1
1880
1881
1882 yield global_index
1883
1884
1885 - def model_statistics(self, model_info=None, spin_id=None, global_stats=None):
1886 """Return the k, n, and chi2 model statistics.
1887
1888 k - number of parameters.
1889 n - number of data points.
1890 chi2 - the chi-squared value.
1891
1892
1893 @keyword model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices).
1894 @type model_info: int
1895 @keyword spin_id: The spin identification string. Either this or the instance keyword argument must be supplied.
1896 @type spin_id: None or str
1897 @keyword global_stats: A parameter which determines if global or local statistics are returned. If None, then the appropriateness of global or local statistics is automatically determined.
1898 @type global_stats: None or bool
1899 @return: The optimisation statistics, in tuple format, of the number of parameters (k), the number of data points (n), and the chi-squared value (chi2).
1900 @rtype: tuple of (int, int, float)
1901 """
1902
1903
1904 if model_info == None and spin_id == None:
1905 raise RelaxError("Either the model_info or spin_id argument must be supplied.")
1906 elif model_info != None and spin_id != None:
1907 raise RelaxError("The model_info arg " + repr(model_info) + " and spin_id arg " + repr(spin_id) + " clash. Only one should be supplied.")
1908
1909
1910 model_type = self._determine_model_type()
1911
1912
1913 if global_stats == None:
1914 if model_type in ['mf', 'local_tm']:
1915 global_stats = False
1916 else:
1917 global_stats = True
1918
1919
1920 if not global_stats:
1921
1922 if spin_id:
1923 spin = return_spin(spin_id)
1924 else:
1925 spin = return_spin_from_index(model_info)
1926
1927
1928 if not spin.select:
1929 return None, None, None
1930
1931
1932 if not hasattr(spin, 'ri_data'):
1933 return None, None, None
1934
1935
1936 param_vector = self._assemble_param_vector(spin=spin)
1937 k = len(param_vector)
1938
1939
1940 n = len(spin.ri_data)
1941
1942
1943 chi2 = spin.chi2
1944
1945
1946 elif global_stats:
1947
1948 param_vector = self._assemble_param_vector()
1949 k = len(param_vector)
1950
1951
1952 n = 0
1953 chi2 = 0
1954 for spin in spin_loop():
1955
1956 if not spin.select:
1957 continue
1958
1959
1960 if not hasattr(spin, 'ri_data') or not len(spin.ri_data):
1961 continue
1962
1963 n = n + len(spin.ri_data)
1964
1965
1966 if model_type == 'local_tm':
1967 chi2 = chi2 + spin.chi2
1968
1969
1970 if model_type != 'local_tm':
1971 if not hasattr(cdp, 'chi2'):
1972 raise RelaxError("Global statistics are not available, most likely because the global model has not been optimised.")
1973 chi2 = cdp.chi2
1974
1975
1976 return k, n, chi2
1977
1978
1979 - def model_type(self):
1980 """Return the type of the model, either being 'local' or 'global'.
1981
1982 @return: The model type, one of 'local' or 'global'.
1983 @rtype: str
1984 """
1985
1986
1987 model_type = self._determine_model_type()
1988
1989
1990 if model_type in ['all', 'diff']:
1991 return 'global'
1992
1993
1994 else:
1995 return 'local'
1996
1997
1998 - def num_instances(self):
1999 """Function for returning the number of instances.
2000
2001 @return: The number of instances used for optimisation. Either the number of spins if
2002 the local optimisations are setup ('mf' and 'local_tm'), or 1 for the global
2003 models.
2004 @rtype: int
2005 """
2006
2007
2008 if not exists_mol_res_spin_data():
2009 return 0
2010
2011
2012 model_type = self._determine_model_type()
2013
2014
2015 if model_type == 'mf' or model_type == 'local_tm':
2016 return count_spins()
2017
2018
2019 elif model_type == 'diff' or model_type == 'all':
2020 return 1
2021
2022
2023 else:
2024 raise RelaxFault
2025
2026
2027 - def overfit_deselect(self):
2028 """Deselect spins which have insufficient data to support minimisation."""
2029
2030
2031 print("\n\nOver-fit spin deselection.\n")
2032
2033
2034 if not exists_mol_res_spin_data():
2035 raise RelaxNoSequenceError
2036
2037
2038 need_vect = False
2039 if hasattr(cdp, 'diff_tensor') and (cdp.diff_tensor.type == 'spheroid' or cdp.diff_tensor.type == 'ellipsoid'):
2040 need_vect = True
2041
2042
2043 for spin, spin_id in spin_loop(return_id=True):
2044
2045 if not spin.select:
2046 continue
2047
2048
2049 data_points = 0
2050 if hasattr(cdp, 'ri_ids') and hasattr(spin, 'ri_data'):
2051 for id in cdp.ri_ids:
2052 if spin.ri_data.has_key(id) and spin.ri_data[id] != None:
2053 data_points += 1
2054
2055
2056 if not hasattr(spin, 'ri_data'):
2057 warn(RelaxDeselectWarning(spin_id, 'missing relaxation data'))
2058 spin.select = False
2059
2060
2061 elif data_points < 3:
2062 warn(RelaxDeselectWarning(spin_id, 'insufficient relaxation data, 3 or more data points are required'))
2063 spin.select = False
2064
2065
2066 elif hasattr(spin, 'params') and spin.params and len(spin.params) > data_points:
2067 warn(RelaxDeselectWarning(spin_id, 'over-fitting - more parameters than data points'))
2068 spin.select = False
2069
2070
2071 elif need_vect and not hasattr(spin, 'xh_vect'):
2072 warn(RelaxDeselectWarning(spin_id, 'missing structural data'))
2073 spin.select = False
2074 elif need_vect and spin.xh_vect == None:
2075 warn(RelaxDeselectWarning(spin_id, 'missing structural data'))
2076 spin.select = False
2077
2078
2079 - def return_data_desc(self, name):
2080 """Return a description of the spin specific object.
2081
2082 @param name: The name of the spin specific object.
2083 @type name: str
2084 @return: The object description, or None.
2085 @rtype: str or None
2086 """
2087
2088
2089 if self.SPIN_PARAMS.contains(name):
2090 return self.SPIN_PARAMS.get_desc(name)
2091
2092
2093 return relax_data.return_data_desc(name)
2094
2095
2096 return_data_name_doc = ["Model-free data type string matching patterns", """
2097 _____________________________________________
2098 | | |
2099 | Data type | Object name |
2100 |________________________|__________________|
2101 | | |
2102 | Local tm | 'local_tm' |
2103 | | |
2104 | Order parameter S2 | 's2' |
2105 | | |
2106 | Order parameter S2f | 's2f' |
2107 | | |
2108 | Order parameter S2s | 's2s' |
2109 | | |
2110 | Correlation time te | 'te' |
2111 | | |
2112 | Correlation time tf | 'tf' |
2113 | | |
2114 | Correlation time ts | 'ts' |
2115 | | |
2116 | Chemical exchange | 'rex' |
2117 | | |
2118 | Bond length | 'r' |
2119 | | |
2120 | CSA | 'csa' |
2121 | | |
2122 | Heteronucleus type | 'heteronuc_type' |
2123 | | |
2124 | Proton type | 'proton_type' |
2125 |________________________|__________________|
2126
2127 """]
2128
2129 - def return_data_name(self, param):
2130 """Return a unique identifying string for the model-free parameter.
2131
2132 @param param: The model-free parameter name.
2133 @type param: str
2134 @return: The unique parameter identifying string.
2135 @rtype: str
2136 """
2137
2138
2139 diff_obj = diffusion_tensor.return_data_name(param)
2140 if diff_obj:
2141 return param
2142
2143
2144 if self.SPIN_PARAMS.contains(param):
2145 return param
2146
2147
2148 set_doc = ["Model-free set details", """
2149 Setting a parameter value may have no effect depending on which model-free model is chosen, for example if S2f values and S2s values are set but the run corresponds to model-free model 'm4' then, because these data values are not parameters of the model, they will have no effect.
2150
2151 Note that the Rex values are scaled quadratically with field strength and should be supplied as a field strength independent value. Use the following formula to get the correct value:
2152
2153 value = rex / (2.0 * pi * frequency) ** 2
2154
2155 where:
2156 rex is the chemical exchange value for the current frequency.
2157 pi is in the namespace of relax, ie just type 'pi'.
2158 frequency is the proton frequency corresponding to the data.
2159 """]
2160
2161
2162 - def set_error(self, model_info, index, error):
2163 """Set the parameter errors.
2164
2165 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices).
2166 @type model_info: int
2167 @param index: The index of the parameter to set the errors for.
2168 @type index: int
2169 @param error: The error value.
2170 @type error: float
2171 """
2172
2173
2174 inc = 0
2175
2176
2177 model_type = self._determine_model_type()
2178
2179
2180 param_names = self.data_names(set='params')
2181
2182
2183
2184
2185
2186 if model_type == 'diff' or model_type == 'all':
2187
2188 if cdp.diff_tensor.type == 'sphere':
2189
2190 if index == 0:
2191 cdp.diff_tensor.tm_err = error
2192
2193
2194 inc = inc + 1
2195
2196
2197 elif cdp.diff_tensor.type == 'spheroid':
2198
2199 if index == 0:
2200 cdp.diff_tensor.tm_err = error
2201 elif index == 1:
2202 cdp.diff_tensor.Da_err = error
2203 elif index == 2:
2204 cdp.diff_tensor.theta_err = error
2205 elif index == 3:
2206 cdp.diff_tensor.phi_err = error
2207
2208
2209 inc = inc + 4
2210
2211
2212 elif cdp.diff_tensor.type == 'ellipsoid':
2213
2214 if index == 0:
2215 cdp.diff_tensor.tm_err = error
2216 elif index == 1:
2217 cdp.diff_tensor.Da_err = error
2218 elif index == 2:
2219 cdp.diff_tensor.Dr_err = error
2220 elif index == 3:
2221 cdp.diff_tensor.alpha_err = error
2222 elif index == 4:
2223 cdp.diff_tensor.beta_err = error
2224 elif index == 5:
2225 cdp.diff_tensor.gamma_err = error
2226
2227
2228 inc = inc + 6
2229
2230
2231
2232
2233
2234 if model_type == 'all':
2235
2236 for spin in spin_loop():
2237
2238 if not spin.select:
2239 continue
2240
2241
2242 for param in param_names:
2243
2244 if index == inc:
2245 setattr(spin, param + "_err", error)
2246
2247
2248 inc = inc + 1
2249
2250
2251
2252
2253
2254 if model_type == 'mf' or model_type == 'local_tm':
2255
2256 spin = return_spin_from_index(model_info)
2257
2258
2259 if not spin.select:
2260 return
2261
2262
2263 for param in param_names:
2264
2265 if index == inc:
2266 setattr(spin, param + "_err", error)
2267
2268
2269 inc = inc + 1
2270
2271
2272 - def set_param_values(self, param=None, value=None, spin_id=None, force=True):
2273 """Set the model-free parameter values.
2274
2275 @keyword param: The parameter name list.
2276 @type param: list of str
2277 @keyword value: The parameter value list.
2278 @type value: list
2279 @keyword spin_id: The spin identification string, only used for spin specific parameters.
2280 @type spin_id: None or str
2281 @keyword force: A flag which if True will cause current values to be overwritten. If False, a RelaxError will raised if the parameter value is already set.
2282 @type force: bool
2283 """
2284
2285
2286 arg_check.is_str_list(param, 'parameter name')
2287
2288
2289 diff_params = []
2290 diff_vals = []
2291 mf_params = []
2292 mf_vals = []
2293 for i in range(len(param)):
2294
2295 diff_obj = diffusion_tensor.return_data_name(param[i])
2296 if diff_obj:
2297 diff_params.append(param[i])
2298 diff_vals.append(value[i])
2299
2300
2301 else:
2302 mf_params.append(param[i])
2303 mf_vals.append(value[i])
2304
2305
2306 if diff_params:
2307 diffusion_tensor.set(value=diff_vals, param=diff_params)
2308
2309
2310 for i in range(len(mf_params)):
2311
2312 obj_name = self.return_data_name(mf_params[i])
2313
2314
2315 if obj_name not in self.data_names(set='params') and obj_name not in self.data_names(set='generic'):
2316 raise RelaxError("The parameter '%s' is unknown. It should be one of %s or %s" % (mf_params[i], self.data_names(set='params'), self.data_names(set='generic')))
2317
2318
2319 for spin in spin_loop(spin_id):
2320 setattr(spin, obj_name, mf_vals[i])
2321
2322
2323 - def set_selected_sim(self, model_info, select_sim):
2324 """Set all simulation selection flags.
2325
2326 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices).
2327 @type model_info: int
2328 @param select_sim: The selection flags.
2329 @type select_sim: bool
2330 """
2331
2332
2333 model_type = self._determine_model_type()
2334
2335
2336 if model_type == 'all' or model_type == 'diff':
2337 cdp.select_sim = select_sim
2338
2339
2340 else:
2341
2342 spin = return_spin_from_index(model_info)
2343
2344
2345 if not spin.select:
2346 return
2347
2348
2349 spin.select_sim = deepcopy(select_sim)
2350
2351
2352 - def set_update(self, param, spin):
2353 """Function to update the other model-free parameters.
2354
2355 @param param: The name of the parameter which has been changed.
2356 @type param: str
2357 @param spin: The SpinContainer object.
2358 @type spin: SpinContainer
2359 """
2360
2361
2362 if param == 's2f':
2363
2364 if hasattr(spin, 's2s') and spin.s2s != None:
2365 spin.s2 = spin.s2f * spin.s2s
2366
2367
2368
2369 if param == 's2s':
2370
2371 if hasattr(spin, 's2f') and spin.s2f != None:
2372 spin.s2 = spin.s2f * spin.s2s
2373
2374
2375 - def sim_init_values(self):
2376 """Initialise the Monte Carlo parameter values."""
2377
2378
2379 model_type = self._determine_model_type()
2380
2381
2382 param_names = self.data_names(set='params')
2383
2384
2385 min_names = self.data_names(set='min')
2386
2387
2388 if model_type == 'diff' or model_type == 'all':
2389
2390 if cdp.diff_tensor.type == 'sphere':
2391 diff_params = ['tm']
2392
2393
2394 elif cdp.diff_tensor.type == 'spheroid':
2395 diff_params = ['tm', 'Da', 'theta', 'phi']
2396
2397
2398 elif cdp.diff_tensor.type == 'ellipsoid':
2399 diff_params = ['tm', 'Da', 'Dr', 'alpha', 'beta', 'gamma']
2400
2401
2402
2403
2404
2405
2406 if model_type == 'diff' or model_type == 'all':
2407
2408 for object_name in diff_params:
2409
2410 sim_object_name = object_name + '_sim'
2411
2412
2413 if hasattr(cdp.diff_tensor, sim_object_name):
2414 raise RelaxError("Monte Carlo parameter values have already been set.")
2415
2416
2417 for object_name in min_names:
2418
2419 sim_object_name = object_name + '_sim'
2420
2421
2422 if hasattr(cdp, sim_object_name):
2423 raise RelaxError("Monte Carlo parameter values have already been set.")
2424
2425
2426 if model_type != 'diff':
2427 for spin in spin_loop():
2428
2429 if not spin.select:
2430 continue
2431
2432
2433 for object_name in param_names:
2434
2435 sim_object_name = object_name + '_sim'
2436
2437
2438 if hasattr(spin, sim_object_name):
2439 raise RelaxError("Monte Carlo parameter values have already been set.")
2440
2441
2442
2443
2444
2445
2446 for object_name in min_names:
2447
2448 if not hasattr(cdp, object_name):
2449 continue
2450
2451
2452 sim_object_name = object_name + '_sim'
2453
2454
2455 setattr(cdp, sim_object_name, [])
2456
2457
2458 sim_object = getattr(cdp, sim_object_name)
2459
2460
2461 for j in xrange(cdp.sim_number):
2462
2463 object = getattr(cdp, object_name)
2464
2465
2466 sim_object.append(deepcopy(object))
2467
2468
2469 if model_type == 'diff' or model_type == 'all':
2470
2471 for object_name in diff_params:
2472
2473 sim_object_name = object_name + '_sim'
2474
2475
2476 setattr(cdp.diff_tensor, sim_object_name, [])
2477
2478
2479 sim_object = getattr(cdp.diff_tensor, sim_object_name)
2480
2481
2482 for j in xrange(cdp.sim_number):
2483
2484 sim_object.append(deepcopy(getattr(cdp.diff_tensor, object_name)))
2485
2486
2487 if model_type != 'diff':
2488 for spin in spin_loop():
2489
2490 if not spin.select:
2491 continue
2492
2493
2494 for object_name in param_names:
2495
2496 sim_object_name = object_name + '_sim'
2497
2498
2499 setattr(spin, sim_object_name, [])
2500
2501
2502 sim_object = getattr(spin, sim_object_name)
2503
2504
2505 for j in xrange(cdp.sim_number):
2506
2507 sim_object.append(deepcopy(getattr(spin, object_name)))
2508
2509
2510 for object_name in min_names:
2511
2512 sim_object_name = object_name + '_sim'
2513
2514
2515 setattr(spin, sim_object_name, [])
2516
2517
2518 sim_object = getattr(spin, sim_object_name)
2519
2520
2521 for j in xrange(cdp.sim_number):
2522
2523 sim_object.append(deepcopy(getattr(spin, object_name)))
2524
2525
2526 - def sim_return_chi2(self, model_info, index=None):
2527 """Return the simulation chi-squared values.
2528
2529 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices).
2530 @type model_info: int
2531 @keyword index: The optional simulation index.
2532 @type index: int
2533 @return: The list of simulation chi-squared values. If the index is supplied, only a single value will be returned.
2534 @rtype: list of float or float
2535 """
2536
2537
2538 model_type = self._determine_model_type()
2539
2540
2541 if model_type == 'all' or model_type == 'diff':
2542 return cdp.chi2_sim
2543
2544
2545 else:
2546
2547 spin = return_spin_from_index(model_info)
2548
2549
2550 return spin.chi2_sim
2551
2552
2553 - def sim_return_param(self, model_info, index):
2554 """Return the array of simulation parameter values.
2555
2556 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices).
2557 @type model_info: int
2558 @param index: The index of the parameter to return the array of values for.
2559 @type index: int
2560 @return: The array of simulation parameter values.
2561 @rtype: list of float
2562 """
2563
2564
2565 inc = 0
2566
2567
2568 model_type = self._determine_model_type()
2569
2570
2571 param_names = self.data_names(set='params')
2572
2573
2574
2575
2576
2577 if model_type == 'diff' or model_type == 'all':
2578
2579 if cdp.diff_tensor.type == 'sphere':
2580
2581 if index == 0:
2582 return cdp.diff_tensor.tm_sim
2583
2584
2585 inc = inc + 1
2586
2587
2588 elif cdp.diff_tensor.type == 'spheroid':
2589
2590 if index == 0:
2591 return cdp.diff_tensor.tm_sim
2592 elif index == 1:
2593 return cdp.diff_tensor.Da_sim
2594 elif index == 2:
2595 return cdp.diff_tensor.theta_sim
2596 elif index == 3:
2597 return cdp.diff_tensor.phi_sim
2598
2599
2600 inc = inc + 4
2601
2602
2603 elif cdp.diff_tensor.type == 'ellipsoid':
2604
2605 if index == 0:
2606 return cdp.diff_tensor.tm_sim
2607 elif index == 1:
2608 return cdp.diff_tensor.Da_sim
2609 elif index == 2:
2610 return cdp.diff_tensor.Dr_sim
2611 elif index == 3:
2612 return cdp.diff_tensor.alpha_sim
2613 elif index == 4:
2614 return cdp.diff_tensor.beta_sim
2615 elif index == 5:
2616 return cdp.diff_tensor.gamma_sim
2617
2618
2619 inc = inc + 6
2620
2621
2622
2623
2624
2625 if model_type == 'all':
2626
2627 for spin in spin_loop():
2628
2629 if not spin.select:
2630 continue
2631
2632
2633 for param in param_names:
2634
2635 if index == inc:
2636 return getattr(spin, param + "_sim")
2637
2638
2639 inc = inc + 1
2640
2641
2642
2643
2644
2645 if model_type == 'mf' or model_type == 'local_tm':
2646
2647 spin = return_spin_from_index(model_info)
2648
2649
2650 if not spin.select:
2651 return
2652
2653
2654 for param in param_names:
2655
2656 if index == inc:
2657 return getattr(spin, param + "_sim")
2658
2659
2660 inc = inc + 1
2661
2662
2663 - def sim_return_selected(self, model_info):
2664 """Return the array of selected simulation flags for the spin.
2665
2666 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices).
2667 @type model_info: int
2668 @return: The array of selected simulation flags.
2669 @rtype: list of int
2670 """
2671
2672
2673 model_type = self._determine_model_type()
2674
2675
2676 if model_type == 'all' or model_type == 'diff':
2677 return cdp.select_sim
2678
2679
2680 else:
2681
2682 spin = return_spin_from_index(model_info)
2683
2684
2685 if not spin.select:
2686 return
2687
2688
2689 return spin.select_sim
2690
2691
2692 - def skip_function(self, model_info):
2693 """Skip certain data.
2694
2695 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices).
2696 @type model_info: int
2697 @return: True if the data should be skipped, False otherwise.
2698 @rtype: bool
2699 """
2700
2701
2702 model_type = self._determine_model_type()
2703
2704
2705 if (model_type == 'mf' or model_type == 'local_tm') and not return_spin_from_index(model_info).select:
2706 return True
2707
2708
2709 return False
2710