LSSTApplications  20.0.0
LSSTDataManagementBasePackage
Public Types | Public Member Functions | Protected Member Functions | Protected Attributes | Static Protected Attributes | List of all members
lsst::ip::diffim::MaskedKernelSolution< InputT > Class Template Reference

#include <KernelSolution.h>

Inheritance diagram for lsst::ip::diffim::MaskedKernelSolution< InputT >:
lsst::ip::diffim::StaticKernelSolution< InputT > lsst::ip::diffim::KernelSolution

Public Types

typedef std::shared_ptr< MaskedKernelSolution< InputT > > Ptr
 
enum  KernelSolvedBy {
  NONE = 0, CHOLESKY_LDLT = 1, CHOLESKY_LLT = 2, LU = 3,
  EIGENVECTOR = 4
}
 
enum  ConditionNumberType { EIGENVALUE = 0, SVD = 1 }
 
typedef lsst::afw::math::Kernel::Pixel PixelT
 
typedef lsst::afw::image::Image< lsst::afw::math::Kernel::PixelImageT
 

Public Member Functions

 MaskedKernelSolution (lsst::afw::math::KernelList const &basisList, bool fitForBackground)
 
virtual ~MaskedKernelSolution ()
 
virtual void buildOrig (lsst::afw::image::Image< InputT > const &templateImage, lsst::afw::image::Image< InputT > const &scienceImage, lsst::afw::image::Image< lsst::afw::image::VariancePixel > const &varianceEstimate, lsst::afw::image::Mask< lsst::afw::image::MaskPixel > pixelMask)
 
virtual void buildWithMask (lsst::afw::image::Image< InputT > const &templateImage, lsst::afw::image::Image< InputT > const &scienceImage, lsst::afw::image::Image< lsst::afw::image::VariancePixel > const &varianceEstimate, lsst::afw::image::Mask< lsst::afw::image::MaskPixel > const &pixelMask)
 
virtual void buildSingleMaskOrig (lsst::afw::image::Image< InputT > const &templateImage, lsst::afw::image::Image< InputT > const &scienceImage, lsst::afw::image::Image< lsst::afw::image::VariancePixel > const &varianceEstimate, lsst::geom::Box2I maskBox)
 
void solve ()
 
virtual void solve (Eigen::MatrixXd const &mMat, Eigen::VectorXd const &bVec)
 
virtual void build (lsst::afw::image::Image< InputT > const &templateImage, lsst::afw::image::Image< InputT > const &scienceImage, lsst::afw::image::Image< lsst::afw::image::VariancePixel > const &varianceEstimate)
 
virtual std::shared_ptr< lsst::afw::math::KernelgetKernel ()
 
virtual std::shared_ptr< lsst::afw::image::Image< lsst::afw::math::Kernel::Pixel > > makeKernelImage ()
 
virtual double getBackground ()
 
virtual double getKsum ()
 
virtual std::pair< std::shared_ptr< lsst::afw::math::Kernel >, double > getSolutionPair ()
 
KernelSolvedBy getSolvedBy ()
 
virtual double getConditionNumber (ConditionNumberType conditionType)
 
virtual double getConditionNumber (Eigen::MatrixXd const &mMat, ConditionNumberType conditionType)
 
Eigen::MatrixXd const & getM ()
 
Eigen::VectorXd const & getB ()
 
void printM ()
 
void printB ()
 
void printA ()
 
int getId () const
 

Protected Member Functions

void _setKernel ()
 Set kernel after solution. More...
 
void _setKernelUncertainty ()
 Not implemented. More...
 

Protected Attributes

Eigen::MatrixXd _cMat
 K_i x R. More...
 
Eigen::VectorXd _iVec
 Vectorized I. More...
 
Eigen::VectorXd _ivVec
 Inverse variance. More...
 
std::shared_ptr< lsst::afw::math::Kernel_kernel
 Derived single-object convolution kernel. More...
 
double _background
 Derived differential background estimate. More...
 
double _kSum
 Derived kernel sum. More...
 
int _id
 Unique ID for object. More...
 
Eigen::MatrixXd _mMat
 Derived least squares M matrix. More...
 
Eigen::VectorXd _bVec
 Derived least squares B vector. More...
 
Eigen::VectorXd _aVec
 Derived least squares solution matrix. More...
 
KernelSolvedBy _solvedBy
 Type of algorithm used to make solution. More...
 
bool _fitForBackground
 Background terms included in fit. More...
 

Static Protected Attributes

static int _SolutionId = 0
 Unique identifier for solution. More...
 

Detailed Description

template<typename InputT>
class lsst::ip::diffim::MaskedKernelSolution< InputT >

Definition at line 119 of file KernelSolution.h.

Member Typedef Documentation

◆ ImageT

Definition at line 35 of file KernelSolution.h.

◆ PixelT

Definition at line 34 of file KernelSolution.h.

◆ Ptr

Definition at line 121 of file KernelSolution.h.

Member Enumeration Documentation

◆ ConditionNumberType

Enumerator
EIGENVALUE 
SVD 

Definition at line 45 of file KernelSolution.h.

45  {
46  EIGENVALUE = 0,
47  SVD = 1
48  };

◆ KernelSolvedBy

Enumerator
NONE 
CHOLESKY_LDLT 
CHOLESKY_LLT 
LU 
EIGENVECTOR 

Definition at line 37 of file KernelSolution.h.

37  {
38  NONE = 0,
39  CHOLESKY_LDLT = 1,
40  CHOLESKY_LLT = 2,
41  LU = 3,
42  EIGENVECTOR = 4
43  };

Constructor & Destructor Documentation

◆ MaskedKernelSolution()

template<typename InputT >
lsst::ip::diffim::MaskedKernelSolution< InputT >::MaskedKernelSolution ( lsst::afw::math::KernelList const &  basisList,
bool  fitForBackground 
)

Definition at line 492 of file KernelSolution.cc.

495  :
496  StaticKernelSolution<InputT>(basisList, fitForBackground)
497  {};

◆ ~MaskedKernelSolution()

template<typename InputT >
virtual lsst::ip::diffim::MaskedKernelSolution< InputT >::~MaskedKernelSolution ( )
inlinevirtual

Definition at line 125 of file KernelSolution.h.

125 {};

Member Function Documentation

◆ _setKernel()

template<typename InputT >
void lsst::ip::diffim::StaticKernelSolution< InputT >::_setKernel
protectedinherited

Set kernel after solution.

Definition at line 422 of file KernelSolution.cc.

422  {
424  throw LSST_EXCEPT(pexExcept::Exception, "Kernel not solved; cannot make solution");
425  }
426 
427  unsigned int const nParameters = _aVec.size();
428  unsigned int const nBackgroundParameters = _fitForBackground ? 1 : 0;
429  unsigned int const nKernelParameters =
430  std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(_kernel)->getKernelList().size();
431  if (nParameters != (nKernelParameters + nBackgroundParameters))
432  throw LSST_EXCEPT(pexExcept::Exception, "Mismatched sizes in kernel solution");
433 
434  /* Fill in the kernel results */
435  std::vector<double> kValues(nKernelParameters);
436  for (unsigned int idx = 0; idx < nKernelParameters; idx++) {
437  if (std::isnan(_aVec(idx))) {
439  str(boost::format("Unable to determine kernel solution %d (nan)") % idx));
440  }
441  kValues[idx] = _aVec(idx);
442  }
443  _kernel->setKernelParameters(kValues);
444 
447  );
448  _kSum = _kernel->computeImage(*image, false);
449 
450  if (_fitForBackground) {
451  if (std::isnan(_aVec(nParameters-1))) {
453  str(boost::format("Unable to determine background solution %d (nan)") %
454  (nParameters-1)));
455  }
456  _background = _aVec(nParameters-1);
457  }
458  }

