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