1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """Common API methods for use in different specific analyses."""
24
25
26 from copy import deepcopy
27 import sys
28
29
30 import lib.arg_check
31 from lib.errors import RelaxError, RelaxNoSequenceError
32 from lib.text.sectioning import subsection
33 from pipe_control.mol_res_spin import count_spins, exists_mol_res_spin_data, return_spin, spin_loop
34
35
37 """Base class containing API methods common to multiple analysis types."""
38
40 """Generator method for looping over the base data of the specific analysis type (spin system specific).
41
42 This method simply loops over the spins, returning the spin identification string.
43
44 @return: The spin identification string
45 @rtype: str
46 """
47
48
49 for spin, spin_id in spin_loop(return_id=True):
50
51 if not spin.select:
52 continue
53
54
55 yield spin_id
56
57
59 """Return the Monte Carlo relaxation data list for the corresponding spin.
60
61 @param data_id: The spin identification string, as yielded by the base_data_loop() generator method.
62 @type data_id: str
63 """
64
65
66 spin = return_spin(data_id)
67
68
69 data = []
70
71
72 for ri_id in cdp.ri_ids:
73 data.append(spin.ri_data[ri_id])
74
75
76 return data
77
78
80 """Dummy method for initialising data structures.
81
82 This method does nothing!
83
84
85 @param data: The data from the base_data_loop() method.
86 @type data: instance
87 @keyword sim: The unused Monte Carlo simulation flag.
88 @type sim: bool
89 """
90
91
93 """Initialise data structures (spin system specific).
94
95 @param data: The spin ID string from the _base_data_loop_spin() method.
96 @type data: str
97 @keyword sim: The Monte Carlo simulation flag, which if true will initialise the simulation data structure.
98 @type sim: bool
99 """
100
101
102 spin_id = data
103 spin = return_spin(spin_id)
104
105
106 for name in self._PARAMS.loop(set='params', scope='spin', error_names=False, sim_names=sim):
107
108 if name not in spin.params:
109 continue
110
111
112 if hasattr(spin, name):
113 continue
114
115
116 param_type = self._PARAMS.type(name)
117 if param_type == dict:
118 value = {}
119 elif param_type == list:
120 value = []
121 else:
122 value = None
123
124
125 setattr(spin, name, value)
126
127
129 """Common method for deselecting a global model.
130
131 @keyword sim_index: The optional Monte Carlo simulation index. If None, then models will be deselected, otherwise the given simulation will.
132 @type sim_index: None or int
133 @keyword model_info: The model information from _model_loop_single_global(). This should be zero for the single global model.
134 @type model_info: int
135 """
136
137
138 if sim_index != None:
139 cdp.select_sim[sim_index] = False
140
141
142 else:
143 cdp.select = False
144
145
147 """Dummy method for model elimination.
148
149 This simply returns False to signal that no model elimination is to be performed.
150
151
152 @param name: The parameter name.
153 @type name: str
154 @param value: The parameter value.
155 @type value: float
156 @param args: The elimination constant overrides.
157 @type args: None or tuple of float
158 @keyword sim: The Monte Carlo simulation index.
159 @type sim: int
160 @keyword model_info: The model information from model_loop().
161 @type model_info: unknown
162 @return: False to prevent model elimination.
163 @rtype: bool
164 """
165
166
167 return False
168
169
171 """Return the current data pipe as the model container.
172
173 @keyword model_info: The model information from model_loop().
174 @type model_info: unknown
175 @return: The data container corresponding to the model.
176 @rtype: class instance
177 """
178
179
180 return cdp
181
182
184 """Testing if errors exist for the current data pipe (spin system specific).
185
186 @return: The answer to the question of whether errors exist.
187 @rtype: bool
188 """
189
190
191 if hasattr(cdp, 'diff'):
192 for object_name in dir(cdp.diff):
193
194 object_error = object_name + '_err'
195
196
197 if hasattr(cdp.diff, object_error):
198 return True
199
200
201 for spin in spin_loop():
202
203 for object_name in dir(spin):
204
205 object_error = object_name + '_err'
206
207
208 if hasattr(spin, object_error):
209 return True
210
211
212 return False
213
214
216 """Common method stating that the parameter is not spin specific.
217
218 This method always returns False, hence all parameters will be considered global.
219
220 @param name: The name of the parameter.
221 @type name: str
222 @return: False
223 @rtype: bool
224 """
225
226
227 return False
228
229
231 """Common method stating that the parameter is spin specific.
232
233 This method always returns true, hence all parameters will be considered residents of a SpinContainer object.
234
235 @param name: The name of the parameter.
236 @type name: str
237 @return: True
238 @rtype: bool
239 """
240
241
242 return True
243
244
246 """Default generator method for looping over the models, where each spin has a separate model.
247
248 In this case only a single model per spin system is assumed. The yielded data is the spin container object. The spin ID string is also yielded to allow the corresponding spin container to be identified.
249
250
251 @return: The spin container and the spin ID string.
252 @rtype: SpinContainer instance, str
253 """
254
255
256 for spin, spin_id in spin_loop(return_id=True):
257
258 if not spin.select:
259 continue
260
261
262 yield spin, spin_id
263
264
266 """Default generator method for looping over a single global (non-spin specific) model.
267
268 The loop will yield a single index, zero, once to indicate a single model.
269
270
271 @return: The global model index of zero.
272 @rtype: int
273 """
274
275
276 yield 0
277
278
280 """Return the type of the model as being 'global'.
281
282 @return: The model type of 'global'.
283 @rtype: str
284 """
285
286
287 return 'global'
288
289
291 """Return the type of the model as being 'local'.
292
293 @return: The model type of 'local'.
294 @rtype: str
295 """
296
297
298 return 'local'
299
300
302 """Return the number of instances, equal to the number of selected spins.
303
304 @return: The number of instances (equal to the number of spins).
305 @rtype: int
306 """
307
308
309 if not exists_mol_res_spin_data():
310 raise RelaxNoSequenceError
311
312
313 return count_spins()
314
315
317 """Dummy method, normally for deselecting spins with insufficient data for minimisation."""
318
319
321 """Default method for when the model_loop() method simply loops over a single global model.
322
323 @keyword prefix: The starting text of the title. This should be printed out first, followed by the model information text.
324 @type prefix: str
325 @keyword model_info: The model information from _model_loop_single_global(). This should be zero for the single global model.
326 @type model_info: int
327 """
328
329
330 text = ''
331 if prefix:
332 text += prefix
333 else:
334 text += 'Model '
335 text += repr(model_info)
336
337
338 subsection(file=sys.stdout, text=text, prespace=2)
339
340
342 """Default method for when the model_loop() method simply loops over spins.
343
344 @keyword prefix: The starting text of the title. This should be printed out first, followed by the model information text.
345 @type prefix: str
346 @keyword model_info: The spin container and the spin ID string from the _model_loop_spin() method.
347 @type model_info: SpinContainer instance, str
348 """
349
350
351 spin_id = model_info[1]
352 text = prefix + "The spin %s" % spin_id
353 subsection(file=sys.stdout, text=text, prespace=2)
354
355
357 """Method for returning 1.0.
358
359 @param param: The parameter name.
360 @type param: str
361 @return: A conversion factor of 1.0.
362 @rtype: float
363 """
364
365 return 1.0
366
367
369 """Return the Ri data structure for the given spin.
370
371 @param spin: The SpinContainer object.
372 @type spin: SpinContainer instance
373 @return: The array of relaxation data values.
374 @rtype: list of float
375 """
376
377
378 data = []
379 for ri_id in cdp.ri_ids:
380
381 if ri_id not in spin.ri_data:
382 data.append(None)
383
384
385 else:
386 data.append(spin.ri_data[ri_id])
387
388
389 return data
390
391
393 """Return the Ri error structure for the corresponding spin.
394
395 @param data_id: The data identification information, as yielded by the base_data_loop() generator method.
396 @type data_id: str
397 @return: The array of relaxation data error values.
398 @rtype: list of float
399 """
400
401
402 spin = return_spin(data_id)
403
404
405 error = []
406 for ri_id in cdp.ri_ids:
407
408 if ri_id not in spin.ri_data_err:
409 error.append(None)
410
411
412 else:
413 error.append(spin.ri_data_err[ri_id])
414
415
416 return error
417
418
420 """Return the value and error corresponding to the parameter 'param'.
421
422 If sim is set to an integer, return the value of the simulation and None. The values are taken from the given SpinContainer object.
423
424
425 @param spin: The SpinContainer object.
426 @type spin: SpinContainer
427 @param param: The name of the parameter to return values for.
428 @type param: str
429 @param sim: The Monte Carlo simulation index.
430 @type sim: None or int
431 @keyword bc: The back-calculated data flag. If True, then the back-calculated data will be returned rather than the actual data.
432 @type bc: bool
433 @return: The value and error corresponding to
434 @rtype: tuple of length 2 of floats or None
435 """
436
437
438 index = None
439
440
441 if param:
442 object_error = param + '_err'
443 object_sim = param + '_sim'
444 object_bc = param + '_bc'
445 key = None
446
447
448 else:
449
450 if hasattr(cdp, 'spectrum_ids') and param in cdp.spectrum_ids:
451 param = 'intensity'
452 object_error = 'intensity_err'
453 object_sim = 'intensity_sim'
454 object_bc = 'intensity_bc'
455 key = param
456
457
458 else:
459 raise RelaxError("The parameter " + repr(param) + " does not exist.")
460
461
462 value = None
463 error = None
464
465
466 if bc:
467 param = object_bc
468
469
470 if sim != None:
471 param = object_sim
472
473
474 if hasattr(spin, param):
475 value = getattr(spin, param)
476
477
478 if hasattr(spin, object_error):
479 error = getattr(spin, object_error)
480
481
482 elif hasattr(cdp, param):
483 value = getattr(cdp, param)
484
485
486 if hasattr(cdp, object_error):
487 error = getattr(cdp, object_error)
488
489
490 if index != None:
491 value = value[index]
492 if error:
493 error = error[index]
494
495
496 if key:
497
498 if key not in value:
499 value = None
500 else:
501 value = value[key]
502
503 if error:
504
505 if key not in error:
506 error = None
507 else:
508 error = error[key]
509
510
511 if sim == None:
512 return value, error
513 elif value == None:
514 return value, error
515 else:
516 return value[sim], error
517
518
520 """Set the parameter errors (spin system specific).
521
522 @param index: The index of the parameter to set the errors for.
523 @type index: int
524 @param error: The error value.
525 @type error: float
526 @keyword model_info: The spin container and the spin ID string from the _model_loop_spin() method.
527 @type model_info: SpinContainer instance, str
528 """
529
530
531 spin, spin_id = model_info
532
533
534 inc = 0
535
536
537 for param in self.data_names(set='params'):
538
539 if index == inc:
540 setattr(spin, param + "_err", error)
541
542
543 inc = inc + 1
544
545
547 """Set the global parameter values in the top layer of the data pipe.
548
549 @keyword param: The parameter name list.
550 @type param: list of str
551 @keyword value: The parameter value list.
552 @type value: list
553 @keyword index: The index for parameters which are of the list-type. This is unused.
554 @type index: None or int
555 @keyword spin_id: The spin identification string (unused).
556 @type spin_id: None
557 @keyword error: A flag which if True will allow the parameter errors to be set instead of the values.
558 @type error: bool
559 @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.
560 @type force: bool
561 """
562
563
564 lib.arg_check.is_str_list(param, 'parameter name')
565 lib.arg_check.is_list(value, 'parameter value')
566
567
568 for i in range(len(param)):
569
570 if not param[i]:
571 raise RelaxError("The parameter '%s' is not valid for this data pipe type." % param[i])
572
573
574 if error:
575 param[i] += '_err'
576
577
578 if not force and hasattr(cdp, param[i]) and getattr(cdp, param[i]) != None:
579 raise RelaxError("The parameter '%s' already exists, set the force flag to True to overwrite." % param[i])
580
581
582 setattr(cdp, param[i], value[i])
583
584
586 """Set the spin specific parameter values.
587
588 @keyword param: The parameter name list.
589 @type param: list of str
590 @keyword value: The parameter value list.
591 @type value: list
592 @keyword index: The index for parameters which are of the list-type. This is unused.
593 @type index: None or int
594 @keyword spin_id: The spin identification string, only used for spin specific parameters.
595 @type spin_id: None or str
596 @keyword error: A flag which if True will allow the parameter errors to be set instead of the values.
597 @type error: bool
598 @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.
599 @type force: bool
600 """
601
602
603 lib.arg_check.is_str_list(param, 'parameter name')
604 lib.arg_check.is_list(value, 'parameter value')
605
606
607 for i in range(len(param)):
608
609 if not self._PARAMS.contains(param[i]):
610 raise RelaxError("The parameter '%s' is not valid for this data pipe type." % param[i])
611
612
613 for spin in spin_loop(spin_id):
614
615 if not spin.select:
616 continue
617
618
619 obj_name = param[i]
620 if error:
621 obj_name += '_err'
622
623
624 param_type = self._PARAMS.type(param[i])
625 if param_type == dict:
626 obj = getattr(spin, obj_name)
627 for key in obj:
628 obj[key] = value[i]
629 elif param_type == list:
630 obj = getattr(spin, obj_name)
631 for j in range(len(obj)):
632 obj[j] = value[i]
633 else:
634 setattr(spin, obj_name, value[i])
635
636
638 """Set the simulation selection flag (for a single global model).
639
640 @param select_sim: The selection flag for the simulations.
641 @type select_sim: bool
642 @keyword model_info: The model information from _model_loop_single_global(). This should be zero for the single global model.
643 @type model_info: int
644 """
645
646
647 cdp.select_sim = deepcopy(select_sim)
648
649
651 """Set the simulation selection flag (spin system specific).
652
653 @param select_sim: The selection flag for the simulations.
654 @type select_sim: bool
655 @keyword model_info: The spin container and the spin ID string from the _model_loop_spin() method.
656 @type model_info: SpinContainer instance, str
657 """
658
659
660 spin, spin_id = model_info
661
662
663 spin.select_sim = deepcopy(select_sim)
664
665
667 """Dummy method to do nothing!
668
669 @param param: The name of the parameter which has been changed.
670 @type param: str
671 @param spin: The SpinContainer object.
672 @type spin: SpinContainer
673 """
674
675
677 """Initialise the Monte Carlo parameter values (spin system specific)."""
678
679
680 param_names = self.data_names(set='params')
681
682
683 min_names = self.data_names(set='min')
684
685
686
687
688
689
690 for spin in spin_loop():
691
692 if not spin.select:
693 continue
694
695
696 for object_name in param_names:
697
698 sim_object_name = object_name + '_sim'
699
700
701
702
703
704
705 for spin in spin_loop():
706
707 if not spin.select:
708 continue
709
710
711 for object_name in param_names:
712
713 if object_name not in spin.params:
714 continue
715
716
717 sim_object_name = object_name + '_sim'
718
719
720 setattr(spin, sim_object_name, [])
721
722
723 sim_object = getattr(spin, sim_object_name)
724
725
726 for j in range(cdp.sim_number):
727
728 sim_object.append(deepcopy(getattr(spin, object_name)))
729
730
731 for object_name in min_names:
732
733 sim_object_name = object_name + '_sim'
734
735
736 setattr(spin, sim_object_name, [])
737
738
739 sim_object = getattr(spin, sim_object_name)
740
741
742 for j in range(cdp.sim_number):
743
744 sim_object.append(deepcopy(getattr(spin, object_name)))
745
746
748 """Pack the Monte Carlo simulation relaxation data into the corresponding spin container.
749
750 @param data_id: The spin identification string, as yielded by the base_data_loop() generator method.
751 @type data_id: str
752 @param sim_data: The Monte Carlo simulation data.
753 @type sim_data: list of float
754 """
755
756
757 spin = return_spin(data_id)
758
759
760 spin.ri_data_sim = {}
761
762
763 for i in range(len(cdp.ri_ids)):
764
765 ri_id = cdp.ri_ids[i]
766
767
768 spin.ri_data_sim[ri_id] = []
769
770
771 for j in range(cdp.sim_number):
772 spin.ri_data_sim[ri_id].append(sim_data[j][i])
773
774
776 """Return the simulation chi-squared values (spin system specific).
777
778 @keyword index: The optional simulation index.
779 @type index: int
780 @keyword model_info: The spin container and the spin ID string from the _model_loop_spin() method.
781 @type model_info: SpinContainer instance, str
782 @return: The list of simulation chi-squared values. If the index is supplied, only a single value will be returned.
783 @rtype: list of float or float
784 """
785
786
787 spin, spin_id = model_info
788
789
790 if index != None:
791 return spin.chi2_sim[index]
792
793
794 else:
795 return spin.chi2_sim
796
797
799 """Return the array of simulation parameter values (spin system specific).
800
801 @param index: The index of the parameter to return the array of values for.
802 @type index: int
803 @keyword model_info: The spin container and the spin ID string from the _model_loop_spin() method.
804 @type model_info: SpinContainer instance, str
805 @return: The array of simulation parameter values.
806 @rtype: list of float
807 """
808
809
810 spin, spin_id = model_info
811
812
813 inc = 0
814
815
816 for param in self.data_names(set='params'):
817
818 if param not in spin.params:
819 continue
820
821
822 if index == inc:
823 return getattr(spin, param + "_sim")
824
825
826 inc = inc + 1
827
828
830 """Return the array of selected simulation flags for the global model.
831
832 @keyword model_info: The model information from _model_loop_single_global(). This should be zero for the single global model.
833 @type model_info: int
834 @return: The array of selected simulation flags.
835 @rtype: list of int
836 """
837
838
839 return cdp.select_sim
840
841
843 """Return the array of selected simulation flags (spin system specific).
844
845 @keyword model_info: The spin container and the spin ID string from the _model_loop_spin() method.
846 @type model_info: SpinContainer instance, str
847 @return: The array of selected simulation flags.
848 @rtype: list of int
849 """
850
851
852 spin, spin_id = model_info
853
854
855 return spin.select_sim
856