1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """API methods in common between different analysis types."""
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 data.append(spin.ri_data[ri_id])
240
241
242 return data
243
244
246 """Return the Ri error structure for the corresponding spin.
247
248 @param data_id: The data identification information, as yielded by the base_data_loop() generator method.
249 @type data_id: str
250 @return: The array of relaxation data error values.
251 @rtype: list of float
252 """
253
254
255 spin = return_spin(data_id)
256
257
258 error = []
259 for ri_id in cdp.ri_ids:
260 error.append(spin.ri_data_err[ri_id])
261
262
263 return error
264
265
267 """Return the value and error corresponding to the parameter 'param'.
268
269 If sim is set to an integer, return the value of the simulation and None. The values are taken from the given SpinContainer object.
270
271
272 @param spin: The SpinContainer object.
273 @type spin: SpinContainer
274 @param param: The name of the parameter to return values for.
275 @type param: str
276 @param sim: The Monte Carlo simulation index.
277 @type sim: None or int
278 @keyword bc: The back-calculated data flag. If True, then the back-calculated data will be returned rather than the actual data.
279 @type bc: bool
280 @return: The value and error corresponding to
281 @rtype: tuple of length 2 of floats or None
282 """
283
284
285 index = None
286
287
288 object_name = self.return_data_name(param)
289
290
291 if object_name:
292 object_error = object_name + '_err'
293 object_sim = object_name + '_sim'
294 object_bc = object_name + '_bc'
295 key = None
296
297
298 else:
299
300 if hasattr(cdp, 'spectrum_ids') and param in cdp.spectrum_ids:
301 object_name = 'intensities'
302 object_error = 'intensity_err'
303 object_sim = 'intensity_sim'
304 object_bc = 'intensity_bc'
305 key = param
306
307
308 else:
309 raise RelaxError("The parameter " + repr(param) + " does not exist.")
310
311
312 value = None
313 error = None
314
315
316 if bc:
317 object_name = object_bc
318
319
320 if sim != None:
321 object_name = object_sim
322
323
324 if hasattr(spin, object_name):
325 value = getattr(spin, object_name)
326
327
328 if hasattr(spin, object_error):
329 error = getattr(spin, object_error)
330
331
332 elif hasattr(cdp, object_name):
333 value = getattr(cdp, object_name)
334
335
336 if hasattr(cdp, object_error):
337 error = getattr(cdp, object_error)
338
339
340 if index != None:
341 value = value[index]
342 if error:
343 error = error[index]
344
345
346 if key:
347 value = value[key]
348 if error:
349 error = error[key]
350
351
352 if sim == None:
353 return value, error
354 else:
355 return value[sim], error
356
357
359 """Set the parameter errors (spin system specific).
360
361 @param model_info: The spin container originating from model_loop().
362 @type model_info: unknown
363 @param index: The index of the parameter to set the errors for.
364 @type index: int
365 @param error: The error value.
366 @type error: float
367 """
368
369
370 if not isinstance(model_info, SpinContainer):
371 raise RelaxError("The model information argument is not a spin container.")
372 spin = model_info
373
374
375 inc = 0
376
377
378 for param in self.data_names(set='params'):
379
380 if index == inc:
381 setattr(spin, param + "_err", error)
382
383
384 inc = inc + 1
385
386
388 """Set the global parameter values in the top layer of the data pipe.
389
390 @keyword param: The parameter name list.
391 @type param: list of str
392 @keyword value: The parameter value list.
393 @type value: list
394 @keyword spin_id: The spin identification string (unused).
395 @type spin_id: None
396 @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.
397 @type force: bool
398 """
399
400
401 arg_check.is_str_list(param, 'parameter name')
402 arg_check.is_list(value, 'parameter value')
403
404
405 for i in range(len(param)):
406
407 obj_name = self.return_data_name(param[i])
408
409
410 if not obj_name:
411 raise RelaxError("The parameter '%s' is not valid for this data pipe type." % param[i])
412
413
414 if not force and hasattr(cdp, obj_name) and getattr(cdp, obj_name) != None:
415 raise RelaxError("The parameter '%s' already exists, set the force flag to True to overwrite." % param[i])
416
417
418 setattr(cdp, obj_name, value[i])
419
420
422 """Set the spin specific parameter values.
423
424 @keyword param: The parameter name list.
425 @type param: list of str
426 @keyword value: The parameter value list.
427 @type value: list
428 @keyword spin_id: The spin identification string, only used for spin specific parameters.
429 @type spin_id: None or str
430 @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.
431 @type force: bool
432 """
433
434
435 arg_check.is_str_list(param, 'parameter name')
436 arg_check.is_list(value, 'parameter value')
437
438
439 for i in range(len(param)):
440
441 if not self.PARAMS.contains(param[i]):
442 raise RelaxError("The parameter '%s' is not valid for this data pipe type." % param[i])
443
444
445 for spin in spin_loop(spin_id):
446
447 if not spin.select:
448 continue
449
450
451 setattr(spin, param[i], value[i])
452
453
455 """Set the simulation selection flag (for a single global model).
456
457 @param model_info: The model information originating from model_loop(). This should be zero for the single global model.
458 @type model_info: int
459 @param select_sim: The selection flag for the simulations.
460 @type select_sim: bool
461 """
462
463
464 cdp.select_sim = deepcopy(select_sim)
465
466
468 """Set the simulation selection flag (spin system specific).
469
470 @param model_info: The model information originating from model_loop().
471 @type model_info: unknown
472 @param select_sim: The selection flag for the simulations.
473 @type select_sim: bool
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 spin.select_sim = deepcopy(select_sim)
483
484
486 """Dummy method to do nothing!
487
488 @param param: The name of the parameter which has been changed.
489 @type param: str
490 @param spin: The SpinContainer object.
491 @type spin: SpinContainer
492 """
493
494
496 """Initialise the Monte Carlo parameter values (spin system specific)."""
497
498
499 param_names = self.data_names(set='params')
500
501
502 min_names = self.data_names(set='min')
503
504
505
506
507
508
509 for spin in spin_loop():
510
511 if not spin.select:
512 continue
513
514
515 for object_name in param_names:
516
517 sim_object_name = object_name + '_sim'
518
519
520
521
522
523
524 for spin in spin_loop():
525
526 if not spin.select:
527 continue
528
529
530 for object_name in param_names:
531
532 sim_object_name = object_name + '_sim'
533
534
535 setattr(spin, sim_object_name, [])
536
537
538 sim_object = getattr(spin, sim_object_name)
539
540
541 for j in range(cdp.sim_number):
542
543 sim_object.append(deepcopy(getattr(spin, object_name)))
544
545
546 for object_name in min_names:
547
548 sim_object_name = object_name + '_sim'
549
550
551 setattr(spin, sim_object_name, [])
552
553
554 sim_object = getattr(spin, sim_object_name)
555
556
557 for j in range(cdp.sim_number):
558
559 sim_object.append(deepcopy(getattr(spin, object_name)))
560
561
563 """Pack the Monte Carlo simulation relaxation data into the corresponding spin container.
564
565 @param data_id: The spin identification string, as yielded by the base_data_loop() generator method.
566 @type data_id: str
567 @param sim_data: The Monte Carlo simulation data.
568 @type sim_data: list of float
569 """
570
571
572 spin = return_spin(data_id)
573
574
575 spin.ri_data_sim = {}
576
577
578 for i in range(len(cdp.ri_ids)):
579
580 ri_id = cdp.ri_ids[i]
581
582
583 spin.ri_data_sim[ri_id] = []
584
585
586 for j in range(cdp.sim_number):
587 spin.ri_data_sim[ri_id].append(sim_data[j][i])
588
589
591 """Return the simulation chi-squared values (spin system specific).
592
593 @param model_info: The model information originating from model_loop().
594 @type model_info: unknown
595 @keyword index: The optional simulation index.
596 @type index: int
597 @return: The list of simulation chi-squared values. If the index is supplied, only a single value will be returned.
598 @rtype: list of float or float
599 """
600
601
602 if not isinstance(model_info, SpinContainer):
603 raise RelaxError("The model information argument is not a spin container.")
604 spin = model_info
605
606
607 if index != None:
608 return spin.chi2_sim[index]
609
610
611 else:
612 return spin.chi2_sim
613
614
616 """Return the array of simulation parameter values (spin system specific).
617
618 @param model_info: The model information originating from model_loop().
619 @type model_info: unknown
620 @param index: The index of the parameter to return the array of values for.
621 @type index: int
622 @return: The array of simulation parameter values.
623 @rtype: list of float
624 """
625
626
627 if not isinstance(model_info, SpinContainer):
628 raise RelaxError("The model information argument is not a spin container.")
629 spin = model_info
630
631
632 inc = 0
633
634
635 for param in self.data_names(set='params'):
636
637 if index == inc:
638 return getattr(spin, param + "_sim")
639
640
641 inc = inc + 1
642
643
645 """Return the array of selected simulation flags for the global model.
646
647 @param model_info: The model information originating from model_loop(). This should be zero for the single global model.
648 @type model_info: int
649 @return: The array of selected simulation flags.
650 @rtype: list of int
651 """
652
653
654 return cdp.select_sim
655
656
658 """Return the array of selected simulation flags (spin system specific).
659
660 @param model_info: The model information originating from model_loop().
661 @type model_info: unknown
662 @return: The array of selected simulation flags.
663 @rtype: list of int
664 """
665
666
667 if not isinstance(model_info, SpinContainer):
668 raise RelaxError("The model information argument is not a spin container.")
669 spin = model_info
670
671
672 return spin.select_sim
673
674
676 """Test that the grid search options are reasonable.
677
678 @param lower: The lower bounds of the grid search which must be equal to the number of parameters in the model.
679 @type lower: array of numbers
680 @param upper: The upper bounds of the grid search which must be equal to the number of parameters in the model.
681 @type upper: array of numbers
682 @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.
683 @type inc: array of int
684 @param n: The number of parameters in the model.
685 @type n: int
686 """
687
688
689 if lower != None:
690 if len(lower) != n:
691 raise RelaxLenError('lower bounds', n)
692
693
694 if upper != None:
695 if len(upper) != n:
696 raise RelaxLenError('upper bounds', n)
697
698
699 if isinstance(inc, list):
700 if len(inc) != n:
701 raise RelaxLenError('increment', n)
702