Coverage for tests / test_plotUtils.py: 23%

51 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-05-06 09:07 +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/>. 

20 

21import unittest 

22 

23import numpy as np 

24 

25import lsst.utils.tests 

26from lsst.analysis.tools.actions.keyedData.stellarLocusFit import _stellarLocusFit, perpDistance 

27from lsst.analysis.tools.actions.plot.plotUtils import shorten_list 

28 

29 

30class FitTest(lsst.utils.tests.TestCase): 

31 """Test to see if the fitting and distance calculations are working.""" 

32 

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.""" 

36 

37 xs = np.arange(1, 10) 

38 ys = np.arange(1, 10) 

39 mags = np.arange(17.5, 22, 0.5) 

40 

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) 

54 

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) 

63 

64 def testPerpDistance(self): 

65 """Test the calculation of the perpendicular distance.""" 

66 

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)) 

75 

76 

77class ShortListTestCase(lsst.utils.tests.TestCase): 

78 """Test to see if the shorten_list function works as it should.""" 

79 

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 

88 

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 

96 

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") 

100 

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 ) 

107 

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="..") 

115 

116 # Test that it sorts the container. 

117 self.assertEqual(shorten_list([6, 3, 1, 2]), "1-3,6") 

118 

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") 

122 

123 

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()