17 #include "boost/timer.hpp" 
   20 #include "Eigen/Cholesky" 
   23 #include "Eigen/Eigenvalues" 
   38 #include "ndarray/eigen.h" 
   40 #define DEBUG_MATRIX  0 
   41 #define DEBUG_MATRIX2 0 
   67         _fitForBackground(fitForBackground)
 
   78         _fitForBackground(fitForBackground)
 
   87         _fitForBackground(true)
 
  100         switch (conditionType) {
 
  103             Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eVecValues(mMat);
 
  104             Eigen::VectorXd eValues = eVecValues.eigenvalues();
 
  105             double eMax = eValues.maxCoeff();
 
  106             double eMin = eValues.minCoeff();
 
  107             LOGL_DEBUG(
"TRACE3.ip.diffim.KernelSolution.getConditionNumber",
 
  108                        "EIGENVALUE eMax / eMin = %.3e", eMax / eMin);
 
  109             return (eMax / eMin);
 
  114             Eigen::VectorXd sValues = mMat.jacobiSvd().singularValues();
 
  115             double sMax = sValues.maxCoeff();
 
  116             double sMin = sValues.minCoeff();
 
  117             LOGL_DEBUG(
"TRACE3.ip.diffim.KernelSolution.getConditionNumber",
 
  118                        "SVD eMax / eMin = %.3e", sMax / sMin);
 
  119             return (sMax / sMin);
 
  125                               "Undefined ConditionNumberType : only EIGENVALUE, SVD allowed.");
 
  132                                Eigen::VectorXd 
const& bVec) {
 
  141         Eigen::VectorXd aVec = Eigen::VectorXd::Zero(bVec.size());
 
  146         LOGL_DEBUG(
"TRACE2.ip.diffim.KernelSolution.solve",
 
  147                    "Solving for kernel");
 
  149                 Eigen::FullPivLU<Eigen::MatrixXd> lu(mMat);
 
  150                 if (lu.isInvertible()) {
 
  151                         aVec = lu.solve(bVec);
 
  153                         LOGL_DEBUG(
"TRACE3.ip.diffim.KernelSolution.solve",
 
  154                                    "Unable to determine kernel via LU");
 
  159                                 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eVecValues(mMat);
 
  160                                 Eigen::MatrixXd 
const& rMat = eVecValues.eigenvectors();
 
  161                                 Eigen::VectorXd eValues = eVecValues.eigenvalues();
 
  163                                 for (
int i = 0; i != eValues.rows(); ++i) {
 
  164                                         if (eValues(i) != 0.0) {
 
  165                                                 eValues(i) = 1.0/eValues(i);
 
  169                                 aVec = rMat * eValues.asDiagonal() * rMat.transpose() * bVec;
 
  173                                 LOGL_DEBUG(
"TRACE3.ip.diffim.KernelSolution.solve",
 
  174                                            "Unable to determine kernel via eigen-values");
 
  180         double time = t.elapsed();
 
  181         LOGL_DEBUG(
"TRACE3.ip.diffim.KernelSolution.solve",
 
  182                    "Compute time for matrix math : %.2f s", time);
 
  194     template <
typename InputT>
 
  197         bool fitForBackground
 
  214     template <
typename InputT>
 
  222     template <
typename InputT>
 
  230         (void)_kernel->computeImage(*
image, 
false);
 
  234     template <
typename InputT>
 
  242     template <
typename InputT>
 
  250     template <
typename InputT>
 
  260     template <
typename InputT>
 
  270                               "Error: variance less than 0.0");
 
  274                               "Error: variance equals 0.0, cannot inverse variance weight");
 
  278             std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(_kernel)->getKernelList();
 
  280         unsigned int const nKernelParameters     = basisList.
size();
 
  281         unsigned int const nBackgroundParameters = _fitForBackground ? 1 : 0;
 
  282         unsigned int const nParameters           = nKernelParameters + nBackgroundParameters;
 
  319         unsigned int const startCol = goodBBox.
getMinX();
 
  320         unsigned int const startRow = goodBBox.
getMinY();
 
  322         unsigned int endCol = goodBBox.
getMaxX() + 1;
 
  323         unsigned int endRow = goodBBox.
getMaxY() + 1;
 
  338             startRow, startCol, endRow-startRow, endCol-startCol
 
  339         ).array().inverse().matrix();
 
  342         eigenTemplate.resize(eigenTemplate.rows()*eigenTemplate.cols(), 1);
 
  343         eigenScience.resize(eigenScience.rows()*eigenScience.cols(), 1);
 
  344         eigeniVariance.resize(eigeniVariance.rows()*eigeniVariance.cols(), 1);
 
  357         for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
 
  364             cMat.resize(cMat.size(), 1);
 
  369         double time = t.elapsed();
 
  370         LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.build",
 
  371                    "Total compute time to do basis convolutions : %.2f s", time);
 
  378         Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
 
  381         for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
 
  382             cMat.col(kidxj) = eiterj->col(0);
 
  385         if (_fitForBackground)
 
  386             cMat.col(nParameters-1).fill(1.);
 
  389         _ivVec = eigeniVariance.col(0);
 
  390         _iVec = eigenScience.col(0);
 
  393         _mMat = _cMat.transpose() * (_ivVec.asDiagonal() * _cMat);
 
  394         _bVec = _cMat.transpose() * (_ivVec.asDiagonal() * _iVec);
 
  397     template <
