LSSTApplications  18.1.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::afw::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.

◆ KernelSolvedBy

Constructor & Destructor Documentation

◆ MaskedKernelSolution()

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

Definition at line 490 of file KernelSolution.cc.

493  :
494  StaticKernelSolution<InputT>(basisList, fitForBackground)
495  {};

◆ ~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 420 of file KernelSolution.cc.

420  {
422  throw LSST_EXCEPT(pexExcept::Exception, "Kernel not solved; cannot make solution");
423  }
424 
425  unsigned int const nParameters = _aVec.size();
426  unsigned int const nBackgroundParameters = _fitForBackground ? 1 : 0;
427  unsigned int const nKernelParameters =
429  if (nParameters != (nKernelParameters + nBackgroundParameters))
430  throw LSST_EXCEPT(pexExcept::Exception, "Mismatched sizes in kernel solution");
431 
432  /* Fill in the kernel results */
433  std::vector<double> kValues(nKernelParameters);
434  for (unsigned int idx = 0; idx < nKernelParameters; idx++) {
435  if (std::isnan(_aVec(idx))) {
437  str(boost::format("Unable to determine kernel solution %d (nan)") % idx));
438  }
439  kValues[idx] = _aVec(idx);
440  }
441  _kernel->setKernelParameters(kValues);
442 
444  new ImageT(_kernel->getDimensions())
445  );
446  _kSum = _kernel->computeImage(*image, false);
447 
448  if (_fitForBackground) {
449  if (std::isnan(_aVec(nParameters-1))) {
451  str(boost::format("Unable to determine background solution %d (nan)") %
452  (nParameters-1)));
453  }
454  _background = _aVec(nParameters-1);
455  }
456  }
KernelSolvedBy _solvedBy
Type of algorithm used to make solution.
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
double _background
Derived differential background estimate.
bool _fitForBackground
Background terms included in fit.
lsst::afw::image::Image< lsst::afw::math::Kernel::Pixel > ImageT
A kernel that is a linear combination of fixed basis kernels.
Definition: Kernel.h:741
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:168
T dynamic_pointer_cast(T... args)
double _kSum
Derived kernel sum.
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
afw::table::Key< afw::table::Array< ImagePixelT > > image
T isnan(T... args)
Eigen::VectorXd _aVec
Derived least squares solution matrix.
std::shared_ptr< lsst::afw::math::Kernel > _kernel
Derived single-object convolution kernel.
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects...

◆ _setKernelUncertainty()

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

Not implemented.

Definition at line 460 of file KernelSolution.cc.

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

◆ 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 259 of file KernelSolution.cc.

