Hide keyboard shortcuts

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# 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# (http://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 <http://www.gnu.org/licenses/>. 

21 

22import astropy.units as u 

23import copy 

24import functools 

25import numpy as np 

26import os 

27import pandas as pd 

28import unittest 

29 

30import lsst.daf.base as dafBase 

31import lsst.afw.geom as afwGeom 

32import lsst.geom as geom 

33import lsst.meas.base as measBase 

34import lsst.utils.tests 

35from lsst.pipe.tasks.parquetTable import MultilevelParquetTable 

36from lsst.pipe.tasks.functors import (CompositeFunctor, CustomFunctor, Column, RAColumn, 

37 DecColumn, Mag, MagDiff, Color, StarGalaxyLabeller, 

38 DeconvolvedMoments, SdssTraceSize, PsfSdssTraceSizeDiff, 

39 HsmTraceSize, PsfHsmTraceSizeDiff, HsmFwhm, 

40 LocalPhotometry, LocalNanojansky, LocalNanojanskyErr, 

41 LocalMagnitude, LocalMagnitudeErr, 

42 LocalWcs, ComputePixelScale, ConvertPixelToArcseconds) 

43 

44ROOT = os.path.abspath(os.path.dirname(__file__)) 

45 

46 

47class FunctorTestCase(unittest.TestCase): 

48 

49 def simulateMultiParquet(self, dataDict): 

50 """Create a simple test MultilevelParquetTable 

51 """ 

52 simpleDF = pd.DataFrame(dataDict) 

53 dfFilterDSCombos = [] 

54 for ds in self.datasets: 

55 for filterName in self.filters: 

56 df = copy.copy(simpleDF) 

57 df.reindex(sorted(df.columns), axis=1) 

58 df['dataset'] = ds 

59 df['filter'] = filterName 

60 df.columns = pd.MultiIndex.from_tuples( 

61 [(ds, filterName, c) for c in df.columns], 

62 names=('dataset', 'filter', 'column')) 

63 dfFilterDSCombos.append(df) 

64 

65 df = functools.reduce(lambda d1, d2: d1.join(d2), dfFilterDSCombos) 

66 

67 return MultilevelParquetTable(dataFrame=df) 

68 

69 def setUp(self): 

70 np.random.seed(1234) 

71 self.datasets = ['forced_src', 'meas', 'ref'] 

72 self.filters = ['HSC-G', 'HSC-R'] 

73 self.columns = ['coord_ra', 'coord_dec'] 

74 self.nRecords = 5 

75 self.dataDict = { 

76 "coord_ra": [3.77654137, 3.77643059, 3.77621148, 3.77611944, 3.77610396], 

77 "coord_dec": [0.01127624, 0.01127787, 0.01127543, 0.01127543, 0.01127543]} 

78 

79 def _funcVal(self, functor, parq): 

80 self.assertIsInstance(functor.name, str) 

81 self.assertIsInstance(functor.shortname, str) 

82 

83 val = functor(parq) 

84 self.assertIsInstance(val, pd.Series) 

85 

86 val = functor(parq, dropna=True) 

87 self.assertEqual(val.isnull().sum(), 0) 

88 

89 return val 

90 

91 def _differenceVal(self, functor, parq1, parq2): 

92 self.assertIsInstance(functor.name, str) 

93 self.assertIsInstance(functor.shortname, str) 

94 

95 val = functor.difference(parq1, parq2) 

96 self.assertIsInstance(val, pd.Series) 

97 

98 val = functor.difference(parq1, parq2, dropna=True) 

99 self.assertEqual(val.isnull().sum(), 0) 

100 

101 val1 = self._funcVal(functor, parq1) 

102 val2 = self._funcVal(functor, parq2) 

103 

104 self.assertTrue(np.allclose(val, val1 - val2)) 

105 

106 return val 

107 

108 def testColumn(self): 

109 self.columns.append("base_FootprintArea_value") 

110 self.dataDict["base_FootprintArea_value"] = \ 

111 np.full(self.nRecords, 1) 

112 parq = self.simulateMultiParquet(self.dataDict) 

113 func = Column('base_FootprintArea_value', filt='HSC-G') 

114 self._funcVal(func, parq) 

