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 re import search
26 from math import cos, sin
27 from numpy import array, float64, dot, identity, transpose, zeros
28 from types import ListType
29
30
31 from data_classes import Element
32 from maths_fns.coord_transform import spherical_to_cartesian
33 from maths_fns.rotation_matrix import two_vect_to_R
34 from relax_errors import RelaxError
35 from relax_xml import fill_object_contents, xml_to_object
36
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.
325 @type args: tuple
326 @param theta: The azimuthal angle in radians.
327 @type theta: float
328 @param phi: The polar angle in radians.
329 @type phi: float
330 @param Dx_unit: The Dx unit vector.
331 @type Dx_unit: numpy array
332 @param Dy_unit: The Dy unit vector.
333 @type Dy_unit: numpy array
334 @param Dz_unit: The Dz unit vector.
335 @type Dz_unit: numpy array
336 @return: The rotation matrix.
337 @rtype: numpy 3x3 array
338 """
339
340
341 if diff_type == 'sphere':
342 return identity(3, float64)
343
344
345 elif diff_type == 'spheroid':
346
347 spheroid_type, theta, phi = args
348
349
350 R = zeros((3, 3), float64)
351
352
353 if spheroid_type == 'prolate':
354 axis = array([0, 0, 1], float64)
355 else:
356 axis = array([1, 0, 0], float64)
357
358
359 spher_vect = array([1, theta, phi], float64)
360
361
362 diff_axis = zeros(3, float64)
363 spherical_to_cartesian(spher_vect, diff_axis)
364
365
366 two_vect_to_R(diff_axis, axis, R)
367
368
369 return R
370
371
372 elif diff_type == 'ellipsoid':
373
374 Dx_unit, Dy_unit, Dz_unit = args
375
376
377 rotation = identity(3, float64)
378
379
380 rotation[:, 0] = Dx_unit
381
382
383 rotation[:, 1] = Dy_unit
384
385
386 rotation[:, 2] = Dz_unit
387
388
389 return rotation
390
391
392 else:
393 raise RelaxError('The diffusion tensor has not been specified')
394
395
397 """Determine the spheroid type.
398
399 @param Da: The diffusion tensor anisotropy.
400 @type Da: float
401 @param spheroid_type: The current value of spheroid_type.
402 @type spheroid_type: str
403 @param flag: A flag which if True will cause the current spheroid_type value to be returned.
404 @type flag: bool
405 @return: The spheroid type, either 'oblate' or 'prolate'.
406 @rtype: str
407 """
408
409
410 if flag:
411 return spheroid_type
412
413
414 if Da > 0.0:
415 return 'prolate'
416 else:
417 return 'oblate'
418
419
421 """Function for calculating the diffusion tensor (in the structural frame).
422
423 The diffusion tensor is calculated using the diagonalised tensor and the rotation matrix
424 through the equation::
425
426 R . tensor_diag . R^T.
427
428 @keyword rotation: The rotation matrix.
429 @type rotation: numpy 3x3 array
430 @keyword tensor_diag: The diagonalised diffusion tensor.
431 @type tensor_diag: numpy 3x3 array
432 @return: The diffusion tensor (within the structural frame).
433 @rtype: numpy 3x3 array
434 """
435
436
437 return dot(rotation, dot(tensor_diag, transpose(rotation)))
438
439
441 """Function for calculating the diagonalised diffusion tensor.
442
443 The diagonalised spherical diffusion tensor is defined as::
444
445 | Diso 0 0 |
446 tensor = | 0 Diso 0 |.
447 | 0 0 Diso |
448
449 The diagonalised spheroidal tensor is defined as::
450
451 | Dper 0 0 |
452 tensor = | 0 Dper 0 |.
453 | 0 0 Dpar |
454
455 The diagonalised ellipsoidal diffusion tensor is defined as::
456
457 | Dx 0 0 |
458 tensor = | 0 Dy 0 |.
459 | 0 0 Dz |
460
461 @param args: All the arguments.
462 @type args: tuple
463 @param Diso: The Diso parameter of the sphere.
464 @type Diso: float
465 @param Dpar: The Dpar parameter of the spheroid.
466 @type Dpar: float
467 @param Dper: The Dper parameter of the spheroid.
468 @type Dper: float
469 @param Dx: The Dx parameter of the ellipsoid.
470 @type Dx: float
471 @param Dy: The Dy parameter of the ellipsoid.
472 @type Dy: float
473 @param Dz: The Dz parameter of the ellipsoid.
474 @type Dz: float
475 @return: The diagonalised diffusion tensor.
476 @rtype: numpy 3x3 array
477 """
478
479
480 if diff_type == 'sphere':
481
482 Diso, = args
483
484
485 tensor = zeros((3, 3), float64)
486
487
488 tensor[0, 0] = Diso
489 tensor[1, 1] = Diso
490 tensor[2, 2] = Diso
491
492
493 return tensor
494
495
496 elif diff_type == 'spheroid':
497
498 Dpar, Dper = args
499
500
501 tensor = zeros((3, 3), float64)
502
503
504 if Dpar > Dper:
505 tensor[0, 0] = Dper
506 tensor[1, 1] = Dper
507 tensor[2, 2] = Dpar
508 else:
509 tensor[0, 0] = Dpar
510 tensor[1, 1] = Dper
511 tensor[2, 2] = Dper
512
513
514 return tensor
515
516
517 elif diff_type == 'ellipsoid':
518
519 Dx, Dy, Dz = args
520
521
522 tensor = zeros((3, 3), float64)
523
524
525 tensor[0, 0] = Dx
526 tensor[1, 1] = Dy
527 tensor[2, 2] = Dz
528
529
530 return tensor
531
532
534 """Generator for the automatic updating the diffusion tensor data structures.
535
536 The order of the yield statements is important!
537
538 @param diff_type: The type of Brownian rotational diffusion.
539 @type diff_type: str
540 @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.
541 """
542
543
544 if diff_type == 'sphere':
545 yield ('Diso', ['tm'], ['tm'])
546 yield ('tensor_diag', ['tm'], ['type', 'Diso'])
547 yield ('rotation', ['tm'], ['type'])
548 yield ('tensor', ['tm'], ['rotation', 'tensor_diag'])
549
550
551 elif diff_type == 'spheroid':
552 yield ('Diso', ['tm'], ['tm'])
553 yield ('Dpar', ['tm', 'Da'], ['Diso', 'Da'])
554 yield ('Dper', ['tm', 'Da'], ['Diso', 'Da'])
555 yield ('Dratio', ['tm', 'Da'], ['Dpar', 'Dper'])
556 yield ('Dpar_unit', ['theta', 'phi'], ['theta', 'phi'])
557 yield ('tensor_diag', ['tm', 'Da'], ['type', 'Dpar', 'Dper'])
558 yield ('rotation', ['theta', 'phi'], ['type', 'spheroid_type', 'theta', 'phi'])
559 yield ('tensor', ['tm', 'Da', 'theta', 'phi'], ['rotation', 'tensor_diag'])
560 yield ('spheroid_type', ['Da'], ['Da', 'spheroid_type', '__spheroid_type'])
561
562
563 elif diff_type == 'ellipsoid':
564 yield ('Diso', ['tm'], ['tm'])
565 yield ('Dx', ['tm', 'Da', 'Dr'], ['Diso', 'Da', 'Dr'])
566 yield ('Dy', ['tm', 'Da', 'Dr'], ['Diso', 'Da', 'Dr'])
567 yield ('Dz', ['tm', 'Da'], ['Diso', 'Da'])
568 yield ('Dx_unit', ['alpha', 'beta', 'gamma'], ['alpha', 'beta', 'gamma'])
569 yield ('Dy_unit', ['alpha', 'beta', 'gamma'], ['alpha', 'beta', 'gamma'])
570 yield ('Dz_unit', ['beta', 'gamma'], ['beta', 'gamma'])
571 yield ('tensor_diag', ['tm', 'Da', 'Dr'], ['type', 'Dx', 'Dy', 'Dz'])
572 yield ('rotation', ['alpha', 'beta', 'gamma'], ['type', 'Dx_unit', 'Dy_unit', 'Dz_unit'])
573 yield ('tensor', ['tm', 'Da', 'Dr', 'alpha', 'beta', 'gamma'], ['rotation', 'tensor_diag'])
574
575
576
577
578
579
581 """An empty data container for the diffusion tensor elements."""
582
583
584 __mod_attr__ = ['type',
585 'fixed',
586 'spheroid_type',
587 'tm', 'tm_sim', 'tm_err',
588 'Da', 'Da_sim', 'Da_err',
589 'Dr', 'Dr_sim', 'Dr_err',
590 'theta', 'theta_sim', 'theta_err',
591 'phi', 'phi_sim', 'phi_err',
592 'alpha', 'alpha_sim', 'alpha_err',
593 'beta', 'beta_sim', 'beta_err',
594 'gamma', 'gamma_sim', 'gamma_err']
595
597 """Replacement deepcopy method."""
598
599
600 new_obj = self.__class__.__new__(self.__class__)
601
602
603 for name in self.__mod_attr__:
604
605 if not hasattr(self, name):
606 continue
607
608
609 value = getattr(self, name)
610
611
612
613 setattr(new_obj, name, deepcopy(value, memo))
614
615
616 if isinstance(value, DiffTensorSimList):
617
618 new_value = getattr(new_obj, name)
619
620
621 new_value.diff_element = new_obj
622
623
624 for i in range(len(value)):
625 new_value.append(value[i])
626
627
628 return new_obj
629
630
632 """Initialise a few instance variables."""
633
634
635 self.type = None
636
637
638 self.__dict__['__spheroid_type'] = False
639
640
642 """Function for calculating the parameters, unit vectors, and tensors on the fly.
643
644 The equations for the parameters Dper, Dpar, and Dratio are::
645
646 Dratio = Dpar / Dper.
647 """
648
649
650 if search('_err$', name):
651 category = 'err'
652 param_name = name[:-4]
653 elif search('_sim$', name):
654 category = 'sim'
655 param_name = name[:-4]
656 else:
657 category = 'val'
658 param_name = name
659
660
661 if not param_name in self.__mod_attr__:
662 raise RelaxError("The object " + repr(name) + " is not a modifiable attribute.")
663
664
665 self.__dict__[name] = value
666
667
668 if name == 'spheroid_type' and value:
669 self.__dict__['__spheroid_type'] = True
670
671
672 if name in ['type', 'fixed', 'spheroid_type']:
673 return
674
675
676 for target, update_if_set, depends in dependency_generator(self.type):
677 self.__update_object(param_name, target, update_if_set, depends, category)
678
679
681 """Update the Monte Carlo simulation data lists when a simulation value is appended.
682
683 @param param_name: The MC sim parameter name which is being appended to.
684 @type param_name: str
685 @param index: The index of the Monte Carlo simulation which was set.
686 @type index: int
687 """
688
689
690 for target, update_if_set, depends in dependency_generator(self.type):
691
692 if not param_name in update_if_set:
693 continue
694
695
696 fn = globals()['calc_'+target]
697
698
699 missing_dep = 0
700 deps = ()
701 for dep_name in depends:
702
703 if dep_name not in ['type', 'spheroid_type']:
704 dep_name = dep_name+'_sim'
705
706
707 if not hasattr(self, dep_name):
708 missing_dep = 1
709 break
710
711
712 dep_obj = getattr(self, dep_name)
713
714
715 if dep_name in ['type', 'spheroid_type']:
716 deps = deps+(dep_obj,)
717 continue
718
719
720 if len(dep_obj) <= index:
721 missing_dep = 1
722 break
723
724
725 deps = deps+(dep_obj[index],)
726
727
728 if not missing_dep:
729
730 if not target+'_sim' in self.__dict__:
731 self.__dict__[target+'_sim'] = DiffTensorSimList(target, self)
732
733
734 target_obj = getattr(self, target+'_sim')
735
736
737 target_obj.append_untouchable_item(fn(*deps))
738
739
741 """Update the Monte Carlo simulation data lists when a simulation value is set.
742
743 @param param_name: The MC sim parameter name which is being set.
744 @type param_name: str
745 @param index: The index of the Monte Carlo simulation which was set.
746 @type index: int
747 """
748
749
750 for target, update_if_set, depends in dependency_generator(self.type):
751
752 if not param_name in update_if_set:
753 continue
754
755
756 fn = globals()['calc_'+target]
757
758
759 missing_dep = 0
760 deps = ()
761 for dep_name in depends:
762
763 if dep_name not in ['type', 'spheroid_type']:
764 dep_name = dep_name+'_sim'
765
766
767 if not hasattr(self, dep_name):
768 missing_dep = 1
769 break
770
771
772 dep_obj = getattr(self, dep_name)
773
774
775 if dep_name in ['type', 'spheroid_type']:
776 deps = deps+(dep_obj,)
777 continue
778
779
780 if len(dep_obj) <= index:
781 missing_dep = 1
782 break
783
784
785 deps = deps+(dep_obj[index],)
786
787
788 if not missing_dep:
789
790 target_obj = getattr(self, target+'_sim')
791
792
793 skip = False
794 for i in range(len(deps)):
795 if deps[i] == None:
796 skip = True
797
798
799 if not skip:
800 target_obj.set_untouchable_item(index, fn(*deps))
801
802
803 - def __update_object(self, param_name, target, update_if_set, depends, category):
804 """Function for updating the target object, its error, and the MC simulations.
805
806 If the base name of the object is not within the 'update_if_set' list, this function returns
807 without doing anything (to avoid wasting time). Dependant upon the category the object
808 (target), its error (target+'_err'), or all Monte Carlo simulations (target+'_sim') are
809 updated.
810
811 @param param_name: The parameter name which is being set in the __setattr__() function.
812 @type param_name: str
813 @param target: The name of the object to update.
814 @type target: str
815 @param update_if_set: If the parameter being set by the __setattr__() function is not
816 within this list of parameters, don't waste time updating the
817 target.
818 @param depends: An array of names objects that the target is dependent upon.
819 @type depends: array of str
820 @param category: The category of the object to update (one of 'val', 'err', or
821 'sim').
822 @type category: str
823 @return: None
824 """
825
826
827 if not param_name in update_if_set:
828 return
829
830
831 fn = globals()['calc_'+target]
832
833
834
835
836
837 if category == 'val':
838
839 missing_dep = 0
840 deps = ()
841 for dep_name in depends:
842
843 if not hasattr(self, dep_name):
844 missing_dep = 1
845 break
846
847
848 deps = deps+(getattr(self, dep_name),)
849
850
851 if not missing_dep:
852
853 value = fn(*deps)
854
855
856 self.__dict__[target] = value
857
858
859
860
861
862 if category == 'err':
863
864 missing_dep = 0
865 deps = ()
866 for dep_name in depends:
867
868 if not hasattr(self, dep_name+'_err'):
869 missing_dep = 1
870 break
871
872
873 deps = deps+(getattr(self, dep_name+'_err'),)
874
875
876 if not missing_dep:
877
878 value = fn(*deps)
879
880
881 self.__dict__[target+'_err'] = value
882
883
884
885
886
887 if category == 'sim':
888
889 missing_dep = 0
890 deps = []
891 for dep_name in depends:
892
893 if dep_name not in ['type', 'spheroid_type']:
894 dep_name = dep_name+'_sim'
895
896
897 if not hasattr(self, dep_name) or getattr(self, dep_name) == None or not len(getattr(self, dep_name)):
898 missing_dep = 1
899 break
900
901
902 deps.append(getattr(self, dep_name))
903
904
905 if not missing_dep:
906
907 num_sim = len(self.__dict__[update_if_set[0]+'_sim'])
908
909
910 if not target+'_sim' in self.__dict__:
911 self.__dict__[target+'_sim'] = DiffTensorSimList(target, self, elements=num_sim)
912
913
914 args = []
915 skip = False
916 for i in range(num_sim):
917 args.append(())
918
919
920 for j in range(len(deps)):
921
922 if deps[j] == None or deps[j][i] == None:
923 skip = True
924
925
926 if isinstance(deps[j], str):
927 args[-1] = args[-1] + (deps[j],)
928
929
930 else:
931 args[-1] = args[-1] + (deps[j][i],)
932
933
934 if not skip:
935 for i in range(num_sim):
936
937 value = fn(*args[i])
938
939
940 self.__dict__[target+'_sim'][i] = value
941
942
943 - def from_xml(self, diff_tensor_node, file_version=1):
944 """Recreate the diffusion tensor data structure from the XML diffusion tensor node.
945
946 @param diff_tensor_node: The diffusion tensor XML node.
947 @type diff_tensor_node: xml.dom.minicompat.Element instance
948 @keyword file_version: The relax XML version of the XML file.
949 @type file_version: int
950 """
951
952
953 setattr(self, 'type', str(diff_tensor_node.getAttribute('type')))
954
955
956 xml_to_object(diff_tensor_node, self, file_version=file_version)
957
958
959 - def to_xml(self, doc, element):
960 """Create an XML element for the diffusion tensor.
961
962 @param doc: The XML document object.
963 @type doc: xml.dom.minidom.Document instance
964 @param element: The element to add the diffusion tensor element to.
965 @type element: XML element object
966 """
967
968
969 tensor_element = doc.createElement('diff_tensor')
970 element.appendChild(tensor_element)
971
972
973 tensor_element.setAttribute('desc', 'Diffusion tensor')
974 tensor_element.setAttribute('type', self.type)
975
976
977 fill_object_contents(doc, tensor_element, object=self, blacklist=['type'] + list(self.__class__.__dict__.keys()))
978
979
980
982 """Empty data container for Monte Carlo simulation diffusion tensor data."""
983
985 """Replacement deepcopy method."""
986
987
988 new_obj = self.__class__.__new__(self.__class__)
989
990
991 for name in dir(self):
992
993 if search('^_', name):
994 continue
995
996
997 if name in list(self.__class__.__dict__.keys()) or name in dir(ListType):
998 continue
999
1000
1001 if name == 'diff_element':
1002 continue
1003
1004
1005 value = getattr(self, name)
1006
1007
1008 setattr(new_obj, name, deepcopy(value, memo))
1009
1010
1011 return new_obj
1012
1013
1014 - def __init__(self, param_name, diff_element, elements=None):
1015 """Initialise the Monte Carlo simulation parameter list.
1016
1017 This function makes the parameter name and parent object accessible to the functions of this
1018 list object.
1019
1020 @param param_name: The name of the parameter.
1021 @type param_name: str
1022 @param diff_element: The parent class.
1023 @type diff_element: DiffTensorData element
1024 @keyword elements: The optional number of elements to initialise the length of the list
1025 to.
1026 @type elements: None or int
1027 """
1028
1029
1030 self.param_name = param_name
1031 self.diff_element = diff_element
1032
1033
1034 if elements:
1035 for i in range(elements):
1036 self.append(None)
1037
1038
1040 """Set the value."""
1041
1042
1043 ListType.__setitem__(self, index, value)
1044
1045
1046 self.diff_element._DiffTensorData__update_sim_set(self.param_name, index)
1047
1048
1050 """Replacement function for the normal self.append() method."""
1051
1052
1053 self[len(self):len(self)] = [value]
1054
1055
1056 self.diff_element._DiffTensorData__update_sim_append(self.param_name, len(self)-1)
1057
1058
1060 """Append the value for an untouchable MC data structure."""
1061
1062
1063 self[len(self):len(self)] = [value]
1064
1065
1067 """Set the value for an untouchable MC data structure."""
1068
1069
1070 ListType.__setitem__(self, index, value)
1071