263  {
264 
265  afwMath::Statistics varStats = afwMath::makeStatistics(varianceEstimate, afwMath::MIN);
266  if (varStats.getValue(afwMath::MIN) < 0.0) {
268  "Error: variance less than 0.0");
269  }
270  if (varStats.getValue(afwMath::MIN) == 0.0) {
272  "Error: variance equals 0.0, cannot inverse variance weight");
273  }
274 
275  lsst::afw::math::KernelList basisList =
277 
278  unsigned int const nKernelParameters = basisList.size();
279  unsigned int const nBackgroundParameters = _fitForBackground ? 1 : 0;
280  unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
281 
282  std::vector<std::shared_ptr<afwMath::Kernel> >::const_iterator kiter = basisList.begin();
283 
284  /* Ignore buffers around edge of convolved images :
285  *
286  * If the kernel has width 5, it has center pixel 2. The first good pixel
287  * is the (5-2)=3rd pixel, which is array index 2, and ends up being the
288  * index of the central pixel.
289  *
290  * You also have a buffer of unusable pixels on the other side, numbered
291  * width-center-1. The last good usable pixel is N-width+center+1.
292  *
293  * Example : the kernel is width = 5, center = 2
294  *
295  * ---|---|-c-|---|---|
296  *
297  * the image is width = N
298  * convolve this with the kernel, and you get
299  *
300  * |-x-|-x-|-g-|---|---| ... |---|---|-g-|-x-|-x-|
301  *
302  * g = first/last good pixel
303  * x = bad
304  *
305  * the first good pixel is the array index that has the value "center", 2
306  * the last good pixel has array index N-(5-2)+1
307  * eg. if N = 100, you want to use up to index 97
308  * 100-3+1 = 98, and the loops use i < 98, meaning the last
309  * index you address is 97.
310  */
311 
312  /* NOTE - we are accessing particular elements of Eigen arrays using
313  these coordinates, therefore they need to be in LOCAL coordinates.
314  This was written before ndarray unification.
315  */
316  afwGeom::Box2I goodBBox = (*kiter)->shrinkBBox(templateImage.getBBox(afwImage::LOCAL));
317  unsigned int const startCol = goodBBox.getMinX();
318  unsigned int const startRow = goodBBox.getMinY();
319  // endCol/Row is one past the index of the last good col/row
320  unsigned int endCol = goodBBox.getMaxX() + 1;
321  unsigned int endRow = goodBBox.getMaxY() + 1;
322 
323  boost::timer t;
324  t.restart();
325 
326  /* Eigen representation of input images; only the pixels that are unconvolved in cimage below */
327  Eigen::MatrixXd eigenTemplate = imageToEigenMatrix(templateImage).block(startRow,
328  startCol,
329  endRow-startRow,
330  endCol-startCol);
331  Eigen::MatrixXd eigenScience = imageToEigenMatrix(scienceImage).block(startRow,
332  startCol,
333  endRow-startRow,
334  endCol-startCol);
335  Eigen::MatrixXd eigeniVariance = imageToEigenMatrix(varianceEstimate).block(
336  startRow, startCol, endRow-startRow, endCol-startCol
337  ).array().inverse().matrix();
338 
339  /* Resize into 1-D for later usage */
340  eigenTemplate.resize(eigenTemplate.rows()*eigenTemplate.cols(), 1);
341  eigenScience.resize(eigenScience.rows()*eigenScience.cols(), 1);
342  eigeniVariance.resize(eigeniVariance.rows()*eigeniVariance.cols(), 1);
343 
344  /* Holds image convolved with basis function */
345  afwImage::Image<PixelT> cimage(templateImage.getDimensions());
346 
347  /* Holds eigen representation of image convolved with all basis functions */
348  std::vector<Eigen::MatrixXd> convolvedEigenList(nKernelParameters);
349 
350  /* Iterators over convolved image list and basis list */
351  typename std::vector<Eigen::MatrixXd>::iterator eiter = convolvedEigenList.begin();
352  /* Create C_i in the formalism of Alard & Lupton */
353  for (kiter = basisList.begin(); kiter != basisList.end(); ++kiter, ++eiter) {
354  afwMath::convolve(cimage, templateImage, **kiter, false); /* cimage stores convolved image */
355 
356  Eigen::MatrixXd cMat = imageToEigenMatrix(cimage).block(startRow,
357  startCol,
358  endRow-startRow,
359  endCol-startCol);
360  cMat.resize(cMat.size(), 1);
361  *eiter = cMat;
362 
363  }
364 
365  double time = t.elapsed();
366  LOGL_DEBUG("TRACE3.ip.diffim.StaticKernelSolution.build",
367  "Total compute time to do basis convolutions : %.2f s", time);
368  t.restart();
369 
370  /*
371  Load matrix with all values from convolvedEigenList : all images
372  (eigeniVariance, convolvedEigenList) must be the same size
373  */
374  Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
375  typename std::vector<Eigen::MatrixXd>::iterator eiterj = convolvedEigenList.begin();
376  typename std::vector<Eigen::MatrixXd>::iterator eiterE = convolvedEigenList.end();
377  for (unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
378  cMat.col(kidxj) = eiterj->col(0);
379  }
380  /* Treat the last "image" as all 1's to do the background calculation. */
381  if (_fitForBackground)
382  cMat.col(nParameters-1).fill(1.);
383 
384  _cMat = cMat;
385  _ivVec = eigeniVariance.col(0);
386  _iVec = eigenScience.col(0);
387 
388  /* Make these outside of solve() so I can check condition number */
389  _mMat = _cMat.transpose() * (_ivVec.asDiagonal() * _cMat);
390  _bVec = _cMat.transpose() * (_ivVec.asDiagonal() * _iVec);
391  }
estimate sample minimum
Definition: Statistics.h:76
Eigen::VectorXd _bVec
Derived least squares B vector.
T end(T... args)
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
Eigen::VectorXd _iVec
Vectorized I.
#define LOGL_DEBUG(logger, message...)
Log a debug-level message using a varargs/printf style interface.
Definition: Log.h:489
T time(T... args)
Eigen::VectorXd _ivVec
Inverse variance.
A class to evaluate image statistics.
Definition: Statistics.h:215
bool _fitForBackground
Background terms included in fit.
lsst::geom::Box2I getBBox(ImageOrigin origin=PARENT) const
Definition: ImageBase.h:463
int getMaxY() const noexcept
Definition: Box.h:149
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 kernel that is a linear combination of fixed basis kernels.
Definition: Kernel.h:741
Eigen::MatrixXd imageToEigenMatrix(lsst::afw::image::Image< PixelT > const &img)
Turns a 2-d Image into a 2-d Eigen Matrix.
T dynamic_pointer_cast(T... args)
void convolve(OutImageT &convolvedImage, InImageT const &inImage, KernelT const &kernel, ConvolutionControl const &convolutionControl=ConvolutionControl())
Convolve an Image or MaskedImage with a Kernel, setting pixels of an existing output image...
int getMaxX() const noexcept
Definition: Box.h:148
double getValue(Property const prop=NOTHING) const
Return the value of the desired property (if specified in the constructor)
Definition: Statistics.cc:1056
Eigen::MatrixXd _mMat
Derived least squares M matrix.
int getMinX() const noexcept
Definition: Box.h:144
T size(T... args)
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
T begin(T... args)
std::shared_ptr< lsst::afw::math::Kernel > _kernel
Derived single-object convolution kernel.
lsst::geom::Extent2I getDimensions() const
Return the image&#39;s size; useful for passing to constructors.
Definition: ImageBase.h:374
An integer coordinate rectangle.
Definition: Box.h:54
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:59
int getMinY() const noexcept
Definition: Box.h:145

◆ 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 663 of file KernelSolution.cc.