115 

116 def testCustom(self): 

117 self.columns.append("base_FootprintArea_value") 

118 self.dataDict["base_FootprintArea_value"] = \ 

119 np.random.rand(self.nRecords) 

120 parq = self.simulateMultiParquet(self.dataDict) 

121 func = CustomFunctor('2*base_FootprintArea_value', filt='HSC-G') 

122 val = self._funcVal(func, parq) 

123 

124 func2 = Column('base_FootprintArea_value', filt='HSC-G') 

125 

126 np.allclose(val.values, 2*func2(parq).values, atol=1e-13, rtol=0) 

127 

128 def testCoords(self): 

129 parq = self.simulateMultiParquet(self.dataDict) 

130 ra = self._funcVal(RAColumn(), parq) 

131 dec = self._funcVal(DecColumn(), parq) 

132 

133 columnDict = {'dataset': 'ref', 'filter': 'HSC-G', 

134 'column': ['coord_ra', 'coord_dec']} 

135 coords = parq.toDataFrame(columns=columnDict, droplevels=True) / np.pi * 180. 

136 

137 self.assertTrue(np.allclose(ra, coords[('ref', 'HSC-G', 'coord_ra')], atol=1e-13, rtol=0)) 

138 self.assertTrue(np.allclose(dec, coords[('ref', 'HSC-G', 'coord_dec')], atol=1e-13, rtol=0)) 

139 

140 def testMag(self): 

141 self.columns.extend(["base_PsfFlux_instFlux", "base_PsfFlux_instFluxErr"]) 

142 self.dataDict["base_PsfFlux_instFlux"] = np.full(self.nRecords, 1000) 

143 self.dataDict["base_PsfFlux_instFluxErr"] = np.full(self.nRecords, 10) 

144 parq = self.simulateMultiParquet(self.dataDict) 

145 # Change one dataset filter combinations value. 

146 parq._df[("meas", "HSC-G", "base_PsfFlux_instFlux")] -= 1 

147 

148 fluxName = 'base_PsfFlux' 

149 

150 # Check that things work when you provide dataset explicitly 

151 for dataset in ['forced_src', 'meas']: 

152 psfMag_G = self._funcVal(Mag(fluxName, dataset=dataset, 

153 filt='HSC-G'), 

154 parq) 

155 psfMag_R = self._funcVal(Mag(fluxName, dataset=dataset, 

156 filt='HSC-R'), 

157 parq) 

158 

159 psfColor_GR = self._funcVal(Color(fluxName, 'HSC-G', 'HSC-R', 

160 dataset=dataset), 

161 parq) 

162 

163 self.assertTrue(np.allclose((psfMag_G - psfMag_R).dropna(), psfColor_GR, rtol=0, atol=1e-13)) 

164 

165 # Check that behavior as expected when dataset not provided; 

166 # that is, that the color comes from forced and default Mag is meas 

167 psfMag_G = self._funcVal(Mag(fluxName, filt='HSC-G'), parq) 

168 psfMag_R = self._funcVal(Mag(fluxName, filt='HSC-R'), parq) 

169 

170 psfColor_GR = self._funcVal(Color(fluxName, 'HSC-G', 'HSC-R'), parq) 

171 

172 # These should *not* be equal. 

173 self.assertFalse(np.allclose((psfMag_G - psfMag_R).dropna(), psfColor_GR)) 

174 

175 def testMagDiff(self): 

176 self.columns.extend(["base_PsfFlux_instFlux", "base_PsfFlux_instFluxErr", 

177 "modelfit_CModel_instFlux", "modelfit_CModel_instFluxErr"]) 

178 self.dataDict["base_PsfFlux_instFlux"] = np.full(self.nRecords, 1000) 

179 self.dataDict["base_PsfFlux_instFluxErr"] = np.full(self.nRecords, 10) 

180 self.dataDict["modelfit_CModel_instFlux"] = np.full(self.nRecords, 1000) 

181 self.dataDict["modelfit_CModel_instFluxErr"] = np.full(self.nRecords, 10) 

182 parq = self.simulateMultiParquet(self.dataDict) 

183 

184 for filt in self.filters: 

185 filt = 'HSC-G' 

