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