LSSTApplications  8.0.0.0+107,8.0.0.1+13,9.1+18,9.2,master-g084aeec0a4,master-g0aced2eed8+6,master-g15627eb03c,master-g28afc54ef9,master-g3391ba5ea0,master-g3d0fb8ae5f,master-g4432ae2e89+36,master-g5c3c32f3ec+17,master-g60f1e072bb+1,master-g6a3ac32d1b,master-g76a88a4307+1,master-g7bce1f4e06+57,master-g8ff4092549+31,master-g98e65bf68e,master-ga6b77976b1+53,master-gae20e2b580+3,master-gb584cd3397+53,master-gc5448b162b+1,master-gc54cf9771d,master-gc69578ece6+1,master-gcbf758c456+22,master-gcec1da163f+63,master-gcf15f11bcc,master-gd167108223,master-gf44c96c709
LSSTDataManagementBasePackage
Public Types | Public Member Functions | 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 boost::shared_ptr
< MaskedKernelSolution< InputT > > 
Ptr
 
- Public Types inherited from lsst::ip::diffim::StaticKernelSolution< InputT >
typedef boost::shared_ptr
< StaticKernelSolution< InputT > > 
Ptr
 
- Public Types inherited from lsst::ip::diffim::KernelSolution
enum  KernelSolvedBy {
  NONE = 0, CHOLESKY_LDLT = 1, CHOLESKY_LLT = 2, LU = 3,
  EIGENVECTOR = 4
}
 
enum  ConditionNumberType { EIGENVALUE = 0, SVD = 1 }
 
typedef boost::shared_ptr
< KernelSolution
Ptr
 
typedef
lsst::afw::math::Kernel::Pixel 
PixelT
 
typedef
lsst::afw::image::Image
< lsst::afw::math::Kernel::Pixel
ImageT
 

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)
 
- Public Member Functions inherited from lsst::ip::diffim::StaticKernelSolution< InputT >
 StaticKernelSolution (lsst::afw::math::KernelList const &basisList, bool fitForBackground)
 
virtual ~StaticKernelSolution ()
 
void solve ()
 
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
lsst::afw::math::Kernel::Ptr 
getKernel ()
 
virtual
lsst::afw::image::Image
< lsst::afw::math::Kernel::Pixel >
::Ptr 
makeKernelImage ()
 
virtual double getBackground ()
 
virtual double getKsum ()
 
virtual std::pair
< boost::shared_ptr
< lsst::afw::math::Kernel >
, double > 
getSolutionPair ()
 
- Public Member Functions inherited from lsst::ip::diffim::KernelSolution
 KernelSolution (boost::shared_ptr< Eigen::MatrixXd > mMat, boost::shared_ptr< Eigen::VectorXd > bVec, bool fitForBackground)
 
 KernelSolution (bool fitForBackground)
 
 KernelSolution ()
 
virtual ~KernelSolution ()
 
virtual void solve (Eigen::MatrixXd mMat, Eigen::VectorXd bVec)
 
KernelSolvedBy getSolvedBy ()
 
virtual double getConditionNumber (ConditionNumberType conditionType)
 
virtual double getConditionNumber (Eigen::MatrixXd mMat, ConditionNumberType conditionType)
 
boost::shared_ptr
< Eigen::MatrixXd > 
getM ()
 
boost::shared_ptr
< Eigen::VectorXd > 
getB ()
 
void printM ()
 
void printB ()
 
void printA ()
 
int getId () const
 

Additional Inherited Members

- Protected Member Functions inherited from lsst::ip::diffim::StaticKernelSolution< InputT >
void _setKernel ()
 Set kernel after solution. More...
 
void _setKernelUncertainty ()
 Not implemented. More...
 
- Protected Attributes inherited from lsst::ip::diffim::StaticKernelSolution< InputT >
boost::shared_ptr
< Eigen::MatrixXd > 
_cMat
 K_i x R. More...
 
boost::shared_ptr
< Eigen::VectorXd > 
_iVec
 Vectorized I. More...
 
boost::shared_ptr
< Eigen::VectorXd > 
_ivVec
 Inverse variance. More...
 
lsst::afw::math::Kernel::Ptr _kernel
 Derived single-object convolution kernel. More...
 
double _background
 Derived differential background estimate. More...
 
double _kSum
 Derived kernel sum. More...
 
- Protected Attributes inherited from lsst::ip::diffim::KernelSolution
int _id
 Unique ID for object. More...
 
boost::shared_ptr
< Eigen::MatrixXd > 
_mMat
 Derived least squares M matrix. More...
 
boost::shared_ptr
< Eigen::VectorXd > 
_bVec
 Derived least squares B vector. More...
 
boost::shared_ptr
< 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 inherited from lsst::ip::diffim::KernelSolution
static int _SolutionId = 0
 Unique identifier for solution. More...
 

Detailed Description

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

Definition at line 118 of file KernelSolution.h.

Member Typedef Documentation

