Coverage for tests/test_gen3.py : 32%

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_lsst.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://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/>.
22import os
23import unittest
24import shutil
25import tempfile
26from cProfile import Profile
27from pstats import Stats
29import numpy as np
31from lsst.obs.lsst import (LsstCam, LsstComCam, LsstCamImSim, LsstCamPhoSim,
32 LsstTS8, LsstTS3, LsstUCDCam, Latiss)
34from lsst.daf.butler import (Butler, DatasetType, FileDescriptor, Location,
35 StorageClass, StorageClassFactory)
37TESTDIR = os.path.abspath(os.path.dirname(__file__))
38DATAROOT = os.path.join(TESTDIR, os.path.pardir, "data", "input")
40# This test is unfortunately slow; leave a profiling option in in case we want
41# to improve it later. Initial version is about 60% YamlCamera construction
42# (!) and 40% SQLite operations inside Butler.
43PRINT_PROFILE = False
46class TestInstruments(unittest.TestCase):
48 def setUp(self):
49 self.root = tempfile.mkdtemp(dir=TESTDIR)
50 self.rng = np.random.RandomState(50) # arbitrary deterministic seed
52 @classmethod
53 def setUpClass(cls):
54 if PRINT_PROFILE:
55 cls.profile = Profile()
56 cls.profile.enable()
58 def tearDown(self):
59 if self.root is not None and os.path.exists(self.root):
60 shutil.rmtree(self.root, ignore_errors=True)
62 @classmethod
63 def tearDownClass(cls):
64 if PRINT_PROFILE:
65 stats = Stats(cls.profile)
66 stats.strip_dirs()
67 stats.sort_stats("cumtime")
68 stats.print_stats()
70 def checkInstrumentWithRegistry(self, cls, testRaw):
72 Butler.makeRepo(self.root)
73 butler = Butler(self.root, run="tests")
74 instrument = cls()
75 scFactory = StorageClassFactory()
77 # Check instrument class and metadata translator agree on
78 # instrument name -- use the raw formatter to do the file reading
79 rawFormatterClass = instrument.getRawFormatter({})
80 formatter = rawFormatterClass(FileDescriptor(Location(DATAROOT, testRaw), StorageClass("x")))
81 obsInfo = formatter.observationInfo
82 self.assertEqual(instrument.getName(), obsInfo.instrument)
84 # Add Instrument, Detector, and PhysicalFilter entries to the
85 # Butler Registry.
86 instrument.register(butler.registry)
88 # Define a DatasetType for the cameraGeom.Camera, which can be
89 # accessed just by identifying its Instrument.
90 # A real-world Camera DatasetType should be identified by a
91 # validity range as well.
92 cameraDatasetType = DatasetType("camera", dimensions=["instrument"],
93 storageClass=scFactory.getStorageClass("Camera"),
94 universe=butler.registry.dimensions)
95 butler.registry.registerDatasetType(cameraDatasetType)
97 # Define a DatasetType for cameraGeom.Detectors, which can be
98 # accessed by identifying its Instrument and (Butler) Detector.
99 # A real-world Detector DatasetType probably doesn't need to exist,
100 # as it would just duplicate information in the Camera, and
101 # reading a full Camera just to get a single Detector should be
102 # plenty efficient.
103 detectorDatasetType = DatasetType("detector", dimensions=["instrument", "detector"],
104 storageClass=scFactory.getStorageClass("Detector"),
105 universe=butler.registry.dimensions)
106 butler.registry.registerDatasetType(detectorDatasetType)
108 # Put and get the Camera.
109 dataId = dict(instrument=instrument.instrument)
110 butler.put(instrument.getCamera(), "camera", dataId=dataId)
111 camera = butler.get("camera", dataId)
112 # Full camera comparisons are *slow*; just compare names.
113 self.assertEqual(instrument.getCamera().getName(), camera.getName())
115 # Put and get a random subset of the Detectors.
116 allDetectors = list(instrument.getCamera())
117 numDetectors = min(3, len(allDetectors))
118 someDetectors = [allDetectors[i] for i in self.rng.choice(len(allDetectors),
119 size=numDetectors, replace=False)]
120 for cameraGeomDetector in someDetectors:
121 # Right now we only support integer detector IDs in data IDs;
122 # support for detector names and groups (i.e. rafts) is
123 # definitely planned but not yet implemented.
124 dataId = dict(instrument=instrument.instrument, detector=cameraGeomDetector.getId())
125 butler.put(cameraGeomDetector, "detector", dataId=dataId)
126 cameraGeomDetector2 = butler.get("detector", dataId=dataId)
127 # Full detector comparisons are *slow*; just compare names and
128 # serials.
129 self.assertEqual(cameraGeomDetector.getName(), cameraGeomDetector2.getName())
130 self.assertEqual(cameraGeomDetector.getSerial(), cameraGeomDetector2.getSerial())
132 def testLsstCam(self):
133 testFpath = "lsstCam/raw/2019-03-22/3019032200002/3019032200002-R10-S22-det035.fits"
134 self.checkInstrumentWithRegistry(LsstCam, testFpath)
136 def testComCam(self):
137 testFpath = "comCam/raw/2019-05-30/3019053000001/3019053000001-R22-S00-det000.fits"
138 self.checkInstrumentWithRegistry(LsstComCam, testFpath)
140 def testImSim(self):
141 self.checkInstrumentWithRegistry(LsstCamImSim,
142 "imsim/raw/204595/R11/00204595-R11-S20-det042.fits")
144 def testPhoSim(self):
145 self.checkInstrumentWithRegistry(LsstCamPhoSim,
146 "phosim/raw/204595/R11/00204595-R11-S20-det042.fits")
148 def testTs8(self):
149 self.checkInstrumentWithRegistry(LsstTS8,
150 "ts8/raw/6006D/201807241028453-RTM-010-S11-det067.fits")
152 def testTs3(self):
153 self.checkInstrumentWithRegistry(LsstTS3,
154 "ts3/raw/2016-07-22/201607220607067-R071-S00-det071.fits")
156 def testUcdCam(self):
157 self.checkInstrumentWithRegistry(LsstUCDCam,
158 "ucd/raw/2018-12-05/20181205233148-S00-det000.fits")
160 def testLatiss(self):
161 self.checkInstrumentWithRegistry(Latiss,
162 "latiss/raw/2018-09-20/3018092000065-det000.fits")
165if __name__ == "__main__": 165 ↛ 166line 165 didn't jump to line 166, because the condition on line 165 was never true
166 unittest.main()