668  {
669 
670  afwMath::Statistics varStats = afwMath::makeStatistics(varianceEstimate, afwMath::MIN);
671  if (varStats.getValue(afwMath::MIN) < 0.0) {
673  "Error: variance less than 0.0");
674  }
675  if (varStats.getValue(afwMath::MIN) == 0.0) {
677  "Error: variance equals 0.0, cannot inverse variance weight");
678  }
679 
680  lsst::afw::math::KernelList basisList =
682  std::vector<std::shared_ptr<afwMath::Kernel> >::const_iterator kiter = basisList.begin();
683 
684  /* Only BAD pixels marked in this mask */
686  afwImage::MaskPixel bitMask =
690  sMask &= bitMask;
691  /* TBD: Need to figure out a way to spread this; currently done in Python */
692 
693  unsigned int const nKernelParameters = basisList.size();
694  unsigned int const nBackgroundParameters = this->_fitForBackground ? 1 : 0;
695  unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
696 
697  /* NOTE - we are accessing particular elements of Eigen arrays using
698  these coordinates, therefore they need to be in LOCAL coordinates.
699  This was written before ndarray unification.
700  */
701  /* Ignore known EDGE pixels for speed */
702  afwGeom::Box2I shrunkLocalBBox = (*kiter)->shrinkBBox(templateImage.getBBox(afwImage::LOCAL));
703  LOGL_DEBUG("TRACE3.ip.diffim.MaskedKernelSolution.build",
704  "Limits of good pixels after convolution: %d,%d -> %d,%d (local)",
705  shrunkLocalBBox.getMinX(), shrunkLocalBBox.getMinY(),
706  shrunkLocalBBox.getMaxX(), shrunkLocalBBox.getMaxY());
707 
708  /* Subimages are addressed in raw pixel coordinates */
709  unsigned int startCol = shrunkLocalBBox.getMinX();
710  unsigned int startRow = shrunkLocalBBox.getMinY();
711  unsigned int endCol = shrunkLocalBBox.getMaxX();
712  unsigned int endRow = shrunkLocalBBox.getMaxY();
713  /* Needed for Eigen block slicing operation */
714  endCol += 1;
715  endRow += 1;
716 
717  boost::timer t;
718  t.restart();
719 
720  /* Eigen representation of input images; only the pixels that are unconvolved in cimage below */
721  Eigen::MatrixXi eMask = maskToEigenMatrix(sMask).block(startRow,
722  startCol,
723  endRow-startRow,
724  endCol-startCol);
725 
726  Eigen::MatrixXd eigenTemplate = imageToEigenMatrix(templateImage).block(startRow,
727  startCol,
728  endRow-startRow,
729  endCol-startCol);
730  Eigen::MatrixXd eigenScience = imageToEigenMatrix(scienceImage).block(startRow,
731  startCol,
732  endRow-startRow,
733  endCol-startCol);
734  Eigen::MatrixXd eigeniVariance = imageToEigenMatrix(varianceEstimate).block(
735  startRow, startCol, endRow-startRow, endCol-startCol
736  ).array().inverse().matrix();
737 
738  /* Resize into 1-D for later usage */
739  eMask.resize(eMask.rows()*eMask.cols(), 1);
740  eigenTemplate.resize(eigenTemplate.rows()*eigenTemplate.cols(), 1);
741  eigenScience.resize(eigenScience.rows()*eigenScience.cols(), 1);
742  eigeniVariance.resize(eigeniVariance.rows()*eigeniVariance.cols(), 1);
743 
744  /* Do the masking, slowly for now... */
745  Eigen::MatrixXd maskedEigenTemplate(eigenTemplate.rows(), 1);
746  Eigen::MatrixXd maskedEigenScience(eigenScience.rows(), 1);
747  Eigen::MatrixXd maskedEigeniVariance(eigeniVariance.rows(), 1);
748  int nGood = 0;
749  for (int i = 0; i < eMask.rows(); i++) {
750  if (eMask(i, 0) == 0) {
751  maskedEigenTemplate(nGood, 0) = eigenTemplate(i, 0);
752  maskedEigenScience(nGood, 0) = eigenScience(i, 0);
753  maskedEigeniVariance(nGood, 0) = eigeniVariance(i, 0);
754  nGood += 1;
755  }
756  }
757  /* Can't resize() since all values are lost; use blocks */
758  eigenTemplate = maskedEigenTemplate.block(0, 0, nGood, 1);
759  eigenScience = maskedEigenScience.block(0, 0, nGood, 1);
760  eigeniVariance = maskedEigeniVariance.block(0, 0, nGood, 1);
761 
762 
763  /* Holds image convolved with basis function */
764  afwImage::Image<InputT> cimage(templateImage.getDimensions());
765 
766  /* Holds eigen representation of image convolved with all basis functions */
767  std::vector<Eigen::MatrixXd> convolvedEigenList(nKernelParameters);
768 
769  /* Iterators over convolved image list and basis list */
770  typename std::vector<Eigen::MatrixXd>::iterator eiter = convolvedEigenList.begin();
771  /* Create C_i in the formalism of Alard & Lupton */
772  for (kiter = basisList.begin(); kiter != basisList.end(); ++kiter, ++eiter) {
773  afwMath::convolve(cimage, templateImage, **kiter, false); /* cimage stores convolved image */
774 
775  Eigen::MatrixXd cMat = imageToEigenMatrix(cimage).block(startRow,
776  startCol,
777  endRow-startRow,
778  endCol-startCol);
779  cMat.resize(cMat.size(), 1);
780 
781  /* Do masking */
782  Eigen::MatrixXd maskedcMat(cMat.rows(), 1);
783  int nGood = 0;
784  for (int i = 0; i < eMask.rows(); i++) {
785  if (eMask(i, 0) == 0) {
786  maskedcMat(nGood, 0) = cMat(i, 0);
787  nGood += 1;
788  }
789  }
790  cMat = maskedcMat.block(0, 0, nGood, 1);
791  *eiter = cMat;
792  }
793 
794  double time = t.elapsed();
795  LOGL_DEBUG("TRACE3.ip.diffim.StaticKernelSolution.build",
796  "Total compute time to do basis convolutions : %.2f s", time);
797  t.restart();
798 
799  /*
800  Load matrix with all values from convolvedEigenList : all images
801  (eigeniVariance, convolvedEigenList) must be the same size
802  */
803  Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
804  typename std::vector<Eigen::MatrixXd>::iterator eiterj = convolvedEigenList.begin();
805  typename std::vector<Eigen::MatrixXd>::iterator eiterE = convolvedEigenList.end();
806  for (unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
807  cMat.col(kidxj) = eiterj->col(0);
808  }
809  /* Treat the last "image" as all 1's to do the background calculation. */
810  if (this->_fitForBackground)
811  cMat.col(nParameters-1).fill(1.);
812 
813  this->_cMat = cMat;
814  this->_ivVec = eigeniVariance.col(0);
815  this->_iVec = eigenScience.col(0);
816 
817  /* Make these outside of solve() so I can check condition number */
818  this->_mMat = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_cMat;
819  this->_bVec = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_iVec;
820 
821  }
Eigen::MatrixXi maskToEigenMatrix(lsst::afw::image::Mask< lsst::afw::image::MaskPixel > const &mask)
estimate sample minimum
Definition: Statistics.h:76
Eigen::VectorXd _bVec
Derived least squares B vector.
T end(T... args)
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
Eigen::VectorXd _iVec
Vectorized I.
#define LOGL_DEBUG(logger, message...)
Log a debug-level message using a varargs/printf style interface.
Definition: Log.h:489
T time(T... args)
Eigen::VectorXd _ivVec
Inverse variance.
A class to evaluate image statistics.
Definition: Statistics.h:215
bool _fitForBackground
Background terms included in fit.
lsst::geom::Box2I getBBox(ImageOrigin origin=PARENT) const
Definition: ImageBase.h:463
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:78
int getMaxY() const noexcept
Definition: Box.h:149
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 kernel that is a linear combination of fixed basis kernels.
Definition: Kernel.h:741
Eigen::MatrixXd imageToEigenMatrix(lsst::afw::image::Image< PixelT > const &img)
Turns a 2-d Image into a 2-d Eigen Matrix.
T dynamic_pointer_cast(T... args)
static MaskPixelT getPlaneBitMask(const std::vector< std::string > &names)
Return the bitmask corresponding to a vector of plane names OR&#39;d together.
Definition: Mask.cc:383
void convolve(OutImageT &convolvedImage, InImageT const &inImage, KernelT const &kernel, ConvolutionControl const &convolutionControl=ConvolutionControl())
Convolve an Image or MaskedImage with a Kernel, setting pixels of an existing output image...
int getMaxX() const noexcept
Definition: Box.h:148
double getValue(Property const prop=NOTHING) const
Return the value of the desired property (if specified in the constructor)
Definition: Statistics.cc:1056
Eigen::MatrixXd _mMat
Derived least squares M matrix.
int getMinX() const noexcept
Definition: Box.h:144
T size(T... args)
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
T begin(T... args)
std::shared_ptr< lsst::afw::math::Kernel > _kernel
Derived single-object convolution kernel.
lsst::geom::Extent2I getDimensions() const
Return the image&#39;s size; useful for passing to constructors.
Definition: ImageBase.h:374
An integer coordinate rectangle.
Definition: Box.h:54
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:59
int getMinY() const noexcept
Definition: Box.h:145

