Coverage for tests/test_applyLookupTable.py : 24%

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#
2# LSST Data Management System
3# Copyright 2017 LSST Corporation.
4#
5# This product includes software developed by the
6# LSST Project (http://www.lsst.org/).
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the LSST License Statement and
19# the GNU General Public License along with this program. If not,
20# see <http://www.lsstcorp.org/LegalNotices/>.
21#
22import unittest
24import numpy as np
26import lsst.utils.tests
27import lsst.geom
28import lsst.afw.image as afwImage
29from lsst.afw.image.testUtils import makeRampImage
30from lsst.ip.isr import applyLookupTable
33def referenceApply(image, table, indOffset):
34 """!Reference implementation of applyLookupTable
36 The algorithm is as follows:
37 numOutOfRange = 0
38 For each i,j of the image:
39 lookupInd = int(indOffset + image[i,j])
40 if lookupInd not in range [0, table.size() - 1]:
41 set lookupInd to nearest edge and increment numOutOfRange
42 image[i,j] += table[lookupInd]
43 return numOutOfRange
45 @param[in,out] image image to which to add the values; modified in place
46 @param[in] table lookup table
47 @param[in] indOffset scalar added to image value before truncating to lookup column
49 @return the number of pixels whose values were out of range
50 """
51 imArr = image.getArray()
52 indArr = np.array(imArr + indOffset, dtype=int)
53 maxInd = len(table) - 1
54 numBadPoints = np.sum(indArr < 0)
55 numBadPoints += np.sum(indArr > maxInd)
56 indArr = np.where(indArr < 0, 0, indArr)
57 indArr = np.where(indArr >= maxInd, maxInd, indArr)
58 imArr += table[indArr]
59 return numBadPoints
62class ApplyLookupTableTestCase(lsst.utils.tests.TestCase):
64 def setUp(self):
65 np.random.seed(42)
67 def testBasics(self):
68 """!Test basic functionality of applyLookupTable
69 """
70 bbox = lsst.geom.Box2I(lsst.geom.Point2I(-31, 22), lsst.geom.Extent2I(100, 85))
71 imMin = -5
72 imMax = 2500
73 tableLen = 2000
74 tableSigma = 55
75 for indOffset in (0, -50, 234):
76 for imageClass in (afwImage.ImageF, afwImage.ImageD):
77 inImage = makeRampImage(bbox=bbox, start=imMin, stop=imMax, imageClass=imageClass)
78 table = np.random.normal(scale=tableSigma, size=tableLen)
79 table = np.array(table, dtype=inImage.getArray().dtype)
81 refImage = imageClass(inImage, True)
82 refNumBad = referenceApply(image=refImage, table=table, indOffset=indOffset)
84 measImage = imageClass(inImage, True)
85 measNumBad = applyLookupTable(measImage, table, indOffset)
87 self.assertEqual(refNumBad, measNumBad)
88 self.assertImagesAlmostEqual(refImage, measImage)
90 def testKnown(self):
91 """Test that a given image and lookup table produce the known answer
93 Apply a negative ramp table to a positive ramp image to get a flat image,
94 but have one value out of range at each end, to offset each end point by one
95 """
96 # generate a small ramp image with ascending integer values
97 # starting at some small negative value going positive
98 bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(3, 4))
99 numPix = bbox.getWidth()*bbox.getHeight()
100 start = -3
101 stop = start + numPix - 1
102 im = makeRampImage(bbox=bbox, start=start, stop=stop, imageClass=afwImage.ImageF)
103 # generate a ramp lookup table with descending integer values,
104 # with a range offset by a small arbitrary value from the image ramp
105 # make it two elements too short so we can have one value out of range at each end
106 numOutOfRangePerEnd = 1
107 numOutOfRange = 2*numOutOfRangePerEnd
108 tableOffset = -2
109 table = np.linspace(
110 start=stop + tableOffset,
111 stop=numOutOfRange + start + tableOffset,
112 num=numPix - numOutOfRange)
113 table = np.array(table, dtype=im.getArray().dtype)
114 # apply the table with the first and last image value out of range by one
115 indOffset = -(start + numOutOfRangePerEnd)
116 measNumOutOfRange = applyLookupTable(im, table, indOffset)
117 self.assertEqual(numOutOfRange, measNumOutOfRange)
118 # at this point the image should all have the same value
119 # except the first point will be one less and the last one more
120 imArr = im.getArray()
121 desVal = start + numOutOfRangePerEnd + table[0]
122 desImArr = np.zeros(numPix, dtype=im.getArray().dtype)
123 desImArr[:] = desVal
124 desImArr[0] -= 1
125 desImArr[-1] += 1
126 desImArr.shape = imArr.shape
127 self.assertFloatsAlmostEqual(desImArr, imArr)
130class MemoryTester(lsst.utils.tests.MemoryTestCase):
131 pass
134def setup_module(module):
135 lsst.utils.tests.init()
138if __name__ == "__main__": 138 ↛ 139line 138 didn't jump to line 139, because the condition on line 138 was never true
139 lsst.utils.tests.init()
140 unittest.main()