28#include "ndarray/eigen.h"
41template <
typename MaskedImageT>
44 explicit FootprintBits() : _anyBits(0), _allBits(~static_cast<typename MaskedImageT::Mask::Pixel>(0x0)) {}
49 _allBits = ~static_cast<typename MaskedImageT::Mask::Pixel>(0x0);
52 void operator()(
geom::Point2I const& point,
typename MaskedImageT::Mask::Pixel
const& value) {
58 typename MaskedImageT::Mask::Pixel getAnyBits()
const {
return _anyBits; }
60 typename MaskedImageT::Mask::Pixel getAllBits()
const {
return _allBits; }
63 typename MaskedImageT::Mask::Pixel _anyBits;
64 typename MaskedImageT::Mask::Pixel _allBits;
67typedef afw::image::MaskedImage<float> MaskedImageF;
71 const FootprintBits<MaskedImageF>& func, afw::table::SourceRecord& measRecord) {
72 for (
auto const& i : maskFlagToPixelFlag) {
74 if (func.getAnyBits() & MaskedImageF::Mask::getPlaneBitMask(i.first)) {
75 measRecord.set(i.second,
true);
77 }
catch (pex::exceptions::InvalidParameterError& err) {
85 const FootprintBits<MaskedImageF>& func, afw::table::SourceRecord& measRecord) {
86 for (
auto const& i : maskFlagToPixelFlag) {
88 if (func.getAllBits() & MaskedImageF::Mask::getPlaneBitMask(i.first)) {
89 measRecord.set(i.second,
true);
91 }
catch (pex::exceptions::InvalidParameterError& err) {
103 _generalFailureKey = schema.
addField<afw::table::Flag>(
104 name +
"_flag",
"General failure flag, set if anything went wrong setting flags.");
106 schema.
addField<afw::table::Flag>(name +
"_flag" +
"_offimage",
"Source center is off image");
108 _anyKeys[
"EDGE"] = schema.
addField<afw::table::Flag>(
110 "Pixel in source outside usable exposure region (masked EDGE or centroid off image).");
111 _anyKeys[
"NO_DATA"] = schema.
addField<afw::table::Flag>(name +
"_flag_nodata",
112 "NO_DATA pixel in the source footprint.");
113 _anyKeys[
"INTRP"] = schema.
addField<afw::table::Flag>(name +
"_flag_interpolated",
114 "Interpolated pixel in the Source footprint");
115 _anyKeys[
"SAT"] = schema.
addField<afw::table::Flag>(name +
"_flag_saturated",
116 "Saturated pixel in the Source footprint");
118 schema.
addField<afw::table::Flag>(name +
"_flag_cr",
"Cosmic ray in the Source footprint");
120 schema.
addField<afw::table::Flag>(name +
"_flag_bad",
"Bad pixel in the Source footprint");
121 _anyKeys[
"SUSPECT"] = schema.
addField<afw::table::Flag>(name +
"_flag_suspect",
122 "Source's footprint includes suspect pixels");
124 _centerKeys[
"EDGE"] = schema.
addField<afw::table::Flag>(
125 name +
"_flag_edgeCenter",
"EDGE pixel in the 3x3 region around the centroid.");
126 _centerKeys[
"NO_DATA"] = schema.
addField<afw::table::Flag>(
127 name +
"_flag_nodataCenter",
"NO_DATA pixel in the 3x3 region around the centroid.");
128 _centerKeys[
"INTRP"] = schema.
addField<afw::table::Flag>(
129 name +
"_flag_interpolatedCenter",
"Interpolated pixel in the 3x3 region around the centroid.");
130 _centerKeys[
"SAT"] = schema.
addField<afw::table::Flag>(
131 name +
"_flag_saturatedCenter",
"Saturated pixel in the 3x3 region around the centroid.");
132 _centerKeys[
"CR"] = schema.
addField<afw::table::Flag>(
133 name +
"_flag_crCenter",
"Cosmic ray in the 3x3 region around the centroid.");
134 _centerKeys[
"BAD"] = schema.
addField<afw::table::Flag>(name +
"_flag_badCenter",
135 "Bad pixel in the 3x3 region around the centroid");
136 _centerKeys[
"SUSPECT"] = schema.
addField<afw::table::Flag>(
137 name +
"_flag_suspectCenter",
"Suspect pixel in the 3x3 region around the centroid.");
140 _centerAllKeys[
"EDGE"] = schema.
addField<afw::table::Flag>(
141 name +
"_flag_edgeCenterAll",
142 "All pixels in the 3x3 region around the centroid are marked EDGE.");
143 _centerAllKeys[
"NO_DATA"] = schema.
addField<afw::table::Flag>(
144 name +
"_flag_nodataCenterAll",
145 "All pixels in the 3x3 region around the centroid are marked NO_DATA");
146 _centerAllKeys[
"INTRP"] = schema.
addField<afw::table::Flag>(
147 name +
"_flag_interpolatedCenterAll",
148 "All pixels in the 3x3 region around the centroid are interpolated.");
149 _centerAllKeys[
"SAT"] = schema.
addField<afw::table::Flag>(
150 name +
"_flag_saturatedCenterAll",
151 "All pixels in the 3x3 region around the centroid are saturated.");
152 _centerAllKeys[
"CR"] = schema.
addField<afw::table::Flag>(
153 name +
"_flag_crCenterAll",
154 "All pixels in the 3x3 region around the centroid have the cosmic ray mask bit.");
155 _centerAllKeys[
"BAD"] = schema.
addField<afw::table::Flag>(
156 name +
"_flag_badCenterAll",
"All pixels in the 3x3 region around the centroid are bad.");
157 _centerAllKeys[
"SUSPECT"] = schema.
addField<afw::table::Flag>(
158 name +
"_flag_suspectCenterAll",
"All pixels in the 3x3 region around the centroid are suspect.");
161 for (
auto const& i : _ctrl.masksFpCenter) {
162 std::string maskName(i);
163 std::transform(maskName.begin(), maskName.end(), maskName.begin(), ::tolower);
164 _centerKeys[i] = schema.addField<afw::table::Flag>(
165 name +
"_flag_" + maskName +
"Center",
"3x3 region around the centroid has " + i +
" pixels");
167 for (
auto const& i : _ctrl.masksFpCenter) {
168 std::string maskName(i);
169 std::transform(maskName.begin(), maskName.end(), maskName.begin(), ::tolower);
170 _centerAllKeys[i] = schema.addField<afw::table::Flag>(
171 name +
"_flag_" + maskName +
"CenterAll",
172 "All pixels in the 3x3 region around the source centroid are " + i +
" pixels");
175 for (
auto const& i : _ctrl.masksFpAnywhere) {
176 std::string maskName(i);
177 std::transform(maskName.begin(), maskName.end(), maskName.begin(), ::tolower);
178 _anyKeys[i] = schema.addField<afw::table::Flag>(name +
"_flag_" + maskName,
179 "Source footprint includes " + i +
" pixels");
186 FootprintBits<MaskedImageF> func;
190 if (measRecord.
getTable()->getCentroidSlot().getMeasKey().isValid()) {
195 measRecord.
set(_generalFailureKey,
true);
204 if (!footprint || footprint->getPeaks().empty()) {
207 center.setX(footprint->getPeaks().front().getFx());
208 center.setY(footprint->getPeaks().front().getFy());
216 measRecord.
set(_offImageKey,
true);
217 measRecord.
set(_anyKeys.at(
"EDGE"),
true);
218 measRecord.
set(_centerKeys.at(
"EDGE"),
true);
219 measRecord.
set(_centerAllKeys.at(
"EDGE"),
true);
226 (boost::format(
"Source id %d has no footprint.") % measRecord.
getId()).str());
228 auto fullSpans = footprint->getSpans();
232 (boost::format(
"Source id %d has no spans in footprint.") % measRecord.
getId()).str());
234 fullSpans->clippedTo(mimage.getBBox())->applyFunctor(func, *(mimage.getMask()));
237 updateFlags(_anyKeys, func, measRecord);
241 (boost::format(
"Centroid of source id %d passed to PixelFlags is non-finite; "
242 "footprint-based flags have been set, but centroid-based flags will not be.") %
254 middle.
getSpans()->clippedTo(mimage.getBBox())->applyFunctor(func, *(mimage.getMask()));
257 updateFlags(_centerKeys, func, measRecord);
258 updateFlagsAll(_centerAllKeys, func, measRecord);
263 measRecord.
set(_generalFailureKey,
true);
#define LSST_EXCEPT(type,...)
This is the algorithm for PixelFlags.
MaskedImageT getMaskedImage()
void set(Key< T > const &key, U const &value)
Key< T > addField(Field< T > const &field, bool doReplace=false)
CentroidSlotDefinition::MeasValue getCentroid() const
std::shared_ptr< SourceTable const > getTable() const
std::shared_ptr< Footprint > getFootprint() const
bool contains(Point2D const &point) const noexcept
Exception to be thrown when a measurement algorithm experiences a fatal error.
Exception to be thrown when a measurement algorithm experiences a known failure mode.
std::map< std::string, afw::table::Key< afw::table::Flag > > KeyMap
virtual void fail(afw::table::SourceRecord &measRecord, MeasurementError *error=nullptr) const
Handle an exception thrown by the current algorithm by setting flags in the given record.
PixelFlagsControl Control
A typedef to the Control object for this algorithm, defined above.
PixelFlagsAlgorithm(Control const &ctrl, std::string const &name, afw::table::Schema &schema)
virtual void measure(afw::table::SourceRecord &measRecord, afw::image::Exposure< float > const &exposure) const
Called to measure a single child source in an image.
virtual char const * what(void) const noexcept
int positionToIndex(double pos)
Point< double, 2 > Point2D