1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 """Module for the manipulation of angular information."""
25
26
27 from math import acos, pi, sin
28 from numpy import dot
29 from warnings import warn
30
31
32 from generic_fns import pipes
33 from generic_fns.mol_res_spin import exists_mol_res_spin_data, generate_spin_id, spin_loop
34 from relax_errors import RelaxError, RelaxNoPdbError, RelaxNoSequenceError, RelaxNoTensorError
35 from relax_warnings import RelaxWarning
36
37
67
68
70 """Calculate the spherical angles of the bond vector in the ellipsoid frame."""
71
72
73 Dx, Dy, Dz = diffusion_tensor.unit_axes()
74
75
76 for spin, mol_name, res_num, res_name in spin_loop(full_info=True):
77
78 if not hasattr(spin, 'xh_vect'):
79
80 spin_id = generate_spin_id(mol_name, res_num, res_name, spin.num, spin.name)
81
82
83 warn(RelaxWarning("No angles could be calculated for the spin " + repr(spin_id) + "."))
84
85
86 continue
87
88
89 dz = dot(Dz, spin.xh_vect)
90 dx = dot(Dx, spin.xh_vect)
91
92
93 spin.theta = acos(dz)
94
95
96 spin.phi = acos(dx / sin(spin.theta))
97
98
99 -def fold_spherical_angles(theta, phi, theta_lower=0, theta_upper=2*pi, theta_window=2*pi, phi_lower=0, phi_upper=2*pi, phi_window=2*pi):
100 """Fold the spherical angles taking symmetry into account.
101
102 The angles will be folded between::
103
104 0 <= theta <= pi,
105 0 <= phi <= 2*pi,
106
107 @param theta: The azimuthal angle.
108 @type theta: float
109 @param phi: The polar angle.
110 @type phi: float
111 @param theta_lower: The theta angle lower bound (defaults to 0).
112 @type theta_lower: float
113 @param theta_upper: The theta angle upper bound (defaults to 2*pi).
114 @type theta_upper: float
115 @param theta_window: The size of the theta angle window where symmetry exists (defaults to 2*pi).
116 @type theta_window: float
117 @param phi_lower: The phi angle lower bound (defaults to 0).
118 @type phi_lower: float
119 @param phi_upper: The phi angle upper bound (defaults to 2*pi).
120 @type phi_upper: float
121 @param phi_window: The size of the phi angle window where symmetry exists (defaults to 2*pi).
122 @type phi_window: float
123 @return: The folded angles, theta and phi.
124 @rtype: float
125 """
126
127
128 if theta_window - (theta_upper - theta_lower) > 1e-7:
129 raise RelaxError, "The theta angle lower and upper bounds [%s, %s] do not match the window size of %s." % (theta_lower, theta_upper, theta_window)
130 if phi_window - (phi_upper - phi_lower) > 1e-7:
131 raise RelaxError, "The phi angle lower and upper bounds [%s, %s] do not match the window size of %s." % (phi_lower, phi_upper, phi_window)
132
133
134 theta = wrap_angles(theta, theta_lower, theta_upper, theta_window)
135 phi = wrap_angles(phi, phi_lower, phi_upper, phi_window)
136
137
138 if phi >= phi_upper - phi_window/2.0:
139 theta = pi - theta
140 phi = phi - pi
141
142
143 theta = wrap_angles(theta, theta_lower, theta_upper, theta_window)
144 phi = wrap_angles(phi, phi_lower, phi_upper, phi_window)
145
146
147 return theta, phi
148
149
151 """Function for calculating the angle alpha of the XH vector within the spheroid frame."""
152
153
154 for spin, mol_name, res_num, res_name in spin_loop(full_info=True):
155
156 if not hasattr(spin, 'xh_vect'):
157
158 spin_id = generate_spin_id(mol_name, res_num, res_name, spin.num, spin.name)
159
160
161 warn(RelaxWarning("No angles could be calculated for the spin " + repr(spin_id) + "."))
162
163
164 continue
165
166
167 spin.alpha = acos(dot(cdp.diff_tensor.Dpar_unit, spin.xh_vect))
168
169
171 """Convert the given angle to be between the lower and upper values.
172
173 @param angle: The starting angle.
174 @type angle: float
175 @param lower: The lower bound.
176 @type lower: float
177 @param upper: The upper bound.
178 @type upper: float
179 @param window: The size of the window where symmetry exists (defaults to 2pi).
180 @type window: float
181 @return: The wrapped angle.
182 @rtype: float
183 """
184
185
186 if window - (upper - lower) > 1e-7:
187 raise RelaxError, "The lower and upper bounds [%s, %s] do not match the window size of %s." % (lower, upper, window)
188
189
190 while True:
191
192 if angle > upper:
193 angle = angle - window
194
195
196 elif angle < lower:
197 angle = angle + window
198
199
200 else:
201 break
202
203
204 return angle
205