186 val = self._funcVal(MagDiff('base_PsfFlux', 'modelfit_CModel', filt=filt), parq) 

187 

188 mag1 = self._funcVal(Mag('modelfit_CModel', filt=filt), parq) 

189 mag2 = self._funcVal(Mag('base_PsfFlux', filt=filt), parq) 

190 self.assertTrue(np.allclose((mag2 - mag1).dropna(), val, rtol=0, atol=1e-13)) 

191 

192 def testDifference(self): 

193 """Test .difference method using MagDiff as the example. 

194 """ 

195 self.columns.extend(["base_PsfFlux_instFlux", "base_PsfFlux_instFluxErr", 

196 "modelfit_CModel_instFlux", "modelfit_CModel_instFluxErr"]) 

197 

198 self.dataDict["base_PsfFlux_instFlux"] = np.full(self.nRecords, 1000) 

199 self.dataDict["modelfit_CModel_instFlux"] = np.full(self.nRecords, 1000) 

200 parq1 = self.simulateMultiParquet(self.dataDict) 

201 

202 self.dataDict["base_PsfFlux_instFlux"] = np.full(self.nRecords, 999) 

203 self.dataDict["modelfit_CModel_instFlux"] = np.full(self.nRecords, 999) 

204 parq2 = self.simulateMultiParquet(self.dataDict) 

205 

206 magDiff = MagDiff('base_PsfFlux', 'modelfit_CModel', filt='HSC-G') 

207 

208 # Asserts that differences computed properly 

209 self._differenceVal(magDiff, parq1, parq2) 

210 

211 def testLabeller(self): 

212 # Covering the code is better than nothing 

213 self.columns.append("base_ClassificationExtendedness_value") 

214 self.dataDict["base_ClassificationExtendedness_value"] = np.full(self.nRecords, 1) 

215 parq = self.simulateMultiParquet(self.dataDict) 

216 labels = self._funcVal(StarGalaxyLabeller(), parq) # noqa 

217 

218 def testPixelScale(self): 

219 # Test that the pixel scale and pix->arcsec calculations perform as 

220 # expected. 

221 pass 

222 

223 def testOther(self): 

224 self.columns.extend(["ext_shapeHSM_HsmSourceMoments_xx", "ext_shapeHSM_HsmSourceMoments_yy", 

225 "base_SdssShape_xx", "base_SdssShape_yy", 

226 "ext_shapeHSM_HsmPsfMoments_xx", "ext_shapeHSM_HsmPsfMoments_yy", 

227 "base_SdssShape_psf_xx", "base_SdssShape_psf_yy"]) 

228 self.dataDict["ext_shapeHSM_HsmSourceMoments_xx"] = np.full(self.nRecords, 1 / np.sqrt(2)) 

229 self.dataDict["ext_shapeHSM_HsmSourceMoments_yy"] = np.full(self.nRecords, 1 / np.sqrt(2)) 

230 self.dataDict["base_SdssShape_xx"] = np.full(self.nRecords, 1 / np.sqrt(2)) 

231 self.dataDict["base_SdssShape_yy"] = np.full(self.nRecords, 1 / np.sqrt(2)) 

232 self.dataDict["ext_shapeHSM_HsmPsfMoments_xx"] = np.full(self.nRecords, 1 / np.sqrt(2)) 

233 self.dataDict["ext_shapeHSM_HsmPsfMoments_yy"] = np.full(self.nRecords, 1 / np.sqrt(2)) 

234 self.dataDict["base_SdssShape_psf_xx"] = np.full(self.nRecords, 1) 

235 self.dataDict["base_SdssShape_psf_yy"] = np.full(self.nRecords, 1) 

236 parq = self.simulateMultiParquet(self.dataDict) 

237 # Covering the code is better than nothing 

238 for filt in self.filters: 

239 for Func in [DeconvolvedMoments, 

240 SdssTraceSize, 

241 PsfSdssTraceSizeDiff, 

242 HsmTraceSize, PsfHsmTraceSizeDiff, HsmFwhm]: 

243 val = self._funcVal(Func(filt=filt), parq) # noqa 

244 

245 def _compositeFuncVal(self, functor, parq): 

246 self.assertIsInstance(functor, CompositeFunctor) 

