20 template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
23 template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
27 template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
30 template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
33 template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
36 template <
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
56 const itype nil = 0xffff;
64 foot->getSpans()->setImage(*argmin, static_cast<itype>(i));
65 foot->getSpans()->setImage(*dist, static_cast<dtype>(1));
70 int const height = dist->getHeight();
71 int const width = dist->getWidth();
74 for (
int y = 0;
y != height; ++
y) {
77 for (
int x = 0;
x != width; ++
x, ++dim.x(), ++aim.x()) {
85 dim(0, 0) = width + height;
89 dtype ndist = dim(0,-1) + 1;
90 if (ndist < dim(0,0)) {
97 dtype ndist = dim(-1,0) + 1;
98 if (ndist < dim(0,0)) {
100 aim(0,0) = aim(-1,0);
107 for (
int y = height - 1;
y >= 0; --
y) {
110 for (
int x = width - 1;
x >= 0; --
x, --dim.x(), --aim.x()) {
113 if (y + 1 < height) {
114 dtype ndist = dim(0,1) + 1;
115 if (ndist < dim(0,0)) {
122 dtype ndist = dim(1,0) + 1;
123 if (ndist < dim(0,0)) {
146 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
152 int S = halfsize*2 + 1;
155 xy_loc pix = img.
xy_at(halfsize,halfsize);
157 for (
int i=0; i<S; ++i) {
158 for (
int j=0; j<S; ++j) {
159 locs.
push_back(pix.cache_location(j-halfsize, i-halfsize));
164 ImagePixelT vals[S*S];
165 for (
int y=halfsize;
y<H-halfsize; ++
y) {
168 inpix !=
end; ++inpix.x(), ++optr) {
169 for (
int i=0; i<SS; ++i)
170 vals[i] = inpix[locs[i]];
177 for (
int y=0;
y<2*halfsize; ++
y) {
180 iy = H - 1 - (
y-halfsize);
183 for (; iptr !=
end; ++iptr,++optr)
186 for (
int y=halfsize;
y<H-halfsize; ++
y) {
189 for (; iptr !=
end; ++iptr,++optr)
194 for (; iptr !=
end; ++iptr,++optr)
224 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
231 int cx = peak.
getIx();
232 int cy = peak.
getIy();
233 int ix0 = img.
getX0();
234 int iy0 = img.
getY0();
247 for (s = 0; s <
std::max(DW,DH); s += S) {
249 for (p=0; p<S; p++) {
289 for (
int i=0; i<(8*L); i++, x += dx, y += dy) {
293 if (i % (2*L) == 0) {
296 dx = ( leg % 2) * (-1 + 2*(leg/2));
298 dy = ((leg+1) % 2) * ( 1 - 2*(leg/2));
301 int px = cx + x - ix0;
302 int py = cy + y - iy0;
304 if (px < 0 || px >= iW || py < 0 || py >= iH)
307 ImagePixelT pix = (*shadowingImg)(px,py);
314 const double A = 0.3;
320 ds0 = (double(y) / double(x)) - A;
323 for (shx=1; shx<=S; shx++) {
324 int xsign = (x>0?1:-1);
326 psx = cx + x + (xsign*shx) - ix0;
327 if (psx < 0 || psx >= iW)
330 for (shy = lround(shx * ds0);
331 shy <= lround(shx * ds1); shy++) {
332 psy = cy + y + xsign*shy - iy0;
333 if (psy < 0 || psy >= iH)
335 img(psx, psy) =
std::min(img(psx, psy), pix);
341 ds0 = (double(x) / double(y)) - A;
344 for (shy=1; shy<=S; shy++) {
345 int ysign = (y>0?1:-1);
346 psy = cy + y + (ysign*shy) - iy0;
347 if (psy < 0 || psy >= iH)
350 for (shx = lround(shy * ds0);
351 shx <= lround(shy * ds1); shx++) {
352 psx = cx + x + ysign*shx - ix0;
353 if (psx < 0 || psx >= iW)
355 img(psx, psy) =
std::min(img(psx, psy), pix);
361 shadowingImg->assign(img);
365 static double _get_contrib_r_to_footprint(
int x,
int y,
371 int dx = sp.getX0() - x;
384 int dy = sp.getY() - y;
385 minr2 =
std::min(minr2, (
double)(mindx*mindx + dy*dy));
388 return 1. / (1. + minr2);
392 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
398 int strayFluxOptions,
403 double clipStrayFluxFraction,
418 int ix0 = img.
getX0();
419 int iy0 = img.
getY0();
424 for (
size_t i=0; i<tfoots.size(); ++i) {
431 bool always = (strayFluxOptions & STRAYFLUX_TO_POINT_SOURCES_ALWAYS);
436 if (strayFluxOptions & STRAYFLUX_NEAREST_FOOTPRINT) {
446 if (!always && ispsf.
size()) {
449 auto empty = std::make_shared<det::Footprint>();
451 for (
size_t i=0; i<tfoots.size(); ++i) {
458 footlist = &templist;
460 nearestFootprint(*footlist, nearest, dist);
470 tsum->row_begin(y - sumy0) + (x0 - sumx0);
473 double contrib[tfoots.size()];
475 for (
int x = x0; x <= x1; ++x, ++tsum_it, ++in_it) {
479 if ((*tsum_it > 0) || (*in_it).image() <= 0) {
483 if (strayFluxOptions & STRAYFLUX_R_TO_FOOTPRINT) {
485 for (
size_t i=0; i<tfoots.size(); ++i) {
488 }
else if (strayFluxOptions & STRAYFLUX_NEAREST_FOOTPRINT) {
489 for (
size_t i=0; i<tfoots.size(); ++i) {
492 int i = nearest->get0(x, y);
496 for (
size_t i=0; i<tfoots.size(); ++i) {
501 contrib[i] = 1. / (1. + dx*dx + dy*dy);
507 bool ptsrcs = always;
509 for (
size_t i=0; i<tfoots.size(); ++i) {
511 if ((!ptsrcs) && ispsf.
size() && ispsf[i]) {
514 if (contrib[i] == -1.0) {
515 contrib[i] = _get_contrib_r_to_footprint(x, y, tfoots[i]);
521 STRAYFLUX_TO_POINT_SOURCES_WHEN_NECESSARY)) {
525 for (
size_t i=0; i<tfoots.size(); ++i) {
526 if (contrib[i] == -1.0) {
527 contrib[i] = _get_contrib_r_to_footprint(x, y, tfoots[i]);
534 double strayclip = (clipStrayFluxFraction * csum);
536 for (
size_t i=0; i<tfoots.size(); ++i) {
538 if ((!ptsrcs) && ispsf.
size() && ispsf[i]) {
543 if (contrib[i] < strayclip) {
550 for (
size_t i=0; i<tfoots.size(); ++i) {
551 if (contrib[i] == 0.) {
555 double p = (contrib[i] / csum) * (*in_it).image();
558 strayfoot[i] = std::make_shared<det::Footprint>();
564 strayvar[i].
push_back((*in_it).variance());
570 for (
size_t i=0; i<tfoots.size(); ++i) {
572 strayfoot[i]->setSpans(std::make_shared<afwGeom::SpanSet>(straySpans[i]));
580 HeavyFootprintPtrT heavy(
new HeavyFootprint(*strayfoot[i]));
581 ndarray::Array<ImagePixelT,1,1> himg = heavy->getImageArray();
585 typename ndarray::Array<ImagePixelT,1,1>::Iterator hpix;
586 typename ndarray::Array<MaskPixelT,1,1>::Iterator mpix;
587 typename ndarray::Array<VariancePixelT,1,1>::Iterator vpix;
589 assert((
size_t)strayfoot[i]->getArea() == straypix[i].size());
591 for (spix = straypix[i].begin(),
592 smask = straymask[i].begin(),
593 svar = strayvar [i].begin(),
595 mpix = heavy->getMaskArray().begin(),
596 vpix = heavy->getVarianceArray().begin();
597 spix != straypix[i].
end();
598 ++spix, ++smask, ++svar, ++hpix, ++mpix, ++vpix) {
608 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
618 for (
size_t i=0; i<timgs.
size(); ++i) {
634 tsum->row_begin(y - sumy0) + (copyx0 - sumx0);
635 for (; in_it != inend; ++in_it, ++tsum_it) {
636 *tsum_it +=
std::max((ImagePixelT)0., static_cast<ImagePixelT>(*in_it));
691 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
703 int strayFluxOptions,
704 double clipStrayFluxFraction
707 if (timgs.
size() != tfoots.size()) {
709 (boost::format(
"Template images must be the same length as template footprints (%d vs %d)")
710 % timgs.
size() % tfoots.size()).str());
713 for (
size_t i=0; i<timgs.
size(); ++i) {
714 if (!timgs[i]->getBBox().contains(tfoots[i]->getBBox())) {
716 "Template image MUST contain template footprint");
720 "Image bbox MUST contain parent footprint");
730 LOG_LOGGER _log =
LOG_GET(
"meas.deblender.apportionFlux");
731 bool findStrayFlux = (strayFluxOptions & ASSIGN_STRAYFLUX);
733 int ix0 = img.
getX0();
734 int iy0 = img.
getY0();
742 if (!tsum->getBBox().contains(foot.
getBBox())) {
744 "Template sum image MUST contain parent footprint");
751 _sum_templates(timgs, tsum);
754 for (
size_t i=0; i<timgs.
size(); ++i) {
758 port->setXY0(timg->getXY0());
772 timg->row_begin(y - ty0) + (copyx0 - tx0);
775 tsum->row_begin(y - sumy0) + (copyx0 - sumx0);
777 port->row_begin(y - ty0) + (copyx0 - tx0);
778 for (; tptr != tend; ++tptr, ++in_it, ++out_it, ++tsum_it) {
782 double frac =
std::max((ImagePixelT)0., static_cast<ImagePixelT>(*tptr)) / (*tsum_it);
786 out_it.mask() = (*in_it).mask();
787 out_it.variance() = (*in_it).variance();
788 out_it.image() = (*in_it).image() * frac;
794 if ((ispsf.size() > 0) && (ispsf.size() != timgs.
size())) {
796 (boost::format(
"'ispsf' must be the same length as templates (%d vs %d)")
797 % ispsf.size() % timgs.
size()).str());
799 if ((pkx.size() != timgs.
size()) || (pky.size() != timgs.
size())) {
801 (boost::format(
"'pkx' and 'pky' must be the same length as templates (%d,%d vs %d)")
802 % pkx.size() % pky.size() % timgs.
size()).str());
804 _find_stray_flux(foot, tsum, img, strayFluxOptions, tfoots,
805 ispsf, pkx, pky, clipStrayFluxFraction, strays);
827 int cx,
int cy,
bool forward=
true)
828 : _real(real), _cx(cx), _cy(cy), _forward(forward)
838 return _real == other;
841 return _real != other;
844 return _real <= other;
847 return _real < other;
850 return _real >= other;
853 return _real > other;
857 return (_real == other._real) &&
858 (_cx == other._cx) && (_cy == other._cy) &&
859 (_forward == other._forward);
862 return !(*
this == other);
883 return _real >= _end;
889 return _real->getX0() - _cx;
891 return _cx - _real->getX1();
896 return _real->getX1() - _cx;
898 return _cx - _real->getX0();
902 return std::abs(_real->getY() - _cy);
905 return _real->getX0();
908 return _real->getX1();
911 return _real->getY();
973 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
980 auto sfoot = std::make_shared<det::Footprint>();
984 LOG_LOGGER _log =
LOG_GET(
"meas.deblender.symmetrizeFootprint");
995 if (peakspan == spans.
begin()) {
997 if (!sp.contains(cx, cy)) {
999 "Failed to find span containing (%i,%i): before the beginning of this footprint", cx, cy);
1006 if (!sp.contains(cx, cy)) {
1009 if (!sp.contains(cx, cy)) {
1011 LOGL_WARN(_log,
"Failed to find span containing (%i,%i): nearest is %i, [%i,%i]. " 1012 "Footprint bbox is [%i,%i],[%i,%i]",
1013 cx, cy, sp.getY(), sp.getX0(), sp.getX1(),
1019 LOGL_DEBUG(_log,
"Span containing (%i,%i): (x=[%i,%i], y=%i)",
1020 cx, cy, sp.getX0(), sp.getX1(), sp.getY());
1055 while (fwd.notDone() && back.
notDone()) {
1060 int fdxlo = fwd.dxlo();
1061 int bdxlo = back.
dxlo();
1068 for (fend = fwd; fend.
notDone(); ++fend) {
1069 if (fend.
dy() != dy)
1072 for (bend = back; bend.
notDone(); ++bend) {
1073 if (bend.
dy() != dy)
1077 LOGL_DEBUG(_log,
"dy=%i, fy=%i, fx=[%i, %i], by=%i, fx=[%i, %i], fdx=%i, bdx=%i",
1078 dy, fy, fwd.x0(), fwd.x1(), by, back.
x0(), back.
x1(),
1082 if (bdxlo > fdxlo) {
1087 while ((fwd != fend) && (fwd.dxhi() < bdxlo)) {
1092 LOGL_DEBUG(_log,
"Advanced to forward span %i, [%i, %i]",
1093 fy, fwd.x0(), fwd.x1());
1096 }
else if (fdxlo > bdxlo) {
1101 while ((back != bend) && (back.
dxhi() < fdxlo)) {
1106 LOGL_DEBUG(_log,
"Advanced to backward span %i, [%i, %i]",
1107 by, back.
x0(), back.
x1());
1112 if ((back == bend) || (fwd == fend)) {
1131 LOGL_DEBUG(_log,
"Adding span fwd %i, [%i, %i], back %i, [%i, %i]",
1132 fy, cx+dxlo, cx+dxhi, by, cx-dxhi, cx-dxlo);
1138 if (fwd.dxhi() < back.
dxhi()) {
1143 LOGL_DEBUG(_log,
"Stepped forward to span %i, [%i, %i]",
1144 fwd.y(), fwd.x0(), fwd.x1());
1151 LOGL_DEBUG(_log,
"Stepped backward to span %i, [%i, %i]",
1152 back.
y(), back.
x0(), back.
x1());
1156 if ((back == bend) || (fwd == fend)) {
1171 sfoot->setSpans(std::make_shared<afwGeom::SpanSet>(
std::move(tmpSpans)));
1187 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
1198 bool* patchedEdges) {
1202 *patchedEdges =
false;
1204 int cx = peak.
getIx();
1205 int cy = peak.
getIy();
1207 LOG_LOGGER _log =
LOG_GET(
"meas.deblender.symmetricFootprint");
1221 "Image too small for symmetrized footprint");
1226 bool touchesEdge =
false;
1228 LOGL_DEBUG(_log,
"Checking footprint for EDGE bits");
1231 MaskPixelT edgebit = mask->getPlaneBitMask(
"EDGE");
1233 fwd != spans.
end(); ++fwd) {
1234 int x0 = fwd->getX0();
1235 int x1 = fwd->getX1();
1237 mask->x_at(x0 - mask->getX0(), fwd->getY() - mask->getY0());
1238 for (
int x=x0; x<=x1; ++x, ++xiter) {
1239 if ((*xiter) & edgebit) {
1248 LOGL_DEBUG(_log,
"Footprint includes an EDGE pixel.");
1261 for (; fwd <= back; fwd++, back--) {
1262 int fy = fwd->getY();
1263 int by = back->getY();
1265 for (
int fx=fwd->getX0(), bx=back->getX1();
1274 assert(theimg->getBBox(image::PARENT).contains(
geom::Point2I(fx, fy)));
1275 assert(theimg->getBBox(image::PARENT).contains(
geom::Point2I(bx, by)));
1280 ImagePixelT pixf = theimg->get0(fx, fy);
1281 ImagePixelT pixb = theimg->get0(bx, by);
1282 ImagePixelT pix =
std::min(pixf, pixb);
1284 pix =
std::max(pix, static_cast<ImagePixelT>(0));
1286 targetimg->set0(fx, fy, pix);
1287 targetimg->set0(bx, by, pix);
1303 LOGL_DEBUG(_log,
"Footprint touches EDGE: start bbox [%i,%i],[%i,%i]",
1307 for (fwd = ospans.begin(); fwd != ospans.end(); ++fwd) {
1308 int y = fwd->getY();
1309 int x = fwd->getX0();
1311 int ym = cy + (cy - y);
1312 int xm = cx + (cx - x);
1322 LOGL_DEBUG(_log,
"Footprint touches EDGE: grown bbox [%i,%i],[%i,%i]",
1327 sfoot->getSpans()->copyImage(*targetimg, *targetimg2);
1329 LOGL_DEBUG(_log,
"Symmetric footprint spans:");
1331 for (fwd = sspans.
begin(); fwd != sspans.
end(); ++fwd) {
1332 LOGL_DEBUG(_log,
" %s", fwd->toString().c_str());
1338 for (fwd = ospans.begin(); fwd != ospans.end(); ++fwd) {
1339 int y = fwd->getY();
1340 int x0 = fwd->getX0();
1341 int x1 = fwd->getX1();
1343 int ym = cy + (cy - y);
1344 int xm0 = cx + (cx - x0);
1345 int xm1 = cx + (cx - x1);
1356 x0 = cx + (cx - (imbb.
getMinX() - 1));
1359 x1 = cx + (cx - (imbb.
getMaxX() + 1));
1361 LOGL_DEBUG(_log,
"Span y=%i, x=[%i,%i] has mirror (%i,[%i,%i]) out-of-bounds; clipped to %i,[%i,%i]",
1362 y, fwd->getX0(), fwd->getX1(), ym, xm1, xm0, y, x0, x1);
1366 targetimg2->x_at(x0 - targetimg2->getX0(), y - targetimg2->getY0());
1367 for (
int x=x0; x<=x1; ++x, ++outiter, ++initer) {
1368 *outiter = initer.
image();
1372 sfoot->setSpans(std::make_shared<afwGeom::SpanSet>(
std::move(newSpans)));
1373 targetimg = targetimg2;
1376 *patchedEdges = touchesEdge;
1384 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
1389 ImagePixelT thresh) {
1391 LOG_LOGGER _log =
LOG_GET(
"meas.deblender.hasSignificantFluxAtEdge");
1399 int const y = sp->getY();
1400 int const x0 = sp->getX0();
1401 int const x1 = sp->getX1();
1404 for (xiter = img->x_at(x0 - img->getX0(), y - img->getY0()), x=x0; x<=x1; ++x, ++xiter) {
1405 if (*xiter >= thresh) {
1417 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
1422 ImagePixelT thresh) {
1423 LOG_LOGGER _log =
LOG_GET(
"meas.deblender.getSignificantEdgePixels");
1426 auto significant = std::make_shared<det::Footprint>();
1429 int const x0 = img->getX0(), y0 = img->getY0();
1434 int const y = span.
getY();
1435 int x = span.
getX0();
1437 bool onSpan =
false;
1439 for (; x <= span.
getX1(); ++x, ++iter) {
1440 if (*iter >= thresh) {
1443 }
else if (onSpan) {
1452 significant->setSpans(std::make_shared<afwGeom::SpanSet>(
std::move(tmpSpans)));
static bool hasSignificantFluxAtEdge(ImagePtrT, std::shared_ptr< lsst::afw::detection::Footprint >, ImagePixelT threshold)
Returns true if the given Footprint sfoot in image img has flux above value thresh at its edge...
Extent2I const getDimensions() const noexcept
Key< Flag > const & target
static std::shared_ptr< lsst::afw::detection::Footprint > getSignificantEdgePixels(ImagePtrT, std::shared_ptr< lsst::afw::detection::Footprint >, ImagePixelT threshold)
Returns a list of pixels that are on the edge of the given Footprint sfoot* in image img...
bool operator<(const SpanSet::const_iterator &other)
const_iterator end() const
_const_view_t::x_iterator const_x_iterator
bool operator==(RelativeSpanIterator &other)
bool operator!=(const SpanSet::const_iterator &other)
_view_t::x_iterator x_iterator
static void _find_stray_flux(lsst::afw::detection::Footprint const &foot, ImagePtrT tsum, MaskedImageT const &img, int strayFluxOptions, std::vector< std::shared_ptr< lsst::afw::detection::Footprint > > tfoots, std::vector< bool > const &ispsf, std::vector< int > const &pkx, std::vector< int > const &pky, double clipStrayFluxFraction, std::vector< std::shared_ptr< typename lsst::afw::detection::HeavyFootprint< ImagePixelT, MaskPixelT, VariancePixelT > > > &strays)
boost::shared_ptr< lsst::afw::detection::Footprint > FootprintPtrT
bool operator==(const SpanSet::const_iterator &other)
const_iterator begin() const
RelativeSpanIterator(SpanSet::const_iterator const &real, SpanSet const &arr, int cx, int cy, bool forward=true)
static boost::shared_ptr< lsst::afw::detection::Footprint > symmetrizeFootprint(lsst::afw::detection::Footprint const &foot, int cx, int cy)
Given a Footprint foot and peak cx,cy, returns a Footprint that is symmetric around the peak (with tw...
x_iterator row_begin(int y) const
x_iterator x_at(int x, int y) const
ImagePtr getImage() const
static void medianFilter(ImageT const &img, ImageT &outimg, int halfsize)
Run a spatial median filter over the given input img, writing the results to out. ...
bool operator>=(const SpanSet::const_iterator &other)
boost::shared_ptr< lsst::afw::image::Mask< MaskPixelT > > MaskPtrT
int getMaxY() const noexcept
x_iterator row_begin(int y) const
int getWidth() const noexcept
Reference< ImagePixelT >::type image()
int getMaxX() const noexcept
std::unique_ptr< SchemaItem< U > > result
int getMinX() const noexcept
static void makeMonotonic(ImageT &img, lsst::afw::detection::PeakRecord const &pk)
Given an image mimg and Peak location peak, overwrite mimg so that pixels further from the peak have ...
#define LSST_EXCEPT(type,...)
def apportionFlux(debResult, log, assignStrayFlux=True, strayFluxAssignment='r-to-peak', strayFluxToPointSources='necessary', clipStrayFluxFraction=0.001, getTemplateSum=False)
std::vector< Span >::const_iterator const_iterator
void include(Point2I const &point)
This is a convenience class used in symmetrizeFootprint, wrapping the idea of iterating through a Spa...
static void _sum_templates(std::vector< ImagePtrT > timgs, ImagePtrT tsum)
bool contains(Point2I const &point) const noexcept
void clip(Box2I const &other) noexcept
#define LOGL_DEBUG(logger, message...)
x_iterator row_end(int y) const
bool operator!=(RelativeSpanIterator &other)
int getX1() const noexcept
int getY() const noexcept
static std::pair< ImagePtrT, FootprintPtrT > buildSymmetricTemplate(MaskedImageT const &img, lsst::afw::detection::Footprint const &foot, lsst::afw::detection::PeakRecord const &pk, double sigma1, bool minZero, bool patchEdges, bool *patchedEdges)
Given an img, footprint foot, and peak, creates a symmetric template around the peak; produce a Maske...
RelativeSpanIterator operator++()
RelativeSpanIterator operator++(int dummy)
lsst::geom::Box2I getBBox(ImageOrigin const origin=PARENT) const
_view_t::xy_locator xy_locator
#define LOGL_WARN(logger, message...)
boost::shared_ptr< lsst::afw::image::MaskedImage< ImagePixelT > MaskPixelT, VariancePixelT > MaskedImagePtrT
xy_locator xy_at(int x, int y) const
bool operator>(const SpanSet::const_iterator &other)
bool operator<=(const SpanSet::const_iterator &other)
int getMinY() const noexcept
boost::shared_ptr< lsst::afw::detection::HeavyFootprint< ImagePixelT > MaskPixelT, VariancePixelT > HeavyFootprintPtrT
int getX0() const noexcept
boost::shared_ptr< lsst::afw::image::Image< ImagePixelT > > ImagePtrT