def createCandidate(self, threshold=0.1): """Create a PSF candidate from self.exp @param threshold: Threshold for creating footprints on image """ source = self.catalog.addNew() fpSet = afwDet.FootprintSet(self.exp.getMaskedImage(), afwDet.Threshold(threshold), "DETECTED") if display: ds9.mtv(self.exp, frame=1) for fp in fpSet.getFootprints(): for peak in fp.getPeaks(): ds9.dot("x", peak.getIx(), peak.getIy(), frame=1) # There might be multiple footprints; only the one around self.x,self.y should go in the source found = False for fp in fpSet.getFootprints(): if fp.contains(afwGeom.Point2I(self.x, self.y)): found = True break self.assertTrue( found, "Unable to find central peak in footprint: faulty test") source.setFootprint(fp) return measAlg.PsfCandidateF(source, self.exp, self.x, self.y)
def checkMatches(srcMatchSet, exposure, log=None): """Check astrometric matches and assess Wcs quality by computing statics over spacial cells in the image. Parameters ---------- srcMatchSet : `list` of `lsst.afw.table.ReferenceMatch` List of matched sources to a reference catalog. exposure : `lsst.afw.image.Exposure` Image the sources in srcMatchSet were detected/measured in. log : `lsst.log.Log` Logger object. Returns ------- values : `dict` Result dictionary with fields: - ``minObjectsPerCell`` : (`int`) - ``maxObjectsPerCell`` : (`int`) - ``meanObjectsPerCell`` : (`float`) - ``stdObjectsPerCell`` : (`float`) """ if not exposure: return {} if log is None: log = Log.getLogger("meas.astrom.verifyWcs.checkMatches") im = exposure.getMaskedImage().getImage() width, height = im.getWidth(), im.getHeight() nx, ny = 3, 3 w, h = width // nx, height // ny if w == 0: w = 1 while nx * w < width: w += 1 if h == 0: h = 1 while ny * h < height: h += 1 cellSet = afwMath.SpatialCellSet( lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(width, height)), w, h) # # Populate cellSet # i = -1 for m in srcMatchSet: i += 1 src = m.second csrc = afwDetection.Source() csrc.setId(i) csrc.setXAstrom(src.getXAstrom()) csrc.setYAstrom(src.getYAstrom()) try: cellSet.insertCandidate( measAlg.PsfCandidateF(csrc, exposure.getMaskedImage())) except Exception as e: log.warn(str(e)) ncell = len(cellSet.getCellList()) nobj = np.ndarray(ncell, dtype='i') for i in range(ncell): cell = cellSet.getCellList()[i] nobj[i] = cell.size() dx = np.ndarray(cell.size()) dy = np.ndarray(cell.size()) j = 0 for cand in cell: # # Swig doesn't know that we're a SpatialCellImageCandidate; all it knows is that we have # a SpatialCellCandidate so we need an explicit (dynamic) cast # mid = cand.getSource().getId() dx[j] = srcMatchSet[mid].first.getXAstrom( ) - srcMatchSet[mid].second.getXAstrom() dy[j] = srcMatchSet[mid].first.getYAstrom( ) - srcMatchSet[mid].second.getYAstrom() j += 1 log.debug("%s %-30s %8s dx,dy = %5.2f,%5.2f rms_x,y = %5.2f,%5.2f", cell.getLabel(), cell.getBBox(), ("nobj=%d" % cell.size()), dx.mean(), dy.mean(), dx.std(), dy.std()) nobj.sort() values = {} values["minObjectsPerCell"] = int( nobj[0]) # otherwise it's a numpy integral type values["maxObjectsPerCell"] = int(nobj[-1]) values["meanObjectsPerCell"] = nobj.mean() values["stdObjectsPerCell"] = nobj.std() return values
def checkMatches(srcMatchSet, exposure, log=None): if not exposure: return {} if log is None: log = Log.getLogger("meas.astrom.verifyWcs.checkMatches") im = exposure.getMaskedImage().getImage() width, height = im.getWidth(), im.getHeight() nx, ny = 3, 3 w, h = width // nx, height // ny if w == 0: w = 1 while nx * w < width: w += 1 if h == 0: h = 1 while ny * h < height: h += 1 cellSet = afwMath.SpatialCellSet( afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(width, height)), w, h) # # Populate cellSet # i = -1 for m in srcMatchSet: i += 1 src = m.second csrc = afwDetection.Source() csrc.setId(i) csrc.setXAstrom(src.getXAstrom()) csrc.setYAstrom(src.getYAstrom()) try: cellSet.insertCandidate( measAlg.PsfCandidateF(csrc, exposure.getMaskedImage())) except Exception as e: log.warn(str(e)) ncell = len(cellSet.getCellList()) nobj = np.ndarray(ncell, dtype='i') for i in range(ncell): cell = cellSet.getCellList()[i] nobj[i] = cell.size() dx = np.ndarray(cell.size()) dy = np.ndarray(cell.size()) j = 0 for cand in cell: # # Swig doesn't know that we're a SpatialCellImageCandidate; all it knows is that we have # a SpatialCellCandidate so we need an explicit (dynamic) cast # mid = cand.getSource().getId() dx[j] = srcMatchSet[mid].first.getXAstrom( ) - srcMatchSet[mid].second.getXAstrom() dy[j] = srcMatchSet[mid].first.getYAstrom( ) - srcMatchSet[mid].second.getYAstrom() j += 1 log.debug("%s %-30s %8s dx,dy = %5.2f,%5.2f rms_x,y = %5.2f,%5.2f", cell.getLabel(), cell.getBBox(), ("nobj=%d" % cell.size()), dx.mean(), dy.mean(), dx.std(), dy.std()) nobj.sort() values = {} values["minObjectsPerCell"] = int( nobj[0]) # otherwise it's a numpy integral type values["maxObjectsPerCell"] = int(nobj[-1]) values["meanObjectsPerCell"] = nobj.mean() values["stdObjectsPerCell"] = nobj.std() return values