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