Skip to content

Commit 7530cf6

Browse files
authored
Merge pull request #6 from cta-observatory/fix-solid-angle
Fix solid angle
2 parents ecae9ec + 6ef79bb commit 7530cf6

File tree

1 file changed

+22
-52
lines changed

1 file changed

+22
-52
lines changed

src/pybkgmodel/camera.py

Lines changed: 22 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import numpy
2-
import numpy.ma
32
import scipy.special
43
import scipy.optimize
54

@@ -11,64 +10,35 @@
1110
from matplotlib import pyplot
1211

1312

14-
def rectangle_area(l, w):
13+
def solid_angle_lat_lon_rectangle(theta_E, theta_W, phi_N, phi_S):
1514
"""
16-
Area of the rectangle on a sphere of the unit radius.
15+
Calculate the solid angle of a latitude-longitude rectangle on a globe.
16+
Source of the formula: https://en.wikipedia.org/wiki/Solid_angle
1717
1818
Parameters
1919
----------
20-
l: astropy.units.rad or convertable to it
21-
Rectangle extension in longitude.
22-
w: astropy.units.rad or convertable to it
23-
Rectangle extension in latitude.
20+
phi_N: astropy.units.Quantity or astropy.coordinates.Angle
21+
North line of latitude
22+
phi_S: astropy.units.Quantity or astropy.coordinates.Angle
23+
South line of latitude
24+
theta_E: astropy.units.Quantity or astropy.coordinates.Angle
25+
East line of longitude
26+
theta_W: astropy.units.Quantity or astropy.coordinates.Angle
27+
West line of longitude
2428
2529
Returns
2630
-------
27-
area: astropy.units.sr
28-
Calcuated area
29-
30-
References
31-
----------
32-
[1] https://math.stackexchange.com/questions/1205927/how-to-calculate-the-area-covered-by-any-spherical-rectangle
33-
[2] http://en.wikipedia.org/wiki/Spherical_trigonometry#Area_and_spherical_excess
31+
solid_angle: astropy.units.sr
32+
Calculated solid angle of a latitude-longitude rectangle.
3433
"""
3534

36-
t1 = numpy.tan(l.to('rad').value / 2)
37-
t2 = numpy.tan(w.to('rad').value / 2)
38-
39-
return 4 * numpy.arcsin(t1 * t2) * u.sr
35+
phi_N = phi_N.to(u.Unit("rad"))
36+
phi_S = phi_S.to(u.Unit("rad"))
37+
theta_E = theta_E.to(u.Unit("rad"))
38+
theta_W = theta_W.to(u.Unit("rad"))
39+
solid_angle = (numpy.sin(phi_N) - numpy.sin(phi_S)) * (theta_E.to_value() - theta_W.to_value()) * u.sr
4040

41-
42-
def pixel_area(xedges, yedges):
43-
"""
44-
Area of a rectangular pixel on a shere. Pixel is defined by its edges.
45-
46-
Parameters
47-
----------
48-
xedges: array_like of astropy.units.rad or convertable to it
49-
Longitude of the pixel edges. Must have the shape of (2,).
50-
yedges: array_like of astropy.units.rad or convertable to it
51-
latitude of the pixel edges. Must have the shape of (2,).
52-
53-
Returns
54-
-------
55-
area: astropy.units.sr
56-
Calcuated area
57-
"""
58-
59-
l = abs(xedges[1] - xedges[0])
60-
w_outer = 2 * max(numpy.abs(yedges))
61-
w_inner = 2 * min(abs(yedges))
62-
63-
w_sign = numpy.sign(yedges)
64-
signes_match = numpy.equal(*w_sign)
65-
66-
if signes_match:
67-
area = 0.5 * (rectangle_area(l, w_outer) - rectangle_area(l, w_inner))
68-
else:
69-
area = 0.5 * (rectangle_area(l, w_outer) + rectangle_area(l, w_inner))
70-
71-
return area
41+
return solid_angle
7242

7343

7444
def cstat(y, model_y):
@@ -346,7 +316,7 @@ def mask_region(self, region):
346316
dummy_wcs = WCS(naxis=2)
347317
# Taken from https://docs.astropy.org/en/stable/wcs/example_create_imaging.html
348318
# Set up an "Airy's zenithal" projection
349-
# Vector properties may be set with Python lists, or Numpy arrays
319+
# Vector properties may be set with Python lists, or np arrays
350320
dummy_wcs.wcs.crpix = [-234.75, 8.3393]
351321
dummy_wcs.wcs.cdelt = numpy.array([-0.066667, 0.066667])
352322
dummy_wcs.wcs.crval = [0, -90]
@@ -423,8 +393,8 @@ def get_pixel_areas(self):
423393

424394
for i in range(nx):
425395
for j in range(ny):
426-
area[i, j] = pixel_area(self.xedges[i:i+2], self.yedges[j:j+2])
427-
396+
area[i, j] = solid_angle_lat_lon_rectangle(self.xedges[i], self.xedges[i+1], self.yedges[j], self.yedges[j+1])
397+
428398
return area
429399

430400
def to_hdu(self, name='BACKGROUND'):

0 commit comments

Comments
 (0)