Coverage for tests/test_finalizeCharacterization.py: 26%

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

88 statements  

1# This file is part of pipe_tasks. 

2# 

3# LSST Data Management System 

4# This product includes software developed by the 

5# LSST Project (http://www.lsst.org/). 

6# See COPYRIGHT file at the top of the source tree. 

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 <https://www.lsstcorp.org/LegalNotices/>. 

21# 

22"""Test FinalizeCharacterizationTask. 

23""" 

24import unittest 

25import numpy as np 

26import pandas as pd 

27 

28import lsst.utils.tests 

29import lsst.daf.butler 

30import lsst.pipe.base as pipeBase 

31 

32from lsst.pipe.tasks.finalizeCharacterization import (FinalizeCharacterizationConfig, 

33 FinalizeCharacterizationTask) 

34 

35 

36class MockDataFrameReference(lsst.daf.butler.DeferredDatasetHandle): 

37 """Very simple object that looks like a Gen3 data reference to 

38 a dataframe. 

39 """ 

40 def __init__(self, df): 

41 self.df = df 

42 

43 def get(self, parameters={}, **kwargs): 

44 """Retrieve the specified dataset using the API of the Gen3 Butler. 

45 

46 Parameters 

47 ---------- 

48 parameters : `dict`, optional 

49 Parameter dictionary. Supported key is ``columns``. 

50 

51 Returns 

52 ------- 

53 dataframe : `pandas.DataFrame` 

54 dataframe, cut to the specified columns. 

55 """ 

56 if 'columns' in parameters: 

57 _columns = parameters['columns'] 

58 

59 return self.df[_columns] 

60 else: 

61 return self.df.copy() 

62 

63 

64class TestFinalizeCharacterizationTask(FinalizeCharacterizationTask): 

65 """A derived class which skips the initialization routines. 

66 """ 

67 def __init__(self, **kwargs): 

68 pipeBase.PipelineTask.__init__(self, **kwargs) 

69 

70 self.makeSubtask('reserve_selection') 

71 

72 

73class FinalizeCharacterizationTestCase(lsst.utils.tests.TestCase): 

74 """Tests of some functionality of FinalizeCharacterizationTask. 

75 

76 Full testing comes from integration tests such as ci_hsc and ci_imsim. 

77 

78 These tests bypass the middleware used for accessing data and 

79 managing Task execution. 

80 """ 

81 def setUp(self): 

82 config = FinalizeCharacterizationConfig() 

83 

84 self.finalizeCharacterizationTask = TestFinalizeCharacterizationTask( 

85 config=config, 

86 ) 

87 

88 self.isolated_star_cat_dict, self.isolated_star_source_dict = self._make_isocats() 

89 

90 def _make_isocats(self): 

91 """Make test isolated star catalogs. 

92 

93 Returns 

94 ------- 

95 isolated_star_cat_dict : `dict` 

96 Per-"tract" dict of isolated star catalogs. 

97 isolate_star_source_dict : `dict` 

98 Per-"tract" dict of isolated source catalogs. 

99 """ 

100 dtype_cat = [('isolated_star_id', 'i8'), 

101 ('ra', 'f8'), 

102 ('decl', 'f8'), 

103 ('primary_band', 'U2'), 

104 ('source_cat_index', 'i4'), 

105 ('nsource', 'i4'), 

106 ('source_cat_index_i', 'i4'), 

107 ('nsource_i', 'i4'), 

108 ('source_cat_index_r', 'i4'), 

109 ('nsource_r', 'i4')] 

110 

111 dtype_source = [('sourceId', 'i8'), 

112 ('obj_index', 'i4')] 

113 

114 isolated_star_cat_dict = {} 

115 isolated_star_source_dict = {} 

116 

117 np.random.seed(12345) 

118 

119 # There are 90 stars in both r, i. 10 individually in each. 

120 nstar = 110 

121 nsource_per_band_per_star = 2 

122 self.nstar_total = nstar 

123 self.nstar_per_band = nstar - 10 

124 

125 # This is a brute-force assembly of a star catalog and matched sources. 

126 for tract in [0, 1]: 

