LSSTApplications  18.0.0+106,18.0.0+50,19.0.0,19.0.0+1,19.0.0+10,19.0.0+11,19.0.0+13,19.0.0+17,19.0.0+2,19.0.0-1-g20d9b18+6,19.0.0-1-g425ff20,19.0.0-1-g5549ca4,19.0.0-1-g580fafe+6,19.0.0-1-g6fe20d0+1,19.0.0-1-g7011481+9,19.0.0-1-g8c57eb9+6,19.0.0-1-gb5175dc+11,19.0.0-1-gdc0e4a7+9,19.0.0-1-ge272bc4+6,19.0.0-1-ge3aa853,19.0.0-10-g448f008b,19.0.0-12-g6990b2c,19.0.0-2-g0d9f9cd+11,19.0.0-2-g3d9e4fb2+11,19.0.0-2-g5037de4,19.0.0-2-gb96a1c4+3,19.0.0-2-gd955cfd+15,19.0.0-3-g2d13df8,19.0.0-3-g6f3c7dc,19.0.0-4-g725f80e+11,19.0.0-4-ga671dab3b+1,19.0.0-4-gad373c5+3,19.0.0-5-ga2acb9c+2,19.0.0-5-gfe96e6c+2,w.2020.01
LSSTDataManagementBasePackage
KernelCandidate.cc
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
12 #include "boost/timer.hpp"
13 
14 #include "lsst/afw/math.h"
15 #include "lsst/afw/image.h"
16 #include "lsst/log/Log.h"
18 
23 
24 namespace afwMath = lsst::afw::math;
25 namespace afwImage = lsst::afw::image;
27 
28 namespace lsst {
29 namespace ip {
30 namespace diffim {
31 
32 template <typename PixelT>
33 KernelCandidate<PixelT>::KernelCandidate(float const xCenter, float const yCenter,
34  MaskedImagePtr const& templateMaskedImage,
35  MaskedImagePtr const& scienceMaskedImage,
37  : lsst::afw::math::SpatialCellImageCandidate(xCenter, yCenter),
38  _templateMaskedImage(templateMaskedImage),
39  _scienceMaskedImage(scienceMaskedImage),
40  _varianceEstimate(),
41  _ps(ps.deepCopy()),
42  _source(),
43  _coreFlux(),
44  _isInitialized(false),
45  _useRegularization(false),
46  _fitForBackground(ps.getAsBool("fitForBackground")),
47  _kernelSolutionOrig(),
48  _kernelSolutionPca() {
49  /* Rank by mean core S/N in science image */
50  ImageStatistics<PixelT> imstats(ps);
51  int candidateCoreRadius = _ps->getAsInt("candidateCoreRadius");
52  try {
53  imstats.apply(*_scienceMaskedImage, candidateCoreRadius);
54  } catch (pexExcept::Exception& e) {
55  LOGL_DEBUG("TRACE2.ip.diffim.KernelCandidate",
56  "Unable to calculate core imstats for ranking Candidate %d", this->getId());
58  return;
59  }
60 
61  _coreFlux = imstats.getMean();
62  LOGL_DEBUG("TRACE4.ip.diffim.KernelCandidate", "Candidate %d at %.2f %.2f with ranking %.2f",
63  this->getId(), this->getXCenter(), this->getYCenter(), _coreFlux);
64 }
65 
66 template <typename PixelT>
68  MaskedImagePtr const& scienceMaskedImage,
70  : lsst::afw::math::SpatialCellImageCandidate(source->getX(), source->getY()),
71  _templateMaskedImage(templateMaskedImage),
72  _scienceMaskedImage(scienceMaskedImage),
73  _varianceEstimate(),
74  _ps(ps.deepCopy()),
75  _source(source),
76  _coreFlux(source->getPsfInstFlux()),
77  _isInitialized(false),
78  _useRegularization(false),
79  _fitForBackground(ps.getAsBool("fitForBackground")),
80  _kernelSolutionOrig(),
81  _kernelSolutionPca() {
82  LOGL_DEBUG("TRACE4.ip.diffim.KernelCandidate", "Candidate %d at %.2f %.2f with ranking %.2f",
83  this->getId(), this->getXCenter(), this->getYCenter(), _coreFlux);
84 }
85 
86 template <typename PixelT>
88  build(basisList, Eigen::MatrixXd());
89 }
90 
91 template <typename PixelT>
93  Eigen::MatrixXd const& hMat) {
94  /* Examine the property set for control over the variance estimate */
96  afwImage::Image<afwImage::VariancePixel>(*(_scienceMaskedImage->getVariance()), true);
97  /* Variance estimate comes from sum of image variances */
98  var += (*(_templateMaskedImage->getVariance()));
99 
100  if (_ps->getAsBool("constantVarianceWeighting")) {
101  /* Constant variance weighting */
103  float varValue;
104  if (varStats.getValue(afwMath::MEDIAN) <= 0.0)
105  varValue = 1.0;
106  else
107  varValue = varStats.getValue(afwMath::MEDIAN);
108  LOGL_DEBUG("TRACE4.ip.diffim.KernelCandidate", "Candidate %d using constant variance of %.2f",
109  this->getId(), varValue);
110  var = varValue;
111  }
112 
113  _varianceEstimate = VariancePtr(new afwImage::Image<afwImage::VariancePixel>(var));
114 
115  try {
116  _buildKernelSolution(basisList, hMat);
117  } catch (pexExcept::Exception& e) {
118  throw e;
119  }
120 
121  if (_ps->getAsBool("iterateSingleKernel") && (!(_ps->getAsBool("constantVarianceWeighting")))) {
123  _varianceEstimate = diffim.getVariance();
124 
125  try {
126  _buildKernelSolution(basisList, hMat);
127  } catch (pexExcept::Exception& e) {
128  throw e;
129  }
130  }
131 
132  _isInitialized = true;
133 }
134 
135 template <typename PixelT>
137  Eigen::MatrixXd const& hMat) {
138  bool checkConditionNumber = _ps->getAsBool("checkConditionNumber");
139  double maxConditionNumber = _ps->getAsDouble("maxConditionNumber");
140  std::string conditionNumberType = _ps->getAsString("conditionNumberType");
142  if (conditionNumberType == "SVD") {
143  ctype = KernelSolution::SVD;
144  } else if (conditionNumberType == "EIGENVALUE") {
146  } else {
147  throw LSST_EXCEPT(pexExcept::Exception, "conditionNumberType not recognized");
148  }
149 
150  /* Do we have a regularization matrix? If so use it */
151  if (hMat.size() > 0) {
152  _useRegularization = true;
153  LOGL_DEBUG("TRACE4.ip.diffim.KernelCandidate.build", "Using kernel regularization");
154 
155  if (_isInitialized) {
156  _kernelSolutionPca = std::shared_ptr<StaticKernelSolution<PixelT> >(
157  new RegularizedKernelSolution<PixelT>(basisList, _fitForBackground, hMat, *_ps));
158  _kernelSolutionPca->build(*(_templateMaskedImage->getImage()), *(_scienceMaskedImage->getImage()),
159  *_varianceEstimate);
160  if (checkConditionNumber) {
161  if (_kernelSolutionPca->getConditionNumber(ctype) > maxConditionNumber) {
162  LOGL_DEBUG("TRACE4.ip.diffim.KernelCandidate",
163  "Candidate %d solution has bad condition number", this->getId());
165  return;
166  }
167  }
168  _kernelSolutionPca->solve();
169  } else {
170  _kernelSolutionOrig = std::shared_ptr<StaticKernelSolution<PixelT> >(
171  new RegularizedKernelSolution<PixelT>(basisList, _fitForBackground, hMat, *_ps));
172  _kernelSolutionOrig->build(*(_templateMaskedImage->getImage()),
173  *(_scienceMaskedImage->getImage()), *_varianceEstimate);
174  if (checkConditionNumber) {
175  if (_kernelSolutionOrig->getConditionNumber(ctype) > maxConditionNumber) {
176  LOGL_DEBUG("TRACE4.ip.diffim.KernelCandidate",
177  "Candidate %d solution has bad condition number", this->getId());
179  return;
180  }
181  }
182  _kernelSolutionOrig->solve();
183  }
184  } else {
185  _useRegularization = false;
186  LOGL_DEBUG("TRACE4.ip.diffim.KernelCandidate.build", "Not using kernel regularization");
187  if (_isInitialized) {
188  _kernelSolutionPca = std::shared_ptr<StaticKernelSolution<PixelT> >(
189  new StaticKernelSolution<PixelT>(basisList, _fitForBackground));
190  _kernelSolutionPca->build(*(_templateMaskedImage->getImage()), *(_scienceMaskedImage->getImage()),
191  *_varianceEstimate);
192  if (checkConditionNumber) {
193  if (_kernelSolutionPca->getConditionNumber(ctype) > maxConditionNumber) {
194  LOGL_DEBUG("TRACE4.ip.diffim.KernelCandidate",
195  "Candidate %d solution has bad condition number", this->getId());
197  return;
198  }
199  }
200  _kernelSolutionPca->solve();
201  } else {
202  _kernelSolutionOrig = std::shared_ptr<StaticKernelSolution<PixelT> >(
203  new StaticKernelSolution<PixelT>(basisList, _fitForBackground));
204  _kernelSolutionOrig->build(*(_templateMaskedImage->getImage()),
205  *(_scienceMaskedImage->getImage()), *_varianceEstimate);
206  if (checkConditionNumber) {
207  if (_kernelSolutionOrig->getConditionNumber(ctype) > maxConditionNumber) {
208  LOGL_DEBUG("TRACE4.ip.diffim.KernelCandidate",
209  "Candidate %d solution has bad condition number", this->getId());
211  return;
212  }
213  }
214  _kernelSolutionOrig->solve();
215  }
216  }
217 }
218 
219 template <typename PixelT>
221  if (cand == KernelCandidate::ORIG) {
222  if (_kernelSolutionOrig)
223  return _kernelSolutionOrig->getKernel();
224  else
225  throw LSST_EXCEPT(pexExcept::Exception, "Original kernel does not exist");
226  } else if (cand == KernelCandidate::PCA) {
227  if (_kernelSolutionPca)
228  return _kernelSolutionPca->getKernel();
229  else
230  throw LSST_EXCEPT(pexExcept::Exception, "Pca kernel does not exist");
231  } else if (cand == KernelCandidate::RECENT) {
232  if (_kernelSolutionPca)
233  return _kernelSolutionPca->getKernel();
234  else if (_kernelSolutionOrig)
235  return _kernelSolutionOrig->getKernel();
236  else
237  throw LSST_EXCEPT(pexExcept::Exception, "No kernels exist");
238  } else {
239  throw LSST_EXCEPT(pexExcept::Exception, "Invalid CandidateSwitch, cannot get kernel");
240  }
241 }
242 
243 template <typename PixelT>
245  if (cand == KernelCandidate::ORIG) {
246  if (_kernelSolutionOrig)
247  return _kernelSolutionOrig->getBackground();
248  else
249  throw LSST_EXCEPT(pexExcept::Exception, "Original kernel does not exist");
250  } else if (cand == KernelCandidate::PCA) {
251  if (_kernelSolutionPca)
252  return _kernelSolutionPca->getBackground();
253  else
254  throw LSST_EXCEPT(pexExcept::Exception, "Pca kernel does not exist");
255  } else if (cand == KernelCandidate::RECENT) {
256  if (_kernelSolutionPca)
257  return _kernelSolutionPca->getBackground();
258  else if (_kernelSolutionOrig)
259  return _kernelSolutionOrig->getBackground();
260  else
261  throw LSST_EXCEPT(pexExcept::Exception, "No kernels exist");
262  } else {
263  throw LSST_EXCEPT(pexExcept::Exception, "Invalid CandidateSwitch, cannot get background");
264  }
265 }
266 
267 template <typename PixelT>
269  if (cand == KernelCandidate::ORIG) {
270  if (_kernelSolutionOrig)
271  return _kernelSolutionOrig->getKsum();
272  else
273  throw LSST_EXCEPT(pexExcept::Exception, "Original kernel does not exist");
274  } else if (cand == KernelCandidate::PCA) {
275  if (_kernelSolutionPca)
276  return _kernelSolutionPca->getKsum();
277  else
278  throw LSST_EXCEPT(pexExcept::Exception, "Pca kernel does not exist");
279  } else if (cand == KernelCandidate::RECENT) {
280  if (_kernelSolutionPca)
281  return _kernelSolutionPca->getKsum();
282  else if (_kernelSolutionOrig)
283  return _kernelSolutionOrig->getKsum();
284  else
285  throw LSST_EXCEPT(pexExcept::Exception, "No kernels exist");
286  } else {
287  throw LSST_EXCEPT(pexExcept::Exception, "Invalid CandidateSwitch, cannot get kSum");
288  }
289 }
290 
291 template <typename PixelT>
293  CandidateSwitch cand) const {
294  if (cand == KernelCandidate::ORIG) {
295  if (_kernelSolutionOrig)
296  return _kernelSolutionOrig->makeKernelImage();
297  else
298  throw LSST_EXCEPT(pexExcept::Exception, "Original kernel does not exist");
299  } else if (cand == KernelCandidate::PCA) {
300  if (_kernelSolutionPca)
301  return _kernelSolutionPca->makeKernelImage();
302  else
303  throw LSST_EXCEPT(pexExcept::Exception, "Pca kernel does not exist");
304  } else if (cand == KernelCandidate::RECENT) {
305  if (_kernelSolutionPca)
306  return _kernelSolutionPca->makeKernelImage();
307  else if (_kernelSolutionOrig)
308  return _kernelSolutionOrig->makeKernelImage();
309  else
310  throw LSST_EXCEPT(pexExcept::Exception, "No kernels exist");
311  } else {
312  throw LSST_EXCEPT(pexExcept::Exception, "Invalid CandidateSwitch, cannot get kernel image");
313  }
314 }
315 
316 template <typename PixelT>
319 }
320 
321 template <typename PixelT>
323  CandidateSwitch cand) const {
324  if (cand == KernelCandidate::ORIG) {
325  if (_kernelSolutionOrig)
326  return _kernelSolutionOrig;
327  else
328  throw LSST_EXCEPT(pexExcept::Exception, "Original kernel does not exist");
329  } else if (cand == KernelCandidate::PCA) {
330  if (_kernelSolutionPca)
331  return _kernelSolutionPca;
332  else
333  throw LSST_EXCEPT(pexExcept::Exception, "Pca kernel does not exist");
334  } else if (cand == KernelCandidate::RECENT) {
335  if (_kernelSolutionPca)
336  return _kernelSolutionPca;
337  else if (_kernelSolutionOrig)
338  return _kernelSolutionOrig;
339  else
340  throw LSST_EXCEPT(pexExcept::Exception, "No kernels exist");
341  } else {
342  throw LSST_EXCEPT(pexExcept::Exception, "Invalid CandidateSwitch, cannot get solution");
343  }
344 }
345 
346 template <typename PixelT>
348  if (cand == KernelCandidate::ORIG) {
349  if (_kernelSolutionOrig)
350  return getDifferenceImage(_kernelSolutionOrig->getKernel(), _kernelSolutionOrig->getBackground());
351  else
352  throw LSST_EXCEPT(pexExcept::Exception, "Original kernel does not exist");
353  } else if (cand == KernelCandidate::PCA) {
354  if (_kernelSolutionPca)
355  return getDifferenceImage(_kernelSolutionPca->getKernel(), _kernelSolutionPca->getBackground());
356  else
357  throw LSST_EXCEPT(pexExcept::Exception, "Pca kernel does not exist");
358  } else if (cand == KernelCandidate::RECENT) {
359  if (_kernelSolutionPca)
360  return getDifferenceImage(_kernelSolutionPca->getKernel(), _kernelSolutionPca->getBackground());
361  else if (_kernelSolutionOrig)
362  return getDifferenceImage(_kernelSolutionOrig->getKernel(), _kernelSolutionOrig->getBackground());
363  else
364  throw LSST_EXCEPT(pexExcept::Exception, "No kernels exist");
365  } else {
366  throw LSST_EXCEPT(pexExcept::Exception, "Invalid CandidateSwitch, cannot get diffim");
367  }
368 }
369 
370 template <typename PixelT>
373  /* Make diffim and set chi2 from result */
375  convolveAndSubtract(*_templateMaskedImage, *_scienceMaskedImage, *kernel, background);
376  return diffIm;
377 }
378 
379 /***********************************************************************************************************/
380 //
381 // Explicit instantiations
382 //
383 typedef float PixelT;
384 
385 template class KernelCandidate<PixelT>;
386 
387 } // namespace diffim
388 } // namespace ip
389 } // namespace lsst
VariancePtr getVariance() const
Return a (shared_ptr to) the MaskedImage&#39;s variance.
Definition: MaskedImage.h:1090
void setStatus(Status status)
Set the candidate&#39;s status.
Definition: SpatialCell.cc:54
void apply(lsst::afw::image::MaskedImage< PixelT > const &image)
double getBackground(CandidateSwitch cand) const
afw::table::Key< afw::table::Array< ImagePixelT > > image
Class stored in SpatialCells for spatial Kernel fitting.
float getXCenter() const
Return the object&#39;s column-centre.
Definition: SpatialCell.h:90
afw::image::MaskedImage< PixelT > getDifferenceImage(CandidateSwitch cand)
Calculate associated difference image using internal solutions.
Image Subtraction helper functions.
std::shared_ptr< StaticKernelSolution< PixelT > > getKernelSolution(CandidateSwitch cand) const
std::shared_ptr< afw::math::Kernel > getKernel(CandidateSwitch cand) const
Return results of kernel solution.
void build(afw::math::KernelList const &basisList)
Core functionality of KernelCandidate, to build and fill a KernelSolution.
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
boost::shared_ptr< ImageT > getKernelImage(CandidateSwitch cand) const
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.
int getId() const
Return the candidate&#39;s unique ID.
Definition: SpatialCell.h:104
#define LOGL_DEBUG(logger, message...)
Log a debug-level message using a varargs/printf style interface.
Definition: Log.h:504
A class to evaluate image statistics.
Definition: Statistics.h:215
Declaration of classes to store the solution for convolution kernels.
STL class.
LSST DM logging module built on log4cxx.
std::shared_ptr< afw::image::Image< afw::image::VariancePixel > > VariancePtr
estimate sample median
Definition: Statistics.h:70
A base class for image defects.
SpatialCellImageCandidate(float const xCenter, float const yCenter)
ctor
Definition: SpatialCell.h:129
Statistics makeStatistics(lsst::afw::image::Image< Pixel > const &img, lsst::afw::image::Mask< image::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl=StatisticsControl())
Handle a watered-down front-end to the constructor (no variance)
Definition: Statistics.h:354
A class to manipulate images, masks, and variance as a single object.
Definition: MaskedImage.h:73
const char * source()
Source function that allows astChannel to source from a Stream.
Definition: Stream.h:224
Class used by SpatialModelCell for spatial Kernel fitting.
KernelCandidate(float const xCenter, float const yCenter, MaskedImagePtr const &templateMaskedImage, MaskedImagePtr const &scienceMaskedImage, daf::base::PropertySet const &ps)
Constructor.
double getValue(Property const prop=NOTHING) const
Return the value of the desired property (if specified in the constructor)
Definition: Statistics.cc:1056
Class to calculate difference image statistics.
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
boost::shared_ptr< ImageT const > getImage() const
float getYCenter() const
Return the object&#39;s row-centre.
Definition: SpatialCell.h:93
Class for storing generic metadata.
Definition: PropertySet.h:67
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects...
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:58
Image Subtraction helper functions.
double getKsum(CandidateSwitch cand) const