◆ _setKernelUncertainty()

template<typename InputT >
void lsst::ip::diffim::StaticKernelSolution< InputT >::_setKernelUncertainty
protectedinherited

Not implemented.

Definition at line 462 of file KernelSolution.cc.

462  {
463  throw LSST_EXCEPT(pexExcept::Exception, "Uncertainty calculation not supported");
464 
465  /* Estimate of parameter uncertainties comes from the inverse of the
466  * covariance matrix (noise spectrum).
467  * N.R. 15.4.8 to 15.4.15
468  *
469  * Since this is a linear problem no need to use Fisher matrix
470  * N.R. 15.5.8
471  *
472  * Although I might be able to take advantage of the solution above.
473  * Since this now works and is not the rate limiting step, keep as-is for DC3a.
474  *
475  * Use Cholesky decomposition again.
476  * Cholkesy:
477  * Cov = L L^t
478  * Cov^(-1) = (L L^t)^(-1)
479  * = (L^T)^-1 L^(-1)
480  *
481  * Code would be:
482  *
483  * Eigen::MatrixXd cov = _mMat.transpose() * _mMat;
484  * Eigen::LLT<Eigen::MatrixXd> llt = cov.llt();
485  * Eigen::MatrixXd error2 = llt.matrixL().transpose().inverse()*llt.matrixL().inverse();
486  */
487  }

◆ build()

template<typename InputT >
void lsst::ip::diffim::StaticKernelSolution< InputT >::build ( lsst::afw::image::Image< InputT > const &  templateImage,
lsst::afw::image::Image< InputT > const &  scienceImage,
lsst::afw::image::Image< lsst::afw::image::VariancePixel > const &  varianceEstimate 
)
virtualinherited

Definition at line 261 of file KernelSolution.cc.

265  {
266 
267  afwMath::Statistics varStats = afwMath::makeStatistics(varianceEstimate, afwMath::MIN);
268  if (varStats.getValue(afwMath::MIN) < 0.0) {
270  "Error: variance less than 0.0");
271  }
272  if (varStats.getValue(afwMath::MIN) == 0.0) {
274  "Error: variance equals 0.0, cannot inverse variance weight");
275  }
276 
277  lsst::afw::math::KernelList basisList =
278  std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(_kernel)->getKernelList();
279 
280  unsigned int const nKernelParameters = basisList.size();
281  unsigned int const nBackgroundParameters = _fitForBackground ? 1 : 0;
282  unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
283 
284  std::vector<std::shared_ptr<afwMath::Kernel> >::const_iterator kiter = basisList.begin();
285 
286  /* Ignore buffers around edge of convolved images :
287  *
288  * If the kernel has width 5, it has center pixel 2. The first good pixel
289  * is the (5-2)=3rd pixel, which is array index 2, and ends up being the
290  * index of the central pixel.
291  *
292  * You also have a buffer of unusable pixels on the other side, numbered
293  * width-center-1. The last good usable pixel is N-width+center+1.
294  *
295  * Example : the kernel is width = 5, center = 2
296  *
297  * ---|---|-c-|---|---|
298  *
299  * the image is width = N
300  * convolve this with the kernel, and you get
301  *
302  * |-x-|-x-|-g-|---|---| ... |---|---|-g-|-x-|-x-|
303  *
304  * g = first/last good pixel
305  * x = bad
306  *
307  * the first good pixel is the array index that has the value "center", 2
308  * the last good pixel has array index N-(5-2)+1
309  * eg. if N = 100, you want to use up to index 97
310  * 100-3+1 = 98, and the loops use i < 98, meaning the last
311  * index you address is 97.
312  */
313 
314  /* NOTE - we are accessing particular elements of Eigen arrays using
315  these coordinates, therefore they need to be in LOCAL coordinates.
316  This was written before ndarray unification.
317  */
318  geom::Box2I goodBBox = (*kiter)->shrinkBBox(templateImage.getBBox(afwImage::LOCAL));
319  unsigned int const startCol = goodBBox.getMinX();
320  unsigned int const startRow = goodBBox.getMinY();
321  // endCol/Row is one past the index of the last good col/row
322  unsigned int endCol = goodBBox.getMaxX() + 1;
323  unsigned int endRow = goodBBox.getMaxY() + 1;
324 
325  boost::timer t;
326  t.restart();
327 
328  /* Eigen representation of input images; only the pixels that are unconvolved in cimage below */
329  Eigen::MatrixXd eigenTemplate = imageToEigenMatrix(templateImage).block(startRow,
330  startCol,
331  endRow-startRow,
332  endCol-startCol);
333  Eigen::MatrixXd eigenScience = imageToEigenMatrix(scienceImage).block(startRow,
334  startCol,
335  endRow-startRow,
336  endCol-startCol);
337  Eigen::MatrixXd eigeniVariance = imageToEigenMatrix(varianceEstimate).block(
338  startRow, startCol, endRow-startRow, endCol-startCol
339  ).array().inverse().matrix();
340 
341  /* Resize into 1-D for later usage */
342  eigenTemplate.resize(eigenTemplate.rows()*eigenTemplate.cols(), 1);
343  eigenScience.resize(eigenScience.rows()*eigenScience.cols(), 1);
344  eigeniVariance.resize(eigeniVariance.rows()*eigeniVariance.cols(), 1);
345 
346  /* Holds image convolved with basis function */
347  afwImage::Image<PixelT> cimage(templateImage.getDimensions());
348 
349  /* Holds eigen representation of image convolved with all basis functions */
350  std::vector<Eigen::MatrixXd> convolvedEigenList(nKernelParameters);
351 
352  /* Iterators over convolved image list and basis list */
353  typename std::vector<Eigen::MatrixXd>::iterator eiter = convolvedEigenList.begin();
354  /* Create C_i in the formalism of Alard & Lupton */
355  for (kiter = basisList.begin(); kiter != basisList.end(); ++kiter, ++eiter) {
356  afwMath::convolve(cimage, templateImage, **kiter, false); /* cimage stores convolved image */
357 
358  Eigen::MatrixXd cMat = imageToEigenMatrix(cimage).block(startRow,
359  startCol,
360  endRow-startRow,
361  endCol-startCol);
362  cMat.resize(cMat.size(), 1);
363  *eiter = cMat;
364 
365  }
366 
367  double time = t.elapsed();
368  LOGL_DEBUG("TRACE3.ip.diffim.StaticKernelSolution.build",
369  "Total compute time to do basis convolutions : %.2f s", time);
370  t.restart();
371 
372  /*
373  Load matrix with all values from convolvedEigenList : all images
374  (eigeniVariance, convolvedEigenList) must be the same size
375  */
376  Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
377  typename std::vector<Eigen::MatrixXd>::iterator eiterj = convolvedEigenList.begin();
378  typename std::vector<Eigen::MatrixXd>::iterator eiterE = convolvedEigenList.end();
379  for (unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
380  cMat.col(kidxj) = eiterj->col(0);
381  }
382  /* Treat the last "image" as all 1's to do the background calculation. */
383  if (_fitForBackground)
384  cMat.col(nParameters-1).fill(1.);
385 
386  _cMat = cMat;
387  _ivVec = eigeniVariance.col(0);
388  _iVec = eigenScience.col(0);
389 
390  /* Make these outside of solve() so I can check condition number */
391  _mMat = _cMat.transpose() * (_ivVec.asDiagonal() * _cMat);
392  _bVec = _cMat.transpose() * (_ivVec.asDiagonal() * _iVec);
393  }

◆ buildOrig()

