def testBadPatch(self): """Test that a large bad patch of an image doesn't cause an absolute failure""" initialValue = 20 mi = afwImage.MaskedImageF(500, 200) mi.set((initialValue, 0x0, 1.0)) mi.image[0:200, :] = np.nan badBits = mi.mask.getPlaneBitMask( ['EDGE', 'DETECTED', 'DETECTED_NEGATIVE']) mi.mask[0:400, :] |= badBits if debugMode: afwDisplay.Display(frame=0).mtv(mi, title=self._testMethodName + " image") sctrl = afwMath.StatisticsControl() sctrl.setAndMask(badBits) nx, ny = 17, 17 bctrl = afwMath.BackgroundControl(nx, ny, sctrl, afwMath.MEANCLIP) bkgd = afwMath.makeBackground(mi, bctrl) statsImage = bkgd.getStatsImage() if debugMode: afwDisplay.Display(frame=1).mtv(statsImage, title=self._testMethodName + " bkgd StatsImage") # the test is that this doesn't fail if the bug (#2297) is fixed bkgdImage = bkgd.getImageF(afwMath.Interpolate.NATURAL_SPLINE, afwMath.REDUCE_INTERP_ORDER) self.assertEqual(np.mean(bkgdImage[0:100, 0:100].array), initialValue) if debugMode: afwDisplay.Display(frame=2).mtv(bkgdImage, title=self._testMethodName + " bkgdImage") # Check that we can fix the NaNs in the statsImage sim = statsImage.getImage().getArray() sim[np.isnan(sim)] = initialValue # replace NaN by initialValue bkgdImage = bkgd.getImageF(afwMath.Interpolate.NATURAL_SPLINE, afwMath.REDUCE_INTERP_ORDER) self.assertAlmostEqual( np.mean(bkgdImage[0:100, 0:100].array, dtype=np.float64), initialValue)
def testConformMaskPlanes2(self): """Test conformMaskPlanes() when the two planes are different""" testMask3 = afwImage.Mask(self.testMask.getDimensions()) name1 = "Great Timothy" name2 = "Our Boss" p1 = self.Mask.addMaskPlane(name1) p2 = self.Mask.addMaskPlane(name2) oldDict = self.testMask.getMaskPlaneDict() testMask3.setMaskPlaneValues(p1, 0, 5, 0) testMask3.setMaskPlaneValues(p2, 0, 5, 1) if display: afwDisplay.Display(frame=1).mtv(testMask3, title="testConformMaskPlanes2") self.assertEqual(testMask3[0, 0], testMask3.getPlaneBitMask(name1)) self.assertEqual(testMask3[0, 1], testMask3.getPlaneBitMask(name2)) self.testMask.removeAndClearMaskPlane(name1, True) self.testMask.removeAndClearMaskPlane(name2, True) self.Mask.addMaskPlane(name2) # added in opposite order to testMask3 self.Mask.addMaskPlane(name1) self.assertEqual(self.testMask[0, 0], 0) if display: afwDisplay.Display(frame=2).mtv(testMask3, title="testConformMaskPlanes2 (cleared and re-added)") self.assertNotEqual(testMask3[0, 0], testMask3.getPlaneBitMask(name1)) self.assertNotEqual(testMask3[0, 1], testMask3.getPlaneBitMask(name2)) testMask3.conformMaskPlanes(oldDict) self.assertEqual(testMask3[0, 0], testMask3.getPlaneBitMask(name1)) self.assertEqual(testMask3[0, 1], testMask3.getPlaneBitMask(name2)) if display: afwDisplay.Display(frame=3).mtv(testMask3, title="testConformMaskPlanes2 (conform with oldDict)") self.testMask |= testMask3
def measureExposure(self, exposure, positions, title="Fringe"): """Measure fringe amplitudes for an exposure The fringe amplitudes are measured as the statistic within a square aperture. The statistic within a larger aperture are subtracted so as to remove the background. Parameters ---------- exposure : `lsst.afw.image.Exposure` Exposure to measure the positions on. positions : `numpy.array` Two-dimensional array containing the positions to sample for fringe amplitudes. title : `str`, optional Title used for debug out plots. Returns ------- fringes : `numpy.array` Array of measured exposure values at each of the positions supplied. """ stats = afwMath.StatisticsControl() stats.setNumSigmaClip(self.config.stats.clip) stats.setNumIter(self.config.stats.iterations) stats.setAndMask(exposure.getMaskedImage().getMask().getPlaneBitMask( self.config.stats.badMaskPlanes)) num = self.config.num fringes = numpy.ndarray(num) for i in range(num): x, y = positions[i] small = measure(exposure.getMaskedImage(), x, y, self.config.small, self.config.stats.stat, stats) large = measure(exposure.getMaskedImage(), x, y, self.config.large, self.config.stats.stat, stats) fringes[i] = small - large import lsstDebug display = lsstDebug.Info(__name__).display if display: disp = afwDisplay.Display(frame=getFrame()) disp.mtv(exposure, title=title) if False: with disp.Buffering(): for x, y in positions: corners = numpy.array([[-1, -1], [1, -1], [1, 1], [-1, 1], [-1, -1]]) + [[x, y]] disp.line(corners * self.config.small, ctype=afwDisplay.GREEN) disp.line(corners * self.config.large, ctype=afwDisplay.BLUE) return fringes
def expToPng(exp, saveFilename, title=None): fig = plt.figure(figsize=(15, 15)) afwDisplay.setDefaultBackend("matplotlib") display = afwDisplay.Display(fig, open=True) display.setImageColormap('viridis') display.scale('asinh', 'zscale') display.mtv(exp, title=title) plt.tight_layout() fig.savefig(saveFilename) return
def testRotate(self): """Test that we end up with the correct image after rotating by 90 degrees. """ for nQuarter, x, y in [(0, 0, 0), (1, 9, 0), (2, 19, 9), (3, 0, 19)]: outImage = afwMath.rotateImageBy90(self.inImage, nQuarter) if display: afwDisplay.Display(frame=nQuarter).mtv(outImage, title=f"out {nQuarter}") self.assertEqual(self.inImage[0, 0, afwImage.LOCAL], outImage[x, y, afwImage.LOCAL])
def measure(self, footprintSet, exposure): """Measure a set of Footprints, returning a SourceCatalog""" catalog = afwTable.SourceCatalog(self.schema) if display: afwDisplay.Display(frame=0).mtv(exposure, title="Original") footprintSet.makeSources(catalog) self.measureSources.run(catalog, exposure) return catalog
def test1295(self): """A test case for #1295 (failure to interpolate over groups of defects.""" im = afwImage.ImageF(lsst.geom.ExtentI(100, 100)) mi = afwImage.makeMaskedImage(im) mi.set(100) flat = afwImage.ImageF(im.getDimensions()) flat.set(1) flat[50:51, :, afwImage.LOCAL] = 0.0 flat[55:56, :, afwImage.LOCAL] = 0.0 flat[58:59, :, afwImage.LOCAL] = 0.0 flat[51:60, 51:, afwImage.LOCAL] = 0.0 mi /= flat if display: afwDisplay.Display(frame=0).mtv(mi, title=self._testMethodName + ": Raw") defectList = [] bbox = lsst.geom.BoxI(lsst.geom.PointI(50, 0), lsst.geom.ExtentI(1, 100)) defectList.append(algorithms.Defect(bbox)) bbox = lsst.geom.BoxI(lsst.geom.PointI(55, 0), lsst.geom.ExtentI(1, 100)) defectList.append(algorithms.Defect(bbox)) bbox = lsst.geom.BoxI(lsst.geom.PointI(58, 0), lsst.geom.ExtentI(1, 100)) defectList.append(algorithms.Defect(bbox)) bbox = lsst.geom.BoxI(lsst.geom.PointI(51, 51), lsst.geom.ExtentI(9, 49)) defectList.append(algorithms.Defect(bbox)) psf = algorithms.DoubleGaussianPsf( 15, 15, 1. / (2 * math.sqrt(2 * math.log(2)))) algorithms.interpolateOverDefects(mi, psf, defectList, 50.) if display: afwDisplay.Display(frame=1).mtv(mi, title=self._testMethodName + ": Interpolated") self.assertTrue(np.isfinite(mi.image[56, 51, afwImage.LOCAL]))
def display(self, xy0=None, frame=1, ctype=None): """Display polygon on existing frame""" import lsst.geom import lsst.afw.display as afwDisplay xy0 = lsst.geom.Extent2D(0, 0) if xy0 is None else lsst.geom.Extent2D(xy0) disp = afwDisplay.Display(frame=frame) with disp.Buffering(): for p1, p2 in self.getEdges(): disp.line((p1 - xy0, p2 - xy0), ctype=ctype)
def checkFringe(self, task, exp, fringes, stddevMax): """Run fringe subtraction and verify. Parameters ---------- task : `lsst.ip.isr.fringe.FringeTask` Task to run. exp : `lsst.afw.image.ExposureF` Science exposure. fringes : `list` of `lsst.afw.image.ExposureF` Data reference that will provide the fringes. stddevMax : `float` Maximum allowable standard deviation. """ if display: frame = 0 afwDisplay.Display(frame=frame).mtv(exp, title=self._testMethodName + ": Science exposure") frame += 1 if not isinstance(fringes, list): fringe = [fringes] else: fringe = fringes for i, f in enumerate(fringe): afwDisplay.Display(frame=frame).mtv( f, title=self._testMethodName + ": Fringe frame %d" % (i + 1)) frame += 1 task.run(exp, fringes) mi = exp.getMaskedImage() if display: afwDisplay.Display(frame=frame).mtv(exp, title=self._testMethodName + ": Subtracted") frame += 1 mi -= afwMath.makeStatistics(mi, afwMath.MEAN).getValue() self.assertLess( afwMath.makeStatistics(mi, afwMath.STDEV).getValue(), stddevMax)
def showSourceSetSky(sSet, wcs, xy0, frame=0, ctype=afwDisplay.GREEN, symb="+", size=2): """Draw the (RA, Dec) positions of a set of Sources. Image has the XY0. """ disp = afwDisplay.Display(frame=frame) with disp.Buffering(): for s in sSet: (xc, yc) = wcs.skyToPixel(s.getCoord().getRa(), s.getCoord().getDec()) xc -= xy0[0] yc -= xy0[1] disp.dot(symb, xc, yc, ctype=ctype, size=size)
def testSetFromFootprint(self): """Test setting mask/image pixels from a Footprint list""" mi = afwImage.MaskedImageF(lsst.geom.Extent2I(12, 8)) im = mi.getImage() # # Objects that we should detect # self.objects = [] self.objects += [Object(10, [(1, 4, 4), (2, 3, 5), (3, 4, 4)])] self.objects += [Object(20, [(5, 7, 8), (5, 10, 10), (6, 8, 9)])] self.objects += [Object(20, [(6, 3, 3)])] im.set(0) # clear image for obj in self.objects: obj.insert(im) ds = afwDetect.FootprintSet(mi, afwDetect.Threshold(15)) objects = ds.getFootprints() afwDetect.setMaskFromFootprintList(mi.getMask(), objects, 0x1) self.assertEqual(mi.getMask()[4, 2, afwImage.LOCAL], 0x0) self.assertEqual(mi.getMask()[3, 6, afwImage.LOCAL], 0x1) self.assertEqual(mi.getImage()[3, 6, afwImage.LOCAL], 20) for ft in objects: ft.spans.setImage(mi.getImage(), 5.0) self.assertEqual(mi.getImage()[4, 2, afwImage.LOCAL], 10) self.assertEqual(mi.getImage()[3, 6, afwImage.LOCAL], 5) if display: afwDisplay.Display(frame=1).mtv(mi, title=self._testMethodName + " image") # # Check Footprint.contains() while we are about it # self.assertTrue(objects[0].contains(lsst.geom.Point2I(7, 5))) self.assertFalse(objects[0].contains(lsst.geom.Point2I(10, 6))) self.assertFalse(objects[0].contains(lsst.geom.Point2I(7, 6))) self.assertFalse(objects[0].contains(lsst.geom.Point2I(4, 2))) self.assertTrue(objects[1].contains(lsst.geom.Point2I(3, 6))) # Verify the FootprintSet footprint list setter can accept inputs from # the footprint list getter # Create a copy of the ds' FootprintList dsFpList = ds.getFootprints() footprintListCopy = [afwDetect.Footprint().assign(f) for f in dsFpList] # Use the FootprintList setter with the output from the getter ds.setFootprints(ds.getFootprints()[:-1]) dsFpListNew = ds.getFootprints() self.assertTrue(len(dsFpListNew) == len(footprintListCopy) - 1) for new, old in zip(dsFpListNew, footprintListCopy[:-1]): self.assertEqual(new, old)
def testCandidateList(self): if False and display: disp = afwDisplay.Display(frame=0) disp.mtv(self.mi, title=self._testMethodName + ": image") for cell in self.cellSet.getCellList(): x0, y0, x1, y1 = (cell.getBBox().getX0(), cell.getBBox().getY0(), cell.getBBox().getX1(), cell.getBBox().getY1()) print((x0, y0, " ", x1, y1)) x0 -= 0.5 y0 -= 0.5 x1 += 0.5 y1 += 0.5 disp.line([(x0, y0), (x1, y0), (x1, y1), (x0, y1), (x0, y0)], ctype=afwDisplay.RED) self.assertFalse(self.cellSet.getCellList()[0].empty()) self.assertTrue(self.cellSet.getCellList()[1].empty()) self.assertFalse(self.cellSet.getCellList()[2].empty()) stamps = [] for cell in self.cellSet.getCellList(): for cand in cell: cand = cell[0] width, height = 15, 17 cand.setWidth(width) cand.setHeight(height) im = cand.getMaskedImage() stamps.append(im) self.assertEqual(im.getWidth(), width) self.assertEqual(im.getHeight(), height) if display: mos = afwDisplay.utils.Mosaic() afwDisplay.Display(frame=1).mtv(mos.makeMosaic(stamps), title=self._testMethodName + ": image")
def testStatsZebra(self): """Add 1 to every other row""" for image, isInt, mean, median, std in self.images: image2 = image.clone() # # Add 1 to every other row, so the variance is increased by 1/4 # self.assertEqual(image2.getHeight() % 2, 0) width = image2.getWidth() for y in range(1, image2.getHeight(), 2): sim = image2[lsst.geom.Box2I(lsst.geom.Point2I(0, y), lsst.geom.Extent2I(width, 1))] sim += 1 if display: afwDisplay.Display(frame=0).mtv(image, "Image 1") afwDisplay.Display(frame=1).mtv(image2, "Image 2 (var inc by 1/4)") stats = afwMath.makeStatistics( image2, afwMath.NPOINT | afwMath.STDEV | afwMath.MEAN | afwMath.ERRORS) meanRes = stats.getResult(afwMath.MEAN) n = stats.getValue(afwMath.NPOINT) sd = stats.getValue(afwMath.STDEV) self.assertAlmostEqual(meanRes[0], mean + 0.5, delta=self.delta("mean", isInt)) self.assertAlmostEqual( sd, np.hypot(std, 1 / math.sqrt(4.0) * math.sqrt(n / (n - 1))), delta=0.00011) self.assertAlmostEqual( meanRes[1], sd / math.sqrt(image2.getWidth() * image2.getHeight()), 10) meanSquare = afwMath.makeStatistics(image2, afwMath.MEANSQUARE).getValue() self.assertAlmostEqual(meanSquare, 0.5 * (mean**2 + (mean + 1)**2) + std**2, delta=0.00025 if isInt else 0.00006)
def displayImage(self, image, centroid=None): import lsst.afw.image as afwImage import lsst.afw.display as afwDisp disp1 = afwDisp.Display(987, open=True) tempImg = afwImage.ImageF(np.zeros(image.data.shape, dtype=np.float32)) tempImg.array[:] = image.data disp1.mtv(tempImg) if centroid: disp1.dot('x', centroid[0], centroid[1], size=100)
def testXY0(self): """Test that inserting a HeavyFootprint obeys XY0""" fs = afwDetect.FootprintSet(self.mi, afwDetect.Threshold(1)) fs.makeHeavy(self.mi) bbox = lsst.geom.BoxI(lsst.geom.PointI(9, 1), lsst.geom.ExtentI(7, 4)) omi = self.mi.Factory(self.mi, bbox, afwImage.LOCAL, True) omi.set((0, 0x0, 0)) for foot in fs.getFootprints(): foot.insert(omi) if display: afwDisplay.Display(frame=0).mtv(self.mi, title="testXY0 input") afwDisplay.Display(frame=1).mtv(omi, title="testXY0 sub") submi = self.mi.Factory(self.mi, bbox, afwImage.LOCAL) self.assertFloatsEqual(submi.getImage().getArray(), omi.getImage().getArray())
def validateInterp(miInterp, useFallbackValueAtEdge, fallbackValue): imaInterp = miInterp.getImage().getArray() if display: afwDisplay.Display(frame=1).mtv(miInterp, title=self._testMethodName + ": interp image") self.assertGreater(np.min(imaInterp), min(-2, 2*fallbackValue)) self.assertGreater(max(2, 2*fallbackValue), np.max(imaInterp)) val0 = np.mean(miInterp.image[1:2, :, afwImage.LOCAL].array, dtype=float) if useFallbackValueAtEdge: self.assertAlmostEqual(val0, fallbackValue, 6) else: self.assertNotEqual(val0, 0)
def displayDipoles(self, exposure, sources): """Display debugging information on the detected dipoles Parameters ---------- exposure : `lsst.afw.image.Exposure` Image the dipoles were measured on sources : `lsst.afw.table.SourceCatalog` The set of diaSources that were measured""" import lsstDebug display = lsstDebug.Info(__name__).display displayDiaSources = lsstDebug.Info(__name__).displayDiaSources maskTransparency = lsstDebug.Info(__name__).maskTransparency if not maskTransparency: maskTransparency = 90 disp = afwDisplay.Display(frame=lsstDebug.frame) disp.setMaskTransparency(maskTransparency) disp.mtv(exposure) if display and displayDiaSources: with disp.Buffering(): for source in sources: cenX, cenY = source.get("ipdiffim_DipolePsfFlux_centroid") if np.isinf(cenX) or np.isinf(cenY): cenX, cenY = source.getCentroid() isdipole = source.get( "ip_diffim_ClassificationDipole_value") if isdipole and np.isfinite(isdipole): # Dipole ctype = afwDisplay.GREEN else: # Not dipole ctype = afwDisplay.RED disp.dot("o", cenX, cenY, size=2, ctype=ctype) negCenX = source.get( "ip_diffim_PsfDipoleFlux_neg_centroid_x") negCenY = source.get( "ip_diffim_PsfDipoleFlux_neg_centroid_y") posCenX = source.get( "ip_diffim_PsfDipoleFlux_pos_centroid_x") posCenY = source.get( "ip_diffim_PsfDipoleFlux_pos_centroid_y") if (np.isinf(negCenX) or np.isinf(negCenY) or np.isinf(posCenX) or np.isinf(posCenY)): continue disp.line([(negCenX, negCenY), (posCenX, posCenY)], ctype=afwDisplay.YELLOW) lsstDebug.frame += 1
def testFitsRead(self): """Check if we read MaskedImages""" image = self.mi.getImage() mask = self.mi.getMask() if display: afwDisplay.Display(frame=0).mtv(self.mi, title="Image") self.assertEqual(image[32, 1, afwImage.LOCAL], 3728) self.assertEqual(mask[0, 0, afwImage.LOCAL], 2) # == BAD
def showPsfSpatialCells(exposure, psfCellSet, nMaxPerCell=-1, showChi2=False, showMoments=False, symb=None, ctype=None, ctypeUnused=None, ctypeBad=None, size=2, display=None): """Show the SpatialCells. If symb is something that afwDisplay.Display.dot() understands (e.g. "o"), the top nMaxPerCell candidates will be indicated with that symbol, using ctype and size. """ if not display: display = afwDisplay.Display() with display.Buffering(): origin = [-exposure.getMaskedImage().getX0(), -exposure.getMaskedImage().getY0()] for cell in psfCellSet.getCellList(): displayUtils.drawBBox(cell.getBBox(), origin=origin, display=display) if nMaxPerCell < 0: nMaxPerCell = 0 i = 0 goodies = ctypeBad is None for cand in cell.begin(goodies): if nMaxPerCell > 0: i += 1 xc, yc = cand.getXCenter() + origin[0], cand.getYCenter() + origin[1] if i > nMaxPerCell: if not ctypeUnused: continue color = ctypeBad if cand.isBad() else ctype if symb: if i > nMaxPerCell: ct = ctypeUnused else: ct = ctype display.dot(symb, xc, yc, ctype=ct, size=size) source = cand.getSource() if showChi2: rchi2 = cand.getChi2() if rchi2 > 1e100: rchi2 = numpy.nan display.dot("%d %.1f" % (splitId(source.getId(), True)["objId"], rchi2), xc - size, yc - size - 4, ctype=color, size=2) if showMoments: display.dot("%.2f %.2f %.2f" % (source.getIxx(), source.getIxy(), source.getIyy()), xc-size, yc + size + 4, ctype=color, size=size) return display
def testDetection(self): """Test Interp algorithms.""" if display: frame = 0 afwDisplay.Display(frame=frame).mtv(self.mi, title=self._testMethodName + ": Original") algorithms.interpolateOverDefects(self.mi, self.psf, self.badPixels) if display: frame += 1 afwDisplay.Display(frame=frame).mtv(self.mi, title=self._testMethodName + ": Interpolated") frame += 1 afwDisplay.Display(frame=frame).mtv(self.mi.getVariance(), title=self._testMethodName + ": Variance")
def testGrow2(self): """Grow some more interesting shaped Footprints. Informative with display, but no numerical tests""" ds = afwDetect.FootprintSet(self.ms, afwDetect.Threshold(10), "OBJECT") idImage = afwImage.ImageU(self.ms.getDimensions()) idImage.set(0) i = 1 for foot in ds.getFootprints()[0:1]: foot.dilate(3, afwGeom.Stencil.MANHATTAN) foot.spans.setImage(idImage, i, doClip=True) i += 1 if display: afwDisplay.Display(frame=0).mtv(self.ms, title=self._testMethodName + " self.ms") afwDisplay.Display(frame=1).mtv(idImage, title=self._testMethodName + " image")
def testBadRows(self): """Test that a bad set of rows in an image doesn't cause a failure""" initialValue = 20 mi = afwImage.MaskedImageF(500, 200) mi.set((initialValue, 0x0, 1.0)) mi.image[:, 0:100] = np.nan badBits = mi.mask.getPlaneBitMask( ['EDGE', 'DETECTED', 'DETECTED_NEGATIVE']) mi.mask[0:400, :] |= badBits if debugMode: afwDisplay.Display(frame=0).mtv(mi, title=self._testMethodName + " image") sctrl = afwMath.StatisticsControl() sctrl.setAndMask(badBits) nx, ny = 17, 17 bctrl = afwMath.BackgroundControl(nx, ny, sctrl, afwMath.MEANCLIP) bkgd = afwMath.makeBackground(mi, bctrl) statsImage = bkgd.getStatsImage() if debugMode: afwDisplay.Display(frame=1).mtv(statsImage, title=self._testMethodName + " bkgd StatsImage") # the test is that this doesn't fail if the bug (#2297) is fixed for frame, interpStyle in enumerate([ afwMath.Interpolate.CONSTANT, afwMath.Interpolate.LINEAR, afwMath.Interpolate.NATURAL_SPLINE, afwMath.Interpolate.AKIMA_SPLINE ], 2): bkgdImage = bkgd.getImageF(interpStyle, afwMath.REDUCE_INTERP_ORDER) self.assertEqual(np.mean(bkgdImage[0:100, 0:100].array), initialValue) if debugMode: afwDisplay.Display(frame=frame).mtv( bkgdImage, title=f"{self._testMethodName} bkgdImage: {interpStyle}")
def testInvarianceOfPixelToSky(self): for deep in (True, False): llc = lsst.geom.Point2I(20, 30) bbox = lsst.geom.Box2I(llc, lsst.geom.Extent2I(60, 50)) subImg = afwImage.ExposureF(self.parent, bbox, afwImage.LOCAL, deep) xy0 = subImg.getMaskedImage().getXY0() if display: afwDisplay.Display(frame=0).mtv(self.parent, title=self._testMethodName + ": parent") afwDisplay.Display(frame=1).mtv(subImg, title=self._testMethodName + ": subImg") for p in self.testPositions: subP = p - lsst.geom.Extent2D(llc[0], llc[1]) # pixel in subImg if subP[0] < 0 or subP[0] >= bbox.getWidth( ) or subP[1] < 0 or subP[1] >= bbox.getHeight(): continue adParent = self.parent.getWcs().pixelToSky(p) adSub = subImg.getWcs().pixelToSky( subP + lsst.geom.Extent2D(xy0[0], xy0[1])) # # Check that we're talking about the same pixel # self.assertEqual( self.parent.maskedImage[lsst.geom.Point2I(p), afwImage.LOCAL], subImg.maskedImage[lsst.geom.Point2I(subP), afwImage.LOCAL]) self.assertEqual(adParent[0], adSub[0], f"RAs are equal; deep = {deep}") self.assertEqual(adParent[1], adSub[1], f"DECs are equal; deep = {deep}")
def check(self, ImageClass): image = ImageClass(self.size, self.size) x, y = np.indices((self.size, self.size)) image.getImage().getArray()[y, x] = np.where(x * y % self.freqImage, 0, np.nan) image.getMask().getArray()[y, x] = np.where(x * y % self.freqMask, 0, self.allowMask) image.getVariance().getArray()[y, x] = np.where(x * y % self.freqVariance, 0, np.nan) if display: afwDisplay.Display(frame=1).mtv(image.getImage(), title=self._testMethodName + ": Image") afwDisplay.Display(frame=2).mtv(image.getVariance(), title=self._testMethodName + ": Variance") afwDisplay.Display(frame=3).mtv(image.getMask(), title=self._testMethodName + ": Original mask") isUnmasked = np.logical_not(image.getMask().getArray() & self.allowMask) isNan = np.logical_or(np.isnan(image.getImage().getArray()), np.isnan(image.getVariance().getArray())) maskExpected = np.where(np.logical_and(isUnmasked, isNan), self.afterMask, image.getMask().getArray()) numExpected = np.count_nonzero(maskExpected & self.afterMask) numNans = maskNans(image, self.afterMask, self.allowMask) if display: afwDisplay.Display(frame=4).mtv(image.getMask(), title=self._testMethodName + ": UNC-ed mask") self.assertEqual(numNans, numExpected) self.assertMasksEqual(image.getMask(), maskExpected)
def testLinearRamp(self): """Fit a ramp""" binsize = 1 ramp, rampCoeffs, xVec, yVec = self.makeRamp(binsize) # Add a (labelled) bad value ramp[ramp.getWidth() // 2, ramp.getHeight() // 2, afwImage.LOCAL] = (0, 0x1, np.nan) if display: afwDisplay.Display(frame=0).mtv(ramp, title=self._testMethodName + ": Input") # Here's the range that the approximation should be valid (and also the # bbox of the image returned by getImage) bbox = lsst.geom.BoxI( lsst.geom.PointI(0, 0), lsst.geom.PointI(binsize * ramp.getWidth() - 1, binsize * ramp.getHeight() - 1)) order = 3 # 1 would be enough to fit the ramp actrl = afwMath.ApproximateControl( afwMath.ApproximateControl.CHEBYSHEV, order) approx = afwMath.makeApproximate(xVec, yVec, ramp, bbox, actrl) for i, aim in enumerate([ approx.getImage(), approx.getMaskedImage().getImage(), ]): if i == 0 and display: disp = afwDisplay.Display(frame=1) disp.mtv(aim, title=self._testMethodName + ": Interpolated") with disp.Buffering(): for x in xVec: for y in yVec: disp.dot('+', x, y, size=0.4) for x, y in aim.getBBox().getCorners(): self.assertEqual( aim[x, y, afwImage.LOCAL], rampCoeffs[0] + rampCoeffs[1] * x + rampCoeffs[1] * y)
def setUp(self): global oldBackend if backend != oldBackend: afwDisplay.setDefaultBackend(backend) afwDisplay.delAllDisplays() # as some may use the old backend oldBackend = backend dirName = os.path.split(__file__)[0] self.fileName = os.path.join(dirName, "data", "HSC-0908120-056-small.fits") self.display0 = afwDisplay.Display(frame=0, verbose=True)
def testImageSliceFromBox(self): """Test using a Box2I to index an Image""" im = afwImage.ImageF(10, 20) bbox = lsst.geom.BoxI(lsst.geom.PointI(1, 3), lsst.geom.PointI(6, 9)) im[bbox] = -1 if display: afwDisplay.Display(frame=0).mtv(im, title="testImageSliceFromBox") self.assertEqual(im[0, 6], 0) self.assertEqual(im[1, 6], -1) self.assertEqual(im[3, 9], -1)
def testBadAreaFailsSpline(self): """Check that a NaN in the stats image doesn't cause spline interpolation to fail (#2734)""" image = afwImage.ImageF(15, 9) for y in range(image.getHeight()): for x in range(image.getWidth()): # n.b. linear, which is what the interpolation will fall back # to image[x, y, afwImage.LOCAL] = 1 + 2*y # Set the right corner to NaN. This will mean that we have too few # points for a spline interpolator binSize = 3 image[-binSize:, -binSize:, afwImage.LOCAL] = np.nan nx = image.getWidth()//binSize ny = image.getHeight()//binSize sctrl = afwMath.StatisticsControl() bctrl = afwMath.BackgroundControl(nx, ny, sctrl, afwMath.MEANCLIP) bkgd = afwMath.makeBackground(image, bctrl) if debugMode: afwDisplay.Display(frame=0).mtv(image, title=self._testMethodName + " image") afwDisplay.Display(frame=1).mtv(bkgd.getStatsImage(), title=self._testMethodName + " bkgd StatsImage") # Should throw if we don't permit REDUCE_INTERP_ORDER self.assertRaises(lsst.pex.exceptions.OutOfRangeError, bkgd.getImageF, afwMath.Interpolate.NATURAL_SPLINE) # The interpolation should fall back to linear for the right part of the image # where the NaNs don't permit spline interpolation (n.b. this happens # to be exact) bkgdImage = bkgd.getImageF( afwMath.Interpolate.NATURAL_SPLINE, afwMath.REDUCE_INTERP_ORDER) if debugMode: afwDisplay.Display(frame=2).mtv(bkgdImage, title=self._testMethodName + " bkgdImage") image -= bkgdImage self.assertEqual(afwMath.makeStatistics(image, afwMath.MEAN).getValue(), 0.0)
def testCreate(self): """Check that we can create a HeavyFootprint""" imi = self.mi.Factory(self.mi, True) # copy of input image hfoot = afwDetect.makeHeavyFootprint(self.foot, self.mi) # check we can call a base-class method self.assertTrue(hfoot.isHeavy()) # # Check we didn't modify the input image # self.assertFloatsEqual(self.mi.getImage().getArray(), imi.getImage().getArray()) omi = self.mi.Factory(self.mi.getDimensions()) omi.set((1, 0x4, 0.1)) hfoot.insert(omi) if display: afwDisplay.Display(frame=0).mtv(imi, title="testCreate input") afwDisplay.Display(frame=1).mtv(omi, title="testCreate output") for s in self.foot.getSpans(): y = s.getY() for x in range(s.getX0(), s.getX1() + 1): self.assertEqual(imi[x, y, afwImage.LOCAL], omi[x, y, afwImage.LOCAL]) # Check that we can call getImageArray(), etc arr = hfoot.getImageArray() # Check that it's iterable for x in arr: pass arr = hfoot.getMaskArray() for x in arr: pass arr = hfoot.getVarianceArray() # Check that it's iterable for x in arr: pass
def OLDprepareFrames(mos, frame0=1, R=23, medianN=23, onlyVisits=[], force=False): """Prepare frames to have their radial profiles measured. #. Subtract the first quartile #. Set a radius R circle about the centre of Arcturus to NaN #. Set a chip with a bad QE value to NaN #. Median filter with a medianN x medianN filter The result is set as mos[-visit] If onlyVisits is specified, only process those chips [n.b. frame0 is still obeyed] """ visits = sorted(position.keys()) width, height = mos[visits[0]].getDimensions() X, Y = np.meshgrid(np.arange(width), np.arange(height)) frame = frame0 - 1 for v in visits: frame += 1 if onlyVisits and v not in onlyVisits: continue print("Processing %d" % v) im = mos[v].clone() im[2121:2230, 590:830] = np.nan # QE for this chip is bad ima = im.getArray() im[:] -= np.percentile(ima, 25) xc, yc = position[v] xc -= im.getX0() yc -= im.getY0() ima[np.hypot(X - xc, Y - yc) < R] = np.nan if force or -v not in mos: im = utils.medianFilterImage(im, medianN) mos[-v] = im else: im = mos[-v] disp = afwDisplay.Display(frame=frame) if True: disp.mtv(im, title=v) else: disp.erase() disp.dot("o", xc, yc, size=R, ctype=afwDisplay.GREEN if yc < im.getHeight() else afwDisplay.RED)