lsst.obs.base  19.0.0-25-g78ff95b
instrument_tests.py
Go to the documentation of this file.
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 <http://www.gnu.org/licenses/>.
21 
22 """Helpers for writing tests against subclassses of Instrument.
23 
24 These are not tests themselves, but can be subclassed (plus unittest.TestCase)
25 to get a functional test of an Instrument.
26 """
27 
28 import abc
29 import dataclasses
30 
31 from lsst.daf.butler import Registry
32 from lsst.daf.butler import ButlerConfig
33 
34 
35 @dataclasses.dataclass
37  """Values to test against in sublcasses of `InstrumentTests`.
38  """
39 
40  name: str
41  """The name of the Camera this instrument describes."""
42 
43  nDetectors: int
44  """The number of detectors in the Camera."""
45 
46  firstDetectorName: str
47  """The name of the first detector in the Camera."""
48 
49  physical_filters: {str}
50  """A subset of the physical filters should be registered."""
51 
52 
53 class InstrumentTests(metaclass=abc.ABCMeta):
54  """Tests of sublcasses of Instrument.
55 
56  TestCase subclasses must derive from this, then `TestCase`, and override
57  ``data`` and ``instrument``.
58  """
59 
60  data = None
61  """`InstrumentTestData` containing the values to test against."""
62 
63  instrument = None
64  """The `~lsst.obs.base.Instrument` to be tested."""
65 
66  def test_name(self):
67  self.assertEqual(self.instrument.getName(), self.data.name)
68 
69  def test_getCamera(self):
70  """Test that getCamera() returns a reasonable Camera definition.
71  """
72  camera = self.instrument.getCamera()
73  self.assertEqual(camera.getName(), self.instrument.getName())
74  self.assertEqual(len(camera), self.data.nDetectors)
75  self.assertEqual(next(iter(camera)).getName(), self.data.firstDetectorName)
76 
77  def test_register(self):
78  """Test that register() sets appropriate Dimensions.
79  """
80  registry = Registry.fromConfig(ButlerConfig())
81  # check that the registry starts out empty
82  self.assertEqual(list(registry.queryDimensions(["instrument"])), [])
83  self.assertEqual(list(registry.queryDimensions(["detector"])), [])
84  self.assertEqual(list(registry.queryDimensions(["physical_filter"])), [])
85 
86  # register the instrument and check that certain dimensions appear
87  self.instrument.register(registry)
88  instrumentDataIds = list(registry.queryDimensions(["instrument"]))
89  self.assertEqual(len(instrumentDataIds), 1)
90  instrumentNames = {dataId["instrument"] for dataId in instrumentDataIds}
91  self.assertEqual(instrumentNames, {self.data.name})
92  detectorDataIds = list(registry.queryDimensions(["detector"]))
93  self.assertEqual(len(detectorDataIds), self.data.nDetectors)
94  detectorNames = {dataId.records["detector"].full_name for dataId in detectorDataIds}
95  self.assertIn(self.data.firstDetectorName, detectorNames)
96  physicalFilterDataIds = list(registry.queryDimensions(["physical_filter"]))
97  filterNames = {dataId['physical_filter'] for dataId in physicalFilterDataIds}
98  self.assertGreaterEqual(filterNames, self.data.physical_filters)