◆ 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::afw::geom::Box2I  maskBox 
)
virtual

Definition at line 826 of file KernelSolution.cc.

831  {
832 
833  afwMath::Statistics varStats = afwMath::makeStatistics(varianceEstimate, afwMath::MIN);
834  if (varStats.getValue(afwMath::MIN) < 0.0) {
836  "Error: variance less than 0.0");
837  }
838  if (varStats.getValue(afwMath::MIN) == 0.0) {
840  "Error: variance equals 0.0, cannot inverse variance weight");
841  }
842 
843  lsst::afw::math::KernelList basisList =
845 
846  unsigned int const nKernelParameters = basisList.size();
847  unsigned int const nBackgroundParameters = this->_fitForBackground ? 1 : 0;
848  unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
849 
850  std::vector<std::shared_ptr<afwMath::Kernel> >::const_iterator kiter = basisList.begin();
851 
852  /*
853  NOTE : If we are using these views in Afw's Image space, we need to
854  make sure and compensate for the XY0 of the image:
855 
856  afwGeom::Box2I fullBBox = templateImage.getBBox();
857  int maskStartCol = maskBox.getMinX();
858  int maskStartRow = maskBox.getMinY();
859  int maskEndCol = maskBox.getMaxX();
860  int maskEndRow = maskBox.getMaxY();
861 
862 
863  If we are going to be doing the slicing in Eigen matrices derived from
864  the images, ignore the XY0.
865 
866  afwGeom::Box2I fullBBox = templateImage.getBBox(afwImage::LOCAL);
867 
868  int maskStartCol = maskBox.getMinX() - templateImage.getX0();
869  int maskStartRow = maskBox.getMinY() - templateImage.getY0();
870  int maskEndCol = maskBox.getMaxX() - templateImage.getX0();
871  int maskEndRow = maskBox.getMaxY() - templateImage.getY0();
872 
873  */
874 
875 
876  afwGeom::Box2I shrunkBBox = (*kiter)->shrinkBBox(templateImage.getBBox());
877 
878  LOGL_DEBUG("TRACE3.ip.diffim.MaskedKernelSolution.build",
879  "Limits of good pixels after convolution: %d,%d -> %d,%d",
880  shrunkBBox.getMinX(), shrunkBBox.getMinY(),
881  shrunkBBox.getMaxX(), shrunkBBox.getMaxY());
882 
883  unsigned int const startCol = shrunkBBox.getMinX();
884  unsigned int const startRow = shrunkBBox.getMinY();
885  unsigned int const endCol = shrunkBBox.getMaxX();
886  unsigned int const endRow = shrunkBBox.getMaxY();
887 
888  /* NOTE: no endCol/endRow += 1 for block slicing, since we are doing the
889  slicing using Afw, not Eigen
890 
891  Eigen arrays have index 0,0 in the upper right, while LSST images
892  have 0,0 in the lower left. The y-axis is flipped. When translating
893  Images to Eigen matrices in ipDiffim::imageToEigenMatrix this is
894  accounted for. However, we still need to be aware of this fact if
895  addressing subregions of an Eigen matrix. This is why the slicing is
896  done in Afw, its cleaner.
897 
898  Please see examples/maskedKernel.cc for elaboration on some of the
899  tests done to make sure this indexing gets done right.
900 
901  */
902 
903 
904  /* Inner limits; of mask box */
905  int maskStartCol = maskBox.getMinX();
906  int maskStartRow = maskBox.getMinY();
907  int maskEndCol = maskBox.getMaxX();
908  int maskEndRow = maskBox.getMaxY();
909 
910  /*
911 
912  |---------------------------|
913  | Kernel Boundary |
914  | |---------------------| |
915  | | Top | |
916  | |......_________......| |
917  | | | | | |
918  | | L | Box | R | |
919  | | | | | |
920  | |......---------......| |
921  | | Bottom | |
922  | |---------------------| |
923  | |
924  |---------------------------|
925 
926  4 regions we want to extract from the pixels: top bottom left right
927 
928  */
929  afwGeom::Box2I tBox = afwGeom::Box2I(afwGeom::Point2I(startCol, maskEndRow + 1),
930  afwGeom::Point2I(endCol, endRow));
931 
932  afwGeom::Box2I bBox = afwGeom::Box2I(afwGeom::Point2I(startCol, startRow),
933  afwGeom::Point2I(endCol, maskStartRow - 1));
934 
935  afwGeom::Box2I lBox = afwGeom::Box2I(afwGeom::Point2I(startCol, maskStartRow),
936  afwGeom::Point2I(maskStartCol - 1, maskEndRow));
937 
938  afwGeom::Box2I rBox = afwGeom::Box2I(afwGeom::Point2I(maskEndCol + 1, maskStartRow),
939  afwGeom::Point2I(endCol, maskEndRow));
940 
941  LOGL_DEBUG("TRACE3.ip.diffim.MaskedKernelSolution.build",
942  "Upper good pixel region: %d,%d -> %d,%d",
943  tBox.getMinX(), tBox.getMinY(), tBox.getMaxX(), tBox.getMaxY());
944  LOGL_DEBUG("TRACE3.ip.diffim.MaskedKernelSolution.build",
945  "Bottom good pixel region: %d,%d -> %d,%d",
946  bBox.getMinX(), bBox.getMinY(), bBox.getMaxX(), bBox.getMaxY());
947  LOGL_DEBUG("TRACE3.ip.diffim.MaskedKernelSolution.build",
948  "Left good pixel region: %d,%d -> %d,%d",
949  lBox.getMinX(), lBox.getMinY(), lBox.getMaxX(), lBox.getMaxY());
950  LOGL_DEBUG("TRACE3.ip.diffim.MaskedKernelSolution.build",
951  "Right good pixel region: %d,%d -> %d,%d",
952  rBox.getMinX(), rBox.getMinY(), rBox.getMaxX(), rBox.getMaxY());
953 
955  boxArray.push_back(tBox);
956  boxArray.push_back(bBox);
957  boxArray.push_back(lBox);
958  boxArray.push_back(rBox);
959 
960  int totalSize = tBox.getWidth() * tBox.getHeight();
961  totalSize += bBox.getWidth() * bBox.getHeight();
962  totalSize += lBox.getWidth() * lBox.getHeight();
963  totalSize += rBox.getWidth() * rBox.getHeight();
964 
965  Eigen::MatrixXd eigenTemplate(totalSize, 1);
966  Eigen::MatrixXd eigenScience(totalSize, 1);
967  Eigen::MatrixXd eigeniVariance(totalSize, 1);
968  eigenTemplate.setZero();
969  eigenScience.setZero();
970  eigeniVariance.setZero();
971 
972  boost::timer t;
973  t.restart();
974 
975  int nTerms = 0;
976  typename std::vector<afwGeom::Box2I>::iterator biter = boxArray.begin();
977  for (; biter != boxArray.end(); ++biter) {
978  int area = (*biter).getWidth() * (*biter).getHeight();
979 
980  afwImage::Image<InputT> siTemplate(templateImage, *biter);
981  afwImage::Image<InputT> siScience(scienceImage, *biter);
982  afwImage::Image<InputT> sVarEstimate(varianceEstimate, *biter);
983 
984  Eigen::MatrixXd eTemplate = imageToEigenMatrix(siTemplate);
985  Eigen::MatrixXd eScience = imageToEigenMatrix(siScience);
986  Eigen::MatrixXd eiVarEstimate = imageToEigenMatrix(sVarEstimate).array().inverse().matrix();
987 
988  eTemplate.resize(area, 1);
989  eScience.resize(area, 1);
990  eiVarEstimate.resize(area, 1);
991 
992  eigenTemplate.block(nTerms, 0, area, 1) = eTemplate.block(0, 0, area, 1);
993  eigenScience.block(nTerms, 0, area, 1) = eScience.block(0, 0, area, 1);
994  eigeniVariance.block(nTerms, 0, area, 1) = eiVarEstimate.block(0, 0, area, 1);
995 
996  nTerms += area;
997  }
998 
999  afwImage::Image<InputT> cimage(templateImage.getDimensions());
1000 
1001  std::vector<Eigen::MatrixXd> convolvedEigenList(nKernelParameters);
1002  typename std::vector<Eigen::MatrixXd>::iterator eiter = convolvedEigenList.begin();
1003  /* Create C_i in the formalism of Alard & Lupton */
1004  for (kiter = basisList.begin(); kiter != basisList.end(); ++kiter, ++eiter) {
1005  afwMath::convolve(cimage, templateImage, **kiter, false); /* cimage stores convolved image */
1006  Eigen::MatrixXd cMat(totalSize, 1);
1007  cMat.setZero();
1008 
1009  int nTerms = 0;
1010  typename std::vector<afwGeom::Box2I>::iterator biter = boxArray.begin();
1011  for (; biter != boxArray.end(); ++biter) {
1012  int area = (*biter).getWidth() * (*biter).getHeight();
1013 
1014  afwImage::Image<InputT> csubimage(cimage, *biter);
1015  Eigen::MatrixXd esubimage = imageToEigenMatrix(csubimage);
1016  esubimage.resize(area, 1);
1017  cMat.block(nTerms, 0, area, 1) = esubimage.block(0, 0, area, 1);
1018 
1019  nTerms += area;
1020  }
1021 
1022  *eiter = cMat;
1023 
1024  }
1025 
1026  double time = t.elapsed();
1027  LOGL_DEBUG("TRACE3.ip.diffim.MaskedKernelSolution.build",
1028  "Total compute time to do basis convolutions : %.2f s", time);
1029  t.restart();
1030 
1031  /*
1032  Load matrix with all values from convolvedEigenList : all images
1033  (eigeniVariance, convolvedEigenList) must be the same size
1034  */
1035  Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
1036  typename std::vector<Eigen::MatrixXd>::iterator eiterj = convolvedEigenList.begin();
1037  typename std::vector<Eigen::MatrixXd>::iterator eiterE = convolvedEigenList.end();
1038  for (unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
1039  cMat.col(kidxj) = eiterj->col(0);
1040  }
1041  /* Treat the last "image" as all 1's to do the background calculation. */
1042  if (this->_fitForBackground)
1043  cMat.col(nParameters-1).fill(1.);
1044 
1045  this->_cMat = cMat;
1046  this->_ivVec = eigeniVariance.col(0);
1047  this->_iVec = eigenScience.col(0);
1048 
1049  /* Make these outside of solve() so I can check condition number */
1050  this->_mMat = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_cMat;
1051  this->_bVec = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_iVec;
1052  }
int getHeight() const noexcept
Definition: Box.h:175
estimate sample minimum
Definition: Statistics.h:76
Eigen::VectorXd _bVec
Derived least squares B vector.
T end(T... args)
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
Eigen::VectorXd _iVec
Vectorized I.
#define LOGL_DEBUG(logger, message...)
Log a debug-level message using a varargs/printf style interface.
Definition: Log.h:489
T time(T... args)
Eigen::VectorXd _ivVec
Inverse variance.
A class to evaluate image statistics.
Definition: Statistics.h:215
T push_back(T... args)
bool _fitForBackground
Background terms included in fit.
lsst::geom::Box2I getBBox(ImageOrigin origin=PARENT) const
Definition: ImageBase.h:463
int getMaxY() const noexcept
Definition: Box.h:149
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 kernel that is a linear combination of fixed basis kernels.
Definition: Kernel.h:741
int getWidth() const noexcept
Definition: Box.h:174
Eigen::MatrixXd imageToEigenMatrix(lsst::afw::image::Image< PixelT > const &img)
Turns a 2-d Image into a 2-d Eigen Matrix.
T dynamic_pointer_cast(T... args)
void convolve(OutImageT &convolvedImage, InImageT const &inImage, KernelT const &kernel, ConvolutionControl const &convolutionControl=ConvolutionControl())
Convolve an Image or MaskedImage with a Kernel, setting pixels of an existing output image...
int getMaxX() const noexcept
Definition: Box.h:148
double getValue(Property const prop=NOTHING) const
Return the value of the desired property (if specified in the constructor)
Definition: Statistics.cc:1056
Eigen::MatrixXd _mMat
Derived least squares M matrix.
int getMinX() const noexcept
Definition: Box.h:144
T size(T... args)
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
T begin(T... args)
std::shared_ptr< lsst::afw::math::Kernel > _kernel
Derived single-object convolution kernel.
lsst::geom::Extent2I getDimensions() const
Return the image&#39;s size; useful for passing to constructors.
Definition: ImageBase.h:374
An integer coordinate rectangle.
Definition: Box.h:54
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:59
int getMinY() const noexcept
Definition: Box.h:145

