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