Coverage for tests/test_diff_matched_tract_catalog.py: 19%

87 statements  

« prev     ^ index     » next       coverage.py v7.5.1, created at 2024-05-16 11:06 +0000

1# This file is part of pipe_tasks. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (https://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# This program is free software: you can redistribute it and/or modify 

10# it under the terms of the GNU General Public License as published by 

11# the Free Software Foundation, either version 3 of the License, or 

12# (at your option) any later version. 

13# 

14# This program is distributed in the hope that it will be useful, 

15# but WITHOUT ANY WARRANTY; without even the implied warranty of 

16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

17# GNU General Public License for more details. 

18# 

19# You should have received a copy of the GNU General Public License 

20# along with this program. If not, see <https://www.gnu.org/licenses/>. 

21 

22 

23import unittest 

24import lsst.utils.tests 

25 

26import lsst.afw.geom as afwGeom 

27from lsst.meas.astrom import ConvertCatalogCoordinatesConfig 

28from lsst.pipe.tasks.diff_matched_tract_catalog import ( 

29 DiffMatchedTractCatalogConfig, DiffMatchedTractCatalogTask, MatchedCatalogFluxesConfig, 

30) 

31 

32import numpy as np 

33import os 

34import pandas as pd 

35 

36 

37def _error_format(column): 

38 return f'{column}Err' 

39 

40 

41ROOT = os.path.dirname(__file__) 

42filename_diff_matched = os.path.join(ROOT, "data", "test_diff_matched.txt") 

43 

44 

45class DiffMatchedTractCatalogTaskTestCase(lsst.utils.tests.TestCase): 

46 """DiffMatchedTractCatalogTask test case.""" 

47 def setUp(self): 

48 ra_cen = 180. 

49 ra = ra_cen + np.array([-5.1, -2.2, 0., 3.1, -3.2, 2.01, -4.1])/60 

50 dec_cen = 0. 

51 dec = dec_cen + np.array([-4.15, 1.15, 0, 2.15, -7.15, -3.05, 5.7])/60 

52 mag_g = np.array([23., 24., 25., 25.5, 26., 24.7, 23.3]) 

53 mag_r = mag_g + [0.5, -0.2, -0.8, -0.5, -1.5, 0.8, -0.4] 

54 

55 coord_format = ConvertCatalogCoordinatesConfig 

56 zeropoint = coord_format.mag_zeropoint_ref.default 

57 fluxes = tuple(10**(-0.4*(mag - zeropoint)) for mag in (mag_g, mag_r)) 

58 # Percent error in measurement 

59 err_flux = np.array((0.02, 0.015, -0.035, 0.02, -0.04, 0.06, 0.01)) 

60 # Absolute error 

61 eps_coord = np.array((2.3, 0.6, -1.7, 3.6, -2.4, 55.0, -40.8)) 

62 err_coord = np.full_like(eps_coord, 0.02) 

63 eps_coord *= err_coord 

64 extended_ref = [True, False, True, False, True, False, True] 

65 extended_target = [False, False, True, True, True, False, True] 

66 flags = np.ones_like(eps_coord, dtype=bool) 

67 

68 bands = ['g', 'r'] 

69 

70 columns_flux = [f'flux_{band}' for band in bands] 

71 columns_flux_err = [_error_format(column) for column in columns_flux] 

72 

73 column_ra_ref = coord_format.column_ref_coord1.default 

74 column_dec_ref = coord_format.column_ref_coord2.default 

75 column_ra_target = coord_format.column_target_coord1.default 

76 column_dec_target = coord_format.column_target_coord2.default 

77 

78 column_ra_target_err, column_dec_target_err = [ 

79 _error_format(col) for col in (column_ra_target, column_dec_target) 

80 ] 

81 

82 n_points = len(ra) 

83 n_unmatched = 2 

84 n_matched = n_points - n_unmatched 

85 # Reorder some indices to make arbitrary differences 

86 idx_ref = np.empty(n_points, dtype=int) 

87 idx_ref[:n_matched] = np.arange(n_matched)[::-1] 

88 idx_ref[n_matched:] = np.arange(n_matched, n_points) 

89 data_ref = { 

90 column_ra_ref: ra[idx_ref], 

91 column_dec_ref: dec[idx_ref], 

92 columns_flux[0]: fluxes[0][idx_ref], 

93 columns_flux[1]: fluxes[1][idx_ref], 

94 DiffMatchedTractCatalogConfig.column_ref_extended.default: extended_ref, 

95 } 

96 self.catalog_ref = pd.DataFrame(data=data_ref) 

97 