◆ 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 498 of file KernelSolution.cc.

503  {
504 
505  afwMath::Statistics varStats = afwMath::makeStatistics(varianceEstimate, afwMath::MIN);
506  if (varStats.getValue(afwMath::MIN) < 0.0) {
508  "Error: variance less than 0.0");
509  }
510  if (varStats.getValue(afwMath::MIN) == 0.0) {
512  "Error: variance equals 0.0, cannot inverse variance weight");
513  }
514 
515  /* Full footprint of all input images */
517  new afwDet::Footprint(std::make_shared<afwGeom::SpanSet>(templateImage.getBBox())));
518 
519  afwMath::KernelList basisList =
521  std::vector<std::shared_ptr<afwMath::Kernel> >::const_iterator kiter = basisList.begin();
522 
523  /* Only BAD pixels marked in this mask */
524  afwImage::MaskPixel bitMask =
529 
530  /* Create a Footprint that contains all the masked pixels set above */
532  afwDet::FootprintSet maskFpSet(pixelMask, threshold, true);
533 
534  /* And spread it by the kernel half width */
535  int growPix = (*kiter)->getCtr().getX();
536  afwDet::FootprintSet maskedFpSetGrown(maskFpSet, growPix, true);
537 
538 #if 0
539  for (typename afwDet::FootprintSet::FootprintList::iterator
540  ptr = maskedFpSetGrown.getFootprints()->begin(),
541  end = maskedFpSetGrown.getFootprints()->end();
542  ptr != end;
543  ++ptr) {
544 
545  afwDet::setMaskFromFootprint(finalMask,
546  (**ptr),
548  }
549 #endif
550 
551  afwImage::Mask<afwImage::MaskPixel> finalMask(pixelMask.getDimensions());
552  for (auto const & foot : *(maskedFpSetGrown.getFootprints())) {
553  foot->getSpans()->setMask(finalMask, afwImage::Mask<afwImage::MaskPixel>::getPlaneBitMask("BAD"));
554  }
555  pixelMask.writeFits("pixelmask.fits");
556  finalMask.writeFits("finalmask.fits");
557 
558 
559  ndarray::Array<int, 1, 1> maskArray =
560  ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
561  fullFp->getSpans()->flatten(maskArray, finalMask.getArray(), templateImage.getXY0());
562  auto maskEigen = ndarray::asEigenMatrix(maskArray);
563 
564  ndarray::Array<InputT, 1, 1> arrayTemplate =
565  ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
566  fullFp->getSpans()->flatten(arrayTemplate, templateImage.getArray(), templateImage.getXY0());
567  auto eigenTemplate0 = ndarray::asEigenMatrix(arrayTemplate);
568 
569  ndarray::Array<InputT, 1, 1> arrayScience =
570  ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
571  fullFp->getSpans()->flatten(arrayScience, scienceImage.getArray(), scienceImage.getXY0());
572  auto eigenScience0 = ndarray::asEigenMatrix(arrayScience);
573 
574  ndarray::Array<afwImage::VariancePixel, 1, 1> arrayVariance =
575  ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
576  fullFp->getSpans()->flatten(arrayVariance, varianceEstimate.getArray(), varianceEstimate.getXY0());
577  auto eigenVariance0 = ndarray::asEigenMatrix(arrayVariance);
578 
579  int nGood = 0;
580  for (int i = 0; i < maskEigen.size(); i++) {
581  if (maskEigen(i) == 0.0)
582  nGood += 1;
583  }
584 
585  Eigen::VectorXd eigenTemplate(nGood);
586  Eigen::VectorXd eigenScience(nGood);
587  Eigen::VectorXd eigenVariance(nGood);
588  int nUsed = 0;
589  for (int i = 0; i < maskEigen.size(); i++) {
590  if (maskEigen(i) == 0.0) {
591  eigenTemplate(nUsed) = eigenTemplate0(i);
592  eigenScience(nUsed) = eigenScience0(i);
593  eigenVariance(nUsed) = eigenVariance0(i);
594  nUsed += 1;
595  }
596  }
597 
598 
599  boost::timer t;
600  t.restart();
601 
602  unsigned int const nKernelParameters = basisList.size();
603  unsigned int const nBackgroundParameters = this->_fitForBackground ? 1 : 0;
604  unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
605 
606  /* Holds image convolved with basis function */
607  afwImage::Image<InputT> cimage(templateImage.getDimensions());
608 
609  /* Holds eigen representation of image convolved with all basis functions */
610  std::vector<Eigen::VectorXd> convolvedEigenList(nKernelParameters);
611 
612  /* Iterators over convolved image list and basis list */
613  typename std::vector<Eigen::VectorXd>::iterator eiter = convolvedEigenList.begin();
614 
615  /* Create C_i in the formalism of Alard & Lupton */
616  for (kiter = basisList.begin(); kiter != basisList.end(); ++kiter, ++eiter) {
617  afwMath::convolve(cimage, templateImage, **kiter, false); /* cimage stores convolved image */
618 
619  ndarray::Array<InputT, 1, 1> arrayC =
620  ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
621  fullFp->getSpans()->flatten(arrayC, cimage.getArray(), cimage.getXY0());
622  auto eigenC0 = ndarray::asEigenMatrix(arrayC);
623 
624  Eigen::VectorXd eigenC(nGood);
625  int nUsed = 0;
626  for (int i = 0; i < maskEigen.size(); i++) {
627  if (maskEigen(i) == 0.0) {
628  eigenC(nUsed) = eigenC0(i);
629  nUsed += 1;
630  }
631  }
632 
633  *eiter = eigenC;
634  }
635  double time = t.elapsed();
636  LOGL_DEBUG("TRACE3.ip.diffim.StaticKernelSolution.buildWithMask",
637  "Total compute time to do basis convolutions : %.2f s", time);
638  t.restart();
639 
640  /* Load matrix with all convolved images */
641  Eigen::MatrixXd cMat(eigenTemplate.size(), nParameters);
642  typename std::vector<Eigen::VectorXd>::iterator eiterj = convolvedEigenList.begin();
643  typename std::vector<Eigen::VectorXd>::iterator eiterE = convolvedEigenList.end();
644  for (unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
645  cMat.block(0, kidxj, eigenTemplate.size(), 1) =
646  Eigen::MatrixXd(*eiterj).block(0, 0, eigenTemplate.size(), 1);
647  }
648  /* Treat the last "image" as all 1's to do the background calculation. */
649  if (this->_fitForBackground)
650  cMat.col(nParameters-1).fill(1.);
651 
652  this->_cMat = cMat;
653  this->_ivVec = eigenVariance.array().inverse().matrix();
654  this->_iVec = eigenScience;
655 
656  /* Make these outside of solve() so I can check condition number */
657  this->_mMat = this->_cMat.transpose() * this->_ivVec.asDiagonal() * (this->_cMat);
658  this->_bVec = this->_cMat.transpose() * this->_ivVec.asDiagonal() * (this->_iVec);
659  }
uint64_t * ptr
Definition: RangeSet.cc:88
estimate sample minimum
Definition: Statistics.h:76
Eigen::VectorXd _bVec
Derived least squares B vector.
Use (pixels & (given mask))
Definition: Threshold.h:48
A Threshold is used to pass a threshold value to detection algorithms.
Definition: Threshold.h:43
T end(T... args)
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
Eigen::VectorXd _iVec
Vectorized I.
#define LOGL_DEBUG(logger, message...)
Log a debug-level message using a varargs/printf style interface.
Definition: Log.h:489
T time(T... args)
Eigen::VectorXd _ivVec
Inverse variance.
A class to evaluate image statistics.
Definition: Statistics.h:215
bool _fitForBackground
Background terms included in fit.
lsst::geom::Box2I getBBox(ImageOrigin origin=PARENT) const
Definition: ImageBase.h:463
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:78
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 kernel that is a linear combination of fixed basis kernels.
Definition: Kernel.h:741
T dynamic_pointer_cast(T... args)
static MaskPixelT getPlaneBitMask(const std::vector< std::string > &names)
Return the bitmask corresponding to a vector of plane names OR&#39;d together.
Definition: Mask.cc:383
void convolve(OutImageT &convolvedImage, InImageT const &inImage, KernelT const &kernel, ConvolutionControl const &convolutionControl=ConvolutionControl())
Convolve an Image or MaskedImage with a Kernel, setting pixels of an existing output image...
Class to describe the properties of a detected object from an image.
Definition: Footprint.h:62
double getValue(Property const prop=NOTHING) const
Return the value of the desired property (if specified in the constructor)
Definition: Statistics.cc:1056
Eigen::MatrixXd _mMat
Derived least squares M matrix.
lsst::geom::Point2I getXY0() const
Return the image&#39;s origin.
Definition: ImageBase.h:341
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
A set of Footprints, associated with a MaskedImage.
Definition: FootprintSet.h:53
T begin(T... args)
std::shared_ptr< lsst::afw::math::Kernel > _kernel
Derived single-object convolution kernel.
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.
lsst::geom::Extent2I getDimensions() const
Return the image&#39;s size; useful for passing to constructors.
Definition: ImageBase.h:374
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:59
int end