247 

248 df = functor(parq) 

249 

250 self.assertIsInstance(df, pd.DataFrame) 

251 self.assertTrue(np.all([k in df.columns for k in functor.funcDict.keys()])) 

252 

253 df = functor(parq, dropna=True) 

254 

255 # Check that there are no nulls 

256 self.assertFalse(df.isnull().any(axis=None)) 

257 

258 return df 

259 

260 def _compositeDifferenceVal(self, functor, parq1, parq2): 

261 self.assertIsInstance(functor, CompositeFunctor) 

262 

263 df = functor.difference(parq1, parq2) 

264 

265 self.assertIsInstance(df, pd.DataFrame) 

266 self.assertTrue(np.all([k in df.columns for k in functor.funcDict.keys()])) 

267 

268 df = functor.difference(parq1, parq2, dropna=True) 

269 

270 # Check that there are no nulls 

271 self.assertFalse(df.isnull().any(axis=None)) 

272 

273 df1 = functor(parq1) 

274 df2 = functor(parq2) 

275 

276 self.assertTrue(np.allclose(df.values, df1.values - df2.values)) 

277 

278 return df 

279 

280 def testComposite(self): 

281 self.columns.extend(["modelfit_CModel_instFlux", "base_PsfFlux_instFlux"]) 

282 self.dataDict["modelfit_CModel_instFlux"] = np.full(self.nRecords, 1) 

283 self.dataDict["base_PsfFlux_instFlux"] = np.full(self.nRecords, 1) 

284 parq = self.simulateMultiParquet(self.dataDict) 

285 # Modify r band value slightly. 

286 parq._df[("meas", "HSC-R", "base_PsfFlux_instFlux")] -= 0.1 

287 

288 filt = 'HSC-G' 

289 funcDict = {'psfMag_ref': Mag('base_PsfFlux', dataset='ref'), 

290 'ra': RAColumn(), 

291 'dec': DecColumn(), 

292 'psfMag': Mag('base_PsfFlux', filt=filt), 

293 'cmodel_magDiff': MagDiff('base_PsfFlux', 

294 'modelfit_CModel', filt=filt)} 

295 func = CompositeFunctor(funcDict) 

296 df = self._compositeFuncVal(func, parq) 

297 

298 # Repeat same, but define filter globally instead of individually 

299 funcDict2 = {'psfMag_ref': Mag('base_PsfFlux', dataset='ref'), 

300 'ra': RAColumn(), 

301 'dec': DecColumn(), 

302 'psfMag': Mag('base_PsfFlux'), 

303 'cmodel_magDiff': MagDiff('base_PsfFlux', 

304 'modelfit_CModel')} 

305 

306 func2 = CompositeFunctor(funcDict2, filt=filt) 

307 df2 = self._compositeFuncVal(func2, parq) 

308 self.assertTrue(df.equals(df2)) 

309 

310 func2.filt = 'HSC-R' 

311 df3 = self._compositeFuncVal(func2, parq) 

312 # Because we modified the R filter this should fail. 

313 self.assertFalse(df2.equals(df3)) 

314 

315 # Make sure things work with passing list instead of dict 

316 funcs = [Mag('base_PsfFlux', dataset='ref'), 

317 RAColumn(), 

318 DecColumn(), 

319 Mag('base_PsfFlux', filt=filt), 

320 MagDiff('base_PsfFlux', 'modelfit_CModel', filt=filt)] 

321 

322 df = self._compositeFuncVal(CompositeFunctor(funcs), parq) 

323 

324 def testCompositeColor(self): 

325 self.dataDict["base_PsfFlux_instFlux"] = np.full(self.nRecords, 1000) 

326 self.dataDict["base_PsfFlux_instFluxErr"] = np.full(self.nRecords, 10) 

327 parq = self.simulateMultiParquet(self.dataDict) 

328 funcDict = {'a': Mag('base_PsfFlux', dataset='meas', filt='HSC-G'), 

329 'b': Mag('base_PsfFlux', dataset='forced_src', filt='HSC-G'), 

330 'c': Color('base_PsfFlux', 'HSC-G', 'HSC-R')} 

331 # Covering the code is better than nothing 