98 data_target = { 

99 column_ra_target: ra + eps_coord, 

100 column_dec_target: dec + eps_coord, 

101 column_ra_target_err: err_coord, 

102 column_dec_target_err: err_coord, 

103 columns_flux[0]: fluxes[0]*(1 + err_flux), 

104 columns_flux[1]: fluxes[1]*(1 + err_flux), 

105 _error_format(columns_flux[0]): np.sqrt(fluxes[0]), 

106 _error_format(columns_flux[1]): np.sqrt(fluxes[1]), 

107 DiffMatchedTractCatalogConfig.columns_target_select_true.default[0]: flags, 

108 DiffMatchedTractCatalogConfig.columns_target_select_false.default[0]: ~flags, 

109 DiffMatchedTractCatalogConfig.column_target_extended.default: extended_target, 

110 } 

111 self.catalog_target = pd.DataFrame(data=data_target) 

112 

113 # Make the last two rows unmatched (we set eps_coord very large) 

114 match_row = np.arange(len(ra))[::-1] - n_unmatched 

115 self.catalog_match_ref = pd.DataFrame(data={ 

116 'match_candidate': flags, 

117 'match_row': match_row, 

118 }) 

119 

120 self.catalog_match_target = pd.DataFrame(data={ 

121 'match_candidate': flags, 

122 'match_row': match_row, 

123 }) 

124 

125 self.diff_matched = np.loadtxt(filename_diff_matched) 

126 

127 columns_flux_configs = { 

128 band: MatchedCatalogFluxesConfig( 

129 column_ref_flux=columns_flux[idx], 

130 columns_target_flux=[columns_flux[idx]], 

131 columns_target_flux_err=[columns_flux_err[idx]], 

132 ) 

133 for idx, band in enumerate(bands) 

134 } 

135 

136 self.task = DiffMatchedTractCatalogTask(config=DiffMatchedTractCatalogConfig( 

137 columns_target_coord_err=[column_ra_target_err, column_dec_target_err], 

138 columns_flux=columns_flux_configs, 

139 mag_num_bins=1, 

140 )) 

141 self.wcs = afwGeom.makeSkyWcs(crpix=lsst.geom.Point2D(9000, 9000), 

142 crval=lsst.geom.SpherePoint(ra_cen, dec_cen, lsst.geom.degrees), 

143 cdMatrix=afwGeom.makeCdMatrix(scale=0.2*lsst.geom.arcseconds)) 

144 

145 def tearDown(self): 

146 del self.catalog_ref 

147 del self.catalog_target 

148 del self.catalog_match_ref 

149 del self.catalog_match_target 

150 del self.diff_matched 

151 del self.task 

152 del self.wcs 

153 

154 def test_DiffMatchedTractCatalogTask(self): 

155 # These tables will have columns added to them in run 

156 columns_ref, columns_target = (list(x.columns) for x in (self.catalog_ref, self.catalog_target)) 

157 result = self.task.run( 

158 catalog_ref=self.catalog_ref, 

159 catalog_target=self.catalog_target, 

160 catalog_match_ref=self.catalog_match_ref, 

161 catalog_match_target=self.catalog_match_target, 

162 wcs=self.wcs, 

163 ) 

164 columns_result = list(result.cat_matched.columns) 

165 columns_expect = list(columns_target) + ["match_distance", "match_distanceErr"] 

166 prefix = DiffMatchedTractCatalogConfig.column_matched_prefix_ref.default 

167 columns_expect.append(f'{prefix}index') 

168 columns_expect.extend((f'{prefix}{col}' for col in columns_ref)) 

169 self.assertEqual(columns_expect, columns_result) 

170 

171 row = result.diff_matched.iloc[0].values.astype(float) 

172 # Run to re-save reference data. Will be loaded after this test completes. 

173 resave = False 

174 if resave: 

175 np.savetxt(filename_diff_matched, row) 

176 

177 self.assertEqual(len(row), len(self.diff_matched)) 

178 self.assertFloatsAlmostEqual(row, self.diff_matched, atol=1e-8, rtol=1e-8) 

179 

180 self.task.config.coord_format.coords_spherical = not self.task.config.coord_format.coords_spherical 

181 self.task.run( 

182 catalog_ref=self.catalog_ref, 

183 catalog_target=self.catalog_target, 

184 catalog_match_ref=self.catalog_match_ref, 

185 catalog_match_target=self.catalog_match_target, 

186 wcs=self.wcs, 

187 ) 

188 

189 

190class MemoryTester(lsst.utils.tests.MemoryTestCase): 

191 pass 

192 

193 

194def setup_module(module): 

195 lsst.utils.tests.init() 

196 

197 

198if __name__ == "__main__": 198 ↛ 199line 198 didn't jump to line 199, because the condition on line 198 was never true

199 lsst.utils.tests.init() 

200 unittest.main()