template<typename InputT >
void lsst::ip::diffim::MaskedKernelSolution< InputT >::buildOrig ( lsst::afw::image::Image< InputT > const &  templateImage,
lsst::afw::image::Image< InputT > const &  scienceImage,
lsst::afw::image::Image< lsst::afw::image::VariancePixel > const &  varianceEstimate,
lsst::afw::image::Mask< lsst::afw::image::MaskPixel pixelMask 
)
virtual

Definition at line 665 of file KernelSolution.cc.

670  {
671 
672  afwMath::Statistics varStats = afwMath::makeStatistics(varianceEstimate, afwMath::MIN);
673  if (varStats.getValue(afwMath::MIN) < 0.0) {
675  "Error: variance less than 0.0");
676  }
677  if (varStats.getValue(afwMath::MIN) == 0.0) {
679  "Error: variance equals 0.0, cannot inverse variance weight");
680  }
681 
682  lsst::afw::math::KernelList basisList =
683  std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(this->_kernel)->getKernelList();
684  std::vector<std::shared_ptr<afwMath::Kernel> >::const_iterator kiter = basisList.begin();
685 
686  /* Only BAD pixels marked in this mask */
688  afwImage::MaskPixel bitMask =
692  sMask &= bitMask;
693  /* TBD: Need to figure out a way to spread this; currently done in Python */
694 
695  unsigned int const nKernelParameters = basisList.size();
696  unsigned int const nBackgroundParameters = this->_fitForBackground ? 1 : 0;
697  unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
698 
699  /* NOTE - we are accessing particular elements of Eigen arrays using
700  these coordinates, therefore they need to be in LOCAL coordinates.
701  This was written before ndarray unification.
702  */
703  /* Ignore known EDGE pixels for speed */
704  geom::Box2I shrunkLocalBBox = (*kiter)->shrinkBBox(templateImage.getBBox(afwImage::LOCAL));
705  LOGL_DEBUG("TRACE3.ip.diffim.MaskedKernelSolution.build",
706  "Limits of good pixels after convolution: %d,%d -> %d,%d (local)",
707  shrunkLocalBBox.getMinX(), shrunkLocalBBox.getMinY(),
708  shrunkLocalBBox.getMaxX(), shrunkLocalBBox.getMaxY());
709 
710  /* Subimages are addressed in raw pixel coordinates */
711  unsigned int startCol = shrunkLocalBBox.getMinX();
712  unsigned int startRow = shrunkLocalBBox.getMinY();
713  unsigned int endCol = shrunkLocalBBox.getMaxX();
714  unsigned int endRow = shrunkLocalBBox.getMaxY();
715  /* Needed for Eigen block slicing operation */
716  endCol += 1;
717  endRow += 1;
718 
719  boost::timer t;
720  t.restart();
721 
722  /* Eigen representation of input images; only the pixels that are unconvolved in cimage below */
723  Eigen::MatrixXi eMask = maskToEigenMatrix(sMask).block(startRow,
724  startCol,
725  endRow-startRow,
726  endCol-startCol);
727 
728  Eigen::MatrixXd eigenTemplate = imageToEigenMatrix(templateImage).block(startRow,
729  startCol,
730  endRow-startRow,
731  endCol-startCol);
732  Eigen::MatrixXd eigenScience = imageToEigenMatrix(scienceImage).block(startRow,
733  startCol,
734  endRow-startRow,
735  endCol-startCol);
736  Eigen::MatrixXd eigeniVariance = imageToEigenMatrix(varianceEstimate).block(
737  startRow, startCol, endRow-startRow, endCol-startCol
738  ).array().inverse().matrix();
739 
740  /* Resize into 1-D for later usage */
741  eMask.resize(eMask.rows()*eMask.cols(), 1);
742  eigenTemplate.resize(eigenTemplate.rows()*eigenTemplate.cols(), 1);
743  eigenScience.resize(eigenScience.rows()*eigenScience.cols(), 1);
744  eigeniVariance.resize(eigeniVariance.rows()*eigeniVariance.cols(), 1);
745 
746  /* Do the masking, slowly for now... */
747  Eigen::MatrixXd maskedEigenTemplate(eigenTemplate.rows(), 1);
748  Eigen::MatrixXd maskedEigenScience(eigenScience.rows(), 1);
749  Eigen::MatrixXd maskedEigeniVariance(eigeniVariance.rows(), 1);
750  int nGood = 0;
751  for (int i = 0; i < eMask.rows(); i++) {
752  if (eMask(i, 0) == 0) {
753  maskedEigenTemplate(nGood, 0) = eigenTemplate(i, 0);
754  maskedEigenScience(nGood, 0) = eigenScience(i, 0);
755  maskedEigeniVariance(nGood, 0) = eigeniVariance(i, 0);
756  nGood += 1;
757  }
758  }
759  /* Can't resize() since all values are lost; use blocks */
760  eigenTemplate = maskedEigenTemplate.block(0, 0, nGood, 1);
761  eigenScience = maskedEigenScience.block(0, 0, nGood, 1);
762  eigeniVariance = maskedEigeniVariance.block(0, 0, nGood, 1);
763 
764 
765  /* Holds image convolved with basis function */
766  afwImage::Image<InputT> cimage(templateImage.getDimensions());
767 
768  /* Holds eigen representation of image convolved with all basis functions */
769  std::vector<Eigen::MatrixXd> convolvedEigenList(nKernelParameters);
770 
771  /* Iterators over convolved image list and basis list */
772  typename std::vector<Eigen::MatrixXd>::iterator eiter = convolvedEigenList.begin();
773  /* Create C_i in the formalism of Alard & Lupton */
774  for (kiter = basisList.begin(); kiter != basisList.end(); ++kiter, ++eiter) {
775  afwMath::convolve(cimage, templateImage, **kiter, false); /* cimage stores convolved image */
776 
777  Eigen::MatrixXd cMat = imageToEigenMatrix(cimage).block(startRow,
778  startCol,
779  endRow-startRow,
780  endCol-startCol);
781  cMat.resize(cMat.size(), 1);
782 
783  /* Do masking */
784  Eigen::MatrixXd maskedcMat(cMat.rows(), 1);
785  int nGood = 0;
786  for (int i = 0; i < eMask.rows(); i++) {
787  if (eMask(i, 0) == 0) {
788  maskedcMat(nGood, 0) = cMat(i, 0);
789  nGood += 1;
790  }
791  }
792  cMat = maskedcMat.block(0, 0, nGood, 1);
793  *eiter = cMat;
794  }
795 
796  double time = t.elapsed();
797  LOGL_DEBUG("TRACE3.ip.diffim.StaticKernelSolution.build",
798  "Total compute time to do basis convolutions : %.2f s", time);
799  t.restart();
800 
801  /*
802  Load matrix with all values from convolvedEigenList : all images
803  (eigeniVariance, convolvedEigenList) must be the same size
804  */
805  Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
806  typename std::vector<Eigen::MatrixXd>::iterator eiterj = convolvedEigenList.begin();
807  typename std::vector<Eigen::MatrixXd>::iterator eiterE = convolvedEigenList.end();
808  for (unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
809  cMat.col(kidxj) = eiterj->col(0);
810  }
811  /* Treat the last "image" as all 1's to do the background calculation. */
812  if (this->_fitForBackground)
813  cMat.col(nParameters-1).fill(1.);
814 
815  this->_cMat = cMat;
816  this->_ivVec = eigeniVariance.col(0);
817  this->_iVec = eigenScience.col(0);
818 
819  /* Make these outside of solve() so I can check condition number */
820  this->_mMat = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_cMat;
821  this->_bVec = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_iVec;
822 
823  }

◆ buildSingleMaskOrig()

