12 #include "lsst/afw/math.h"
13 #include "lsst/afw/image.h"
14 #include "lsst/log/Log.h"
15 #include "lsst/pex/policy/Policy.h"
16 #include "lsst/pex/exceptions/Runtime.h"
22 #define DEBUG_IMAGES 0
24 namespace afwMath = lsst::afw::math;
25 namespace afwImage = lsst::afw::image;
26 namespace pexPolicy = lsst::pex::policy;
27 namespace pexExcept = lsst::pex::exceptions;
53 template<
typename PixelT>
55 std::shared_ptr<lsst::afw::math::LinearCombinationKernel> spatialKernel,
56 lsst::afw::math::Kernel::SpatialFunctionPtr spatialBackground,
57 lsst::pex::policy::Policy
const& policy
59 afwMath::CandidateVisitor(),
60 _spatialKernel(spatialKernel),
61 _spatialBackground(spatialBackground),
67 _useCoreStats(_policy.getBool(
"useCoreStats")),
68 _coreRadius(_policy.getInt(
"candidateCoreRadius"))
71 template<
typename PixelT>
73 lsst::afw::math::SpatialCellCandidate *candidate
77 if (kCandidate == NULL) {
78 throw LSST_EXCEPT(pexExcept::LogicError,
79 "Failed to cast SpatialCellCandidate to KernelCandidate");
82 kCandidate->setStatus(afwMath::SpatialCellCandidate::BAD);
83 LOGL_DEBUG(
"TRACE2.ip.diffim.AssessSpatialKernelVisitor.processCandidate",
84 "Cannot process candidate %d, continuing", kCandidate->getId());
88 LOGL_DEBUG(
"TRACE1.ip.diffim.AssessSpatialKernelVisitor.processCandidate",
89 "Processing candidate %d", kCandidate->getId());
96 afwImage::Image<double> kImage(_spatialKernel->getDimensions());
97 double kSum = _spatialKernel->computeImage(kImage,
false,
98 kCandidate->getXCenter(), kCandidate->getYCenter());
99 std::shared_ptr<afwMath::Kernel>
100 kernelPtr(
new afwMath::FixedKernel(kImage));
103 double background = (*_spatialBackground)(kCandidate->getXCenter(), kCandidate->getYCenter());
108 kImage.writeFits(str(boost::format(
"askv_k%d.fits") % kCandidate->getId()));
109 diffim.writeFits(str(boost::format(
"askv_d%d.fits") % kCandidate->getId()));
115 _imstats.apply(diffim, _coreRadius);
117 _imstats.apply(diffim);
118 }
catch (pexExcept::Exception& e) {
119 LOGL_DEBUG(
"TRACE2.ip.diffim.AssessSpatialKernelVisitor.processCandidate",
120 "Unable to calculate imstats for Candidate %d", kCandidate->getId());
121 kCandidate->setStatus(afwMath::SpatialCellCandidate::BAD);
127 LOGL_DEBUG(
"TRACE4.ip.diffim.AssessSpatialKernelVisitor.processCandidate",
128 "Chi2 = %.3f", _imstats.getVariance());
129 LOGL_DEBUG(
"TRACE4.ip.diffim.AssessSpatialKernelVisitor.processCandidate",
131 kCandidate->getXCenter(),
132 kCandidate->getYCenter());
133 LOGL_DEBUG(
"TRACE4.ip.diffim.AssessSpatialKernelVisitor.processCandidate",
134 "Kernel Sum = %.3f", kSum);
135 LOGL_DEBUG(
"TRACE4.ip.diffim.AssessSpatialKernelVisitor.processCandidate",
136 "Background = %.3f", background);
137 LOGL_DEBUG(
"TRACE2.ip.diffim.AssessSpatialKernelVisitor.processCandidate",
138 "Candidate %d resids = %.3f +/- %.3f sigma (%d pix)",
144 bool meanIsNan = std::isnan(_imstats.getMean());
145 bool rmsIsNan = std::isnan(_imstats.getRms());
146 if (meanIsNan || rmsIsNan) {
147 kCandidate->setStatus(afwMath::SpatialCellCandidate::BAD);
148 LOGL_DEBUG(
"TRACE3.ip.diffim.AssessSpatialKernelVisitor.processCandidate",
149 "Rejecting candidate %d, encountered NaN",
150 kCandidate->getId());
155 if (_policy.getBool(
"spatialKernelClipping")) {
156 if (fabs(_imstats.getMean()) > _policy.getDouble(
"candidateResidualMeanMax")) {
157 kCandidate->setStatus(afwMath::SpatialCellCandidate::BAD);
158 LOGL_DEBUG(
"TRACE3.ip.diffim.AssessSpatialKernelVisitor.processCandidate",
159 "Rejecting candidate %d; bad mean residual : |%.3f| > %.3f",
162 _policy.getDouble(
"candidateResidualMeanMax"));
165 else if (_imstats.getRms() > _policy.getDouble(
"candidateResidualStdMax")) {
166 kCandidate->setStatus(afwMath::SpatialCellCandidate::BAD);
167 LOGL_DEBUG(
"TRACE3.ip.diffim.AssessSpatialKernelVisitor.processCandidate",
168 "Rejecting candidate %d; bad residual rms : %.3f > %.3f",
171 _policy.getDouble(
"candidateResidualStdMax"));
175 kCandidate->setStatus(afwMath::SpatialCellCandidate::GOOD);
176 LOGL_DEBUG(
"TRACE3.ip.diffim.AssessSpatialKernelVisitor.processCandidate",
177 "Spatial kernel OK");
182 kCandidate->setStatus(afwMath::SpatialCellCandidate::GOOD);
183 LOGL_DEBUG(
"TRACE5.ip.diffim.AssessSpatialKernelVisitor.processCandidate",
184 "Sigma clipping not enabled");
189 if (!(_useCoreStats)) {
191 _imstats.apply(diffim, _coreRadius);
192 }
catch (pexExcept::Exception& e) {
193 LOGL_DEBUG(
"TRACE2.ip.diffim.AssessSpatialKernelVisitor.processCandidate",
194 "Unable to calculate core imstats for Candidate %d",
195 kCandidate->getId());
196 kCandidate->setStatus(afwMath::SpatialCellCandidate::BAD);
199 LOGL_DEBUG(
"TRACE3.ip.diffim.AssessSpatialKernelVisitor.processCandidate",
200 "Candidate %d core resids = %.3f +/- %.3f sigma (%d pix)",
Asseses the quality of a candidate given a spatial kernel and background model.
AssessSpatialKernelVisitor(std::shared_ptr< lsst::afw::math::LinearCombinationKernel > spatialKernel, lsst::afw::math::Kernel::SpatialFunctionPtr spatialBackground, lsst::pex::policy::Policy const &policy)
Class stored in SpatialCells for spatial Kernel fitting.
afw::image::MaskedImage< PixelT > getDifferenceImage(CandidateSwitch cand)
Calculate associated difference image using internal solutions.
lsst::afw::image::MaskedImage< PixelT > MaskedImageT
bool isInitialized() const
Class used by SpatialModelCell for spatial Kernel fitting.
Class to calculate difference image statistics.
void processCandidate(lsst::afw::math::SpatialCellCandidate *candidate)
Declaration of AssessSpatialKernelVisitor.
Image Subtraction helper functions.