Coverage for tests/test_utils.py: 25%
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
38import lsst.log
40import lsst.cp.pipe.utils as cpUtils
43class UtilsTestCase(lsst.utils.tests.TestCase):
44 """A test case for the utility functions for cp_pipe."""
46 def setUp(self):
48 mockImageConfig = isrMock.IsrMock.ConfigClass()
50 # flatDrop is not really relevant as we replace the data
51 # but good to note it in case we change how this image is made
52 mockImageConfig.flatDrop = 0.99999
53 mockImageConfig.isTrimmed = True
55 self.flatExp = isrMock.FlatMock(config=mockImageConfig).run()
56 (shapeY, shapeX) = self.flatExp.getDimensions()
58 self.rng = np.random.RandomState(0)
59 self.flatMean = 1000
60 self.flatWidth = np.sqrt(self.flatMean)
61 flatData = self.rng.normal(self.flatMean, self.flatWidth, (shapeX, shapeY))
62 self.flatExp.image.array[:] = flatData
64 def test_countMaskedPixels(self):
65 exp = self.flatExp.clone()
66 mi = exp.maskedImage
67 self.assertEqual(cpUtils.countMaskedPixels(mi, 'NO_DATA'), 0)
68 self.assertEqual(cpUtils.countMaskedPixels(mi, 'BAD'), 0)
70 NODATABIT = mi.mask.getPlaneBitMask("NO_DATA")
71 noDataBox = Box2I(Point2I(31, 49), Extent2I(3, 6))
72 mi.mask[noDataBox] |= NODATABIT
74 self.assertEqual(cpUtils.countMaskedPixels(mi, 'NO_DATA'), noDataBox.getArea())
75 self.assertEqual(cpUtils.countMaskedPixels(mi, 'BAD'), 0)
77 mi.mask[noDataBox] ^= NODATABIT # XOR to reset what we did
78 self.assertEqual(cpUtils.countMaskedPixels(mi, 'NO_DATA'), 0)
80 def test_parseCmdlineNumberString(self):
81 parsed = cpUtils.parseCmdlineNumberString('1..5')
82 self.assertEqual(parsed, [1, 2, 3, 4, 5])
84 parsed = cpUtils.parseCmdlineNumberString('1..5:2^123..126')
85 self.assertEqual(parsed, [1, 3, 5, 123, 124, 125, 126])
87 parsed = cpUtils.parseCmdlineNumberString('12^23^34^43^987')
88 self.assertEqual(parsed, [12, 23, 34, 43, 987])
90 parsed = cpUtils.parseCmdlineNumberString('12^23^34^43^987..990')
91 self.assertEqual(parsed, [12, 23, 34, 43, 987, 988, 989, 990])
93 def test_checkExpLengthEqual(self):
94 exp1 = self.flatExp.clone()
95 exp2 = self.flatExp.clone()
97 self.assertTrue(cpUtils.checkExpLengthEqual(exp1, exp2))
99 visitInfo = afwImage.VisitInfo(exposureTime=-1, darkTime=1)
100 exp2.getInfo().setVisitInfo(visitInfo)
101 self.assertFalse(cpUtils.checkExpLengthEqual(exp1, exp2))
103 with self.assertRaises(RuntimeError):
104 cpUtils.checkExpLengthEqual(exp1, exp2, raiseWithMessage=True)
106 def test_validateIsrConfig(self):
108 # heavily abbreviated for the sake of the line lengths later
109 mandatory = ['doAssembleCcd'] # the mandatory options
110 forbidden = ['doFlat', 'doFringe'] # the forbidden options
111 desirable = ['doBias', 'doDark'] # the desirable options
112 undesirable = ['doLinearize', 'doBrighterFatter'] # the undesirable options
114 passingConfig = ipIsr.IsrTask.ConfigClass()
115 for item in (mandatory + desirable):
116 setattr(passingConfig, item, True)
117 for item in (forbidden + undesirable):
118 setattr(passingConfig, item, False)
120 task = ipIsr.IsrTask(config=passingConfig)
122 with self.assertRaises(TypeError):
123 cpUtils.validateIsrConfig(None, mandatory, forbidden, desirable, undesirable)
124 cpUtils.validateIsrConfig(passingConfig, mandatory, forbidden, desirable, undesirable)
126 with self.assertRaises(RuntimeError): # mandatory/forbidden swapped
127 cpUtils.validateIsrConfig(task, forbidden, mandatory, desirable, undesirable)
129 with self.assertRaises(RuntimeError): # raise for missing mandatory
130 cpUtils.validateIsrConfig(task, mandatory + ['test'], forbidden, desirable, undesirable)
132 logName = 'testLogger'
133 with lsst.log.UsePythonLogging(): # otherwise none of this is caught
134 with self.assertLogs(logName, level='INFO'): # not found info-logs for (un)desirable
135 cpUtils.validateIsrConfig(task, mandatory, forbidden,
136 desirable + ['test'], undesirable, logName=logName)
137 cpUtils.validateIsrConfig(task, mandatory, forbidden,
138 desirable, undesirable + ['test'], logName=logName)
140 with self.assertLogs(logName, "WARN"): # not found warnings for forbidden
141 cpUtils.validateIsrConfig(task, mandatory, forbidden + ['test'],
142 desirable, undesirable, logName=logName)
145class TestMemory(lsst.utils.tests.MemoryTestCase):
146 pass
149def setup_module(module):
150 lsst.utils.tests.init()
153if __name__ == "__main__": 153 ↛ 154line 153 didn't jump to line 154, because the condition on line 153 was never true
154 lsst.utils.tests.init()
155 unittest.main()