41 namespace algorithms {
47 template <
typename PixelT>
48 int PsfCandidate<PixelT>::_border = 0;
49 template <
typename PixelT>
50 int PsfCandidate<PixelT>::_defaultWidth = 21;
51 template <
typename PixelT>
52 float PsfCandidate<PixelT>::_pixelThreshold = 0.0;
53 template <
typename PixelT>
54 bool PsfCandidate<PixelT>::_doMaskBlends =
true;
59 struct noop :
public afw::image::pixelOp1<T> {
60 T operator()(T
x)
const {
return x; }
64 struct andMask :
public afw::image::pixelOp1<T> {
66 T operator()(T
x)
const {
return (
x & _mask); }
73 andMask<T> makeAndMask(T
val) {
74 return andMask<T>(
val);
80 template <
typename LhsT,
typename RhsT>
82 afw::image::Mask<RhsT>
const& rhs,
83 afw::image::pixelOp1<RhsT>
const& func = noop<RhsT>()
86 std::make_shared<afw::image::Image<LhsT>>(rhs.getDimensions());
87 lhs->setXY0(rhs.getXY0());
89 for (
int y = 0;
y != lhs->getHeight(); ++
y) {
93 lhsEnd = lhs->row_end(
y);
94 lhsPtr != lhsEnd; ++rhsPtr, ++lhsPtr) {
95 *lhsPtr = func(*rhsPtr);
103 double distanceSquared(
double x,
double y, afw::detection::PeakRecord
const&
peak) {
111 template <
typename MaskT>
112 class BlendedFunctor {
114 BlendedFunctor(afw::detection::PeakRecord
const& central,
119 : _central(central), _peaks(peaks), _turnOff(~turnOff), _turnOn(turnOn) {}
123 int x = point.getX();
124 int y = point.getY();
125 double const central = distanceSquared(
x,
y, _central);
128 double const dist2 = distanceSquared(
x,
y, *
iter);
129 if (dist2 < central) {
137 afw::detection::PeakRecord
const& _central;
163 template <
typename PixelT>
164 PTR(afw::image::MaskedImage<PixelT>)
165 PsfCandidate<PixelT>::extractImage(
unsigned int width,
170 geom::Point2I const llc(cen[0] - width / 2 - _parentExposure->getX0(),
171 cen[1] - height / 2 - _parentExposure->getY0());
177 MaskedImageT mimg = _parentExposure->getMaskedImage();
179 }
catch (pex::exceptions::LengthError& e) {
188 MaskedImageT::Mask::getPlaneBitMask(
"INTRP");
192 if (getMaskBlends()) {
196 if (peaks.size() > 1) {
199 PTR(afw::detection::PeakRecord) central;
200 for (PeakCatalog::const_iterator
iter = peaks.begin(),
end = peaks.end();
iter !=
end; ++
iter) {
201 double const dist2 = distanceSquared(getXCenter(), getYCenter(), *
iter);
210 others.reserve(peaks.size() - 1);
211 for (PeakCatalog::const_iterator
iter = peaks.begin(),
end = peaks.end();
iter !=
end; ++
iter) {
213 if (central !=
ptr) {
214 others.push_back(
ptr);
218 BlendedFunctor<typename MaskedImageT::Mask::Pixel> functor(*central, others, detected, intrp);
219 foot->getSpans()->clippedTo(
image->getBBox())->applyFunctor(functor, *
image->getMask());
229 PTR(afw::image::Image<int>) mim = makeImageFromMask<int>(*
image->getMask(), makeAndMask(detected));
230 PTR(afw::detection::FootprintSet)
231 fs = std::make_shared<afw::detection::FootprintSet>(*mim, afw::detection::Threshold(1));
232 CONST_PTR(FootprintList) feet = fs->getFootprints();
234 if (feet->size() > 1) {
239 for (FootprintList::const_iterator fiter = feet->begin(); fiter != feet->end(); ++fiter) {
241 if (foot->contains(cen)) {
246 auto bigSpan = foot->getSpans()->dilated(ngrow)->clippedTo(
image->getBBox());
247 bigSpan->clearMask(*
image->getMask(), detected);
248 bigSpan->setMask(*
image->getMask(), intrp);
253 if (_pixelThreshold > 0.0) {
255 fpSet = std::make_shared<afw::detection::FootprintSet>(
257 for (FootprintList::const_iterator fpIter = fpSet->getFootprints()->begin();
258 fpIter != fpSet->getFootprints()->end(); ++fpIter) {
260 if (!fp->contains(cen)) {
261 fp->getSpans()->clearMask(*
image->getMask(), detected);
262 fp->getSpans()->setMask(*
image->getMask(), intrp);
275 template <
typename PixelT>
276 CONST_PTR(afw::image::MaskedImage<PixelT>)
278 if (!_image || (width != _image->getWidth() || height != _image->getHeight())) {
279 _image = extractImage(width, height);
289 template <
typename PixelT>
292 int const width = getWidth() == 0 ? _defaultWidth : getWidth();
293 int const height = getHeight() == 0 ? _defaultWidth : getHeight();
294 return getMaskedImage(width, height);
297 template <
typename PixelT>
302 template <
typename PixelT>
307 template <
typename PixelT>
309 _pixelThreshold = threshold;
312 template <
typename PixelT>
314 return _pixelThreshold;
317 template <
typename PixelT>
319 _doMaskBlends = doMaskBlends;
322 template <
typename PixelT>
324 return _doMaskBlends;
332 template <
typename PixelT>
337 unsigned int const width = getWidth() == 0 ? _defaultWidth : getWidth();
338 unsigned int const height = getHeight() == 0 ? _defaultWidth : getHeight();
339 if (_offsetImage &&
static_cast<unsigned int>(_offsetImage->getWidth()) == width + 2 * buffer &&
340 static_cast<unsigned int>(_offsetImage->getHeight()) == height + 2 * buffer) {
346 double const xcen = getXCenter(), ycen = getYCenter();