typename InputT>
 
  399         LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.solve",
 
  400                    "mMat is %d x %d; bVec is %d; cMat is %d x %d; vVec is %d; iVec is %d",
 
  401                    _mMat.rows(), _mMat.cols(), _bVec.size(),
 
  402                    _cMat.rows(), _cMat.cols(), _ivVec.size(), _iVec.size());
 
  423     template <
typename InputT>
 
  429         unsigned int const nParameters           = _aVec.size();
 
  430         unsigned int const nBackgroundParameters = _fitForBackground ? 1 : 0;
 
  431         unsigned int const nKernelParameters     =
 
  432             std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(_kernel)->getKernelList().size();
 
  433         if (nParameters != (nKernelParameters + nBackgroundParameters))
 
  438         for (
unsigned int idx = 0; idx < nKernelParameters; idx++) {
 
  441                                   str(
boost::format(
"Unable to determine kernel solution %d (nan)") % idx));
 
  443             kValues[idx] = _aVec(idx);
 
  445         _kernel->setKernelParameters(kValues);
 
  448             new ImageT(_kernel->getDimensions())
 
  450         _kSum  = _kernel->computeImage(*
image, 
false);
 
  452         if (_fitForBackground) {
 
  455                                   str(
boost::format(
"Unable to determine background solution %d (nan)") %
 
  458             _background = _aVec(nParameters-1);
 
  463     template <
typename InputT>
 
  493     template <
typename InputT>
 
  496         bool fitForBackground
 
  501     template <
typename InputT>
 
  512                               "Error: variance less than 0.0");
 
  516                               "Error: variance equals 0.0, cannot inverse variance weight");
 
  524             std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(this->_kernel)->getKernelList();
 
  539         int growPix = (*kiter)->getCtr().getX();
 
  543         for (
typename afwDet::FootprintSet::FootprintList::iterator
 
  549             afwDet::setMaskFromFootprint(finalMask,
 
  556         for (
auto const & foot : *(maskedFpSetGrown.
getFootprints())) {
 
  563         ndarray::Array<int, 1, 1> maskArray =
 
  564             ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
 
  565         fullFp->getSpans()->flatten(maskArray, finalMask.
getArray(), templateImage.
getXY0());
 
  566         auto maskEigen = ndarray::asEigenMatrix(maskArray);
 
  568         ndarray::Array<InputT, 1, 1> arrayTemplate =
 
  569             ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
 
  570         fullFp->getSpans()->flatten(arrayTemplate, templateImage.
getArray(), templateImage.
getXY0());
 
  571         auto eigenTemplate0 = ndarray::asEigenMatrix(arrayTemplate);
 
  573         ndarray::Array<InputT, 1, 1> arrayScience =
 
  574             ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
 
  575         fullFp->getSpans()->flatten(arrayScience, scienceImage.
getArray(), scienceImage.
getXY0());
 
  576         auto eigenScience0 = ndarray::asEigenMatrix(arrayScience);
 
  578         ndarray::Array<afwImage::VariancePixel, 1, 1> arrayVariance =
 
  579             ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
 
  580         fullFp->getSpans()->flatten(arrayVariance, varianceEstimate.
getArray(), varianceEstimate.
getXY0());
 
  581         auto eigenVariance0 = ndarray::asEigenMatrix(arrayVariance);
 
  584         for (
int i = 0; i < maskEigen.size(); i++) {
 
  585             if (maskEigen(i) == 0.0)
 
  589         Eigen::VectorXd eigenTemplate(nGood);
 
  590         Eigen::VectorXd eigenScience(nGood);
 
  591         Eigen::VectorXd eigenVariance(nGood);
 
  593         for (
int i = 0; i < maskEigen.size(); i++) {
 
  594             if (maskEigen(i) == 0.0) {
 
  595                 eigenTemplate(nUsed) = eigenTemplate0(i);
 
  596                 eigenScience(nUsed) = eigenScience0(i);
 
  597                 eigenVariance(nUsed) = eigenVariance0(i);
 
  606         unsigned int const nKernelParameters     = basisList.
size();
 
  607         unsigned int const nBackgroundParameters = this->_fitForBackground ? 1 : 0;
 
  608         unsigned int const nParameters           = nKernelParameters + nBackgroundParameters;
 
  622         for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
 
  625             ndarray::Array<InputT, 1, 1> arrayC =
 
  626                 ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
 
  627             fullFp->getSpans()->flatten(arrayC, cimage.
getArray(), cimage.
getXY0());
 
  628             auto eigenC0 = ndarray::asEigenMatrix(arrayC);
 
  630             Eigen::VectorXd eigenC(nGood);
 
  632             for (
int i = 0; i < maskEigen.size(); i++) {
 
  633                 if (maskEigen(i) == 0.0) {
 
  634                     eigenC(nUsed) = eigenC0(i);
 
  641         double time = t.elapsed();
 
  642         LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.buildWithMask",
 
  643                    "Total compute time to do basis convolutions : %.2f s", time);
 
  647         Eigen::MatrixXd cMat(eigenTemplate.size(), nParameters);
 
  650         for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
 
  651             cMat.block(0, kidxj, eigenTemplate.size(), 1) =
 
  652                 Eigen::MatrixXd(*eiterj).block(0, 0, eigenTemplate.size(), 1);
 
  655         if (this->_fitForBackground)
 
  656             cMat.col(nParameters-1).fill(1.);
 
  659         this->_ivVec = eigenVariance.array().inverse().matrix();
 
  660         this->_iVec = eigenScience;
 
  663         this->_mMat = this->_cMat.transpose() * this->_ivVec.asDiagonal() * (this->_cMat);
 
  664         this->_bVec = this->_cMat.transpose() * this->_ivVec.asDiagonal() * (this->_iVec);
 
  668     template <
typename InputT>
 
  679                               "Error: variance less than 0.0");
 
  683                               "Error: variance equals 0.0, cannot inverse variance weight");
 
  687             std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(this->_kernel)->getKernelList();
 
  699         unsigned int const nKernelParameters     = basisList.
size();
 
  700         unsigned int const nBackgroundParameters = this->_fitForBackground ? 1 : 0;
 
  701         unsigned int const nParameters           = nKernelParameters + nBackgroundParameters;
 
  709         LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
 
  710                    "Limits of good pixels after convolution: %d,%d -> %d,%d (local)",
 
  715         unsigned int startCol = shrunkLocalBBox.
getMinX();
 
  716         unsigned int startRow = shrunkLocalBBox.
getMinY();
 
  717         unsigned int endCol   = shrunkLocalBBox.
getMaxX();
 
  718         unsigned int endRow   = shrunkLocalBBox.
getMaxY();
 
  741             startRow, startCol, endRow-startRow, endCol-startCol
 
  742         ).array().inverse().matrix();
 
  745         eMask.resize(eMask.rows()*eMask.cols(), 1);
 
  746         eigenTemplate.resize(eigenTemplate.rows()*eigenTemplate.cols(), 1);
 
  747         eigenScience.resize(eigenScience.rows()*eigenScience.cols(), 1);
 
  748         eigeniVariance.resize(eigeniVariance.rows()*eigeniVariance.cols(), 1);
 
  751         Eigen::MatrixXd maskedEigenTemplate(eigenTemplate.rows(), 1);
 
  752         Eigen::MatrixXd maskedEigenScience(eigenScience.rows(), 1);
 
  753         Eigen::MatrixXd maskedEigeniVariance(eigeniVariance.rows(), 1);
 
  755         for (
int i = 0; i < eMask.rows(); i++) {
 
  756             if (eMask(i, 0) == 0) {
 
  757                 maskedEigenTemplate(nGood, 0) = eigenTemplate(i, 0);
 
  758                 maskedEigenScience(nGood, 0) = eigenScience(i, 0);
 
  759                 maskedEigeniVariance(nGood, 0) = eigeniVariance(i, 0);
 
  764         eigenTemplate    = maskedEigenTemplate.block(0, 0, nGood, 1);
 
  765         eigenScience     = maskedEigenScience.block(0, 0, nGood, 1);
 
  766         eigeniVariance   = maskedEigeniVariance.block(0, 0, nGood, 1);
 
  780        for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
 
  787             cMat.resize(cMat.size(), 1);
 
  790             Eigen::MatrixXd maskedcMat(cMat.rows(), 1);
 
  792             for (
int i = 0; i < eMask.rows(); i++) {
 
  793                 if (eMask(i, 0) == 0) {
 
  794                     maskedcMat(nGood, 0) = cMat(i, 0);
 
  798             cMat = maskedcMat.block(0, 0, nGood, 1);
 
  802         double time = t.elapsed();
 
  803         LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.build",
 
  804                    "Total compute time to do basis convolutions : %.2f s", time);
 
  811         Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
 
  814         for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
 
  815             cMat.col(kidxj) = eiterj->col(0);
 
  818         if (this->_fitForBackground)
 
  819             cMat.col(nParameters-1).fill(1.);
 
  822         this->_ivVec = eigeniVariance.col(0);
 
  823         this->_iVec = eigenScience.col(0);
 
  826         this->_mMat = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_cMat;
 
  827         this->_bVec = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_iVec;
 
  833     template <
typename InputT>
 
  844                               "Error: variance less than 0.0");
 
  848                               "Error: variance equals 0.0, cannot inverse variance weight");
 
  852             std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(this->_kernel)->getKernelList();
 
  854         unsigned int const nKernelParameters     = basisList.
size();
 
  855         unsigned int const nBackgroundParameters = this->_fitForBackground ? 1 : 0;
 
  856         unsigned int const nParameters           = nKernelParameters + nBackgroundParameters;
 
  886         LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
 
  887                    "Limits of good pixels after convolution: %d,%d -> %d,%d",
 
  891         unsigned int const startCol = shrunkBBox.
getMinX();
 
  892         unsigned int const startRow = shrunkBBox.
getMinY();
 
  893         unsigned int const endCol   = shrunkBBox.
getMaxX();
 
  894         unsigned int const endRow   = shrunkBBox.
getMaxY();
 
  913         int maskStartCol = maskBox.
getMinX();
 
  914         int maskStartRow = maskBox.
getMinY();
 
  915         int maskEndCol   = maskBox.
getMaxX();
 
  916         int maskEndRow   = maskBox.
getMaxY();
 
  949         LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
 
  950                    "Upper good pixel region: %d,%d -> %d,%d",
 
  952         LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
 
  953                    "Bottom good pixel region: %d,%d -> %d,%d",
 
  955         LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
 
  956                    "Left good pixel region: %d,%d -> %d,%d",
 
  958         LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
 
  959                    "Right good pixel region: %d,%d -> %d,%d",
 
  973         Eigen::MatrixXd eigenTemplate(totalSize, 1);
 
  974         Eigen::MatrixXd eigenScience(totalSize, 1);
 
  975         Eigen::MatrixXd eigeniVariance(totalSize, 1);
 
  976         eigenTemplate.setZero();
 
  977         eigenScience.setZero();
 
  978         eigeniVariance.setZero();
 
  985         for (; biter != boxArray.
end(); ++biter) {
 
  986             int area = (*biter).getWidth() * (*biter).getHeight();
 
  994             Eigen::MatrixXd eiVarEstimate = 
imageToEigenMatrix(sVarEstimate).array().inverse().matrix();
 
  996             eTemplate.resize(area, 1);
 
  997             eScience.resize(area, 1);
 
  998             eiVarEstimate.resize(area, 1);
 
 1000             eigenTemplate.block(nTerms, 0, area, 1) = eTemplate.block(0, 0, area, 1);
 
 1001             eigenScience.block(nTerms, 0, area, 1) = eScience.block(0, 0, area, 1);
 
 1002             eigeniVariance.block(nTerms, 0, area, 1) = eiVarEstimate.block(0, 0, area, 1);
 
 1014         for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
 
 1016             Eigen::MatrixXd cMat(totalSize, 1);
 
 1021             for (; biter != boxArray.
end(); ++biter) {
 
 1022                 int area = (*biter).getWidth() * (*biter).getHeight();
 
 1026                 esubimage.resize(area, 1);
 
 1027                 cMat.block(nTerms, 0, area, 1) = esubimage.block(0, 0, area, 1);
 
 1036         double time = t.elapsed();
 
 1037         LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
 
 1038                    "Total compute time to do basis convolutions : %.2f s", time);
 
 1045         Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
 
 1048         for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
 
 1049             cMat.col(kidxj) = eiterj->col(0);
 
 1052         if (this->_fitForBackground)
 
 1053             cMat.col(nParameters-1).fill(1.);
 
 1056         this->_ivVec = eigeniVariance.col(0);
 
 1057         this->_iVec = eigenScience.col(0);
 
 1060         this->_mMat = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_cMat;
 
 1061         this->_bVec = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_iVec;
 
 1066     template <
typename InputT>
 
 1069         bool fitForBackground,
 
 1070         Eigen::MatrixXd 
const& hMat,
 
 1079     template <
typename InputT>
 
 1081         Eigen::MatrixXd vMat      = this->_cMat.jacobiSvd().matrixV();
 
 1082         Eigen::MatrixXd vMatvMatT = vMat * vMat.transpose();
 
 1085         Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eVecValues(this->_mMat);
 
 1086         Eigen::MatrixXd 
const& rMat = eVecValues.eigenvectors();
 
 1087         Eigen::VectorXd eValues = eVecValues.eigenvalues();
 
 1088         double eMax = eValues.maxCoeff();
 
 1089         for (
int i = 0; i != eValues.rows(); ++i) {
 
 1090             if (eValues(i) == 0.0) {
 
 1093             else if ((eMax / eValues(i)) > maxCond) {
 
 1094                 LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.estimateRisk",
 
 1095                            "Truncating eValue %d; %.5e / %.5e = %.5e vs. %.5e",
 
 1096                            i, eMax, eValues(i), eMax / eValues(i), maxCond);
 
 1100                 eValues(i) = 1.0 / eValues(i);
 
 1103         Eigen::MatrixXd mInv    = rMat * eValues.asDiagonal() * rMat.transpose();
 
 1107         for (
unsigned int i = 0; i < lambdas.
size(); i++) {
 
 1108             double l = lambdas[i];
 
 1109             Eigen::MatrixXd mLambda = this->_mMat + l * _hMat;
 
 1117             Eigen::VectorXd term1 = (this->_aVec.transpose() * vMatvMatT * this->_aVec);
 
 1118             if (term1.size() != 1)
 
 1121             double term2a = (vMatvMatT * mLambda.inverse()).
trace();
 
 1123             Eigen::VectorXd term2b = (this->_aVec.transpose() * (mInv * this->_bVec));
 
 1124             if (term2b.size() != 1)
 
 1127             double risk   = term1(0) + 2 * (term2a - term2b(0));
 
 1128             LOGL_DEBUG(
"TRACE4.ip.diffim.RegularizedKernelSolution.estimateRisk",
 
 1129                        "Lambda = %.3f, Risk = %.5e",
 
 1131             LOGL_DEBUG(
"TRACE5.ip.diffim.RegularizedKernelSolution.estimateRisk",
 
 1132                        "%.5e + 2 * (%.5e - %.5e)",
 
 1133                        term1(0), term2a, term2b(0));
 
 1138         LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.estimateRisk",
 
 1139                    "Minimum Risk = %.3e at lambda = %.3e", risks[index], lambdas[index]);
 
 1141         return lambdas[index];
 
 1145     template <
typename InputT>
 
 1147         if (includeHmat == 
true) {
 
 1148             return this->_mMat + _lambda * _hMat;
 
 1155     template <
typename InputT>
 
 1158         LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.solve",
 
 1159                    "cMat is %d x %d; vVec is %d; iVec is %d; hMat is %d x %d",
 
 1160                    this->_cMat.rows(), this->_cMat.cols(), this->_ivVec.size(),
 
 1161                    this->_iVec.size(), _hMat.rows(), _hMat.cols());
 
 1176         this->_mMat = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_cMat;
 
 1177         this->_bVec = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_iVec;
 
 1229         std::string lambdaType = _ps->getAsString(
"lambdaType");
 
 1230         if (lambdaType == 
"absolute") {
 
 1231             _lambda = _ps->getAsDouble(
"lambdaValue");
 
 1233         else if (lambdaType ==  
"relative") {
 
 1234             _lambda  = this->_mMat.trace() / this->_hMat.trace();
 
 1235             _lambda *= _ps->getAsDouble(
"lambdaScaling");
 
 1237         else if (lambdaType ==  
"minimizeBiasedRisk") {
 
 1238             double tol = _ps->getAsDouble(
"maxConditionNumber");
 
 1239             _lambda = estimateRisk(tol);
 
 1241         else if (lambdaType ==  
"minimizeUnbiasedRisk") {
 
 1248         LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.solve",
 
 1249                    "Applying kernel regularization with lambda = %.2e", _lambda);
 
 1262     template <
typename InputT>
 
 1266         std::string lambdaStepType = _ps->getAsString(
"lambdaStepType");
 
 1267         if (lambdaStepType == 
"linear") {
 
 1268             double lambdaLinMin   = _ps->getAsDouble(
"lambdaLinMin");
 
 1269             double lambdaLinMax   = _ps->getAsDouble(
"lambdaLinMax");
 
 1270             double lambdaLinStep  = _ps->getAsDouble(
"lambdaLinStep");
 
 1271             for (
double l = lambdaLinMin; l <= lambdaLinMax; l += lambdaLinStep) {
 
 1275         else if (lambdaStepType == 
"log") {
 
 1276             double lambdaLogMin   = _ps->getAsDouble(
"lambdaLogMin");
 
 1277             double lambdaLogMax   = _ps->getAsDouble(
"lambdaLogMax");
 
 1278             double lambdaLogStep  = _ps->getAsDouble(
"lambdaLogStep");
 
 1279             for (
double l = lambdaLogMin; l <= lambdaLogMax; l += lambdaLogStep) {
 
 1298         _spatialKernelFunction(spatialKernelFunction),
 
 1299         _constantFirstTerm(false),
 
 1309         bool isAlardLupton    = _ps->getAsString(
"kernelBasisSet") == 
"alard-lupton";
 
 1310         bool usePca           = _ps->getAsBool(
"usePcaForSpatialKernel");
 
 1311         if (isAlardLupton || usePca) {
 
 1312             _constantFirstTerm = 
true;
 
 1316         _nbases = basisList.
size();
 
 1317         _nkt = _spatialKernelFunction->getParameters().size();
 
 1320         if (_constantFirstTerm) {
 
 1321             _nt = (_nbases - 1) * _nkt + 1 + _nbt;
 
 1323             _nt = _nbases * _nkt + _nbt;
 
 1326         Eigen::MatrixXd mMat(_nt, _nt);
 
 1327         Eigen::VectorXd bVec(_nt);
 
 1338         LOGL_DEBUG(
"TRACE3.ip.diffim.SpatialKernelSolution",
 
 1339                    "Initializing with size %d %d %d and constant first term = %s",
 
 1341                    _constantFirstTerm ? 
"true" : 
"false");
 
 1346                                               Eigen::MatrixXd 
const& qMat,
 
 1347                                               Eigen::VectorXd 
const& wVec) {
 
 1349         LOGL_DEBUG(
"TRACE5.ip.diffim.SpatialKernelSolution.addConstraint",
 
 1350                    "Adding candidate at %f, %f", xCenter, yCenter);
 
 1354         Eigen::VectorXd pK(_nkt);
 
 1356         for (
int idx = 0; idx < _nkt; idx++) { paramsK[idx] = 0.0; }
 
 1357         for (
int idx = 0; idx < _nkt; idx++) {
 
 1359             _spatialKernelFunction->setParameters(paramsK);
 
 1360             pK(idx) = (*_spatialKernelFunction)(xCenter, yCenter); 
 
 1363         Eigen::MatrixXd pKpKt = (pK * pK.transpose());
 
 1366         Eigen::MatrixXd pBpBt;
 
 1367         Eigen::MatrixXd pKpBt;
 
 1369             pB = Eigen::VectorXd(_nbt);
 
 1373             for (
int idx = 0; idx < _nbt; idx++) { paramsB[idx] = 0.0; }
 
 1374             for (
int idx = 0; idx < _nbt; idx++) {
 
 1376                 _background->setParameters(paramsB);
 
 1377                 pB(idx) = (*_background)(xCenter, yCenter);       
 
 1380             pBpBt = (pB * pB.transpose());
 
 1383             pKpBt = (pK * pB.transpose());
 
 1406         int mb = _nt - _nbt;
 
 1408         if (_constantFirstTerm) {
 
 1412             _mMat(0, 0) += qMat(0,0);
 
 1413             for(
int m2 = 1; m2 < _nbases; m2++)  {
 
 1414                 _mMat.block(0, m2*_nkt-dm, 1, _nkt) += qMat(0,m2) * pK.transpose();
 
 1416             _bVec(0) += wVec(0);
 
 1419                 _mMat.block(0, mb, 1, _nbt) += qMat(0,_nbases) * pB.transpose();
 
 1424         for(
int m1 = m0; m1 < _nbases; m1++)  {
 
 1426             _mMat.block(m1*_nkt-dm, m1*_nkt-dm, _nkt, _nkt) +=
 
 1427                 (pKpKt * qMat(m1,m1)).triangularView<Eigen::Upper>();
 
 1430             for(
int m2 = m1+1; m2 < _nbases; m2++)  {
 
 1431                 _mMat.block(m1*_nkt-dm, m2*_nkt-dm, _nkt, _nkt) += qMat(m1,m2) * pKpKt;
 
 1436                 _mMat.block(m1*_nkt-dm, mb, _nkt, _nbt) += qMat(m1,_nbases) * pKpBt;
 
 1440             _bVec.segment(m1*_nkt-dm, _nkt) += wVec(m1) * pK;
 
 1445             _mMat.block(mb, mb, _nbt, _nbt) +=
 
 1446                 (pBpBt * qMat(_nbases,_nbases)).triangularView<Eigen::Upper>();
 
 1447             _bVec.segment(mb, _nbt)         += wVec(_nbases) * pB;
 
 1471         for (
int i = 0; i < _nt; i++) {
 
 1472             for (
int j = i+1; j < _nt; j++) {
 
 1496     void SpatialKernelSolution::_setKernel() {
 
 1505             for (
int i = 0; i < _nbases; i++) {
 
 1510                                 "I. Unable to determine spatial kernel solution %d (nan).  Condition number = %.3e") % i % cNumber));
 
 1512                 kCoeffs[i] = 
_aVec(i);
 
 1515                 std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(_kernel)->getKernelList();
 
 1525             for (
int i = 0, idx = 0; i < _nbases; i++) {
 
 1529                 if ((i == 0) && (_constantFirstTerm)) {
 
 1534                                     "II. Unable to determine spatial kernel solution %d (nan).  Condition number = %.3e") % idx % cNumber));
 
 1536                     kCoeffs[i][0] = 
_aVec(idx++);
 
 1539                     for (
int j = 0; j < _nkt; j++) {
 
 1544                                         "III. Unable to determine spatial kernel solution %d (nan).  Condition number = %.3e") % idx % cNumber));
 
 1546                         kCoeffs[i][j] = 
_aVec(idx++);
 
 1560             for (
int i = 0; i < _nbt; i++) {
 
 1561                 int idx = _nt - _nbt + i;
 
 1565                            "Unable to determine spatial background solution %d (nan)") % (idx)));
 
 1567                 bgCoeffs[i] = 
_aVec(idx);
 
 1573         _background->setParameters(bgCoeffs);
 
#define LSST_EXCEPT_ADD(e, m)
Add the current location and a message to an existing exception before rethrowing it.
 
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
 
Image Subtraction helper functions.
 
Declaration of classes to store the solution for convolution kernels.
 
LSST DM logging module built on log4cxx.
 
#define LOGL_DEBUG(logger, message...)
Log a debug-level message using a varargs/printf style interface.
 
A Threshold is used to pass a threshold value to detection algorithms.
 
@ BITMASK
Use (pixels & (given mask))
 
lsst::geom::Box2I getBBox(ImageOrigin origin=PARENT) const
 
lsst::geom::Extent2I getDimensions() const
Return the image's size; useful for passing to constructors.
 
lsst::geom::Point2I getXY0() const
Return the image's origin.
 
A class to represent a 2-dimensional array of pixels.
 
Represent a 2-dimensional array of bitmask pixels.
 
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.
 
static MaskPixelT getPlaneBitMask(const std::vector< std::string > &names)
Return the bitmask corresponding to a vector of plane names OR'd together.
 
Parameters to control convolution.
 
void setDoNormalize(bool doNormalize)
 
lsst::geom::Extent2I const getDimensions() const
Return the Kernel's dimensions (width, height)
 
std::shared_ptr< lsst::afw::math::Function2< double > > SpatialFunctionPtr
 
double computeImage(lsst::afw::image::Image< Pixel > &image, bool doNormalize, double x=0.0, double y=0.0) const
Compute an image (pixellized representation of the kernel) in place.
 
void setSpatialParameters(const std::vector< std::vector< double >> params)
Set the parameters of all spatial functions.
 
A kernel that is a linear combination of fixed basis kernels.
 
A class to evaluate image statistics.
 
double getValue(Property const prop=NOTHING) const
Return the value of the desired property (if specified in the constructor)
 
Class for storing generic metadata.
 
An integer coordinate rectangle.
 
int getMinY() const noexcept
 
int getHeight() const noexcept
 
int getMinX() const noexcept
 
int getWidth() const noexcept
 
int getMaxX() const noexcept
 
int getMaxY() const noexcept
 
bool _fitForBackground
Background terms included in fit.
 
virtual double getConditionNumber(ConditionNumberType conditionType)
 
Eigen::VectorXd _bVec
Derived least squares B vector.
 
Eigen::VectorXd _aVec
Derived least squares solution matrix.
 
KernelSolvedBy _solvedBy
Type of algorithm used to make solution.
 
Eigen::MatrixXd _mMat
Derived least squares M matrix.
 
static int _SolutionId
Unique identifier for solution.
 
Eigen::MatrixXd const  & getM()
 
lsst::afw::image::Image< lsst::afw::math::Kernel::Pixel > ImageT
 
virtual void buildWithMask(lsst::afw::image::Image< InputT > const &templateImage, lsst::afw::image::Image< InputT > const &scienceImage, lsst::afw::image::Image< lsst::afw::image::VariancePixel > const &varianceEstimate, lsst::afw::image::Mask< lsst::afw::image::MaskPixel > const &pixelMask)
 
virtual void buildSingleMaskOrig(lsst::afw::image::Image< InputT > const &templateImage, lsst::afw::image::Image< InputT > const &scienceImage, lsst::afw::image::Image< lsst::afw::image::VariancePixel > const &varianceEstimate, lsst::geom::Box2I maskBox)
 
MaskedKernelSolution(lsst::afw::math::KernelList const &basisList, bool fitForBackground)
 
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)
 
RegularizedKernelSolution(lsst::afw::math::KernelList const &basisList, bool fitForBackground, Eigen::MatrixXd const &hMat, lsst::daf::base::PropertySet const &ps)
 
double estimateRisk(double maxCond)
 
std::pair< std::shared_ptr< lsst::afw::math::LinearCombinationKernel >, lsst::afw::math::Kernel::SpatialFunctionPtr > getSolutionPair()
 
std::shared_ptr< lsst::afw::image::Image< lsst::afw::math::Kernel::Pixel > > makeKernelImage(lsst::geom::Point2D const &pos)
 
SpatialKernelSolution(lsst::afw::math::KernelList const &basisList, lsst::afw::math::Kernel::SpatialFunctionPtr spatialKernelFunction, lsst::afw::math::Kernel::SpatialFunctionPtr background, lsst::daf::base::PropertySet const &ps)
 
void addConstraint(float xCenter, float yCenter, Eigen::MatrixXd const &qMat, Eigen::VectorXd const &wVec)
 
virtual std::pair< std::shared_ptr< lsst::afw::math::Kernel >, double > getSolutionPair()
 
void _setKernel()
Set kernel after solution.
 
virtual double getBackground()
 
virtual std::shared_ptr< lsst::afw::math::Kernel > getKernel()
 
std::shared_ptr< lsst::afw::math::Kernel > _kernel
Derived single-object convolution kernel.
 
void _setKernelUncertainty()
Not implemented.
 
virtual std::shared_ptr< lsst::afw::image::Image< lsst::afw::math::Kernel::Pixel > > makeKernelImage()
 
StaticKernelSolution(lsst::afw::math::KernelList const &basisList, bool fitForBackground)
 
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)
 
Provides consistent interface for LSST exceptions.
 
Reports invalid arguments.
 
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
 
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)
 
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.
 
@ MIN
estimate sample minimum
 
Eigen::MatrixXd imageToEigenMatrix(lsst::afw::image::Image< PixelT > const &img)
Turns a 2-d Image into a 2-d Eigen Matrix.
 
Eigen::MatrixXi maskToEigenMatrix(lsst::afw::image::Mask< lsst::afw::image::MaskPixel > const &mask)
 
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
 
A base class for image defects.