332 df = self._compositeFuncVal(CompositeFunctor(funcDict), parq) # noqa 

333 

334 def testCompositeDifference(self): 

335 self.dataDict["base_PsfFlux_instFlux"] = np.full(self.nRecords, 1000) 

336 self.dataDict["base_PsfFlux_instFluxErr"] = np.full(self.nRecords, 10) 

337 parq1 = self.simulateMultiParquet(self.dataDict) 

338 

339 self.dataDict["base_PsfFlux_instFlux"] = np.full(self.nRecords, 999) 

340 self.dataDict["base_PsfFlux_instFluxErr"] = np.full(self.nRecords, 9) 

341 parq2 = self.simulateMultiParquet(self.dataDict) 

342 

343 funcDict = {'a': Mag('base_PsfFlux', dataset='meas', filt='HSC-G'), 

344 'b': Mag('base_PsfFlux', dataset='forced_src', filt='HSC-G'), 

345 'c': Color('base_PsfFlux', 'HSC-G', 'HSC-R')} 

346 # Covering the code is better than nothing 

347 df = self._compositeDifferenceVal(CompositeFunctor(funcDict), parq1, parq2) # noqa 

348 

349 def testLocalPhotometry(self): 

350 """Test the local photometry functors. 

351 """ 

352 flux = 1000 

353 fluxErr = 10 

354 calib = 10 

355 calibErr = 1 

356 self.dataDict["base_PsfFlux_instFlux"] = np.full(self.nRecords, flux) 

357 self.dataDict["base_PsfFlux_instFluxErr"] = np.full(self.nRecords, 

358 fluxErr) 

359 self.dataDict["base_LocalPhotoCalib"] = np.full(self.nRecords, calib) 

360 self.dataDict["base_LocalPhotoCalibErr"] = np.full(self.nRecords, 

361 calibErr) 

362 parq = self.simulateMultiParquet(self.dataDict) 

363 func = LocalPhotometry("base_PsfFlux_instFlux", 

364 "base_PsfFlux_instFluxErr", 

365 "base_LocalPhotoCalib", 

366 "base_LocalPhotoCalibErr") 

367 df = parq.toDataFrame(columns={"dataset": "meas", 

368 "filter": "HSC-G", 

369 "columns": ["base_PsfFlux_instFlux", 

370 "base_PsfFlux_instFluxErr", 

371 "base_LocalPhotoCalib", 

372 "base_LocalPhotoCalibErr"]}) 

373 nanoJansky = func.instFluxToNanojansky( 

374 df[("meas", "HSC-G", "base_PsfFlux_instFlux")], 

375 df[("meas", "HSC-G", "base_LocalPhotoCalib")]) 

376 mag = func.instFluxToMagnitude( 

377 df[("meas", "HSC-G", "base_PsfFlux_instFlux")], 

378 df[("meas", "HSC-G", "base_LocalPhotoCalib")]) 

379 nanoJanskyErr = func.instFluxErrToNanojanskyErr( 

380 df[("meas", "HSC-G", "base_PsfFlux_instFlux")], 

381 df[("meas", "HSC-G", "base_PsfFlux_instFluxErr")], 

382 df[("meas", "HSC-G", "base_LocalPhotoCalib")], 

383 df[("meas", "HSC-G", "base_LocalPhotoCalibErr")]) 

384 magErr = func.instFluxErrToMagnitudeErr( 

385 df[("meas", "HSC-G", "base_PsfFlux_instFlux")], 

386 df[("meas", "HSC-G", "base_PsfFlux_instFluxErr")], 

387 df[("meas", "HSC-G", "base_LocalPhotoCalib")], 

388 df[("meas", "HSC-G", "base_LocalPhotoCalibErr")]) 

389 

390 self.assertTrue(np.allclose(nanoJansky.values, 

391 flux * calib, 

392 atol=1e-13, 

393 rtol=0)) 

394 self.assertTrue(np.allclose(mag.values, 

395 (flux * calib * u.nJy).to_value(u.ABmag), 

396 atol=1e-13, 

397 rtol=0)) 

398 self.assertTrue(np.allclose(nanoJanskyErr.values, 

399 np.hypot(fluxErr * calib, flux * calibErr), 

400 atol=1e-13, 

401 rtol=0)) 

