lsst.ip.diffim  16.0-9-g1de645c+6
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>
34  float const xCenter,
35  float const yCenter,
36  MaskedImagePtr const& templateMaskedImage,
37  MaskedImagePtr const& scienceMaskedImage,
38  lsst::pex::policy::Policy const& policy
39  ) :
40  lsst::afw::math::SpatialCellImageCandidate(xCenter, yCenter),
41  _templateMaskedImage(templateMaskedImage),
42  _scienceMaskedImage(scienceMaskedImage),
43  _varianceEstimate(),
44  _policy(policy),
45  _source(),
46  _coreFlux(),
47  _isInitialized(false),
48  _useRegularization(false),
49  _fitForBackground(_policy.getBool("fitForBackground")),
50  _kernelSolutionOrig(),
51  _kernelSolutionPca()
52  {
53 
54  /* Rank by mean core S/N in science image */
55  ImageStatistics<PixelT> imstats(_policy);
56  int candidateCoreRadius = _policy.getInt("candidateCoreRadius");
57  try {
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());
63  return;
64  }
65 
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);
70  }
71 
72  template <typename PixelT>
74  SourcePtr const& source,
75  MaskedImagePtr const& templateMaskedImage,
76  MaskedImagePtr const& scienceMaskedImage,
77  lsst::pex::policy::Policy const& policy
78  ) :
79  lsst::afw::math::SpatialCellImageCandidate(source->getX(), source->getY()),
80  _templateMaskedImage(templateMaskedImage),
81  _scienceMaskedImage(scienceMaskedImage),
82  _varianceEstimate(),
83  _policy(policy),
84  _source(source),
85  _coreFlux(source->getPsfFlux()),
86  _isInitialized(false),
87  _useRegularization(false),
88  _fitForBackground(_policy.getBool("fitForBackground")),
89  _kernelSolutionOrig(),
90  _kernelSolutionPca()
91  {
92  LOGL_DEBUG("TRACE4.ip.diffim.KernelCandidate",
93  "Candidate %d at %.2f %.2f with ranking %.2f",
94  this->getId(), this->getXCenter(), this->getYCenter(), _coreFlux);
95  }
96 
97  template <typename PixelT>
99  lsst::afw::math::KernelList const& basisList
100  ) {
101  build(basisList, Eigen::MatrixXd());
102  }
103 
104  template <typename PixelT>
106  lsst::afw::math::KernelList const& basisList,
107  Eigen::MatrixXd const& hMat
108  ) {
109 
110  /* Examine the policy for control over the variance estimate */
112  afwImage::Image<afwImage::VariancePixel>(*(_scienceMaskedImage->getVariance()), true);
113  /* Variance estimate comes from sum of image variances */
114  var += (*(_templateMaskedImage->getVariance()));
115 
116  if (_policy.getBool("constantVarianceWeighting")) {
117  /* Constant variance weighting */
118  afwMath::Statistics varStats = afwMath::makeStatistics(var, afwMath::MEDIAN);
119  float varValue;
120  if (varStats.getValue(afwMath::MEDIAN) <= 0.0)
121  varValue = 1.0;
122  else
123  varValue = varStats.getValue(afwMath::MEDIAN);
124  LOGL_DEBUG("TRACE4.ip.diffim.KernelCandidate",
125  "Candidate %d using constant variance of %.2f", this->getId(), varValue);
126  var = varValue;
127 
128  }
129 
130  _varianceEstimate = VariancePtr( new afwImage::Image<afwImage::VariancePixel>(var) );
131 
132  try {
133  _buildKernelSolution(basisList, hMat);
134  } catch (pexExcept::Exception &e) {
135  throw e;
136  }
137 
138  if (_policy.getBool("iterateSingleKernel") && (!(_policy.getBool("constantVarianceWeighting")))) {
140  _varianceEstimate = diffim.getVariance();
141 
142  try {
143  _buildKernelSolution(basisList, hMat);
144  } catch (pexExcept::Exception &e) {
145  throw e;
146  }
147  }
148 
149  _isInitialized = true;
150 
151  }
152 
153  template <typename PixelT>
155  Eigen::MatrixXd const& hMat)
156  {
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;
163  }
164  else if (conditionNumberType == "EIGENVALUE") {
166  }
167  else {
168  throw LSST_EXCEPT(pexExcept::Exception, "conditionNumberType not recognized");
169  }
170 
171  /* Do we have a regularization matrix? If so use it */
172  if (hMat.size() > 0) {
173  _useRegularization = true;
174  LOGL_DEBUG("TRACE4.ip.diffim.KernelCandidate.build",
175  "Using kernel regularization");
176 
177  if (_isInitialized) {
178  _kernelSolutionPca = std::shared_ptr<StaticKernelSolution<PixelT> >(
179  new RegularizedKernelSolution<PixelT>(basisList, _fitForBackground, hMat, _policy)
180  );
181  _kernelSolutionPca->build(*(_templateMaskedImage->getImage()),
182  *(_scienceMaskedImage->getImage()),
183  *_varianceEstimate);
184  if (checkConditionNumber) {
185  if (_kernelSolutionPca->getConditionNumber(ctype) > maxConditionNumber) {
186  LOGL_DEBUG("TRACE4.ip.diffim.KernelCandidate",
187  "Candidate %d solution has bad condition number",
188  this->getId());
190  return;
191  }
192  }
193  _kernelSolutionPca->solve();
194  }
195  else {
196  _kernelSolutionOrig = std::shared_ptr<StaticKernelSolution<PixelT> >(
197  new RegularizedKernelSolution<PixelT>(basisList, _fitForBackground, hMat, _policy)
198  );
199  _kernelSolutionOrig->build(*(_templateMaskedImage->getImage()),
200  *(_scienceMaskedImage->getImage()),
201  *_varianceEstimate);
202  if (checkConditionNumber) {
203  if (_kernelSolutionOrig->getConditionNumber(ctype) > maxConditionNumber) {
204  LOGL_DEBUG("TRACE4.ip.diffim.KernelCandidate",
205  "Candidate %d solution has bad condition number",
206  this->getId());
208  return;
209  }
210  }
211  _kernelSolutionOrig->solve();
212  }
213  }
214  else {
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> >(
220  new StaticKernelSolution<PixelT>(basisList, _fitForBackground)
221  );
222  _kernelSolutionPca->build(*(_templateMaskedImage->getImage()),
223  *(_scienceMaskedImage->getImage()),
224  *_varianceEstimate);
225  if (checkConditionNumber) {
226  if (_kernelSolutionPca->getConditionNumber(ctype) > maxConditionNumber) {
227  LOGL_DEBUG("TRACE4.ip.diffim.KernelCandidate",
228  "Candidate %d solution has bad condition number",
229  this->getId());
231  return;
232  }
233  }
234  _kernelSolutionPca->solve();
235  }
236  else {
237  _kernelSolutionOrig = std::shared_ptr<StaticKernelSolution<PixelT> >(
238  new StaticKernelSolution<PixelT>(basisList, _fitForBackground)
239  );
240  _kernelSolutionOrig->build(*(_templateMaskedImage->getImage()),
241  *(_scienceMaskedImage->getImage()),
242  *_varianceEstimate);
243  if (checkConditionNumber) {
244  if (_kernelSolutionOrig->getConditionNumber(ctype) > maxConditionNumber) {
245  LOGL_DEBUG("TRACE4.ip.diffim.KernelCandidate",
246  "Candidate %d solution has bad condition number",
247  this->getId());
249  return;
250  }
251  }
252  _kernelSolutionOrig->solve();
253  }
254  }
255  }
256 
257  template <typename PixelT>
259  if (cand == KernelCandidate::ORIG) {
260  if (_kernelSolutionOrig)
261  return _kernelSolutionOrig->getKernel();
262  else
263  throw LSST_EXCEPT(pexExcept::Exception, "Original kernel does not exist");
264  }
265  else if (cand == KernelCandidate::PCA) {
266  if (_kernelSolutionPca)
267  return _kernelSolutionPca->getKernel();
268  else
269  throw LSST_EXCEPT(pexExcept::Exception, "Pca kernel does not exist");
270  }
271  else if (cand == KernelCandidate::RECENT) {
272  if (_kernelSolutionPca)
273  return _kernelSolutionPca->getKernel();
274  else if (_kernelSolutionOrig)
275  return _kernelSolutionOrig->getKernel();
276  else
277  throw LSST_EXCEPT(pexExcept::Exception, "No kernels exist");
278  }
279  else {
280  throw LSST_EXCEPT(pexExcept::Exception, "Invalid CandidateSwitch, cannot get kernel");
281  }
282  }
283 
284  template <typename PixelT>
286  if (cand == KernelCandidate::ORIG) {
287  if (_kernelSolutionOrig)
288  return _kernelSolutionOrig->getBackground();
289  else
290  throw LSST_EXCEPT(pexExcept::Exception, "Original kernel does not exist");
291  }
292  else if (cand == KernelCandidate::PCA) {
293  if (_kernelSolutionPca)
294  return _kernelSolutionPca->getBackground();
295  else
296  throw LSST_EXCEPT(pexExcept::Exception, "Pca kernel does not exist");
297  }
298  else if (cand == KernelCandidate::RECENT) {
299  if (_kernelSolutionPca)
300  return _kernelSolutionPca->getBackground();
301  else if (_kernelSolutionOrig)
302  return _kernelSolutionOrig->getBackground();
303  else
304  throw LSST_EXCEPT(pexExcept::Exception, "No kernels exist");
305  }
306  else {
307  throw LSST_EXCEPT(pexExcept::Exception, "Invalid CandidateSwitch, cannot get background");
308  }
309  }
310 
311  template <typename PixelT>
313  if (cand == KernelCandidate::ORIG) {
314  if (_kernelSolutionOrig)
315  return _kernelSolutionOrig->getKsum();
316  else
317  throw LSST_EXCEPT(pexExcept::Exception, "Original kernel does not exist");
318  }
319  else if (cand == KernelCandidate::PCA) {
320  if (_kernelSolutionPca)
321  return _kernelSolutionPca->getKsum();
322  else
323  throw LSST_EXCEPT(pexExcept::Exception, "Pca kernel does not exist");
324  }
325  else if (cand == KernelCandidate::RECENT) {
326  if (_kernelSolutionPca)
327  return _kernelSolutionPca->getKsum();
328  else if (_kernelSolutionOrig)
329  return _kernelSolutionOrig->getKsum();
330  else
331  throw LSST_EXCEPT(pexExcept::Exception, "No kernels exist");
332  }
333  else {
334  throw LSST_EXCEPT(pexExcept::Exception, "Invalid CandidateSwitch, cannot get kSum");
335  }
336  }
337 
338  template <typename PixelT>
340  CandidateSwitch cand) const {
341  if (cand == KernelCandidate::ORIG) {
342  if (_kernelSolutionOrig)
343  return _kernelSolutionOrig->makeKernelImage();
344  else
345  throw LSST_EXCEPT(pexExcept::Exception, "Original kernel does not exist");
346  }
347  else if (cand == KernelCandidate::PCA) {
348  if (_kernelSolutionPca)
349  return _kernelSolutionPca->makeKernelImage();
350  else
351  throw LSST_EXCEPT(pexExcept::Exception, "Pca kernel does not exist");
352  }
353  else if (cand == KernelCandidate::RECENT) {
354  if (_kernelSolutionPca)
355  return _kernelSolutionPca->makeKernelImage();
356  else if (_kernelSolutionOrig)
357  return _kernelSolutionOrig->makeKernelImage();
358  else
359  throw LSST_EXCEPT(pexExcept::Exception, "No kernels exist");
360  }
361  else {
362  throw LSST_EXCEPT(pexExcept::Exception, "Invalid CandidateSwitch, cannot get kernel image");
363  }
364  }
365 
366  template <typename PixelT>
369  }
370 
371  template <typename PixelT>
373  CandidateSwitch cand) const {
374  if (cand == KernelCandidate::ORIG) {
375  if (_kernelSolutionOrig)
376  return _kernelSolutionOrig;
377  else
378  throw LSST_EXCEPT(pexExcept::Exception, "Original kernel does not exist");
379  }
380  else if (cand == KernelCandidate::PCA) {
381  if (_kernelSolutionPca)
382  return _kernelSolutionPca;
383  else
384  throw LSST_EXCEPT(pexExcept::Exception, "Pca kernel does not exist");
385  }
386  else if (cand == KernelCandidate::RECENT) {
387  if (_kernelSolutionPca)
388  return _kernelSolutionPca;
389  else if (_kernelSolutionOrig)
390  return _kernelSolutionOrig;
391  else
392  throw LSST_EXCEPT(pexExcept::Exception, "No kernels exist");
393  }
394  else {
395  throw LSST_EXCEPT(pexExcept::Exception, "Invalid CandidateSwitch, cannot get solution");
396  }
397  }
398 
399  template <typename PixelT>
401  CandidateSwitch cand) {
402  if (cand == KernelCandidate::ORIG) {
403  if (_kernelSolutionOrig)
404  return getDifferenceImage(_kernelSolutionOrig->getKernel(),
405  _kernelSolutionOrig->getBackground());
406  else
407  throw LSST_EXCEPT(pexExcept::Exception, "Original kernel does not exist");
408  }
409  else if (cand == KernelCandidate::PCA) {
410  if (_kernelSolutionPca)
411  return getDifferenceImage(_kernelSolutionPca->getKernel(),
412  _kernelSolutionPca->getBackground());
413  else
414  throw LSST_EXCEPT(pexExcept::Exception, "Pca kernel does not exist");
415  }
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());
423  else
424  throw LSST_EXCEPT(pexExcept::Exception, "No kernels exist");
425  }
426  else {
427  throw LSST_EXCEPT(pexExcept::Exception, "Invalid CandidateSwitch, cannot get diffim");
428  }
429  }
430 
431  template <typename PixelT>
434  double background
435  ) {
436  /* Make diffim and set chi2 from result */
437  afwImage::MaskedImage<PixelT> diffIm = convolveAndSubtract(*_templateMaskedImage,
438  *_scienceMaskedImage,
439  *kernel,
440  background);
441  return diffIm;
442  }
443 
444 /***********************************************************************************************************/
445 //
446 // Explicit instantiations
447 //
448  typedef float PixelT;
449 
450  template class KernelCandidate<PixelT>;
451 
452 }}} // end of namespace lsst::ip::diffim
VariancePtr getVariance() const
void apply(lsst::afw::image::MaskedImage< PixelT > const &image)
double getBackground(CandidateSwitch cand) const
Class stored in SpatialCells for spatial Kernel fitting.
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.
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.
Declaration of classes to store the solution for convolution kernels.
STL class.
bool getBool(const std::string &name) const
std::shared_ptr< afw::image::Image< afw::image::VariancePixel > > VariancePtr
SpatialCellImageCandidate(float const xCenter, float const yCenter)
int getInt(const std::string &name) const
const std::string getString(const std::string &name) const
Class used by SpatialModelCell for spatial Kernel fitting.
double getValue(Property const prop=NOTHING) const
Class to calculate difference image statistics.
double getDouble(const std::string &name) const
#define LSST_EXCEPT(type,...)
STL class.
boost::shared_ptr< ImageT const > getImage() const
#define LOGL_DEBUG(logger, message...)
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