32 #include "boost/format.hpp"
49 #include <boost/archive/text_iarchive.hpp>
50 #include <boost/archive/text_oarchive.hpp>
51 #include <boost/archive/xml_iarchive.hpp>
52 #include <boost/archive/xml_oarchive.hpp>
53 #include <boost/archive/binary_iarchive.hpp>
54 #include <boost/archive/binary_oarchive.hpp>
55 #include <boost/serialization/shared_ptr.hpp>
56 #include <boost/serialization/vector.hpp>
58 using boost::serialization::make_nvp;
72 struct compareSpanByYX :
73 public std::binary_function<Span::ConstPtr, Span::ConstPtr, bool> {
74 int operator()(Span::ConstPtr a, Span::ConstPtr
b) {
96 ) : lsst::daf::base::Citizen(typeid(this)),
105 lsst::pex::exceptions::InvalidParameterError,
106 str(
boost::format(
"Number of spans requested is -ve: %d") % nspan));
113 ) : lsst::daf::base::Citizen(typeid(this)),
124 for (
int i = y0; i <= y1; ++i) {
134 ) : lsst::daf::base::Citizen(typeid(this)),
140 int const r2 =
static_cast<int>(radius*radius + 0.5);
141 int const r =
static_cast<int>(std::sqrt(static_cast<double>(r2)));
143 for (
int i = -r; i <= r; ++i) {
144 int hlen =
static_cast<int>(std::sqrt(static_cast<double>(r2 - i*i)));
145 addSpan(center.getY() + i, center.getX() - hlen, center.getX() + hlen);
151 geom::ellipses::Ellipse
const & ellipse,
153 ) : lsst::daf::base::Citizen(typeid(this)),
156 _bbox(geom::Box2I()),
160 geom::ellipses::PixelRegion pr(ellipse);
162 geom::ellipses::PixelRegion::Iterator spanIter = pr.begin(), end = pr.end();
166 if (!spanIter->isEmpty()) {
174 Footprint::SpanList
const & spans,
176 ) : lsst::daf::base::Citizen(typeid(this)),
179 _bbox(geom::Box2I()),
183 _spans.reserve(spans.size());
184 for(SpanList::const_iterator i(spans.begin()); i != spans.end(); ++i) {
190 : lsst::daf::base::Citizen(typeid(this)),
193 _region(other._region)
196 _spans.reserve(other._spans.size());
197 for(SpanList::const_iterator i(other._spans.begin());
198 i != other._spans.end(); ++i
203 _normalized = other._normalized;
206 _peaks.reserve(other._peaks.size());
207 for(PeakList::const_iterator i(other._peaks.begin()); i != other._peaks.end(); ++i) {
208 _peaks.push_back(
PTR(Peak)(
new Peak(**i)));
212 Footprint::~Footprint() {
215 bool Footprint::contains(
220 for (Footprint::SpanList::const_iterator siter = _spans.begin(); siter != _spans.end(); ++siter) {
221 if ((*siter)->contains(pix.getX(), pix.getY())) {
231 Footprint::SpanList::iterator it = _spans.begin();
232 for (; it != _spans.end();) {
233 Span *sp = it->get();
234 if ((sp->getY() < bbox.
getMinY()) ||
235 (sp->getY() > bbox.
getMaxY())) {
237 it = _spans.erase(it);
240 if ((sp->getX0() > bbox.
getMaxX()) ||
241 (sp->getX1() < bbox.
getMinX())) {
243 it = _spans.erase(it);
247 if (sp->getX0() < bbox.
getMinX()) {
251 if (sp->getX1() > bbox.
getMaxX()) {
258 Footprint::PeakList::iterator pit = _peaks.begin();
259 for (; pit != _peaks.end();) {
260 Peak *pk = pit->get();
262 pit = _peaks.erase(pit);
268 if (_spans.empty()) {
282 assert(!_spans.empty());
287 sort(_spans.begin(), _spans.end(), compareSpanByYX());
289 Footprint::SpanList::iterator ptr = _spans.begin(), end = _spans.end();
290 Span *lspan = ptr->get();
293 _area = lspan->getWidth();
294 int minX = lspan->_x0, minY=
y, maxX=x1;
298 for (; ptr != end; ++ptr) {
299 Span *rspan = ptr->get();
300 if (rspan->_y == y) {
301 if (rspan->_x0 <= x1 + 1) {
302 if (rspan->_x1 > x1) {
304 _area += rspan->_x1 - x1;
306 x1 = lspan->_x1 = rspan->_x1;
308 if(x1 > maxX) maxX = x1;
311 ptr = _spans.erase(ptr);
321 _area += rspan->getWidth();
322 if(rspan->_x1 > maxX) maxX = rspan->_x1;
325 _area += rspan->getWidth();
332 if(lspan->_x0 < minX) minX = lspan->_x0;
333 if(x1 > maxX) maxX = x1;
340 Span
const& Footprint::addSpan(
346 return addSpan(y, x1, x0);
349 PTR(Span) sp(new Span(y, x0, x1));
350 _spans.push_back(sp);
352 _area += sp->getWidth();
364 return addSpan(span._y, span._x0, span._x1);
367 const Span& Footprint::addSpan(
372 return addSpan(span._y + dy, span._x0 + dx, span._x1 + dx);
375 const Span& Footprint::addSpanInSeries(
381 return addSpanInSeries(y, x1, x0);
383 if (_spans.size() == 0) {
384 const Span& s = addSpan(y, x0, x1);
389 PTR(Span) lastspan = _spans.back();
390 if ((y == lastspan->getY()) &&
391 (x0 == (lastspan->getX1() + 1))) {
394 _area += (1 + x1 - x0);
398 if (!((y > lastspan->getY()) ||
399 (x0 > (lastspan->getX1() + 1)))) {
401 lsst::pex::exceptions::InvalidParameterError,
402 str(
boost::format(
"addSpanInSeries: new span %i,[%i,%i] is NOT in series after last span "
404 y % x0 % x1 % lastspan->getY() % lastspan->getX0() % lastspan->getX1()));
406 const Span& s = addSpan(y, x0, x1);
415 for (SpanList::iterator i = _spans.begin(); i != _spans.end(); ++i){
430 double xc = 0, yc = 0;
431 for (Footprint::SpanList::const_iterator siter = _spans.begin(); siter != _spans.end(); ++siter) {
433 int const y = span->getY();
434 int const x0 = span->getX0();
435 int const x1 = span->getX1();
436 int const npix = x1 - x0 + 1;
439 xc += npix*0.5*(x1 + x0);
444 return geom::
Point2D(xc/_area, yc/_area);
447 geom::ellipses::Quadrupole
451 double const xc = cen.getX();
452 double const yc = cen.getY();
454 double sumxx = 0, sumxy = 0, sumyy = 0;
455 for (Footprint::SpanList::const_iterator siter = _spans.begin(); siter != _spans.end(); ++siter) {
457 int const y = span->getY();
458 int const x0 = span->getX0();
459 int const x1 = span->getX1();
460 int const npix = x1 - x0 + 1;
462 for (
int x = x0;
x <= x1; ++
x) {
463 sumxx += (
x - xc)*(
x - xc);
465 sumxy += npix*(0.5*(x1 + x0) - xc)*(y - yc);
466 sumyy += npix*(y - yc)*(y - yc);
469 return geom::ellipses::Quadrupole(sumxx/_area, sumyy/_area, sumxy/_area);
479 template<
bool overwriteId,
typename PixelT>
482 Footprint::SpanList
const& _spans,
484 boost::uint64_t
const id,
487 std::set<boost::uint64_t> *oldIds=NULL
490 int width, height, x0, y0;
504 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
506 "Footprint's host Image of size (%dx%d)") %
511 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
512 str(
boost::format(
"Id 0x%x sets bits in the protected mask 0x%x") %
id % mask));
515 typename std::set<boost::uint64_t>::const_iterator pos;
517 pos = oldIds->begin();
519 for (Footprint::SpanList::const_iterator spi = _spans.begin(); spi != _spans.end(); ++spi) {
522 int const sy0 = span->getY() - y0;
523 if (sy0 < 0 || sy0 >= height) {
527 int sx0 = span->getX0() - x0;
531 int sx1 = span->getX1() - x0;
532 int const swidth = (sx1 >= width) ? width - sx0 : sx1 - sx0 + 1;
535 end = ptr + swidth; ptr != end; ++ptr) {
537 long val = *ptr & ~mask;
538 if (val != 0 and oldIds != NULL) {
539 pos = oldIds->insert(pos, val);
541 *ptr = (*ptr & mask) +
id;
550 template<
typename PixelT>
554 int const ix0 = img.
getX0();
555 int const iy0 = img.
getY0();
558 for (SpanList::iterator s = _spans.begin(); s < _spans.end(); ++s) {
559 int const y = (*s)->getY();
560 int const x0 = (*s)->getX0();
561 int const x1 = (*s)->getX1();
562 typename ImageT::x_iterator img_it = img.
row_begin(y - iy0) + (x0 - ix0);
565 for (leftx = x0; leftx <= x1; ++leftx, ++img_it) {
566 if (*img_it != zero) {
578 img_it = img.
row_begin(y - iy0) + (x1 - ix0);
579 for (rightx = x1; rightx >= leftx; --rightx, --img_it) {
580 if (*img_it != zero) {
594 if (_spans.empty()) {
601 template<
typename PixelT>
603 Footprint::insertIntoImage(
605 boost::uint64_t
const id,
609 static_cast<void>(doInsertIntoImage<false>(_region, _spans, idImage,
id, region));
612 template<
typename PixelT>
614 Footprint::insertIntoImage(
616 boost::uint64_t
const id,
619 std::set<boost::uint64_t> *oldIds,
625 lsst::pex::exceptions::OutOfRangeError,
626 "id out of range for image type"
630 doInsertIntoImage<true>(_region, _spans, idImage,
id, region, mask, oldIds);
632 doInsertIntoImage<false>(_region, _spans, idImage,
id, region, mask, oldIds);
637 class FootprintFactory :
public table::io::PersistableFactory {
640 virtual PTR(table::io::Persistable)
641 read(InputArchive const & archive, CatalogVector const & catalogs)
const {
644 result->readSpans(catalogs.front());
645 result->readPeaks(catalogs.back());
649 explicit FootprintFactory(std::
string const & name) : table::io::PersistableFactory(name) {}
656 class FootprintPersistenceHelper :
private boost::noncopyable {
667 static FootprintPersistenceHelper
const &
get() {
668 static FootprintPersistenceHelper instance;
673 FootprintPersistenceHelper() :
675 spanY(spanSchema.addField<int>(
"y",
"row position of span",
"pixels")),
676 spanX0(spanSchema.addField<int>(
"x0",
"first column of span (inclusive)",
"pixels")),
677 spanX1(spanSchema.addField<int>(
"x1",
"first column of span (inclusive)",
"pixels")),
679 peakX(peakSchema.addField<float>(
"x",
"column position of peak",
"pixels")),
680 peakY(peakSchema.addField<float>(
"y",
"column position of peak",
"pixels")),
681 peakValue(peakSchema.addField<float>(
"value",
"value of peak pixel",
"pixels"))
683 spanSchema.getCitizen().markPersistent();
684 peakSchema.getCitizen().markPersistent();
688 std::string getFootprintPersistenceName() {
return "Footprint"; }
692 FootprintFactory registration(getFootprintPersistenceName());
696 std::string Footprint::getPersistenceName()
const {
return getFootprintPersistenceName(); }
698 std::string Footprint::getPythonModule()
const {
return "lsst.afw.detection"; }
700 void Footprint::write(OutputArchiveHandle & handle)
const {
701 FootprintPersistenceHelper
const & keys = FootprintPersistenceHelper::get();
703 spanCat.reserve(_spans.size());
704 for (SpanList::const_iterator i = _spans.begin(); i != _spans.end(); ++i) {
705 PTR(afw::table::BaseRecord)
record = spanCat.addNew();
706 record->set(keys.spanY, (**i).getY());
707 record->set(keys.spanX0, (**i).getX0());
708 record->set(keys.spanX1, (**i).getX1());
710 handle.saveCatalog(spanCat);
711 afw::table::
BaseCatalog peakCat = handle.makeCatalog(keys.peakSchema);
712 peakCat.reserve(_peaks.size());
713 for (PeakList::const_iterator i = _peaks.begin(); i != _peaks.end(); ++i) {
714 PTR(afw::table::BaseRecord)
record = peakCat.addNew();
715 record->set(keys.peakX, (**i).getFx());
716 record->set(keys.peakY, (**i).getFy());
717 record->set(keys.peakValue, (**i).getPeakValue());
719 handle.saveCatalog(peakCat);
723 FootprintPersistenceHelper
const & keys = FootprintPersistenceHelper::get();
725 addSpan(i->get(keys.spanY), i->get(keys.spanX0), i->get(keys.spanX1));
730 FootprintPersistenceHelper
const & keys = FootprintPersistenceHelper::get();
733 boost::make_shared<Peak>(i->get(keys.peakX), i->get(keys.peakY), i->get(keys.peakValue))
738 template <
typename Archive>
739 void Footprint::serialize(Archive & ar,
const unsigned int version) {
740 ar & make_nvp(
"spans", _spans);
741 ar & make_nvp(
"peaks", _peaks);
742 ar & make_nvp(
"area", _area);
743 ar & make_nvp(
"normalized", _normalized);
745 int x0, y0, width, height;
746 int rx0, ry0, rwidth, rheight;
747 if(Archive::is_saving::value) {
761 ar & make_nvp(
"x0", x0) & make_nvp(
"y0", y0) & make_nvp(
"width", width) & make_nvp(
"height", height);
762 ar & make_nvp(
"rx0", rx0) & make_nvp(
"ry0", ry0) & make_nvp(
"rwidth", rwidth)
763 & make_nvp(
"rheight", rheight);
765 if(Archive::is_loading::value) {
771 template void Footprint::serialize(boost::archive::text_oarchive &,
unsigned int const);
772 template void Footprint::serialize(boost::archive::text_iarchive &,
unsigned int const);
773 template void Footprint::serialize(boost::archive::xml_oarchive &,
unsigned int const);
774 template void Footprint::serialize(boost::archive::xml_iarchive &,
unsigned int const);
775 template void Footprint::serialize(boost::archive::binary_oarchive &,
unsigned int const);
776 template void Footprint::serialize(boost::archive::binary_iarchive &,
unsigned int const);
779 _region = other._region;
783 _spans.reserve(other._spans.size());
784 for(SpanList::const_iterator i(other._spans.begin());
785 i != other._spans.end(); ++i
790 _normalized = other._normalized;
795 _peaks.reserve(other._peaks.size());
796 for(PeakList::iterator i(other._peaks.begin()); i != other._peaks.end(); ++i) {
797 _peaks.push_back(
PTR(Peak)(
new Peak(**i)));
802 template<
typename MaskT>
803 void Footprint::intersectMask(
813 SpanList::iterator s(_spans.begin());
814 while((*s)->getY() < maskBBox.
getMinY() && s != _spans.end()){
820 SpanList maskedSpans;
822 for( ; s != _spans.end(); ++s) {
847 for(
int x = x0;
x <= x1; ++
x, ++mIter) {
848 if((*mIter & bitmask) != 0) {
854 PTR(Span) maskedSpan(new Span(y, x0,
x- 1));
855 maskedSpans.push_back(maskedSpan);
856 maskedArea += maskedSpan->getWidth();
865 PTR(Span) maskedSpan(new Span(y, x0, x1));
866 maskedSpans.push_back(maskedSpan);
867 maskedArea += maskedSpan->getWidth();
871 _spans = maskedSpans;
872 _bbox.clip(maskBBox);
879 geom::Box2I const& region,
897 for (
int y = tBoxI.getBeginY(); y < tBoxI.getEndY(); ++y) {
901 for (
int x = tBoxI.getBeginX(); x < tBoxI.getEndX(); ++
x) {
903 int const xSource = std::floor(0.5 + p.getX());
904 int const ySource = std::floor(0.5 + p.getY());
913 fpNew->addSpan(y, start, x - 1);
917 fpNew->addSpan(y, start, tBoxI.getMaxX());
921 fpNew->clipTo(region);
931 bool _checkNormalized(Footprint
const& foot) {
932 Footprint
copy(foot);
934 if (
copy.getArea() != foot.getArea()) {
937 if (
copy.getSpans().size() != foot.getSpans().size()) {
940 Footprint::SpanList
const& spansa = foot.getSpans();
941 Footprint::SpanList
const& spansb =
copy.getSpans();
942 Footprint::SpanList::const_iterator spa = spansa.begin();
943 Footprint::SpanList::const_iterator spb = spansb.begin();
944 for (; spa != spansa.end(); ++spa, ++spb) {
945 if ((*spa)->getY() != (*spb)->getY()) {
948 if ((*spa)->getX0() != (*spb)->getX0()) {
951 if ((*spa)->getX1() != (*spb)->getX1()) {
960 template<
typename MaskT>
962 PTR(Footprint) const& fp,
963 typename lsst::afw::
image::Mask<MaskT>::Ptr const& mask,
966 PTR(Footprint) newFp(new Footprint());
972 template<typename MaskT>
974 image::Mask<MaskT> *mask,
975 Footprint const& foot,
979 int const width =
static_cast<int>(mask->getWidth());
980 int const height =
static_cast<int>(mask->getHeight());
982 for (Footprint::SpanList::const_iterator siter = foot.getSpans().begin();
983 siter != foot.getSpans().end(); ++siter) {
985 int const y = span->getY() - mask->getY0();
986 if (y < 0 || y >= height) {
990 int x0 = span->getX0() - mask->getX0();
991 int x1 = span->getX1() - mask->getX0();
992 x0 = (x0 < 0) ? 0 : (x0 >= width ? width - 1 : x0);
993 x1 = (x1 < 0) ? 0 : (x1 >= width ? width - 1 : x1);
996 end = mask->x_at(x1 + 1, y); ptr != end; ++ptr) {
1006 template<
typename MaskT>
1009 Footprint
const& foot,
1012 int const width =
static_cast<int>(mask->
getWidth());
1013 int const height =
static_cast<int>(mask->
getHeight());
1015 for (Footprint::SpanList::const_iterator siter = foot.getSpans().begin();
1016 siter != foot.getSpans().end(); ++siter) {
1018 int const y = span->getY() - mask->getY0();
1019 if (y < 0 || y >= height) {
1024 int x1 = span->getX1() - mask->
getX0();
1025 x0 = (x0 < 0) ? 0 : (x0 >= width ? width - 1 : x0);
1026 x1 = (x1 < 0) ? 0 : (x1 >= width ? width - 1 : x1);
1029 end = mask->
x_at(x1 + 1, y); ptr != end; ++ptr) {
1039 template<
typename MaskT>
1042 std::vector<
PTR(Footprint)>
const& footprints,
1045 for (std::vector<
PTR(Footprint)>::const_iterator fiter = footprints.begin();
1046 fiter != footprints.end(); ++fiter) {
1055 template<
typename MaskT>
1058 CONST_PTR(std::vector<
PTR(Footprint)>)
const & footprints,
1066 template<
typename ImageT>
1067 class SetFootprint :
public FootprintFunctor<ImageT> {
1069 SetFootprint(ImageT
const&
image,
1070 typename ImageT::Pixel value) :
1071 FootprintFunctor<ImageT>(image), _value(value) {}
1074 void operator()(
typename ImageT::xy_locator loc,
int,
int) {
1078 typename ImageT::Pixel _value;
1082 template<
typename ImageT>
1085 Footprint
const& foot,
1086 typename ImageT::Pixel
const value
1088 SetFootprint<ImageT> setit(*image, value);
1094 template<
typename ImageT>
1098 typename ImageT::Pixel
const value
1103 template<
typename ImageT>
1106 std::vector<
PTR(Footprint)>
const& footprints,
1107 typename ImageT::Pixel
const value
1109 SetFootprint<ImageT> setit(*image, value);
1110 for (std::vector<
PTR(Footprint)>::const_iterator fiter = footprints.begin(),
1111 end = footprints.end(); fiter != end; ++fiter) {
1112 setit.apply(**fiter);
1122 template <
typename IDPixelT>
1123 static void set_footprint_id(
1125 Footprint
const& foot,
1129 for (Footprint::SpanList::const_iterator i = foot.getSpans().begin();
1130 i != foot.getSpans().end(); ++i) {
1132 for (typename image::Image<IDPixelT>::x_iterator ptr =
1133 idImage->x_at(span->getX0() + dx, span->getY() + dy),
1134 end = ptr + span->getWidth(); ptr != end; ++ptr) {
1140 template <
typename IDPixelT>
1142 set_footprint_array_ids(
1144 std::vector<
PTR(Footprint)>
const& footprints,
1145 bool const relativeIDs
1149 for (std::vector<
PTR(Footprint)>::const_iterator fiter = footprints.begin();
1150 fiter != footprints.end(); ++fiter) {
1159 set_footprint_id<IDPixelT>(idImage, *foot,
id);
1163 template void set_footprint_array_ids<int>(
1165 std::vector<PTR(Footprint)>
const& footprints,
1166 bool const relativeIDs);
1175 template <
typename IDImageT>
1176 typename boost::shared_ptr<image::Image<IDImageT> > setFootprintArrayIDs(
1177 std::vector<
PTR(Footprint)>
const& footprints,
1178 bool const relativeIDs
1180 std::vector<PTR(Footprint)>::const_iterator fiter = footprints.begin();
1181 if (fiter == footprints.end()) {
1183 lsst::pex::exceptions::InvalidParameterError,
1184 "You didn't provide any footprints"
1189 typename image::Image<IDImageT>::Ptr idImage(
1190 new image::Image<IDImageT>(foot->getRegion())
1196 set_footprint_array_ids<IDImageT>(idImage, footprints, relativeIDs);
1201 template image::Image<
int>::Ptr setFootprintArrayIDs(
1202 std::vector<
PTR(Footprint)> const& footprints,
1203 bool const relativeIDs);
1207 template <typename IDImageT>
1208 typename boost::shared_ptr<image::Image<IDImageT> > setFootprintID(
1217 set_footprint_id<IDImageT>(idImage, *foot,
id);
1231 class StructuringElement
1234 enum class Shape { CIRCLE, DIAMOND };
1235 typedef std::vector<Span>::const_iterator const_iterator;
1236 StructuringElement(
Shape shape,
int radius);
1237 StructuringElement(
int left,
int right,
int up,
int down);
1238 const_iterator begin()
const {
return _widths.begin(); }
1239 const_iterator end()
const {
return _widths.end(); }
1240 int getYRange()
const {
return _yRange; }
1243 std::vector<Span> _widths;
1252 StructuringElement::StructuringElement(
Shape shape,
int radius) {
1253 _yRange = 2*radius + 1;
1254 _widths.reserve(_yRange);
1257 for (
auto dy = -radius; dy <= radius; dy++) {
1258 int dx =
static_cast<int>(sqrt(radius*radius - dy*dy));
1259 _widths.push_back(Span(dy, -dx, dx));
1262 case Shape::DIAMOND:
1263 for (
auto dy = -radius; dy <= radius; dy++) {
1264 int dx = radius - abs(dy);
1265 _widths.push_back(Span(dy, -dx, dx));
1275 StructuringElement::StructuringElement(
int left,
int right,
int up,
int down) {
1276 _yRange = up + down + 1;
1277 _widths.reserve(_yRange);
1278 for (
auto dy = 1; dy <= up; dy++) {
1279 _widths.push_back(Span(dy, 0, 0));
1281 for (
auto dy = -1; dy >= -down; dy--) {
1282 _widths.push_back(Span(dy, 0, 0));
1284 _widths.push_back(Span(0, -left, right));
1291 PTR(Footprint) growFootprintImpl(
1292 Footprint const& foot,
1293 StructuringElement const& element
1296 PTR(Footprint) grown(new Footprint(0, foot.getRegion()));
1300 for (auto spanIter = foot.getSpans().begin(); spanIter != foot.getSpans().end(); spanIter++) {
1301 for (
auto it = element.begin(); it != element.end(); it++) {
1302 int xmin = (*spanIter)->getX0() + it->getX0();
1303 int xmax = (*spanIter)->getX1() + it->getX1();
1304 grown->addSpan((*spanIter)->getY() + it->getY(), xmin, xmax);
1323 int m,
y, xmin, xmax;
1330 bool comparePrimaryRun(PrimaryRun
const& first, PrimaryRun
const& second) {
1331 if (first.y != second.y) {
1332 return first.y < second.y;
1333 }
else if (first.m != second.m) {
1334 return first.m < second.m;
1336 return first.xmin < second.xmin;
1340 class ComparePrimaryRunY{
1342 bool operator()(PrimaryRun
const& pr,
int yval) {
1345 bool operator()(
int yval, PrimaryRun
const& pr) {
1350 class ComparePrimaryRunM{
1352 bool operator()(PrimaryRun
const& pr,
int mval) {
1355 bool operator()(
int mval, PrimaryRun
const& pr) {
1364 PTR(Footprint) shrinkFootprintImpl(
1365 Footprint const& foot,
1366 StructuringElement const& element
1369 PTR(Footprint) shrunk(new Footprint(0, foot.getRegion()));
1372 std::vector<PrimaryRun> primaryRuns;
1373 for (auto spanIter = foot.getSpans().begin(); spanIter != foot.getSpans().end(); ++spanIter) {
1375 for (
auto it = element.begin(); it != element.end(); ++it, ++m) {
1376 if ((it->getX1() - it->getX0()) <= ((*spanIter)->getX1() - (*spanIter)->getX0())) {
1377 int xmin = (*spanIter)->getX0() - it->getX0();
1378 int xmax = (*spanIter)->getX1() - it->getX1();
1379 int y = (*spanIter)->getY() - it->getY();
1380 primaryRuns.push_back(PrimaryRun({m,
y, xmin, xmax}));
1387 std::sort(primaryRuns.begin(), primaryRuns.end(), comparePrimaryRun);
1389 for (
int y = primaryRuns.front().y; y <= primaryRuns.back().y; ++
y) {
1390 auto yRange = std::equal_range(primaryRuns.begin(), primaryRuns.end(),
y, ComparePrimaryRunY());
1395 if (std::distance(yRange.first, yRange.second) < element.getYRange()) {
1404 std::list<PrimaryRun> goodRuns;
1406 for (
int m = 0; m < element.getYRange(); ++m) {
1407 auto mRange = std::equal_range(yRange.first, yRange.second, m, ComparePrimaryRunM());
1408 if (mRange.first == mRange.second) {
1415 std::list<PrimaryRun> candidateRuns;
1416 int start_x = mRange.first->xmin;
1417 int end_x = mRange.first->xmax;
1418 for (
auto run = mRange.first+1;
run != mRange.second; ++
run) {
1419 if (
run->xmin > end_x) {
1421 candidateRuns.push_back(PrimaryRun{m,
y, start_x, end_x});
1422 start_x =
run->xmin;
1429 candidateRuns.push_back(PrimaryRun{m,
y, start_x, end_x});
1438 std::list<PrimaryRun> newlist;
1439 for (
auto good = goodRuns.begin(); good != goodRuns.end(); ++good) {
1440 for (
auto cand = candidateRuns.begin(); cand != candidateRuns.end(); ++cand) {
1441 int start =
std::max(good->xmin, cand->xmin);
1442 int end =
std::min(good->xmax, cand->xmax);
1444 newlist.push_back(PrimaryRun({m,
y, start, end}));
1452 for (
auto run = goodRuns.begin();
run != goodRuns.end(); ++
run) {
1453 shrunk->addSpan(
run->y,
run->xmin,
run->xmax);
1457 shrunk->normalize();
1465 PTR(Footprint) _mergeFootprints(Footprint const& aFoot, Footprint const& bFoot) {
1466 PTR(Footprint) foot(new Footprint());
1468 Footprint::PeakList const& aPeaks = aFoot.getPeaks();
1469 Footprint::PeakList const& bPeaks = bFoot.getPeaks();
1470 Footprint::PeakList & peaks = foot->getPeaks();
1471 peaks.reserve(aPeaks.size() + bPeaks.size());
1472 peaks.insert(peaks.begin(), aPeaks.begin(), aPeaks.end());
1473 peaks.insert(peaks.end()-1, bPeaks.begin(), bPeaks.end());
1474 assert(peaks.size() == (aPeaks.size() + bPeaks.size()));
1476 Footprint::SpanList const& aSpans = aFoot.getSpans();
1477 Footprint::SpanList const& bSpans = bFoot.getSpans();
1478 Footprint::SpanList::const_iterator aSpan = aSpans.begin();
1479 Footprint::SpanList::const_iterator bSpan = bSpans.begin();
1480 Footprint::SpanList::const_iterator aEnd = aSpans.end();
1481 Footprint::SpanList::const_iterator bEnd = bSpans.end();
1483 foot->getSpans().reserve(std::
max(aSpans.size(), bSpans.size()));
1485 while ((aSpan != aEnd) && (bSpan != bEnd)) {
1486 int y = (*aSpan)->getY();
1487 int x0 = (*aSpan)->getX0();
1488 int x1 = (*aSpan)->getX1();
1489 int yb = (*bSpan)->getY();
1490 int xb0 = (*bSpan)->getX0();
1491 int xb1 = (*bSpan)->getX1();
1493 if ((y < yb) || (y == yb && (x1 < (xb0-1)))) {
1495 foot->addSpanInSeries(y, x0, x1);
1499 if ((yb < y) || (y == yb && (xb1 < (x0-1)))) {
1501 foot->addSpanInSeries(yb, xb0, xb1);
1514 if ((aSpan != aEnd) &&
1515 ((*aSpan)->getY() ==
y) &&
1516 ((*aSpan)->getX0() <= (x1+1))) {
1518 x1 =
std::max(x1, (*aSpan)->getX1());
1522 if ((bSpan != bEnd) &&
1523 ((*bSpan)->getY() ==
y) &&
1524 ((*bSpan)->getX0() <= (x1+1))) {
1526 x1 =
std::max(x1, (*bSpan)->getX1());
1532 foot->addSpanInSeries(y, x0, x1);
1537 for (; aSpan != aEnd; ++aSpan) {
1538 foot->addSpanInSeries((*aSpan)->getY(), (*aSpan)->getX0(), (*aSpan)->getX1());
1541 for (; bSpan != bEnd; ++bSpan) {
1542 foot->addSpanInSeries((*bSpan)->getY(), (*bSpan)->getX0(), (*bSpan)->getX1());
1551 return _mergeFootprints(foot1, foot2);
1555 if (!foot1.isNormalized() || !foot2.isNormalized()) {
1557 lsst::pex::exceptions::InvalidParameterError,
1558 "mergeFootprints(const Footprints) requires normalize()d Footprints.");
1560 return _mergeFootprints(foot1, foot2);
1573 typedef boost::uint16_t dtype;
1574 typedef boost::uint16_t itype;
1576 const itype nil = 0xffff;
1582 int const x0 = bbox.
getMinX();
1583 int const y0 = bbox.
getMinY();
1585 for (
size_t i=0; i<foots.size(); ++i) {
1587 set_footprint_id<itype>(argmin, *foots[i], i, -x0, -y0);
1588 set_footprint_id<dtype>(dist, *foots[i], 1, -x0, -y0);
1592 int const width = dist->
getWidth();
1595 for (
int y = 0; y != height; ++
y) {
1598 for (
int x = 0; x != width; ++
x, ++dim.x(), ++aim.x()) {
1599 if (dim(0, 0) == 1) {
1606 dim(0, 0) = width + height;
1610 dtype ndist = dim(0,-1) + 1;
1611 if (ndist < dim(0,0)) {
1613 aim(0,0) = aim(0,-1);
1618 dtype ndist = dim(-1,0) + 1;
1619 if (ndist < dim(0,0)) {
1621 aim(0,0) = aim(-1,0);
1628 for (
int y = height - 1; y >= 0; --
y) {
1631 for (
int x = width - 1; x >= 0; --
x, --dim.x(), --aim.x()) {
1634 if (y + 1 < height) {
1635 dtype ndist = dim(0,1) + 1;
1636 if (ndist < dim(0,0)) {
1638 aim(0,0) = aim(0,1);
1642 if (x + 1 < width) {
1643 dtype ndist = dim(1,0) + 1;
1644 if (ndist < dim(0,0)) {
1646 aim(0,0) = aim(1,0);
1654 Footprint const& foot,
1658 if (nGrow <= 0 || foot.getNpix() == 0 ) {
1667 Shape shape = isotropic ? Shape::CIRCLE : Shape::DIAMOND;
1668 return growFootprintImpl(foot, StructuringElement(shape, nGrow));
1683 if (nGrow <= 0 || foot.getNpix() == 0 ) {
1687 return growFootprintImpl(foot, StructuringElement(left ? nGrow: 0, right ? nGrow : 0,
1688 up ? nGrow : 0, down ? nGrow : 0));
1692 Footprint const& foot,
1697 Shape shape = isotropic ? Shape::CIRCLE : Shape::DIAMOND;
1698 return shrinkFootprintImpl(foot, StructuringElement(shape, nShrink));
1704 typedef boost::uint16_t ImageT;
1712 foot.insertIntoImage(*idImage, 1, fpBBox);
1714 std::vector<geom::Box2I> bboxes;
1729 while (y0 < height) {
1731 for (
int y = y0; y != height; ++
y) {
1738 int const x0 = first - begin;
1739 int const x1 = last - begin;
1741 std::fill(first, last + 1, 0);
1747 for (++y; y != height; ++
y) {
1748 if (std::find(idImage->at(x0, y), idImage->at(x1 + 1, y), 0) != idImage->at(x1 + 1, y)) {
1751 std::fill(idImage->at(x0, y), idImage->at(x1 + 1, y), 0);
1757 bboxes.push_back(bbox);
1769 template<
typename ImageOrMaskedImageT>
1772 PTR(ImageOrMaskedImageT)
const input,
1773 PTR(ImageOrMaskedImageT) output) {
1774 Footprint::SpanList spans = foot.getSpans();
1775 for (Footprint::SpanList::iterator sp = spans.begin();
1776 sp != spans.end(); ++sp) {
1777 int y = (*sp)->getY();
1778 int x0 = (*sp)->getX0();
1779 int x1 = (*sp)->getX1();
1780 typename ImageOrMaskedImageT::const_x_iterator initer = input->x_at(
1781 x0 - input->getX0(), y - input->getY0());
1782 typename ImageOrMaskedImageT::x_iterator outiter = output->x_at(
1783 x0 - output->getX0(), y - output->getY0());
1784 for (
int x=x0; x <= x1; ++
x, ++initer, ++outiter) {
1799 psArray *pmGrowFootprintArray(psArray
const *footprints,
1801 assert (footprints->n == 0 || pmIsFootprint(footprints->data[0]));
1803 if (footprints->n == 0) {
1804 return psArrayAlloc(0);
1810 psImage *idImage = pmSetFootprintArrayIDs(footprints,
true);
1814 psKernel *circle = psKernelAlloc(-r, r, -r, r);
1815 assert (circle->image->numRows == 2*r + 1 && circle->image->numCols == circle->image->numRows);
1816 for (
int i = 0; i <= r; ++i) {
1817 for (
int j = 0; j <= r; ++j) {
1818 if (i*i + j*j <= r*r) {
1819 circle->kernel[i][j] =
1820 circle->kernel[i][-j] =
1821 circle->kernel[-i][j] =
1822 circle->kernel[-i][-j] = 1;
1827 psImage *grownIdImage = psImageConvolveDirect(idImage, circle);
1830 psArray *grown = pmFindFootprints(grownIdImage, 0.5, 1);
1831 assert (grown != NULL);
1833 psFree(grownIdImage);
1838 psArray
const *peaks = pmFootprintArrayToPeaks(footprints);
1839 pmPeaksAssignToFootprints(grown, peaks);
1840 psFree((psArray *)peaks);
1852 psArray *pmMergeFootprintArrays(psArray
const *footprints1,
1853 psArray
const *footprints2,
1854 int const includePeaks) {
1855 assert (footprints1->n == 0 || pmIsFootprint(footprints1->data[0]));
1856 assert (footprints2->n == 0 || pmIsFootprint(footprints2->data[0]));
1858 if (footprints1->n == 0 || footprints2->n == 0) {
1859 psArray
const *old = (footprints1->n == 0) ? footprints2 : footprints1;
1861 psArray *merged = psArrayAllocEmpty(old->n);
1862 for (
int i = 0; i < old->n; ++i) {
1863 psArrayAdd(merged, 1, old->data[i]);
1873 pmFootprint *fp1 = footprints1->data[0];
1874 pmFootprint *fp2 = footprints2->data[0];
1875 if (fp1->region.x0 != fp2->region.x0 ||
1876 fp1->region.x1 != fp2->region.x1 ||
1877 fp1->region.y0 != fp2->region.y0 ||
1878 fp1->region.y1 != fp2->region.y1) {
1879 psError(PS_ERR_BAD_PARAMETER_SIZE,
true,
1880 "The two pmFootprint arrays correspnond to different-sized regions");
1888 psImage *idImage = pmSetFootprintArrayIDs(footprints1,
true);
1889 set_footprint_array_ids(idImage, footprints2,
true);
1891 psArray *merged = pmFindFootprints(idImage, 0.5, 1);
1892 assert (merged != NULL);
1898 if (includePeaks & 0x1) {
1899 psArray
const *peaks = pmFootprintArrayToPeaks(footprints1);
1900 pmPeaksAssignToFootprints(merged, peaks);
1901 psFree((psArray *)peaks);
1904 if (includePeaks & 0x2) {
1905 psArray
const *peaks = pmFootprintArrayToPeaks(footprints2);
1906 pmPeaksAssignToFootprints(merged, peaks);
1907 psFree((psArray *)peaks);
1920 pmPeaksAssignToFootprints(psArray *footprints,
1921 psArray
const *peaks) {
1922 assert (footprints != NULL);
1923 assert (footprints->n == 0 || pmIsFootprint(footprints->data[0]));
1924 assert (peaks != NULL);
1925 assert (peaks->n == 0 || pmIsPeak(peaks->data[0]));
1927 if (footprints->n == 0) {
1929 return psError(PS_ERR_BAD_PARAMETER_SIZE,
true,
"Your list of footprints is empty");
1937 psImage *ids = pmSetFootprintArrayIDs(footprints,
true);
1938 assert (ids != NULL);
1939 assert (ids->type.type == PS_TYPE_S32);
1940 int const y0 = ids->y0;
1941 int const x0 = ids->x0;
1942 int const numRows = ids->numRows;
1943 int const numCols = ids->numCols;
1945 for (
int i = 0; i < peaks->n; ++i) {
1946 pmPeak *peak = peaks->data[i];
1947 int const x = peak->x - x0;
1948 int const y = peak->y - y0;
1950 assert (x >= 0 && x < numCols && y >= 0 && y < numRows);
1951 int id = ids->data.S32[
y][x - x0];
1954 pmFootprint *nfp = pmFootprintAlloc(1, ids);
1955 pmFootprintAddSpan(nfp, y, x, x);
1956 psArrayAdd(footprints, 1, nfp);
1961 assert (
id >= 1 && id <= footprints->n);
1962 pmFootprint *fp = footprints->data[
id - 1];
1963 psArrayAdd(fp->peaks, 5, peak);
1970 for (
int i = 0; i < footprints->n; ++i) {
1971 pmFootprint *fp = footprints->data[i];
1972 fp->peaks = psArraySort(fp->peaks, pmPeakSortBySN);
1974 for (
int j = 1; j < fp->peaks->n; ++j) {
1975 if (fp->peaks->data[j] == fp->peaks->data[j-1]) {
1976 (void)psArrayRemoveIndex(fp->peaks, j);
1992 psErrorCode pmFootprintCullPeaks(psImage
const *img,
1993 psImage
const *weight,
1995 float const nsigma_delta,
1997 float const min_threshold) {
1998 assert (img != NULL);
1999 assert (img->type.type == PS_TYPE_F32);
2000 assert (weight != NULL);
2001 assert (weight->type.type == PS_TYPE_F32);
2002 assert (img->y0 == weight->y0 && img->x0 == weight->x0);
2003 assert (fp != NULL);
2005 if (fp->peaks == NULL || fp->peaks->n == 0) {
2010 subRegion.x0 = fp->bbox.x0;
2011 subRegion.x1 = fp->bbox.x1 + 1;
2012 subRegion.y0 = fp->bbox.y0;
2013 subRegion.y1 = fp->bbox.y1 + 1;
2014 psImage
const *subImg = psImageSubset((psImage *)img, subRegion);
2015 psImage
const *subWt = psImageSubset((psImage *)weight, subRegion);
2016 assert (subImg != NULL && subWt != NULL);
2024 psArray *brightPeaks = psArrayAlloc(0);
2025 psFree(brightPeaks->data);
2026 brightPeaks->data = psMemIncrRefCounter(fp->peaks->data);
2030 for (
int i = 1; i < fp->peaks->n; ++i) {
2031 pmPeak
const *peak = fp->peaks->data[i];
2032 int x = peak->x - subImg->x0;
2033 int y = peak->y - subImg->y0;
2038 assert (x >= 0 && x < subImg->numCols && y >= 0 && y < subImg->numRows);
2039 float const stdev = std::sqrt(subWt->data.F32[y][x]);
2040 float threshold = subImg->data.F32[
y][
x] - nsigma_delta*
stdev;
2042 #if 1 // min_threshold is assumed to be below the detection threshold,
2044 (void)psArrayRemoveIndex(fp->peaks, i);
2048 #error n.b. We will be running LOTS of checks at this threshold, so only find the footprint once
2049 threshold = min_threshold;
2052 if (threshold > subImg->data.F32[y][x]) {
2053 threshold = subImg->data.F32[
y][
x] - 10*FLT_EPSILON;
2056 int const peak_id = 1;
2058 pmFootprint *peakFootprint = pmFindFootprintAtPoint(subImg, threshold, brightPeaks, peak->y, peak->x);
2060 psImage *idImg = pmSetFootprintID(peakFootprint, peak_id);
2061 psFree(peakFootprint);
2064 for (j = 0; j < i; ++j) {
2065 pmPeak
const *peak2 = fp->peaks->data[j];
2066 int x2 = peak2->x - subImg->x0;
2067 int y2 = peak2->y - subImg->y0;
2068 int const peak2_id = idImg->data.S32[y2][x2];
2070 if (peak2_id == peak_id) {
2072 (void)psArrayRemoveIndex(fp->peaks, i);
2085 psFree(brightPeaks);
2086 psFree((psImage *)subImg);
2087 psFree((psImage *)subWt);
2096 pmFootprintArrayCullPeaks(psImage
const *img,
2097 psImage
const *weight,
2098 psArray *footprints,
2099 float const nsigma_delta,
2101 float const min_threshold) {
2102 for (
int i = 0; i < footprints->n; ++i) {
2103 pmFootprint *fp = footprints->data[i];
2104 if (pmFootprintCullPeaks(img, weight, fp, nsigma_delta, min_threshold) != PS_ERR_NONE) {
2105 return psError(PS_ERR_UNKNOWN,
false,
"Culling pmFootprint %d", fp->id);
2116 psArray *pmFootprintArrayToPeaks(psArray
const *footprints) {
2117 assert(footprints != NULL);
2118 assert(footprints->n == 0 || pmIsFootprint(footprints->data[0]));
2121 for (
int i = 0; i < footprints->n; ++i) {
2122 pmFootprint
const *fp = footprints->data[i];
2123 npeak += fp->peaks->n;
2126 psArray *peaks = psArrayAllocEmpty(npeak);
2128 for (
int i = 0; i < footprints->n; ++i) {
2129 pmFootprint
const *fp = footprints->data[i];
2130 for (
int j = 0; j < fp->peaks->n; ++j) {
2131 psArrayAdd(peaks, 1, fp->peaks->data[j]);
2146 void Footprint::intersectMask(
2152 PTR(Footprint) const& foot,
2153 image::Mask<image::
MaskPixel>::Ptr const& mask,
2159 CONST_PTR(std::vector<
PTR(Footprint)>) const& footprints,
2164 std::vector<
PTR(Footprint)> const& footprints,
2168 Footprint const& foot, image::
MaskPixel const bitmask);
2171 Footprint const& foot, image::
MaskPixel const bitmask);
2173 #define INSTANTIATE_NUMERIC(TYPE) \
2175 TYPE setImageFromFootprint(image::Image<TYPE> *image, \
2176 Footprint const& footprint, \
2177 TYPE const value); \
2179 TYPE setImageFromFootprintList(image::Image<TYPE> *image, \
2180 std::vector<PTR(Footprint)> const& footprints, \
2181 TYPE const value); \
2183 TYPE setImageFromFootprintList(image::Image<TYPE> *image, \
2184 CONST_PTR(std::vector<PTR(Footprint)>) footprints, \
2185 TYPE const value); \
2187 void copyWithinFootprint(Footprint const&, \
2188 PTR(lsst::afw::image::Image<TYPE>) const, \
2189 PTR(lsst::afw::image::Image<TYPE>)); \
2191 void copyWithinFootprint(Footprint const&, \
2192 PTR(lsst::afw::image::MaskedImage<TYPE>) const, \
2193 PTR(lsst::afw::image::MaskedImage<TYPE>)); \
2195 void Footprint::clipToNonzero(lsst::afw::image::Image<TYPE> const&); \
2198 INSTANTIATE_NUMERIC(
float);
2199 INSTANTIATE_NUMERIC(
double);
2201 INSTANTIATE_NUMERIC(boost::uint16_t);
2202 INSTANTIATE_NUMERIC(
int);
2203 INSTANTIATE_NUMERIC(boost::uint64_t);
2206 #define INSTANTIATE_MASK(PIXEL) \
2208 void Footprint::insertIntoImage( \
2209 lsst::afw::image::Image<PIXEL>& idImage, \
2210 boost::uint64_t const id, \
2211 geom::Box2I const& region=geom::Box2I() \
2214 void Footprint::insertIntoImage( \
2215 lsst::afw::image::Image<PIXEL>& idImage, \
2216 boost::uint64_t const id, \
2217 bool const overwriteId, long const idMask, \
2218 std::set<boost::uint64_t> *oldIds, \
2219 geom::Box2I const& region=geom::Box2I() \
2222 INSTANTIATE_MASK(boost::uint16_t);
2223 INSTANTIATE_MASK(
int);
2224 INSTANTIATE_MASK(boost::uint64_t);
Defines the fields and offsets for a table.
void nearestFootprint(std::vector< boost::shared_ptr< Footprint >> const &foots, lsst::afw::image::Image< boost::uint16_t >::Ptr argmin, lsst::afw::image::Image< boost::uint16_t >::Ptr dist)
Declare the Kernel class and subclasses.
A coordinate class intended to represent absolute positions.
Extent2I const getDimensions() const
void shift(Extent2I const &offset)
Shift the position of the box by the given offset.
x_iterator x_at(int x, int y) const
Return an x_iterator to the point (x, y) in the image.
void swap(ImageBase< PixelT > &a, ImageBase< PixelT > &b)
bool contains(Point2I const &point) const
Return true if the box contains the point.
CatalogT< BaseRecord > BaseCatalog
boost::uint16_t MaskPixel
void include(Point2I const &point)
Expand this to ensure that this->contains(point).
geom::Point2D skyToPixel(geom::Angle sky1, geom::Angle sky2) const
Convert from sky coordinates (e.g ra/dec) to pixel positions.
boost::shared_ptr< Footprint > footprintAndMask(boost::shared_ptr< Footprint > const &foot, typename image::Mask< MaskT >::Ptr const &mask, MaskT const bitmask)
Return a Footprint that's the intersection of a Footprint with a Mask.
definition of the Trace messaging facilities
SelectEigenView< T >::Type copy(Eigen::EigenBase< T > const &other)
Copy an arbitrary Eigen expression into a new EigenView.
Point< double, 2 > Point2D
geom::Box2I getBBox(ImageOrigin origin=PARENT) const
Implementation of the WCS standard for a any projection.
void shift(Vector< T, N > const &offset, Array< std::complex< T >, N, C > const &array, int const real_last_dim)
Perform a Fourier-space translation transform.
boost::shared_ptr< coord::Coord > pixelToSky(double pix1, double pix2) const
Convert from celestial coordinates to pixel coordinates.
Extent< int, 2 > Extent2I
An integer coordinate rectangle.
table::Key< table::Array< Kernel::Pixel > > image
boost::shared_ptr< Footprint > shrinkFootprint(Footprint const &foot, int nGrow, bool isotropic)
afw::geom::ellipses::Quadrupole Shape
boost::shared_ptr< Footprint > growFootprint(Footprint const &foot, int nGrow, bool isotropic=true)
Include files required for standard LSST Exception handling.
geom::Box2I const & _bbox
void include(Point2D const &point)
Expand this to ensure that this->contains(point).
int getHeight() const
Return the number of rows in the image.
bool isEmpty() const
Return true if the box contains no points.
CatalogIterator< typename Internal::const_iterator > const_iterator
MaskT clearMaskFromFootprint(lsst::afw::image::Mask< MaskT > *mask, Footprint const &footprint, MaskT const bitmask)
(AND ~bitmask) all the Mask's pixels that are in the Footprint; that is, set to zero in the Mask-inte...
ImageT::Pixel setImageFromFootprint(ImageT *image, Footprint const &footprint, typename ImageT::Pixel const value)
Set all image pixels in a Footprint to a given value.
Support for peaks in images.
#define LSST_EXCEPT(type,...)
std::vector< lsst::afw::geom::Box2I > footprintToBBoxList(Footprint const &foot)
lsst::afw::detection::Footprint Footprint
MaskT setMaskFromFootprint(lsst::afw::image::Mask< MaskT > *mask, Footprint const &footprint, MaskT const bitmask)
OR bitmask into all the Mask's pixels that are in the Footprint.
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
afw::table::Key< double > b
xy_locator xy_at(int x, int y) const
x_iterator row_begin(int y) const
A floating-point coordinate rectangle geometry.
boost::shared_ptr< Footprint > mergeFootprints(Footprint const &foot1, Footprint const &foot2)
int getWidth() const
Return the number of columns in the image.
A class to represent a 2-dimensional array of pixels.
Utility functions for kernels.
afw::table::SourceRecord * record
void copyWithinFootprint(Footprint const &foot, boost::shared_ptr< ImageOrMaskedImageT > const input, boost::shared_ptr< ImageOrMaskedImageT > output)
ImageT::Pixel setImageFromFootprintList(ImageT *image, boost::shared_ptr< std::vector< boost::shared_ptr< Footprint >> const > footprints, typename ImageT::Pixel const value)
Set all image pixels in a set of Footprints to a given value.
MaskT setMaskFromFootprintList(lsst::afw::image::Mask< MaskT > *mask, std::vector< boost::shared_ptr< Footprint >> const &footprints, MaskT const bitmask)
OR bitmask into all the Mask's pixels which are in the set of Footprints.