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