1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 from copy import deepcopy
25 from math import pi
26 from minfx.grid import grid_split
27 from numpy import array, dot, float64, int8, zeros
28 from numpy.linalg import inv
29 from re import match, search
30 import sys
31 from warnings import warn
32
33
34 import arg_check
35 from float import isNaN, isInf
36 from generic_fns import diffusion_tensor, pipes
37 from generic_fns.diffusion_tensor import diff_data_exists
38 from generic_fns.mol_res_spin import count_spins, exists_mol_res_spin_data, return_spin_from_index, spin_loop
39 from maths_fns.mf import Mf
40 from multi import Processor_box
41 from multi_processor_commands import MF_grid_command, MF_memo, MF_minimise_command
42 from physical_constants import h_bar, mu0, return_gyromagnetic_ratio
43 from relax_errors import RelaxError, RelaxInfError, RelaxLenError, RelaxMultiVectorError, RelaxNaNError, RelaxNoModelError, RelaxNoPdbError, RelaxNoResError, RelaxNoSequenceError, RelaxNoTensorError, RelaxNoValueError, RelaxNoVectorsError, RelaxNucleusError, RelaxProtonTypeError, RelaxSpinTypeError
44 from relax_warnings import RelaxWarning
45
46
47
49 """Empty class to be used for data storage."""
50
51
53 """Class containing functions specific to model-free optimisation."""
54
56 """Disassemble the model-free parameter vector.
57
58 @param model_type: The model-free model type. This must be one of 'mf', 'local_tm',
59 'diff', or 'all'.
60 @type model_type: str
61 @keyword param_vector: The model-free parameter vector.
62 @type param_vector: numpy array
63 @keyword spin: The spin data container. If this argument is supplied, then the spin_id
64 argument will be ignored.
65 @type spin: SpinContainer instance
66 @keyword spin_id: The spin identification string.
67 @type spin_id: str
68 @keyword sim_index: The optional MC simulation index.
69 @type sim_index: int
70 """
71
72
73 param_index = 0
74
75
76 if sim_index != None and (model_type == 'diff' or model_type == 'all'):
77
78 if cdp.diff_tensor.type == 'sphere':
79
80 cdp.diff_tensor.tm_sim[sim_index] = param_vector[0]
81
82
83 param_index = param_index + 1
84
85
86 elif cdp.diff_tensor.type == 'spheroid':
87
88 cdp.diff_tensor.tm_sim[sim_index] = param_vector[0]
89 cdp.diff_tensor.Da_sim[sim_index] = param_vector[1]
90 cdp.diff_tensor.theta_sim[sim_index] = param_vector[2]
91 cdp.diff_tensor.phi_sim[sim_index] = param_vector[3]
92 diffusion_tensor.fold_angles(sim_index=sim_index)
93
94
95 param_index = param_index + 4
96
97
98 elif cdp.diff_tensor.type == 'ellipsoid':
99
100 cdp.diff_tensor.tm_sim[sim_index] = param_vector[0]
101 cdp.diff_tensor.Da_sim[sim_index] = param_vector[1]
102 cdp.diff_tensor.Dr_sim[sim_index] = param_vector[2]
103 cdp.diff_tensor.alpha_sim[sim_index] = param_vector[3]
104 cdp.diff_tensor.beta_sim[sim_index] = param_vector[4]
105 cdp.diff_tensor.gamma_sim[sim_index] = param_vector[5]
106 diffusion_tensor.fold_angles(sim_index=sim_index)
107
108
109 param_index = param_index + 6
110
111
112 elif model_type == 'diff' or model_type == 'all':
113
114 if cdp.diff_tensor.type == 'sphere':
115
116 cdp.diff_tensor.tm = param_vector[0]
117
118
119 param_index = param_index + 1
120
121
122 elif cdp.diff_tensor.type == 'spheroid':
123
124 cdp.diff_tensor.tm = param_vector[0]
125 cdp.diff_tensor.Da = param_vector[1]
126 cdp.diff_tensor.theta = param_vector[2]
127 cdp.diff_tensor.phi = param_vector[3]
128 diffusion_tensor.fold_angles()
129
130
131 param_index = param_index + 4
132
133
134 elif cdp.diff_tensor.type == 'ellipsoid':
135
136 cdp.diff_tensor.tm = param_vector[0]
137 cdp.diff_tensor.Da = param_vector[1]
138 cdp.diff_tensor.Dr = param_vector[2]
139 cdp.diff_tensor.alpha = param_vector[3]
140 cdp.diff_tensor.beta = param_vector[4]
141 cdp.diff_tensor.gamma = param_vector[5]
142 diffusion_tensor.fold_angles()
143
144
145 param_index = param_index + 6
146
147
148 if model_type != 'diff':
149
150 if spin:
151 loop = [spin]
152 else:
153 loop = spin_loop(spin_id)
154
155
156 for spin in loop:
157
158 if not spin.select:
159 continue
160
161
162 for j in xrange(len(spin.params)):
163
164 if spin.params[j] == 'local_tm':
165 if sim_index == None:
166 spin.local_tm = param_vector[param_index]
167 else:
168 spin.local_tm_sim[sim_index] = param_vector[param_index]
169
170
171 elif spin.params[j] == 's2':
172 if sim_index == None:
173 spin.s2 = param_vector[param_index]
174 else:
175 spin.s2_sim[sim_index] = param_vector[param_index]
176
177
178 elif spin.params[j] == 's2f':
179 if sim_index == None:
180 spin.s2f = param_vector[param_index]
181 else:
182 spin.s2f_sim[sim_index] = param_vector[param_index]
183
184
185 elif spin.params[j] == 's2s':
186 if sim_index == None:
187 spin.s2s = param_vector[param_index]
188 else:
189 spin.s2s_sim[sim_index] = param_vector[param_index]
190
191
192 elif spin.params[j] == 'te':
193 if sim_index == None:
194 spin.te = param_vector[param_index]
195 else:
196 spin.te_sim[sim_index] = param_vector[param_index]
197
198
199 elif spin.params[j] == 'tf':
200 if sim_index == None:
201 spin.tf = param_vector[param_index]
202 else:
203 spin.tf_sim[sim_index] = param_vector[param_index]
204
205
206 elif spin.params[j] == 'ts':
207 if sim_index == None:
208 spin.ts = param_vector[param_index]
209 else:
210 spin.ts_sim[sim_index] = param_vector[param_index]
211
212
213 elif spin.params[j] == 'rex':
214 if sim_index == None:
215 spin.rex = param_vector[param_index]
216 else:
217 spin.rex_sim[sim_index] = param_vector[param_index]
218
219
220 elif spin.params[j] == 'r':
221 if sim_index == None:
222 spin.r = param_vector[param_index]
223 else:
224 spin.r_sim[sim_index] = param_vector[param_index]
225
226
227 elif spin.params[j] == 'csa':
228 if sim_index == None:
229 spin.csa = param_vector[param_index]
230 else:
231 spin.csa_sim[sim_index] = param_vector[param_index]
232
233
234 else:
235 raise RelaxError("Unknown parameter.")
236
237
238 param_index = param_index + 1
239
240
241 if model_type != 'diff':
242
243 if spin:
244 loop = [spin]
245 else:
246 loop = spin_loop(spin_id)
247
248
249 for spin in loop:
250
251 if not spin.select:
252 continue
253
254
255 if sim_index == None:
256
257 if 's2' not in spin.params and 's2f' in spin.params and 's2s' in spin.params:
258 spin.s2 = spin.s2f * spin.s2s
259
260
261 if 's2f' not in spin.params and 's2' in spin.params and 's2s' in spin.params:
262 if spin.s2s == 0.0:
263 spin.s2f = 1e99
264 else:
265 spin.s2f = spin.s2 / spin.s2s
266
267
268 if 's2s' not in spin.params and 's2' in spin.params and 's2f' in spin.params:
269 if spin.s2f == 0.0:
270 spin.s2s = 1e99
271 else:
272 spin.s2s = spin.s2 / spin.s2f
273
274
275 else:
276
277 if 's2' not in spin.params and 's2f' in spin.params and 's2s' in spin.params:
278 spin.s2_sim[sim_index] = spin.s2f_sim[sim_index] * spin.s2s_sim[sim_index]
279
280
281 if 's2f' not in spin.params and 's2' in spin.params and 's2s' in spin.params:
282 if spin.s2s_sim[sim_index] == 0.0:
283 spin.s2f_sim[sim_index] = 1e99
284 else:
285 spin.s2f_sim[sim_index] = spin.s2_sim[sim_index] / spin.s2s_sim[sim_index]
286
287
288 if 's2s' not in spin.params and 's2' in spin.params and 's2f' in spin.params:
289 if spin.s2f_sim[sim_index] == 0.0:
290 spin.s2s_sim[sim_index] = 1e99
291 else:
292 spin.s2s_sim[sim_index] = spin.s2_sim[sim_index] / spin.s2f_sim[sim_index]
293
294
295 - def _disassemble_result(self, param_vector=None, func=None, iter=None, fc=None, gc=None, hc=None, warning=None, spin=None, sim_index=None, model_type=None, scaling=None, scaling_matrix=None):
296 """Disassemble the optimisation results.
297
298 @keyword param_vector: The model-free parameter vector.
299 @type param_vector: numpy array
300 @keyword func: The optimised chi-squared value.
301 @type func: float
302 @keyword iter: The number of optimisation steps required to find the minimum.
303 @type iter: int
304 @keyword fc: The function count.
305 @type fc: int
306 @keyword gc: The gradient count.
307 @type gc: int
308 @keyword hc: The Hessian count.
309 @type hc: int
310 @keyword warning: Any optimisation warnings.
311 @type warning: str or None
312 @keyword spin: The spin container.
313 @type spin: SpinContainer instance or None
314 @keyword sim_index: The Monte Carlo simulation index.
315 @type sim_index: int or None
316 @keyword model_type: The model-free model type, one of 'mf', 'local_tm', 'diff', or
317 'all'.
318 @type model_type: str
319 @keyword scaling: If True, diagonal scaling is enabled during optimisation to
320 allow the problem to be better conditioned.
321 @type scaling: bool
322 @keyword scaling_matrix: The diagonal, square scaling matrix.
323 @type scaling_matrix: numpy diagonal matrix
324 """
325
326
327 cdp = pipes.get_pipe()
328
329
330 if isInf(func):
331 raise RelaxInfError('chi-squared')
332
333
334 if isNaN(func):
335 raise RelaxNaNError('chi-squared')
336
337
338 if scaling:
339 param_vector = dot(scaling_matrix, param_vector)
340
341
342 if sim_index == None:
343
344 chi2 = None
345 if (model_type == 'mf' or model_type == 'local_tm') and hasattr(cdp, 'chi2'):
346 chi2 = spin.chi2
347 if (model_type == 'diff' or model_type == 'all') and hasattr(cdp, 'chi2'):
348 chi2 = cdp.chi2
349
350
351 if chi2 != None and func >= chi2:
352 print("Discarding the optimisation results, the optimised chi-squared value is higher than the current value (%s >= %s)." % (func, chi2))
353
354
355 return
356
357
358 else:
359 print("Storing the optimisation results, the optimised chi-squared value is lower than the current value (%s < %s)." % (func, chi2))
360
361
362 self._disassemble_param_vector(model_type, param_vector=param_vector, spin=spin, sim_index=sim_index)
363
364
365 if sim_index != None:
366
367 if model_type == 'mf' or model_type == 'local_tm':
368
369
370 spin.chi2_sim[sim_index] = func
371
372
373 spin.iter_sim[sim_index] = iter
374
375
376 spin.f_count_sim[sim_index] = fc
377
378
379 spin.g_count_sim[sim_index] = gc
380
381
382 spin.h_count_sim[sim_index] = hc
383
384
385 spin.warning_sim[sim_index] = warning
386
387
388 elif model_type == 'diff' or model_type == 'all':
389
390 cdp.chi2_sim[sim_index] = func
391
392
393 cdp.iter_sim[sim_index] = iter
394
395
396 cdp.f_count_sim[sim_index] = fc
397
398
399 cdp.g_count_sim[sim_index] = gc
400
401
402 cdp.h_count_sim[sim_index] = hc
403
404
405 cdp.warning_sim[sim_index] = warning
406
407
408 else:
409
410 if model_type == 'mf' or model_type == 'local_tm':
411
412 spin.chi2 = func
413
414
415 spin.iter = iter
416
417
418 spin.f_count = fc
419
420
421 spin.g_count = gc
422
423
424 spin.h_count = hc
425
426
427 spin.warning = warning
428
429
430 elif model_type == 'diff' or model_type == 'all':
431
432 cdp.chi2 = func
433
434
435 cdp.iter = iter
436
437
438 cdp.f_count = fc
439
440
441 cdp.g_count = gc
442
443
444 cdp.h_count = hc
445
446
447 cdp.warning = warning
448
449
450 - def _grid_search_config(self, num_params, spin=None, spin_id=None, lower=None, upper=None, inc=None, scaling_matrix=None, verbosity=1):
451 """Configure the grid search.
452
453 @param num_params: The number of parameters in the model.
454 @type num_params: int
455 @keyword spin: The spin data container.
456 @type spin: SpinContainer instance
457 @keyword spin_id: The spin identification string.
458 @type spin_id: str
459 @keyword lower: The lower bounds of the grid search which must be equal to the
460 number of parameters in the model.
461 @type lower: array of numbers
462 @keyword upper: The upper bounds of the grid search which must be equal to the
463 number of parameters in the model.
464 @type upper: array of numbers
465 @keyword inc: The increments for each dimension of the space for the grid
466 search. The number of elements in the array must equal to the
467 number of parameters in the model.
468 @type inc: array of int
469 @keyword scaling_matrix: The diagonal, square scaling matrix.
470 @type scaling_matrix: numpy diagonal matrix
471 @keyword verbosity: A flag specifying the amount of information to print. The
472 higher the value, the greater the verbosity.
473 @type verbosity: int
474 """
475
476
477 self.test_grid_ops(lower=lower, upper=upper, inc=inc, n=num_params)
478
479
480 if isinstance(inc, int):
481 inc = [inc]*num_params
482
483
484 if not lower:
485
486 lower = []
487 upper = []
488
489
490 model_type = self._determine_model_type()
491
492
493 if model_type == 'diff' or model_type == 'all':
494
495 self._grid_search_diff_bounds(lower, upper)
496
497
498 if model_type != 'diff':
499
500 if spin:
501 loop = [spin]
502 else:
503 loop = spin_loop(spin_id)
504
505
506 for spin in loop:
507
508 if not spin.select:
509 continue
510
511
512 self._grid_search_spin_bounds(spin, lower, upper)
513
514
515 lower_new = []
516 upper_new = []
517 for i in xrange(num_params):
518 lower_new.append(lower[i] / scaling_matrix[i, i])
519 upper_new.append(upper[i] / scaling_matrix[i, i])
520
521
522 return inc, lower_new, upper_new
523
524
526 """Set up the default grid search bounds the diffusion tensor.
527
528 This method appends the default bounds to the lower and upper lists.
529
530 @param lower: The lower bound list to append to.
531 @type lower: list
532 @param upper: The upper bound list to append to.
533 @type upper: list
534 """
535
536
537 if cdp.diff_tensor.type == 'sphere':
538 lower.append(1.0 * 1e-9)
539 upper.append(12.0 * 1e-9)
540
541
542 if cdp.diff_tensor.type == 'spheroid':
543
544 lower.append(1.0 * 1e-9)
545 upper.append(12.0 * 1e-9)
546
547
548 if cdp.diff_tensor.spheroid_type == 'prolate':
549 lower.append(0.0)
550 upper.append(1e7)
551 elif cdp.diff_tensor.spheroid_type == 'oblate':
552 lower.append(-1e7)
553 upper.append(0.0)
554 else:
555 lower.append(-1e7)
556 upper.append(1e7)
557
558
559 lower.append(0.0)
560 upper.append(pi)
561
562
563 lower.append(0.0)
564 upper.append(pi)
565
566
567 elif cdp.diff_tensor.type == 'ellipsoid':
568
569 lower.append(1.0 * 1e-9)
570 upper.append(12.0 * 1e-9)
571
572
573 lower.append(0.0)
574 upper.append(1e7)
575
576
577 lower.append(0.0)
578 upper.append(1.0)
579
580
581 lower.append(0.0)
582 upper.append(pi)
583
584
585 lower.append(0.0)
586 upper.append(pi)
587
588
589 lower.append(0.0)
590 upper.append(pi)
591
592
594 """Set up the default grid search bounds for a single spin.
595
596 This method appends the default bounds to the lower and upper lists. The ordering of the
597 lists in min_options matches that of the params list in the spin container.
598
599 @param spin: A SpinContainer object.
600 @type spin: class instance
601 @param lower: The lower bound list to append to.
602 @type lower: list
603 @param upper: The upper bound list to append to.
604 @type upper: list
605 """
606
607
608 for i in xrange(len(spin.params)):
609
610 if spin.params[i] == 'local_tm':
611 lower.append(1.0 * 1e-9)
612 upper.append(12.0 * 1e-9)
613
614
615 elif match('s2', spin.params[i]):
616 lower.append(0.0)
617 upper.append(1.0)
618
619
620 elif match('t', spin.params[i]):
621 lower.append(0.0)
622 upper.append(500.0 * 1e-12)
623
624
625 elif spin.params[i] == 'rex':
626 lower.append(0.0)
627 upper.append(5.0 / (2.0 * pi * cdp.frq[cdp.ri_ids[0]])**2)
628
629
630 elif spin.params[i] == 'r':
631 lower.append(1.0 * 1e-10)
632 upper.append(1.05 * 1e-10)
633
634
635 elif spin.params[i] == 'csa':
636 lower.append(-120 * 1e-6)
637 upper.append(-200 * 1e-6)
638
639
640 else:
641 raise RelaxError("Unknown model-free parameter.")
642
643
644 - def _linear_constraints(self, num_params, model_type=None, spin=None, spin_id=None, scaling_matrix=None):
645 """Set up the model-free linear constraint matrices A and b.
646
647 Standard notation
648 =================
649
650 The order parameter constraints are::
651
652 0 <= S2 <= 1
653 0 <= S2f <= 1
654 0 <= S2s <= 1
655
656 By substituting the formula S2 = S2f.S2s into the above inequalities, the additional two
657 inequalities can be derived::
658
659 S2 <= S2f
660 S2 <= S2s
661
662 Correlation time constraints are::
663
664 te >= 0
665 tf >= 0
666 ts >= 0
667
668 tf <= ts
669
670 te, tf, ts <= 2 * tm
671
672 Additional constraints used include::
673
674 Rex >= 0
675 0.9e-10 <= r <= 2e-10
676 -300e-6 <= CSA <= 0
677
678
679 Rearranged notation
680 ===================
681
682 The above inequality constraints can be rearranged into::
683
684 S2 >= 0
685 -S2 >= -1
686 S2f >= 0
687 -S2f >= -1
688 S2s >= 0
689 -S2s >= -1
690 S2f - S2 >= 0
691 S2s - S2 >= 0
692 te >= 0
693 tf >= 0
694 ts >= 0
695 ts - tf >= 0
696 Rex >= 0
697 r >= 0.9e-10
698 -r >= -2e-10
699 CSA >= -300e-6
700 -CSA >= 0
701
702
703 Matrix notation
704 ===============
705
706 In the notation A.x >= b, where A is an matrix of coefficients, x is an array of parameter
707 values, and b is a vector of scalars, these inequality constraints are::
708
709 | 1 0 0 0 0 0 0 0 0 | | 0 |
710 | | | |
711 |-1 0 0 0 0 0 0 0 0 | | -1 |
712 | | | |
713 | 0 1 0 0 0 0 0 0 0 | | 0 |
714 | | | |
715 | 0 -1 0 0 0 0 0 0 0 | | -1 |
716 | | | |
717 | 0 0 1 0 0 0 0 0 0 | | S2 | | 0 |
718 | | | | | |
719 | 0 0 -1 0 0 0 0 0 0 | | S2f | | -1 |
720 | | | | | |
721 |-1 1 0 0 0 0 0 0 0 | | S2s | | 0 |
722 | | | | | |
723 |-1 0 1 0 0 0 0 0 0 | | te | | 0 |
724 | | | | | |
725 | 0 0 0 1 0 0 0 0 0 | . | tf | >= | 0 |
726 | | | | | |
727 | 0 0 0 0 1 0 0 0 0 | | ts | | 0 |
728 | | | | | |
729 | 0 0 0 0 0 1 0 0 0 | | Rex | | 0 |
730 | | | | | |
731 | 0 0 0 0 -1 1 0 0 0 | | r | | 0 |
732 | | | | | |
733 | 0 0 0 0 0 0 1 0 0 | | CSA | | 0 |
734 | | | |
735 | 0 0 0 0 0 0 0 1 0 | | 0.9e-10 |
736 | | | |
737 | 0 0 0 0 0 0 0 -1 0 | | -2e-10 |
738 | | | |
739 | 0 0 0 0 0 0 0 0 1 | | -300e-6 |
740 | | | |
741 | 0 0 0 0 0 0 0 0 -1 | | 0 |
742
743
744 @param num_params: The number of parameters in the model.
745 @type num_params: int
746 @keyword model_type: The model type, one of 'all', 'diff', 'mf', or 'local_tm'.
747 @type model_type: str
748 @keyword spin: The spin data container. If this argument is supplied, then the
749 spin_id argument will be ignored.
750 @type spin: SpinContainer instance
751 @keyword spin_id: The spin identification string.
752 @type spin_id: str
753 @keyword scaling_matrix: The diagonal, square scaling matrix.
754 @type scaling_matrix: numpy diagonal matrix
755 """
756
757
758 upper_time_limit = 1
759
760
761 A = []
762 b = []
763 zero_array = zeros(num_params, float64)
764 i = 0
765 j = 0
766
767
768 if model_type != 'mf' and diffusion_tensor.diff_data_exists():
769
770 if cdp.diff_tensor.type == 'sphere':
771
772 A.append(zero_array * 0.0)
773 A.append(zero_array * 0.0)
774 A[j][i] = 1.0
775 A[j+1][i] = -1.0
776 b.append(0.0 / scaling_matrix[i, i])
777 b.append(-200.0 * 1e-9 / scaling_matrix[i, i])
778 i = i + 1
779 j = j + 2
780
781
782 elif cdp.diff_tensor.type == 'spheroid':
783
784 A.append(zero_array * 0.0)
785 A.append(zero_array * 0.0)
786 A[j][i] = 1.0
787 A[j+1][i] = -1.0
788 b.append(0.0 / scaling_matrix[i, i])
789 b.append(-200.0 * 1e-9 / scaling_matrix[i, i])
790 i = i + 1
791 j = j + 2
792
793
794 if cdp.diff_tensor.spheroid_type == 'prolate':
795 A.append(zero_array * 0.0)
796 A[j][i] = 1.0
797 b.append(0.0 / scaling_matrix[i, i])
798 i = i + 1
799 j = j + 1
800
801
802 i = i + 2
803
804
805 elif cdp.diff_tensor.spheroid_type == 'oblate':
806 A.append(zero_array * 0.0)
807 A[j][i] = -1.0
808 b.append(0.0 / scaling_matrix[i, i])
809 i = i + 1
810 j = j + 1
811
812
813 i = i + 2
814
815 else:
816
817 i = i + 3
818
819
820 elif cdp.diff_tensor.type == 'ellipsoid':
821
822 A.append(zero_array * 0.0)
823 A.append(zero_array * 0.0)
824 A[j][i] = 1.0
825 A[j+1][i] = -1.0
826 b.append(0.0 / scaling_matrix[i, i])
827 b.append(-200.0 * 1e-9 / scaling_matrix[i, i])
828 i = i + 1
829 j = j + 2
830
831
832 A.append(zero_array * 0.0)
833 A[j][i] = 1.0
834 b.append(0.0 / scaling_matrix[i, i])
835 i = i + 1
836 j = j + 1
837
838
839 A.append(zero_array * 0.0)
840 A.append(zero_array * 0.0)
841 A[j][i] = 1.0
842 A[j+1][i] = -1.0
843 b.append(0.0 / scaling_matrix[i, i])
844 b.append(-1.0 / scaling_matrix[i, i])
845 i = i + 1
846 j = j + 2
847
848
849 i = i + 3
850
851
852 if model_type != 'diff':
853
854 if spin:
855 loop = [spin]
856 else:
857 loop = spin_loop(spin_id)
858
859
860 for spin in loop:
861
862 if not spin.select:
863 continue
864
865
866 old_i = i
867
868
869 for l in xrange(len(spin.params)):
870
871 if spin.params[l] == 'local_tm':
872 if upper_time_limit:
873
874 A.append(zero_array * 0.0)
875 A.append(zero_array * 0.0)
876 A[j][i] = 1.0
877 A[j+1][i] = -1.0
878 b.append(0.0 / scaling_matrix[i, i])
879 b.append(-200.0 * 1e-9 / scaling_matrix[i, i])
880 j = j + 2
881 else:
882
883 A.append(zero_array * 0.0)
884 A[j][i] = 1.0
885 b.append(0.0 / scaling_matrix[i, i])
886 j = j + 1
887
888
889 elif match('s2', spin.params[l]):
890
891 A.append(zero_array * 0.0)
892 A.append(zero_array * 0.0)
893 A[j][i] = 1.0
894 A[j+1][i] = -1.0
895 b.append(0.0 / scaling_matrix[i, i])
896 b.append(-1.0 / scaling_matrix[i, i])
897 j = j + 2
898
899
900 if spin.params[l] == 's2':
901 for m in xrange(len(spin.params)):
902 if spin.params[m] == 's2f' or spin.params[m] == 's2s':
903 A.append(zero_array * 0.0)
904 A[j][i] = -1.0
905 A[j][old_i+m] = 1.0
906 b.append(0.0)
907 j = j + 1
908
909
910 elif match('t[efs]', spin.params[l]):
911
912 A.append(zero_array * 0.0)
913 A[j][i] = 1.0
914 b.append(0.0 / scaling_matrix[i, i])
915 j = j + 1
916
917
918 if spin.params[l] == 'ts':
919 for m in xrange(len(spin.params)):
920 if spin.params[m] == 'tf':
921 A.append(zero_array * 0.0)
922 A[j][i] = 1.0
923 A[j][old_i+m] = -1.0
924 b.append(0.0)
925 j = j + 1
926
927
928 if upper_time_limit:
929 if not spin.params[l] == 'tf':
930 if model_type == 'mf':
931 A.append(zero_array * 0.0)
932 A[j][i] = -1.0
933 b.append(-2.0 * cdp.diff_tensor.tm / scaling_matrix[i, i])
934 else:
935 A.append(zero_array * 0.0)
936 A[j][0] = 2.0
937 A[j][i] = -1.0
938 b.append(0.0)
939
940 j = j + 1
941
942
943 elif spin.params[l] == 'rex':
944 A.append(zero_array * 0.0)
945 A[j][i] = 1.0
946 b.append(0.0 / scaling_matrix[i, i])
947 j = j + 1
948
949
950 elif spin.params[l] == 'r':
951
952 A.append(zero_array * 0.0)
953 A.append(zero_array * 0.0)
954 A[j][i] = 1.0
955 A[j+1][i] = -1.0
956 b.append(0.9e-10 / scaling_matrix[i, i])
957 b.append(-2e-10 / scaling_matrix[i, i])
958 j = j + 2
959
960
961 elif spin.params[l] == 'csa':
962
963 A.append(zero_array * 0.0)
964 A.append(zero_array * 0.0)
965 A[j][i] = 1.0
966 A[j+1][i] = -1.0
967 b.append(-300e-6 / scaling_matrix[i, i])
968 b.append(0.0 / scaling_matrix[i, i])
969 j = j + 2
970
971
972 i = i + 1
973
974
975 A = array(A, int8)
976 b = array(b, float64)
977
978 return A, b
979
980
981 - def _minimise_data_setup(self, data_store, min_algor, num_data_sets, min_options, spin=None, sim_index=None):
982 """Set up all the data required for minimisation.
983
984 @param data_store: A data storage container.
985 @type data_store: class instance
986 @param min_algor: The minimisation algorithm to use.
987 @type min_algor: str
988 @param num_data_sets: The number of data sets.
989 @type num_data_sets: int
990 @param min_options: The minimisation options array.
991 @type min_options: list
992 @keyword spin: The spin data container.
993 @type spin: SpinContainer instance
994 @keyword sim_index: The optional MC simulation index.
995 @type sim_index: int
996 @return: An insane tuple. The full tuple is (ri_data, ri_data_err, equations, param_types, param_values, r, csa, num_frq, frq, num_ri, remap_table, noe_r1_table, ri_types, num_params, xh_unit_vectors, diff_type, diff_params)
997 @rtype: tuple
998 """
999
1000
1001 data_store.ri_data = []
1002 data_store.ri_data_err = []
1003 data_store.equations = []
1004 data_store.param_types = []
1005 data_store.param_values = None
1006 data_store.r = []
1007 data_store.csa = []
1008 data_store.num_frq = []
1009 data_store.frq = []
1010 data_store.num_ri = []
1011 data_store.remap_table = []
1012 data_store.noe_r1_table = []
1013 data_store.ri_types = []
1014 data_store.gx = []
1015 data_store.gh = []
1016 data_store.num_params = []
1017 data_store.xh_unit_vectors = []
1018 if data_store.model_type == 'local_tm':
1019 data_store.mf_params = []
1020 elif data_store.model_type == 'diff':
1021 data_store.param_values = []
1022
1023
1024 if min_algor == 'back_calc':
1025
1026 data_store.ri_data = [0.0]
1027 data_store.ri_data_err = [0.000001]
1028 data_store.equations = [spin.equation]
1029 data_store.param_types = [spin.params]
1030 data_store.r = [spin.r]
1031 data_store.csa = [spin.csa]
1032 data_store.num_frq = [1]
1033 data_store.frq = [[min_options[3]]]
1034 data_store.num_ri = [1]
1035 data_store.remap_table = [[0]]
1036 data_store.noe_r1_table = [[None]]
1037 data_store.ri_types = [[min_options[2]]]
1038 data_store.gx = [return_gyromagnetic_ratio(spin.heteronuc_type)]
1039 data_store.gh = [return_gyromagnetic_ratio(spin.proton_type)]
1040 if data_store.model_type != 'local_tm' and cdp.diff_tensor.type != 'sphere':
1041 data_store.xh_unit_vectors = [spin.xh_vect]
1042 else:
1043 data_store.xh_unit_vectors = [None]
1044
1045
1046 data_store.num_params = [len(spin.params)]
1047
1048
1049 for j in xrange(num_data_sets):
1050
1051 if data_store.model_type == 'diff' or data_store.model_type == 'all':
1052 spin_index = j
1053 spin, data_store.spin_id = return_spin_from_index(global_index=spin_index, return_spin_id=True)
1054
1055
1056 if not spin.select:
1057 continue
1058
1059
1060 if not hasattr(spin, 'ri_data') or not hasattr(spin, 'ri_data_err'):
1061 continue
1062
1063
1064 for ri_id in cdp.ri_ids:
1065
1066 err = spin.ri_data_err[ri_id]
1067
1068
1069 if err != None and err == 0.0:
1070 raise RelaxError("Zero error for spin '%s' for the relaxation data ID '%s', minimisation not possible." % (errid))
1071 elif err != None and err < 0.0:
1072 raise RelaxError("Negative error of %s for spin '%s' for the relaxation data ID '%s', minimisation not possible." % (err, data_store.spin_id, ri_id))
1073
1074
1075 data = self._relax_data_opt_structs(spin, sim_index=sim_index)
1076
1077
1078 data_store.ri_data.append(data[0])
1079 data_store.ri_data_err.append(data[1])
1080 data_store.num_frq.append(data[2])
1081 data_store.num_ri.append(data[3])
1082 data_store.ri_types.append(data[4])
1083 data_store.frq.append(data[5])
1084 data_store.remap_table.append(data[6])
1085 data_store.noe_r1_table.append(data[7])
1086
1087
1088 data_store.equations.append(spin.equation)
1089 data_store.param_types.append(spin.params)
1090 data_store.gx.append(return_gyromagnetic_ratio(spin.heteronuc_type))
1091 data_store.gh.append(return_gyromagnetic_ratio(spin.proton_type))
1092 if sim_index == None or data_store.model_type == 'diff':
1093 data_store.r.append(spin.r)
1094 data_store.csa.append(spin.csa)
1095 else:
1096 data_store.r.append(spin.r_sim[sim_index])
1097 data_store.csa.append(spin.csa_sim[sim_index])
1098
1099
1100 if data_store.model_type == 'local_tm':
1101 pass
1102
1103
1104 if data_store.model_type != 'local_tm' and cdp.diff_tensor.type != 'sphere':
1105
1106 if arg_check.is_num_list(spin.xh_vect[0], raise_error=False):
1107 raise RelaxMultiVectorError(data_store.spin_id)
1108
1109
1110 data_store.xh_unit_vectors.append(spin.xh_vect)
1111
1112
1113 else:
1114 data_store.xh_unit_vectors.append(None)
1115
1116
1117 data_store.num_params.append(len(spin.params))
1118
1119
1120 if data_store.model_type == 'diff':
1121 data_store.param_values.append(self._assemble_param_vector(model_type='mf'))
1122
1123
1124 for k in xrange(len(data_store.ri_data)):
1125 data_store.ri_data[k] = array(data_store.ri_data[k], float64)
1126 data_store.ri_data_err[k] = array(data_store.ri_data_err[k], float64)
1127
1128
1129 if data_store.model_type == 'local_tm':
1130 data_store.diff_type = 'sphere'
1131 else:
1132 data_store.diff_type = cdp.diff_tensor.type
1133
1134
1135 data_store.diff_params = None
1136 if data_store.model_type == 'mf':
1137
1138 if data_store.diff_type == 'sphere':
1139 data_store.diff_params = [cdp.diff_tensor.tm]
1140
1141
1142 elif data_store.diff_type == 'spheroid':
1143 data_store.diff_params = [cdp.diff_tensor.tm, cdp.diff_tensor.Da, cdp.diff_tensor.theta, cdp.diff_tensor.phi]
1144
1145
1146 elif data_store.diff_type == 'ellipsoid':
1147 data_store.diff_params = [cdp.diff_tensor.tm, cdp.diff_tensor.Da, cdp.diff_tensor.Dr, cdp.diff_tensor.alpha, cdp.diff_tensor.beta, cdp.diff_tensor.gamma]
1148 elif min_algor == 'back_calc' and data_store.model_type == 'local_tm':
1149
1150 data_store.diff_params = [spin.local_tm]
1151
1152
1154 """Package the relaxation data into the data structures used for optimisation.
1155
1156 @param spin: The spin container to extract the data from.
1157 @type spin: SpinContainer instance
1158 @keyword sim_index: The optional MC simulation index.
1159 @type sim_index: int
1160 @return: The structures ri_data, ri_data_err, num_frq, num_ri, ri_ids, frq, remap_table, noe_r1_table.
1161 @rtype: tuple
1162 """
1163
1164
1165 ri_data = []
1166 ri_data_err = []
1167 ri_labels = []
1168 frq = []
1169 remap_table = []
1170 noe_r1_table = []
1171
1172
1173 for ri_id in cdp.ri_ids:
1174
1175 if sim_index == None:
1176 data = spin.ri_data[ri_id]
1177 else:
1178 data = spin.ri_data_sim[ri_id][sim_index]
1179
1180
1181 err = spin.ri_data_err[ri_id]
1182
1183
1184 if data == None or err == None:
1185 continue
1186
1187
1188 ri_data.append(data)
1189 ri_data_err.append(err)
1190
1191
1192 ri_labels.append(cdp.ri_type[ri_id])
1193
1194
1195 if cdp.frq[ri_id] not in frq:
1196 frq.append(cdp.frq[ri_id])
1197
1198
1199 remap_table.append(frq.index(cdp.frq[ri_id]))
1200
1201
1202 noe_r1_table.append(None)
1203
1204
1205 num_ri = len(ri_data)
1206
1207
1208 for i in range(num_ri):
1209
1210 if cdp.ri_type[cdp.ri_ids[i]] == 'NOE':
1211 for j in range(num_ri):
1212 if cdp.ri_type[cdp.ri_ids[j]] == 'R1' and cdp.frq[cdp.ri_ids[i]] == cdp.frq[cdp.ri_ids[j]]:
1213 noe_r1_table[i] = j
1214
1215
1216 return ri_data, ri_data_err, len(frq), num_ri, ri_labels, frq, remap_table, noe_r1_table
1217
1218
1220 """Reset all the minimisation statistics.
1221
1222 All global and spin specific values will be set to None.
1223 """
1224
1225
1226 if hasattr(cdp, 'chi2'):
1227 cdp.chi2 = None
1228 cdp.iter = None
1229 cdp.f_count = None
1230 cdp.g_count = None
1231 cdp.h_count = None
1232 cdp.warning = None
1233
1234
1235 for spin in spin_loop():
1236 if hasattr(spin, 'chi2'):
1237 spin.chi2 = None
1238 spin.iter = None
1239 spin.f_count = None
1240 spin.g_count = None
1241 spin.h_count = None
1242 spin.warning = None
1243
1244
1245 - def calculate(self, spin_id=None, verbosity=1, sim_index=None):
1246 """Calculation of the model-free chi-squared value.
1247
1248 @keyword spin_id: The spin identification string.
1249 @type spin_id: str
1250 @keyword verbosity: The amount of information to print. The higher the value, the greater the verbosity.
1251 @type verbosity: int
1252 @keyword sim_index: The optional MC simulation index.
1253 @type sim_index: int
1254 """
1255
1256
1257 if not exists_mol_res_spin_data():
1258 raise RelaxNoSequenceError
1259
1260
1261 model_type = self._determine_model_type()
1262
1263
1264 if model_type != 'local_tm' and not diff_data_exists():
1265 raise RelaxNoTensorError('diffusion')
1266
1267
1268 if model_type != 'local_tm' and cdp.diff_tensor.type != 'sphere' and not hasattr(cdp, 'structure'):
1269 raise RelaxNoPdbError
1270
1271
1272 for spin, id in spin_loop(spin_id, return_id=True):
1273
1274 if not spin.select:
1275 continue
1276
1277
1278 if not spin.model:
1279 raise RelaxNoModelError
1280
1281
1282 if model_type != 'local_tm' and cdp.diff_tensor.type != 'sphere' and not hasattr(spin, 'xh_vect'):
1283 raise RelaxNoVectorsError
1284
1285
1286 if model_type != 'local_tm' and cdp.diff_tensor.type != 'sphere' and hasattr(spin, 'xh_vect') and arg_check.is_num_list(spin.xh_vect[0], raise_error=False):
1287 raise RelaxMultiVectorError
1288
1289
1290 if not hasattr(spin, 'heteronuc_type'):
1291 raise RelaxSpinTypeError
1292
1293
1294 if not hasattr(spin, 'proton_type'):
1295 raise RelaxProtonTypeError
1296
1297
1298 unset_param = self._are_mf_params_set(spin)
1299 if unset_param != None:
1300 raise RelaxNoValueError(unset_param)
1301
1302
1303 if not hasattr(spin, 'csa') or spin.csa == None:
1304 raise RelaxNoValueError("CSA")
1305
1306
1307 if not hasattr(spin, 'r') or spin.r == None:
1308 raise RelaxNoValueError("bond length")
1309
1310
1311 if not hasattr(spin, 'ri_data') or not hasattr(spin, 'ri_data_err'):
1312 continue
1313
1314
1315 for ri_id in cdp.ri_ids:
1316
1317 err = spin.ri_data_err[ri_id]
1318
1319
1320 if err != None and err == 0.0:
1321 raise RelaxError("Zero error for spin '%s' for the relaxation data ID '%s', minimisation not possible." % (id, ri_id))
1322 elif err != None and err < 0.0:
1323 raise RelaxError("Negative error of %s for spin '%s' for the relaxation data ID '%s', minimisation not possible." % (err, id, ri_id))
1324
1325
1326 param_vector = self._assemble_param_vector(spin=spin, sim_index=sim_index)
1327
1328
1329 data = self._relax_data_opt_structs(spin, sim_index=sim_index)
1330
1331
1332 ri_data = [array(data[0])]
1333 ri_data_err = [array(data[1])]
1334 num_frq = [data[2]]
1335 num_ri = [data[3]]
1336 ri_labels = [data[4]]
1337 frq = [data[5]]
1338 remap_table = [data[6]]
1339 noe_r1_table = [data[7]]
1340
1341
1342 if sim_index == None:
1343 r = [spin.r]
1344 csa = [spin.csa]
1345 else:
1346 r = [spin.r_sim[sim_index]]
1347 csa = [spin.csa_sim[sim_index]]
1348
1349
1350 if model_type != 'local_tm' and cdp.diff_tensor.type != 'sphere':
1351 xh_unit_vectors = [spin.xh_vect]
1352 else:
1353 xh_unit_vectors = [None]
1354
1355
1356 gx = [return_gyromagnetic_ratio(spin.heteronuc_type)]
1357 gh = [return_gyromagnetic_ratio(spin.proton_type)]
1358
1359
1360 num_params = [len(spin.params)]
1361
1362
1363 param_values = [self._assemble_param_vector(model_type='mf')]
1364
1365
1366 if model_type == 'local_tm':
1367 diff_params = [spin.local_tm]
1368 diff_type = 'sphere'
1369 else:
1370
1371 diff_type = cdp.diff_tensor.type
1372
1373
1374 if diff_type == 'sphere':
1375 diff_params = [cdp.diff_tensor.tm]
1376
1377
1378 elif diff_type == 'spheroid':
1379 diff_params = [cdp.diff_tensor.tm, cdp.diff_tensor.Da, cdp.diff_tensor.theta, cdp.diff_tensor.phi]
1380
1381
1382 elif diff_type == 'ellipsoid':
1383 diff_params = [cdp.diff_tensor.tm, cdp.diff_tensor.Da, cdp.diff_tensor.Dr, cdp.diff_tensor.alpha, cdp.diff_tensor.beta, cdp.diff_tensor.gamma]
1384
1385
1386 mf = Mf(init_params=param_vector, model_type='mf', diff_type=diff_type, diff_params=diff_params, num_spins=1, equations=[spin.equation], param_types=[spin.params], param_values=param_values, relax_data=ri_data, errors=ri_data_err, bond_length=r, csa=csa, num_frq=num_frq, frq=frq, num_ri=num_ri, remap_table=remap_table, noe_r1_table=noe_r1_table, ri_labels=ri_labels, gx=gx, gh=gh, h_bar=h_bar, mu0=mu0, num_params=num_params, vectors=xh_unit_vectors)
1387
1388
1389 try:
1390 chi2 = mf.func(param_vector)
1391 except OverflowError:
1392 chi2 = 1e200
1393
1394
1395 if model_type == 'all' or model_type == 'diff':
1396 cdp.chi2 = cdp.chi2 + chi2
1397 else:
1398 spin.chi2 = chi2
1399
1400
1401 - def grid_search(self, lower=None, upper=None, inc=None, constraints=True, verbosity=1, sim_index=None):
1402 """The model-free grid search function.
1403
1404 @keyword lower: The lower bounds of the grid search which must be equal to the
1405 number of parameters in the model.
1406 @type lower: array of numbers
1407 @keyword upper: The upper bounds of the grid search which must be equal to the
1408 number of parameters in the model.
1409 @type upper: array of numbers
1410 @keyword inc: The increments for each dimension of the space for the grid search.
1411 The number of elements in the array must equal to the number of
1412 parameters in the model.
1413 @type inc: array of int
1414 @keyword constraints: If True, constraints are applied during the grid search (eliminating
1415 parts of the grid). If False, no constraints are used.
1416 @type constraints: bool
1417 @keyword verbosity: A flag specifying the amount of information to print. The higher
1418 the value, the greater the verbosity.
1419 @type verbosity: int
1420 @keyword sim_index: The index of the simulation to apply the grid search to. If None,
1421 the normal model is optimised.
1422 @type sim_index: int
1423 """
1424
1425
1426 self.minimise(min_algor='grid', lower=lower, upper=upper, inc=inc, constraints=constraints, verbosity=verbosity, sim_index=sim_index)
1427
1428
1429 - def minimise(self, min_algor=None, min_options=None, func_tol=None, grad_tol=None, max_iterations=None, constraints=False, scaling=True, verbosity=0, sim_index=None, lower=None, upper=None, inc=None):
1430 """Model-free minimisation function.
1431
1432 Three categories of models exist for which the approach to minimisation is different. These
1433 are:
1434
1435 Single spin optimisations: The 'mf' and 'local_tm' model types which are the
1436 model-free parameters for single spins, optionally with a local tm parameter. These
1437 models have no global parameters.
1438
1439 Diffusion tensor optimisations: The 'diff' diffusion tensor model type. No spin
1440 specific parameters exist.
1441
1442 Optimisation of everything: The 'all' model type consisting of all model-free and all
1443 diffusion tensor parameters.
1444
1445
1446 @keyword min_algor: The minimisation algorithm to use.
1447 @type min_algor: str
1448 @keyword min_options: An array of options to be used by the minimisation algorithm.
1449 @type min_options: array of str
1450 @keyword func_tol: The function tolerance which, when reached, terminates optimisation.
1451 Setting this to None turns of the check.
1452 @type func_tol: None or float
1453 @keyword grad_tol: The gradient tolerance which, when reached, terminates optimisation.
1454 Setting this to None turns of the check.
1455 @type grad_tol: None or float
1456 @keyword max_iterations: The maximum number of iterations for the algorithm.
1457 @type max_iterations: int
1458 @keyword constraints: If True, constraints are used during optimisation.
1459 @type constraints: bool
1460 @keyword scaling: If True, diagonal scaling is enabled during optimisation to allow
1461 the problem to be better conditioned.
1462 @type scaling: bool
1463 @keyword verbosity: The amount of information to print. The higher the value, the
1464 greater the verbosity.
1465 @type verbosity: int
1466 @keyword sim_index: The index of the simulation to optimise. This should be None if
1467 normal optimisation is desired.
1468 @type sim_index: None or int
1469 @keyword lower: The lower bounds of the grid search which must be equal to the
1470 number of parameters in the model. This optional argument is only
1471 used when doing a grid search.
1472 @type lower: array of numbers
1473 @keyword upper: The upper bounds of the grid search which must be equal to the
1474 number of parameters in the model. This optional argument is only
1475 used when doing a grid search.
1476 @type upper: array of numbers
1477 @keyword inc: The increments for each dimension of the space for the grid search.
1478 The number of elements in the array must equal to the number of
1479 parameters in the model. This argument is only used when doing a
1480 grid search.
1481 @type inc: array of int
1482 """
1483
1484
1485 if not exists_mol_res_spin_data():
1486 raise RelaxNoSequenceError
1487
1488
1489 for spin in spin_loop():
1490
1491 if not spin.select:
1492 continue
1493
1494
1495 if not spin.model:
1496 raise RelaxNoModelError
1497
1498
1499 if not hasattr(spin, 'heteronuc_type'):
1500 raise RelaxSpinTypeError
1501
1502
1503 if not hasattr(spin, 'proton_type'):
1504 raise RelaxProtonTypeError
1505
1506
1507 if sim_index == None and min_algor != 'back_calc':
1508 self._reset_min_stats()
1509
1510
1511 data_store = Data_container()
1512 opt_params = Data_container()
1513
1514
1515 data_store.h_bar = h_bar
1516 data_store.mu0 = mu0
1517 opt_params.min_algor = min_algor
1518 opt_params.min_options = min_options
1519 opt_params.func_tol = func_tol
1520 opt_params.grad_tol = grad_tol
1521 opt_params.max_iterations = max_iterations
1522
1523
1524 opt_params.verbosity = verbosity
1525
1526
1527 data_store.model_type = self._determine_model_type()
1528 if not data_store.model_type:
1529 return
1530
1531
1532 if min_algor == 'back_calc' and data_store.model_type != 'local_tm':
1533 data_store.model_type = 'mf'
1534
1535
1536 if data_store.model_type != 'local_tm' and not diffusion_tensor.diff_data_exists():
1537 raise RelaxNoTensorError('diffusion')
1538
1539
1540 if data_store.model_type != 'local_tm' and cdp.diff_tensor.type != 'sphere':
1541
1542 if not hasattr(cdp, 'structure'):
1543 raise RelaxNoPdbError
1544
1545
1546 for spin in spin_loop():
1547
1548 if not spin.select:
1549 continue
1550
1551
1552 if not hasattr(spin, 'xh_vect'):
1553 raise RelaxNoVectorsError
1554
1555
1556 if data_store.model_type == 'diff':
1557
1558 for spin in spin_loop():
1559 unset_param = self._are_mf_params_set(spin)
1560 if unset_param != None:
1561 raise RelaxNoValueError(unset_param)
1562
1563
1564 if verbosity >= 1:
1565 if data_store.model_type == 'mf':
1566 print("Only the model-free parameters for single spins will be used.")
1567 elif data_store.model_type == 'local_mf':
1568 print("Only a local tm value together with the model-free parameters for single spins will be used.")
1569 elif data_store.model_type == 'diff':
1570 print("Only diffusion tensor parameters will be used.")
1571 elif data_store.model_type == 'all':
1572 print("The diffusion tensor parameters together with the model-free parameters for all spins will be used.")
1573
1574
1575 for spin in spin_loop():
1576
1577 if not spin.select:
1578 continue
1579
1580
1581 if not hasattr(spin, 'csa') or spin.csa == None:
1582 raise RelaxNoValueError("CSA")
1583
1584
1585 if not hasattr(spin, 'r') or spin.r == None:
1586 raise RelaxNoValueError("bond length")
1587
1588
1589 if data_store.model_type == 'mf' or data_store.model_type == 'local_tm':
1590 num_instances = count_spins(skip_desel=False)
1591 num_data_sets = 1
1592 data_store.num_spins = 1
1593 elif data_store.model_type == 'diff' or data_store.model_type == 'all':
1594 num_instances = 1
1595 num_data_sets = count_spins(skip_desel=False)
1596 data_store.num_spins = count_spins()
1597
1598
1599 if min_algor == 'back_calc':
1600 num_instances = 1
1601 num_data_sets = 0
1602 data_store.num_spins = 1
1603
1604
1605 processor_box = Processor_box()
1606 processor = processor_box.processor
1607
1608
1609
1610
1611 for i in xrange(num_instances):
1612
1613 if data_store.model_type == 'diff' or data_store.model_type == 'all':
1614 spin_index = None
1615 spin, data_store.spin_id = None, None
1616 elif min_algor == 'back_calc':
1617 spin_index = opt_params.min_options[0]
1618 spin, data_store.spin_id = return_spin_from_index(global_index=spin_index, return_spin_id=True)
1619 else:
1620 spin_index = i
1621 spin, data_store.spin_id = return_spin_from_index(global_index=spin_index, return_spin_id=True)
1622
1623
1624 if spin and (data_store.model_type == 'mf' or data_store.model_type == 'local_tm') and not min_algor == 'back_calc':
1625
1626 if not spin.select:
1627 continue
1628
1629
1630 if not hasattr(spin, 'ri_data') or not hasattr(spin, 'ri_data_err'):
1631 continue
1632
1633
1634 if min_algor == 'back_calc':
1635
1636 opt_params.param_vector = self._assemble_param_vector(spin=spin, model_type=data_store.model_type)
1637
1638
1639 data_store.scaling_matrix = None
1640
1641 else:
1642
1643 opt_params.param_vector = self._assemble_param_vector(spin=spin, sim_index=sim_index)
1644
1645
1646 num_params = len(opt_params.param_vector)
1647
1648
1649 data_store.scaling_matrix = self._assemble_scaling_matrix(num_params, model_type=data_store.model_type, spin=spin, scaling=scaling)
1650 if len(data_store.scaling_matrix):
1651 opt_params.param_vector = dot(inv(data_store.scaling_matrix), opt_params.param_vector)
1652
1653
1654 opt_params.inc, opt_params.lower, opt_params.upper = None, None, None
1655 if match('^[Gg]rid', min_algor):
1656 opt_params.inc, opt_params.lower, opt_params.upper = self._grid_search_config(num_params, spin=spin, lower=lower, upper=upper, inc=inc, scaling_matrix=data_store.scaling_matrix)
1657
1658
1659 if match('^[Ss]et', min_algor):
1660 opt_params.min_options = dot(inv(data_store.scaling_matrix), opt_params.min_options)
1661
1662
1663 if constraints:
1664 opt_params.A, opt_params.b = self._linear_constraints(num_params, model_type=data_store.model_type, spin=spin, scaling_matrix=data_store.scaling_matrix)
1665 else:
1666 opt_params.A, opt_params.b = None, None
1667
1668
1669 self._minimise_data_setup(data_store, min_algor, num_data_sets, opt_params.min_options, spin=spin, sim_index=sim_index)
1670
1671
1672 if constraints and not match('^[Gg]rid', min_algor):
1673 algor = opt_params.min_options[0]
1674 else:
1675 algor = min_algor
1676
1677
1678 if min_algor == 'back_calc' or match('[Ll][Mm]$', algor) or match('[Ll]evenburg-[Mm]arquardt$', algor):
1679 self.mf = Mf(init_params=opt_params.param_vector, model_type=data_store.model_type, diff_type=data_store.diff_type, diff_params=data_store.diff_params, scaling_matrix=data_store.scaling_matrix, num_spins=data_store.num_spins, equations=data_store.equations, param_types=data_store.param_types, param_values=data_store.param_values, relax_data=data_store.ri_data, errors=data_store.ri_data_err, bond_length=data_store.r, csa=data_store.csa, num_frq=data_store.num_frq, frq=data_store.frq, num_ri=data_store.num_ri, remap_table=data_store.remap_table, noe_r1_table=data_store.noe_r1_table, ri_labels=data_store.ri_types, gx=data_store.gx, gh=data_store.gh, h_bar=data_store.h_bar, mu0=data_store.mu0, num_params=data_store.num_params, vectors=data_store.xh_unit_vectors)
1680
1681
1682 if match('[Ll][Mm]$', algor) or match('[Ll]evenburg-[Mm]arquardt$', algor):
1683
1684 number_ri = 0
1685 for k in xrange(len(ri_data_err)):
1686 number_ri = number_ri + len(ri_data_err[k])
1687
1688
1689 lm_error = zeros(number_ri, float64)
1690 index = 0
1691 for k in xrange(len(ri_data_err)):
1692 lm_error[index:index+len(ri_data_err[k])] = ri_data_err[k]
1693 index = index + len(ri_data_err[k])
1694
1695 opt_params.min_options = opt_params.min_options + (self.mf.lm_dri, lm_error)
1696
1697
1698 if min_algor == 'back_calc':
1699 return self.mf.calc_ri()
1700
1701
1702 if match('^[Gg]rid', min_algor) and data_store.model_type == 'diff':
1703
1704 print("Parallelised diffusion tensor grid search.")
1705
1706
1707 for subdivision in grid_split(divisions=processor.processor_size(), lower=opt_params.lower, upper=opt_params.upper, inc=opt_params.inc):
1708
1709 opt_params.subdivision = subdivision
1710
1711
1712 command = MF_grid_command()
1713
1714
1715 command.store_data(deepcopy(data_store), deepcopy(opt_params))
1716
1717
1718 memo = MF_memo(model_free=self, model_type=data_store.model_type, spin=spin, sim_index=sim_index, scaling=scaling, scaling_matrix=data_store.scaling_matrix)
1719 processor.add_to_queue(command, memo)
1720
1721
1722 processor.run_queue()
1723
1724
1725 return
1726
1727
1728 if search('^[Gg]rid', min_algor):
1729 command = MF_grid_command()
1730
1731
1732 else:
1733 command = MF_minimise_command()
1734
1735
1736 command.store_data(deepcopy(data_store), deepcopy(opt_params))
1737
1738
1739 memo = MF_memo(model_free=self, model_type=data_store.model_type, spin=spin, sim_index=sim_index, scaling=scaling, scaling_matrix=data_store.scaling_matrix)
1740 processor.add_to_queue(command, memo)
1741
1742
1743 processor.run_queue()
1744