1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """Module containing all the different cone type classes."""
24
25
26 from math import acos, asin, cos, pi, sqrt, sin
27
28
30 """A base class for all the cone objects."""
31
33 """Set up the cone object.
34
35 @param phi_x: The maximum cone angle along the x-eigenvector.
36 @type phi_x: float
37 @param phi_y: The maximum cone angle along the y-eigenvector.
38 @type phi_y: float
39 """
40
41
42 self._phi_x = phi_x
43 self._phi_y = phi_y
44
45
47 """Determine if the point is within the cone.
48
49 @param phi: The polar angle.
50 @type phi: float
51 @param theta: The azimuthal angle.
52 @type theta: float
53 @return: True if the point is within the cone, False otherwise.
54 @rtype: bool
55 """
56
57
58 if phi > self.phi_max(theta):
59 return False
60
61
62 return True
63
64
65
67 """The class for the cosine cone.
68
69 The ellipse is defined by::
70
71 phi_max = cos(theta) * phi_x + sin(theta) * phi_y,
72
73 where phi_max is the maximum polar angle for the given azimuthal angle theta, phi_x is the maximum cone angle along the x-eigenvector, and phi_y is that of the y-eigenvector. The cone axis is assumed to be the z-axis. The maximum cone opening angle allowed is pi/2.
74 """
75
77 """Set up the cone object.
78
79 @param phi_x: The maximum cone angle along the x-eigenvector.
80 @type phi_x: float
81 @param phi_y: The maximum cone angle along the y-eigenvector.
82 @type phi_y: float
83 """
84
85
86 self._phi_x = phi_x
87 self._phi_y = phi_y
88
89
90 self._scale = (phi_x - phi_y)/2
91
92
93 self._shift = (phi_x + phi_y)/2
94
95
97 """Return the maximum polar angle phi for the given azimuthal angle theta.
98
99 @param theta: The azimuthal angle.
100 @type theta: float
101 @return: The maximum polar angle phi for the value of theta.
102 @rtype: float
103 """
104
105
106 phi_max = self._scale * cos(theta*2) + self._shift
107
108
109 return phi_max
110
111
112 - def theta_max(self, phi, theta_min=0.0, theta_max=2*pi):
113 """Return the maximum azimuthal angle theta for the given polar angle phi.
114
115 @param phi: The polar angle.
116 @type phi: float
117 @keyword theta_min: The lower limit of the azimuthal angle range for complex distributions.
118 @type theta_min: float
119 @keyword theta_max: The upper limit of the azimuthal angle range for complex distributions.
120 @type theta_max: float
121 @return: The maximum azimuthal angle theta for the value of phi.
122 @rtype: float
123 """
124
125
126 b = (phi - self._shift)/self._scale
127
128
129 if theta_max < pi/2:
130 theta = 0.5*acos(b)
131 elif theta_max < pi:
132 theta = 0.5*acos(-b) + pi/2
133 elif theta_max < 3*pi/2:
134 theta = 0.5*acos(b) + pi
135 elif theta_max < 2*pi:
136 theta = 0.5*acos(-b) + 3*pi/2
137
138
139 return theta
140
141
142
144 """The class for the elliptic cone.
145
146 The ellipse is defined by::
147
148 1 / sin(phi_max)^2 = cos(theta)^2 / sin(phi_x)^2 + sin(theta)^2 / sin(phi_y)^2,
149
150 where phi_max is the maximum polar angle for the given azimuthal angle theta, phi_x is the maximum cone angle along the x-eigenvector, and phi_y is that of the y-eigenvector. The cone axis is assumed to be the z-axis. The maximum cone opening angle allowed is pi/2.
151 """
152
154 """Return the maximum polar angle phi for the given azimuthal angle theta.
155
156 @param theta: The azimuthal angle.
157 @type theta: float
158 @return: The maximum polar angle phi for the value of theta.
159 @rtype: float
160 """
161
162
163 phi_max = asin(1.0/sqrt((cos(theta) / sin(self._phi_x))**2 + (sin(theta) / sin(self._phi_y))**2))
164
165
166 return phi_max
167
168
169 - def theta_max(self, phi, theta_min=0.0, theta_max=2*pi):
170 """Return the maximum azimuthal angle theta for the given polar angle phi.
171
172 @param phi: The polar angle.
173 @type phi: float
174 @keyword theta_min: The lower limit of the azimuthal angle range for complex distributions.
175 @type theta_min: float
176 @keyword theta_max: The upper limit of the azimuthal angle range for complex distributions.
177 @type theta_max: float
178 @return: The maximum azimuthal angle theta for the value of phi.
179 @rtype: float
180 """
181
182
183 b = sqrt((1.0/sin(phi)**2 - 1.0/sin(self._phi_y)**2)/(1.0/sin(self._phi_x)**2 - 1.0/sin(self._phi_y)**2))
184
185
186 if theta_max < pi/2:
187 theta = acos(b)
188 elif theta_max < pi:
189 theta = acos(-b)
190 elif theta_max < 3*pi/2:
191 theta = -acos(-b)
192 elif theta_max < 2*pi:
193 theta = -acos(b)
194
195
196 return theta
197
198
199
201 """The class for the isotropic cone."""
202
204 """Set up the cone object.
205
206 @param angle: The cone angle.
207 @type angle: float
208 """
209
210
211 self._angle = angle
212
213
215 """Return the maximum polar angle phi for the given azimuthal angle theta.
216
217 @param theta: The azimuthal angle.
218 @type theta: float
219 @return: The maximum polar angle phi for the value of theta.
220 @rtype: float
221 """
222
223
224 return self._angle
225
226
228 """Return the maximum azimuthal angle theta for the given polar angle phi.
229
230 @param phi: The polar angle.
231 @type phi: float
232 @return: The maximum azimuthal angle theta for the value of phi.
233 @rtype: float
234 """
235
236
237 return 0.0
238
239
240
242 """The class for another pseudo-elliptic cone.
243
244 The pseudo-ellipse is defined by::
245
246 1/phi_max^2 = 1/phi_x^2 * cos(theta)^2 + 1/phi_y^2 * sin(theta)^2,
247
248 where phi_max is the maximum polar angle for the given azimuthal angle theta, phi_x is the maximum cone angle along the x-eigenvector, and phi_y is that of the y-eigenvector. The cone axis is assumed to be the z-axis.
249 """
250
252 """Return the maximum polar angle phi for the given azimuthal angle theta.
253
254 @param theta: The azimuthal angle.
255 @type theta: float
256 @return: The maximum polar angle phi for the value of theta.
257 @rtype: float
258 """
259
260
261 if self._phi_x == 0.0 or self._phi_y == 0.0:
262 return 0.0
263
264
265 phi_max = 1.0/sqrt(((1.0/self._phi_x) * cos(theta))**2 + ((1.0/self._phi_y) * sin(theta))**2)
266
267
268 return phi_max
269
270
271 - def theta_max(self, phi, theta_min=0.0, theta_max=2*pi):
272 """Return the maximum azimuthal angle theta for the given polar angle phi.
273
274 @param phi: The polar angle.
275 @type phi: float
276 @keyword theta_min: The lower limit of the azimuthal angle range for complex distributions.
277 @type theta_min: float
278 @keyword theta_max: The upper limit of the azimuthal angle range for complex distributions.
279 @type theta_max: float
280 @return: The maximum azimuthal angle theta for the value of phi.
281 @rtype: float
282 """
283
284
285 b = sqrt(((1.0/phi)**2 - (1.0/self._phi_y)**2) / ((1.0/self._phi_x)**2 - (1.0/self._phi_y)**2))
286
287
288 if theta_max < pi/2:
289 phi = acos(b)
290 elif theta_max < pi:
291 phi = acos(-b)
292 elif theta_max < 3*pi/2:
293 phi = -acos(-b)
294 elif theta_max < 2*pi:
295 phi = -acos(b)
296
297
298 return phi
299
300
301
303 """The class for the pseudo-elliptic cone.
304
305 This is not an elliptic cone! The pseudo-ellipse is defined by::
306
307 phi_max^2 = phi_x^2 * cos(theta)^2 + phi_y^2 * sin(theta)^2,
308
309 where phi_max is the maximum polar angle for the given azimuthal angle theta, phi_x is the maximum cone angle along the x-eigenvector, and phi_y is that of the y-eigenvector. The cone axis is assumed to be the z-axis.
310 """
311
313 """Return the maximum polar angle phi for the given azimuthal angle theta.
314
315 @param theta: The azimuthal angle.
316 @type theta: float
317 @return: The maximum polar angle phi for the value of theta.
318 @rtype: float
319 """
320
321
322 phi_max = sqrt((self._phi_x * cos(theta))**2 + (self._phi_y * sin(theta))**2)
323
324
325 return phi_max
326
327
328 - def theta_max(self, phi, theta_min=0.0, theta_max=2*pi):
329 """Return the maximum azimuthal angle theta for the given polar angle phi.
330
331 @param phi: The polar angle.
332 @type phi: float
333 @keyword theta_min: The lower limit of the azimuthal angle range for complex distributions.
334 @type theta_min: float
335 @keyword theta_max: The upper limit of the azimuthal angle range for complex distributions.
336 @type theta_max: float
337 @return: The maximum azimuthal angle theta for the value of phi.
338 @rtype: float
339 """
340
341
342 b = sqrt((phi**2 - self._phi_y**2)/(self._phi_x**2 - self._phi_y**2))
343
344
345 if theta_max < pi/2:
346 phi = acos(b)
347 elif theta_max < pi:
348 phi = acos(-b)
349 elif theta_max < 3*pi/2:
350 phi = -acos(-b)
351 elif theta_max < 2*pi:
352 phi = -acos(b)
353
354
355 return phi
356
357
358
360 r"""The class for the square cone.
361
362 The cone is defined by::
363
364 / phi_y, if 0 <= theta < pi/2,
365 |
366 phi_max = < phi_x, if pi/2 <= theta < 3*pi/3,
367 |
368 \ phi_y, if 3*pi/2 <= theta < 2*pi,
369
370 where phi_max is the maximum polar angle for the given azimuthal angle theta, phi_x is the maximum cone angle along the x-eigenvector, and phi_y is that of the y-eigenvector. The cone axis is assumed to be the z-axis. The maximum cone opening angle allowed is pi/2.
371 """
372
374 """Return the maximum polar angle phi for the given azimuthal angle theta.
375
376 @param theta: The azimuthal angle.
377 @type theta: float
378 @return: The maximum polar angle phi for the value of theta.
379 @rtype: float
380 """
381
382
383 if theta < pi/2:
384 phi_max = self._phi_y
385 elif theta < 3*pi/2:
386 phi_max = self._phi_x
387 elif theta < 2*pi:
388 phi_max = self._phi_y
389
390
391 return phi_max
392
393
394 - def theta_max(self, phi, theta_min=0.0, theta_max=2*pi):
395 """Return the maximum azimuthal angle theta for the given polar angle phi.
396
397 @param phi: The polar angle.
398 @type phi: float
399 @keyword theta_min: The lower limit of the azimuthal angle range for complex distributions.
400 @type theta_min: float
401 @keyword theta_max: The upper limit of the azimuthal angle range for complex distributions.
402 @type theta_max: float
403 @return: The maximum azimuthal angle theta for the value of phi.
404 @rtype: float
405 """
406
407
408 return 0
409 b = (phi - self._shift)/self._scale
410
411
412 if theta_max < pi/2:
413 theta = pi/4 *(1 - b)
414 elif theta_max < pi:
415 theta = pi/4 *(3 + b)
416 elif theta_max < 3*pi/2:
417 theta = pi/4 *(5 - b)
418 elif theta_max < 2*pi:
419 theta = pi/4 *(7 + b)
420
421
422 return theta
423
424
425
427 """The class for the zig-zag cone.
428
429 The cone is defined by::
430
431 phi_max = c * asin(cos(theta*2)) + a,
432
433 where::
434
435 c = (phi_x - phi_y)/2,
436
437 a = (phi_x + phi_y)/2,
438
439 and where phi_max is the maximum polar angle for the given azimuthal angle theta, phi_x is the maximum cone angle along the x-eigenvector, and phi_y is that of the y-eigenvector. The cone axis is assumed to be the z-axis. The maximum cone opening angle allowed is pi/2.
440 """
441
443 """Set up the cone object.
444
445 @param phi_x: The maximum cone angle along the x-eigenvector.
446 @type phi_x: float
447 @param phi_y: The maximum cone angle along the y-eigenvector.
448 @type phi_y: float
449 """
450
451
452 self._phi_x = phi_x
453 self._phi_y = phi_y
454
455
456 self._scale = (phi_x - phi_y)/2
457
458
459 self._shift = (phi_x + phi_y)/2
460
461
463 """Return the maximum polar angle phi for the given azimuthal angle theta.
464
465 @param theta: The azimuthal angle.
466 @type theta: float
467 @return: The maximum polar angle phi for the value of theta.
468 @rtype: float
469 """
470
471
472 b = 4.0 * theta / pi
473
474
475 if theta < pi/2:
476 phi_max = 1 - b
477 elif theta < pi:
478 phi_max = b - 3
479 elif theta < 3*pi/2:
480 phi_max = 5 - b
481 elif theta < 2*pi:
482 phi_max = b - 7
483
484
485 phi_max = self._scale * phi_max + self._shift
486
487
488 return phi_max
489
490
491 - def theta_max(self, phi, theta_min=0.0, theta_max=2*pi):
492 """Return the maximum azimuthal angle theta for the given polar angle phi.
493
494 @param phi: The polar angle.
495 @type phi: float
496 @keyword theta_min: The lower limit of the azimuthal angle range for complex distributions.
497 @type theta_min: float
498 @keyword theta_max: The upper limit of the azimuthal angle range for complex distributions.
499 @type theta_max: float
500 @return: The maximum azimuthal angle theta for the value of phi.
501 @rtype: float
502 """
503
504
505 b = (phi - self._shift)/self._scale
506
507
508 if theta_max < pi/2:
509 theta = pi/4 *(1 - b)
510 elif theta_max < pi:
511 theta = pi/4 *(3 + b)
512 elif theta_max < 3*pi/2:
513 theta = pi/4 *(5 - b)
514 elif theta_max < 2*pi:
515 theta = pi/4 *(7 + b)
516
517
518 return theta
519