1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 """The diffusion tensor objects of the relax data store."""
25
26
27 from copy import deepcopy
28 from re import search
29 from math import cos, sin
30 from numpy import array, float64, dot, identity, transpose, zeros
31
32
33 from data_store.data_classes import Element
34 from lib.geometry.coord_transform import spherical_to_cartesian
35 from lib.geometry.rotations import two_vect_to_R
36 from lib.errors import RelaxError
37 from lib.xml import fill_object_contents, xml_to_object
38
39
41 """Function for calculating the Diso value.
42
43 The equation for calculating the parameter is::
44
45 Diso = 1 / (6tm).
46
47 @keyword tm: The global correlation time.
48 @type tm: float
49 @return: The isotropic diffusion rate (Diso).
50 @rtype: float
51 """
52
53
54 return 1.0 / (6.0 * tm)
55
56
58 """Function for calculating the Dpar value.
59
60 The equation for calculating the parameter is::
61
62 Dpar = Diso + 2/3 Da.
63
64 @keyword Diso: The isotropic diffusion rate.
65 @type Diso: float
66 @keyword Da: The anisotropic diffusion rate.
67 @type Da: float
68 @return: The diffusion rate parallel to the unique axis of the spheroid.
69 @rtype: float
70 """
71
72
73 return Diso + 2.0/3.0 * Da
74
75
77 """Function for calculating the Dpar unit vector.
78
79 The unit vector parallel to the unique axis of the diffusion tensor is::
80
81 | sin(theta) * cos(phi) |
82 Dpar_unit = | sin(theta) * sin(phi) |.
83 | cos(theta) |
84
85 @keyword theta: The azimuthal angle in radians.
86 @type theta: float
87 @keyword phi: The polar angle in radians.
88 @type phi: float
89 @return: The Dpar unit vector.
90 @rtype: numpy array
91 """
92
93
94 Dpar_unit = zeros(3, float64)
95
96
97 Dpar_unit[0] = sin(theta) * cos(phi)
98 Dpar_unit[1] = sin(theta) * sin(phi)
99 Dpar_unit[2] = cos(theta)
100
101
102 return Dpar_unit
103
104
106 """Function for calculating the Dper value.
107
108 The equation for calculating the parameter is::
109
110 Dper = Diso - 1/3 Da.
111
112 @keyword Diso: The isotropic diffusion rate.
113 @type Diso: float
114 @keyword Da: The anisotropic diffusion rate.
115 @type Da: float
116 @return: The diffusion rate perpendicular to the unique axis of the spheroid.
117 @rtype: float
118 """
119
120
121 return Diso - 1.0/3.0 * Da
122
123
125 """Function for calculating the Dratio value.
126
127 The equation for calculating the parameter is::
128
129 Dratio = Dpar / Dper.
130
131 @keyword Dpar: The diffusion rate parallel to the unique axis of the spheroid.
132 @type Dpar: float
133 @keyword Dper: The diffusion rate perpendicular to the unique axis of the spheroid.
134 @type Dper: float
135 @return: The ratio of the parallel and perpendicular diffusion rates.
136 @rtype: float
137 """
138
139
140 return Dpar / Dper
141
142
144 """Function for calculating the Dx value.
145
146 The equation for calculating the parameter is::
147
148 Dx = Diso - 1/3 Da(1 + 3Dr).
149
150 @keyword Diso: The isotropic diffusion rate.
151 @type Diso: float
152 @keyword Da: The anisotropic diffusion rate.
153 @type Da: float
154 @keyword Dr: The rhombic component of the diffusion tensor.
155 @type Dr: float
156 @return: The diffusion rate parallel to the x-axis of the ellipsoid.
157 @rtype: float
158 """
159
160
161 return Diso - 1.0/3.0 * Da * (1.0 + 3.0*Dr)
162
163
165 """Function for calculating the Dx unit vector.
166
167 The unit Dx vector is::
168
169 | -sin(alpha) * sin(gamma) + cos(alpha) * cos(beta) * cos(gamma) |
170 Dx_unit = | -sin(alpha) * cos(gamma) - cos(alpha) * cos(beta) * sin(gamma) |.
171 | cos(alpha) * sin(beta) |
172
173 @keyword alpha: The Euler angle alpha in radians using the z-y-z convention.
174 @type alpha: float
175 @keyword beta: The Euler angle beta in radians using the z-y-z convention.
176 @type beta: float
177 @keyword gamma: The Euler angle gamma in radians using the z-y-z convention.
178 @type gamma: float
179 @return: The Dx unit vector.
180 @rtype: numpy array
181 """
182
183
184 Dx_unit = zeros(3, float64)
185
186
187 Dx_unit[0] = -sin(alpha) * sin(gamma) + cos(alpha) * cos(beta) * cos(gamma)
188 Dx_unit[1] = -sin(alpha) * cos(gamma) - cos(alpha) * cos(beta) * sin(gamma)
189 Dx_unit[2] = cos(alpha) * sin(beta)
190
191
192 return Dx_unit
193
194
196 """Function for calculating the Dy value.
197
198 The equation for calculating the parameter is::
199
200 Dy = Diso - 1/3 Da(1 - 3Dr),
201
202 @keyword Diso: The isotropic diffusion rate.
203 @type Diso: float
204 @keyword Da: The anisotropic diffusion rate.
205 @type Da: float
206 @keyword Dr: The rhombic component of the diffusion tensor.
207 @type Dr: float
208 @return: The Dy value.
209 @rtype: float
210 """
211
212
213 return Diso - 1.0/3.0 * Da * (1.0 - 3.0*Dr)
214
215
217 """Function for calculating the Dy unit vector.
218
219 The unit Dy vector is::
220
221 | cos(alpha) * sin(gamma) + sin(alpha) * cos(beta) * cos(gamma) |
222 Dy_unit = | cos(alpha) * cos(gamma) - sin(alpha) * cos(beta) * sin(gamma) |.
223 | sin(alpha) * sin(beta) |
224
225 @keyword alpha: The Euler angle alpha in radians using the z-y-z convention.
226 @type alpha: float
227 @keyword beta: The Euler angle beta in radians using the z-y-z convention.
228 @type beta: float
229 @keyword gamma: The Euler angle gamma in radians using the z-y-z convention.
230 @type gamma: float
231 @return: The Dy unit vector.
232 @rtype: numpy array
233 """
234
235
236 Dy_unit = zeros(3, float64)
237
238
239 Dy_unit[0] = cos(alpha) * sin(gamma) + sin(alpha) * cos(beta) * cos(gamma)
240 Dy_unit[1] = cos(alpha) * cos(gamma) - sin(alpha) * cos(beta) * sin(gamma)
241 Dy_unit[2] = sin(alpha) * sin(beta)
242
243
244 return Dy_unit
245
246
248 """Function for calculating the Dz value.
249
250 The equation for calculating the parameter is::
251
252 Dz = Diso + 2/3 Da.
253
254 @keyword Diso: The isotropic diffusion rate.
255 @type Diso: float
256 @keyword Da: The anisotropic diffusion rate.
257 @type Da: float
258 @return: The Dz value.
259 @rtype: float
260 """
261
262
263 return Diso + 2.0/3.0 * Da
264
265
267 """Function for calculating the Dz unit vector.
268
269 The unit Dz vector is::
270
271 | -sin(beta) * cos(gamma) |
272 Dz_unit = | sin(beta) * sin(gamma) |.
273 | cos(beta) |
274
275 @keyword beta: The Euler angle beta in radians using the z-y-z convention.
276 @type beta: float
277 @keyword gamma: The Euler angle gamma in radians using the z-y-z convention.
278 @type gamma: float
279 @return: The Dz unit vector.
280 @rtype: numpy array
281 """
282
283
284 Dz_unit = zeros(3, float64)
285
286
287 Dz_unit[0] = -sin(beta) * cos(gamma)
288 Dz_unit[1] = sin(beta) * sin(gamma)
289 Dz_unit[2] = cos(beta)
290
291
292 return Dz_unit
293
294
296 """Function for calculating the rotation matrix.
297
298 Spherical diffusion
299 ===================
300
301 As the orientation of the diffusion tensor within the structural frame is undefined when the molecule diffuses as a sphere, the rotation matrix is simply the identity matrix::
302
303 | 1 0 0 |
304 R = | 0 1 0 |.
305 | 0 0 1 |
306
307
308 Spheroidal diffusion
309 ====================
310
311 The rotation matrix required to shift from the diffusion tensor frame to the structural frame is generated from the unique axis of the diffusion tensor.
312
313
314 Ellipsoidal diffusion
315 =====================
316
317 The rotation matrix required to shift from the diffusion tensor frame to the structural frame is equal to::
318
319 R = | Dx_unit Dy_unit Dz_unit |,
320
321 | Dx_unit[0] Dy_unit[0] Dz_unit[0] |
322 = | Dx_unit[1] Dy_unit[1] Dz_unit[1] |.
323 | Dx_unit[2] Dy_unit[2] Dz_unit[2] |
324
325 @param args: All the function arguments. For the spheroid, this includes the spheroid_type (str), the azimuthal angle theta in radians (float), and the polar angle phi in radians (float). For the ellipsoid, this includes the Dx unit vector (numpy 3D, rank-1 array), the Dy unit vector (numpy 3D, rank-1 array), and the Dz unit vector (numpy 3D, rank-1 array).
326 @type args: tuple
327 @return: The rotation matrix.
328 @rtype: numpy 3x3 array
329 """
330
331
332 if diff_type == 'sphere':
333 return identity(3, float64)
334
335
336 elif diff_type == 'spheroid':
337
338 spheroid_type, theta, phi = args
339
340
341 R = zeros((3, 3), float64)
342
343
344 if spheroid_type == 'prolate':
345 axis = array([0, 0, 1], float64)
346 else:
347 axis = array([1, 0, 0], float64)
348
349
350 spher_vect = array([1, theta, phi], float64)
351
352
353 diff_axis = zeros(3, float64)
354 spherical_to_cartesian(spher_vect, diff_axis)
355
356
357 two_vect_to_R(diff_axis, axis, R)
358
359
360 return R
361
362
363 elif diff_type == 'ellipsoid':
364
365 Dx_unit, Dy_unit, Dz_unit = args
366
367
368 rotation = identity(3, float64)
369
370
371 rotation[:, 0] = Dx_unit
372
373
374 rotation[:, 1] = Dy_unit
375
376
377 rotation[:, 2] = Dz_unit
378
379
380 return rotation
381
382
383 else:
384 raise RelaxError('The diffusion tensor has not been specified')
385
386
388 """Determine the spheroid type.
389
390 @param Da: The diffusion tensor anisotropy.
391 @type Da: float
392 @param spheroid_type: The current value of spheroid_type.
393 @type spheroid_type: str
394 @param flag: A flag which if True will cause the current spheroid_type value to be returned.
395 @type flag: bool
396 @return: The spheroid type, either 'oblate' or 'prolate'.
397 @rtype: str
398 """
399
400
401 if flag:
402 return spheroid_type
403
404
405 if Da > 0.0:
406 return 'prolate'
407 else:
408 return 'oblate'
409
410
412 """Function for calculating the diffusion tensor (in the structural frame).
413
414 The diffusion tensor is calculated using the diagonalised tensor and the rotation matrix
415 through the equation::
416
417 R . tensor_diag . R^T.
418
419 @keyword rotation: The rotation matrix.
420 @type rotation: numpy 3x3 array
421 @keyword tensor_diag: The diagonalised diffusion tensor.
422 @type tensor_diag: numpy 3x3 array
423 @return: The diffusion tensor (within the structural frame).
424 @rtype: numpy 3x3 array
425 """
426
427
428 return dot(rotation, dot(tensor_diag, transpose(rotation)))
429
430
432 """Function for calculating the diagonalised diffusion tensor.
433
434 The diagonalised spherical diffusion tensor is defined as::
435
436 | Diso 0 0 |
437 tensor = | 0 Diso 0 |.
438 | 0 0 Diso |
439
440 The diagonalised spheroidal tensor is defined as::
441
442 | Dper 0 0 |
443 tensor = | 0 Dper 0 |.
444 | 0 0 Dpar |
445
446 The diagonalised ellipsoidal diffusion tensor is defined as::
447
448 | Dx 0 0 |
449 tensor = | 0 Dy 0 |.
450 | 0 0 Dz |
451
452 @param args: All the arguments. For the sphere, this includes the Diso parameter (float). For the spheroid, this includes Dpar and Dper parameters (floats). For the ellipsoid, this includes the Dx, Dy, and Dz parameters (floats).
453 @type args: tuple
454 @return: The diagonalised diffusion tensor.
455 @rtype: numpy 3x3 array
456 """
457
458
459 if diff_type == 'sphere':
460
461 Diso, = args
462
463
464 tensor = zeros((3, 3), float64)
465
466
467 tensor[0, 0] = Diso
468 tensor[1, 1] = Diso
469 tensor[2, 2] = Diso
470
471
472 return tensor
473
474
475 elif diff_type == 'spheroid':
476
477 Dpar, Dper = args
478
479
480 tensor = zeros((3, 3), float64)
481
482
483 if Dpar > Dper:
484 tensor[0, 0] = Dper
485 tensor[1, 1] = Dper
486 tensor[2, 2] = Dpar
487 else:
488 tensor[0, 0] = Dpar
489 tensor[1, 1] = Dper
490 tensor[2, 2] = Dper
491
492
493 return tensor
494
495
496 elif diff_type == 'ellipsoid':
497
498 Dx, Dy, Dz = args
499
500
501 tensor = zeros((3, 3), float64)
502
503
504 tensor[0, 0] = Dx
505 tensor[1, 1] = Dy
506 tensor[2, 2] = Dz
507
508
509 return tensor
510
511
513 """Generator for the automatic updating the diffusion tensor data structures.
514
515 The order of the yield statements is important!
516
517 @param diff_type: The type of Brownian rotational diffusion.
518 @type diff_type: str
519 @return: This generator successively yields three objects, the target object to update, the list of parameters which if modified cause the target to be updated, and the list of parameters that the target depends upon.
520 """
521
522
523 if diff_type == 'sphere':
524 yield ('Diso', ['tm'], ['tm'])
525 yield ('tensor_diag', ['tm'], ['type', 'Diso'])
526 yield ('rotation', ['tm'], ['type'])
527 yield ('tensor', ['tm'], ['rotation', 'tensor_diag'])
528
529
530 elif diff_type == 'spheroid':
531 yield ('Diso', ['tm'], ['tm'])
532 yield ('Dpar', ['tm', 'Da'], ['Diso', 'Da'])
533 yield ('Dper', ['tm', 'Da'], ['Diso', 'Da'])
534 yield ('Dratio', ['tm', 'Da'], ['Dpar', 'Dper'])
535 yield ('Dpar_unit', ['theta', 'phi'], ['theta', 'phi'])
536 yield ('tensor_diag', ['tm', 'Da'], ['type', 'Dpar', 'Dper'])
537 yield ('rotation', ['theta', 'phi'], ['type', 'spheroid_type', 'theta', 'phi'])
538 yield ('tensor', ['tm', 'Da', 'theta', 'phi'], ['rotation', 'tensor_diag'])
539 yield ('spheroid_type', ['Da'], ['Da', 'spheroid_type', '_spheroid_type'])
540
541
542 elif diff_type == 'ellipsoid':
543 yield ('Diso', ['tm'], ['tm'])
544 yield ('Dx', ['tm', 'Da', 'Dr'], ['Diso', 'Da', 'Dr'])
545 yield ('Dy', ['tm', 'Da', 'Dr'], ['Diso', 'Da', 'Dr'])
546 yield ('Dz', ['tm', 'Da'], ['Diso', 'Da'])
547 yield ('Dx_unit', ['alpha', 'beta', 'gamma'], ['alpha', 'beta', 'gamma'])
548 yield ('Dy_unit', ['alpha', 'beta', 'gamma'], ['alpha', 'beta', 'gamma'])
549 yield ('Dz_unit', ['beta', 'gamma'], ['beta', 'gamma'])
550 yield ('tensor_diag', ['tm', 'Da', 'Dr'], ['type', 'Dx', 'Dy', 'Dz'])
551 yield ('rotation', ['alpha', 'beta', 'gamma'], ['type', 'Dx_unit', 'Dy_unit', 'Dz_unit'])
552 yield ('tensor', ['tm', 'Da', 'Dr', 'alpha', 'beta', 'gamma'], ['rotation', 'tensor_diag'])
553
554
555
556
557
558
560 """An empty data container for the diffusion tensor elements."""
561
562
563 _mod_attr = [
564 'type',
565 'fixed',
566 'spheroid_type',
567 'tm', 'tm_sim', 'tm_err',
568 'Da', 'Da_sim', 'Da_err',
569 'Dr', 'Dr_sim', 'Dr_err',
570 'theta', 'theta_sim', 'theta_err',
571 'phi', 'phi_sim', 'phi_err',
572 'alpha', 'alpha_sim', 'alpha_err',
573 'beta', 'beta_sim', 'beta_err',
574 'gamma', 'gamma_sim', 'gamma_err'
575 ]
576
578 """Replacement deepcopy method."""
579
580
581 new_obj = self.__class__.__new__(self.__class__)
582
583
584 new_obj.__init__()
585
586
587 new_obj.__dict__['_sim_num'] = self._sim_num
588
589
590 for name in self._mod_attr:
591
592 if not hasattr(self, name):
593 continue
594
595
596 if search('_err$', name):
597 category = 'err'
598 param = name.replace('_err', '')
599 elif search('_sim$', name):
600 category = 'sim'
601 param = name.replace('_sim', '')
602 else:
603 category = 'val'
604 param = name
605
606
607 value = getattr(self, name)
608
609
610 if category == 'val':
611 new_obj.set(param=param, value=deepcopy(value, memo))
612
613
614 elif category == 'err':
615 new_obj.set(param=param, value=deepcopy(value, memo), category='err')
616
617
618 else:
619
620 for i in range(len(value)):
621 new_obj.set(param=param, value=value[i], category='sim', sim_index=i)
622
623
624 return new_obj
625
626
628 """Initialise a few instance variables."""
629
630
631 self.__dict__['type'] = None
632
633
634 self.__dict__['_spheroid_type'] = False
635
636
637 self.__dict__['_sim_num'] = None
638
639
641 """Make this object read-only."""
642
643 raise RelaxError("The diffusion tensor is a read-only object. The diffusion tensor set() method must be used instead.")
644
645
646 - def _update_object(self, param_name, target, update_if_set, depends, category):
647 """Function for updating the target object, its error, and the MC simulations.
648
649 If the base name of the object is not within the 'update_if_set' list, this function returns
650 without doing anything (to avoid wasting time). Dependant upon the category the object
651 (target), its error (target+'_err'), or all Monte Carlo simulations (target+'_sim') are
652 updated.
653
654 @param param_name: The parameter name which is being set in the __setattr__() function.
655 @type param_name: str
656 @param target: The name of the object to update.
657 @type target: str
658 @param update_if_set: If the parameter being set by the __setattr__() function is not
659 within this list of parameters, don't waste time updating the
660 target.
661 @param depends: An array of names objects that the target is dependent upon.
662 @type depends: array of str
663 @param category: The category of the object to update (one of 'val', 'err', or
664 'sim').
665 @type category: str
666 @return: None
667 """
668
669
670 if not param_name in update_if_set:
671 return
672
673
674 fn = globals()['calc_'+target]
675
676
677
678
679
680 if category == 'val':
681
682 missing_dep = 0
683 deps = ()
684 for dep_name in depends:
685
686 if not hasattr(self, dep_name):
687 missing_dep = 1
688 break
689
690
691 deps = deps+(getattr(self, dep_name),)
692
693
694 if not missing_dep:
695
696 value = fn(*deps)
697
698
699 self.__dict__[target] = value
700
701
702
703
704
705 if category == 'err':
706
707 missing_dep = 0
708 deps = ()
709 for dep_name in depends:
710
711 if not hasattr(self, dep_name+'_err'):
712 missing_dep = 1
713 break
714
715
716 deps = deps+(getattr(self, dep_name+'_err'),)
717
718
719 if not missing_dep:
720
721 value = fn(*deps)
722
723
724 self.__dict__[target+'_err'] = value
725
726
727
728
729
730 if category == 'sim':
731
732 missing_dep = 0
733 deps = []
734 for dep_name in depends:
735
736 if dep_name not in ['type', 'spheroid_type']:
737 dep_name = dep_name+'_sim'
738
739
740 if not hasattr(self, dep_name) or getattr(self, dep_name) == None or not len(getattr(self, dep_name)):
741 missing_dep = 1
742 break
743
744
745 deps.append(getattr(self, dep_name))
746
747
748 if not missing_dep:
749
750 if not target+'_sim' in self.__dict__:
751 self.__dict__[target+'_sim'] = DiffTensorSimList(elements=self._sim_num)
752
753
754 args = []
755 skip = False
756 for i in range(self._sim_num):
757 args.append(())
758
759
760 for j in range(len(deps)):
761
762 if deps[j] is None or deps[j][i] is None:
763 skip = True
764
765
766 if isinstance(deps[j], str):
767 args[-1] = args[-1] + (deps[j],)
768
769
770 else:
771 args[-1] = args[-1] + (deps[j][i],)
772
773
774 if not skip:
775 for i in range(self._sim_num):
776
777 value = fn(*args[i])
778
779
780 self.__dict__[target+'_sim']._set(value=value, sim_index=i)
781
782
783 - def from_xml(self, diff_tensor_node, file_version=1):
784 """Recreate the diffusion tensor data structure from the XML diffusion tensor node.
785
786 @param diff_tensor_node: The diffusion tensor XML node.
787 @type diff_tensor_node: xml.dom.minicompat.Element instance
788 @keyword file_version: The relax XML version of the XML file.
789 @type file_version: int
790 """
791
792
793 self.__dict__['type'] = str(diff_tensor_node.getAttribute('type'))
794
795
796 temp_obj = Element()
797
798
799 xml_to_object(diff_tensor_node, temp_obj, file_version=file_version)
800
801
802 for name in self._mod_attr:
803
804 if not hasattr(temp_obj, name):
805 continue
806
807
808 if search('_err$', name):
809 category = 'err'
810 param = name.replace('_err', '')
811 elif search('_sim$', name):
812 category = 'sim'
813 param = name.replace('_sim', '')
814 else:
815 category = 'val'
816 param = name
817
818
819 value = getattr(temp_obj, name)
820
821
822 if category == 'val':
823 self.set(param=param, value=value)
824
825
826 elif category == 'err':
827 self.set(param=param, value=value, category='err')
828
829
830 else:
831
832 for i in range(len(value)):
833 self.set(param=param, value=value[i], category='sim', sim_index=i)
834
835
836 del temp_obj
837
838
839 - def set(self, param=None, value=None, category='val', sim_index=None):
840 """Set a diffusion tensor parameter.
841
842 @keyword param: The name of the parameter to set.
843 @type param: str
844 @keyword value: The parameter value.
845 @type value: anything
846 @keyword category: The type of parameter to set. This can be 'val' for the normal parameter, 'err' for the parameter error, or 'sim' for Monte Carlo or other simulated parameters.
847 @type category: str
848 @keyword sim_index: The index for a Monte Carlo simulation for simulated parameter.
849 @type sim_index: int or None
850 """
851
852
853 if category not in ['val', 'err', 'sim']:
854 raise RelaxError("The category of the parameter '%s' is incorrectly set to %s - it must be one of 'val', 'err' or 'sim'." % (param, category))
855
856
857 if not param in self._mod_attr:
858 raise RelaxError("The object '%s' is not a modifiable attribute." % param)
859
860
861 if category == 'val':
862 self.__dict__[param] = value
863
864
865 elif category == 'err':
866 self.__dict__[param+'_err'] = value
867
868
869 else:
870
871 if self._sim_num == None:
872 raise RelaxError("The diffusion tensor simulation number has not yet been specified, therefore a simulation value cannot be set.")
873
874
875 sim_param = param+'_sim'
876
877
878 if not hasattr(self, sim_param):
879 self.__dict__[sim_param] = DiffTensorSimList(elements=self._sim_num)
880
881
882 obj = getattr(self, sim_param)
883
884
885 obj._set(value=value, sim_index=sim_index)
886
887
888 if param == 'spheroid_type' and value:
889 self.__dict__['_spheroid_type'] = True
890
891
892 if param in ['type', 'fixed', 'spheroid_type']:
893 return
894
895
896 for target, update_if_set, depends in dependency_generator(self.type):
897 self._update_object(param, target, update_if_set, depends, category)
898
899
901 """Set if the diffusion tensor should be fixed during optimisation or not.
902
903 @param flag: The fixed flag.
904 @type flag: bool
905 """
906
907 self.__dict__['fixed'] = flag
908
909
911 """Set the number of Monte Carlo simulations for the construction of the simulation structures.
912
913 @keyword sim_number: The number of Monte Carlo simulations.
914 @type sim_number: int
915 """
916
917
918 if self._sim_num != None:
919 raise RelaxError("The number of simulations has already been set.")
920
921
922 self.__dict__['_sim_num'] = sim_number
923
924
926 """Set the diffusion tensor type.
927
928 @param value: The diffusion tensor type. This can be one of 'sphere', 'spheroid' or 'ellipsoid'.
929 @type value: str
930 """
931
932
933 allowed = ['sphere', 'spheroid', 'ellipsoid']
934 if value not in allowed:
935 raise RelaxError("The diffusion tensor type '%s' must be one of %s." % (value, allowed))
936
937
938 self.__dict__['type'] = value
939
940
941 - def to_xml(self, doc, element):
942 """Create an XML element for the diffusion tensor.
943
944 @param doc: The XML document object.
945 @type doc: xml.dom.minidom.Document instance
946 @param element: The element to add the diffusion tensor element to.
947 @type element: XML element object
948 """
949
950
951 tensor_element = doc.createElement('diff_tensor')
952 element.appendChild(tensor_element)
953
954
955 tensor_element.setAttribute('desc', 'Diffusion tensor')
956 tensor_element.setAttribute('type', self.type)
957
958
959 blacklist = ['type', 'is_empty'] + list(self.__class__.__dict__.keys())
960 for name in dir(self):
961 if name not in self._mod_attr:
962 blacklist.append(name)
963
964
965 fill_object_contents(doc, tensor_element, object=self, blacklist=blacklist)
966
967
968
970 """Empty data container for Monte Carlo simulation diffusion tensor data."""
971
973 """Replacement deepcopy method."""
974
975
976 new_obj = self.__class__.__new__(self.__class__)
977
978
979 for name in dir(self):
980
981 if search('^_', name):
982 continue
983
984
985 if name in self.__class__.__dict__ or name in dir(list):
986 continue
987
988
989 value = getattr(self, name)
990
991
992 setattr(new_obj, name, deepcopy(value, memo))
993
994
995 return new_obj
996
997
999 """Initialise the Monte Carlo simulation parameter list.
1000
1001 @keyword elements: The number of elements to initialise the length of the list to.
1002 @type elements: None or int
1003 """
1004
1005
1006 for i in range(elements):
1007 self._append(None)
1008
1009
1011 """This is a read-only object!"""
1012
1013 raise RelaxError("The diffusion tensor is a read-only object. The diffusion tensor set() method must be used instead.")
1014
1015
1017 """The secret append method.
1018
1019 @param value: The value to append to the list.
1020 @type value: anything
1021 """
1022
1023
1024 super(DiffTensorSimList, self).append(value)
1025
1026
1027 - def _set(self, value=None, sim_index=None):
1028 """Replacement secret method for __setitem__().
1029
1030 @keyword value: The value to set.
1031 @type value: anything
1032 @keyword sim_index: The index of the simulation value to set.
1033 @type sim_index: int
1034 """
1035
1036
1037 super(DiffTensorSimList, self).__setitem__(sim_index, value)
1038
1039
1041 """This is a read-only object!"""
1042
1043 raise RelaxError("The diffusion tensor is a read-only object. The diffusion tensor set() method must be used instead.")
1044