template<typename InputT >
typedef boost::shared_ptr<MaskedKernelSolution<InputT> > lsst::ip::diffim::MaskedKernelSolution< InputT >::Ptr

Definition at line 120 of file KernelSolution.h.

Constructor & Destructor Documentation

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

Definition at line 503 of file KernelSolution.cc.

506  :
507  StaticKernelSolution<InputT>(basisList, fitForBackground)
508  {};
template<typename InputT >
virtual lsst::ip::diffim::MaskedKernelSolution< InputT >::~MaskedKernelSolution ( )
inlinevirtual

Definition at line 124 of file KernelSolution.h.

124 {};

Member Function Documentation

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

697  {
698 
699  afwMath::Statistics varStats = afwMath::makeStatistics(varianceEstimate, afwMath::MIN);
700  if (varStats.getValue(afwMath::MIN) < 0.0) {
702  "Error: variance less than 0.0");
703  }
704  if (varStats.getValue(afwMath::MIN) == 0.0) {
706  "Error: variance equals 0.0, cannot inverse variance weight");
707  }
708 
709  lsst::afw::math::KernelList basisList =
710  boost::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(this->_kernel)->getKernelList();
711  std::vector<boost::shared_ptr<afwMath::Kernel> >::const_iterator kiter = basisList.begin();
712 
713  /* Only BAD pixels marked in this mask */
715  afwImage::MaskPixel bitMask =
719  sMask &= bitMask;
720  /* TBD: Need to figure out a way to spread this; currently done in Python */
721 
722  unsigned int const nKernelParameters = basisList.size();
723  unsigned int const nBackgroundParameters = this->_fitForBackground ? 1 : 0;
724  unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
725 
726  /* NOTE - we are accessing particular elements of Eigen arrays using
727  these coordinates, therefore they need to be in LOCAL coordinates.
728  This was written before ndarray unification.
729  */
730  /* Ignore known EDGE pixels for speed */
731  afwGeom::Box2I shrunkLocalBBox = (*kiter)->shrinkBBox(templateImage.getBBox(afwImage::LOCAL));
732  pexLog::TTrace<5>("lsst.ip.diffim.MaskedKernelSolution.build",
733  "Limits of good pixels after convolution: %d,%d -> %d,%d (local)",
734  shrunkLocalBBox.getMinX(), shrunkLocalBBox.getMinY(),
735  shrunkLocalBBox.getMaxX(), shrunkLocalBBox.getMaxY());
736 
737  /* Subimages are addressed in raw pixel coordinates */
738  unsigned int startCol = shrunkLocalBBox.getMinX();
739  unsigned int startRow = shrunkLocalBBox.getMinY();
740  unsigned int endCol = shrunkLocalBBox.getMaxX();
741  unsigned int endRow = shrunkLocalBBox.getMaxY();
742  /* Needed for Eigen block slicing operation */
743  endCol += 1;
744  endRow += 1;
745 
746  boost::timer t;
747  t.restart();
748 
749  /* Eigen representation of input images; only the pixels that are unconvolved in cimage below */
750  Eigen::MatrixXi eMask = maskToEigenMatrix(sMask).block(startRow,
751  startCol,
752  endRow-startRow,
753  endCol-startCol);
754 
755  Eigen::MatrixXd eigenTemplate = imageToEigenMatrix(templateImage).block(startRow,
756  startCol,
757  endRow-startRow,
758  endCol-startCol);
759  Eigen::MatrixXd eigenScience = imageToEigenMatrix(scienceImage).block(startRow,
760  startCol,
761  endRow-startRow,
762  endCol-startCol);
763  Eigen::MatrixXd eigeniVariance = imageToEigenMatrix(varianceEstimate).block(
764  startRow, startCol, endRow-startRow, endCol-startCol
765  ).array().inverse().matrix();
766 
767  /* Resize into 1-D for later usage */
768  eMask.resize(eMask.rows()*eMask.cols(), 1);
769  eigenTemplate.resize(eigenTemplate.rows()*eigenTemplate.cols(), 1);
770  eigenScience.resize(eigenScience.rows()*eigenScience.cols(), 1);
771  eigeniVariance.resize(eigeniVariance.rows()*eigeniVariance.cols(), 1);
772 
773  /* Do the masking, slowly for now... */
774  Eigen::MatrixXd maskedEigenTemplate(eigenTemplate.rows(), 1);
775  Eigen::MatrixXd maskedEigenScience(eigenScience.rows(), 1);
776  Eigen::MatrixXd maskedEigeniVariance(eigeniVariance.rows(), 1);
777  int nGood = 0;
778  for (int i = 0; i < eMask.rows(); i++) {
779  if (eMask(i, 0) == 0) {
780  maskedEigenTemplate(nGood, 0) = eigenTemplate(i, 0);
781  maskedEigenScience(nGood, 0) = eigenScience(i, 0);
782  maskedEigeniVariance(nGood, 0) = eigeniVariance(i, 0);
783  nGood += 1;
784  }
785  }
786  /* Can't resize() since all values are lost; use blocks */
787  eigenTemplate = maskedEigenTemplate.block(0, 0, nGood, 1);
788  eigenScience = maskedEigenScience.block(0, 0, nGood, 1);
789  eigeniVariance = maskedEigeniVariance.block(0, 0, nGood, 1);
790 
791 
792  /* Holds image convolved with basis function */
793  afwImage::Image<InputT> cimage(templateImage.getDimensions());
794 
795  /* Holds eigen representation of image convolved with all basis functions */
796  std::vector<boost::shared_ptr<Eigen::MatrixXd> > convolvedEigenList(nKernelParameters);
797 
798  /* Iterators over convolved image list and basis list */
799  typename std::vector<boost::shared_ptr<Eigen::MatrixXd> >::iterator eiter =
800  convolvedEigenList.begin();
801  /* Create C_i in the formalism of Alard & Lupton */
802  for (kiter = basisList.begin(); kiter != basisList.end(); ++kiter, ++eiter) {
803  afwMath::convolve(cimage, templateImage, **kiter, false); /* cimage stores convolved image */
804 
805  Eigen::MatrixXd cMat = imageToEigenMatrix(cimage).block(startRow,
806  startCol,
807  endRow-startRow,
808  endCol-startCol);
809  cMat.resize(cMat.rows() * cMat.cols(), 1);
810 
811  /* Do masking */
812  Eigen::MatrixXd maskedcMat(cMat.rows(), 1);
813  int nGood = 0;
814  for (int i = 0; i < eMask.rows(); i++) {
815  if (eMask(i, 0) == 0) {
816  maskedcMat(nGood, 0) = cMat(i, 0);
817  nGood += 1;
818  }
819  }
820  cMat = maskedcMat.block(0, 0, nGood, 1);
821  boost::shared_ptr<Eigen::MatrixXd> cMatPtr (new Eigen::MatrixXd(cMat));
822  *eiter = cMatPtr;
823  }
824 
825  double time = t.elapsed();
826  pexLog::TTrace<5>("lsst.ip.diffim.StaticKernelSolution.build",
827  "Total compute time to do basis convolutions : %.2f s", time);
828  t.restart();
829 
830  /*
831  Load matrix with all values from convolvedEigenList : all images
832  (eigeniVariance, convolvedEigenList) must be the same size
833  */
834  Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
835  typename std::vector<boost::shared_ptr<Eigen::MatrixXd> >::iterator eiterj =
836  convolvedEigenList.begin();
837  typename std::vector<boost::shared_ptr<Eigen::MatrixXd> >::iterator eiterE =
838  convolvedEigenList.end();
839  for (unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
840  cMat.col(kidxj) = (*eiterj)->col(0);
841  }
842  /* Treat the last "image" as all 1's to do the background calculation. */
843  if (this->_fitForBackground)
844  cMat.col(nParameters-1).fill(1.);
845 
846  this->_cMat.reset(new Eigen::MatrixXd(cMat));
847  this->_ivVec.reset(new Eigen::VectorXd(eigeniVariance.col(0)));
848  this->_iVec.reset(new Eigen::VectorXd(eigenScience.col(0)));
849 
850  /* Make these outside of solve() so I can check condition number */
851  this->_mMat.reset(
852  new Eigen::MatrixXd(this->_cMat->transpose() * this->_ivVec->asDiagonal() * *(this->_cMat))
853  );
854  this->_bVec.reset(
855  new Eigen::VectorXd(this->_cMat->transpose() * this->_ivVec->asDiagonal() * *(this->_iVec))
856  );
857 
858  }
int getMaxY() const
Definition: Box.h:129
Eigen::MatrixXi maskToEigenMatrix(lsst::afw::image::Mask< lsst::afw::image::MaskPixel > const &mask)
estimate sample minimum
Definition: Statistics.h:76
boost::uint16_t MaskPixel
lsst::afw::math::Kernel::Ptr _kernel
Derived single-object convolution kernel.
geom::Box2I getBBox(ImageOrigin origin=PARENT) const
Definition: Image.h:377
An integer coordinate rectangle.
Definition: Box.h:53
double getValue(Property const prop=NOTHING) const
Return the value of the desired property (if specified in the constructor)
Definition: Statistics.cc:950
bool _fitForBackground
Background terms included in fit.
geom::Extent2I getDimensions() const
Return the image&#39;s size; useful for passing to constructors.
Definition: Image.h:298
int getMinY() const
Definition: Box.h:125
boost::shared_ptr< Eigen::VectorXd > _iVec
Vectorized I.
A kernel that is a linear combination of fixed basis kernels.
Definition: Kernel.h:814
int getMinX() const
Definition: Box.h:124
boost::shared_ptr< Eigen::VectorXd > _bVec
Derived least squares B vector.
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:859
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
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...
boost::shared_ptr< Eigen::MatrixXd > _mMat
Derived least squares M matrix.
Statistics makeStatistics(afwImage::Mask< afwImage::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl)
Specialization to handle Masks.
Definition: Statistics.cc:1023
boost::shared_ptr< Eigen::MatrixXd > _cMat
K_i x R.
int getMaxX() const
Definition: Box.h:128
boost::shared_ptr< Eigen::VectorXd > _ivVec
Inverse variance.
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:415
Eigen::MatrixXd imageToEigenMatrix(lsst::afw::image::Image< PixelT > const &img)
Turns Image into a 2-D Eigen Matrix.
std::vector< boost::shared_ptr< Kernel > > KernelList
Definition: Kernel.h:542
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 863 of file KernelSolution.cc.

