43 namespace algorithms {
49 template <
typename PixelT>
50 int PsfCandidate<PixelT>::_border = 0;
51 template <
typename PixelT>
52 int PsfCandidate<PixelT>::_defaultWidth = 21;
53 template <
typename PixelT>
54 float PsfCandidate<PixelT>::_pixelThreshold = 0.0;
55 template <
typename PixelT>
56 bool PsfCandidate<PixelT>::_doMaskBlends =
true;
61 struct noop :
public afw::image::pixelOp1<T> {
62 T operator()(T x)
const {
return x; }
66 struct andMask :
public afw::image::pixelOp1<T> {
67 andMask(T mask) : _mask(mask) {}
68 T operator()(T x)
const {
return (x & _mask); }
75 andMask<T> makeAndMask(T
val) {
76 return andMask<T>(
val);
82 template <
typename LhsT,
typename RhsT>
84 afw::image::Mask<RhsT>
const& rhs,
85 afw::image::pixelOp1<RhsT>
const& func = noop<RhsT>()
88 std::make_shared<afw::image::Image<LhsT>>(rhs.getDimensions());
89 lhs->setXY0(rhs.getXY0());
91 for (
int y = 0;
y != lhs->getHeight(); ++
y) {
95 lhsEnd = lhs->row_end(y);
96 lhsPtr != lhsEnd; ++rhsPtr, ++lhsPtr) {
97 *lhsPtr = func(*rhsPtr);
105 double distanceSquared(
double x,
double y, afw::detection::PeakRecord
const& peak) {
113 template <
typename MaskT>
114 class BlendedFunctor {
116 BlendedFunctor(afw::detection::PeakRecord
const& central,
121 : _central(central), _peaks(peaks), _turnOff(~turnOff), _turnOn(turnOn) {}
125 int x = point.getX();
126 int y = point.getY();
127 double const central = distanceSquared(x, y, _central);
129 iter !=
end; ++iter) {
130 double const dist2 = distanceSquared(x, y, *iter);
131 if (dist2 < central) {
139 afw::detection::PeakRecord
const& _central;
165 template <
typename PixelT>
166 PTR(afw::image::MaskedImage<PixelT>)
167 PsfCandidate<PixelT>::extractImage(
unsigned int width,
172 geom::Point2I const llc(cen[0] - width / 2 - _parentExposure->getX0(),
173 cen[1] - height / 2 - _parentExposure->getY0());
179 MaskedImageT mimg = _parentExposure->getMaskedImage();
181 }
catch (pex::exceptions::LengthError& e) {
190 MaskedImageT::Mask::getPlaneBitMask(
"INTRP");
194 if (getMaskBlends()) {
195 CONST_PTR(afw::detection::Footprint) foot = getSource()->getFootprint();
197 PeakCatalog
const& peaks = foot->getPeaks();
198 if (peaks.size() > 1) {
201 PTR(afw::detection::PeakRecord) central;
202 for (PeakCatalog::const_iterator iter = peaks.begin(),
end = peaks.end(); iter !=
end; ++iter) {
203 double const dist2 = distanceSquared(getXCenter(), getYCenter(), *iter);
211 PeakCatalog others(peaks.getTable());
212 others.reserve(peaks.size() - 1);
213 for (PeakCatalog::const_iterator iter = peaks.begin(),
end = peaks.end(); iter !=
end; ++iter) {
214 PTR(afw::detection::PeakRecord) ptr(iter);
215 if (central != ptr) {
216 others.push_back(ptr);
220 BlendedFunctor<typename MaskedImageT::Mask::Pixel> functor(*central, others, detected, intrp);
221 foot->getSpans()->clippedTo(
image->getBBox())->applyFunctor(functor, *
image->getMask());
231 PTR(afw::image::Image<int>) mim = makeImageFromMask<int>(*
image->getMask(), makeAndMask(detected));
232 PTR(afw::detection::FootprintSet)
233 fs = std::make_shared<afw::detection::FootprintSet>(*mim, afw::detection::Threshold(1));
234 CONST_PTR(FootprintList) feet = fs->getFootprints();
236 if (feet->size() > 1) {
241 for (FootprintList::const_iterator fiter = feet->begin(); fiter != feet->end(); ++fiter) {
242 PTR(afw::detection::Footprint) foot = *fiter;
243 if (foot->contains(cen)) {
248 auto bigSpan = foot->getSpans()->dilated(ngrow)->clippedTo(
image->getBBox());
249 bigSpan->clearMask(*
image->getMask(), detected);
250 bigSpan->setMask(*
image->getMask(), intrp);
255 if (_pixelThreshold > 0.0) {
257 fpSet = std::make_shared<afw::detection::FootprintSet>(
259 for (FootprintList::const_iterator fpIter = fpSet->getFootprints()->begin();
260 fpIter != fpSet->getFootprints()->end(); ++fpIter) {
261 CONST_PTR(afw::detection::Footprint) fp = *fpIter;
262 if (!fp->contains(cen)) {
263 fp->getSpans()->clearMask(*image->getMask(), detected);
264 fp->getSpans()->setMask(*image->getMask(), intrp);
277 template <
typename PixelT>
278 CONST_PTR(afw::image::MaskedImage<PixelT>)
280 if (!_image || (width != _image->getWidth() || height != _image->getHeight())) {
281 _image = extractImage(width, height);
291 template <
typename PixelT>
294 int const width = getWidth() == 0 ? _defaultWidth : getWidth();
295 int const height = getHeight() == 0 ? _defaultWidth : getHeight();
296 return getMaskedImage(width, height);
299 template <
typename PixelT>
304 template <
typename PixelT>
309 template <
typename PixelT>
311 _pixelThreshold = threshold;
314 template <
typename PixelT>
316 return _pixelThreshold;
319 template <
typename PixelT>
321 _doMaskBlends = doMaskBlends;
324 template <
typename PixelT>
326 return _doMaskBlends;
334 template <
typename PixelT>
339 unsigned int const width = getWidth() == 0 ? _defaultWidth : getWidth();
340 unsigned int const height = getHeight() == 0 ? _defaultWidth : getHeight();
341 if (_offsetImage && static_cast<unsigned int>(_offsetImage->getWidth()) == width + 2 * buffer &&
342 static_cast<unsigned int>(_offsetImage->getHeight()) == height + 2 * buffer) {
346 PTR(
MaskedImageT) image = extractImage(width + 2 * buffer, height + 2 * buffer);
348 double const xcen = getXCenter(), ycen = getYCenter();
static void setMaskBlends(bool doMaskBlends)
Set whether blends are masked.
int positionToIndex(double pos)
_const_view_t::x_iterator const_x_iterator
_view_t::x_iterator x_iterator
static float getPixelThreshold()
Get threshold for rejecting pixels unconnected with the central footprint.
static void setBorderWidth(int border)
Set the number of pixels to ignore around the candidate image's edge.
afw::table::CatalogT< PeakRecord > PeakCatalog
Class used by SpatialCell for spatial PSF fittig.
static void setPixelThreshold(float threshold)
Set threshold for rejecting pixels unconnected with the central footprint.
static int getBorderWidth()
Return the number of pixels being ignored around the candidate image's edge.
CatalogIterator< typename Internal::const_iterator > const_iterator
std::shared_ptr< ImageT > offsetImage(ImageT const &image, float dx, float dy, std::string const &algorithmName="lanczos5", unsigned int buffer=0)
static bool getMaskBlends()
Get whether blends are masked.
#define LSST_EXCEPT_ADD(e, m)
Class stored in SpatialCells for spatial Psf fitting.