template<typename InputT >
void lsst::ip::diffim::MaskedKernelSolution< InputT >::buildSingleMaskOrig ( lsst::afw::image::Image< InputT > const &  templateImage,
lsst::afw::image::Image< InputT > const &  scienceImage,
lsst::afw::image::Image< lsst::afw::image::VariancePixel > const &  varianceEstimate,
lsst::geom::Box2I  maskBox 
)
virtual

Definition at line 828 of file KernelSolution.cc.

833  {
834 
835  afwMath::Statistics varStats = afwMath::makeStatistics(varianceEstimate, afwMath::MIN);
836  if (varStats.getValue(afwMath::MIN) < 0.0) {
838  "Error: variance less than 0.0");
839  }
840  if (varStats.getValue(afwMath::MIN) == 0.0) {
842  "Error: variance equals 0.0, cannot inverse variance weight");
843  }
844 
845  lsst::afw::math::KernelList basisList =
846  std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(this->_kernel)->getKernelList();
847 
848  unsigned int const nKernelParameters = basisList.size();
849  unsigned int const nBackgroundParameters = this->_fitForBackground ? 1 : 0;
850  unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
851 
852  std::vector<std::shared_ptr<afwMath::Kernel> >::const_iterator kiter = basisList.begin();
853 
854  /*
855  NOTE : If we are using these views in Afw's Image space, we need to
856  make sure and compensate for the XY0 of the image:
857 
858  geom::Box2I fullBBox = templateImage.getBBox();
859  int maskStartCol = maskBox.getMinX();
860  int maskStartRow = maskBox.getMinY();
861  int maskEndCol = maskBox.getMaxX();
862  int maskEndRow = maskBox.getMaxY();
863 
864 
865  If we are going to be doing the slicing in Eigen matrices derived from
866  the images, ignore the XY0.
867 
868  geom::Box2I fullBBox = templateImage.getBBox(afwImage::LOCAL);
869 
870  int maskStartCol = maskBox.getMinX() - templateImage.getX0();
871  int maskStartRow = maskBox.getMinY() - templateImage.getY0();
872  int maskEndCol = maskBox.getMaxX() - templateImage.getX0();
873  int maskEndRow = maskBox.getMaxY() - templateImage.getY0();
874 
875  */
876 
877 
878  geom::Box2I shrunkBBox = (*kiter)->shrinkBBox(templateImage.getBBox());
879 
880  LOGL_DEBUG("TRACE3.ip.diffim.MaskedKernelSolution.build",
881  "Limits of good pixels after convolution: %d,%d -> %d,%d",
882  shrunkBBox.getMinX(), shrunkBBox.getMinY(),
883  shrunkBBox.getMaxX(), shrunkBBox.getMaxY());
884 
885  unsigned int const startCol = shrunkBBox.getMinX();
886  unsigned int const startRow = shrunkBBox.getMinY();
887  unsigned int const endCol = shrunkBBox.getMaxX();
888  unsigned int const endRow = shrunkBBox.getMaxY();
889 
890  /* NOTE: no endCol/endRow += 1 for block slicing, since we are doing the
891  slicing using Afw, not Eigen
892 
893  Eigen arrays have index 0,0 in the upper right, while LSST images
894  have 0,0 in the lower left. The y-axis is flipped. When translating
895  Images to Eigen matrices in ipDiffim::imageToEigenMatrix this is
896  accounted for. However, we still need to be aware of this fact if
897  addressing subregions of an Eigen matrix. This is why the slicing is
898  done in Afw, its cleaner.
899 
900  Please see examples/maskedKernel.cc for elaboration on some of the
901  tests done to make sure this indexing gets done right.
902 
903  */
904 
905 
906  /* Inner limits; of mask box */
907  int maskStartCol = maskBox.getMinX();
908  int maskStartRow = maskBox.getMinY();
909  int maskEndCol = maskBox.getMaxX();
910  int maskEndRow = maskBox.getMaxY();
911 
912  /*
913 
914  |---------------------------|
915  | Kernel Boundary |
916  | |---------------------| |
917  | | Top | |
918  | |......_________......| |
919  | | | | | |
920  | | L | Box | R | |
921  | | | | | |
922  | |......---------......| |
923  | | Bottom | |
924  | |---------------------| |
925  | |
926  |---------------------------|
927 
928  4 regions we want to extract from the pixels: top bottom left right
929 
930  */
931  geom::Box2I tBox = geom::Box2I(geom::Point2I(startCol, maskEndRow + 1),
932  geom::Point2I(endCol, endRow));
933 
934  geom::Box2I bBox = geom::Box2I(geom::Point2I(startCol, startRow),
935  geom::Point2I(endCol, maskStartRow - 1));
936 
937  geom::Box2I lBox = geom::Box2I(geom::Point2I(startCol, maskStartRow),
938  geom::Point2I(maskStartCol - 1, maskEndRow));
939 
940  geom::Box2I rBox = geom::Box2I(geom::Point2I(maskEndCol + 1, maskStartRow),
941  geom::Point2I(endCol, maskEndRow));
942 
943  LOGL_DEBUG("TRACE3.ip.diffim.MaskedKernelSolution.build",
944  "Upper good pixel region: %d,%d -> %d,%d",
945  tBox.getMinX(), tBox.getMinY(), tBox.getMaxX(), tBox.getMaxY());
946  LOGL_DEBUG("TRACE3.ip.diffim.MaskedKernelSolution.build",
947  "Bottom good pixel region: %d,%d -> %d,%d",
948  bBox.getMinX(), bBox.getMinY(), bBox.getMaxX(), bBox.getMaxY());
949  LOGL_DEBUG("TRACE3.ip.diffim.MaskedKernelSolution.build",
950  "Left good pixel region: %d,%d -> %d,%d",
951  lBox.getMinX(), lBox.getMinY(), lBox.getMaxX(), lBox.getMaxY());
952  LOGL_DEBUG("TRACE3.ip.diffim.MaskedKernelSolution.build",
953  "Right good pixel region: %d,%d -> %d,%d",
954  rBox.getMinX(), rBox.getMinY(), rBox.getMaxX(), rBox.getMaxY());
955 
956  std::vector<geom::Box2I> boxArray;
957  boxArray.push_back(tBox);
958  boxArray.push_back(bBox);
959  boxArray.push_back(lBox);
960  boxArray.push_back(rBox);
961 
962  int totalSize = tBox.getWidth() * tBox.getHeight();
963  totalSize += bBox.getWidth() * bBox.getHeight();
964  totalSize += lBox.getWidth() * lBox.getHeight();
965  totalSize += rBox.getWidth() * rBox.getHeight();
966 
967  Eigen::MatrixXd eigenTemplate(totalSize, 1);
968  Eigen::MatrixXd eigenScience(totalSize, 1);
969  Eigen::MatrixXd eigeniVariance(totalSize, 1);
970  eigenTemplate.setZero();
971  eigenScience.setZero();
972  eigeniVariance.setZero();
973 
974  boost::timer t;
975  t.restart();
976 
977  int nTerms = 0;
978  typename std::vector<geom::Box2I>::iterator biter = boxArray.begin();
979  for (; biter != boxArray.end(); ++biter) {
980  int area = (*biter).getWidth() * (*biter).getHeight();
981 
982  afwImage::Image<InputT> siTemplate(templateImage, *biter);
983  afwImage::Image<InputT> siScience(scienceImage, *biter);
984  afwImage::Image<InputT> sVarEstimate(varianceEstimate, *biter);
985 
986  Eigen::MatrixXd eTemplate = imageToEigenMatrix(siTemplate);
987  Eigen::MatrixXd eScience = imageToEigenMatrix(siScience);
988  Eigen::MatrixXd eiVarEstimate = imageToEigenMatrix(sVarEstimate).array().inverse().matrix();
989 
990  eTemplate.resize(area, 1);
991  eScience.resize(area, 1);
992  eiVarEstimate.resize(area, 1);
993 
994  eigenTemplate.block(nTerms, 0, area, 1) = eTemplate.block(0, 0, area, 1);
995  eigenScience.block(nTerms, 0, area, 1) = eScience.block(0, 0, area, 1);
996  eigeniVariance.block(nTerms, 0, area, 1) = eiVarEstimate.block(0, 0, area, 1);
997 
998  nTerms += area;
999  }
1000 
1001  afwImage::Image<InputT> cimage(templateImage.getDimensions());
1002 
1003  std::vector<Eigen::MatrixXd> convolvedEigenList(nKernelParameters);
1004  typename std::vector<Eigen::MatrixXd>::iterator eiter = convolvedEigenList.begin();
1005  /* Create C_i in the formalism of Alard & Lupton */
1006  for (kiter = basisList.begin(); kiter != basisList.end(); ++kiter, ++eiter) {
1007  afwMath::convolve(cimage, templateImage, **kiter, false); /* cimage stores convolved image */
1008  Eigen::MatrixXd cMat(totalSize, 1);
1009  cMat.setZero();
1010 
1011  int nTerms = 0;
1012  typename std::vector<geom::Box2I>::iterator biter = boxArray.begin();
1013  for (; biter != boxArray.end(); ++biter) {
1014  int area = (*biter).getWidth() * (*biter).getHeight();
1015 
1016  afwImage::Image<InputT> csubimage(cimage, *biter);
1017  Eigen::MatrixXd esubimage = imageToEigenMatrix(csubimage);
1018  esubimage.resize(area, 1);
1019  cMat.block(nTerms, 0, area, 1) = esubimage.block(0, 0, area, 1);
1020 
1021  nTerms += area;
1022  }
1023 
1024  *eiter = cMat;
1025 
1026  }
1027 
1028  double time = t.elapsed();
1029  LOGL_DEBUG("TRACE3.ip.diffim.MaskedKernelSolution.build",
1030  "Total compute time to do basis convolutions : %.2f s", time);
1031  t.restart();
1032 
1033  /*
1034  Load matrix with all values from convolvedEigenList : all images
1035  (eigeniVariance, convolvedEigenList) must be the same size
1036  */
1037  Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
1038  typename std::vector<Eigen::MatrixXd>::iterator eiterj = convolvedEigenList.begin();
1039  typename std::vector<Eigen::MatrixXd>::iterator eiterE = convolvedEigenList.end();
1040  for (unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
1041  cMat.col(kidxj) = eiterj->col(0);
1042  }
1043  /* Treat the last "image" as all 1's to do the background calculation. */
1044  if (this->_fitForBackground)
1045  cMat.col(nParameters-1).fill(1.);
1046 
1047  this->_cMat = cMat;
1048  this->_ivVec = eigeniVariance.col(0);
1049  this->_iVec = eigenScience.col(0);
1050 
1051  /* Make these outside of solve() so I can check condition number */
1052  this->_mMat = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_cMat;
1053  this->_bVec = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_iVec;
1054  }