127 ra = np.random.uniform(low=tract, high=tract + 1.0, size=nstar) 

128 dec = np.random.uniform(low=0.0, high=1.0, size=nstar) 

129 

130 cat = np.zeros(nstar, dtype=dtype_cat) 

131 cat['isolated_star_id'] = tract*nstar + np.arange(nstar) 

132 cat['ra'] = ra 

133 cat['decl'] = dec 

134 cat['primary_band'][0: 100] = 'i' 

135 cat['primary_band'][100:] = 'r' 

136 

137 source_cats = [] 

138 counter = 0 

139 for i in range(cat.size): 

140 cat['source_cat_index'][i] = counter 

141 if i < 90: 

142 cat['nsource'][i] = 2*nsource_per_band_per_star 

143 bands = ['r', 'i'] 

144 else: 

145 cat['nsource'][i] = nsource_per_band_per_star 

146 if i < 100: 

147 bands = ['i'] 

148 else: 

149 bands = ['r'] 

150 

151 for band in bands: 

152 cat[f'source_cat_index_{band}'][i] = counter 

153 cat[f'nsource_{band}'][i] = nsource_per_band_per_star 

154 source_cat = np.zeros(nsource_per_band_per_star, dtype=dtype_source) 

155 source_cat['sourceId'] = np.arange( 

156 tract*nstar + counter, 

157 tract*nstar + counter + nsource_per_band_per_star 

158 ) 

159 source_cat['obj_index'] = i 

160 

161 source_cats.append(source_cat) 

162 

163 counter += nsource_per_band_per_star 

164 

165 source_cat = np.concatenate(source_cats) 

166 

167 isolated_star_cat_dict[tract] = MockDataFrameReference(pd.DataFrame(cat)) 

168 isolated_star_source_dict[tract] = MockDataFrameReference(pd.DataFrame(source_cat)) 

169 

170 return isolated_star_cat_dict, isolated_star_source_dict 

171 

172 def test_concat_isolated_star_cats(self): 

173 """Test concatenation and reservation of the isolated star catalogs. 

174 """ 

175 

176 for band in ['r', 'i']: 

177 iso, iso_src = self.finalizeCharacterizationTask.concat_isolated_star_cats( 

178 band, 

179 self.isolated_star_cat_dict, 

180 self.isolated_star_source_dict 

181 ) 

182 

183 # There are two tracts, so double everything. 

184 self.assertEqual(len(iso), 2*self.nstar_per_band) 

185 

186 reserve_fraction = self.finalizeCharacterizationTask.config.reserve_selection.reserve_fraction 

187 self.assertEqual(np.sum(iso['reserved']), 

188 int(reserve_fraction*len(iso))) 

189 

190 # 2 tracts, 4 observations per tract per star, minus 2*10 not in the given band. 

191 self.assertEqual(len(iso_src), 2*(4*len(iso)//2 - 20)) 

192 

193 # Check that every star is properly matched to the sources. 

194 for i in range(len(iso)): 

195 np.testing.assert_array_equal( 

196 iso_src['obj_index'][iso[f'source_cat_index_{band}'][i]: 

197 iso[f'source_cat_index_{band}'][i] + iso[f'nsource_{band}'][i]], 

198 i 

199 ) 

200 

201 # Check that every reserved star is marked as a reserved source. 

202 res_star, = np.where(iso['reserved']) 

203 for i in res_star: 

204 np.testing.assert_array_equal( 

205 iso_src['reserved'][iso[f'source_cat_index_{band}'][i]: 

206 iso[f'source_cat_index_{band}'][i] + iso[f'nsource_{band}'][i]], 

207 True 

208 ) 

209 

210 # Check that every reserved source is marked as a reserved star. 

211 res_src, = np.where(iso_src['reserved']) 

212 np.testing.assert_array_equal( 

213 iso['reserved'][iso_src['obj_index'][res_src]], 

214 True 

215 ) 

216 

217 

218class MyMemoryTestCase(lsst.utils.tests.MemoryTestCase): 

219 pass 

220 

221 

222def setup_module(module): 

223 lsst.utils.tests.init() 

224 

225 

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

227 lsst.utils.tests.init() 

228 unittest.main()