def testReferenceFilter(self): """Test sub-selecting reference objects by flux.""" sourceCat = self.loadSourceCatalog(self.filename) refCat = self.computePosRefCatalog(sourceCat) # Apply source selector to sourceCat, using the astrometry config defaults tempConfig = measAstrom.AstrometryTask.ConfigClass() tempSolver = measAstrom.AstrometryTask(config=tempConfig, refObjLoader=None) sourceSelection = tempSolver.sourceSelector.run(sourceCat) distortedCat = distort.distortList(sourceSelection.sourceCat, distort.linearXDistort) matchPessConfig = measAstrom.MatchPessimisticBTask.ConfigClass() matchPessConfig.maxRefObjects = 150 matchPessConfig.minMatchDistPixels = 5.0 matchPess = measAstrom.MatchPessimisticBTask(config=matchPessConfig) trimmedRefCat = matchPess._filterRefCat(refCat, 'r_flux') self.assertEqual(len(trimmedRefCat), matchPessConfig.maxRefObjects) matchRes = matchPess.matchObjectsToSources( refCat=refCat, sourceCat=distortedCat, wcs=self.distortedWcs, sourceFluxField='slot_ApFlux_instFlux', refFluxField="r_flux", ) self.assertEqual(len(matchRes.matches), matchPessConfig.maxRefObjects - 3)
def singleTestInstance(self, filename, distortFunc): cat = self.loadCatalogue(self.filename) img = distort.distortList(cat, distortFunc) bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(1000, 1000)) res = self.astrom.determineWcs2(img, bbox=bbox) imgWcs = res.getWcs() # Create a wcs with sip cat = cat.cast(SimpleCatalog, False) matchList = self.matchSrcAndCatalogue(cat, img, imgWcs) print("*** num matches =", len(matchList)) return sipObject = sip.makeCreateWcsWithSip(matchList, imgWcs, 3) imgWcs = sipObject.getNewWcs() print('number of matches:', len(matchList), sipObject.getNPoints()) scatter = sipObject.getScatterOnSky().asArcseconds() print("Scatter in arcsec is %g" % (scatter)) self.assertLess(scatter, self.tolArcsec, "Scatter exceeds tolerance in arcsec") if False: scatter = sipObject.getScatterInPixels() self.assertLess( scatter, self.tolPixel, "Scatter exceeds tolerance in pixels: %g" % (scatter, ))
def testPassingMatcherState(self): """Test that results of the matcher can be propagated to to in subsequent iterations. """ sourceCat = self.loadSourceCatalog(self.filename) refCat = self.computePosRefCatalog(sourceCat) # Apply source selector to sourceCat, using the astrometry config defaults tempConfig = measAstrom.AstrometryTask.ConfigClass() tempSolver = measAstrom.AstrometryTask(config=tempConfig, refObjLoader=None) sourceSelection = tempSolver.sourceSelector.run(sourceCat) distortedCat = distort.distortList(sourceSelection.sourceCat, distort.linearXDistort) sourceCat = distortedCat matchRes = self.MatchPessimisticB.matchObjectsToSources( refCat=refCat, sourceCat=sourceCat, wcs=self.distortedWcs, sourceFluxField='slot_ApFlux_instFlux', refFluxField="r_flux", ) maxShift = matchRes.match_tolerance.maxShift * 300 # Force the matcher to use a different pattern thatn the previous # "iteration". matchTol = measAstrom.MatchTolerancePessimistic( maxMatchDist=matchRes.match_tolerance.maxMatchDist, autoMaxMatchDist=matchRes.match_tolerance.autoMaxMatchDist, maxShift=maxShift, lastMatchedPattern=0, failedPatternList=[0], PPMbObj=matchRes.match_tolerance.PPMbObj, ) matchRes = self.MatchPessimisticB.matchObjectsToSources( refCat=refCat, sourceCat=sourceCat, wcs=self.distortedWcs, sourceFluxField='slot_ApFlux_instFlux', refFluxField="r_flux", match_tolerance=matchTol, ) self.assertEqual(len(matchRes.matches), self.expectedMatches) self.assertLess(matchRes.match_tolerance.maxShift, maxShift) self.assertEqual(matchRes.match_tolerance.lastMatchedPattern, 1) self.assertIsNotNone(matchRes.match_tolerance.maxMatchDist) self.assertIsNotNone(matchRes.match_tolerance.autoMaxMatchDist) self.assertIsNotNone(matchRes.match_tolerance.lastMatchedPattern) self.assertIsNotNone(matchRes.match_tolerance.failedPatternList) self.assertIsNotNone(matchRes.match_tolerance.PPMbObj)
def singleTestInstance(self, filename, distortFunc, doPlot=False): sourceCat = self.loadSourceCatalog(self.filename) refCat = self.computePosRefCatalog(sourceCat) distortedCat = distort.distortList(sourceCat, distortFunc) if doPlot: import matplotlib.pyplot as plt undistorted = [self.wcs.skyToPixel(self.distortedWcs.pixelToSky(ss.getCentroid())) for ss in distortedCat] refs = [self.wcs.skyToPixel(ss.getCoord()) for ss in refCat] def plot(catalog, symbol): plt.plot([ss.getX() for ss in catalog], [ss.getY() for ss in catalog], symbol) #plot(sourceCat, 'k+') # Original positions: black + plot(distortedCat, 'b+') # Distorted positions: blue + plot(undistorted, 'g+') # Undistorted positions: green + plot(refs, 'rx') # Reference catalog: red x # The green + should overlap with the red x, because that's how matchOptimisticB does it. # The black + happens to overlap with those also, but that's beside the point. plt.show() sourceCat = distortedCat matchRes = self.matchOptimisticB.matchObjectsToSources( refCat = refCat, sourceCat = sourceCat, wcs = self.distortedWcs, refFluxField = "r_flux", ) matches = matchRes.matches if doPlot: measAstrom.plotAstrometry(matches=matches, refCat=refCat, sourceCat=sourceCat) self.assertEqual(len(matches), 183) refCoordKey = afwTable.CoordKey(refCat.schema["coord"]) srcCoordKey = afwTable.CoordKey(sourceCat.schema["coord"]) refCentroidKey = afwTable.Point2DKey(refCat.getSchema()["centroid"]) maxDistErr = afwGeom.Angle(0) for refObj, source, distRad in matches: sourceCoord = source.get(srcCoordKey) refCoord = refObj.get(refCoordKey) predDist = sourceCoord.angularSeparation(refCoord) distErr = abs(predDist - distRad*afwGeom.radians) maxDistErr = max(distErr, maxDistErr) if refObj.getId() != source.getId(): refCentroid = refObj.get(refCentroidKey) sourceCentroid = source.getCentroid() radius = math.hypot(*(refCentroid - sourceCentroid)) self.fail("ID mismatch: %s at %s != %s at %s; error = %0.1f pix" % (refObj.getId(), refCentroid, source.getId(), sourceCentroid, radius)) self.assertLess(maxDistErr.asArcseconds(), 1e-7)
def singleTestInstance(self, filename, distortFunc): cat = self.loadCatalogue(self.filename) img = distort.distortList(cat, distortFunc) bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(1000, 1000)) res = self.astrom.determineWcs2(img, bbox=bbox) imgWcs = res.getWcs() def printWcs(wcs): print("WCS metadata:") md = wcs.getFitsMetadata() for name in md.names(): print("%s: %r" % (name, md.get(name))) printWcs(imgWcs) # Create a wcs with sip cat = cat.cast(SimpleCatalog, False) matchList = self.matchSrcAndCatalogue(cat, img, imgWcs) print("*** num matches =", len(matchList)) return sipObject = sip.makeCreateWcsWithSip(matchList, imgWcs, 3) # print 'Put in TAN Wcs:' # print imgWcs.getFitsMetadata().toString() imgWcs = sipObject.getNewWcs() # print 'Got SIP Wcs:' # print imgWcs.getFitsMetadata().toString() # Write out the SIP header # afwImage.fits_write_imageF('createWcsWithSip.sip', afwImage.ImageF(0,0), # imgWcs.getFitsMetadata()) print('number of matches:', len(matchList), sipObject.getNPoints()) scatter = sipObject.getScatterOnSky().asArcseconds() print("Scatter in arcsec is %g" % (scatter)) self.assertLess(scatter, self.tolArcsec, "Scatter exceeds tolerance in arcsec") if False: scatter = sipObject.getScatterInPixels() self.assertLess( scatter, self.tolPixel, "Scatter exceeds tolerance in pixels: %g" % (scatter, ))
def singleTestInstance(self, filename, distortFunc): cat = self.loadCatalogue(self.filename) img = distort.distortList(cat, distortFunc) bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(1000, 1000)) res = self.astrom.determineWcs2(img, bbox=bbox) imgWcs = res.getWcs() def printWcs(wcs): print "WCS metadata:" md = wcs.getFitsMetadata() for name in md.names(): print "%s: %r" % (name, md.get(name)) printWcs(imgWcs) #Create a wcs with sip cat = cat.cast(afwTable.SimpleCatalog, False) matchList = self.matchSrcAndCatalogue(cat, img, imgWcs) print "*** num matches =", len(matchList) return sipObject = sip.makeCreateWcsWithSip(matchList, imgWcs, 3) #print 'Put in TAN Wcs:' #print imgWcs.getFitsMetadata().toString() imgWcs = sipObject.getNewWcs() #print 'Got SIP Wcs:' #print imgWcs.getFitsMetadata().toString() # Write out the SIP header #afwImage.fits_write_imageF('createWcsWithSip.sip', afwImage.ImageF(0,0), #imgWcs.getFitsMetadata()) print 'number of matches:', len(matchList), sipObject.getNPoints() scatter = sipObject.getScatterOnSky().asArcseconds() print "Scatter in arcsec is %g" % (scatter) self.assertLess(scatter, self.tolArcsec, "Scatter exceeds tolerance in arcsec") if False: scatter = sipObject.getScatterInPixels() self.assertLess(scatter, self.tolPixel, "Scatter exceeds tolerance in pixels: %g" %(scatter))
def singleTestInstance(self, filename, distortFunc, doPlot=False): sourceCat = self.loadSourceCatalog(self.filename) refCat = self.computePosRefCatalog(sourceCat) distortedCat = distort.distortList(sourceCat, distortFunc) if doPlot: import matplotlib.pyplot as plt undistorted = [ self.wcs.skyToPixel( self.distortedWcs.pixelToSky(ss.getCentroid())) for ss in distortedCat ] refs = [self.wcs.skyToPixel(ss.getCoord()) for ss in refCat] def plot(catalog, symbol): plt.plot([ss.getX() for ss in catalog], [ss.getY() for ss in catalog], symbol) plot(distortedCat, 'b+') # Distorted positions: blue + plot(undistorted, 'g+') # Undistorted positions: green + plot(refs, 'rx') # Reference catalog: red x # The green + should overlap with the red x, because that's how # MatchPessimisticB does it. plt.show() sourceCat = distortedCat matchRes = self.MatchPessimisticB.matchObjectsToSources( refCat=refCat, sourceCat=sourceCat, wcs=self.distortedWcs, refFluxField="r_flux", ) matches = matchRes.matches if doPlot: measAstrom.plotAstrometry(matches=matches, refCat=refCat, sourceCat=sourceCat) self.assertEqual(len(matches), 183) refCoordKey = afwTable.CoordKey(refCat.schema["coord"]) srcCoordKey = afwTable.CoordKey(sourceCat.schema["coord"]) refCentroidKey = afwTable.Point2DKey(refCat.getSchema()["centroid"]) maxDistErr = afwGeom.Angle(0) for refObj, source, distRad in matches: sourceCoord = source.get(srcCoordKey) refCoord = refObj.get(refCoordKey) predDist = sourceCoord.angularSeparation(refCoord) distErr = abs(predDist - distRad * afwGeom.radians) maxDistErr = max(distErr, maxDistErr) if refObj.getId() != source.getId(): refCentroid = refObj.get(refCentroidKey) sourceCentroid = source.getCentroid() radius = math.hypot(*(refCentroid - sourceCentroid)) self.fail( "ID mismatch: %s at %s != %s at %s; error = %0.1f pix" % (refObj.getId(), refCentroid, source.getId(), sourceCentroid, radius)) self.assertLess(maxDistErr.asArcseconds(), 1e-7)
def singleTestInstance(self, filename, distortFunc, doPlot=False): sourceCat = self.loadSourceCatalog(self.filename) refCat = self.computePosRefCatalog(sourceCat) # Apply source selector to sourceCat, using the astrometry config defaults tempConfig = measAstrom.AstrometryTask.ConfigClass() tempConfig.matcher.retarget(measAstrom.MatchOptimisticBTask) tempConfig.sourceSelector["matcher"].excludePixelFlags = False tempSolver = measAstrom.AstrometryTask(config=tempConfig, refObjLoader=None) sourceSelection = tempSolver.sourceSelector.run(sourceCat) distortedCat = distort.distortList(sourceSelection.sourceCat, distortFunc) if doPlot: import matplotlib.pyplot as plt undistorted = [ self.wcs.skyToPixel( self.distortedWcs.pixelToSky(ss.getCentroid())) for ss in distortedCat ] refs = [self.wcs.skyToPixel(ss.getCoord()) for ss in refCat] def plot(catalog, symbol): plt.plot([ss.getX() for ss in catalog], [ss.getY() for ss in catalog], symbol) # plot(sourceCat, 'k+') # Original positions: black + plot(distortedCat, 'b+') # Distorted positions: blue + plot(undistorted, 'g+') # Undistorted positions: green + plot(refs, 'rx') # Reference catalog: red x # The green + should overlap with the red x, because that's how matchOptimisticB does it. # The black + happens to overlap with those also, but that's beside the point. plt.show() sourceCat = distortedCat matchRes = self.matchOptimisticB.matchObjectsToSources( refCat=refCat, sourceCat=sourceCat, wcs=self.distortedWcs, sourceFluxField='slot_ApFlux_instFlux', refFluxField="r_flux", ) matches = matchRes.matches if doPlot: measAstrom.plotAstrometry(matches=matches, refCat=refCat, sourceCat=sourceCat) self.assertEqual(len(matches), 183) refCoordKey = afwTable.CoordKey(refCat.schema["coord"]) srcCoordKey = afwTable.CoordKey(sourceCat.schema["coord"]) refCentroidKey = afwTable.Point2DKey(refCat.getSchema()["centroid"]) maxDistErr = 0 * lsst.geom.radians for refObj, source, distRad in matches: sourceCoord = source.get(srcCoordKey) refCoord = refObj.get(refCoordKey) predDist = sourceCoord.separation(refCoord) distErr = abs(predDist - distRad * lsst.geom.radians) maxDistErr = max(distErr, maxDistErr) if refObj.getId() != source.getId(): refCentroid = refObj.get(refCentroidKey) sourceCentroid = source.getCentroid() radius = math.hypot(*(refCentroid - sourceCentroid)) self.fail( "ID mismatch: %s at %s != %s at %s; error = %0.1f pix" % (refObj.getId(), refCentroid, source.getId(), sourceCentroid, radius)) self.assertLess(maxDistErr.asArcseconds(), 1e-7)
def singleTestInstance(self, filename, distortFunc, doPlot=False): sourceCat = self.loadSourceCatalog(self.filename) refCat = self.computePosRefCatalog(sourceCat) # Apply source selector to sourceCat, using the astrometry config defaults tempConfig = measAstrom.AstrometryTask.ConfigClass() tempSolver = measAstrom.AstrometryTask(config=tempConfig, refObjLoader=None) sourceSelection = tempSolver.sourceSelector.run(sourceCat) distortedCat = distort.distortList(sourceSelection.sourceCat, distortFunc) if doPlot: import matplotlib.pyplot as plt undistorted = [self.wcs.skyToPixel(self.distortedWcs.pixelToSky(ss.getCentroid())) for ss in distortedCat] refs = [self.wcs.skyToPixel(ss.getCoord()) for ss in refCat] def plot(catalog, symbol): plt.plot([ss.getX() for ss in catalog], [ss.getY() for ss in catalog], symbol) plot(distortedCat, 'b+') # Distorted positions: blue + plot(undistorted, 'g+') # Undistorted positions: green + plot(refs, 'rx') # Reference catalog: red x # The green + should overlap with the red x, because that's how # MatchPessimisticB does it. plt.show() sourceCat = distortedCat matchRes = self.MatchPessimisticB.matchObjectsToSources( refCat=refCat, sourceCat=sourceCat, wcs=self.distortedWcs, sourceFluxField='slot_ApFlux_instFlux', refFluxField="r_flux", ) matches = matchRes.matches if doPlot: measAstrom.plotAstrometry(matches=matches, refCat=refCat, sourceCat=sourceCat) self.assertEqual(len(matches), self.expectedMatches) refCoordKey = afwTable.CoordKey(refCat.schema["coord"]) srcCoordKey = afwTable.CoordKey(sourceCat.schema["coord"]) refCentroidKey = afwTable.Point2DKey(refCat.getSchema()["centroid"]) maxDistErr = 0*lsst.geom.radians for refObj, source, distRad in matches: sourceCoord = source.get(srcCoordKey) refCoord = refObj.get(refCoordKey) predDist = sourceCoord.separation(refCoord) distErr = abs(predDist - distRad*lsst.geom.radians) maxDistErr = max(distErr, maxDistErr) if refObj.getId() != source.getId(): refCentroid = refObj.get(refCentroidKey) sourceCentroid = source.getCentroid() radius = math.hypot(*(refCentroid - sourceCentroid)) self.fail( "ID mismatch: %s at %s != %s at %s; error = %0.1f pix" % (refObj.getId(), refCentroid, source.getId(), sourceCentroid, radius)) self.assertLess(maxDistErr.asArcseconds(), 1e-7)