◆ buildWithMask()

template<typename InputT >
void lsst::ip::diffim::MaskedKernelSolution< InputT >::buildWithMask ( lsst::afw::image::Image< InputT > const &  templateImage,
lsst::afw::image::Image< InputT > const &  scienceImage,
lsst::afw::image::Image< lsst::afw::image::VariancePixel > const &  varianceEstimate,
lsst::afw::image::Mask< lsst::afw::image::MaskPixel > const &  pixelMask 
)
virtual

Definition at line 500 of file KernelSolution.cc.

505  {
506 
507  afwMath::Statistics varStats = afwMath::makeStatistics(varianceEstimate, afwMath::MIN);
508  if (varStats.getValue(afwMath::MIN) < 0.0) {
510  "Error: variance less than 0.0");
511  }
512  if (varStats.getValue(afwMath::MIN) == 0.0) {
514  "Error: variance equals 0.0, cannot inverse variance weight");
515  }
516 
517  /* Full footprint of all input images */
519  new afwDet::Footprint(std::make_shared<afwGeom::SpanSet>(templateImage.getBBox())));
520 
521  afwMath::KernelList basisList =
522  std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(this->_kernel)->getKernelList();
523  std::vector<std::shared_ptr<afwMath::Kernel> >::const_iterator kiter = basisList.begin();
524 
525  /* Only BAD pixels marked in this mask */
526  afwImage::MaskPixel bitMask =
531 
532  /* Create a Footprint that contains all the masked pixels set above */
534  afwDet::FootprintSet maskFpSet(pixelMask, threshold, true);
535 
536  /* And spread it by the kernel half width */
537  int growPix = (*kiter)->getCtr().getX();
538  afwDet::FootprintSet maskedFpSetGrown(maskFpSet, growPix, true);
539 
540 #if 0
541  for (typename afwDet::FootprintSet::FootprintList::iterator
542  ptr = maskedFpSetGrown.getFootprints()->begin(),
543  end = maskedFpSetGrown.getFootprints()->end();
544  ptr != end;
545  ++ptr) {
546 
547  afwDet::setMaskFromFootprint(finalMask,
548  (**ptr),
550  }
551 #endif
552 
553  afwImage::Mask<afwImage::MaskPixel> finalMask(pixelMask.getDimensions());
554  for (auto const & foot : *(maskedFpSetGrown.getFootprints())) {
555  foot->getSpans()->setMask(finalMask, afwImage::Mask<afwImage::MaskPixel>::getPlaneBitMask("BAD"));
556  }
557  pixelMask.writeFits("pixelmask.fits");
558  finalMask.writeFits("finalmask.fits");
559 
560 
561  ndarray::Array<int, 1, 1> maskArray =
562  ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
563  fullFp->getSpans()->flatten(maskArray, finalMask.getArray(), templateImage.getXY0());
564  auto maskEigen = ndarray::asEigenMatrix(maskArray);
565 
566  ndarray::Array<InputT, 1, 1> arrayTemplate =
567  ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
568  fullFp->getSpans()->flatten(arrayTemplate, templateImage.getArray(), templateImage.getXY0());
569  auto eigenTemplate0 = ndarray::asEigenMatrix(arrayTemplate);
570 
571  ndarray::Array<InputT, 1, 1> arrayScience =
572  ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
573  fullFp->getSpans()->flatten(arrayScience, scienceImage.getArray(), scienceImage.getXY0());
574  auto eigenScience0 = ndarray::asEigenMatrix(arrayScience);
575 
576  ndarray::Array<afwImage::VariancePixel, 1, 1> arrayVariance =
577  ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
578  fullFp->getSpans()->flatten(arrayVariance, varianceEstimate.getArray(), varianceEstimate.getXY0());
579  auto eigenVariance0 = ndarray::asEigenMatrix(arrayVariance);
580 
581  int nGood = 0;
582  for (int i = 0; i < maskEigen.size(); i++) {
583  if (maskEigen(i) == 0.0)
584  nGood += 1;
585  }
586 
587  Eigen::VectorXd eigenTemplate(nGood);
588  Eigen::VectorXd eigenScience(nGood);
589  Eigen::VectorXd eigenVariance(nGood);
590  int nUsed = 0;
591  for (int i = 0; i < maskEigen.size(); i++) {
592  if (maskEigen(i) == 0.0) {
593  eigenTemplate(nUsed) = eigenTemplate0(i);
594  eigenScience(nUsed) = eigenScience0(i);
595  eigenVariance(nUsed) = eigenVariance0(i);
596  nUsed += 1;
597  }
598  }
599 
600 
601  boost::timer t;
602  t.restart();
603 
604  unsigned int const nKernelParameters = basisList.size();
605  unsigned int const nBackgroundParameters = this->_fitForBackground ? 1 : 0;
606  unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
607 
608  /* Holds image convolved with basis function */
609  afwImage::Image<InputT> cimage(templateImage.getDimensions());
610 
611  /* Holds eigen representation of image convolved with all basis functions */
612  std::vector<Eigen::VectorXd> convolvedEigenList(nKernelParameters);
613 
614  /* Iterators over convolved image list and basis list */
615  typename std::vector<Eigen::VectorXd>::iterator eiter = convolvedEigenList.begin();
616 
617  /* Create C_i in the formalism of Alard & Lupton */
618  for (kiter = basisList.begin(); kiter != basisList.end(); ++kiter, ++eiter) {
619  afwMath::convolve(cimage, templateImage, **kiter, false); /* cimage stores convolved image */
620 
621  ndarray::Array<InputT, 1, 1> arrayC =
622  ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
623  fullFp->getSpans()->flatten(arrayC, cimage.getArray(), cimage.getXY0());
624  auto eigenC0 = ndarray::asEigenMatrix(arrayC);
625 
626  Eigen::VectorXd eigenC(nGood);
627  int nUsed = 0;
628  for (int i = 0; i < maskEigen.size(); i++) {
629  if (maskEigen(i) == 0.0) {
630  eigenC(nUsed) = eigenC0(i);
631  nUsed += 1;
632  }
633  }
634 
635  *eiter = eigenC;
636  }
637  double time = t.elapsed();
638  LOGL_DEBUG("TRACE3.ip.diffim.StaticKernelSolution.buildWithMask",
639  "Total compute time to do basis convolutions : %.2f s", time);
640  t.restart();
641 
642  /* Load matrix with all convolved images */
643  Eigen::MatrixXd cMat(eigenTemplate.size(), nParameters);
644  typename std::vector<Eigen::VectorXd>::iterator eiterj = convolvedEigenList.begin();
645  typename std::vector<Eigen::VectorXd>::iterator eiterE = convolvedEigenList.end();
646  for (unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
647  cMat.block(0, kidxj, eigenTemplate.size(), 1) =
648  Eigen::MatrixXd(*eiterj).block(0, 0, eigenTemplate.size(), 1);
649  }
650  /* Treat the last "image" as all 1's to do the background calculation. */
651  if (this->_fitForBackground)
652  cMat.col(nParameters-1).fill(1.);
653 
654  this->_cMat = cMat;
655  this->_ivVec = eigenVariance.array().inverse().matrix();
656  this->_iVec = eigenScience;
657 
658  /* Make these outside of solve() so I can check condition number */
659  this->_mMat = this->_cMat.transpose() * this->_ivVec.asDiagonal() * (this->_cMat);
660  this->_bVec = this->_cMat.transpose() * this->_ivVec.asDiagonal() * (this->_iVec);
661  }