402 self.assertTrue(np.allclose( 

403 magErr.values, 

404 2.5 / np.log(10) * nanoJanskyErr.values / nanoJansky.values, 

405 atol=1e-13, 

406 rtol=0)) 

407 

408 # Test functors against the values computed above. 

409 self._testLocalPhotometryFunctors(LocalNanojansky, 

410 parq, 

411 nanoJansky) 

412 self._testLocalPhotometryFunctors(LocalNanojanskyErr, 

413 parq, 

414 nanoJanskyErr) 

415 self._testLocalPhotometryFunctors(LocalMagnitude, 

416 parq, 

417 mag) 

418 self._testLocalPhotometryFunctors(LocalMagnitudeErr, 

419 parq, 

420 magErr) 

421 

422 def _testLocalPhotometryFunctors(self, functor, parq, testValues): 

423 func = functor("base_PsfFlux_instFlux", 

424 "base_PsfFlux_instFluxErr", 

425 "base_LocalPhotoCalib", 

426 "base_LocalPhotoCalibErr") 

427 val = self._funcVal(func, parq) 

428 self.assertTrue(np.allclose(testValues.values, 

429 val.values, 

430 atol=1e-13, 

431 rtol=0)) 

432 

433 def testConvertPixelToArcseconds(self): 

434 """Test calculations of the pixel scale and conversions of pixel to 

435 arcseconds. 

436 """ 

437 dipoleSep = 10 

438 np.random.seed(1234) 

439 testPixelDeltas = np.random.uniform(-100, 100, size=(self.nRecords, 2)) 

440 import lsst.afw.table as afwTable 

441 localWcsPlugin = measBase.EvaluateLocalWcsPlugin( 

442 None, 

443 "base_LocalWcs", 

444 afwTable.SourceTable.makeMinimalSchema(), 

445 None) 

446 for dec in np.linspace(-90, 90, 10): 

447 for x, y in zip(np.random.uniform(2 * 1109.99981456774, size=10), 

448 np.random.uniform(2 * 560.018167811613, size=10)): 

449 

450 center = geom.Point2D(x, y) 

451 wcs = self._makeWcs(dec) 

452 skyOrigin = wcs.pixelToSky(center) 

453 

454 linAffMatrix = localWcsPlugin.makeLocalTransformMatrix(wcs, 

455 center) 

456 self.dataDict["dipoleSep"] = np.full(self.nRecords, dipoleSep) 

457 self.dataDict["slot_Centroid_x"] = np.full(self.nRecords, x) 

458 self.dataDict["slot_Centroid_y"] = np.full(self.nRecords, y) 

459 self.dataDict["someCentroid_x"] = x + testPixelDeltas[:, 0] 

460 self.dataDict["someCentroid_y"] = y + testPixelDeltas[:, 1] 

461 self.dataDict["base_LocalWcs_CDMatrix_1_1"] = np.full(self.nRecords, 

462 linAffMatrix[0, 0]) 

463 self.dataDict["base_LocalWcs_CDMatrix_1_2"] = np.full(self.nRecords, 

464 linAffMatrix[0, 1]) 

465 self.dataDict["base_LocalWcs_CDMatrix_2_1"] = np.full(self.nRecords, 

466 linAffMatrix[1, 0]) 

467 self.dataDict["base_LocalWcs_CDMatrix_2_2"] = np.full(self.nRecords, 

468 linAffMatrix[1, 1]) 

469 parq = self.simulateMultiParquet(self.dataDict) 

470 func = LocalWcs("base_LocalWcs_CDMatrix_1_1", 

471 "base_LocalWcs_CDMatrix_1_2", 

472 "base_LocalWcs_CDMatrix_2_1", 

473 "base_LocalWcs_CDMatrix_2_2") 

474 df = parq.toDataFrame(columns={"dataset": "meas", 

475 "filter": "HSC-G", 

476 "columns": ["dipoleSep", 

477 "slot_Centroid_x", 

478 "slot_Centroid_y", 

479 "someCentroid_x", 

480 "someCentroid_y", 

481 "base_LocalWcs_CDMatrix_1_1", 

482 "base_LocalWcs_CDMatrix_1_2", 

483 "base_LocalWcs_CDMatrix_2_1", 

484 "base_LocalWcs_CDMatrix_2_2"]}) 

