12 #include "boost/timer.hpp" 14 #include "lsst/afw/math.h" 15 #include "lsst/afw/image.h" 16 #include "lsst/log/Log.h" 17 #include "lsst/pex/exceptions/Runtime.h" 24 namespace afwMath = lsst::afw::math;
25 namespace afwImage = lsst::afw::image;
26 namespace pexExcept = lsst::pex::exceptions;
32 template <
typename PixelT>
36 MaskedImagePtr
const& templateMaskedImage,
37 MaskedImagePtr
const& scienceMaskedImage,
38 lsst::pex::policy::Policy
const& policy
40 lsst::afw::math::SpatialCellImageCandidate(xCenter, yCenter),
41 _templateMaskedImage(templateMaskedImage),
42 _scienceMaskedImage(scienceMaskedImage),
47 _isInitialized(false),
48 _useRegularization(false),
49 _fitForBackground(_policy.getBool(
"fitForBackground")),
50 _kernelSolutionOrig(),
55 ImageStatistics<PixelT> imstats(_policy);
56 int candidateCoreRadius = _policy.getInt(
"candidateCoreRadius");
58 imstats.apply(*_scienceMaskedImage, candidateCoreRadius);
59 }
catch (pexExcept::Exception& e) {
60 LOGL_DEBUG(
"TRACE2.ip.diffim.KernelCandidate",
61 "Unable to calculate core imstats for ranking Candidate %d", this->getId());
62 this->setStatus(afwMath::SpatialCellCandidate::BAD);
66 _coreFlux = imstats.getMean();
67 LOGL_DEBUG(
"TRACE4.ip.diffim.KernelCandidate",
68 "Candidate %d at %.2f %.2f with ranking %.2f",
69 this->getId(), this->getXCenter(), this->getYCenter(), _coreFlux);
72 template <
typename PixelT>
73 KernelCandidate<PixelT>::KernelCandidate(
74 SourcePtr
const& source,
75 MaskedImagePtr
const& templateMaskedImage,
76 MaskedImagePtr
const& scienceMaskedImage,
77 lsst::pex::policy::Policy
const& policy
79 lsst::afw::math::SpatialCellImageCandidate(source->getX(), source->getY()),
80 _templateMaskedImage(templateMaskedImage),
81 _scienceMaskedImage(scienceMaskedImage),
85 _coreFlux(source->getPsfFlux()),
86 _isInitialized(false),
87 _useRegularization(false),
88 _fitForBackground(_policy.getBool(
"fitForBackground")),
89 _kernelSolutionOrig(),
92 LOGL_DEBUG(
"TRACE4.ip.diffim.KernelCandidate",
93 "Candidate %d at %.2f %.2f with ranking %.2f",
94 this->getId(), this->getXCenter(), this->getYCenter(), _coreFlux);
97 template <
typename PixelT>
98 void KernelCandidate<PixelT>::build(
99 lsst::afw::math::KernelList
const& basisList
101 build(basisList, Eigen::MatrixXd());
104 template <
typename PixelT>
105 void KernelCandidate<PixelT>::build(
106 lsst::afw::math::KernelList
const& basisList,
107 Eigen::MatrixXd
const& hMat
111 afwImage::Image<afwImage::VariancePixel> var =
112 afwImage::Image<afwImage::VariancePixel>(*(_scienceMaskedImage->getVariance()),
true);
114 var += (*(_templateMaskedImage->getVariance()));
116 if (_policy.getBool(
"constantVarianceWeighting")) {
118 afwMath::Statistics varStats = afwMath::makeStatistics(var, afwMath::MEDIAN);
120 if (varStats.getValue(afwMath::MEDIAN) <= 0.0)
123 varValue = varStats.getValue(afwMath::MEDIAN);
124 LOGL_DEBUG(
"TRACE4.ip.diffim.KernelCandidate",
125 "Candidate %d using constant variance of %.2f", this->getId(), varValue);
130 _varianceEstimate = VariancePtr(
new afwImage::Image<afwImage::VariancePixel>(var) );
133 _buildKernelSolution(basisList, hMat);
134 }
catch (pexExcept::Exception &e) {
138 if (_policy.getBool(
"iterateSingleKernel") && (!(_policy.getBool(
"constantVarianceWeighting")))) {
139 afwImage::MaskedImage<PixelT> diffim = getDifferenceImage(KernelCandidate::RECENT);
140 _varianceEstimate = diffim.getVariance();
143 _buildKernelSolution(basisList, hMat);
144 }
catch (pexExcept::Exception &e) {
149 _isInitialized =
true;
153 template <
typename PixelT>
155 Eigen::MatrixXd
const& hMat)
157 bool checkConditionNumber = _policy.getBool(
"checkConditionNumber");
158 double maxConditionNumber = _policy.getDouble(
"maxConditionNumber");
159 std::string conditionNumberType = _policy.getString(
"conditionNumberType");
161 if (conditionNumberType ==
"SVD") {
162 ctype = KernelSolution::SVD;
164 else if (conditionNumberType ==
"EIGENVALUE") {
165 ctype = KernelSolution::EIGENVALUE;
168 throw LSST_EXCEPT(pexExcept::Exception,
"conditionNumberType not recognized");
172 if (hMat.size() > 0) {
173 _useRegularization =
true;
174 LOGL_DEBUG(
"TRACE4.ip.diffim.KernelCandidate.build",
175 "Using kernel regularization");
177 if (_isInitialized) {
178 _kernelSolutionPca = std::shared_ptr<StaticKernelSolution<PixelT> >(
181 _kernelSolutionPca->build(*(_templateMaskedImage->getImage()),
182 *(_scienceMaskedImage->getImage()),
184 if (checkConditionNumber) {
185 if (_kernelSolutionPca->getConditionNumber(ctype) > maxConditionNumber) {
186 LOGL_DEBUG(
"TRACE4.ip.diffim.KernelCandidate",
187 "Candidate %d solution has bad condition number",
189 this->setStatus(afwMath::SpatialCellCandidate::BAD);
193 _kernelSolutionPca->solve();
196 _kernelSolutionOrig = std::shared_ptr<StaticKernelSolution<PixelT> >(
199 _kernelSolutionOrig->build(*(_templateMaskedImage->getImage()),
200 *(_scienceMaskedImage->getImage()),
202 if (checkConditionNumber) {
203 if (_kernelSolutionOrig->getConditionNumber(ctype) > maxConditionNumber) {
204 LOGL_DEBUG(
"TRACE4.ip.diffim.KernelCandidate",
205 "Candidate %d solution has bad condition number",
207 this->setStatus(afwMath::SpatialCellCandidate::BAD);
211 _kernelSolutionOrig->solve();
215 _useRegularization =
false;
216 LOGL_DEBUG(
"TRACE4.ip.diffim.KernelCandidate.build",
217 "Not using kernel regularization");
218 if (_isInitialized) {
219 _kernelSolutionPca = std::shared_ptr<StaticKernelSolution<PixelT> >(
222 _kernelSolutionPca->build(*(_templateMaskedImage->getImage()),
223 *(_scienceMaskedImage->getImage()),
225 if (checkConditionNumber) {
226 if (_kernelSolutionPca->getConditionNumber(ctype) > maxConditionNumber) {
227 LOGL_DEBUG(
"TRACE4.ip.diffim.KernelCandidate",
228 "Candidate %d solution has bad condition number",
230 this->setStatus(afwMath::SpatialCellCandidate::BAD);
234 _kernelSolutionPca->solve();
237 _kernelSolutionOrig = std::shared_ptr<StaticKernelSolution<PixelT> >(
240 _kernelSolutionOrig->build(*(_templateMaskedImage->getImage()),
241 *(_scienceMaskedImage->getImage()),
243 if (checkConditionNumber) {
244 if (_kernelSolutionOrig->getConditionNumber(ctype) > maxConditionNumber) {
245 LOGL_DEBUG(
"TRACE4.ip.diffim.KernelCandidate",
246 "Candidate %d solution has bad condition number",
248 this->setStatus(afwMath::SpatialCellCandidate::BAD);
252 _kernelSolutionOrig->solve();
257 template <
typename PixelT>
259 if (cand == KernelCandidate::ORIG) {
260 if (_kernelSolutionOrig)
263 throw LSST_EXCEPT(pexExcept::Exception,
"Original kernel does not exist");
265 else if (cand == KernelCandidate::PCA) {
266 if (_kernelSolutionPca)
267 return _kernelSolutionPca->getKernel();
269 throw LSST_EXCEPT(pexExcept::Exception,
"Pca kernel does not exist");
271 else if (cand == KernelCandidate::RECENT) {
272 if (_kernelSolutionPca)
273 return _kernelSolutionPca->getKernel();
274 else if (_kernelSolutionOrig)
275 return _kernelSolutionOrig->getKernel();
277 throw LSST_EXCEPT(pexExcept::Exception,
"No kernels exist");
280 throw LSST_EXCEPT(pexExcept::Exception,
"Invalid CandidateSwitch, cannot get kernel");
284 template <
typename PixelT>
286 if (cand == KernelCandidate::ORIG) {
287 if (_kernelSolutionOrig)
290 throw LSST_EXCEPT(pexExcept::Exception,
"Original kernel does not exist");
292 else if (cand == KernelCandidate::PCA) {
293 if (_kernelSolutionPca)
294 return _kernelSolutionPca->getBackground();
296 throw LSST_EXCEPT(pexExcept::Exception,
"Pca kernel does not exist");
298 else if (cand == KernelCandidate::RECENT) {
299 if (_kernelSolutionPca)
300 return _kernelSolutionPca->getBackground();
301 else if (_kernelSolutionOrig)
302 return _kernelSolutionOrig->getBackground();
304 throw LSST_EXCEPT(pexExcept::Exception,
"No kernels exist");
307 throw LSST_EXCEPT(pexExcept::Exception,
"Invalid CandidateSwitch, cannot get background");
311 template <
typename PixelT>
313 if (cand == KernelCandidate::ORIG) {
314 if (_kernelSolutionOrig)
315 return _kernelSolutionOrig->
getKsum();
317 throw LSST_EXCEPT(pexExcept::Exception,
"Original kernel does not exist");
319 else if (cand == KernelCandidate::PCA) {
320 if (_kernelSolutionPca)
321 return _kernelSolutionPca->getKsum();
323 throw LSST_EXCEPT(pexExcept::Exception,
"Pca kernel does not exist");
325 else if (cand == KernelCandidate::RECENT) {
326 if (_kernelSolutionPca)
327 return _kernelSolutionPca->getKsum();
328 else if (_kernelSolutionOrig)
329 return _kernelSolutionOrig->getKsum();
331 throw LSST_EXCEPT(pexExcept::Exception,
"No kernels exist");
334 throw LSST_EXCEPT(pexExcept::Exception,
"Invalid CandidateSwitch, cannot get kSum");
338 template <
typename PixelT>
341 if (cand == KernelCandidate::ORIG) {
342 if (_kernelSolutionOrig)
343 return _kernelSolutionOrig->makeKernelImage();
345 throw LSST_EXCEPT(pexExcept::Exception,
"Original kernel does not exist");
347 else if (cand == KernelCandidate::PCA) {
348 if (_kernelSolutionPca)
349 return _kernelSolutionPca->makeKernelImage();
351 throw LSST_EXCEPT(pexExcept::Exception,
"Pca kernel does not exist");
353 else if (cand == KernelCandidate::RECENT) {
354 if (_kernelSolutionPca)
355 return _kernelSolutionPca->makeKernelImage();
356 else if (_kernelSolutionOrig)
357 return _kernelSolutionOrig->makeKernelImage();
359 throw LSST_EXCEPT(pexExcept::Exception,
"No kernels exist");
362 throw LSST_EXCEPT(pexExcept::Exception,
"Invalid CandidateSwitch, cannot get kernel image");
366 template <
typename PixelT>
368 return getKernelImage(KernelCandidate::ORIG);
371 template <
typename PixelT>
374 if (cand == KernelCandidate::ORIG) {
375 if (_kernelSolutionOrig)
376 return _kernelSolutionOrig;
378 throw LSST_EXCEPT(pexExcept::Exception,
"Original kernel does not exist");
380 else if (cand == KernelCandidate::PCA) {
381 if (_kernelSolutionPca)
382 return _kernelSolutionPca;
384 throw LSST_EXCEPT(pexExcept::Exception,
"Pca kernel does not exist");
386 else if (cand == KernelCandidate::RECENT) {
387 if (_kernelSolutionPca)
388 return _kernelSolutionPca;
389 else if (_kernelSolutionOrig)
390 return _kernelSolutionOrig;
392 throw LSST_EXCEPT(pexExcept::Exception,
"No kernels exist");
395 throw LSST_EXCEPT(pexExcept::Exception,
"Invalid CandidateSwitch, cannot get solution");
399 template <
typename PixelT>
402 if (cand == KernelCandidate::ORIG) {
403 if (_kernelSolutionOrig)
404 return getDifferenceImage(_kernelSolutionOrig->getKernel(),
405 _kernelSolutionOrig->getBackground());
407 throw LSST_EXCEPT(pexExcept::Exception,
"Original kernel does not exist");
409 else if (cand == KernelCandidate::PCA) {
410 if (_kernelSolutionPca)
411 return getDifferenceImage(_kernelSolutionPca->getKernel(),
412 _kernelSolutionPca->getBackground());
414 throw LSST_EXCEPT(pexExcept::Exception,
"Pca kernel does not exist");
416 else if (cand == KernelCandidate::RECENT) {
417 if (_kernelSolutionPca)
418 return getDifferenceImage(_kernelSolutionPca->getKernel(),
419 _kernelSolutionPca->getBackground());
420 else if (_kernelSolutionOrig)
421 return getDifferenceImage(_kernelSolutionOrig->getKernel(),
422 _kernelSolutionOrig->getBackground());
424 throw LSST_EXCEPT(pexExcept::Exception,
"No kernels exist");
427 throw LSST_EXCEPT(pexExcept::Exception,
"Invalid CandidateSwitch, cannot get diffim");
431 template <
typename PixelT>
433 std::shared_ptr<lsst::afw::math::Kernel> kernel,
438 *_scienceMaskedImage,
double getBackground(CandidateSwitch cand) const
Class stored in SpatialCells for spatial Kernel fitting.
Image Subtraction helper functions.
std::shared_ptr< afw::math::Kernel > getKernel(CandidateSwitch cand) const
Return results of kernel solution.
lsst::afw::image::MaskedImage< PixelT > convolveAndSubtract(lsst::afw::image::MaskedImage< PixelT > const &templateImage, lsst::afw::image::MaskedImage< PixelT > const &scienceMaskedImage, lsst::afw::math::Kernel const &convolutionKernel, BackgroundT background, bool invert=true)
Execute fundamental task of convolving template and subtracting it from science image.
Declaration of classes to store the solution for convolution kernels.
Class used by SpatialModelCell for spatial Kernel fitting.
KernelCandidate(float const xCenter, float const yCenter, MaskedImagePtr const &templateMaskedImage, MaskedImagePtr const &scienceMaskedImage, pex::policy::Policy const &policy)
Constructor.
Image Subtraction helper functions.
double getKsum(CandidateSwitch cand) const