◆ getB()

Eigen::VectorXd const& lsst::ip::diffim::KernelSolution::getB ( )
inlineinherited

Definition at line 65 of file KernelSolution.h.

65 {return _bVec;}

◆ getBackground()

template<typename InputT >
double lsst::ip::diffim::StaticKernelSolution< InputT >::getBackground
virtualinherited

Definition at line 235 of file KernelSolution.cc.

235  {
237  throw LSST_EXCEPT(pexExcept::Exception, "Kernel not solved; cannot return background");
238  }
239  return _background;
240  }

◆ getConditionNumber() [1/2]

double lsst::ip::diffim::KernelSolution::getConditionNumber ( ConditionNumberType  conditionType)
virtualinherited

Definition at line 94 of file KernelSolution.cc.

94  {
95  return getConditionNumber(_mMat, conditionType);
96  }

◆ getConditionNumber() [2/2]

double lsst::ip::diffim::KernelSolution::getConditionNumber ( Eigen::MatrixXd const &  mMat,
ConditionNumberType  conditionType 
)
virtualinherited

Definition at line 98 of file KernelSolution.cc.

99  {
100  switch (conditionType) {
101  case EIGENVALUE:
102  {
103  Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eVecValues(mMat);
104  Eigen::VectorXd eValues = eVecValues.eigenvalues();
105  double eMax = eValues.maxCoeff();
106  double eMin = eValues.minCoeff();
107  LOGL_DEBUG("TRACE3.ip.diffim.KernelSolution.getConditionNumber",
108  "EIGENVALUE eMax / eMin = %.3e", eMax / eMin);
109  return (eMax / eMin);
110  break;
111  }
112  case SVD:
113  {
114  Eigen::VectorXd sValues = mMat.jacobiSvd().singularValues();
115  double sMax = sValues.maxCoeff();
116  double sMin = sValues.minCoeff();
117  LOGL_DEBUG("TRACE3.ip.diffim.KernelSolution.getConditionNumber",
118  "SVD eMax / eMin = %.3e", sMax / sMin);
119  return (sMax / sMin);
120  break;
121  }
122  default:
123  {
125  "Undefined ConditionNumberType : only EIGENVALUE, SVD allowed.");
126  break;
127  }
128  }
129  }

◆ getId()

int lsst::ip::diffim::KernelSolution::getId ( ) const
inlineinherited

Definition at line 69 of file KernelSolution.h.

69 { return _id; }

◆ getKernel()

template<typename InputT >
std::shared_ptr< lsst::afw::math::Kernel > lsst::ip::diffim::StaticKernelSolution< InputT >::getKernel
virtualinherited

Definition at line 215 of file KernelSolution.cc.

215  {
217  throw LSST_EXCEPT(pexExcept::Exception, "Kernel not solved; cannot return solution");
218  }
219  return _kernel;
220  }

◆ getKsum()

template<typename InputT >
double lsst::ip::diffim::StaticKernelSolution< InputT >::getKsum
virtualinherited

Definition at line 243 of file KernelSolution.cc.

243  {
245  throw LSST_EXCEPT(pexExcept::Exception, "Kernel not solved; cannot return ksum");
246  }
247  return _kSum;
248  }

◆ getM()

Eigen::MatrixXd const& lsst::ip::diffim::KernelSolution::getM ( )
inlineinherited

Definition at line 64 of file KernelSolution.h.

64 {return _mMat;}

◆ getSolutionPair()

template<typename InputT >
std::pair< std::shared_ptr< lsst::afw::math::Kernel >, double > lsst::ip::diffim::StaticKernelSolution< InputT >::getSolutionPair
virtualinherited

Definition at line 252 of file KernelSolution.cc.

252  {
254  throw LSST_EXCEPT(pexExcept::Exception, "Kernel not solved; cannot return solution");
255  }
256 
258  }

◆ getSolvedBy()

KernelSolvedBy lsst::ip::diffim::KernelSolution::getSolvedBy ( )
inlineinherited

Definition at line 60 of file KernelSolution.h.

60 {return _solvedBy;}

◆ makeKernelImage()

template<typename InputT >
std::shared_ptr< lsst::afw::image::Image< lsst::afw::math::Kernel::Pixel > > lsst::ip::diffim::StaticKernelSolution< InputT >::makeKernelImage
virtualinherited

Definition at line 223 of file KernelSolution.cc.

223  {
225  throw LSST_EXCEPT(pexExcept::Exception, "Kernel not solved; cannot return image");
226  }
229  );
230  (void)_kernel->computeImage(*image, false);
231  return image;
232  }

◆ printA()

void lsst::ip::diffim::KernelSolution::printA ( )
inlineinherited

Definition at line 68 of file KernelSolution.h.

68 {std::cout << _aVec << std::endl;}

◆ printB()

void lsst::ip::diffim::KernelSolution::printB ( )
inlineinherited

Definition at line 67 of file KernelSolution.h.

67 {std::cout << _bVec << std::endl;}

◆ printM()

void lsst::ip::diffim::KernelSolution::printM ( )
inlineinherited

