1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """Module for the support of diffusion tensors."""
24
25
26 from copy import deepcopy
27 from math import cos, pi, sin
28 from numpy import float64, int32, zeros
29 import string
30
31
32 from data_store.diff_tensor import DiffTensorData
33 from lib.diffusion.main import tensor_eigen_system, tensor_info_table
34 from lib.errors import RelaxError, RelaxNoTensorError, RelaxTensorError, RelaxUnknownParamCombError, RelaxUnknownParamError
35 from lib.geometry.angles import fold_spherical_angles, wrap_angles
36 from lib.physical_constants import element_from_isotope, number_from_isotope
37 from pipe_control import pipes
38 from pipe_control.interatomic import return_interatom_list
39 from pipe_control.mol_res_spin import get_molecule_names, return_spin, spin_loop
40
41
43 """Read the relaxation data from the NMR-STAR dictionary object.
44
45 @param star: The NMR-STAR dictionary object.
46 @type star: NMR_STAR instance
47 """
48
49
50 found = 0
51 for data in star.tensor.loop():
52
53 if data == None:
54 continue
55
56
57 if data['tensor_type'] != 'diffusion':
58 continue
59
60
61 found = found + 1
62
63
64 if not found:
65 return
66
67
68 if found != 1:
69 raise RelaxError("More than one diffusion tensor found.")
70
71
72 tensor = zeros((3, 3), float64)
73 tensor[0, 0] = data['tensor_11'][0]
74 tensor[0, 1] = data['tensor_12'][0]
75 tensor[0, 2] = data['tensor_13'][0]
76 tensor[1, 0] = data['tensor_21'][0]
77 tensor[1, 1] = data['tensor_22'][0]
78 tensor[1, 2] = data['tensor_23'][0]
79 tensor[2, 0] = data['tensor_31'][0]
80 tensor[2, 1] = data['tensor_32'][0]
81 tensor[2, 2] = data['tensor_33'][0]
82
83
84 Di, R, alpha, beta, gamma = tensor_eigen_system(tensor)
85
86
87 xy_match = False
88 epsilon = 1e-1
89 if abs(Di[0] - Di[1]) < epsilon:
90 xy_match = True
91
92
93 yz_match = False
94 if abs(Di[1] - Di[2]) < epsilon:
95 yz_match = True
96
97
98 if xy_match and yz_match:
99 shape = ['sphere']
100 elif xy_match:
101 shape = ['spheroid', 'prolate spheroid']
102 type = 'prolate'
103 Dpar = Di[2]
104 Dper = Di[0]
105 elif yz_match:
106 shape = ['spheroid', 'oblate spheroid']
107 type = 'oblate'
108 Dpar = Di[0]
109 Dper = Di[2]
110 else:
111 shape = ['ellipsoid']
112
113
114 if data['geometric_shape'] not in shape:
115 raise RelaxError("The tensor with eigenvalues %s does not match the %s geometric shape." % (Di, shape[0]))
116
117
118 cdp.diff_tensor = DiffTensorData()
119
120
121 cdp.diff_tensor.set_fixed(True)
122
123
124 if data['geometric_shape'] == 'sphere':
125 sphere(params=Di[0], d_scale=1.0, param_types=1)
126
127
128 elif data['geometric_shape'] in ['spheroid', 'oblate spheroid', 'prolate spheroid']:
129
130 theta = data['axial_sym_axis_polar_angle'][0]
131 phi = data['axial_sym_axis_azimuthal_angle'][0]
132
133
134 spheroid(params=(Dpar, Dper, theta, phi), d_scale=1.0, param_types=3, spheroid_type=type)
135
136
137 elif data['geometric_shape'] == 'ellipsoid':
138 ellipsoid(params=(Di[0], Di[1], Di[2], alpha, beta, gamma), d_scale=1.0, param_types=3)
139
140
142 """Generate the diffusion tensor saveframes for the NMR-STAR dictionary object.
143
144 @param star: The NMR-STAR dictionary object.
145 @type star: NMR_STAR instance
146 """
147
148
149 cdp = pipes.get_pipe()
150
151
152 mol_name_list = []
153 res_num_list = []
154 res_name_list = []
155 atom_name_list = []
156 isotope_list = []
157 element_list = []
158 attached_atom_name_list = []
159 attached_isotope_list = []
160 attached_element_list = []
161
162
163 for spin, mol_name, res_num, res_name, spin_id in spin_loop(full_info=True, return_id=True):
164
165 if res_num == None:
166 raise RelaxError("For the BMRB, the residue of spin '%s' must be numbered." % spin_id)
167 if res_name == None:
168 raise RelaxError("For the BMRB, the residue of spin '%s' must be named." % spin_id)
169 if spin.name == None:
170 raise RelaxError("For the BMRB, the spin '%s' must be named." % spin_id)
171 if not hasattr(spin, 'isotope') or spin.isotope == None:
172 raise RelaxError("For the BMRB, the spin isotope type of '%s' must be specified." % spin_id)
173
174
175 mol_name_list.append(mol_name)
176 res_num_list.append(str(res_num))
177 res_name_list.append(str(res_name))
178 atom_name_list.append(str(spin.name))
179
180
181 interatoms = return_interatom_list(spin_id)
182 if len(interatoms) == 0:
183 raise RelaxError("No interatomic interactions are defined for the spin '%s'." % spin_id)
184 if len(interatoms) > 1:
185 raise RelaxError("The BMRB only handles a signal interatomic interaction for the spin '%s'." % spin_id)
186
187
188 spin_attached = return_spin(interatoms[0].spin_id1)
189 if id(spin_attached) == id(spin):
190 spin_attached = return_spin(interatoms[0].spin_id2)
191
192
193 if hasattr(spin_attached, 'name'):
194 attached_atom_name_list.append(str(spin_attached.name))
195 else:
196 attached_atom_name_list.append(None)
197 if hasattr(spin_attached, 'isotope'):
198 attached_element_list.append(element_from_isotope(spin_attached.isotope))
199 attached_isotope_list.append(str(number_from_isotope(spin_attached.isotope)))
200 else:
201 attached_element_list.append(None)
202 attached_isotope_list.append(None)
203
204
205 isotope_list.append(int(spin.isotope.strip(string.ascii_letters)))
206 element_list.append(spin.element)
207
208
209 entity_ids = zeros(len(mol_name_list), int32)
210 mol_names = get_molecule_names()
211 for i in range(len(mol_name_list)):
212 for j in range(len(mol_names)):
213 if mol_name_list[i] == mol_names[j]:
214 entity_ids[i] = j+1
215
216
217 geometric_shape = cdp.diff_tensor.type
218 if geometric_shape == 'spheroid':
219 geometric_shape = "%s %s" % (cdp.diff_tensor.spheroid_type, geometric_shape)
220
221
222 shapes = ['sphere', 'oblate spheroid', 'prolate spheroid', 'ellipsoid']
223 sym = ['isotropic', 'axial symmetry', 'axial symmetry', 'rhombic']
224 for i in range(len(shapes)):
225 if geometric_shape == shapes[i]:
226 tensor_symmetry = sym[i]
227
228
229 theta = None
230 phi = None
231 if tensor_symmetry == 'axial symmetry':
232 theta = cdp.diff_tensor.theta
233 phi = cdp.diff_tensor.phi
234
235
236 alpha, beta, gamma = None, None, None
237 if tensor_symmetry == 'rhombic':
238 alpha = cdp.diff_tensor.alpha
239 beta = cdp.diff_tensor.beta
240 gamma = cdp.diff_tensor.gamma
241
242
243 Diso = cdp.diff_tensor.Diso
244 Da = None
245 Dr = None
246 if tensor_symmetry == 'axial symmetry':
247 Da = cdp.diff_tensor.Da
248 elif tensor_symmetry == 'rhombic':
249 Dr = cdp.diff_tensor.Dr
250
251
252 tensor_11 = cdp.diff_tensor.tensor[0, 0]
253 tensor_12 = cdp.diff_tensor.tensor[0, 1]
254 tensor_13 = cdp.diff_tensor.tensor[0, 2]
255 tensor_21 = cdp.diff_tensor.tensor[1, 0]
256 tensor_22 = cdp.diff_tensor.tensor[1, 1]
257 tensor_23 = cdp.diff_tensor.tensor[1, 2]
258 tensor_31 = cdp.diff_tensor.tensor[2, 0]
259 tensor_32 = cdp.diff_tensor.tensor[2, 1]
260 tensor_33 = cdp.diff_tensor.tensor[2, 2]
261
262
263
264 star.tensor.add(tensor_type='diffusion', euler_type='zyz', geometric_shape=geometric_shape, tensor_symmetry=tensor_symmetry, matrix_val_units='s-1', angle_units='rad', iso_val_formula='Diso = 1/(6.tm)', aniso_val_formula='Da = Dpar - Dper', rhomb_val_formula='Dr = (Dy - Dx)/2Da', entity_ids=entity_ids, res_nums=res_num_list, res_names=res_name_list, atom_names=atom_name_list, atom_types=element_list, isotope=isotope_list, axial_sym_axis_polar_angle=theta, axial_sym_axis_azimuthal_angle=phi, iso_val=Diso, aniso_val=Da, rhombic_val=Dr, euler_alpha=alpha, euler_beta=beta, euler_gamma=gamma, tensor_11=tensor_11, tensor_12=tensor_12, tensor_13=tensor_13, tensor_21=tensor_21, tensor_22=tensor_22, tensor_23=tensor_23, tensor_31=tensor_31, tensor_32=tensor_32, tensor_33=tensor_33)
265
266
267
268 -def copy(pipe_from=None, pipe_to=None):
269 """Function for copying diffusion tensor data from one data pipe to another.
270
271 @param pipe_from: The data pipe to copy the diffusion tensor data from. This defaults to the
272 current data pipe.
273 @type pipe_from: str
274 @param pipe_to: The data pipe to copy the diffusion tensor data to. This defaults to the
275 current data pipe.
276 @type pipe_to: str
277 """
278
279
280 if pipe_from == None and pipe_to == None:
281 raise RelaxError("The pipe_from and pipe_to arguments cannot both be set to None.")
282 elif pipe_from == None:
283 pipe_from = pipes.cdp_name()
284 elif pipe_to == None:
285 pipe_to = pipes.cdp_name()
286
287
288 pipes.test(pipe_from)
289 pipes.test(pipe_to)
290
291
292 dp_from = pipes.get_pipe(pipe_from)
293 dp_to = pipes.get_pipe(pipe_to)
294
295
296 if not diff_data_exists(pipe_from):
297 raise RelaxNoTensorError('diffusion')
298
299
300 if diff_data_exists(pipe_to):
301 raise RelaxTensorError('diffusion')
302
303
304 dp_to.diff_tensor = deepcopy(dp_from.diff_tensor)
305
306
308 """Function for returning a list of names of data structures associated with the sequence."""
309
310 names = [ 'diff_type',
311 'diff_params' ]
312
313 return names
314
315
328
329
331 """Function for determining if diffusion data exists in the current data pipe.
332
333 @param pipe: The data pipe to search for data in.
334 @type pipe: str
335 @return: The answer to the question.
336 @rtype: bool
337 """
338
339
340 if pipe == None:
341 pipe = pipes.cdp_name()
342
343
344 dp = pipes.get_pipe(pipe)
345
346
347 if hasattr(dp, 'diff_tensor'):
348 return True
349 else:
350 return False
351
352
354 """Function for displaying the diffusion tensor."""
355
356
357 pipes.test()
358
359
360 if not diff_data_exists():
361 raise RelaxNoTensorError('diffusion')
362
363
364 if cdp.diff_tensor.type == 'sphere':
365 tensor_info_table(type='sphere', tm=cdp.diff_tensor.tm, Diso=cdp.diff_tensor.Diso, fixed=cdp.diff_tensor.fixed)
366 elif cdp.diff_tensor.type == 'spheroid':
367 tensor_info_table(type='spheroid', tm=cdp.diff_tensor.tm, Diso=cdp.diff_tensor.Diso, Da=cdp.diff_tensor.Da, Dpar=cdp.diff_tensor.Dpar, Dper=cdp.diff_tensor.Dper, Dratio=cdp.diff_tensor.Dratio, theta=cdp.diff_tensor.theta, phi=cdp.diff_tensor.phi, fixed=cdp.diff_tensor.fixed)
368 elif cdp.diff_tensor.type == 'ellipsoid':
369 tensor_info_table(type='ellipsoid', tm=cdp.diff_tensor.tm, Diso=cdp.diff_tensor.Diso, Da=cdp.diff_tensor.Da, Dr=cdp.diff_tensor.Dr, Dx=cdp.diff_tensor.Dx, Dy=cdp.diff_tensor.Dy, Dz=cdp.diff_tensor.Dz, alpha=cdp.diff_tensor.alpha, beta=cdp.diff_tensor.beta, gamma=cdp.diff_tensor.gamma, fixed=cdp.diff_tensor.fixed)
370
371
372 -def ellipsoid(params=None, time_scale=None, d_scale=None, angle_units=None, param_types=None):
373 """Function for setting up a ellipsoidal diffusion tensor.
374
375 @param params: The diffusion tensor parameter.
376 @type params: float
377 @param time_scale: The correlation time scaling value.
378 @type time_scale: float
379 @param d_scale: The diffusion tensor eigenvalue scaling value.
380 @type d_scale: float
381 @param angle_units: The units for the angle parameters which can be either 'deg' or 'rad'.
382 @type angle_units: str
383 @param param_types: The type of parameters supplied. These correspond to 0: {tm, Da, theta,
384 phi}, 1: {Diso, Da, theta, phi}, 2: {tm, Dratio, theta, phi}, 3: {Dpar,
385 Dper, theta, phi}, 4: {Diso, Dratio, theta, phi}.
386 @type param_types: int
387 """
388
389
390 cdp.diff_tensor.set_type('ellipsoid')
391
392
393 if param_types == 0:
394
395 tm, Da, Dr, alpha, beta, gamma = params
396
397
398 tm = tm * time_scale
399 Da = Da * d_scale
400
401
402 set(value=[tm, Da, Dr], param=['tm', 'Da', 'Dr'])
403
404
405 elif param_types == 1:
406
407 Diso, Da, Dr, alpha, beta, gamma = params
408
409
410 Diso = Diso * d_scale
411 Da = Da * d_scale
412
413
414 set(value=[Diso, Da, Dr], param=['Diso', 'Da', 'Dr'])
415
416
417 elif param_types == 2:
418
419 Dx, Dy, Dz, alpha, beta, gamma = params
420
421
422 Dx = Dx * d_scale
423 Dy = Dy * d_scale
424 Dz = Dz * d_scale
425
426
427 set(value=[Dx, Dy, Dz], param=['Dx', 'Dy', 'Dz'])
428
429
430 elif param_types == 3:
431
432 Dxx, Dyy, Dzz, Dxy, Dxz, Dyz = params
433
434
435 tensor = zeros((3, 3), float64)
436 tensor[0, 0] = Dxx
437 tensor[1, 1] = Dyy
438 tensor[2, 2] = Dzz
439 tensor[0, 1] = tensor[1, 0] = Dxy
440 tensor[0, 2] = tensor[2, 0] = Dxz
441 tensor[1, 2] = tensor[2, 1] = Dyz
442
443
444 tensor = tensor * d_scale
445
446
447 Di, R, alpha, beta, gamma = tensor_eigen_system(tensor)
448
449
450 set(value=[Di[0], Di[1], Di[2]], param=['Dx', 'Dy', 'Dz'])
451
452
453 angle_units = 'rad'
454
455
456 else:
457 raise RelaxUnknownParamCombError('param_types', param_types)
458
459
460 if angle_units == 'deg':
461 print("Converting the angles from degrees to radian units.")
462 alpha = (alpha / 360.0) * 2.0 * pi
463 beta = (beta / 360.0) * 2.0 * pi
464 gamma = (gamma / 360.0) * 2.0 * pi
465
466
467 set(value=[alpha, beta, gamma], param=['alpha', 'beta', 'gamma'])
468
469
471 """Wrap the Euler or spherical angles and remove the glide reflection and translational symmetries.
472
473 Wrap the angles such that::
474
475 0 <= theta <= pi,
476 0 <= phi <= 2pi,
477
478 and::
479
480 0 <= alpha <= 2pi,
481 0 <= beta <= pi,
482 0 <= gamma <= 2pi.
483
484
485 For the simulated values, the angles are wrapped as::
486
487 theta - pi/2 <= theta_sim <= theta + pi/2
488 phi - pi <= phi_sim <= phi + pi
489
490 and::
491
492 alpha - pi <= alpha_sim <= alpha + pi
493 beta - pi/2 <= beta_sim <= beta + pi/2
494 gamma - pi <= gamma_sim <= gamma + pi
495
496
497 @param sim_index: The simulation index. If set to None then the actual values will be folded
498 rather than the simulation values.
499 @type sim_index: int or None
500 """
501
502
503
504
505
506
507 if cdp.diff_tensor.type == 'spheroid':
508
509 theta = cdp.diff_tensor.theta
510 phi = cdp.diff_tensor.phi
511
512
513 if sim_index != None:
514 theta_sim = cdp.diff_tensor.theta_sim[sim_index]
515 phi_sim = cdp.diff_tensor.phi_sim[sim_index]
516
517
518 if sim_index == None:
519 cdp.diff_tensor.set(param='theta', value=wrap_angles(theta, 0.0, 2.0*pi))
520 cdp.diff_tensor.set(param='phi', value=wrap_angles(phi, 0.0, 2.0*pi))
521
522
523 else:
524 cdp.diff_tensor.set(param='theta', value=wrap_angles(theta_sim, theta - pi, theta + pi), category='sim', sim_index=sim_index)
525 cdp.diff_tensor.set(param='phi', value=wrap_angles(phi_sim, phi - pi, phi + pi), category='sim', sim_index=sim_index)
526
527
528 elif cdp.diff_tensor.type == 'ellipsoid':
529
530 alpha = cdp.diff_tensor.alpha
531 beta = cdp.diff_tensor.beta
532 gamma = cdp.diff_tensor.gamma
533
534
535 if sim_index != None:
536 alpha_sim = cdp.diff_tensor.alpha_sim[sim_index]
537 beta_sim = cdp.diff_tensor.beta_sim[sim_index]
538 gamma_sim = cdp.diff_tensor.gamma_sim[sim_index]
539
540
541 if sim_index == None:
542 cdp.diff_tensor.set(param='alpha', value=wrap_angles(alpha, 0.0, 2.0*pi))
543 cdp.diff_tensor.set(param='beta', value= wrap_angles(beta, 0.0, 2.0*pi))
544 cdp.diff_tensor.set(param='gamma', value=wrap_angles(gamma, 0.0, 2.0*pi))
545
546
547 else:
548 cdp.diff_tensor.set(param='alpha', value=wrap_angles(alpha_sim, alpha - pi, alpha + pi), category='sim', sim_index=sim_index)
549 cdp.diff_tensor.set(param='beta', value= wrap_angles(beta_sim, beta - pi, beta + pi), category='sim', sim_index=sim_index)
550 cdp.diff_tensor.set(param='gamma', value=wrap_angles(gamma_sim, gamma - pi, gamma + pi), category='sim', sim_index=sim_index)
551
552
553
554
555
556
557 if cdp.diff_tensor.type == 'spheroid':
558
559 if sim_index == None:
560
561 if cdp.diff_tensor.phi >= pi:
562 theta, phi = fold_spherical_angles(cdp.diff_tensor.theta, cdp.diff_tensor.phi)
563 cdp.diff_tensor.set(param='theta', value=theta)
564 cdp.diff_tensor.set(param='phi', value=phi)
565
566
567 else:
568
569 if cdp.diff_tensor.phi_sim[sim_index] >= cdp.diff_tensor.phi + pi/2.0:
570 cdp.diff_tensor.set(param='theta', value=pi - cdp.diff_tensor.theta_sim[sim_index], category='sim', sim_index=sim_index)
571 cdp.diff_tensor.set(param='phi', value=cdp.diff_tensor.phi_sim[sim_index] - pi, category='sim', sim_index=sim_index)
572 elif cdp.diff_tensor.phi_sim[sim_index] <= cdp.diff_tensor.phi - pi/2.0:
573 cdp.diff_tensor.set(param='theta', value=pi - cdp.diff_tensor.theta_sim[sim_index], category='sim', sim_index=sim_index)
574 cdp.diff_tensor.set(param='phi', value=cdp.diff_tensor.phi_sim[sim_index] + pi, category='sim', sim_index=sim_index)
575
576
577 elif cdp.diff_tensor.type == 'ellipsoid':
578
579 if sim_index == None:
580
581 if cdp.diff_tensor.alpha >= pi:
582 cdp.diff_tensor.set(param='alpha', value=cdp.diff_tensor.alpha - pi)
583
584
585 if cdp.diff_tensor.beta >= pi:
586 cdp.diff_tensor.set(param='alpha', value=pi - cdp.diff_tensor.alpha)
587 cdp.diff_tensor.set(param='beta', value=cdp.diff_tensor.beta - pi)
588
589
590 if cdp.diff_tensor.gamma >= pi:
591 cdp.diff_tensor.set(param='alpha', value=pi - cdp.diff_tensor.alpha)
592 cdp.diff_tensor.set(param='beta', value=pi - cdp.diff_tensor.beta)
593 cdp.diff_tensor.set(param='gamma', value=cdp.diff_tensor.gamma - pi)
594
595
596 else:
597
598 if cdp.diff_tensor.alpha_sim[sim_index] >= cdp.diff_tensor.alpha + pi/2.0:
599 cdp.diff_tensor.set(param='alpha', value=cdp.diff_tensor.alpha_sim[sim_index] - pi, category='sim', sim_index=sim_index)
600 elif cdp.diff_tensor.alpha_sim[sim_index] <= cdp.diff_tensor.alpha - pi/2.0:
601 cdp.diff_tensor.set(param='alpha', value=cdp.diff_tensor.alpha_sim[sim_index] + pi, category='sim', sim_index=sim_index)
602
603
604 if cdp.diff_tensor.beta_sim[sim_index] >= cdp.diff_tensor.beta + pi/2.0:
605 cdp.diff_tensor.set(param='alpha', value=pi - cdp.diff_tensor.alpha_sim[sim_index], category='sim', sim_index=sim_index)
606 cdp.diff_tensor.set(param='beta', value=cdp.diff_tensor.beta_sim[sim_index] - pi, category='sim', sim_index=sim_index)
607 elif cdp.diff_tensor.beta_sim[sim_index] <= cdp.diff_tensor.beta - pi/2.0:
608 cdp.diff_tensor.set(param='alpha', value=pi - cdp.diff_tensor.alpha_sim[sim_index], category='sim', sim_index=sim_index)
609 cdp.diff_tensor.set(param='beta', value=cdp.diff_tensor.beta_sim[sim_index] + pi, category='sim', sim_index=sim_index)
610
611
612 if cdp.diff_tensor.gamma_sim[sim_index] >= cdp.diff_tensor.gamma + pi/2.0:
613 cdp.diff_tensor.set(param='alpha', value=pi - cdp.diff_tensor.alpha_sim[sim_index], category='sim', sim_index=sim_index)
614 cdp.diff_tensor.set(param='beta', value=pi - cdp.diff_tensor.beta_sim[sim_index], category='sim', sim_index=sim_index)
615 cdp.diff_tensor.set(param='gamma', value=cdp.diff_tensor.gamma_sim[sim_index] - pi, category='sim', sim_index=sim_index)
616 elif cdp.diff_tensor.gamma_sim[sim_index] <= cdp.diff_tensor.gamma - pi/2.0:
617 cdp.diff_tensor.set(param='alpha', value=pi - cdp.diff_tensor.alpha_sim[sim_index], category='sim', sim_index=sim_index)
618 cdp.diff_tensor.set(param='beta', value=pi - cdp.diff_tensor.beta_sim[sim_index], category='sim', sim_index=sim_index)
619 cdp.diff_tensor.set(param='gamma', value=cdp.diff_tensor.gamma_sim[sim_index] + pi, category='sim', sim_index=sim_index)
620
621
622 -def init(params=None, time_scale=1.0, d_scale=1.0, angle_units='deg', param_types=0, spheroid_type=None, fixed=1):
623 """Function for initialising the diffusion tensor.
624
625 @param params: The diffusion tensor parameters.
626 @type params: float
627 @param time_scale: The correlation time scaling value.
628 @type time_scale: float
629 @param d_scale: The diffusion tensor eigenvalue scaling value.
630 @type d_scale: float
631 @param angle_units: The units for the angle parameters.
632 @type angle_units: str (either 'deg' or 'rad')
633 @param param_types: The type of parameters supplied. For spherical diffusion, the flag
634 values correspond to 0: tm, 1: Diso. For spheroidal diffusion, 0: {tm,
635 Da, theta, phi}, 1: {Diso, Da, theta, phi}, 2: {tm, Dratio, theta, phi},
636 3: {Dpar, Dper, theta, phi}, 4: {Diso, Dratio, theta, phi}. For
637 ellipsoidal diffusion, 0: {tm, Da, Dr, alpha, beta, gamma}, 1: {Diso,
638 Da, Dr, alpha, beta, gamma}, 2: {Dx, Dy, Dz, alpha, beta, gamma}.
639 @type param_types: int
640 @param spheroid_type: A string which, if supplied together with spheroid parameters, will
641 restrict the tensor to either being 'oblate' or 'prolate'.
642 @type spheroid_type: str
643 @param fixed: A flag specifying whether the diffusion tensor is fixed or can be
644 optimised.
645 @type fixed: bin
646 """
647
648
649 pipes.test()
650
651
652 if diff_data_exists():
653 raise RelaxTensorError('diffusion')
654
655
656 valid_types = ['deg', 'rad']
657 if not angle_units in valid_types:
658 raise RelaxError("The diffusion tensor 'angle_units' argument " + repr(angle_units) + " should be either 'deg' or 'rad'.")
659
660
661 cdp.diff_tensor = DiffTensorData()
662
663
664 cdp.diff_tensor.set_fixed(fixed)
665
666
667 if isinstance(params, float):
668 num_params = 1
669 sphere(params, time_scale, param_types)
670
671
672 elif (isinstance(params, tuple) or isinstance(params, list)) and len(params) == 4:
673 num_params = 4
674 spheroid(params, time_scale, d_scale, angle_units, param_types, spheroid_type)
675
676
677 elif (isinstance(params, tuple) or isinstance(params, list)) and len(params) == 6:
678 num_params = 6
679 ellipsoid(params, time_scale, d_scale, angle_units, param_types)
680
681
682 else:
683 raise RelaxError("The diffusion tensor parameters " + repr(params) + " are of an unknown type.")
684
685
686 test_params(num_params)
687
688
690 """The function for creating bounds for the mapping function.
691
692 @param param: The name of the parameter to return the bounds for.
693 @type param: str
694 @keyword spin_id: The spin identification string. This arg is unused.
695 @type spin_id: None or str
696 @return: The bounds for the parameter.
697 @rtype: list of len 2 of floats
698 """
699
700
701 if param == 'tm':
702 return [0, 10.0 * 1e-9]
703
704
705 if param == 'Diso' or param == 'Dx' or param == 'Dy' or param == 'Dz' or param == 'Dpar' or param == 'Dper':
706 return [1e6, 1e7]
707
708
709 if param == 'Da':
710 return [-3.0/2.0 * 1e7, 3.0 * 1e7]
711
712
713 if param == 'Dr':
714 return [0, 1]
715
716
717 if param == 'Dratio':
718 return [1.0/3.0, 3.0]
719
720
721 if param == 'theta':
722 return [0, pi]
723
724
725 if param == 'phi':
726 return [0, 2*pi]
727
728
729 if param == 'alpha':
730 return [0, 2*pi]
731
732
733 if param == 'beta':
734 return [0, pi]
735
736
737 if param == 'gamma':
738 return [0, 2*pi]
739
740
742 """Function for creating labels, tick locations, and tick values for an OpenDX map."""
743
744
745 labels = "{"
746 tick_locations = []
747 tick_values = []
748 n = len(params)
749 axis_incs = 5
750 loc_inc = inc / axis_incs
751
752
753 for i in range(n):
754
755 factor = return_conversion_factor(params[swap[i]])
756
757
758 units = return_units(params[swap[i]])
759
760
761 if units:
762 labels = labels + "\"" + params[swap[i]] + " (" + units + ")\""
763 else:
764 labels = labels + "\"" + params[swap[i]] + "\""
765
766
767 vals = bounds[swap[i], 0] / factor
768 val_inc = (bounds[swap[i], 1] - bounds[swap[i], 0]) / (axis_incs * factor)
769
770 if i < n - 1:
771 labels = labels + " "
772 else:
773 labels = labels + "}"
774
775
776 string = "{"
777 val = 0.0
778 for j in range(axis_incs + 1):
779 string = string + " " + repr(val)
780 val = val + loc_inc
781 string = string + " }"
782 tick_locations.append(string)
783
784
785 string = "{"
786 for j in range(axis_incs + 1):
787 string = string + "\"" + "%.2f" % vals + "\" "
788 vals = vals + val_inc
789 string = string + "}"
790 tick_values.append(string)
791
792 return labels, tick_locations, tick_values
793
794
795 -def set(value=None, param=None):
796 """Set the diffusion tensor parameters.
797
798 @keyword tensor: The diffusion tensor object.
799 @type tensor: DiffTensorData instance
800 @keyword value: The list of values to set the parameters to.
801 @type value: list of float
802 @keyword param: The list of parameter names.
803 @type param: list of str
804 """
805
806
807 if not diff_data_exists():
808 raise RelaxNoTensorError('diffusion')
809
810
811 geo_params = []
812 geo_values = []
813 orient_params = []
814 orient_values = []
815
816
817 for i in range(len(param)):
818
819 if not param[i]:
820 raise RelaxUnknownParamError("diffusion tensor", param[i])
821
822
823 if value[i] == None:
824 value[i] = default_value(param[i])
825
826
827 if param[i] in ['tm', 'Diso', 'Da', 'Dratio', 'Dper', 'Dpar', 'Dr', 'Dx', 'Dy', 'Dz']:
828 geo_params.append(param[i])
829 geo_values.append(value[i])
830
831
832 if param[i] in ['theta', 'phi', 'alpha', 'beta', 'gamma']:
833 orient_params.append(param[i])
834 orient_values.append(value[i])
835
836
837
838
839
840 if cdp.diff_tensor.type == 'sphere':
841
842
843
844
845 if len(geo_params) == 1:
846
847 if geo_params[0] == 'tm':
848 cdp.diff_tensor.set(param='tm', value=geo_values[0])
849
850
851 elif geo_params[0] == 'Diso':
852 cdp.diff_tensor.set(param='tm', value=1.0 / (6.0 * geo_values[0]))
853
854
855 else:
856 raise RelaxError("The geometric diffusion parameter " + repr(geo_params[0]) + " cannot be set.")
857
858
859 elif len(geo_params) > 1:
860 raise RelaxUnknownParamCombError('geometric parameter set', geo_params)
861
862
863
864
865
866
867 if len(orient_params):
868 raise RelaxError("For spherical diffusion, the orientation parameters " + repr(orient_params) + " should not exist.")
869
870
871
872
873
874 elif cdp.diff_tensor.type == 'spheroid':
875
876
877
878
879 if len(geo_params) == 1:
880
881 if geo_params[0] == 'tm':
882 cdp.diff_tensor.set(param='tm', value=geo_values[0])
883
884
885 elif geo_params[0] == 'Diso':
886 cdp.diff_tensor.set(param='tm', value=1.0 / (6.0 * geo_values[0]))
887
888
889 elif geo_params[0] == 'Da':
890 cdp.diff_tensor.set(param='Da', value=geo_values[0])
891
892
893 elif geo_params[0] == 'Dratio':
894 Dratio = geo_values[0]
895 cdp.diff_tensor.set(param='Da', value=(Dratio - 1.0) / (2.0 * cdp.diff_tensor.tm * (Dratio + 2.0)))
896
897
898 else:
899 raise RelaxError("The geometric diffusion parameter " + repr(geo_params[0]) + " cannot be set.")
900
901
902 elif len(geo_params) == 2:
903
904 if geo_params.count('tm') == 1 and geo_params.count('Da') == 1:
905
906 tm = geo_values[geo_params.index('tm')]
907 Da = geo_values[geo_params.index('Da')]
908
909
910 cdp.diff_tensor.set(param='tm', value=tm)
911 cdp.diff_tensor.set(param='Da', value=Da)
912
913
914 elif geo_params.count('Diso') == 1 and geo_params.count('Da') == 1:
915
916 Diso = geo_values[geo_params.index('Diso')]
917 Da = geo_values[geo_params.index('Da')]
918
919
920 cdp.diff_tensor.set(param='tm', value=1.0 / (6.0 * Diso))
921 cdp.diff_tensor.set(param='Da', value=Da)
922
923
924 elif geo_params.count('tm') == 1 and geo_params.count('Dratio') == 1:
925
926 tm = geo_values[geo_params.index('tm')]
927 Dratio = geo_values[geo_params.index('Dratio')]
928
929
930 cdp.diff_tensor.set(param='tm', value=tm)
931 cdp.diff_tensor.set(param='Da', value=(Dratio - 1.0) / (2.0 * tm * (Dratio + 2.0)))
932
933
934 elif geo_params.count('Dpar') == 1 and geo_params.count('Dper') == 1:
935
936 Dpar = geo_values[geo_params.index('Dpar')]
937 Dper = geo_values[geo_params.index('Dper')]
938
939
940 cdp.diff_tensor.set(param='tm', value=1.0 / (2.0 * (Dpar + 2.0*Dper)))
941 cdp.diff_tensor.set(param='Da', value=Dpar - Dper)
942
943
944 elif geo_params.count('Diso') == 1 and geo_params.count('Dratio') == 1:
945
946 Diso = geo_values[geo_params.index('Diso')]
947 Dratio = geo_values[geo_params.index('Dratio')]
948
949
950 cdp.diff_tensor.set(param='tm', value=1.0 / (6.0 * Diso))
951 cdp.diff_tensor.set(param='Da', value=3.0 * Diso * (Dratio - 1.0) / (Dratio + 2.0))
952
953
954 else:
955 raise RelaxUnknownParamCombError('geometric parameter set', geo_params)
956
957
958 elif len(geo_params) > 2:
959 raise RelaxUnknownParamCombError('geometric parameter set', geo_params)
960
961
962
963
964
965
966 if len(orient_params) == 1:
967
968 if orient_params[0] == 'theta':
969 cdp.diff_tensor.set(param='theta', value=orient_values[orient_params.index('theta')])
970
971
972 elif orient_params[0] == 'phi':
973 cdp.diff_tensor.set(param='phi', value=orient_values[orient_params.index('phi')])
974
975
976 else:
977 raise RelaxError("For spheroidal diffusion, the orientation parameter " + repr(orient_params) + " cannot be set.")
978
979
980 elif len(orient_params) == 2:
981
982 if orient_params.count('theta') == 1 and orient_params.count('phi') == 1:
983 cdp.diff_tensor.set(param='theta', value=orient_values[orient_params.index('theta')])
984 cdp.diff_tensor.set(param='phi', value=orient_values[orient_params.index('phi')])
985
986
987 else:
988 raise RelaxUnknownParamCombError('orientational parameter set', orient_params)
989
990
991 elif len(orient_params) > 2:
992 raise RelaxUnknownParamCombError('orientational parameter set', orient_params)
993
994
995
996
997
998 elif cdp.diff_tensor.type == 'ellipsoid':
999
1000
1001
1002
1003 if len(geo_params) == 1:
1004
1005 if geo_params[0] == 'tm':
1006 cdp.diff_tensor.set(param='tm', value=geo_values[0])
1007
1008
1009 elif geo_params[0] == 'Diso':
1010 cdp.diff_tensor.set(param='tm', value=1.0 / (6.0 * geo_values[0]))
1011
1012
1013 elif geo_params[0] == 'Da':
1014 cdp.diff_tensor.set(param='Da', value=geo_values[0])
1015
1016
1017 elif geo_params[0] == 'Dr':
1018 cdp.diff_tensor.set(param='Dr', value=geo_values[0])
1019
1020
1021 else:
1022 raise RelaxError("The geometric diffusion parameter " + repr(geo_params[0]) + " cannot be set.")
1023
1024
1025 elif len(geo_params) == 2:
1026
1027 if geo_params.count('tm') == 1 and geo_params.count('Da') == 1:
1028
1029 tm = geo_values[geo_params.index('tm')]
1030 Da = geo_values[geo_params.index('Da')]
1031
1032
1033 cdp.diff_tensor.set(param='tm', value=tm)
1034 cdp.diff_tensor.set(param='Da', value=Da)
1035
1036
1037 elif geo_params.count('tm') == 1 and geo_params.count('Dr') == 1:
1038
1039 tm = geo_values[geo_params.index('tm')]
1040 Dr = geo_values[geo_params.index('Dr')]
1041
1042
1043 cdp.diff_tensor.set(param='tm', value=tm)
1044 cdp.diff_tensor.set(param='Dr', value=Dr)
1045
1046
1047 elif geo_params.count('Diso') == 1 and geo_params.count('Da') == 1:
1048
1049 Diso = geo_values[geo_params.index('Diso')]
1050 Da = geo_values[geo_params.index('Da')]
1051
1052
1053 cdp.diff_tensor.set(param='tm', value=1.0 / (6.0 * Diso))
1054 cdp.diff_tensor.set(param='Da', value=Da)
1055
1056
1057 elif geo_params.count('Diso') == 1 and geo_params.count('Dr') == 1:
1058
1059 Diso = geo_values[geo_params.index('Diso')]
1060 Dr = geo_values[geo_params.index('Dr')]
1061
1062
1063 cdp.diff_tensor.set(param='tm', value=1.0 / (6.0 * Diso))
1064 cdp.diff_tensor.set(param='Dr', value=Dr)
1065
1066
1067 elif geo_params.count('Da') == 1 and geo_params.count('Dr') == 1:
1068
1069 Da = geo_values[geo_params.index('Da')]
1070 Dr = geo_values[geo_params.index('Dr')]
1071
1072
1073 cdp.diff_tensor.set(param='Da', value=Da)
1074 cdp.diff_tensor.set(param='Da', value=Dr)
1075
1076
1077 else:
1078 raise RelaxUnknownParamCombError('geometric parameter set', geo_params)
1079
1080
1081 elif len(geo_params) == 3:
1082
1083 if geo_params.count('tm') == 1 and geo_params.count('Da') == 1 and geo_params.count('Dr') == 1:
1084
1085 tm = geo_values[geo_params.index('tm')]
1086 Da = geo_values[geo_params.index('Da')]
1087 Dr = geo_values[geo_params.index('Dr')]
1088
1089
1090 cdp.diff_tensor.set(param='tm', value=tm)
1091 cdp.diff_tensor.set(param='Da', value=Da)
1092 cdp.diff_tensor.set(param='Dr', value=Dr)
1093
1094
1095 elif geo_params.count('Diso') == 1 and geo_params.count('Da') == 1 and geo_params.count('Dr') == 1:
1096
1097 Diso = geo_values[geo_params.index('Diso')]
1098 Da = geo_values[geo_params.index('Da')]
1099 Dr = geo_values[geo_params.index('Dr')]
1100
1101
1102 cdp.diff_tensor.set(param='tm', value=1.0 / (6.0 * Diso))
1103 cdp.diff_tensor.set(param='Da', value=Da)
1104 cdp.diff_tensor.set(param='Dr', value=Dr)
1105
1106
1107 elif geo_params.count('Dx') == 1 and geo_params.count('Dy') == 1 and geo_params.count('Dz') == 1:
1108
1109 Dx = geo_values[geo_params.index('Dx')]
1110 Dy = geo_values[geo_params.index('Dy')]
1111 Dz = geo_values[geo_params.index('Dz')]
1112
1113
1114 if Dx + Dy + Dz == 0.0:
1115 cdp.diff_tensor.set(param='tm', value=1e99)
1116 else:
1117 cdp.diff_tensor.set(param='tm', value=0.5 / (Dx + Dy + Dz))
1118
1119
1120 cdp.diff_tensor.set(param='Da', value=Dz - 0.5*(Dx + Dy))
1121
1122
1123 if cdp.diff_tensor.Da == 0.0:
1124 cdp.diff_tensor.set(param='Dr', value=(Dy - Dx) * 1e99)
1125 else:
1126 cdp.diff_tensor.set(param='Dr', value=(Dy - Dx) / (2.0*cdp.diff_tensor.Da))
1127
1128
1129 else:
1130 raise RelaxUnknownParamCombError('geometric parameter set', geo_params)
1131
1132
1133
1134 elif len(geo_params) > 3:
1135 raise RelaxUnknownParamCombError('geometric parameter set', geo_params)
1136
1137
1138
1139
1140
1141
1142 if len(orient_params) == 1:
1143
1144 if orient_params[0] == 'alpha':
1145 cdp.diff_tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')])
1146
1147
1148 elif orient_params[0] == 'beta':
1149 cdp.diff_tensor.set(param='beta', value=orient_values[orient_params.index('beta')])
1150
1151
1152 elif orient_params[0] == 'gamma':
1153 cdp.diff_tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')])
1154
1155
1156 else:
1157 raise RelaxError("For ellipsoidal diffusion, the orientation parameter " + repr(orient_params) + " cannot be set.")
1158
1159
1160 elif len(orient_params) == 2:
1161
1162 if orient_params.count('alpha') == 1 and orient_params.count('beta') == 1:
1163 cdp.diff_tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')])
1164 cdp.diff_tensor.set(param='beta', value=orient_values[orient_params.index('beta')])
1165
1166
1167 if orient_params.count('alpha') == 1 and orient_params.count('gamma') == 1:
1168 cdp.diff_tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')])
1169 cdp.diff_tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')])
1170
1171
1172 if orient_params.count('beta') == 1 and orient_params.count('gamma') == 1:
1173 cdp.diff_tensor.set(param='beta', value=orient_values[orient_params.index('beta')])
1174 cdp.diff_tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')])
1175
1176
1177 else:
1178 raise RelaxUnknownParamCombError('orientational parameter set', orient_params)
1179
1180
1181 elif len(orient_params) == 3:
1182
1183 if orient_params.count('alpha') == 1 and orient_params.count('beta') == 1:
1184 cdp.diff_tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')])
1185 cdp.diff_tensor.set(param='beta', value=orient_values[orient_params.index('beta')])
1186 cdp.diff_tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')])
1187
1188
1189 else:
1190 raise RelaxUnknownParamCombError('orientational parameter set', orient_params)
1191
1192
1193 elif len(orient_params) > 3:
1194 raise RelaxUnknownParamCombError('orientational parameter set', orient_params)
1195
1196
1197
1198
1199
1200 if orient_params:
1201 fold_angles()
1202
1203
1204 -def sphere(params=None, time_scale=None, param_types=None):
1205 """Function for setting up a spherical diffusion tensor.
1206
1207 @param params: The diffusion tensor parameter.
1208 @type params: float
1209 @param time_scale: The correlation time scaling value.
1210 @type time_scale: float
1211 @param param_types: The type of parameter supplied. If 0, then the parameter is tm. If 1, then
1212 the parameter is Diso.
1213 @type param_types: int
1214 """
1215
1216
1217 cdp.diff_tensor.set_type('sphere')
1218
1219
1220 if param_types == 0:
1221
1222 tm = params * time_scale
1223
1224
1225 set(value=[tm], param=['tm'])
1226
1227
1228 elif param_types == 1:
1229
1230 Diso = params * d_scale
1231
1232
1233 set(value=[Diso], param=['Diso'])
1234
1235
1236 else:
1237 raise RelaxUnknownParamCombError('param_types', param_types)
1238
1239
1240 -def spheroid(params=None, time_scale=None, d_scale=None, angle_units=None, param_types=None, spheroid_type=None):
1241 """Function for setting up a spheroidal diffusion tensor.
1242
1243 @param params: The diffusion tensor parameter.
1244 @type params: float
1245 @param time_scale: The correlation time scaling value.
1246 @type time_scale: float
1247 @param d_scale: The diffusion tensor eigenvalue scaling value.
1248 @type d_scale: float
1249 @param angle_units: The units for the angle parameters which can be either 'deg' or 'rad'.
1250 @type angle_units: str
1251 @param param_types: The type of parameters supplied. These correspond to 0: {tm, Da, theta,
1252 phi}, 1: {Diso, Da, theta, phi}, 2: {tm, Dratio, theta, phi}, 3: {Dpar,
1253 Dper, theta, phi}, 4: {Diso, Dratio, theta, phi}.
1254 @type param_types: int
1255 @param spheroid_type: A string which, if supplied together with spheroid parameters, will
1256 restrict the tensor to either being 'oblate' or 'prolate'.
1257 @type spheroid_type: str
1258 """
1259
1260
1261 cdp.diff_tensor.set_type('spheroid')
1262
1263
1264 allowed_types = [None, 'oblate', 'prolate']
1265 if spheroid_type not in allowed_types:
1266 raise RelaxError("The 'spheroid_type' argument " + repr(spheroid_type) + " should be 'oblate', 'prolate', or None.")
1267 cdp.diff_tensor.set(param='spheroid_type', value=spheroid_type)
1268
1269
1270 if param_types == 0:
1271
1272 tm, Da, theta, phi = params
1273
1274
1275 tm = tm * time_scale
1276 Da = Da * d_scale
1277
1278
1279 set(value=[tm, Da], param=['tm', 'Da'])
1280
1281
1282 elif param_types == 1:
1283
1284 Diso, Da, theta, phi = params
1285
1286
1287 Diso = Diso * d_scale
1288 Da = Da * d_scale
1289
1290
1291 set(value=[Diso, Da], param=['Diso', 'Da'])
1292
1293
1294 elif param_types == 2:
1295
1296 tm, Dratio, theta, phi = params
1297
1298
1299 tm = tm * time_scale
1300
1301
1302 set(value=[tm, Dratio], param=['tm', 'Dratio'])
1303
1304
1305 elif param_types == 3:
1306
1307 Dpar, Dper, theta, phi = params
1308
1309
1310 Dpar = Dpar * d_scale
1311 Dper = Dper * d_scale
1312
1313
1314 set(value=[Dpar, Dper], param=['Dpar', 'Dper'])
1315
1316
1317 elif param_types == 4:
1318
1319 Diso, Dratio, theta, phi = params
1320
1321
1322 Diso = Diso * d_scale
1323
1324
1325 set(value=[Diso, Dratio], param=['Diso', 'Dratio'])
1326
1327
1328 else:
1329 raise RelaxUnknownParamCombError('param_types', param_types)
1330
1331
1332 if angle_units == 'deg':
1333 print("Converting the angles from degrees to radian units.")
1334 theta = (theta / 360.0) * 2.0 * pi
1335 phi = (phi / 360.0) * 2.0 * pi
1336
1337
1338 set(value=[theta, phi], param=['theta', 'phi'])
1339
1340
1342 """Function for testing the validity of the input parameters."""
1343
1344
1345 error = 1e-4
1346
1347
1348 tm = cdp.diff_tensor.tm
1349 if tm <= 0.0 or tm > 1e-6:
1350 raise RelaxError("The tm value of " + repr(tm) + " should be between zero and one microsecond.")
1351
1352
1353 if num_params == 4:
1354
1355 Diso = 1.0 / (6.0 * cdp.diff_tensor.tm)
1356 Da = cdp.diff_tensor.Da
1357
1358
1359 if Da < (-1.5*Diso - error*Diso) or Da > (3.0*Diso + error*Diso):
1360 raise RelaxError("The Da value of " + repr(Da) + " should be between -3/2 * Diso and 3Diso.")
1361
1362
1363 if num_params == 6:
1364
1365 Diso = 1.0 / (6.0 * cdp.diff_tensor.tm)
1366 Da = cdp.diff_tensor.Da
1367 Dr = cdp.diff_tensor.Dr
1368
1369
1370 if Da < (0.0 - error*Diso) or Da > (3.0*Diso + error*Diso):
1371 raise RelaxError("The Da value of " + repr(Da) + " should be between zero and 3Diso.")
1372
1373
1374 if Dr < (0.0 - error) or Dr > (1.0 + error):
1375 raise RelaxError("The Dr value of " + repr(Dr) + " should be between zero and one.")
1376
1377
1379 """Function for calculating the unit axes of the diffusion tensor.
1380
1381 Spheroid
1382 ========
1383
1384 The unit Dpar vector is::
1385
1386 | sin(theta) * cos(phi) |
1387 Dpar = | sin(theta) * sin(phi) |
1388 | cos(theta) |
1389
1390
1391 Ellipsoid
1392 =========
1393
1394 The unit Dx vector is::
1395
1396 | -sin(alpha) * sin(gamma) + cos(alpha) * cos(beta) * cos(gamma) |
1397 Dx = | -sin(alpha) * cos(gamma) - cos(alpha) * cos(beta) * sin(gamma) |
1398 | cos(alpha) * sin(beta) |
1399
1400 The unit Dy vector is::
1401
1402 | cos(alpha) * sin(gamma) + sin(alpha) * cos(beta) * cos(gamma) |
1403 Dy = | cos(alpha) * cos(gamma) - sin(alpha) * cos(beta) * sin(gamma) |
1404 | sin(alpha) * sin(beta) |
1405
1406 The unit Dz vector is::
1407
1408 | -sin(beta) * cos(gamma) |
1409 Dz = | sin(beta) * sin(gamma) |
1410 | cos(beta) |
1411
1412 """
1413
1414
1415 if cdp.diff_tensor.type == 'spheroid':
1416
1417 Dpar = zeros(3, float64)
1418
1419
1420 sin_theta = sin(cdp.diff_tensor.theta)
1421 cos_theta = cos(cdp.diff_tensor.theta)
1422 sin_phi = sin(cdp.diff_tensor.phi)
1423 cos_phi = cos(cdp.diff_tensor.phi)
1424
1425
1426 Dpar[0] = sin_theta * cos_phi
1427 Dpar[1] = sin_theta * sin_phi
1428 Dpar[2] = cos_theta
1429
1430
1431 return Dpar
1432
1433
1434 if cdp.diff_tensor.type == 'ellipsoid':
1435
1436 Dx = zeros(3, float64)
1437 Dy = zeros(3, float64)
1438 Dz = zeros(3, float64)
1439
1440
1441 sin_alpha = sin(cdp.diff_tensor.alpha)
1442 cos_alpha = cos(cdp.diff_tensor.alpha)
1443 sin_beta = sin(cdp.diff_tensor.beta)
1444 cos_beta = cos(cdp.diff_tensor.beta)
1445 sin_gamma = sin(cdp.diff_tensor.gamma)
1446 cos_gamma = cos(cdp.diff_tensor.gamma)
1447
1448
1449 Dx[0] = -sin_alpha * sin_gamma + cos_alpha * cos_beta * cos_gamma
1450 Dx[1] = -sin_alpha * cos_gamma - cos_alpha * cos_beta * sin_gamma
1451 Dx[2] = cos_alpha * sin_beta
1452
1453
1454 Dx[0] = cos_alpha * sin_gamma + sin_alpha * cos_beta * cos_gamma
1455 Dx[1] = cos_alpha * cos_gamma - sin_alpha * cos_beta * sin_gamma
1456 Dx[2] = sin_alpha * sin_beta
1457
1458
1459 Dx[0] = -sin_beta * cos_gamma
1460 Dx[1] = sin_beta * sin_gamma
1461 Dx[2] = cos_beta
1462
1463
1464 return Dx, Dy, Dz
1465