Coverage for tests / test_plotUtils.py: 23%
51 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-18 09:19 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-18 09:19 +0000
1#
2# Developed for the LSST Data Management System.
3# This product includes software developed by the LSST Project
4# (https://www.lsst.org).
5# See the COPYRIGHT file at the top-level directory of this distribution
6# for details of code ownership.
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 GNU General Public License
19# along with this program. If not, see <https://www.gnu.org/licenses/>.
21import unittest
23import numpy as np
25import lsst.utils.tests
26from lsst.analysis.tools.actions.keyedData.stellarLocusFit import _stellarLocusFit, perpDistance
27from lsst.analysis.tools.actions.plot.plotUtils import shorten_list
30class FitTest(lsst.utils.tests.TestCase):
31 """Test to see if the fitting and distance calculations are working."""
33 def testFitLine(self):
34 """Make a known array of points for x and y and then test that
35 the derived fit parameters are as expected."""
37 xs = np.arange(1, 10)
38 ys = np.arange(1, 10)
39 mags = np.arange(17.5, 22, 0.5)
41 # Define an initial fit box that encompasses the points.
42 testParams = {
43 "xMin": 0,
44 "xMax": 11,
45 "yMin": 0,
46 "yMax": 11,
47 "mFixed": 1,
48 "bFixed": 0,
49 "nSigmaToClip1": 3.5,
50 "nSigmaToClip2": 5.0,
51 "minObjectForFit": 3,
52 }
53 paramsOut = _stellarLocusFit(xs, ys, mags, testParams)
55 # _stellarLocusFit performs two iterations of fitting and also
56 # calculates the perpendicular gradient to the fit line and
57 # the points of intersection between the box and the fit
58 # line. Test that these are returning what is expected.
59 self.assertFloatsAlmostEqual(paramsOut["mODR"], 1.0)
60 self.assertFloatsAlmostEqual(paramsOut["bODR"], 0.0)
61 self.assertFloatsAlmostEqual(paramsOut["bPerpMin"], 0.0)
62 self.assertFloatsAlmostEqual(paramsOut["bPerpMax"], 22.0)
64 def testPerpDistance(self):
65 """Test the calculation of the perpendicular distance."""
67 p1 = np.array([1, 1])
68 p2 = np.array([2, 2])
69 testPoints = np.array([[1, 2], [1.5, 1.5], [2, 1]])
70 # perpDistance uses two points, p1 and p2, to define a line
71 # then calculates the perpendicular distance of the testPoints
72 # to this line
73 dists = perpDistance(p1, p2, testPoints)
74 self.assertFloatsAlmostEqual(np.array([1.0 / np.sqrt(2), 0.0, -1.0 / np.sqrt(2)]), np.array(dists))
77class ShortListTestCase(lsst.utils.tests.TestCase):
78 """Test to see if the shorten_list function works as it should."""
80 def test_shorten_list(self):
81 self.assertEqual(shorten_list([]), "") # empty container
82 self.assertEqual(shorten_list([5]), "5") # single element
83 self.assertEqual(shorten_list([5, 6]), "5-6") # 2 contigous elements
84 self.assertEqual(shorten_list([5, 7]), "5,7") # 2 non-contiguous elements
85 self.assertEqual(shorten_list([-7, -6, -5]), "-7--5") # 3 contiguous elements
86 self.assertEqual(shorten_list([5, 7, 9]), "5,7,9") # 3 non-contiguous elements
87 self.assertEqual(shorten_list([5, 6, 8]), "5-6,8") # 3 mixed elements
89 # Test for different data types
90 self.assertEqual(shorten_list({1, 2, 3, 5, 7, 8, 9, 10, 13}), "1-3,5,7-10,13") # test for a set
91 self.assertEqual(
92 shorten_list((1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18)), "1-3,5-13,15-18"
93 ) # test for a tuple
94 self.assertEqual(shorten_list(range(100)), "0-99") # test for an itertor
95 self.assertEqual(shorten_list(np.arange(100, dtype=int)), "0-99") # test for a numpy array
97 # Test the RC2/DC2 tract list explicitly.
98 self.assertEqual(shorten_list([9615, 9813, 9697]), "9615,9697,9813")
99 self.assertEqual(shorten_list([3828, 3829]), "3828-3829")
101 # Test the keyword-only arguments.
102 self.assertEqual(shorten_list([1, 2, 3, 4, 7, 8, 9], range_indicator=".."), "1..4,7..9")
103 self.assertEqual(shorten_list([1, 2, 3, 4, 7, 8, 9], range_separator="^"), "1-4^7-9")
104 self.assertEqual(
105 shorten_list([1, 2, 3, 4, 7, 8, 9], range_indicator=":", range_separator=";"), "1:4;7:9"
106 )
108 # Test that those are keyword only.
109 with self.assertRaises(TypeError):
110 shorten_list([1, 2, 3, 4, 7, 8, 9], "..", "^")
111 with self.assertRaises(TypeError):
112 shorten_list([1, 2, 3, 4, 7, 8, 9], "..", range_separator="^")
113 with self.assertRaises(TypeError):
114 shorten_list([1, 2, 3, 4, 7, 8, 9], "!", range_indicator="..")
116 # Test that it sorts the container.
117 self.assertEqual(shorten_list([6, 3, 1, 2]), "1-3,6")
119 # Repeated numbers are not expected. Test that the function can
120 # nevertheless handle it.
121 self.assertEqual(shorten_list([1, 2, 2, 3, 3, 3, 5, 7, 8, 7]), "1-3,5,7-8")
124if __name__ == "__main__": 124 ↛ 125line 124 didn't jump to line 125 because the condition on line 124 was never true
125 lsst.utils.tests.init()
126 unittest.main()