Definition at line 66 of file KernelSolution.h.

66 {std::cout << _mMat << std::endl;}

◆ solve() [1/2]

template<typename InputT >
void lsst::ip::diffim::StaticKernelSolution< InputT >::solve
virtualinherited

Reimplemented from lsst::ip::diffim::KernelSolution.

Reimplemented in lsst::ip::diffim::RegularizedKernelSolution< InputT >.

Definition at line 396 of file KernelSolution.cc.

396  {
397  LOGL_DEBUG("TRACE3.ip.diffim.StaticKernelSolution.solve",
398  "mMat is %d x %d; bVec is %d; cMat is %d x %d; vVec is %d; iVec is %d",
399  _mMat.rows(), _mMat.cols(), _bVec.size(),
400  _cMat.rows(), _cMat.cols(), _ivVec.size(), _iVec.size());
401 
402  if (DEBUG_MATRIX) {
403  std::cout << "C" << std::endl;
404  std::cout << _cMat << std::endl;
405  std::cout << "iV" << std::endl;
406  std::cout << _ivVec << std::endl;
407  std::cout << "I" << std::endl;
408  std::cout << _iVec << std::endl;
409  }
410 
411  try {
413  } catch (pexExcept::Exception &e) {
414  LSST_EXCEPT_ADD(e, "Unable to solve static kernel matrix");
415  throw e;
416  }
417  /* Turn matrices into _kernel and _background */
418  _setKernel();
419  }

◆ solve() [2/2]

void lsst::ip::diffim::KernelSolution::solve ( Eigen::MatrixXd const &  mMat,
Eigen::VectorXd const &  bVec 
)
virtualinherited

Definition at line 131 of file KernelSolution.cc.

132  {
133 
134  if (DEBUG_MATRIX) {
135  std::cout << "M " << std::endl;
136  std::cout << mMat << std::endl;
137  std::cout << "B " << std::endl;
138  std::cout << bVec << std::endl;
139  }
140 
141  Eigen::VectorXd aVec = Eigen::VectorXd::Zero(bVec.size());
142 
143  boost::timer t;
144  t.restart();
145 
146  LOGL_DEBUG("TRACE2.ip.diffim.KernelSolution.solve",
147  "Solving for kernel");
148  _solvedBy = LU;
149  Eigen::FullPivLU<Eigen::MatrixXd> lu(mMat);
150  if (lu.isInvertible()) {
151  aVec = lu.solve(bVec);
152  } else {
153  LOGL_DEBUG("TRACE3.ip.diffim.KernelSolution.solve",
154  "Unable to determine kernel via LU");
155  /* LAST RESORT */
156  try {
157 
159  Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eVecValues(mMat);
160  Eigen::MatrixXd const& rMat = eVecValues.eigenvectors();
161  Eigen::VectorXd eValues = eVecValues.eigenvalues();
162 
163  for (int i = 0; i != eValues.rows(); ++i) {
164  if (eValues(i) != 0.0) {
165  eValues(i) = 1.0/eValues(i);
166  }
167  }
168 
169  aVec = rMat * eValues.asDiagonal() * rMat.transpose() * bVec;
170  } catch (pexExcept::Exception& e) {
171 
172  _solvedBy = NONE;
173  LOGL_DEBUG("TRACE3.ip.diffim.KernelSolution.solve",
174  "Unable to determine kernel via eigen-values");
175 
176  throw LSST_EXCEPT(pexExcept::Exception, "Unable to determine kernel solution");
177  }
178  }
179 
180  double time = t.elapsed();
181  LOGL_DEBUG("TRACE3.ip.diffim.KernelSolution.solve",
182  "Compute time for matrix math : %.2f s", time);
183 
184  if (DEBUG_MATRIX) {
185  std::cout << "A " << std::endl;
186  std::cout << aVec << std::endl;
187  }
188 
189  _aVec = aVec;
190  }

Member Data Documentation

◆ _aVec

Eigen::VectorXd lsst::ip::diffim::KernelSolution::_aVec
protectedinherited

Derived least squares solution matrix.

Definition at line 75 of file KernelSolution.h.

◆ _background

template<typename InputT >
double lsst::ip::diffim::StaticKernelSolution< InputT >::_background
protectedinherited

Derived differential background estimate.

Definition at line 110 of file KernelSolution.h.

◆ _bVec

Eigen::VectorXd lsst::ip::diffim::KernelSolution::_bVec
protectedinherited

Derived least squares B vector.

Definition at line 74 of file KernelSolution.h.

◆ _cMat

template<typename InputT >
Eigen::MatrixXd lsst::ip::diffim::StaticKernelSolution< InputT >::_cMat
protectedinherited

K_i x R.

Definition at line 105 of file KernelSolution.h.

◆ _fitForBackground

bool lsst::ip::diffim::KernelSolution::_fitForBackground
protectedinherited

Background terms included in fit.

Definition at line 77 of file KernelSolution.h.

◆ _id

int lsst::ip::diffim::KernelSolution::_id
protectedinherited

Unique ID for object.

Definition at line 72 of file KernelSolution.h.

◆ _iVec

template<typename InputT >
Eigen::VectorXd lsst::ip::diffim::StaticKernelSolution< InputT >::_iVec
protectedinherited

Vectorized I.

Definition at line 106 of file KernelSolution.h.

◆ _ivVec

template<typename InputT >
Eigen::VectorXd lsst::ip::diffim::StaticKernelSolution< InputT >::_ivVec
protectedinherited

Inverse variance.

Definition at line 107 of file KernelSolution.h.

◆ _kernel

template<typename InputT >
std::shared_ptr<lsst::afw::math::Kernel> lsst::ip::diffim::StaticKernelSolution< InputT >::_kernel
protectedinherited

Derived single-object convolution kernel.

Definition at line 109 of file KernelSolution.h.

◆ _kSum

template<typename InputT >
double lsst::ip::diffim::StaticKernelSolution< InputT >::_kSum
protectedinherited

Derived kernel sum.

Definition at line 111 of file KernelSolution.h.

◆ _mMat

Eigen::MatrixXd lsst::ip::diffim::KernelSolution::_mMat
protectedinherited

Derived least squares M matrix.

Definition at line 73 of file KernelSolution.h.

◆ _SolutionId

int lsst::ip::diffim::KernelSolution::_SolutionId = 0
staticprotectedinherited

Unique identifier for solution.

Definition at line 78 of file KernelSolution.h.

◆ _solvedBy

KernelSolvedBy lsst::ip::diffim::KernelSolution::_solvedBy
protectedinherited

Type of algorithm used to make solution.

Definition at line 76 of file KernelSolution.h.