◆ getB()

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

Definition at line 65 of file KernelSolution.h.

65 {return _bVec;}
Eigen::VectorXd _bVec
Derived least squares B vector.

◆ getBackground()

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

Definition at line 233 of file KernelSolution.cc.

233  {
235  throw LSST_EXCEPT(pexExcept::Exception, "Kernel not solved; cannot return background");
236  }
237  return _background;
238  }
KernelSolvedBy _solvedBy
Type of algorithm used to make solution.
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
double _background
Derived differential background estimate.
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48

◆ getConditionNumber() [1/2]

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

Definition at line 92 of file KernelSolution.cc.

92  {
93  return getConditionNumber(_mMat, conditionType);
94  }
virtual double getConditionNumber(ConditionNumberType conditionType)
Eigen::MatrixXd _mMat
Derived least squares M matrix.

◆ getConditionNumber() [2/2]

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

Definition at line 96 of file KernelSolution.cc.

97  {
98  switch (conditionType) {
99  case EIGENVALUE:
100  {
101  Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eVecValues(mMat);
102  Eigen::VectorXd eValues = eVecValues.eigenvalues();
103  double eMax = eValues.maxCoeff();
104  double eMin = eValues.minCoeff();
105  LOGL_DEBUG("TRACE3.ip.diffim.KernelSolution.getConditionNumber",
106  "EIGENVALUE eMax / eMin = %.3e", eMax / eMin);
107  return (eMax / eMin);
108  break;
109  }
110  case SVD:
111  {
112  Eigen::VectorXd sValues = mMat.jacobiSvd().singularValues();
113  double sMax = sValues.maxCoeff();
114  double sMin = sValues.minCoeff();
115  LOGL_DEBUG("TRACE3.ip.diffim.KernelSolution.getConditionNumber",
116  "SVD eMax / eMin = %.3e", sMax / sMin);
117  return (sMax / sMin);
118  break;
119  }
120  default:
121  {
123  "Undefined ConditionNumberType : only EIGENVALUE, SVD allowed.");
124  break;
125  }
126  }
127  }
#define LOGL_DEBUG(logger, message...)
Log a debug-level message using a varargs/printf style interface.
Definition: Log.h:489
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
Reports invalid arguments.
Definition: Runtime.h:66

