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 import arg_check
30 from data.mol_res_spin import SpinContainer
31 from generic_fns.mol_res_spin import count_spins, exists_mol_res_spin_data, return_spin, spin_loop
32 from relax_errors import RelaxError, RelaxLenError, RelaxNoSequenceError
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 """Dummy method for model elimination.
93
94 This simply returns False to signal that no model elimination is to be performed.
95
96
97 @param name: The parameter name.
98 @type name: str
99 @param value: The parameter value.
100 @type value: float
101 @param model_info: The model index from model_info().
102 @type model_info: int
103 @param args: The elimination constant overrides.
104 @type args: None or tuple of float
105 @keyword sim: The Monte Carlo simulation index.
106 @type sim: int
107 @return: False to prevent model elimination.
108 @rtype: bool
109 """
110
111
112 return False
113
114
116 """Testing if errors exist for the current data pipe (spin system specific).
117
118 @return: The answer to the question of whether errors exist.
119 @rtype: bool
120 """
121
122
123 if hasattr(cdp, 'diff'):
124 for object_name in dir(cdp.diff):
125
126 object_error = object_name + '_err'
127
128
129 if hasattr(cdp.diff, object_error):
130 return True
131
132
133 for spin in spin_loop():
134
135 for object_name in dir(spin):
136
137 object_error = object_name + '_err'
138
139
140 if hasattr(spin, object_error):
141 return True
142
143
144 return False
145
146
148 """Dummy method stating that the parameter is spin specific.
149
150 This method always returns true, hence all parameters will be considered residents of a SpinContainer object unless this method is overwritten.
151
152 @param name: The name of the parameter.
153 @type name: str
154 @return: True
155 @rtype: bool
156 """
157
158
159 return True
160
161
163 """Default generator method for looping over the models, where each spin has a separate model.
164
165 In this case only a single model per spin system is assumed. Hence the yielded data is the spin container object.
166
167
168 @return: The spin container.
169 @rtype: SpinContainer instance
170 """
171
172
173 for spin in spin_loop():
174
175 if not spin.select:
176 continue
177
178
179 yield spin
180
181
183 """Default generator method for looping over a single global (non-spin specific) model.
184
185 The loop will yield a single index, zero, once to indicate a single model.
186
187
188 @return: The global model index of zero.
189 @rtype: int
190 """
191
192
193 yield 0
194
195
197 """Return the number of instances, equal to the number of selected spins.
198
199 @return: The number of instances (equal to the number of spins).
200 @rtype: int
201 """
202
203
204 if not exists_mol_res_spin_data():
205 raise RelaxNoSequenceError
206
207
208 return count_spins()
209
210
212 """Dummy method, normally for deselecting spins with insufficient data for minimisation."""
213
214
216 """Method for returning 1.0.
217
218 @param param: The parameter name.
219 @type param: str
220 @return: A conversion factor of 1.0.
221 @rtype: float
222 """
223
224 return 1.0
225
226
228 """Return the Ri data structure for the given spin.
229
230 @param spin: The SpinContainer object.
231 @type spin: SpinContainer instance
232 @return: The array of relaxation data values.
233 @rtype: list of float
234 """
235
236
237 data = []
238 for ri_id in cdp.ri_ids:
239
240 if ri_id not in spin.ri_data:
241 data.append(None)
242
243
244 else:
245 data.append(spin.ri_data[ri_id])
246
247
248 return data
249
250
252 """Return the Ri error structure for the corresponding spin.
253
254 @param data_id: The data identification information, as yielded by the base_data_loop() generator method.
255 @type data_id: str
256 @return: The array of relaxation data error values.
257 @rtype: list of float
258 """
259
260
261 spin = return_spin(data_id)
262
263
264 error = []
265 for ri_id in cdp.ri_ids:
266
267 if ri_id not in spin.ri_data_err:
268 error.append(None)
269
270
271 else:
272 error.append(spin.ri_data_err[ri_id])
273
274
275 return error
276
277
279 """Return the value and error corresponding to the parameter 'param'.
280
281 If sim is set to an integer, return the value of the simulation and None. The values are taken from the given SpinContainer object.
282
283
284 @param spin: The SpinContainer object.
285 @type spin: SpinContainer
286 @param param: The name of the parameter to return values for.
287 @type param: str
288 @param sim: The Monte Carlo simulation index.
289 @type sim: None or int
290 @keyword bc: The back-calculated data flag. If True, then the back-calculated data will be returned rather than the actual data.
291 @type bc: bool
292 @return: The value and error corresponding to
293 @rtype: tuple of length 2 of floats or None
294 """
295
296
297 index = None
298
299
300 object_name = self.return_data_name(param)
301
302
303 if object_name:
304 object_error = object_name + '_err'
305 object_sim = object_name + '_sim'
306 object_bc = object_name + '_bc'
307 key = None
308
309
310 else:
311
312 if hasattr(cdp, 'spectrum_ids') and param in cdp.spectrum_ids:
313 object_name = 'intensities'
314 object_error = 'intensity_err'
315 object_sim = 'intensity_sim'
316 object_bc = 'intensity_bc'
317 key = param
318
319
320 else:
321 raise RelaxError("The parameter " + repr(param) + " does not exist.")
322
323
324 value = None
325 error = None
326
327
328 if bc:
329 object_name = object_bc
330
331
332 if sim != None:
333 object_name = object_sim
334
335
336 if hasattr(spin, object_name):
337 value = getattr(spin, object_name)
338
339
340 if hasattr(spin, object_error):
341 error = getattr(spin, object_error)
342
343
344 elif hasattr(cdp, object_name):
345 value = getattr(cdp, object_name)
346
347
348 if hasattr(cdp, object_error):
349 error = getattr(cdp, object_error)
350
351
352 if index != None:
353 value = value[index]
354 if error:
355 error = error[index]
356
357
358 if key:
359
360 if key not in value:
361 value = None
362 else:
363 value = value[key]
364
365 if error:
366
367 if key not in error:
368 error = None
369 else:
370 error = error[key]
371
372
373 if sim == None:
374 return value, error
375 else:
376 return value[sim], error
377
378
380 """Set the parameter errors (spin system specific).
381
382 @param model_info: The spin container originating from model_loop().
383 @type model_info: unknown
384 @param index: The index of the parameter to set the errors for.
385 @type index: int
386 @param error: The error value.
387 @type error: float
388 """
389
390
391 if not isinstance(model_info, SpinContainer):
392 raise RelaxError("The model information argument is not a spin container.")
393 spin = model_info
394
395
396 inc = 0
397
398
399 for param in self.data_names(set='params'):
400
401 if index == inc:
402 setattr(spin, param + "_err", error)
403
404
405 inc = inc + 1
406
407
409 """Set the global parameter values in the top layer of the data pipe.
410
411 @keyword param: The parameter name list.
412 @type param: list of str
413 @keyword value: The parameter value list.
414 @type value: list
415 @keyword spin_id: The spin identification string (unused).
416 @type spin_id: None
417 @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.
418 @type force: bool
419 """
420
421
422 arg_check.is_str_list(param, 'parameter name')
423 arg_check.is_list(value, 'parameter value')
424
425
426 for i in range(len(param)):
427
428 obj_name = self.return_data_name(param[i])
429
430
431 if not obj_name:
432 raise RelaxError("The parameter '%s' is not valid for this data pipe type." % param[i])
433
434
435 if not force and hasattr(cdp, obj_name) and getattr(cdp, obj_name) != None:
436 raise RelaxError("The parameter '%s' already exists, set the force flag to True to overwrite." % param[i])
437
438
439 setattr(cdp, obj_name, value[i])
440
441
443 """Set the spin specific parameter values.
444
445 @keyword param: The parameter name list.
446 @type param: list of str
447 @keyword value: The parameter value list.
448 @type value: list
449 @keyword spin_id: The spin identification string, only used for spin specific parameters.
450 @type spin_id: None or str
451 @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.
452 @type force: bool
453 """
454
455
456 arg_check.is_str_list(param, 'parameter name')
457 arg_check.is_list(value, 'parameter value')
458
459
460 for i in range(len(param)):
461
462 if not self.PARAMS.contains(param[i]):
463 raise RelaxError("The parameter '%s' is not valid for this data pipe type." % param[i])
464
465
466 for spin in spin_loop(spin_id):
467
468 if not spin.select:
469 continue
470
471
472 setattr(spin, param[i], value[i])
473
474
476 """Set the simulation selection flag (for a single global model).
477
478 @param model_info: The model information originating from model_loop(). This should be zero for the single global model.
479 @type model_info: int
480 @param select_sim: The selection flag for the simulations.
481 @type select_sim: bool
482 """
483
484
485 cdp.select_sim = deepcopy(select_sim)
486
487
489 """Set the simulation selection flag (spin system specific).
490
491 @param model_info: The model information originating from model_loop().
492 @type model_info: unknown
493 @param select_sim: The selection flag for the simulations.
494 @type select_sim: bool
495 """
496
497
498 if not isinstance(model_info, SpinContainer):
499 raise RelaxError("The model information argument is not a spin container.")
500 spin = model_info
501
502
503 spin.select_sim = deepcopy(select_sim)
504
505
507 """Dummy method to do nothing!
508
509 @param param: The name of the parameter which has been changed.
510 @type param: str
511 @param spin: The SpinContainer object.
512 @type spin: SpinContainer
513 """
514
515
517 """Initialise the Monte Carlo parameter values (spin system specific)."""
518
519
520 param_names = self.data_names(set='params')
521
522
523 min_names = self.data_names(set='min')
524
525
526
527
528
529
530 for spin in spin_loop():
531
532 if not spin.select:
533 continue
534
535
536 for object_name in param_names:
537
538 sim_object_name = object_name + '_sim'
539
540
541
542
543
544
545 for spin in spin_loop():
546
547 if not spin.select:
548 continue
549
550
551 for object_name in param_names:
552
553 sim_object_name = object_name + '_sim'
554
555
556 setattr(spin, sim_object_name, [])
557
558
559 sim_object = getattr(spin, sim_object_name)
560
561
562 for j in range(cdp.sim_number):
563
564 sim_object.append(deepcopy(getattr(spin, object_name)))
565
566
567 for object_name in min_names:
568
569 sim_object_name = object_name + '_sim'
570
571
572 setattr(spin, sim_object_name, [])
573
574
575 sim_object = getattr(spin, sim_object_name)
576
577
578 for j in range(cdp.sim_number):
579
580 sim_object.append(deepcopy(getattr(spin, object_name)))
581
582
584 """Pack the Monte Carlo simulation relaxation data into the corresponding spin container.
585
586 @param data_id: The spin identification string, as yielded by the base_data_loop() generator method.
587 @type data_id: str
588 @param sim_data: The Monte Carlo simulation data.
589 @type sim_data: list of float
590 """
591
592
593 spin = return_spin(data_id)
594
595
596 spin.ri_data_sim = {}
597
598
599 for i in range(len(cdp.ri_ids)):
600
601 ri_id = cdp.ri_ids[i]
602
603
604 spin.ri_data_sim[ri_id] = []
605
606
607 for j in range(cdp.sim_number):
608 spin.ri_data_sim[ri_id].append(sim_data[j][i])
609
610
612 """Return the simulation chi-squared values (spin system specific).
613
614 @param model_info: The model information originating from model_loop().
615 @type model_info: unknown
616 @keyword index: The optional simulation index.
617 @type index: int
618 @return: The list of simulation chi-squared values. If the index is supplied, only a single value will be returned.
619 @rtype: list of float or float
620 """
621
622
623 if not isinstance(model_info, SpinContainer):
624 raise RelaxError("The model information argument is not a spin container.")
625 spin = model_info
626
627
628 if index != None:
629 return spin.chi2_sim[index]
630
631
632 else:
633 return spin.chi2_sim
634
635
637 """Return the array of simulation parameter values (spin system specific).
638
639 @param model_info: The model information originating from model_loop().
640 @type model_info: unknown
641 @param index: The index of the parameter to return the array of values for.
642 @type index: int
643 @return: The array of simulation parameter values.
644 @rtype: list of float
645 """
646
647
648 if not isinstance(model_info, SpinContainer):
649 raise RelaxError("The model information argument is not a spin container.")
650 spin = model_info
651
652
653 inc = 0
654
655
656 for param in self.data_names(set='params'):
657
658 if index == inc:
659 return getattr(spin, param + "_sim")
660
661
662 inc = inc + 1
663
664
666 """Return the array of selected simulation flags for the global model.
667
668 @param model_info: The model information originating from model_loop(). This should be zero for the single global model.
669 @type model_info: int
670 @return: The array of selected simulation flags.
671 @rtype: list of int
672 """
673
674
675 return cdp.select_sim
676
677
679 """Return the array of selected simulation flags (spin system specific).
680
681 @param model_info: The model information originating from model_loop().
682 @type model_info: unknown
683 @return: The array of selected simulation flags.
684 @rtype: list of int
685 """
686
687
688 if not isinstance(model_info, SpinContainer):
689 raise RelaxError("The model information argument is not a spin container.")
690 spin = model_info
691
692
693 return spin.select_sim
694
695
697 """Test that the grid search options are reasonable.
698
699 @param lower: The lower bounds of the grid search which must be equal to the number of parameters in the model.
700 @type lower: array of numbers
701 @param upper: The upper bounds of the grid search which must be equal to the number of parameters in the model.
702 @type upper: array of numbers
703 @param inc: The increments for each dimension of the space for the grid search. The number of elements in the array must equal to the number of parameters in the model.
704 @type inc: array of int
705 @param n: The number of parameters in the model.
706 @type n: int
707 """
708
709
710 if lower != None:
711 if len(lower) != n:
712 raise RelaxLenError('lower bounds', n)
713
714
715 if upper != None:
716 if len(upper) != n:
717 raise RelaxLenError('upper bounds', n)
718
719
720 if isinstance(inc, list):
721 if len(inc) != n:
722 raise RelaxLenError('increment', n)
723