30 fluxLim = pexConfig.Field(
31 doc =
"specify the minimum psfFlux for good Psf Candidates",
34 check =
lambda x: x >= 0.0,
36 fluxMax = pexConfig.Field(
37 doc =
"specify the maximum psfFlux for good Psf Candidates (ignored if == 0)",
41 check =
lambda x: x >= 0.0,
43 badStarPixelFlags = pexConfig.ListField(
44 doc =
"PSF candidate objects may not have any of these bits set",
46 default = [
"base_PixelFlags_flag_edge",
"base_PixelFlags_flag_interpolatedCenter",
"base_PixelFlags_flag_saturatedCenter"],
48 kernelSize = pexConfig.Field(
49 doc =
"size of the kernel to create",
53 borderWidth = pexConfig.Field(
54 doc =
"number of pixels to ignore around the edge of PSF candidate postage stamps",
60 """A functor to check whether a source has any flags set that should cause it to be labeled bad."""
62 def __init__(self, table, fluxLim, fluxMax, badStarPixelFlags):
63 self.
keys = [table.getSchema().find(name).key
for name
in badStarPixelFlags]
64 self.keys.append(table.getCentroidFlagKey())
79 ConfigClass = CatalogStarSelectorConfig
82 """Construct a star selector that uses second moments
84 This is a naive algorithm and should be used with caution.
86 @param[in] config: An instance of CatalogStarSelectorConfig
89 config = CatalogStarSelector.ConfigClass()
98 """Return a list of PSF candidates that represent likely stars
100 A list of PSF candidates may be used by a PSF fitter to construct a PSF.
102 @param[in] exposure: the exposure containing the sources
103 @param[in] sources: a source list containing sources that may be stars
104 @param[in] matches: a match vector as produced by meas_astrom; not actually optional
105 (passing None just allows us to handle the exception better here
106 than in calling code)
108 @return psfCandidateList: a list of PSF candidates.
117 "Cannot use catalog star selector without running astrometry."
120 mi = exposure.getMaskedImage()
125 frames[
"displayExposure"] = 1
126 ds9.mtv(mi, frame=frames[
"displayExposure"], title=
"PSF candidates")
138 psfCandidateList = []
140 with ds9.Buffering():
141 for ref, source, d
in matches:
142 if not ref.get(
"resolved"):
143 if not isGoodSource(source):
144 symb, ctype =
"+", ds9.RED
152 if psfCandidate.getWidth() == 0:
157 im = psfCandidate.getMaskedImage().getImage()
159 if not numpy.isfinite(max):
161 psfCandidateList.append(psfCandidate)
163 symb, ctype =
"+", ds9.GREEN
164 except Exception
as err:
165 symb, ctype =
"o", ds9.RED
169 symb, ctype =
"o", ds9.BLUE
171 if display
and displayExposure:
172 ds9.dot(symb, source.getX() - mi.getX0(), source.getY() - mi.getY0(),
173 size=4, frame=frames[
"displayExposure"], ctype=ctype)
175 if display
and pauseAtEnd:
176 raw_input(
"Continue? y[es] p[db] ")
178 return psfCandidateList
180 measAlg.starSelectorRegistry.register(
"catalog", CatalogStarSelector)
boost::shared_ptr< PsfCandidate< PixelT > > makePsfCandidate(boost::shared_ptr< afw::table::SourceRecord > const &source, boost::shared_ptr< afw::image::Exposure< PixelT > > image)
Statistics makeStatistics(afwImage::Mask< afwImage::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl)
Specialization to handle Masks.