Skip to content

Commit a5b3ea7

Browse files
committed
Document the math behind projections
1 parent 00d223f commit a5b3ea7

File tree

1 file changed

+156
-22
lines changed

1 file changed

+156
-22
lines changed

astropy/modeling/projections.py

Lines changed: 156 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Licensed under a 3-clause BSD style license - see LICENSE.rst
2+
# -*- coding: utf-8 -*-
23

34
"""
45
Implements projections--particularly sky projections defined in WCS Paper II
@@ -30,6 +31,7 @@
3031

3132

3233
__all__ = ['Projection', 'Pix2SkyProjection', 'Sky2PixProjection',
34+
'Zenithal', 'Cylindrical',
3335
'Pix2Sky_AZP', 'Sky2Pix_AZP', 'Pix2Sky_CAR', 'Sky2Pix_CAR',
3436
'Pix2Sky_CEA', 'Sky2Pix_CEA', 'Pix2Sky_CYP', 'Sky2Pix_CYP',
3537
'Pix2Sky_MER', 'Sky2Pix_MER',
@@ -66,12 +68,39 @@ class Sky2PixProjection(Projection):
6668

6769

6870
class Zenithal(Projection):
69-
"""Base class for all Zenithal projections."""
71+
r"""Base class for all Zenithal projections.
7072
73+
Zenithal (or azimuthal) projections map the sphere directly onto a
74+
plane. All zenithal projections are specified by defining the
75+
radius as a function of native latitude, :math:`R_\theta`.
7176
72-
class Pix2Sky_AZP(Pix2SkyProjection, Zenithal):
77+
The pixel-to-sky transformation is defined as:
78+
79+
.. math::
80+
\phi &= \arg(-y, x) \\
81+
R_\theta &= \sqrt{x^2 + y^2}
82+
83+
and the inverse (sky-to-pixel) is defined as:
84+
85+
.. math::
86+
x &= R_\theta \sin \phi \\
87+
y &= R_\theta \cos \phi
7388
"""
74-
AZP : Zenital perspective projection - pixel to sky.
89+
90+
91+
class Pix2Sky_AZP(Pix2SkyProjection, Zenithal):
92+
r"""
93+
AZP : Zenithal perspective projection - pixel to sky.
94+
95+
See `Zenithal` for a definition of the full transformation.
96+
97+
.. math::
98+
\theta = \arg(\rho, 1) - \sin^{-1}\left(\frac{\rho \mu}{\sqrt{\rho^2 + 1}}\right)
99+
100+
where:
101+
102+
.. math::
103+
\rho = \frac{\pi}{180^{\circ}}\frac{R_\theta}{\mu + 1}
75104
76105
Parameters
77106
--------------
@@ -138,14 +167,20 @@ def _compute_r_theta(x, y, gamma):
138167

139168

140169
class Sky2Pix_AZP(Sky2PixProjection, Zenithal):
141-
"""
170+
r"""
142171
AZP : Zenital perspective projection - sky to pixel.
143172
173+
See `Zenithal` for a definition of the full transformation.
174+
175+
.. math::
176+
R_\theta = \frac{180^{\circ}}{\pi}\frac{(\mu + 1) \cos \theta}{\mu + \sin \theta}
177+
144178
Parameters
145-
--------------
179+
----------
146180
mu : float
147181
distance from point of projection to center of sphere
148182
in spherical radii, default is 0.
183+
149184
gamma : float
150185
look angle in deg, default is 0.
151186
"""
@@ -185,8 +220,13 @@ def _compute_r_theta(cls, phi, theta, mu, gamma):
185220

186221

187222
class Pix2Sky_TAN(Pix2SkyProjection, Zenithal):
188-
"""
223+
r"""
189224
TAN : Gnomonic projection - pixel to sky.
225+
226+
See `Zenithal` for a definition of the full transformation.
227+
228+
.. math::
229+
\theta = \tan^{-1}\left(\frac{180^{\circ}}{\pi R_\theta}\right)
190230
"""
191231

