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 manipulation of angular information."""
24
25
26 from math import pi
27
28
29 from lib.errors import RelaxError
30
31
32 -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):
33 """Fold the spherical angles taking symmetry into account.
34
35 The angles will be folded between::
36
37 0 <= theta <= pi,
38 0 <= phi <= 2*pi,
39
40 @param theta: The azimuthal angle.
41 @type theta: float
42 @param phi: The polar angle.
43 @type phi: float
44 @param theta_lower: The theta angle lower bound (defaults to 0).
45 @type theta_lower: float
46 @param theta_upper: The theta angle upper bound (defaults to 2*pi).
47 @type theta_upper: float
48 @param theta_window: The size of the theta angle window where symmetry exists (defaults to 2*pi).
49 @type theta_window: float
50 @param phi_lower: The phi angle lower bound (defaults to 0).
51 @type phi_lower: float
52 @param phi_upper: The phi angle upper bound (defaults to 2*pi).
53 @type phi_upper: float
54 @param phi_window: The size of the phi angle window where symmetry exists (defaults to 2*pi).
55 @type phi_window: float
56 @return: The folded angles, theta and phi.
57 @rtype: float
58 """
59
60
61 if theta_window - (theta_upper - theta_lower) > 1e-7:
62 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))
63 if phi_window - (phi_upper - phi_lower) > 1e-7:
64 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))
65
66
67 theta = wrap_angles(theta, theta_lower, theta_upper, theta_window)
68 phi = wrap_angles(phi, phi_lower, phi_upper, phi_window)
69
70
71 if phi >= phi_upper - phi_window/2.0:
72 theta = pi - theta
73 phi = phi - pi
74
75
76 theta = wrap_angles(theta, theta_lower, theta_upper, theta_window)
77 phi = wrap_angles(phi, phi_lower, phi_upper, phi_window)
78
79
80 return theta, phi
81
82
84 """Convert the given angle to be between the lower and upper values.
85
86 @param angle: The starting angle.
87 @type angle: float
88 @param lower: The lower bound.
89 @type lower: float
90 @param upper: The upper bound.
91 @type upper: float
92 @param window: The size of the window where symmetry exists (defaults to 2pi).
93 @type window: float
94 @return: The wrapped angle.
95 @rtype: float
96 """
97
98
99 if window - (upper - lower) > 1e-7:
100 raise RelaxError("The lower and upper bounds [%s, %s] do not match the window size of %s." % (lower, upper, window))
101
102
103 while True:
104
105 if angle > upper:
106 angle = angle - window
107
108
109 elif angle < lower:
110 angle = angle + window
111
112
113 else:
114 break
115
116
117 return angle
118