485 

486 # Exercise the full set of functions in LocalWcs. 

487 sepRadians = func.getSkySeperationFromPixel( 

488 df[("meas", "HSC-G", "someCentroid_x")] - df[("meas", "HSC-G", "slot_Centroid_x")], 

489 df[("meas", "HSC-G", "someCentroid_y")] - df[("meas", "HSC-G", "slot_Centroid_y")], 

490 0.0, 

491 0.0, 

492 df[("meas", "HSC-G", "base_LocalWcs_CDMatrix_1_1")], 

493 df[("meas", "HSC-G", "base_LocalWcs_CDMatrix_1_2")], 

494 df[("meas", "HSC-G", "base_LocalWcs_CDMatrix_2_1")], 

495 df[("meas", "HSC-G", "base_LocalWcs_CDMatrix_2_2")]) 

496 

497 # Test functor values against afw SkyWcs computations. 

498 for centX, centY, sep in zip(testPixelDeltas[:, 0], 

499 testPixelDeltas[:, 1], 

500 sepRadians.values): 

501 afwSepRadians = skyOrigin.separation( 

502 wcs.pixelToSky(x + centX, y + centY)).asRadians() 

503 self.assertAlmostEqual(1 - sep / afwSepRadians, 0, places=6) 

504 

505 # Test the pixel scale computation. 

506 func = ComputePixelScale("base_LocalWcs_CDMatrix_1_1", 

507 "base_LocalWcs_CDMatrix_1_2", 

508 "base_LocalWcs_CDMatrix_2_1", 

509 "base_LocalWcs_CDMatrix_2_2") 

510 pixelScale = self._funcVal(func, parq) 

511 self.assertTrue(np.allclose( 

512 wcs.getPixelScale(center).asArcseconds(), 

513 pixelScale.values, 

514 rtol=1e-8, 

515 atol=0)) 

516 

517 func = ConvertPixelToArcseconds("dipoleSep", 

518 "base_LocalWcs_CDMatrix_1_1", 

519 "base_LocalWcs_CDMatrix_1_2", 

520 "base_LocalWcs_CDMatrix_2_1", 

521 "base_LocalWcs_CDMatrix_2_2") 

522 val = self._funcVal(func, parq) 

523 self.assertTrue(np.allclose(pixelScale.values * dipoleSep, 

524 val.values, 

525 atol=1e-16, 

526 rtol=1e-16)) 

527 

528 def _makeWcs(self, dec=53.1595451514076): 

529 """Create a wcs from real CFHT values. 

530 

531 Returns 

532 ------- 

533 wcs : `lsst.afw.geom` 

534 Created wcs. 

535 """ 

536 metadata = dafBase.PropertySet() 

537 

538 metadata.set("SIMPLE", "T") 

539 metadata.set("BITPIX", -32) 

540 metadata.set("NAXIS", 2) 

541 metadata.set("NAXIS1", 1024) 

542 metadata.set("NAXIS2", 1153) 

543 metadata.set("RADECSYS", 'FK5') 

544 metadata.set("EQUINOX", 2000.) 

545 

546 metadata.setDouble("CRVAL1", 215.604025685476) 

547 metadata.setDouble("CRVAL2", dec) 

548 metadata.setDouble("CRPIX1", 1109.99981456774) 

549 metadata.setDouble("CRPIX2", 560.018167811613) 

550 metadata.set("CTYPE1", 'RA---SIN') 

551 metadata.set("CTYPE2", 'DEC--SIN') 

552 

553 metadata.setDouble("CD1_1", 5.10808596133527E-05) 

554 metadata.setDouble("CD1_2", 1.85579539217196E-07) 

555 metadata.setDouble("CD2_2", -5.10281493481982E-05) 

556 metadata.setDouble("CD2_1", -8.27440751733828E-07) 

557 

558 return afwGeom.makeSkyWcs(metadata) 

559 

560 

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

562 pass 

563 

564 

565def setup_module(module): 

566 lsst.utils.tests.init() 

567 

568 

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

570 lsst.utils.tests.init() 

571 unittest.main()