LSST Applications g0b6bd0c080+a72a5dd7e6,g1182afd7b4+2a019aa3bb,g17e5ecfddb+2b8207f7de,g1d67935e3f+06cf436103,g38293774b4+ac198e9f13,g396055baef+6a2097e274,g3b44f30a73+6611e0205b,g480783c3b1+98f8679e14,g48ccf36440+89c08d0516,g4b93dc025c+98f8679e14,g5c4744a4d9+a302e8c7f0,g613e996a0d+e1c447f2e0,g6c8d09e9e7+25247a063c,g7271f0639c+98f8679e14,g7a9cd813b8+124095ede6,g9d27549199+a302e8c7f0,ga1cf026fa3+ac198e9f13,ga32aa97882+7403ac30ac,ga786bb30fb+7a139211af,gaa63f70f4e+9994eb9896,gabf319e997+ade567573c,gba47b54d5d+94dc90c3ea,gbec6a3398f+06cf436103,gc6308e37c7+07dd123edb,gc655b1545f+ade567573c,gcc9029db3c+ab229f5caf,gd01420fc67+06cf436103,gd877ba84e5+06cf436103,gdb4cecd868+6f279b5b48,ge2d134c3d5+cc4dbb2e3f,ge448b5faa6+86d1ceac1d,gecc7e12556+98f8679e14,gf3ee170dca+25247a063c,gf4ac96e456+ade567573c,gf9f5ea5b4d+ac198e9f13,gff490e6085+8c2580be5c,w.2022.27
LSST Data Management Base Package
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
23namespace geom = lsst::geom;
24namespace afwGeom = lsst::afw::geom;
25namespace afwImage = lsst::afw::image;
28
29namespace lsst {
30namespace ip {
31namespace 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;
277
278}}} // end of namespace lsst::ip::diffim
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
Image Subtraction helper functions.
afw::table::Key< afw::table::Array< ImagePixelT > > image
Detect candidates for kernels within 2 images.
LSST DM logging module built on log4cxx.
#define LOGL_DEBUG(logger, message...)
Log a debug-level message using a varargs/printf style interface.
Definition: Log.h:515
T begin(T... args)
T c_str(T... args)
Class to describe the properties of a detected object from an image.
Definition: Footprint.h:63
A set of Footprints, associated with a MaskedImage.
Definition: FootprintSet.h:55
std::shared_ptr< FootprintList > getFootprints()
: Return the Footprints of detected objects
Definition: FootprintSet.h:162
A Threshold is used to pass a threshold value to detection algorithms.
Definition: Threshold.h:43
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:412
A class to manipulate images, masks, and variance as a single object.
Definition: MaskedImage.h:73
MaskPtr getMask() const
Return a (shared_ptr to) the MaskedImage's mask.
Definition: MaskedImage.h:1030
Class for storing generic metadata.
Definition: PropertySet.h:66
An integer coordinate rectangle.
Definition: Box.h:55
int getMinY() const noexcept
Definition: Box.h:158
int getMinX() const noexcept
Definition: Box.h:157
int getMaxX() const noexcept
Definition: Box.h:161
int getMaxY() const noexcept
Definition: Box.h:162
Class to accumulate Mask bits.
Definition: FindSetBits.h:53
void apply(MaskT const &mask)
Definition: FindSetBits.h:68
MaskT::Pixel getBits() const
Definition: FindSetBits.h:65
Search through images for Footprints with no masked pixels.
bool growCandidate(std::shared_ptr< lsst::afw::detection::Footprint > fp, int fpGrowPix, MaskedImagePtr const &templateMaskedImage, MaskedImagePtr const &scienceMaskedImage)
KernelCandidateDetection(lsst::daf::base::PropertySet const &ps)
void apply(MaskedImagePtr const &templateMaskedImage, MaskedImagePtr const &scienceMaskedImage)
Runs Detection on a single image for significant peaks, and checks returned Footprints for Masked pix...
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
virtual char const * what(void) const noexcept
Return a character string summarizing this exception.
Definition: Exception.cc:99
T clear(T... args)
T end(T... args)
Threshold createThreshold(const double value, const std::string type="value", const bool polarity=true)
Factory method for creating Threshold objects.
Definition: Threshold.cc:109
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
lsst::afw::detection::Footprint Footprint
Definition: Source.h:57
A base class for image defects.
STL namespace.