◆ getId()

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

Definition at line 69 of file KernelSolution.h.

69 { return _id; }
int _id
Unique ID for object.

◆ getKernel()

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

Definition at line 213 of file KernelSolution.cc.

213  {
215  throw LSST_EXCEPT(pexExcept::Exception, "Kernel not solved; cannot return solution");
216  }
217  return _kernel;
218  }
KernelSolvedBy _solvedBy
Type of algorithm used to make solution.
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
std::shared_ptr< lsst::afw::math::Kernel > _kernel
Derived single-object convolution kernel.

◆ getKsum()

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

Definition at line 241 of file KernelSolution.cc.

241  {
243  throw LSST_EXCEPT(pexExcept::Exception, "Kernel not solved; cannot return ksum");
244  }
245  return _kSum;
246  }
KernelSolvedBy _solvedBy
Type of algorithm used to make solution.
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
double _kSum
Derived kernel sum.
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48

◆ getM()

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

Definition at line 64 of file KernelSolution.h.

64 {return _mMat;}
Eigen::MatrixXd _mMat
Derived least squares M matrix.

◆ getSolutionPair()

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

Definition at line 250 of file KernelSolution.cc.

250  {
252  throw LSST_EXCEPT(pexExcept::Exception, "Kernel not solved; cannot return solution");
253  }
254 
256  }
KernelSolvedBy _solvedBy
Type of algorithm used to make solution.
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
double _background
Derived differential background estimate.
T make_pair(T... args)
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
std::shared_ptr< lsst::afw::math::Kernel > _kernel
Derived single-object convolution kernel.

