342 def getClumps(self, sigma=1.0, display=False):
344 raise RuntimeError(
"No candidate PSF sources")
350 width, height = psfImage.getWidth(), psfImage.getHeight()
355 subLargeImg = psfImage.Factory(largeImg, bbox, afwImage.LOCAL)
356 subLargeImg <<= psfImage
361 msk = afwImage.MaskU(largeImg.getDimensions())
363 var = afwImage.ImageF(largeImg.getDimensions())
365 mpsfImage = afwImage.MaskedImageF(largeImg, msk, var)
375 threshold = maxVal - sigma*math.sqrt(maxVal)
386 schema = afwTable.SourceTable.makeMinimalSchema()
387 psfImageConfig = SingleFrameMeasurementConfig()
388 psfImageConfig.doApplyApCorr =
"no"
389 psfImageConfig.slots.centroid =
"base_SdssCentroid"
390 psfImageConfig.slots.psfFlux =
None
391 psfImageConfig.slots.apFlux =
"base_CircularApertureFlux_3_0"
392 psfImageConfig.slots.modelFlux =
None
393 psfImageConfig.slots.instFlux =
None
394 psfImageConfig.slots.calibFlux =
None
395 psfImageConfig.slots.shape =
"base_SdssShape"
398 psfImageConfig.algorithms.names = [
"base_SdssCentroid",
"base_CircularApertureFlux",
"base_SdssShape"]
399 psfImageConfig.algorithms[
"base_CircularApertureFlux"].radii = [3.0]
400 psfImageConfig.validate()
401 task = SingleFrameMeasurementTask(schema, config=psfImageConfig)
406 exposure.setPsf(algorithmsLib.DoubleGaussianPsf(11, 11, gaussianWidth))
408 ds.makeSources(catalog)
417 ds9.mtv(dispImage,title=
"PSF Selection Image", frame=frame)
423 IzzMax = (self._xSize/8.0)**2
426 task.run(exposure, catalog)
427 for i, source
in enumerate(catalog):
428 if source.getCentroidFlag():
430 x, y = source.getX(), source.getY()
432 apFluxes.append(source.getApFlux())
434 val = mpsfImage.getImage().get(int(x) + width, int(y) + height)
436 psfClumpIxx = source.getIxx()
437 psfClumpIxy = source.getIxy()
438 psfClumpIyy = source.getIyy()
442 ds9.pan(x, y, frame=frame)
444 ds9.dot(
"+", x, y, ctype=ds9.YELLOW, frame=frame)
445 ds9.dot(
"@:%g,%g,%g" % (psfClumpIxx, psfClumpIxy, psfClumpIyy), x, y,
446 ctype=ds9.YELLOW, frame=frame)
448 if psfClumpIxx < IzzMin
or psfClumpIyy < IzzMin:
449 psfClumpIxx = max(psfClumpIxx, IzzMin)
450 psfClumpIyy = max(psfClumpIyy, IzzMin)
452 ds9.dot(
"@:%g,%g,%g" % (psfClumpIxx, psfClumpIxy, psfClumpIyy), x, y,
453 ctype=ds9.RED, frame=frame)
455 det = psfClumpIxx*psfClumpIyy - psfClumpIxy*psfClumpIxy
457 a, b, c = psfClumpIyy/det, -psfClumpIxy/det, psfClumpIxx/det
458 except ZeroDivisionError:
459 a, b, c = 1e4, 0, 1e4
461 clumps.append(
Clump(peak=val, x=x, y=y, a=a, b=b, c=c,
462 ixx=psfClumpIxx, ixy=psfClumpIxy, iyy=psfClumpIyy))
465 msg =
"Failed to determine center of PSF clump"
468 raise RuntimeError(msg)
482 if clump.ixx < IzzMax
and clump.iyy < IzzMax:
483 goodClumps.append(clump)
486 if len(goodClumps) == 0:
490 iBestClump = numpy.argsort(apFluxes)[0]
491 clumps = [clumps[iBestClump]]
A Threshold is used to pass a threshold value to detection algorithms.
An integer coordinate rectangle.
Custom catalog class for record/table subclasses that are guaranteed to have an ID, and should generally be sorted by that ID.
Statistics makeStatistics(afwImage::Mask< afwImage::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl)
Specialization to handle Masks.
Exposure< ImagePixelT, MaskPixelT, VariancePixelT >::Ptr makeExposure(MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > &mimage, boost::shared_ptr< Wcs const > wcs=boost::shared_ptr< Wcs const >())