192232
@property
@@ -207,8 +247,13 @@ def _compute_r_theta(x, y):
207247

208248

209249
class Sky2Pix_TAN(Sky2PixProjection, Zenithal):
210-
"""
250+
r"""
211251
TAN : Gnomonic Projection - sky to pixel.
252+
253+
See `Zenithal` for a definition of the full transformation.
254+
255+
.. math::
256+
R_\theta = \frac{180^{\circ}}{\pi}\cot \theta
212257
"""
213258

214259
@property
@@ -232,8 +277,13 @@ def _compute_r_theta(theta):
232277

233278

234279
class Pix2Sky_STG(Pix2SkyProjection, Zenithal):
235-
"""
280+
r"""
236281
STG : Stereographic Projection - pixel to sky.
282+
283+
See `Zenithal` for a definition of the full transformation.
284+
285+
.. math::
286+
\theta = 90^{\circ} - 2 \tan^{-1}\left(\frac{\pi R_\theta}{360^{\circ}}\right)
237287
"""
238288

239289
@property
@@ -254,8 +304,13 @@ def _compute_r_theta(x, y):
254304

255305

256306
class Sky2Pix_STG(Sky2PixProjection, Zenithal):
257-
"""
307+
r"""
258308
STG : Stereographic Projection - sky to pixel.
309+
310+
See `Zenithal` for a definition of the full transformation.
311+
312+
.. math::
313+
R_\theta = \frac{180^{\circ}}{\pi}\frac{2 \cos \theta}{1 + \sin \theta}
259314
"""
260315

261316
@property
@@ -279,8 +334,13 @@ def _compute_r_theta(cls, theta):
279334

280335

281336
class Pix2Sky_SIN(Pix2SkyProjection, Zenithal):
282-
"""
337+
r"""
283338
SIN : Slant orthographic projection - pixel to sky.
339+
340+
See `Zenithal` for a definition of the full transformation.
341+
342+
.. math::
343+
\theta = \cos^{-1}\left(\frac{\pi}{180^{\circ}}R_\theta\right)
284344
"""
285345

286346
@property
@@ -301,8 +361,13 @@ def _compute_r_theta(x, y):
301361

302362

303363
class Sky2Pix_SIN(Sky2PixProjection, Zenithal):
304-
"""
364+
r"""
305365
SIN : Slant orthographic projection - sky to pixel.
366+
367+
See `Zenithal` for a definition of the full transformation.
368+
369+
.. math::
370+
R_\theta = \frac{180^{\circ}}{\pi}\cos \theta
306371
"""
307372

308373
@property
@@ -325,12 +390,34 @@ def _compute_r_theta(cls, theta):
325390

326391

327392
class Cylindrical(Projection):
328-
"""Base class for Cylindrical projections."""
393+
r"""Base class for Cylindrical projections.
394+
395+
Cylindrical projections are so-named because the surface of
396+
projection is a cylinder.
397+
"""
329398

330399

331400
class Pix2Sky_CYP(Pix2SkyProjection, Cylindrical):
332-
"""
401+
r"""
333402
CYP : Cylindrical perspective - pixel to sky.
403+
404+
.. math::
405+
\phi &= \frac{x}{\lambda} \\
406+
\theta &= \arg(1, \eta) + \sin{-1}\left(\frac{\eta \mu}{\sqrt{\eta^2 + 1}}\right)
407+
408+
where:
409+
410+
.. math::
411+
\eta = \frac{\pi}{180^{\circ}}\frac{y}{\mu + \lambda}
412+
413+
Parameters
414+
----------
415+
mu : float
416+
distance from center of sphere in the direction opposite the
417+
projected surface, in spherical radii, default is 0.
418+
419+
lam : float
420+
radius of the cylinder in spherical radii, default is 0.
334421
"""
335422

336423
def _validate_mu(mu, model):
@@ -367,8 +454,21 @@ def evaluate(cls, x, y, mu, lam):
367454