868  {
869 
870  afwMath::Statistics varStats = afwMath::makeStatistics(varianceEstimate, afwMath::MIN);
871  if (varStats.getValue(afwMath::MIN) < 0.0) {
873  "Error: variance less than 0.0");
874  }
875  if (varStats.getValue(afwMath::MIN) == 0.0) {
877  "Error: variance equals 0.0, cannot inverse variance weight");
878  }
879 
880  lsst::afw::math::KernelList basisList =
881  boost::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(this->_kernel)->getKernelList();
882 
883  unsigned int const nKernelParameters = basisList.size();
884  unsigned int const nBackgroundParameters = this->_fitForBackground ? 1 : 0;
885  unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
886 
887  std::vector<boost::shared_ptr<afwMath::Kernel> >::const_iterator kiter = basisList.begin();
888 
889  /*
890  NOTE : If we are using these views in Afw's Image space, we need to
891  make sure and compensate for the XY0 of the image:
892 
893  afwGeom::Box2I fullBBox = templateImage.getBBox();
894  int maskStartCol = maskBox.getMinX();
895  int maskStartRow = maskBox.getMinY();
896  int maskEndCol = maskBox.getMaxX();
897  int maskEndRow = maskBox.getMaxY();
898 
899 
900  If we are going to be doing the slicing in Eigen matrices derived from
901  the images, ignore the XY0.
902 
903  afwGeom::Box2I fullBBox = templateImage.getBBox(afwImage::LOCAL);
904 
905  int maskStartCol = maskBox.getMinX() - templateImage.getX0();
906  int maskStartRow = maskBox.getMinY() - templateImage.getY0();
907  int maskEndCol = maskBox.getMaxX() - templateImage.getX0();
908  int maskEndRow = maskBox.getMaxY() - templateImage.getY0();
909 
910  */
911 
912 
913  afwGeom::Box2I shrunkBBox = (*kiter)->shrinkBBox(templateImage.getBBox());
914 
915  pexLog::TTrace<5>("lsst.ip.diffim.MaskedKernelSolution.build",
916  "Limits of good pixels after convolution: %d,%d -> %d,%d",
917  shrunkBBox.getMinX(), shrunkBBox.getMinY(),
918  shrunkBBox.getMaxX(), shrunkBBox.getMaxY());
919 
920  unsigned int const startCol = shrunkBBox.getMinX();
921  unsigned int const startRow = shrunkBBox.getMinY();
922  unsigned int const endCol = shrunkBBox.getMaxX();
923  unsigned int const endRow = shrunkBBox.getMaxY();
924 
925  /* NOTE: no endCol/endRow += 1 for block slicing, since we are doing the
926  slicing using Afw, not Eigen
927 
928  Eigen arrays have index 0,0 in the upper right, while LSST images
929  have 0,0 in the lower left. The y-axis is flipped. When translating
930  Images to Eigen matrices in ipDiffim::imageToEigenMatrix this is
931  accounted for. However, we still need to be aware of this fact if
932  addressing subregions of an Eigen matrix. This is why the slicing is
933  done in Afw, its cleaner.
934 
935  Please see examples/maskedKernel.cc for elaboration on some of the
936  tests done to make sure this indexing gets done right.
937 
938  */
939 
940 
941  /* Inner limits; of mask box */
942  int maskStartCol = maskBox.getMinX();
943  int maskStartRow = maskBox.getMinY();
944  int maskEndCol = maskBox.getMaxX();
945  int maskEndRow = maskBox.getMaxY();
946 
947  /*
948 
949  |---------------------------|
950  | Kernel Boundary |
951  | |---------------------| |
952  | | Top | |
953  | |......_________......| |
954  | | | | | |
955  | | L | Box | R | |
956  | | | | | |
957  | |......---------......| |
958  | | Bottom | |
959  | |---------------------| |
960  | |
961  |---------------------------|
962 
963  4 regions we want to extract from the pixels: top bottom left right
964 
965  */
966  afwGeom::Box2I tBox = afwGeom::Box2I(afwGeom::Point2I(startCol, maskEndRow + 1),
967  afwGeom::Point2I(endCol, endRow));
968 
969  afwGeom::Box2I bBox = afwGeom::Box2I(afwGeom::Point2I(startCol, startRow),
970  afwGeom::Point2I(endCol, maskStartRow - 1));
971 
972  afwGeom::Box2I lBox = afwGeom::Box2I(afwGeom::Point2I(startCol, maskStartRow),
973  afwGeom::Point2I(maskStartCol - 1, maskEndRow));
974 
975  afwGeom::Box2I rBox = afwGeom::Box2I(afwGeom::Point2I(maskEndCol + 1, maskStartRow),
976  afwGeom::Point2I(endCol, maskEndRow));
977 
978  pexLog::TTrace<5>("lsst.ip.diffim.MaskedKernelSolution.build",
979  "Upper good pixel region: %d,%d -> %d,%d",
980  tBox.getMinX(), tBox.getMinY(), tBox.getMaxX(), tBox.getMaxY());
981  pexLog::TTrace<5>("lsst.ip.diffim.MaskedKernelSolution.build",
982  "Bottom good pixel region: %d,%d -> %d,%d",
983  bBox.getMinX(), bBox.getMinY(), bBox.getMaxX(), bBox.getMaxY());
984  pexLog::TTrace<5>("lsst.ip.diffim.MaskedKernelSolution.build",
985  "Left good pixel region: %d,%d -> %d,%d",
986  lBox.getMinX(), lBox.getMinY(), lBox.getMaxX(), lBox.getMaxY());
987  pexLog::TTrace<5>("lsst.ip.diffim.MaskedKernelSolution.build",
988  "Right good pixel region: %d,%d -> %d,%d",
989  rBox.getMinX(), rBox.getMinY(), rBox.getMaxX(), rBox.getMaxY());
990 
991  std::vector<afwGeom::Box2I> boxArray;
992  boxArray.push_back(tBox);
993  boxArray.push_back(bBox);
994  boxArray.push_back(lBox);
995  boxArray.push_back(rBox);
996 
997  int totalSize = tBox.getWidth() * tBox.getHeight();
998  totalSize += bBox.getWidth() * bBox.getHeight();
999  totalSize += lBox.getWidth() * lBox.getHeight();
1000  totalSize += rBox.getWidth() * rBox.getHeight();
1001 
1002  Eigen::MatrixXd eigenTemplate(totalSize, 1);
1003  Eigen::MatrixXd eigenScience(totalSize, 1);
1004  Eigen::MatrixXd eigeniVariance(totalSize, 1);
1005  eigenTemplate.setZero();
1006  eigenScience.setZero();
1007  eigeniVariance.setZero();
1008 
1009  boost::timer t;
1010  t.restart();
1011 
1012  int nTerms = 0;
1013  typename std::vector<afwGeom::Box2I>::iterator biter = boxArray.begin();
1014  for (; biter != boxArray.end(); ++biter) {
1015  int area = (*biter).getWidth() * (*biter).getHeight();
1016 
1017  afwImage::Image<InputT> siTemplate(templateImage, *biter);
1018  afwImage::Image<InputT> siScience(scienceImage, *biter);
1019  afwImage::Image<InputT> sVarEstimate(varianceEstimate, *biter);
1020 
1021  Eigen::MatrixXd eTemplate = imageToEigenMatrix(siTemplate);
1022  Eigen::MatrixXd eScience = imageToEigenMatrix(siScience);
1023  Eigen::MatrixXd eiVarEstimate = imageToEigenMatrix(sVarEstimate).array().inverse().matrix();
1024 
1025  eTemplate.resize(area, 1);
1026  eScience.resize(area, 1);
1027  eiVarEstimate.resize(area, 1);
1028 
1029  eigenTemplate.block(nTerms, 0, area, 1) = eTemplate.block(0, 0, area, 1);
1030  eigenScience.block(nTerms, 0, area, 1) = eScience.block(0, 0, area, 1);
1031  eigeniVariance.block(nTerms, 0, area, 1) = eiVarEstimate.block(0, 0, area, 1);
1032 
1033  nTerms += area;
1034  }
1035 
1036  afwImage::Image<InputT> cimage(templateImage.getDimensions());
1037 
1038  std::vector<boost::shared_ptr<Eigen::MatrixXd> > convolvedEigenList(nKernelParameters);
1039  typename std::vector<boost::shared_ptr<Eigen::MatrixXd> >::iterator eiter =
1040  convolvedEigenList.begin();
1041  /* Create C_i in the formalism of Alard & Lupton */
1042  for (kiter = basisList.begin(); kiter != basisList.end(); ++kiter, ++eiter) {
1043  afwMath::convolve(cimage, templateImage, **kiter, false); /* cimage stores convolved image */
1044  Eigen::MatrixXd cMat(totalSize, 1);
1045  cMat.setZero();
1046 
1047  int nTerms = 0;
1048  typename std::vector<afwGeom::Box2I>::iterator biter = boxArray.begin();
1049  for (; biter != boxArray.end(); ++biter) {
1050  int area = (*biter).getWidth() * (*biter).getHeight();
1051 
1052  afwImage::Image<InputT> csubimage(cimage, *biter);
1053  Eigen::MatrixXd esubimage = imageToEigenMatrix(csubimage);
1054  esubimage.resize(area, 1);
1055  cMat.block(nTerms, 0, area, 1) = esubimage.block(0, 0, area, 1);
1056 
1057  nTerms += area;
1058  }
1059 
1060  boost::shared_ptr<Eigen::MatrixXd> cMatPtr (new Eigen::MatrixXd(cMat));
1061  *eiter = cMatPtr;
1062 
1063  }
1064 
1065  double time = t.elapsed();
1066  pexLog::TTrace<5>("lsst.ip.diffim.MaskedKernelSolution.build",
1067  "Total compute time to do basis convolutions : %.2f s", time);
1068  t.restart();
1069 
1070  /*
1071  Load matrix with all values from convolvedEigenList : all images
1072  (eigeniVariance, convolvedEigenList) must be the same size
1073  */
1074  Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
1075  typename std::vector<boost::shared_ptr<Eigen::MatrixXd> >::iterator eiterj =
1076  convolvedEigenList.begin();
1077  typename std::vector<boost::shared_ptr<Eigen::MatrixXd> >::iterator eiterE =
1078  convolvedEigenList.end();
1079  for (unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
1080  cMat.col(kidxj) = (*eiterj)->col(0);
1081  }
1082  /* Treat the last "image" as all 1's to do the background calculation. */
1083  if (this->_fitForBackground)
1084  cMat.col(nParameters-1).fill(1.);
1085 
1086  this->_cMat.reset(new Eigen::MatrixXd(cMat));
1087  this->_ivVec.reset(new Eigen::VectorXd(eigeniVariance.col(0)));
1088  this->_iVec.reset(new Eigen::VectorXd(eigenScience.col(0)));
1089 
1090  /* Make these outside of solve() so I can check condition number */
1091  this->_mMat.reset(
1092  new Eigen::MatrixXd(this->_cMat->transpose() * this->_ivVec->asDiagonal() * *(this->_cMat))
1093  );
1094  this->_bVec.reset(
1095  new Eigen::VectorXd(this->_cMat->transpose() * this->_ivVec->asDiagonal() * *(this->_iVec))
1096  );
1097 
1098  }
int getMaxY() const
Definition: Box.h:129
estimate sample minimum
Definition: Statistics.h:76
lsst::afw::math::Kernel::Ptr _kernel
Derived single-object convolution kernel.
geom::Box2I getBBox(ImageOrigin origin=PARENT) const
Definition: Image.h:377
An integer coordinate rectangle.
Definition: Box.h:53
double getValue(Property const prop=NOTHING) const
Return the value of the desired property (if specified in the constructor)
Definition: Statistics.cc:950
bool _fitForBackground
Background terms included in fit.
geom::Extent2I getDimensions() const
Return the image&#39;s size; useful for passing to constructors.
Definition: Image.h:298
int getMinY() const
Definition: Box.h:125
boost::shared_ptr< Eigen::VectorXd > _iVec
Vectorized I.
A kernel that is a linear combination of fixed basis kernels.
Definition: Kernel.h:814
int getMinX() const
Definition: Box.h:124
boost::shared_ptr< Eigen::VectorXd > _bVec
Derived least squares B vector.
int getWidth() const
Definition: Box.h:154
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
int getHeight() const
Definition: Box.h:155
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...
boost::shared_ptr< Eigen::MatrixXd > _mMat
Derived least squares M matrix.
Statistics makeStatistics(afwImage::Mask< afwImage::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl)
Specialization to handle Masks.
Definition: Statistics.cc:1023
boost::shared_ptr< Eigen::MatrixXd > _cMat
K_i x R.
int getMaxX() const
Definition: Box.h:128
boost::shared_ptr< Eigen::VectorXd > _ivVec
Inverse variance.
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:415
Eigen::MatrixXd imageToEigenMatrix(lsst::afw::image::Image< PixelT > const &img)
Turns Image into a 2-D Eigen Matrix.
std::vector< boost::shared_ptr< Kernel > > KernelList
Definition: Kernel.h:542
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 511 of file KernelSolution.cc.

