LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
skyWcs.py
Go to the documentation of this file.
1 # This file is part of afw.
2 #
3 # Developed for the LSST Data Management System.
4 # This product includes software developed by the LSST Project
5 # (https://www.lsst.org).
6 # See the COPYRIGHT file at the top-level directory of this distribution
7 # for details of code ownership.
8 #
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <https://www.gnu.org/licenses/>.
21 
22 import numpy as np
23 import scipy
24 
25 from lsst.utils import continueClass
26 import lsst.geom
27 from ._python import reduceTransform
28 from ._geom import (SkyWcs, makeCdMatrix, makeFlippedWcs, makeModifiedWcs,
29  makeSkyWcs, makeTanSipWcs, makeWcsPairTransform,
30  getIntermediateWorldCoordsToSky, getPixelToIntermediateWorldCoords)
31 from ._hpxUtils import makeHpxWcs
32 
33 __all__ = ["SkyWcs", "makeCdMatrix", "makeFlippedWcs", "makeSkyWcs",
34  "makeModifiedWcs", "makeTanSipWcs", "makeWcsPairTransform",
35  "getIntermediateWorldCoordsToSky", "getPixelToIntermediateWorldCoords",
36  "makeHpxWcs"]
37 
38 
39 @continueClass
40 class SkyWcs: # noqa: F811
41  def pixelToSkyArray(self, x, y, degrees=False):
42  """
43  Convert numpy array pixels (x, y) to numpy array sky (ra, dec)
44  positions.
45 
46  Parameters
47  ----------
48  x : `np.ndarray`
49  Array of x values.
50  y : `np.ndarray`
51  Array of y values.
52  degrees : `bool`, optional
53  Return ra, dec arrays in degrees if True.
54 
55  Returns
56  -------
57  ra : `np.ndarray`
58  Array of Right Ascension. Units are radians unless
59  degrees=True.
60  dec : `np.ndarray`
61  Array of Declination. Units are radians unless
62  degrees=True.
63  """
64  xy = np.vstack((x, y))
65  ra, dec = np.vsplit(self.getTransform().getMapping().applyForward(xy), 2)
66  ra %= (2.*np.pi)
67 
68  if degrees:
69  return np.rad2deg(ra.ravel()), np.rad2deg(dec.ravel())
70  else:
71  return ra.ravel(), dec.ravel()
72 
73  def skyToPixelArray(self, ra, dec, degrees=False):
74  """
75  Convert numpy array sky (ra, dec) positions to numpy array
76  pixels (x, y).
77 
78  Parameters
79  ----------
80  ra : `np.ndarray`
81  Array of Right Ascension. Units are radians unless
82  degrees=True.
83  dec : `np.ndarray`
84  Array of Declination. Units are radians unless
85  degrees=True.
86  degrees : `bool`, optional
87  Input ra, dec arrays are degrees if True.
88 
89  Returns
90  -------
91  x : `np.ndarray`
92  Array of x values.
93  y : `np.ndarray`
94  Array of y values.
95  """
96  radec = np.vstack((ra, dec))
97  if degrees:
98  radec = np.deg2rad(radec)
99 
100  x, y = np.vsplit(self.getTransform().getMapping().applyInverse(radec), 2)
101 
102  return x.ravel(), y.ravel()
103 
104  def getRelativeRotationToWcs(self, otherWcs):
105  """Get the difference in sky rotation angle to the specified wcs.
106 
107  Ignoring location on the sky, if another wcs were atop this one,
108  what would the difference in rotation be? i.e. for
109 
110  otherWcs = createInitialSkyWcsFromBoresight(radec, rotation, detector)
111 
112  what is the value that needs to be added to ``self.rotation`` (or
113  subtracted from `other.rotation``) to align them?
114 
115  Parameters
116  ----------
117  otherWcs : `lsst.afw.geom.SkyWcs`
118  The wcs to calculate the angle to.
119 
120  Returns
121  -------
122  angle : `lsst.geom.Angle`
123  The angle between this and the supplied wcs,
124  over the half-open range [0, 2pi).
125  """
126  # Note: tests for this function live in
127  # obs_lsst/tests/test_afwWcsUtil.py due to the need for an easy
128  # constructor and instantiated detector, and the fact that afw
129  # cannot depend on obs_base or obs_lsst.
130 
131  m1 = self.getCdMatrix()
132  m2 = otherWcs.getCdMatrix()
133 
134  svd1 = scipy.linalg.svd(m1)
135  svd2 = scipy.linalg.svd(m2)
136 
137  m1rot = np.matmul(svd1[0], svd1[2])
138  m2rot = np.matmul(svd2[0], svd2[2])
139 
140  v_rot = [1, 0]
141 
142  v_rot = np.matmul(v_rot, m1rot) # rotate by wcs1
143  v_rot = np.matmul(v_rot, m2rot.T) # rotate _back_ by wcs2
144 
145  rotation = np.arctan2(v_rot[1], v_rot[0])
146  rotation = rotation % (2*np.pi)
147  return lsst.geom.Angle(rotation, lsst.geom.radians)
148 
149 
150 SkyWcs.__reduce__ = reduceTransform
def getRelativeRotationToWcs(self, otherWcs)
Definition: skyWcs.py:104
def skyToPixelArray(self, ra, dec, degrees=False)
Definition: skyWcs.py:73
def pixelToSkyArray(self, x, y, degrees=False)
Definition: skyWcs.py:41
A class representing an angle.
Definition: Angle.h:127