Coverage for python/lsst/obs/base/tests.py : 29%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
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"""
23Test utilities for obs_base and concrete obs* packages.
24"""
26__all__ = (
27 "ObsTests",
28 "make_ramp_array",
29 "make_ramp_exposure_trimmed",
30 "make_ramp_exposure_untrimmed",
31)
33import numpy as np
35from lsst.log import Log
37from lsst.afw.image import Exposure
38from lsst.afw.cameraGeom.utils import calcRawCcdBBox
40from . import butler_tests
41from . import mapper_tests
42from . import camera_tests
44__all__ = ["ObsTests"]
47class ObsTests(butler_tests.ButlerGetTests, mapper_tests.MapperTests,
48 camera_tests.CameraTests):
49 """Aggregator class for all of the obs_* test classes.
51 Inherit from this class, then lsst.utils.tests.TestCase, in that order.
53 Example subclass:
55 .. code-block:: python
57 class TestObs(lsst.obs.base.tests.ObsTests, lsst.utils.tests.TestCase):
58 def setUp(self):
59 self.setUp_tests(...)
60 self.setUp_butler_get(...)
61 self.setUp_mapper(...)
62 self.setUp_camera(...)
64 Notes
65 -----
66 The intention is for each obs package to have a single test class that
67 inherits from this collector class, thus "automatically" getting all new
68 tests. If those tests require setup that isn't defined in a given obs
69 package, that obs package will be broken until updated. This is
70 intentional, as a way to prevent obs packages from falling behind out of
71 neglect.
72 """
74 def setUp_tests(self, butler, mapper, dataIds):
75 """Set up the necessary shared variables used by multiple tests.
77 Parameters
78 ----------
79 butler: lsst.daf.persistence.Butler
80 A butler object, instantiated on the testdata repository for the
81 obs package being tested.
82 mapper: lsst.obs.CameraMapper
83 A CameraMapper object for your camera, instantiated on the testdata
84 repository the obs package being tested.
85 dataIds: dict
86 dictionary of (exposure name): (dataId of that exposure in the
87 testdata repository), with unittest.SkipTest as the value for any
88 exposures you do not have/do not want to test. It must contain a
89 valid 'raw' dataId, in addition to 'bias','flat','dark', which may
90 be set to SkipTest. For example::
92 self.dataIds = {'raw': {'visit': 1, 'filter': 'g'},
93 'bias': {'visit': 1},
94 'flat': {'visit': 1},
95 'dark': unittest.SkipTest
96 }
97 """
98 self.butler = butler
99 self.mapper = mapper
100 self.dataIds = dataIds
101 self.log = Log.getLogger('ObsTests')
103 def tearDown(self):
104 del self.butler
105 del self.mapper
106 super(ObsTests, self).tearDown()
109def make_ramp_array(bbox, pedestal):
110 """Make a 2-d ramp array.
112 Parameters
113 ----------
114 bbox : `lsst.geom.Box2I`
115 Bounding box for the array.
116 pedestal : `int`
117 Minimum value for the ramp.
119 Returns
120 -------
121 ramp : `np.ndarray`
122 A 2-d array with shape ``(bbox.getHeight(), bbox.getWidth())``.
123 end : `int`
124 One past the maximum value in the ramp (for use as the
125 pedestal for another box).
126 """
127 end = pedestal + bbox.getArea()
128 return np.arange(pedestal, end).reshape(bbox.getHeight(), bbox.getWidth()), end
131def make_ramp_exposure_untrimmed(detector, dtype=None):
132 """Create an untrimmed, assembled exposure with different ramps for
133 each sub-amplifier region.
135 Parameters
136 ----------
137 detector : `lsst.afw.cameraGeom.Detector`
138 Detector object that the new exposure should match. Must have all amp
139 flips and offsets set to False/zero (i.e. represent an already-
140 assembled image).
141 dtype : `np.dtype`, optional
142 Type of the new exposure. Defaults to ``int32``.
144 Returns
145 -------
146 exposure : `lsst.afw.image.Exposure`
147 New exposure with the given detector attached.
148 """
149 if dtype is None:
150 dtype = np.dtype(np.int32)
151 ramp_exposure = Exposure(calcRawCcdBBox(detector), dtype=np.dtype(dtype))
152 ramp_exposure.setDetector(detector)
153 pedestal = 0
154 for amp in detector:
155 for name in ("HorizontalOverscan", "VerticalOverscan", "Prescan", "Data"):
156 bbox = getattr(amp, f"getRaw{name}BBox")()
157 ramp, pedestal = make_ramp_array(bbox, pedestal)
158 ramp_exposure.image[bbox].array[:, :] = ramp
159 return ramp_exposure
162def make_ramp_exposure_trimmed(detector, dtype=None):
163 """Create a trimmed, assembled exposure with different ramps for
164 each amplifier region.
166 Parameters
167 ----------
168 detector : `lsst.afw.cameraGeom.Detector`
169 Detector object that the new exposure should match.
170 dtype : `np.dtype`, optional
171 Type of the new exposure. Defaults to ``int32``.
173 Returns
174 -------
175 exposure : `lsst.afw.image.Exposure`
176 New exposure with the given detector attached.
177 """
178 if dtype is None:
179 dtype = np.dtype(np.int32)
180 ramp_exposure = Exposure(detector.getBBox(), dtype=np.dtype(dtype))
181 ramp_exposure.setDetector(detector)
182 pedestal = 0
183 for amp in detector:
184 ramp, pedestal = make_ramp_array(amp.getBBox(), pedestal)
185 ramp_exposure.image[amp.getBBox()].array[:, :] = ramp
186 return ramp_exposure