◆ getSolvedBy()

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

Definition at line 60 of file KernelSolution.h.

60 {return _solvedBy;}
KernelSolvedBy _solvedBy
Type of algorithm used to make solution.

◆ 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 221 of file KernelSolution.cc.

221  {
223  throw LSST_EXCEPT(pexExcept::Exception, "Kernel not solved; cannot return image");
224  }
227  );
228  (void)_kernel->computeImage(*image, false);
229  return image;
230  }
KernelSolvedBy _solvedBy
Type of algorithm used to make solution.
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
afw::table::Key< afw::table::Array< ImagePixelT > > image
std::shared_ptr< lsst::afw::math::Kernel > _kernel
Derived single-object convolution kernel.
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects...
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:59

◆ printA()

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

Definition at line 68 of file KernelSolution.h.

68 {std::cout << _aVec << std::endl;}
T endl(T... args)
Eigen::VectorXd _aVec
Derived least squares solution matrix.

◆ printB()

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

Definition at line 67 of file KernelSolution.h.

67 {std::cout << _bVec << std::endl;}
Eigen::VectorXd _bVec
Derived least squares B vector.
T endl(T... args)

◆ printM()

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

Definition at line 66 of file KernelSolution.h.

66 {std::cout << _mMat << std::endl;}
T endl(T... args)
Eigen::MatrixXd _mMat
Derived least squares M matrix.

◆ solve() [1/2]

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

Definition at line 129 of file KernelSolution.cc.

130  {
131 
132  if (DEBUG_MATRIX) {
133  std::cout << "M " << std::endl;
134  std::cout << mMat << std::endl;
135  std::cout << "B " << std::endl;
136  std::cout << bVec << std::endl;
137  }
138 
139  Eigen::VectorXd aVec = Eigen::VectorXd::Zero(bVec.size());
140 
141  boost::timer t;
142  t.restart();
143 
144  LOGL_DEBUG("TRACE2.ip.diffim.KernelSolution.solve",
145  "Solving for kernel");
146  _solvedBy = LU;
147  Eigen::FullPivLU<Eigen::MatrixXd> lu(mMat);
148  if (lu.isInvertible()) {
149  aVec = lu.solve(bVec);
150  } else {
151  LOGL_DEBUG("TRACE3.ip.diffim.KernelSolution.solve",
152  "Unable to determine kernel via LU");
153  /* LAST RESORT */
154  try {
155 
157  Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eVecValues(mMat);
158  Eigen::MatrixXd const& rMat = eVecValues.eigenvectors();
159  Eigen::VectorXd eValues = eVecValues.eigenvalues();
160 
161  for (int i = 0; i != eValues.rows(); ++i) {
162  if (eValues(i) != 0.0) {
163  eValues(i) = 1.0/eValues(i);
164  }
165  }
166 
167  aVec = rMat * eValues.asDiagonal() * rMat.transpose() * bVec;
168  } catch (pexExcept::Exception& e) {
169 
170  _solvedBy = NONE;
171  LOGL_DEBUG("TRACE3.ip.diffim.KernelSolution.solve",
172  "Unable to determine kernel via eigen-values");
173 
174  throw LSST_EXCEPT(pexExcept::Exception, "Unable to determine kernel solution");
175  }
176  }
177 
178  double time = t.elapsed();
179  LOGL_DEBUG("TRACE3.ip.diffim.KernelSolution.solve",
180  "Compute time for matrix math : %.2f s", time);
181 
182  if (DEBUG_MATRIX) {
183  std::cout << "A " << std::endl;
184  std::cout << aVec << std::endl;
185  }
186 
187  _aVec = aVec;
188  }
T endl(T... args)
KernelSolvedBy _solvedBy
Type of algorithm used to make solution.
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
#define LOGL_DEBUG(logger, message...)
Log a debug-level message using a varargs/printf style interface.
Definition: Log.h:489
T time(T... args)
#define DEBUG_MATRIX
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
Eigen::VectorXd _aVec
Derived least squares solution matrix.

◆ solve() [2/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 394 of file KernelSolution.cc.

394  {
395  LOGL_DEBUG("TRACE3.ip.diffim.StaticKernelSolution.solve",
396  "mMat is %d x %d; bVec is %d; cMat is %d x %d; vVec is %d; iVec is %d",
397  _mMat.rows(), _mMat.cols(), _bVec.size(),
398  _cMat.rows(), _cMat.cols(), _ivVec.size(), _iVec.size());
399 
400  if (DEBUG_MATRIX) {
401  std::cout << "C" << std::endl;
402  std::cout << _cMat << std::endl;
403  std::cout << "iV" << std::endl;
404  std::cout << _ivVec << std::endl;
405  std::cout << "I" << std::endl;
406  std::cout << _iVec << std::endl;
407  }
408 
409  try {
411  } catch (pexExcept::Exception &e) {
412  LSST_EXCEPT_ADD(e, "Unable to solve static kernel matrix");
413  throw e;
414  }
415  /* Turn matrices into _kernel and _background */
416  _setKernel();
417  }
Eigen::VectorXd _bVec
Derived least squares B vector.
T endl(T... args)
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
Eigen::VectorXd _iVec
Vectorized I.
#define LOGL_DEBUG(logger, message...)
Log a debug-level message using a varargs/printf style interface.
Definition: Log.h:489
Eigen::VectorXd _ivVec
Inverse variance.
void _setKernel()
Set kernel after solution.
Eigen::MatrixXd _mMat
Derived least squares M matrix.
#define DEBUG_MATRIX
#define LSST_EXCEPT_ADD(e, m)
Add the current location and a message to an existing exception before rethrowing it...
Definition: Exception.h:54

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: