def testDeltaConvolve(self): """Test convolution with various delta function kernels using optimized code """ for kWidth in range(1, 4): for kHeight in range(1, 4): for activeCol in range(kWidth): for activeRow in range(kHeight): kernel = afwMath.DeltaFunctionKernel( kWidth, kHeight, afwGeom.Point2I(activeCol, activeRow)) if display and False: kim = afwImage.ImageD(kWidth, kHeight) kernel.computeImage(kim, False) ds9.mtv(kim, frame=1) self.runStdTest(kernel, kernelDescr="Delta Function Kernel")
def testCreateTrivialWcsAsPropertySet(self): wcsName = "Z" # arbitrary xy0 = afwGeom.Point2I(47, -200) # arbitrary metadata = createTrivialWcsMetadata(wcsName=wcsName, xy0=xy0) desiredNameValueList = ( # names are missing wcsName suffix ("CRPIX1", 1.0), ("CRPIX2", 1.0), ("CRVAL1", xy0[0]), ("CRVAL2", xy0[1]), ("CTYPE1", "LINEAR"), ("CTYPE2", "LINEAR"), ("CUNIT1", "PIXEL"), ("CUNIT2", "PIXEL"), ) self.assertEqual(len(metadata.names(True)), len(desiredNameValueList)) for name, value in desiredNameValueList: self.assertEqual(metadata.get(name + wcsName), value)
def transposeDefectList(self, defectList, checkBbox=None): retDefectList = measAlg.DefectListT() for defect in defectList: bbox = defect.getBBox() nbbox = afwGeom.Box2I( afwGeom.Point2I(bbox.getMinY(), bbox.getMinX()), afwGeom.Extent2I(bbox.getDimensions()[1], bbox.getDimensions()[0])) if checkBbox: if checkBbox.overlaps(bbox): retDefectList.push_back(measAlg.Defect(nbbox)) else: pass else: retDefectList.push_back(measAlg.Defect(nbbox)) return retDefectList
def testFootprintToBBoxList(self): """Test footprintToBBoxList""" region = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(12, 10)) foot = afwDetect.Footprint(0, region) for y, x0, x1 in [ (3, 3, 5), (3, 7, 7), (4, 2, 3), (4, 5, 7), (5, 2, 3), (5, 5, 8), (6, 3, 5), ]: foot.addSpan(y, x0, x1) idImage = afwImage.ImageU(region.getDimensions()) idImage.set(0) foot.insertIntoImage(idImage, 1) if display: ds9.mtv(idImage) idImageFromBBox = idImage.Factory(idImage, True) idImageFromBBox.set(0) bboxes = afwDetect.footprintToBBoxList(foot) for bbox in bboxes: x0, y0, x1, y1 = bbox.getMinX(), bbox.getMinY(), bbox.getMaxX( ), bbox.getMaxY() for y in range(y0, y1 + 1): for x in range(x0, x1 + 1): idImageFromBBox.set(x, y, 1) if display: x0 -= 0.5 y0 -= 0.5 x1 += 0.5 y1 += 0.5 ds9.line([(x0, y0), (x1, y0), (x1, y1), (x0, y1), (x0, y0)], ctype=ds9.RED) idImageFromBBox -= idImage # should be blank stats = afwMath.makeStatistics(idImageFromBBox, afwMath.MAX) self.assertEqual(stats.getValue(), 0)
def testWriteDefect(self): """Write a Footprint as a set of Defects""" region = afwGeom.Box2I(afwGeom.Point2I(0,0), afwGeom.Extent2I(12,10)) foot = afwDetect.Footprint(0, region) for y, x0, x1 in [(3, 3, 5), (3, 7, 7), (4, 2, 3), (4, 5, 7), (5, 2, 3), (5, 5, 8), (6, 3, 5), ]: foot.addSpan(y, x0, x1) if True: fd = open("/dev/null", "w") else: fd = sys.stdout afwDetectUtils.writeFootprintAsDefects(fd, foot)
def testCreate(self): """Check that we can create a CoaddPsf with 9 elements.""" print("CreatePsfTest") # also test that the weight field name is correctly observed schema = afwTable.ExposureTable.makeMinimalSchema() schema.addField("customweightname", type="D", doc="Coadd weight") mycatalog = afwTable.ExposureCatalog(schema) # Each of the 9 has its peculiar Psf, Wcs, weight, and bounding box. for i in range(1, 10, 1): record = mycatalog.getTable().makeRecord() psf = measAlg.DoubleGaussianPsf(100, 100, i, 1.00, 0.0) record.setPsf(psf) crpix = afwGeom.PointD(i*1000.0, i*1000.0) wcs = afwImage.makeWcs(self.crval, crpix, self.cd11, self.cd12, self.cd21, self.cd22) record.setWcs(wcs) record['customweightname'] = 1.0 * (i+1) record['id'] = i bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(i*1000, i*1000)) record.setBBox(bbox) mycatalog.append(record) # create the coaddpsf mypsf = measAlg.CoaddPsf(mycatalog, self.wcsref, 'customweightname') # check to be sure that we got the right number of components, in the right order self.assertEqual(mypsf.getComponentCount(), 9) for i in range(1, 10, 1): wcs = mypsf.getWcs(i-1) psf = mypsf.getPsf(i-1) bbox = mypsf.getBBox(i-1) weight = mypsf.getWeight(i-1) id = mypsf.getId(i-1) self.assertEqual(i, id) self.assertEqual(weight, 1.0*(i+1)) self.assertEqual(bbox.getBeginX(), 0) self.assertEqual(bbox.getBeginY(), 0) self.assertEqual(bbox.getEndX(), 1000 * i) self.assertEqual(bbox.getEndY(), 1000 * i) self.assertEqual(wcs.getPixelOrigin().getX(), (1000.0 * i)) self.assertEqual(wcs.getPixelOrigin().getY(), (1000.0 * i)) m0, xbar, ybar, mxx, myy, x0, y0 = getPsfMoments(psf, afwGeom.Point2D(0, 0)) self.assertAlmostEqual(i*i, mxx, delta=0.01) self.assertAlmostEqual(i*i, myy, delta=0.01)
def testModelType(self): bbox = afwGeom.Box2I(afwGeom.Point2I(10, 10), afwGeom.Extent2I(10, 10)) basisList = ipDiffim.makeKernelBasisList(self.subconfig) self.policy.set("spatialModelType", "polynomial") ipDiffim.BuildSpatialKernelVisitorF(basisList, bbox, self.policy) self.policy.set("spatialModelType", "chebyshev1") ipDiffim.BuildSpatialKernelVisitorF(basisList, bbox, self.policy) try: self.policy.set("spatialModelType", "foo") ipDiffim.BuildSpatialKernelVisitorF(basisList, bbox, self.policy) except Exception: pass else: self.fail()
def testUnitInterval(self): """!Test small ramp images with unit interval for known values """ for imageClass in (afwImage.ImageU, afwImage.ImageF, afwImage.ImageD): dim = afwGeom.Extent2I(7, 9) box = afwGeom.Box2I(afwGeom.Point2I(-1, 3), dim) numPix = dim[0]*dim[1] for start in (-5, 0, 4): if imageClass == afwImage.ImageU and start < 0: continue predStop = start + numPix - 1 # for integer steps for stop in (None, predStop): rampImage = makeRampImage(bbox=box, start=start, stop=predStop, imageClass=imageClass) predArr = np.arange(start, predStop+1) self.assertEqual(len(predArr), numPix) predArr.shape = (dim[1], dim[0]) self.assertImagesNearlyEqual(rampImage, predArr)
def runNoBg(self, sko): basisList = ipDiffim.makeKernelBasisList(self.subconfig) self.policy.set('spatialKernelOrder', sko) self.policy.set('fitForBackground', False) bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(self.size * 10, self.size * 10)) bsikv = ipDiffim.BuildSingleKernelVisitorF(basisList, self.policy) bspkv = ipDiffim.BuildSpatialKernelVisitorF(basisList, bbox, self.policy) for x in range(1, self.size, 10): for y in range(1, self.size, 10): cand = self.makeCandidate(1.0, x, y) bsikv.processCandidate(cand) bspkv.processCandidate(cand) bspkv.solveLinearEquation() sk, sb = bspkv.getSolutionPair() # Kernel if sko == 0: # Specialization for speedup spatialKernelSolution = sk.getKernelParameters() # One term for each basis function self.assertEqual(len(spatialKernelSolution), len(basisList)) else: spatialKernelSolution = sk.getSpatialParameters() nSpatialTerms = int(0.5 * (sko + 1) * (sko + 2)) # One model for each basis function self.assertEqual(len(spatialKernelSolution), len(basisList)) # First basis has no spatial variation for i in range(1, nSpatialTerms): self.assertEqual(spatialKernelSolution[0][i], 0.) # All bases have correct number of terms for i in range(len(spatialKernelSolution)): self.assertEqual(len(spatialKernelSolution[i]), nSpatialTerms) # Background spatialBgSolution = sb.getParameters() nBgTerms = 1 self.assertEqual(len(spatialBgSolution), nBgTerms)
def __init__(self, line, scti=1e-6, pcti=1e-6): """ AmplifierProperties constructor. Parameters ---------- line : str Line from segmentation.txt to parse for amplifier properties. scti : float, optional Charge transfer inefficiency in the serial direction. pcti : float, optional Charge transfer inefficiency in the parallel direction. """ self.scti = scti self.pcti = pcti tokens = line.strip().split() self.name = tokens[0] xmin, xmax, ymin, ymax = (int(x) for x in tokens[1:5]) xsize = np.abs(xmax - xmin) + 1 ysize = np.abs(ymax - ymin) + 1 self.mosaic_section = afwGeom.Box2I( afwGeom.Point2I(min(xmin, xmax), min(ymin, ymax)), afwGeom.Extent2I(xsize, ysize)) parallel_prescan = int(tokens[15]) serial_overscan = int(tokens[16]) serial_prescan = int(tokens[17]) parallel_overscan = int(tokens[18]) self.imaging = afwGeom.Box2I( afwGeom.Point2I(serial_prescan, parallel_prescan), afwGeom.Extent2I(xsize, ysize)) self.full_segment \ = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(xsize + serial_prescan + serial_overscan, ysize + parallel_prescan + parallel_overscan)) self.prescan = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(serial_prescan, ysize)) self.serial_overscan \ = afwGeom.Box2I(afwGeom.Point2I(serial_prescan + xsize, 0), afwGeom.Extent2I(serial_overscan, ysize)) self.parallel_overscan \ = afwGeom.Box2I(afwGeom.Point2I(0, ysize), afwGeom.Extent2I(serial_prescan + xsize + serial_overscan, parallel_overscan)) self.gain = float(tokens[7]) self.bias_level = float(tokens[9]) self.read_noise = float(tokens[11]) self.dark_current = float(tokens[13]) self.crosstalk = np.array([float(x) for x in tokens[21:]]) self.flip_x = (tokens[5] == '-1') self.flip_y = (tokens[6] == '-1')
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 testDefaultSize(self): """Test of both default size and specified size""" print "DefaultSizeTest" sigma0 = 5 # set the peak of the outer guassian to 0 so this is really a single gaussian. psf = measAlg.DoubleGaussianPsf(60, 60, 1.5 * sigma0, 1, 0.0) if False and display: im = psf.computeImage(afwGeom.PointD(xwid / 2, ywid / 2)) ds9.mtv(im, title="N(%g) psf" % sigma0, frame=0) # this is the coadd Wcs we want cd11 = 5.55555555e-05 cd12 = 0.0 cd21 = 0.0 cd22 = 5.55555555e-05 crval1 = 0.0 crval2 = 0.0 crpix = afwGeom.PointD(1000, 1000) crval = afwCoord.Coord(afwGeom.Point2D(crval1, crval2)) wcsref = afwImage.makeWcs(crval, crpix, cd11, cd12, cd21, cd22) # Now make the catalog schema = afwTable.ExposureTable.makeMinimalSchema() schema.addField("weight", type="D", doc="Coadd weight") mycatalog = afwTable.ExposureCatalog(schema) record = mycatalog.getTable().makeRecord() psf = measAlg.DoubleGaussianPsf(100, 100, 10.0, 1.00, 1.0) record.setPsf(psf) wcs = afwImage.makeWcs(crval, crpix, cd11, cd12, cd21, cd22) record.setWcs(wcs) record['weight'] = 1.0 record['id'] = 1 bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(2000, 2000)) record.setBBox(bbox) mycatalog.append(record) mypsf = measAlg.CoaddPsf(mycatalog, wcsref) #, 'weight') m1coadd, m2coadd = getCoaddSecondMoments(mypsf, afwGeom.Point2D(0, 0)) m1, m2 = getPsfSecondMoments(mypsf, afwGeom.Point2D(1000, 1000)) self.assertTrue(testRelDiff(m1, m1coadd, .01)) self.assertTrue(testRelDiff(m2, m2coadd, .01))
def setUp(self): # Load sample input from disk testDir = os.path.dirname(__file__) self.srcCat = afwTable.SourceCatalog.readFits( os.path.join(testDir, "data", "v695833-e0-c000.xy.fits")) self.srcCat["slot_ApFlux_instFluxErr"] = 1 self.srcCat["slot_PsfFlux_instFluxErr"] = 1 # The .xy.fits file has sources in the range ~ [0,2000],[0,4500] # which is bigger than the exposure self.bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(2048, 4612)) smallExposure = afwImage.ExposureF(os.path.join(testDir, "data", "v695833-e0-c000-a00.sci.fits")) self.exposure = afwImage.ExposureF(self.bbox) self.exposure.setWcs(smallExposure.getWcs()) self.exposure.setFilter(smallExposure.getFilter()) self.exposure.setPhotoCalib(smallExposure.getPhotoCalib()) coordKey = self.srcCat.getCoordKey() centroidKey = self.srcCat.getCentroidKey() wcs = self.exposure.getWcs() for src in self.srcCat: src.set(coordKey, wcs.pixelToSky(src.get(centroidKey))) # Make a reference loader butler = Butler(RefCatDir) self.refObjLoader = LoadIndexedReferenceObjectsTask(butler=butler) logLevel = Log.TRACE self.log = Log.getLogger('testPhotoCal') self.log.setLevel(logLevel) self.config = PhotoCalConfig() self.config.match.matchRadius = 0.5 self.config.match.referenceSelection.doMagLimit = True self.config.match.referenceSelection.magLimit.maximum = 22.0 self.config.match.referenceSelection.magLimit.fluxField = "i_flux" self.config.match.referenceSelection.doFlags = True self.config.match.referenceSelection.flags.good = ['photometric'] self.config.match.referenceSelection.flags.bad = ['resolved'] self.config.match.sourceSelection.doUnresolved = False # Don't have star/galaxy in the srcCat # The test and associated data have been prepared on the basis that we # use the PsfFlux to perform photometry. self.config.fluxField = "base_PsfFlux_instFlux"
def testNonUnitIntervals(self): """!Test a small ramp image with non-integer increments """ for imageClass in (afwImage.ImageU, afwImage.ImageF, afwImage.ImageD): dim = afwGeom.Extent2I(7, 9) box = afwGeom.Box2I(afwGeom.Point2I(-1, 3), dim) numPix = dim[0]*dim[1] for start in (-5.1, 0, 4.3): if imageClass == afwImage.ImageU and start < 0: continue for stop in (7, 1001.5, 5.4): rampImage = makeRampImage( bbox=box, start=start, stop=stop, imageClass=imageClass) dtype = rampImage.getArray().dtype predArr = np.linspace( start, stop, num=numPix, endpoint=True, dtype=dtype) predArr.shape = (dim[1], dim[0]) self.assertImagesAlmostEqual(rampImage, predArr)
def testBbox(self): """Add Spans and check bounding box""" foot = afwDetect.Footprint() for y, x0, x1 in [(10, 100, 105), (11, 99, 104)]: foot.addSpan(y, x0, x1) bbox = foot.getBBox() self.assertEqual(bbox.getWidth(), 7) self.assertEqual(bbox.getHeight(), 2) self.assertEqual(bbox.getMinX(), 99) self.assertEqual(bbox.getMinY(), 10) self.assertEqual(bbox.getMaxX(), 105) self.assertEqual(bbox.getMaxY(), 11) # clip with a bbox that doesn't overlap at all bbox2 = afwGeom.Box2I(afwGeom.Point2I(5, 90), afwGeom.Extent2I(1, 2)) foot.clipTo(bbox2) self.assertTrue(foot.getBBox().isEmpty()) self.assertEqual(foot.getArea(), 0)
def testSortedCcds(self): """Test if the Ccds are sorted by ID after insertion into a Raft""" raft = cameraGeom.Raft(cameraGeom.Id(), 8, 1) Col = 0 for serial in [7, 0, 1, 3, 2, 6, 5, 4]: ccd = cameraGeom.Ccd(cameraGeom.Id(serial)) raft.addDetector(afwGeom.Point2I(Col, 0), cameraGeom.FpPoint(afwGeom.Point2D(0, 0)), cameraGeom.Orientation(0), ccd) Col += 1 # # Check that CCDs are sorted by Id # serials = [] for ccd in raft: serials.append(ccd.getId().getSerial()) self.assertEqual(serials, sorted(serials))
def getBBoxList(path, detectorName): """Read a defects file and return the defects as a list of bounding boxes """ with pyfits.open(path) as hduList: for hdu in hduList[1:]: if hdu.header["name"] != detectorName: print("skipping header with name=%r" % (hdu.header["name"], )) continue bboxList = [] for data in hdu.data: bbox = afwGeom.Box2I( afwGeom.Point2I(int(data['x0']), int(data['y0'])), afwGeom.Extent2I(int(data['width']), int(data['height'])), ) bboxList.append(bbox) return bboxList raise RuntimeError("Data not found for detector %r" % (detectorName, ))
def testFootprintFromCircle(self): """Create an elliptical Footprint""" ellipse = afwGeomEllipses.Ellipse(afwGeomEllipses.Axes(6, 6, 0), afwGeom.Point2D(9, 15)) spanSet = afwGeom.SpanSet.fromShape(ellipse) foot = afwDetect.Footprint( spanSet, afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(20, 30))) idImage = afwImage.ImageU( afwGeom.Extent2I(foot.getRegion().getWidth(), foot.getRegion().getHeight())) idImage.set(0) foot.spans.setImage(idImage, foot.getId()) if False: ds9.mtv(idImage, frame=2)
def testInsert(self): mi = afwImage.MaskedImageF(afwGeom.Extent2I(10, 10)) kc = ipDiffim.makeKernelCandidate(0., 0., mi, mi, self.policy) kc.setStatus(afwMath.SpatialCellCandidate.GOOD) sizeCellX = self.policy.get("sizeCellX") sizeCellY = self.policy.get("sizeCellY") kernelCellSet = afwMath.SpatialCellSet( afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(1, 1)), sizeCellX, sizeCellY) kernelCellSet.insertCandidate(kc) nSeen = 0 for cell in kernelCellSet.getCellList(): for cand in cell.begin(True): self.assertEqual(cand.getStatus(), afwMath.SpatialCellCandidate.GOOD) nSeen += 1 self.assertEqual(nSeen, 1)
def runBasicConvolveEdgeTest(self, kernel, kernelDescr): """Verify that basicConvolve does not write to edge pixels for this kind of kernel """ fullBox = afwGeom.Box2I( afwGeom.Point2I(0, 0), ShiftedBBox.getDimensions(), ) goodBox = kernel.shrinkBBox(fullBox) cnvMaskedImage = afwImage.MaskedImageF(FullMaskedImage, ShiftedBBox, afwImage.LOCAL, True) cnvMaskedImageCopy = afwImage.MaskedImageF(cnvMaskedImage, fullBox, afwImage.LOCAL, True) cnvMaskedImageCopyViewOfGoodRegion = afwImage.MaskedImageF( cnvMaskedImageCopy, goodBox, afwImage.LOCAL, False) # convolve with basicConvolve, which should leave the edge pixels alone convControl = afwMath.ConvolutionControl() mathDetail.basicConvolve(cnvMaskedImage, self.maskedImage, kernel, convControl) # reset the good region to the original convolved image; # this should reset the entire convolved image to its original self cnvMaskedImageGoodView = afwImage.MaskedImageF(cnvMaskedImage, goodBox, afwImage.LOCAL, False) cnvMaskedImageGoodView[:] = cnvMaskedImageCopyViewOfGoodRegion # assert that these two are equal msg = "basicConvolve(MaskedImage, kernel=%s) wrote to edge pixels" % ( kernelDescr, ) try: self.assertMaskedImagesAlmostEqual(cnvMaskedImage, cnvMaskedImageCopy, doVariance=True, rtol=0, atol=0, msg=msg) except Exception: # write out the images, then fail shortKernelDescr = self.removeGarbageChars(kernelDescr) cnvMaskedImage.writeFits("actBasicConvolve%s" % (shortKernelDescr, )) cnvMaskedImageCopy.writeFits("desBasicConvolve%s" % (shortKernelDescr, )) raise
def _fig8Test(self, x1, y1, x2, y2): # Construct a "figure of 8" consisting of two circles touching at the # centre of an image, then demonstrate that it shrinks correctly. # (Helper method for tests below.) radius = 3 imwidth, imheight = 100, 100 nshrink = 1 # These are the correct values for footprint sizes given the paramters # above. circle_npix = 29 initial_npix = circle_npix * 2 - 1 # touch at one pixel shrunk_npix = 26 box = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(imwidth, imheight)) e1 = afwGeomEllipses.Ellipse(afwGeomEllipses.Axes(radius, radius, 0), afwGeom.Point2D(x1, y1)) spanSet1 = afwGeom.SpanSet.fromShape(e1) f1 = afwDetect.Footprint(spanSet1, box) self.assertEqual(f1.getArea(), circle_npix) e2 = afwGeomEllipses.Ellipse(afwGeomEllipses.Axes(radius, radius, 0), afwGeom.Point2D(x2, y2)) spanSet2 = afwGeom.SpanSet.fromShape(e2) f2 = afwDetect.Footprint(spanSet2, box) self.assertEqual(f2.getArea(), circle_npix) initial = afwDetect.mergeFootprints(f1, f2) initial.setRegion( f2.getRegion()) # merge does not propagate the region self.assertEqual(initial_npix, initial.getArea()) shrunk = afwDetect.Footprint().assign(initial) shrunk.erode(nshrink) self.assertEqual(shrunk_npix, shrunk.getArea()) if display: idImage = afwImage.ImageU(imwidth, imheight) for i, foot in enumerate([initial, shrunk]): print(foot.getArea()) foot.spans.setImage(idImage, i + 1) ds9.mtv(idImage)
def testRamp(self): # make a ramping image (spline should be exact for linear increasing image nx = 512 ny = 512 rampimg = afwImage.ImageD(afwGeom.Extent2I(nx, ny)) dzdx, dzdy, z0 = 0.1, 0.2, 10000.0 for x in range(nx): for y in range(ny): rampimg.set(x, y, dzdx * x + dzdy * y + z0) # check corner, edge, and center pixels bctrl = afwMath.BackgroundControl(10, 10) bctrl.setInterpStyle(afwMath.Interpolate.CUBIC_SPLINE) bctrl.setNxSample(6) bctrl.setNySample(6) bctrl.getStatisticsControl().setNumSigmaClip( 20.0) # something large enough to avoid clipping entirely bctrl.getStatisticsControl().setNumIter(1) backobj = afwMath.makeBackground(rampimg, bctrl) xpixels = [0, nx // 2, nx - 1] ypixels = [0, ny // 2, ny - 1] for xpix in xpixels: for ypix in ypixels: testval = afwMath.cast_BackgroundMI(backobj).getPixel( xpix, ypix) self.assertAlmostEqual(testval / rampimg.get(xpix, ypix), 1, 6) # Test pickle bg = afwMath.cast_BackgroundMI(backobj) new = pickle.loads(pickle.dumps(bg)) self.assertBackgroundEqual(bg, new) # Check creation of sub-image box = afwGeom.Box2I(afwGeom.Point2I(123, 45), afwGeom.Extent2I(45, 123)) bgImage = bg.getImageF("AKIMA_SPLINE") bgSubImage = afwImage.ImageF(bgImage, box) testImage = bg.getImageF(box, "AKIMA_SPLINE") self.assertEqual(testImage.getXY0(), bgSubImage.getXY0()) self.assertEqual(testImage.getDimensions(), bgSubImage.getDimensions()) self.assertTrue(np.all(testImage.getArray() == bgSubImage.getArray()))
def testSimpleGaussian(self): """Check that we can measure a single Gaussian's attributes.""" print("SimpleGaussianTest") sigma0 = 5 # set the peak of the outer guassian to 0 so this is really a single gaussian. psf = measAlg.DoubleGaussianPsf(60, 60, 1.5*sigma0, 1, 0.0) sigma = [5, 6, 7, 8] # 5 pixels is the same as a sigma of 1 arcsec. # lay down a simple pattern of four ccds, set in a pattern of 1000 pixels around the center offsets = [(1999, 1999), (1999, 0), (0, 0), (0, 1999)] # Imagine a ccd in each of positions +-1000 pixels from the center for i in range(4): record = self.mycatalog.getTable().makeRecord() psf = measAlg.DoubleGaussianPsf(100, 100, sigma[i], 1.00, 1.0) record.setPsf(psf) crpix = afwGeom.PointD(offsets[i][0], offsets[i][1]) wcs = afwImage.makeWcs(self.crval, crpix, self.cd11, self.cd12, self.cd21, self.cd22) # print out the coorinates of this supposed 2000x2000 ccd in wcsref coordinates beginCoord = wcs.pixelToSky(0, 0) endCoord = wcs.pixelToSky(2000, 2000) self.wcsref.skyToPixel(beginCoord) self.wcsref.skyToPixel(endCoord) record.setWcs(wcs) record['weight'] = 1.0 record['id'] = i bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(2000, 2000)) record.setBBox(bbox) self.mycatalog.append(record) # img = psf.computeImage(afwGeom.Point2D(1000,1000), afwGeom.Extent2I(100,100), False, False) # img.writeFits("img%d.fits"%i) mypsf = measAlg.CoaddPsf(self.mycatalog, self.wcsref) # , 'weight') m1coadd, m2coadd = getCoaddSecondMoments(mypsf, afwGeom.Point2D(1000, 1000)) m1, m2 = getPsfSecondMoments(mypsf, afwGeom.Point2D(1000, 1000)) self.assertAlmostEqual(m1, m1coadd, delta=.01) m1, m2 = getPsfSecondMoments(mypsf, afwGeom.Point2D(1000, 1001)) m1coadd, m2coadd = getCoaddSecondMoments(mypsf, afwGeom.Point2D(1000, 1001)) self.assertAlmostEqual(m1, m1coadd, delta=0.01)
def testFractionalPixel(self): """Check that we can create a CoaddPsf with 10 elements""" print "FractionalPixelTest" # this is the coadd Wcs we want cd11 = 5.55555555e-05 cd12 = 0.0 cd21 = 0.0 cd22 = 5.55555555e-05 crval1 = 0.0 crval2 = 0.0 crpix = afwGeom.PointD(1000, 1000) crval = afwCoord.Coord(afwGeom.Point2D(crval1, crval2)) wcsref = afwImage.makeWcs(crval, crpix, cd11, cd12, cd21, cd22) cd21 = 5.55555555e-05 cd12 = 5.55555555e-05 cd11 = 0.0 cd22 = 0.0 wcs = afwImage.makeWcs(crval, crpix, cd11, cd12, cd21, cd22) schema = afwTable.ExposureTable.makeMinimalSchema() schema.addField("weight", type="D", doc="Coadd weight") mycatalog = afwTable.ExposureCatalog(schema) # make a single record with an oblong Psf record = mycatalog.getTable().makeRecord() psf = makeBiaxialGaussianPsf(100, 100, 6.0, 6.0, 0.0) record.setPsf(psf) record.setWcs(wcs) record['weight'] = 1.0 record['id'] = 1 bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(2000, 2000)) record.setBBox(bbox) mycatalog.append(record) mypsf = measAlg.CoaddPsf(mycatalog, wcsref) img = psf.computeImage(afwGeom.PointD(0.25, 0.75)) img = psf.computeImage(afwGeom.PointD(0.25, 0.75)) img = psf.computeImage(afwGeom.PointD(1000, 1000)) m0, xbar, ybar, mxx, myy, x0, y0 = getPsfMoments( psf, afwGeom.Point2D(0.25, 0.75)) cm0, cxbar, cybar, cmxx, cmyy, cx0, cy0 = getPsfMoments( mypsf, afwGeom.Point2D(0.25, 0.75)) self.assertTrue(testRelDiff(x0 + xbar, cx0 + cxbar, .01)) self.assertTrue(testRelDiff(y0 + ybar, cy0 + cybar, .01))
def _makePsfMaskedImage(self, psfModel, posX, posY, dimensions=None): """! Return a MaskedImage of the a PSF Model of specified dimensions """ rawKernel = psfModel.computeKernelImage(afwGeom.Point2D(posX, posY)).convertF() if dimensions is None: dimensions = rawKernel.getDimensions() if rawKernel.getDimensions() == dimensions: kernelIm = rawKernel else: # make image of proper size kernelIm = afwImage.ImageF(dimensions) bboxToPlace = afwGeom.Box2I(afwGeom.Point2I((dimensions.getX() - rawKernel.getWidth())//2, (dimensions.getY() - rawKernel.getHeight())//2), rawKernel.getDimensions()) kernelIm.assign(rawKernel, bboxToPlace) kernelMask = afwImage.Mask(dimensions, 0x0) kernelVar = afwImage.ImageF(dimensions, 1.0) return afwImage.MaskedImageF(kernelIm, kernelMask, kernelVar)
def createFakeSource(x, y, catalog, exposure, threshold=0.1): """Create a fake source at the given x/y centroid location. Parameters ---------- x,y : `int` The x and y centroid coordinates to place the image at. catalog : `lsst.afw.table.SourceCatalog` The catalog to add the new source to. exposure : `lsst.afw.image.Exposure` The exposure to add the source to. threshold : `float`, optional The footprint threshold for identifying the source. Returns ------- source : `lsst.afw.table.SourceRecord` The created source record that was added to ``catalog``. """ source = catalog.addNew() source['centroid_x'] = x source['centroid_y'] = y exposure.getMaskedImage().getImage()[x, y] = 1.0 fpSet = afwDet.FootprintSet(exposure.getMaskedImage(), afwDet.Threshold(threshold), "DETECTED") if display: ds9.mtv(exposure, 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 x,y should go in the source found = False for fp in fpSet.getFootprints(): if fp.contains(afwGeom.Point2I(x, y)): found = True break # We cannot continue if the the created source wasn't found. assert found, "Unable to find central peak in footprint: faulty test" source.setFootprint(fp) return source
def testClip(self): im = afwImage.ImageI(afwGeom.Box2I(afwGeom.Point2I(-2, -2), afwGeom.Extent2I(20, 20))) span1 = afwGeom.SpanSet.fromShape(5, afwGeom.Stencil.BOX, (6, 6)) span1.setImage(im, 20) im.getArray()[6+2, 6+2] = 0 # Set some negative pixels to ensure they are not clipped im.getArray()[12,:] *= -1 span2 = afwGeom.SpanSet.fromShape(6, afwGeom.Stencil.BOX, (6, 6)) foot = afwDet.Footprint(span2) clipFootprintToNonzeroImpl(foot, im) self.assertEqual(foot.spans, span1)
def getDeltaLinearCombinationKernel(kSize, imSize, spOrder): """Return a LinearCombinationKernel of delta functions @param kSize: kernel size (scalar; height = width) @param x, y imSize: image size """ kernelList = [] for ctrX in range(kSize): for ctrY in range(kSize): kernelList.append( afwMath.DeltaFunctionKernel(kSize, kSize, afwGeom.Point2I(ctrX, ctrY))) polyFunc = afwMath.PolynomialFunction2D(spOrder) kernel = afwMath.LinearCombinationKernel(kernelList, polyFunc) spParams = getSpatialParameters(len(kernelList), polyFunc) kernel.setSpatialParameters(spParams) return kernel
def testSubmasks(self): smask = afwImage.MaskU( self.mask1, afwGeom.Box2I(afwGeom.Point2I(1, 1), afwGeom.ExtentI(3, 2)), afwImage.LOCAL) mask2 = afwImage.MaskU(smask.getDimensions()) mask2.set(666) smask[:] = mask2 del smask del mask2 self.assertEqual(self.mask1.get(0, 0), self.val1) self.assertEqual(self.mask1.get(1, 1), 666) self.assertEqual(self.mask1.get(4, 1), self.val1) self.assertEqual(self.mask1.get(1, 2), 666) self.assertEqual(self.mask1.get(4, 2), self.val1) self.assertEqual(self.mask1.get(1, 3), self.val1)
def testMismatch(self): """Test that we get an exception when there's a size mismatch""" scale = 5 dims = self.image.getDimensions() mask = afwImage.MaskU(dims * scale) mask.set(0xFF) ctrl = afwMath.StatisticsControl() ctrl.setAndMask(0xFF) # If it didn't raise, this would result in a NaN (the image data is completely masked). self.assertRaises(lsst.pex.exceptions.InvalidParameterError, afwMath.makeStatistics, self.image, mask, afwMath.MEDIAN, ctrl) subMask = afwImage.MaskU( mask, afwGeom.Box2I(afwGeom.Point2I(dims * (scale - 1)), dims)) subMask.set(0) # Using subMask is successful. self.assertEqual( afwMath.makeStatistics(self.image, subMask, afwMath.MEDIAN, ctrl).getValue(), self.val)