Coverage for tests/test_utils.py: 27%
Shortcuts 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
Shortcuts 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#!/usr/bin/env python
3#
4# LSST Data Management System
5#
6# Copyright 2008-2017 AURA/LSST.
7#
8# This product includes software developed by the
9# LSST Project (http://www.lsst.org/).
10#
11# This program is free software: you can redistribute it and/or modify
12# it under the terms of the GNU General Public License as published by
13# the Free Software Foundation, either version 3 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the LSST License Statement and
22# the GNU General Public License along with this program. If not,
23# see <https://www.lsstcorp.org/LegalNotices/>.
24#
25"""Test cases for lsst.cp.pipe.utils"""
27from __future__ import absolute_import, division, print_function
28import unittest
29import numpy as np
31import lsst.utils
32import lsst.utils.tests
34import lsst.afw.image as afwImage
35from lsst.geom import Box2I, Point2I, Extent2I
36import lsst.ip.isr as ipIsr
37from lsst.ip.isr import isrMock
39import lsst.cp.pipe.utils as cpUtils
42class UtilsTestCase(lsst.utils.tests.TestCase):
43 """A test case for the utility functions for cp_pipe."""
45 def setUp(self):
47 mockImageConfig = isrMock.IsrMock.ConfigClass()
49 # flatDrop is not really relevant as we replace the data
50 # but good to note it in case we change how this image is made
51 mockImageConfig.flatDrop = 0.99999
52 mockImageConfig.isTrimmed = True
54 self.flatExp = isrMock.FlatMock(config=mockImageConfig).run()
55 (shapeY, shapeX) = self.flatExp.getDimensions()
57 self.rng = np.random.RandomState(0)
58 self.flatMean = 1000
59 self.flatWidth = np.sqrt(self.flatMean)
60 flatData = self.rng.normal(self.flatMean, self.flatWidth, (shapeX, shapeY))
61 self.flatExp.image.array[:] = flatData
63 def test_countMaskedPixels(self):
64 exp = self.flatExp.clone()
65 mi = exp.maskedImage
66 self.assertEqual(cpUtils.countMaskedPixels(mi, 'NO_DATA'), 0)
67 self.assertEqual(cpUtils.countMaskedPixels(mi, 'BAD'), 0)
69 NODATABIT = mi.mask.getPlaneBitMask("NO_DATA")
70 noDataBox = Box2I(Point2I(31, 49), Extent2I(3, 6))
71 mi.mask[noDataBox] |= NODATABIT
73 self.assertEqual(cpUtils.countMaskedPixels(mi, 'NO_DATA'), noDataBox.getArea())
74 self.assertEqual(cpUtils.countMaskedPixels(mi, 'BAD'), 0)
76 mi.mask[noDataBox] ^= NODATABIT # XOR to reset what we did
77 self.assertEqual(cpUtils.countMaskedPixels(mi, 'NO_DATA'), 0)
79 def test_parseCmdlineNumberString(self):
80 parsed = cpUtils.parseCmdlineNumberString('1..5')
81 self.assertEqual(parsed, [1, 2, 3, 4, 5])
83 parsed = cpUtils.parseCmdlineNumberString('1..5:2^123..126')
84 self.assertEqual(parsed, [1, 3, 5, 123, 124, 125, 126])
86 parsed = cpUtils.parseCmdlineNumberString('12^23^34^43^987')
87 self.assertEqual(parsed, [12, 23, 34, 43, 987])
89 parsed = cpUtils.parseCmdlineNumberString('12^23^34^43^987..990')
90 self.assertEqual(parsed, [12, 23, 34, 43, 987, 988, 989, 990])
92 def test_checkExpLengthEqual(self):
93 exp1 = self.flatExp.clone()
94 exp2 = self.flatExp.clone()
96 self.assertTrue(cpUtils.checkExpLengthEqual(exp1, exp2))
98 visitInfo = afwImage.VisitInfo(exposureTime=-1, darkTime=1)
99 exp2.getInfo().setVisitInfo(visitInfo)
100 self.assertFalse(cpUtils.checkExpLengthEqual(exp1, exp2))
102 with self.assertRaises(RuntimeError):
103 cpUtils.checkExpLengthEqual(exp1, exp2, raiseWithMessage=True)
105 def test_validateIsrConfig(self):
107 # heavily abbreviated for the sake of the line lengths later
108 mandatory = ['doAssembleCcd'] # the mandatory options
109 forbidden = ['doFlat', 'doFringe'] # the forbidden options
110 desirable = ['doBias', 'doDark'] # the desirable options
111 undesirable = ['doLinearize', 'doBrighterFatter'] # the undesirable options
113 passingConfig = ipIsr.IsrTask.ConfigClass()
114 for item in (mandatory + desirable):
115 setattr(passingConfig, item, True)
116 for item in (forbidden + undesirable):
117 setattr(passingConfig, item, False)
119 task = ipIsr.IsrTask(config=passingConfig)
121 with self.assertRaises(TypeError):
122 cpUtils.validateIsrConfig(None, mandatory, forbidden, desirable, undesirable)
123 cpUtils.validateIsrConfig(passingConfig, mandatory, forbidden, desirable, undesirable)
125 with self.assertRaises(RuntimeError): # mandatory/forbidden swapped
126 cpUtils.validateIsrConfig(task, forbidden, mandatory, desirable, undesirable)
128 with self.assertRaises(RuntimeError): # raise for missing mandatory
129 cpUtils.validateIsrConfig(task, mandatory + ['test'], forbidden, desirable, undesirable)
131 logName = 'testLogger'
132 with self.assertLogs(logName, level='INFO'): # not found info-logs for (un)desirable
133 cpUtils.validateIsrConfig(task, mandatory, forbidden,
134 desirable + ['test'], undesirable, logName=logName)
135 cpUtils.validateIsrConfig(task, mandatory, forbidden,
136 desirable, undesirable + ['test'], logName=logName)
138 with self.assertLogs(logName, "WARN"): # not found warnings for forbidden
139 cpUtils.validateIsrConfig(task, mandatory, forbidden + ['test'],
140 desirable, undesirable, logName=logName)
141 with self.assertLogs("lsst", "WARN"): # not found warnings for forbidden
142 cpUtils.validateIsrConfig(task, mandatory, forbidden + ['test'],
143 desirable, undesirable, logName=None)
146class TestMemory(lsst.utils.tests.MemoryTestCase):
147 pass
150def setup_module(module):
151 lsst.utils.tests.init()
154if __name__ == "__main__": 154 ↛ 155line 154 didn't jump to line 155, because the condition on line 154 was never true
155 lsst.utils.tests.init()
156 unittest.main()