The documentation for this class was generated from the following files:
lsst::afw::image
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
Definition: imageAlgorithm.dox:1
lsst::afw::image::LOCAL
@ LOCAL
Definition: ImageBase.h:94
std::shared_ptr< ImageT >
lsst::ip::diffim::KernelSolution::SVD
@ SVD
Definition: KernelSolution.h:47
lsst::afw::image::Mask< lsst::afw::image::MaskPixel >
lsst::afw::math::Kernel::getDimensions
lsst::geom::Extent2I const getDimensions() const
Return the Kernel's dimensions (width, height)
Definition: Kernel.h:213
lsst::ip::diffim::KernelSolution::solve
virtual void solve()
Definition: KernelSolution.cc:90
lsst::ip::diffim::KernelSolution::CHOLESKY_LDLT
@ CHOLESKY_LDLT
Definition: KernelSolution.h:39
lsst::geom::Box2I::getHeight
int getHeight() const noexcept
Definition: Box.h:188
lsst::ip::diffim::StaticKernelSolution::_kernel
std::shared_ptr< lsst::afw::math::Kernel > _kernel
Derived single-object convolution kernel.
Definition: KernelSolution.h:109
lsst::ip::diffim::KernelSolution::ImageT
lsst::afw::image::Image< lsst::afw::math::Kernel::Pixel > ImageT
Definition: KernelSolution.h:35
lsst::ip::diffim::KernelSolution::NONE
@ NONE
Definition: KernelSolution.h:38
lsst::afw::image::Mask::writeFits
void writeFits(std::string const &fileName, std::shared_ptr< lsst::daf::base::PropertySet const > metadata=std::shared_ptr< lsst::daf::base::PropertySet >(), std::string const &mode="w") const
Write a mask to a regular FITS file.
std::vector< double >
std::vector::size
T size(T... args)
LSST_EXCEPT_ADD
#define LSST_EXCEPT_ADD(e, m)
Add the current location and a message to an existing exception before rethrowing it.
Definition: Exception.h:54
pex.config.history.format
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:174
lsst::afw::math::Kernel::computeImage
double computeImage(lsst::afw::image::Image< Pixel > &image, bool doNormalize, double x=0.0, double y=0.0) const
Compute an image (pixellized representation of the kernel) in place.
Definition: Kernel.cc:85
lsst::ip::diffim::KernelSolution::_bVec
Eigen::VectorXd _bVec
Derived least squares B vector.
Definition: KernelSolution.h:74
lsst::afw::math::Statistics::getValue
double getValue(Property const prop=NOTHING) const
Return the value of the desired property (if specified in the constructor)
Definition: Statistics.cc:1056
end
int end
Definition: BoundedField.cc:105
std::vector::push_back
T push_back(T... args)
lsst::afw::math::makeStatistics
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
lsst::ip::diffim::KernelSolution::_fitForBackground
bool _fitForBackground
Background terms included in fit.
Definition: KernelSolution.h:77
lsst::ip::diffim::KernelSolution::LU
@ LU
Definition: KernelSolution.h:41
std::isnan
T isnan(T... args)
lsst::afw::detection::FootprintSet
A set of Footprints, associated with a MaskedImage.
Definition: FootprintSet.h:53
lsst::ip::diffim::StaticKernelSolution::_background
double _background
Derived differential background estimate.
Definition: KernelSolution.h:110
lsst::afw::image::Mask::getPlaneBitMask
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:379
lsst::geom::Box2I::getWidth
int getWidth() const noexcept
Definition: Box.h:187
lsst::ip::diffim::KernelSolution::_solvedBy
KernelSolvedBy _solvedBy
Type of algorithm used to make solution.
Definition: KernelSolution.h:76
image
afw::table::Key< afw::table::Array< ImagePixelT > > image
Definition: HeavyFootprint.cc:216
lsst::ip::diffim::KernelSolution::_mMat
Eigen::MatrixXd _mMat
Derived least squares M matrix.
Definition: KernelSolution.h:73
std::cout
lsst::afw::detection::Threshold
A Threshold is used to pass a threshold value to detection algorithms.
Definition: Threshold.h:43
lsst::afw::math.convolveImage.convolveImageContinued.convolve
convolve
Definition: convolveImageContinued.py:28
lsst::ip::diffim::imageToEigenMatrix
Eigen::MatrixXd imageToEigenMatrix(lsst::afw::image::Image< PixelT > const &img)
Turns a 2-d Image into a 2-d Eigen Matrix.
Definition: ImageSubtract.cc:62
lsst::ip::diffim::KernelSolution::getConditionNumber
virtual double getConditionNumber(ConditionNumberType conditionType)
Definition: KernelSolution.cc:94
lsst::afw::detection::Threshold::BITMASK
@ BITMASK
Use (pixels & (given mask))
Definition: Threshold.h:48
lsst::afw::image::ImageBase::getArray
Array getArray()
Definition: ImageBase.h:513
ptr
uint64_t * ptr
Definition: RangeSet.cc:88
std::int32_t
lsst::ip::diffim::KernelSolution::_id
int _id
Unique ID for object.
Definition: KernelSolution.h:72
lsst::ip::diffim::StaticKernelSolution::_ivVec
Eigen::VectorXd _ivVec
Inverse variance.
Definition: KernelSolution.h:107
LSST_EXCEPT
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
lsst::ip::diffim::StaticKernelSolution::_iVec
Eigen::VectorXd _iVec
Vectorized I.
Definition: KernelSolution.h:106
lsst::ip::diffim::KernelSolution::EIGENVECTOR
@ EIGENVECTOR
Definition: KernelSolution.h:42
lsst::afw::image::ImageBase::getDimensions
lsst::geom::Extent2I getDimensions() const
Return the image's size; useful for passing to constructors.
Definition: ImageBase.h:393
lsst::ip::diffim::StaticKernelSolution::_setKernel
void _setKernel()
Set kernel after solution.
Definition: KernelSolution.cc:422
std::endl
T endl(T... args)
lsst::pex::exceptions::InvalidParameterError
Reports invalid arguments.
Definition: Runtime.h:66
lsst::geom::Box2I::getMaxY
int getMaxY() const noexcept
Definition: Box.h:162
LOGL_DEBUG
#define LOGL_DEBUG(logger, message...)
Definition: Log.h:504
std::vector::begin
T begin(T... args)
lsst::afw::math::MIN
@ MIN
estimate sample minimum
Definition: Statistics.h:76
lsst::geom::Box2I::getMaxX
int getMaxX() const noexcept
Definition: Box.h:161
lsst::geom::Point< int, 2 >
lsst::ip::diffim::StaticKernelSolution::_cMat
Eigen::MatrixXd _cMat
K_i x R.
Definition: KernelSolution.h:105
lsst::geom::Box2I
An integer coordinate rectangle.
Definition: Box.h:55
lsst::ip::diffim::maskToEigenMatrix
Eigen::MatrixXi maskToEigenMatrix(lsst::afw::image::Mask< lsst::afw::image::MaskPixel > const &mask)
Definition: ImageSubtract.cc:80
lsst::geom::Box2I::getMinX
int getMinX() const noexcept
Definition: Box.h:157
lsst::afw::math::Statistics
Definition: Statistics.h:215
lsst::afw::image::ImageBase::getXY0
lsst::geom::Point2I getXY0() const
Return the image's origin.
Definition: ImageBase.h:360
std::make_pair
T make_pair(T... args)
std::time
T time(T... args)
lsst::pex::exceptions::Exception
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
std::vector::end
T end(T... args)
lsst::afw::image::ImageBase::getBBox
lsst::geom::Box2I getBBox(ImageOrigin origin=PARENT) const
Definition: ImageBase.h:482
lsst::ip::diffim::KernelSolution::EIGENVALUE
@ EIGENVALUE
Definition: KernelSolution.h:46
lsst::afw::detection::Footprint
Class to describe the properties of a detected object from an image.
Definition: Footprint.h:63
lsst::afw::image::Image
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:58
lsst::afw::math::Kernel::setKernelParameters
void setKernelParameters(std::vector< double > const &params)
Set the kernel parameters of a spatially invariant kernel.
Definition: Kernel.h:388
lsst::ip::diffim::KernelSolution::CHOLESKY_LLT
@ CHOLESKY_LLT
Definition: KernelSolution.h:40
DEBUG_MATRIX
#define DEBUG_MATRIX
Definition: KernelSolution.cc:40
lsst::geom::Box2I::getMinY
int getMinY() const noexcept
Definition: Box.h:158
lsst::ip::diffim::KernelSolution::_aVec
Eigen::VectorXd _aVec
Derived least squares solution matrix.
Definition: KernelSolution.h:75
lsst::ip::diffim::StaticKernelSolution::_kSum
double _kSum
Derived kernel sum.
Definition: KernelSolution.h:111