368455

369456
class Sky2Pix_CYP(Sky2PixProjection, Cylindrical):
370-
"""
457+
r"""
371458
CYP : Cylindrical Perspective - sky to pixel.
459+
460+
.. math::
461+
x &= \lambda \phi
462+
y &= \frac{180^{\circ}}{\pi}\left(\frac{\mu + \lambda}{\mu + \cos \theta}\right)\sin \theta
463+
464+
Parameters
465+
----------
466+
mu : float
467+
distance from center of sphere in the direction opposite the
468+
projected surface, in spherical radii, default is 0.
469+
470+
lam : float
471+
radius of the cylinder in spherical radii, default is 0.
372472
"""
373473

374474
# TODO: Eliminate duplication on these
@@ -403,8 +503,17 @@ def evaluate(cls, phi, theta, mu, lam):
403503

404504

405505
class Pix2Sky_CEA(Pix2SkyProjection, Cylindrical):
406-
"""
506+
r"""
407507
CEA : Cylindrical equal area projection - pixel to sky.
508+
509+
.. math::
510+
\phi &= x \\
511+
\theta &= \sin^{-1}\left(\frac{\pi}{180^{\circ}}\lambda y\right)
512+
513+
Parameters
514+
----------
515+
lam : float
516+
radius of the cylinder in spherical radii, default is 0.
408517
"""
409518

410519
lam = Parameter(default=1)
@@ -422,8 +531,17 @@ def evaluate(cls, x, y, lam):
422531

423532

424533
class Sky2Pix_CEA(Sky2PixProjection, Cylindrical):
425-
"""
534+
r"""
426535
CEA: Cylindrical equal area projection - sky to pixel.
536+
537+
.. math::
538+
x &= \phi \\
539+
y &= \frac{180^{\circ}}{\pi}\frac{\sin \theta}{\lambda}
540+
541+
Parameters
542+
----------
543+
lam : float
544+
radius of the cylinder in spherical radii, default is 0.
427545
"""
428546

429547
lam = Parameter(default=1)
@@ -442,8 +560,12 @@ def evaluate(cls, phi, theta, lam):
442560

443561

444562
class Pix2Sky_CAR(Pix2SkyProjection, Cylindrical):
445-
"""
446-
CAR: Plate carree projection - pixel to sky.
563+
r"""
564+
CAR: Plate carrée projection - pixel to sky.
565+
566+
.. math::
567+
\phi &= x \\
568+
\theta &= y
447569
"""
448570

449571
@property
@@ -460,8 +582,12 @@ def evaluate(x, y):
460582

461583

462584
class Sky2Pix_CAR(Sky2PixProjection, Cylindrical):
463-
"""
464-
CAR: Plate carree projection - sky to pixel.
585+
r"""
586+
CAR: Plate carrée projection - sky to pixel.
587+
588+
.. math::
589+
x &= \phi \\
590+
y &= \theta
465591
"""
466592

467593
@property
@@ -478,8 +604,12 @@ def evaluate(phi, theta):
478604

479605

480606
class Pix2Sky_MER(Pix2SkyProjection, Cylindrical):
481-
"""
607+
r"""
482608
MER: Mercator - pixel to sky.
609+
610+
.. math::
611+
\phi &= x \\
612+
\theta &= 2 \tan^{-1}\left(e^{y \pi / 180^{\circ}}\right)-90^{\circ}
483613
"""
484614

485615
@property
@@ -495,8 +625,12 @@ def evaluate(cls, x, y):
495625

496626

497627
class Sky2Pix_MER(Sky2PixProjection, Cylindrical):
498-
"""
628+
r"""
499629
MER: Mercator - sky to pixel.
630+
631+
.. math::
632+
x &= \phi \\
633+
y &= \frac{180^{\circ}}{\pi}\ln \tan \left(\frac{90^{\circ} + \theta}{2}\right)
500634
"""
501635

502636
@property

0 commit comments

Comments
 (0)