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 phi_max = 1.0/sqrt(((1.0/self._phi_x) * cos(theta))**2 + ((1.0/self._phi_y) * sin(theta))**2)
262
263
264 return phi_max
265
266
267 - def theta_max(self, phi, theta_min=0.0, theta_max=2*pi):
268 """Return the maximum azimuthal angle theta for the given polar angle phi.
269
270 @param phi: The polar angle.
271 @type phi: float
272 @keyword theta_min: The lower limit of the azimuthal angle range for complex distributions.
273 @type theta_min: float
274 @keyword theta_max: The upper limit of the azimuthal angle range for complex distributions.
275 @type theta_max: float
276 @return: The maximum azimuthal angle theta for the value of phi.
277 @rtype: float
278 """
279
280
281 b = sqrt(((1.0/phi)**2 - (1.0/self._phi_y)**2) / ((1.0/self._phi_x)**2 - (1.0/self._phi_y)**2))
282
283
284 if theta_max < pi/2:
285 phi = acos(b)
286 elif theta_max < pi:
287 phi = acos(-b)
288 elif theta_max < 3*pi/2:
289 phi = -acos(-b)
290 elif theta_max < 2*pi:
291 phi = -acos(b)
292
293
294 return phi
295
296
297
299 """The class for the pseudo-elliptic cone.
300
301 This is not an elliptic cone! The pseudo-ellipse is defined by::
302
303 phi_max^2 = phi_x^2 * cos(theta)^2 + phi_y^2 * sin(theta)^2,
304
305 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.
306 """
307
309 """Return the maximum polar angle phi for the given azimuthal angle theta.
310
311 @param theta: The azimuthal angle.
312 @type theta: float
313 @return: The maximum polar angle phi for the value of theta.
314 @rtype: float
315 """
316
317
318 phi_max = sqrt((self._phi_x * cos(theta))**2 + (self._phi_y * sin(theta))**2)
319
320
321 return phi_max
322
323
324 - def theta_max(self, phi, theta_min=0.0, theta_max=2*pi):
325 """Return the maximum azimuthal angle theta for the given polar angle phi.
326
327 @param phi: The polar angle.
328 @type phi: float
329 @keyword theta_min: The lower limit of the azimuthal angle range for complex distributions.
330 @type theta_min: float
331 @keyword theta_max: The upper limit of the azimuthal angle range for complex distributions.
332 @type theta_max: float
333 @return: The maximum azimuthal angle theta for the value of phi.
334 @rtype: float
335 """
336
337
338 b = sqrt((phi**2 - self._phi_y**2)/(self._phi_x**2 - self._phi_y**2))
339
340
341 if theta_max < pi/2:
342 phi = acos(b)
343 elif theta_max < pi:
344 phi = acos(-b)
345 elif theta_max < 3*pi/2:
346 phi = -acos(-b)
347 elif theta_max < 2*pi:
348 phi = -acos(b)
349
350
351 return phi
352
353
354
356 """The class for the square cone.
357
358 The cone is defined by::
359
360 / phi_y, if 0 <= theta < pi/2,
361 |
362 phi_max = < phi_x, if pi/2 <= theta < 3*pi/3,
363 |
364 \ phi_y, if 3*pi/2 <= theta < 2*pi,
365
366 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.
367 """
368
370 """Return the maximum polar angle phi for the given azimuthal angle theta.
371
372 @param theta: The azimuthal angle.
373 @type theta: float
374 @return: The maximum polar angle phi for the value of theta.
375 @rtype: float
376 """
377
378
379 if theta < pi/2:
380 phi_max = self._phi_y
381 elif theta < 3*pi/2:
382 phi_max = self._phi_x
383 elif theta < 2*pi:
384 phi_max = self._phi_y
385
386
387 return phi_max
388
389
390 - def theta_max(self, phi, theta_min=0.0, theta_max=2*pi):
391 """Return the maximum azimuthal angle theta for the given polar angle phi.
392
393 @param phi: The polar angle.
394 @type phi: float
395 @keyword theta_min: The lower limit of the azimuthal angle range for complex distributions.
396 @type theta_min: float
397 @keyword theta_max: The upper limit of the azimuthal angle range for complex distributions.
398 @type theta_max: float
399 @return: The maximum azimuthal angle theta for the value of phi.
400 @rtype: float
401 """
402
403
404 return 0
405 b = (phi - self._shift)/self._scale
406
407
408 if theta_max < pi/2:
409 theta = pi/4 *(1 - b)
410 elif theta_max < pi:
411 theta = pi/4 *(3 + b)
412 elif theta_max < 3*pi/2:
413 theta = pi/4 *(5 - b)
414 elif theta_max < 2*pi:
415 theta = pi/4 *(7 + b)
416
417
418 return theta
419
420
421
423 """The class for the zig-zag cone.
424
425 The cone is defined by::
426
427 phi_max = c * asin(cos(theta*2)) + a,
428
429 where::
430
431 c = (phi_x - phi_y)/2,
432
433 a = (phi_x + phi_y)/2,
434
435 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.
436 """
437
439 """Set up the cone object.
440
441 @param phi_x: The maximum cone angle along the x-eigenvector.
442 @type phi_x: float
443 @param phi_y: The maximum cone angle along the y-eigenvector.
444 @type phi_y: float
445 """
446
447
448 self._phi_x = phi_x
449 self._phi_y = phi_y
450
451
452 self._scale = (phi_x - phi_y)/2
453
454
455 self._shift = (phi_x + phi_y)/2
456
457
459 """Return the maximum polar angle phi for the given azimuthal angle theta.
460
461 @param theta: The azimuthal angle.
462 @type theta: float
463 @return: The maximum polar angle phi for the value of theta.
464 @rtype: float
465 """
466
467
468 b = 4.0 * theta / pi
469
470
471 if theta < pi/2:
472 phi_max = 1 - b
473 elif theta < pi:
474 phi_max = b - 3
475 elif theta < 3*pi/2:
476 phi_max = 5 - b
477 elif theta < 2*pi:
478 phi_max = b - 7
479
480
481 phi_max = self._scale * phi_max + self._shift
482
483
484 return phi_max
485
486
487 - def theta_max(self, phi, theta_min=0.0, theta_max=2*pi):
488 """Return the maximum azimuthal angle theta for the given polar angle phi.
489
490 @param phi: The polar angle.
491 @type phi: float
492 @keyword theta_min: The lower limit of the azimuthal angle range for complex distributions.
493 @type theta_min: float
494 @keyword theta_max: The upper limit of the azimuthal angle range for complex distributions.
495 @type theta_max: float
496 @return: The maximum azimuthal angle theta for the value of phi.
497 @rtype: float
498 """
499
500
501 b = (phi - self._shift)/self._scale
502
503
504 if theta_max < pi/2:
505 theta = pi/4 *(1 - b)
506 elif theta_max < pi:
507 theta = pi/4 *(3 + b)
508 elif theta_max < 3*pi/2:
509 theta = pi/4 *(5 - b)
510 elif theta_max < 2*pi:
511 theta = pi/4 *(7 + b)
512
513
514 return theta
515