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