Return a list of PSF candidates that represent likely stars.
A list of PSF candidates may be used by a PSF fitter to construct a PSF.
297 def selectStars(self, exposure, catalog, matches=None):
298 """!Return a list of PSF candidates that represent likely stars
300 A list of PSF candidates may be used by a PSF fitter to construct a PSF.
302 \param[in] exposure the exposure containing the sources
303 \param[in] catalog a SourceCatalog containing sources that may be stars
304 \param[in] matches astrometric matches; ignored by this star selector
306 \return psfCandidateList a list of PSF candidates.
315 logger =
pexLogging.Log(pexLogging.getDefaultLog(),
"meas.algorithms.objectSizeStarSelector")
317 detector = exposure.getDetector()
318 pixToTanXYTransform =
None
319 if detector
is not None:
320 tanSys = detector.makeCameraSys(cameraGeom.TAN_PIXELS)
321 pixToTanXYTransform = detector.getTransformMap().get(tanSys)
327 xx = numpy.empty(len(catalog))
328 xy = numpy.empty_like(xx)
329 yy = numpy.empty_like(xx)
330 for i, source
in enumerate(catalog):
331 Ixx, Ixy, Iyy = source.getIxx(), source.getIxy(), source.getIyy()
332 if pixToTanXYTransform:
334 linTransform = pixToTanXYTransform.linearizeForwardTransform(p).getLinear()
335 m = geomEllip.Quadrupole(Ixx, Iyy, Ixy)
336 m.transform(linTransform)
337 Ixx, Iyy, Ixy = m.getIxx(), m.getIyy(), m.getIxy()
339 xx[i], xy[i], yy[i] = Ixx, Ixy, Iyy
341 width = numpy.sqrt(0.5*(xx + yy))
345 bad = reduce(
lambda x, y: numpy.logical_or(x, catalog.get(y)), badFlags,
False)
346 bad = numpy.logical_or(bad, flux < self.
_fluxMin)
347 bad = numpy.logical_or(bad, numpy.logical_not(numpy.isfinite(width)))
348 bad = numpy.logical_or(bad, numpy.logical_not(numpy.isfinite(flux)))
349 bad = numpy.logical_or(bad, width < self.
_widthMin)
350 bad = numpy.logical_or(bad, width > self.
_widthMax)
352 bad = numpy.logical_or(bad, flux > self.
_fluxMax)
353 good = numpy.logical_not(bad)
355 if not numpy.any(good):
356 raise RuntimeError(
"No objects passed our cuts for consideration as psf stars")
358 mag = -2.5*numpy.log10(flux[good])
365 import os, cPickle
as pickle
368 pickleFile = os.path.expanduser(os.path.join(
"~",
"widths-%d.pkl" % _ii))
369 if not os.path.exists(pickleFile):
373 with open(pickleFile,
"wb")
as fd:
374 pickle.dump(mag, fd, -1)
375 pickle.dump(width, fd, -1)
377 centers, clusterId =
_kcenters(width, nCluster=4, useMedian=
True,
380 if display
and plotMagSize
and pyplot:
381 fig =
plot(mag, width, centers, clusterId, magType=self._sourceFluxField.split(
".")[-1].title(),
382 marker=
"+", markersize=3, markeredgewidth=
None, ltype=
':', clear=
True)
389 if display
and plotMagSize
and pyplot:
390 plot(mag, width, centers, clusterId, marker=
"x", markersize=3, markeredgewidth=
None, clear=
False)
392 stellar = (clusterId == 0)
399 if display
and displayExposure:
400 ds9.mtv(exposure.getMaskedImage(), frame=frame, title=
"PSF candidates")
403 eventHandler =
EventHandler(fig.get_axes()[0], mag, width,
404 catalog.getX()[good], catalog.getY()[good], frames=[frame])
412 reply = raw_input(
"continue? [c h(elp) q(uit) p(db)] ").strip()
421 We cluster the points; red are the stellar candidates and the other colours are other clusters.
422 Points labelled + are rejects from the cluster (only for cluster 0).
424 At this prompt, you can continue with almost any key; 'p' enters pdb, and 'h' prints this text
426 If displayExposure is true, you can put the cursor on a point and hit 'p' to see it in ds9.
428 elif reply[0] ==
"p":
429 import pdb; pdb.set_trace()
430 elif reply[0] ==
'q':
435 if display
and displayExposure:
436 mi = exposure.getMaskedImage()
438 with ds9.Buffering():
439 for i, source
in enumerate(catalog):
445 ds9.dot(
"+", source.getX() - mi.getX0(),
446 source.getY() - mi.getY0(), frame=frame, ctype=ctype)
450 with ds9.Buffering():
451 psfCandidateList = []
452 for isStellar, source
in zip(stellar, [s
for g, s
in zip(good, catalog)
if g]):
457 psfCandidate = algorithmsLib.makePsfCandidate(source, exposure)
461 if psfCandidate.getWidth() == 0:
466 im = psfCandidate.getMaskedImage().getImage()
468 if not numpy.isfinite(vmax):
470 psfCandidateList.append(psfCandidate)
472 if display
and displayExposure:
473 ds9.dot(
"o", source.getX() - mi.getX0(), source.getY() - mi.getY0(),
474 size=4, frame=frame, ctype=ds9.CYAN)
475 except Exception
as err:
476 logger.logdebug(
"Failed to make a psfCandidate from source %d: %s" % (source.getId(), err))
478 return psfCandidateList
480 starSelectorRegistry.register(
"objectSize", ObjectSizeStarSelector)
def selectStars
Return a list of PSF candidates that represent likely stars.
a place to record messages and descriptions of the state of processing.
Statistics makeStatistics(afwImage::Mask< afwImage::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl)
Specialization to handle Masks.