Coverage for python/lsst/obs/base/utils.py: 35%
28 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-03-29 10:10 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-03-29 10:10 +0000
1# This file is part of obs_base.
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/>.
22__all__ = ("InitialSkyWcsError", "createInitialSkyWcs", "createInitialSkyWcsFromBoresight", "bboxFromIraf")
24import re
26import lsst.geom as geom
27import lsst.pex.exceptions
28from lsst.afw.cameraGeom import FIELD_ANGLE, PIXELS
29from lsst.afw.geom.skyWcs import makeSkyWcs
30from lsst.afw.image import RotType
33class InitialSkyWcsError(Exception):
34 """For handling failures when creating a SkyWcs from a camera geometry and
35 boresight.
37 Typically used as a chained exception from a lower level exception.
38 """
40 pass
43def createInitialSkyWcs(visitInfo, detector, flipX=False):
44 """Create a SkyWcs from the visit information and detector geometry.
46 A typical use case for this is to create the initial WCS for a newly-read
47 raw exposure.
50 Parameters
51 ----------
52 visitInfo : `lsst.afw.image.VisitInfo`
53 Where to get the telescope boresight and rotator angle from.
54 detector : `lsst.afw.cameraGeom.Detector`
55 Where to get the camera geometry from.
56 flipX : `bool`, optional
57 If False, +X is along W, if True +X is along E.
59 Returns
60 -------
61 skyWcs : `lsst.afw.geom.SkyWcs`
62 The new composed WCS.
64 Raises
65 ------
66 InitialSkyWcsError
67 Raised if there is an error generating the SkyWcs, chained from the
68 lower-level exception if available.
69 """
70 if visitInfo.getRotType() != RotType.SKY:
71 msg = (
72 "Cannot create SkyWcs from camera geometry: rotator angle defined using "
73 f"RotType={visitInfo.getRotType()} instead of SKY."
74 )
75 raise InitialSkyWcsError(msg)
76 orientation = visitInfo.getBoresightRotAngle()
77 boresight = visitInfo.getBoresightRaDec()
78 return createInitialSkyWcsFromBoresight(boresight, orientation, detector, flipX)
81def createInitialSkyWcsFromBoresight(boresight, orientation, detector, flipX=False):
82 """Create a SkyWcs from the telescope boresight and detector geometry.
84 A typical usecase for this is to create the initial WCS for a newly-read
85 raw exposure.
87 Parameters
88 ----------
89 boresight : `lsst.geom.SpherePoint`
90 The ICRS boresight RA/Dec
91 orientation : `lsst.geom.Angle`
92 The rotation angle of the focal plane on the sky.
93 detector : `lsst.afw.cameraGeom.Detector`
94 Where to get the camera geometry from.
95 flipX : `bool`, optional
96 If False, +X is along W, if True +X is along E.
98 Returns
99 -------
100 skyWcs : `lsst.afw.geom.SkyWcs`
101 The new composed WCS.
103 Raises
104 ------
105 InitialSkyWcsError
106 Raised if there is an error generating the SkyWcs, chained from the
107 lower-level exception if available.
108 """
109 try:
110 pixelsToFieldAngle = detector.getTransform(
111 detector.makeCameraSys(PIXELS), detector.makeCameraSys(FIELD_ANGLE)
112 )
113 except lsst.pex.exceptions.InvalidParameterError as e:
114 raise InitialSkyWcsError("Cannot compute PIXELS to FIELD_ANGLE Transform.") from e
115 return makeSkyWcs(pixelsToFieldAngle, orientation, flipX, boresight)
118def bboxFromIraf(irafBBoxStr):
119 """Return a Box2I corresponding to an IRAF-style BBOX.
121 [x0:x1,y0:y1] where x0 and x1 are the one-indexed start and end columns,
122 and correspondingly y0 and y1 are the start and end rows.
123 """
124 mat = re.search(r"^\[([-\d]+):([-\d]+),([-\d]+):([-\d]+)\]$", irafBBoxStr)
125 if not mat:
126 raise RuntimeError('Unable to parse IRAF-style bbox "%s"' % irafBBoxStr)
127 x0, x1, y0, y1 = (int(_) for _ in mat.groups())
129 return geom.BoxI(geom.PointI(x0 - 1, y0 - 1), geom.PointI(x1 - 1, y1 - 1))