516  {
517 
518  afwMath::Statistics varStats = afwMath::makeStatistics(varianceEstimate, afwMath::MIN);
519  if (varStats.getValue(afwMath::MIN) < 0.0) {
521  "Error: variance less than 0.0");
522  }
523  if (varStats.getValue(afwMath::MIN) == 0.0) {
525  "Error: variance equals 0.0, cannot inverse variance weight");
526  }
527 
528  /* Full footprint of all input images */
529  afwDet::Footprint::Ptr fullFp(new afwDet::Footprint(templateImage.getBBox()));
530 
531  afwMath::KernelList basisList =
532  boost::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(this->_kernel)->getKernelList();
533  std::vector<boost::shared_ptr<afwMath::Kernel> >::const_iterator kiter = basisList.begin();
534 
535  /* Only BAD pixels marked in this mask */
536  afwImage::MaskPixel bitMask =
540 
541  /* Create a Footprint that contains all the masked pixels set above */
543  afwDet::FootprintSet maskFpSet(pixelMask, threshold, true);
544 
545  /* And spread it by the kernel half width */
546  int growPix = (*kiter)->getCtr().getX();
547  afwDet::FootprintSet maskedFpSetGrown(maskFpSet, growPix, true);
548 
549 #if 0
550  for (typename afwDet::FootprintSet::FootprintList::iterator
551  ptr = maskedFpSetGrown.getFootprints()->begin(),
552  end = maskedFpSetGrown.getFootprints()->end();
553  ptr != end;
554  ++ptr) {
555 
556  afwDet::setMaskFromFootprint(finalMask,
557  (**ptr),
559  }
560 #endif
561 
562  afwImage::Mask<afwImage::MaskPixel> finalMask(pixelMask.getDimensions());
564  *(maskedFpSetGrown.getFootprints()),
566  pixelMask.writeFits("pixelmask.fits");
567  finalMask.writeFits("finalmask.fits");
568 
569 
570  ndarray::Array<int, 1, 1> maskArray =
571  ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
572  afwDet::flattenArray(*fullFp, finalMask.getArray(),
573  maskArray, templateImage.getXY0()); /* Need to fake the XY0 */
574  ndarray::EigenView<int, 1, 1> maskEigen(maskArray);
575 
576  ndarray::Array<InputT, 1, 1> arrayTemplate =
577  ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
578  afwDet::flattenArray(*fullFp, templateImage.getArray(),
579  arrayTemplate, templateImage.getXY0());
580  ndarray::EigenView<InputT, 1, 1> eigenTemplate0(arrayTemplate);
581 
582  ndarray::Array<InputT, 1, 1> arrayScience =
583  ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
584  afwDet::flattenArray(*fullFp, scienceImage.getArray(),
585  arrayScience, scienceImage.getXY0());
586  ndarray::EigenView<InputT, 1, 1> eigenScience0(arrayScience);
587 
589  ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
590  afwDet::flattenArray(*fullFp, varianceEstimate.getArray(),
591  arrayVariance, varianceEstimate.getXY0());
592  ndarray::EigenView<afwImage::VariancePixel, 1, 1> eigenVariance0(arrayVariance);
593 
594  int nGood = 0;
595  for (int i = 0; i < maskEigen.size(); i++) {
596  if (maskEigen(i) == 0.0)
597  nGood += 1;
598  }
599 
600  Eigen::VectorXd eigenTemplate(nGood);
601  Eigen::VectorXd eigenScience(nGood);
602  Eigen::VectorXd eigenVariance(nGood);
603  int nUsed = 0;
604  for (int i = 0; i < maskEigen.size(); i++) {
605  if (maskEigen(i) == 0.0) {
606  eigenTemplate(nUsed) = eigenTemplate0(i);
607  eigenScience(nUsed) = eigenScience0(i);
608  eigenVariance(nUsed) = eigenVariance0(i);
609  nUsed += 1;
610  }
611  }
612 
613 
614  boost::timer t;
615  t.restart();
616 
617  unsigned int const nKernelParameters = basisList.size();
618  unsigned int const nBackgroundParameters = this->_fitForBackground ? 1 : 0;
619  unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
620 
621  /* Holds image convolved with basis function */
622  afwImage::Image<InputT> cimage(templateImage.getDimensions());
623 
624  /* Holds eigen representation of image convolved with all basis functions */
625  std::vector<boost::shared_ptr<Eigen::VectorXd> >
626  convolvedEigenList(nKernelParameters);
627 
628  /* Iterators over convolved image list and basis list */
629  typename std::vector<boost::shared_ptr<Eigen::VectorXd> >::iterator eiter =
630  convolvedEigenList.begin();
631 
632  /* Create C_i in the formalism of Alard & Lupton */
633  for (kiter = basisList.begin(); kiter != basisList.end(); ++kiter, ++eiter) {
634  afwMath::convolve(cimage, templateImage, **kiter, false); /* cimage stores convolved image */
635 
637  ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
638  afwDet::flattenArray(*fullFp, cimage.getArray(),
639  arrayC, cimage.getXY0());
640  ndarray::EigenView<InputT, 1, 1> eigenC0(arrayC);
641 
642  Eigen::VectorXd eigenC(nGood);
643  int nUsed = 0;
644  for (int i = 0; i < maskEigen.size(); i++) {
645  if (maskEigen(i) == 0.0) {
646  eigenC(nUsed) = eigenC0(i);
647  nUsed += 1;
648  }
649  }
650 
651  boost::shared_ptr<Eigen::VectorXd>
652  eigenCptr (new Eigen::VectorXd(eigenC));
653 
654  *eiter = eigenCptr;
655  }
656  double time = t.elapsed();
657  pexLog::TTrace<5>("lsst.ip.diffim.StaticKernelSolution.buildWithMask",
658  "Total compute time to do basis convolutions : %.2f s", time);
659  t.restart();
660 
661  /* Load matrix with all convolved images */
662  Eigen::MatrixXd cMat(eigenTemplate.size(), nParameters);
663  typename std::vector<boost::shared_ptr<Eigen::VectorXd> >::iterator eiterj =
664  convolvedEigenList.begin();
665  typename std::vector<boost::shared_ptr<Eigen::VectorXd> >::iterator eiterE =
666  convolvedEigenList.end();
667  for (unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
668  cMat.block(0, kidxj, eigenTemplate.size(), 1) =
669  Eigen::MatrixXd(**eiterj).block(0, 0, eigenTemplate.size(), 1);
670  }
671  /* Treat the last "image" as all 1's to do the background calculation. */
672  if (this->_fitForBackground)
673  cMat.col(nParameters-1).fill(1.);
674 
675  this->_cMat.reset(new Eigen::MatrixXd(cMat));
676  //this->_ivVec.reset(new Eigen::VectorXd((eigenVariance.template cast<double>()).cwise().inverse()));
677  //this->_iVec.reset(new Eigen::VectorXd(eigenScience.template cast<double>()));
678  this->_ivVec.reset(new Eigen::VectorXd(eigenVariance.array().inverse().matrix()));
679  this->_iVec.reset(new Eigen::VectorXd(eigenScience));
680 
681  /* Make these outside of solve() so I can check condition number */
682  this->_mMat.reset(
683  new Eigen::MatrixXd(this->_cMat->transpose() * this->_ivVec->asDiagonal() * *(this->_cMat))
684  );
685  this->_bVec.reset(
686  new Eigen::VectorXd(this->_cMat->transpose() * this->_ivVec->asDiagonal() * *(this->_iVec))
687  );
688  }
void flattenArray(Footprint const &fp, ndarray::Array< T, N, C > const &src, ndarray::Array< U, N-1, D > const &dest, lsst::afw::geom::Point2I const &xy0=lsst::afw::geom::Point2I())
Flatten the first two dimensions of an array.
boost::shared_ptr< Footprint > Ptr
Definition: Footprint.h:78
void writeFits(std::string const &fileName, boost::shared_ptr< lsst::daf::base::PropertySet const > metadata=boost::shared_ptr< lsst::daf::base::PropertySet >(), std::string const &mode="w") const
Write a mask to a regular FITS file.
estimate sample minimum
Definition: Statistics.h:76
Eigen3 view into an ndarray::Array.
Definition: eigen.h:232
boost::uint16_t MaskPixel
lsst::afw::math::Kernel::Ptr _kernel
Derived single-object convolution kernel.
Use (pixels &amp; (given mask))
Definition: Threshold.h:49
A Threshold is used to pass a threshold value to detection algorithms.
Definition: Threshold.h:44
geom::Box2I getBBox(ImageOrigin origin=PARENT) const
Definition: Image.h:377
double getValue(Property const prop=NOTHING) const
Return the value of the desired property (if specified in the constructor)
Definition: Statistics.cc:950
geom::Point2I getXY0() const
Definition: Image.h:264
bool _fitForBackground
Background terms included in fit.
geom::Extent2I getDimensions() const
Return the image&#39;s size; useful for passing to constructors.
Definition: Image.h:298
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:93
boost::shared_ptr< Eigen::VectorXd > _iVec
Vectorized I.
A kernel that is a linear combination of fixed basis kernels.
Definition: Kernel.h:814
Vector< T, N > makeVector(T v1, T v2,..., T vN)
Variadic constructor for Vector.
boost::shared_ptr< Eigen::VectorXd > _bVec
Derived least squares B vector.
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:859
A set of pixels in an Image.
Definition: Footprint.h:73
detail::SimpleInitializer< N > allocate(Vector< int, N > const &shape)
Create an expression that allocates uninitialized memory for an array.
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
A set of Footprints, associated with a MaskedImage.
Definition: FootprintSet.h:53
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...
boost::shared_ptr< Eigen::MatrixXd > _mMat
Derived least squares M matrix.
MaskT setMaskFromFootprint(lsst::afw::image::Mask< MaskT > *mask, Footprint const &footprint, MaskT const bitmask)
OR bitmask into all the Mask&#39;s pixels that are in the Footprint.
Statistics makeStatistics(afwImage::Mask< afwImage::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl)
Specialization to handle Masks.
Definition: Statistics.cc:1023
boost::shared_ptr< Eigen::MatrixXd > _cMat
K_i x R.
boost::shared_ptr< Eigen::VectorXd > _ivVec
Inverse variance.
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:415
MaskT setMaskFromFootprintList(lsst::afw::image::Mask< MaskT > *mask, std::vector< boost::shared_ptr< Footprint >> const &footprints, MaskT const bitmask)
OR bitmask into all the Mask&#39;s pixels which are in the set of Footprints.
std::vector< boost::shared_ptr< Kernel > > KernelList
Definition: Kernel.h:542

The documentation for this class was generated from the following files: