LSSTApplications  20.0.0
LSSTDataManagementBasePackage
KernelCandidateDetection.cc
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
12 #include "lsst/afw/geom.h"
13 #include "lsst/afw/image.h"
14 #include "lsst/afw/detection.h"
15 #include "lsst/geom.h"
16 #include "lsst/log/Log.h"
19 
22 
23 namespace geom = lsst::geom;
24 namespace afwGeom = lsst::afw::geom;
25 namespace afwImage = lsst::afw::image;
28 
29 namespace lsst {
30 namespace ip {
31 namespace diffim {
32 
33 
34  template <typename PixelT>
37  ) :
38  _ps(ps.deepCopy()),
39  _badBitMask(0),
40  _footprints(std::vector<std::shared_ptr<lsst::afw::detection::Footprint>>()) {
41 
42  std::vector<std::string> detBadMaskPlanes = _ps->getArray<std::string>("badMaskPlanes");
43  for (std::vector<std::string>::iterator mi = detBadMaskPlanes.begin();
44  mi != detBadMaskPlanes.end(); ++mi){
45  try {
47  } catch (pexExcept::Exception& e) {
48  LOGL_DEBUG("TRACE3.ip.diffim.KernelCandidateDetection",
49  "Cannot update bad bit mask with %s", (*mi).c_str());
50  LOGL_DEBUG("TRACE4.ip.diffim.KernelCandidateDetection",
51  e.what());
52  }
53  }
54  LOGL_DEBUG("TRACE2.ip.diffim.KernelCandidateDetection",
55  "Using bad bit mask %d", _badBitMask);
56  }
57 
58 
59 
78  template <typename PixelT>
80  MaskedImagePtr const& templateMaskedImage,
81  MaskedImagePtr const& scienceMaskedImage
82  ) {
83 
84  // Parse the ps
85  int fpNpixMin = _ps->getAsInt("fpNpixMin");
86  int fpGrowPix = _ps->getAsInt("fpGrowPix");
87 
88  bool detOnTemplate = _ps->getAsBool("detOnTemplate");
89  double detThreshold = _ps->getAsDouble("detThreshold");
90  std::string detThresholdType = _ps->getAsString("detThresholdType");
91 
92  /* reset private variables */
93  _footprints.clear();
94 
95  // List of Footprints
97 
98  // Find detections
99  afwDetect::Threshold threshold =
100  afwDetect::createThreshold(detThreshold, detThresholdType);
101 
102  if (detOnTemplate == true) {
103  afwDetect::FootprintSet footprintSet(
104  *(templateMaskedImage),
105  threshold,
106  "",
107  fpNpixMin);
108  // Get the associated footprints
109 
110  footprintListInPtr = footprintSet.getFootprints();
111  LOGL_DEBUG("TRACE2.ip.diffim.KernelCandidateDetection.apply",
112  "Found %d total footprints in template above %.3f %s",
113  footprintListInPtr->size(), detThreshold, detThresholdType.c_str());
114  }
115  else {
116  afwDetect::FootprintSet footprintSet(
117  *(scienceMaskedImage),
118  threshold,
119  "",
120  fpNpixMin);
121 
122  footprintListInPtr = footprintSet.getFootprints();
123  LOGL_DEBUG("TRACE2.ip.diffim.KernelCandidateDetection.apply",
124  "Found %d total footprints in science image above %.3f %s",
125  footprintListInPtr->size(), detThreshold, detThresholdType.c_str());
126  }
127 
128  // Iterate over footprints, look for "good" ones
129  for (std::vector<std::shared_ptr<afwDetect::Footprint>>::iterator i = footprintListInPtr->begin();
130  i != footprintListInPtr->end(); ++i) {
131 
132  growCandidate((*i), fpGrowPix, templateMaskedImage, scienceMaskedImage);
133  }
134 
135  if (_footprints.size() == 0) {
137  "Unable to find any footprints for Psf matching");
138  }
139 
140  LOGL_DEBUG("TRACE1.ip.diffim.KernelCandidateDetection.apply",
141  "Found %d clean footprints above threshold %.3f",
142  _footprints.size(), detThreshold);
143 
144  }
145 
146  template <typename PixelT>
149  int fpGrowPix,
150  MaskedImagePtr const& templateMaskedImage,
151  MaskedImagePtr const& scienceMaskedImage
152  ) {
153  int fpNpixMax = _ps->getAsInt("fpNpixMax");
154 
155  /* Functor to search through the images for masked pixels within *
156  * candidate footprints. Might want to consider changing the default
157  * mask planes it looks through.
158  */
160 
161  geom::Box2I fpBBox = fp->getBBox();
162  /* Failure Condition 1)
163  *
164  * Footprint has too many pixels off the bat. We don't want to throw
165  * away these guys, they have alot of signal! Lets just use the core of
166  * it.
167  *
168  */
169  if (fp->getArea() > static_cast<std::size_t>(fpNpixMax)) {
170  LOGL_DEBUG("TRACE3.ip.diffim.KernelCandidateDetection.apply",
171  "Footprint has too many pix: %d (max =%d)",
172  fp->getArea(), fpNpixMax);
173 
174  int xc = int(0.5 * (fpBBox.getMinX() + fpBBox.getMaxX()));
175  int yc = int(0.5 * (fpBBox.getMinY() + fpBBox.getMaxY()));
178  std::make_shared<afwGeom::SpanSet>(geom::Box2I(geom::Point2I(xc, yc),
179  geom::Extent2I(1,1))))
180  );
181  return growCandidate(fpCore, fpGrowPix, templateMaskedImage, scienceMaskedImage);
182  }
183 
184  LOGL_DEBUG("TRACE5.ip.diffim.KernelCandidateDetection.apply",
185  "Original footprint in parent : %d,%d -> %d,%d -> %d,%d",
186  fpBBox.getMinX(), fpBBox.getMinY(),
187  int(0.5 * (fpBBox.getMinX() + fpBBox.getMaxX())),
188  int(0.5 * (fpBBox.getMinY() + fpBBox.getMaxY())),
189  fpBBox.getMaxX(), fpBBox.getMaxY());
190 
191  /* Grow the footprint
192  * flag true = isotropic grow = slow
193  * flag false = 'manhattan grow' = fast
194  *
195  * The manhattan masks are rotated 45 degree w.r.t. the coordinate
196  * system. They intersect the vertices of the rectangle that would
197  * connect pixels (X0,Y0) (X1,Y0), (X0,Y1), (X1,Y1).
198  *
199  * The isotropic masks do take considerably longer to grow and are
200  * basically elliptical. X0, X1, Y0, Y1 delimit the extent of the
201  * ellipse.
202  *
203  * In both cases, since the masks aren't rectangles oriented with
204  * the image coordinate system, when we DO extract such rectangles
205  * as subimages for kernel fitting, some corner pixels can be found
206  * in multiple subimages.
207  *
208  */
209  std::shared_ptr<afwDetect::Footprint> fpGrow = std::make_shared<afwDetect::Footprint>(
210  fp->getSpans()->dilated(fpGrowPix, afwGeom::Stencil::MANHATTAN)
211  );
212 
213  /* Next we look at the image within this Footprint.
214  */
215  geom::Box2I fpGrowBBox = fpGrow->getBBox();
216  LOGL_DEBUG("TRACE5.ip.diffim.KernelCandidateDetection.apply",
217  "Grown footprint in parent : %d,%d -> %d,%d -> %d,%d",
218  fpGrowBBox.getMinX(), fpGrowBBox.getMinY(),
219  int(0.5 * (fpGrowBBox.getMinX() + fpGrowBBox.getMaxX())),
220  int(0.5 * (fpGrowBBox.getMinY() + fpGrowBBox.getMaxY())),
221  fpGrowBBox.getMaxX(), fpGrowBBox.getMaxY());
222 
223  /* Failure Condition 2)
224  * Grown off the image
225  */
226  if (!(templateMaskedImage->getBBox().contains(fpGrowBBox))) {
227  LOGL_DEBUG("TRACE3.ip.diffim.KernelCandidateDetection.apply",
228  "Footprint grown off image");
229  return false;
230  }
231 
232  /* Grab subimages; report any exception */
233  bool subimageHasFailed = false;
234  try {
235  afwImage::MaskedImage<PixelT> templateSubimage(*templateMaskedImage, fpGrowBBox);
236  afwImage::MaskedImage<PixelT> scienceSubimage(*scienceMaskedImage, fpGrowBBox);
237 
238  // Search for any masked pixels within the footprint
239  fsb.apply(*(templateSubimage.getMask()));
240  if (fsb.getBits() & _badBitMask) {
241  LOGL_DEBUG("TRACE3.ip.diffim.KernelCandidateDetection.apply",
242  "Footprint has masked pix (vals=%d) in image to convolve",
243  fsb.getBits());
244  subimageHasFailed = true;
245  }
246 
247  fsb.apply(*(scienceSubimage.getMask()));
248  if (fsb.getBits() & _badBitMask) {
249  LOGL_DEBUG("TRACE3.ip.diffim.KernelCandidateDetection.apply",
250  "Footprint has masked pix (vals=%d) in image not to convolve",
251  fsb.getBits());
252  subimageHasFailed = true;
253  }
254 
255  } catch (pexExcept::Exception& e) {
256  LOGL_DEBUG("TRACE3.ip.diffim.KernelCandidateDetection.apply",
257  "Exception caught extracting Footprint");
258  LOGL_DEBUG("TRACE4.ip.diffim.KernelCandidateDetection.apply",
259  e.what());
260  subimageHasFailed = true;
261  }
262  if (subimageHasFailed) {
263  return false;
264  } else {
265  /* We have a good candidate */
266  _footprints.push_back(fpGrow);
267  return true;
268  }
269  }
270 
271 /***********************************************************************************************************/
272 //
273 // Explicit instantiations
274 //
275  typedef float PixelT;
276  template class KernelCandidateDetection<PixelT>;
277 
278 }}} // end of namespace lsst::ip::diffim
lsst::afw::image
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
Definition: imageAlgorithm.dox:1
lsst::afw::detection::Footprint::getBBox
lsst::geom::Box2I getBBox() const
Return the Footprint's bounding box.
Definition: Footprint.h:208
std::string
STL class.
std::shared_ptr< lsst::afw::image::MaskedImage< PixelT > >
lsst::ip::diffim::KernelCandidateDetection
Search through images for Footprints with no masked pixels.
Definition: KernelCandidateDetection.h:35
FindSetBits.h
Image Subtraction helper functions.
std::vector< std::string >
lsst::ip::diffim::PixelT
float PixelT
Definition: KernelCandidate.cc:383
lsst::afw
Definition: imageAlgorithm.dox:1
lsst::ip::diffim::KernelCandidateDetection::apply
void apply(MaskedImagePtr const &templateMaskedImage, MaskedImagePtr const &scienceMaskedImage)
Runs Detection on a single image for significant peaks, and checks returned Footprints for Masked pix...
Definition: KernelCandidateDetection.cc:79
lsst::afw::detection::Footprint::getSpans
std::shared_ptr< geom::SpanSet > getSpans() const
Return a shared pointer to the SpanSet.
Definition: Footprint.h:115
KernelCandidateDetection.h
Detect candidates for kernels within 2 images.
lsst::afw::image::MaskedImage::getBBox
lsst::geom::Box2I getBBox(ImageOrigin const origin=PARENT) const
Definition: MaskedImage.h:1097
lsst::ip::diffim::FindSetBits::apply
void apply(MaskT const &mask)
Definition: FindSetBits.h:68
geom.h
geom.h
lsst::afw::detection::FootprintSet::getFootprints
std::shared_ptr< FootprintList > getFootprints()
: Return the Footprints of detected objects
Definition: FootprintSet.h:156
std::string::clear
T clear(T... args)
lsst::afw::detection::FootprintSet
A set of Footprints, associated with a MaskedImage.
Definition: FootprintSet.h:53
lsst::afw::image::MaskedImage< PixelT >
lsst::afw::image::Mask::getPlaneBitMask
static MaskPixelT getPlaneBitMask(const std::vector< std::string > &names)
Return the bitmask corresponding to a vector of plane names OR'd together.
Definition: Mask.cc:379
image
afw::table::Key< afw::table::Array< ImagePixelT > > image
Definition: HeavyFootprint.cc:216
std::string::c_str
T c_str(T... args)
lsst::afw::table::Footprint
lsst::afw::detection::Footprint Footprint
Definition: Source.h:59
PropertySet.h
lsst::geom::Box2I::contains
bool contains(Point2I const &point) const noexcept
Return true if the box contains the point.
Definition: Box.cc:114
lsst::afw::detection::Threshold
A Threshold is used to pass a threshold value to detection algorithms.
Definition: Threshold.h:43
lsst::afw::detection::createThreshold
Threshold createThreshold(const double value, const std::string type="value", const bool polarity=true)
Factory method for creating Threshold objects.
Definition: Threshold.cc:109
lsst::ip::diffim::FindSetBits::getBits
MaskT::Pixel getBits() const
Definition: FindSetBits.h:65
image.h
detection.h
lsst
A base class for image defects.
Definition: imageAlgorithm.dox:1
LSST_EXCEPT
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
lsst::afw::detection
Definition: Footprint.h:50
lsst::afw::detection::Footprint::getArea
std::size_t getArea() const
Return the number of pixels in this Footprint.
Definition: Footprint.h:173
lsst::geom
Definition: geomOperators.dox:4
lsst::geom::Box2I::getMaxY
int getMaxY() const noexcept
Definition: Box.h:162
LOGL_DEBUG
#define LOGL_DEBUG(logger, message...)
Definition: Log.h:504
std::vector::begin
T begin(T... args)
lsst::geom::Box2I::getMaxX
int getMaxX() const noexcept
Definition: Box.h:161
std
STL namespace.
lsst::geom::Point< int, 2 >
lsst::daf::base::PropertySet
Class for storing generic metadata.
Definition: PropertySet.h:67
lsst::ip::diffim::KernelCandidateDetection::KernelCandidateDetection
KernelCandidateDetection(lsst::daf::base::PropertySet const &ps)
Definition: KernelCandidateDetection.cc:35
lsst::geom::Box2I
An integer coordinate rectangle.
Definition: Box.h:55
lsst::geom::Box2I::getMinX
int getMinX() const noexcept
Definition: Box.h:157
lsst::ip::diffim::FindSetBits
Class to accumulate Mask bits.
Definition: FindSetBits.h:53
lsst::pex::exceptions
Definition: Exception.h:37
std::size_t
lsst::pex::exceptions::Exception
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
std::vector::end
T end(T... args)
Exception.h
lsst::afw::detection::Footprint
Class to describe the properties of a detected object from an image.
Definition: Footprint.h:63
lsst::ip::diffim::KernelCandidateDetection::growCandidate
bool growCandidate(std::shared_ptr< lsst::afw::detection::Footprint > fp, int fpGrowPix, MaskedImagePtr const &templateMaskedImage, MaskedImagePtr const &scienceMaskedImage)
Definition: KernelCandidateDetection.cc:147
lsst::afw::image::MaskedImage::getMask
MaskPtr getMask() const
Return a (shared_ptr to) the MaskedImage's mask.
Definition: MaskedImage.h:1069
lsst::geom::Extent< int, 2 >
lsst::pex::exceptions::Exception::what
virtual char const * what(void) const noexcept
Return a character string summarizing this exception.
Definition: Exception.cc:99
Log.h
LSST DM logging module built on log4cxx.
lsst::geom::Box2I::getMinY
int getMinY() const noexcept
Definition: Box.h:158
lsst::afw::geom
Definition: frameSetUtils.h:40