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)
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");
280 unsigned int const nKernelParameters = basisList.
size();
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);
355 for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
362 cMat.resize(cMat.size(), 1);
367 double time = t.elapsed();
368 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.build",
369 "Total compute time to do basis convolutions : %.2f s", time);
376 Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
379 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
380 cMat.col(kidxj) = eiterj->col(0);
384 cMat.col(nParameters-1).fill(1.);
387 _ivVec = eigeniVariance.col(0);
388 _iVec = eigenScience.col(0);
395 template <
typename InputT>
397 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.solve",
398 "mMat is %d x %d; bVec is %d; cMat is %d x %d; vVec is %d; iVec is %d",
421 template <
typename InputT>
427 unsigned int const nParameters =
_aVec.size();
429 unsigned int const nKernelParameters =
431 if (nParameters != (nKernelParameters + nBackgroundParameters))
436 for (
unsigned int idx = 0; idx < nKernelParameters; idx++) {
439 str(
boost::format(
"Unable to determine kernel solution %d (nan)") % idx));
441 kValues[idx] =
_aVec(idx);
443 _kernel->setKernelParameters(kValues);
453 str(
boost::format(
"Unable to determine background solution %d (nan)") %
461 template <
typename InputT>
491 template <
typename InputT>
494 bool fitForBackground
499 template <
typename InputT>
510 "Error: variance less than 0.0");
514 "Error: variance equals 0.0, cannot inverse variance weight");
537 int growPix = (*kiter)->getCtr().getX();
541 for (
typename afwDet::FootprintSet::FootprintList::iterator
547 afwDet::setMaskFromFootprint(finalMask,
554 for (
auto const & foot : *(maskedFpSetGrown.
getFootprints())) {
558 finalMask.writeFits(
"finalmask.fits");
561 ndarray::Array<int, 1, 1> maskArray =
562 ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
563 fullFp->getSpans()->flatten(maskArray, finalMask.getArray(), templateImage.
getXY0());
564 auto maskEigen = ndarray::asEigenMatrix(maskArray);
566 ndarray::Array<InputT, 1, 1> arrayTemplate =
567 ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
568 fullFp->getSpans()->flatten(arrayTemplate, templateImage.
getArray(), templateImage.
getXY0());
569 auto eigenTemplate0 = ndarray::asEigenMatrix(arrayTemplate);
571 ndarray::Array<InputT, 1, 1> arrayScience =
572 ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
573 fullFp->getSpans()->flatten(arrayScience, scienceImage.
getArray(), scienceImage.
getXY0());
574 auto eigenScience0 = ndarray::asEigenMatrix(arrayScience);
576 ndarray::Array<afwImage::VariancePixel, 1, 1> arrayVariance =
577 ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
578 fullFp->getSpans()->flatten(arrayVariance, varianceEstimate.
getArray(), varianceEstimate.
getXY0());
579 auto eigenVariance0 = ndarray::asEigenMatrix(arrayVariance);
582 for (
int i = 0; i < maskEigen.size(); i++) {
583 if (maskEigen(i) == 0.0)
587 Eigen::VectorXd eigenTemplate(nGood);
588 Eigen::VectorXd eigenScience(nGood);
589 Eigen::VectorXd eigenVariance(nGood);
591 for (
int i = 0; i < maskEigen.size(); i++) {
592 if (maskEigen(i) == 0.0) {
593 eigenTemplate(nUsed) = eigenTemplate0(i);
594 eigenScience(nUsed) = eigenScience0(i);
595 eigenVariance(nUsed) = eigenVariance0(i);
604 unsigned int const nKernelParameters = basisList.size();
606 unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
618 for (kiter = basisList.begin(); kiter != basisList.end(); ++kiter, ++eiter) {
621 ndarray::Array<InputT, 1, 1> arrayC =
622 ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
623 fullFp->getSpans()->flatten(arrayC, cimage.getArray(), cimage.getXY0());
624 auto eigenC0 = ndarray::asEigenMatrix(arrayC);
626 Eigen::VectorXd eigenC(nGood);
628 for (
int i = 0; i < maskEigen.size(); i++) {
629 if (maskEigen(i) == 0.0) {
630 eigenC(nUsed) = eigenC0(i);
637 double time = t.elapsed();
638 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.buildWithMask",
639 "Total compute time to do basis convolutions : %.2f s", time);
643 Eigen::MatrixXd cMat(eigenTemplate.size(), nParameters);
646 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
647 cMat.block(0, kidxj, eigenTemplate.size(), 1) =
648 Eigen::MatrixXd(*eiterj).block(0, 0, eigenTemplate.size(), 1);
652 cMat.col(nParameters-1).fill(1.);
655 this->
_ivVec = eigenVariance.array().inverse().matrix();
656 this->
_iVec = eigenScience;
664 template <
typename InputT>
675 "Error: variance less than 0.0");
679 "Error: variance equals 0.0, cannot inverse variance weight");
695 unsigned int const nKernelParameters = basisList.
size();
697 unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
705 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
706 "Limits of good pixels after convolution: %d,%d -> %d,%d (local)",
711 unsigned int startCol = shrunkLocalBBox.
getMinX();
712 unsigned int startRow = shrunkLocalBBox.
getMinY();
713 unsigned int endCol = shrunkLocalBBox.
getMaxX();
714 unsigned int endRow = shrunkLocalBBox.
getMaxY();
737 startRow, startCol, endRow-startRow, endCol-startCol
738 ).array().inverse().matrix();
741 eMask.resize(eMask.rows()*eMask.cols(), 1);
742 eigenTemplate.resize(eigenTemplate.rows()*eigenTemplate.cols(), 1);
743 eigenScience.resize(eigenScience.rows()*eigenScience.cols(), 1);
744 eigeniVariance.resize(eigeniVariance.rows()*eigeniVariance.cols(), 1);
747 Eigen::MatrixXd maskedEigenTemplate(eigenTemplate.rows(), 1);
748 Eigen::MatrixXd maskedEigenScience(eigenScience.rows(), 1);
749 Eigen::MatrixXd maskedEigeniVariance(eigeniVariance.rows(), 1);
751 for (
int i = 0; i < eMask.rows(); i++) {
752 if (eMask(i, 0) == 0) {
753 maskedEigenTemplate(nGood, 0) = eigenTemplate(i, 0);
754 maskedEigenScience(nGood, 0) = eigenScience(i, 0);
755 maskedEigeniVariance(nGood, 0) = eigeniVariance(i, 0);
760 eigenTemplate = maskedEigenTemplate.block(0, 0, nGood, 1);
761 eigenScience = maskedEigenScience.block(0, 0, nGood, 1);
762 eigeniVariance = maskedEigeniVariance.block(0, 0, nGood, 1);
774 for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
781 cMat.resize(cMat.size(), 1);
784 Eigen::MatrixXd maskedcMat(cMat.rows(), 1);
786 for (
int i = 0; i < eMask.rows(); i++) {
787 if (eMask(i, 0) == 0) {
788 maskedcMat(nGood, 0) = cMat(i, 0);
792 cMat = maskedcMat.block(0, 0, nGood, 1);
796 double time = t.elapsed();
797 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.build",
798 "Total compute time to do basis convolutions : %.2f s", time);
805 Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
808 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
809 cMat.col(kidxj) = eiterj->col(0);
813 cMat.col(nParameters-1).fill(1.);
816 this->
_ivVec = eigeniVariance.col(0);
817 this->
_iVec = eigenScience.col(0);
827 template <
typename InputT>
838 "Error: variance less than 0.0");
842 "Error: variance equals 0.0, cannot inverse variance weight");
848 unsigned int const nKernelParameters = basisList.
size();
850 unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
880 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
881 "Limits of good pixels after convolution: %d,%d -> %d,%d",
885 unsigned int const startCol = shrunkBBox.
getMinX();
886 unsigned int const startRow = shrunkBBox.
getMinY();
887 unsigned int const endCol = shrunkBBox.
getMaxX();
888 unsigned int const endRow = shrunkBBox.
getMaxY();
907 int maskStartCol = maskBox.
getMinX();
908 int maskStartRow = maskBox.
getMinY();
909 int maskEndCol = maskBox.
getMaxX();
910 int maskEndRow = maskBox.
getMaxY();
943 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
944 "Upper good pixel region: %d,%d -> %d,%d",
946 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
947 "Bottom good pixel region: %d,%d -> %d,%d",
949 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
950 "Left good pixel region: %d,%d -> %d,%d",
952 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
953 "Right good pixel region: %d,%d -> %d,%d",
958 boxArray.push_back(bBox);
959 boxArray.push_back(lBox);
960 boxArray.push_back(rBox);
967 Eigen::MatrixXd eigenTemplate(totalSize, 1);
968 Eigen::MatrixXd eigenScience(totalSize, 1);
969 Eigen::MatrixXd eigeniVariance(totalSize, 1);
970 eigenTemplate.setZero();
971 eigenScience.setZero();
972 eigeniVariance.setZero();
979 for (; biter != boxArray.
end(); ++biter) {
980 int area = (*biter).getWidth() * (*biter).getHeight();
988 Eigen::MatrixXd eiVarEstimate =
imageToEigenMatrix(sVarEstimate).array().inverse().matrix();
990 eTemplate.resize(area, 1);
991 eScience.resize(area, 1);
992 eiVarEstimate.resize(area, 1);
994 eigenTemplate.block(nTerms, 0, area, 1) = eTemplate.block(0, 0, area, 1);
995 eigenScience.block(nTerms, 0, area, 1) = eScience.block(0, 0, area, 1);
996 eigeniVariance.block(nTerms, 0, area, 1) = eiVarEstimate.block(0, 0, area, 1);
1006 for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
1008 Eigen::MatrixXd cMat(totalSize, 1);
1013 for (; biter != boxArray.
end(); ++biter) {
1014 int area = (*biter).
getWidth() * (*biter).getHeight();
1018 esubimage.resize(area, 1);
1019 cMat.block(nTerms, 0, area, 1) = esubimage.block(0, 0, area, 1);
1028 double time = t.elapsed();
1029 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
1030 "Total compute time to do basis convolutions : %.2f s", time);
1037 Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
1040 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
1041 cMat.col(kidxj) = eiterj->col(0);
1045 cMat.col(nParameters-1).fill(1.);
1048 this->
_ivVec = eigeniVariance.col(0);
1049 this->
_iVec = eigenScience.col(0);
1058 template <
typename InputT>
1061 bool fitForBackground,
1062 Eigen::MatrixXd
const& hMat,
1071 template <
typename InputT>
1073 Eigen::MatrixXd vMat = this->
_cMat.jacobiSvd().matrixV();
1074 Eigen::MatrixXd vMatvMatT = vMat * vMat.transpose();
1077 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eVecValues(this->
_mMat);
1078 Eigen::MatrixXd
const& rMat = eVecValues.eigenvectors();
1079 Eigen::VectorXd eValues = eVecValues.eigenvalues();
1080 double eMax = eValues.maxCoeff();
1081 for (
int i = 0; i != eValues.rows(); ++i) {
1082 if (eValues(i) == 0.0) {
1085 else if ((eMax / eValues(i)) > maxCond) {
1086 LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.estimateRisk",
1087 "Truncating eValue %d; %.5e / %.5e = %.5e vs. %.5e",
1088 i, eMax, eValues(i), eMax / eValues(i), maxCond);
1092 eValues(i) = 1.0 / eValues(i);
1095 Eigen::MatrixXd mInv = rMat * eValues.asDiagonal() * rMat.transpose();
1099 for (
unsigned int i = 0; i < lambdas.
size(); i++) {
1100 double l = lambdas[i];
1101 Eigen::MatrixXd mLambda = this->
_mMat + l * _hMat;
1109 Eigen::VectorXd term1 = (this->
_aVec.transpose() * vMatvMatT * this->
_aVec);
1110 if (term1.size() != 1)
1113 double term2a = (vMatvMatT * mLambda.inverse()).
trace();
1115 Eigen::VectorXd term2b = (this->
_aVec.transpose() * (mInv * this->
_bVec));
1116 if (term2b.size() != 1)
1119 double risk = term1(0) + 2 * (term2a - term2b(0));
1120 LOGL_DEBUG(
"TRACE4.ip.diffim.RegularizedKernelSolution.estimateRisk",
1121 "Lambda = %.3f, Risk = %.5e",
1123 LOGL_DEBUG(
"TRACE5.ip.diffim.RegularizedKernelSolution.estimateRisk",
1124 "%.5e + 2 * (%.5e - %.5e)",
1125 term1(0), term2a, term2b(0));
1130 LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.estimateRisk",
1131 "Minimum Risk = %.3e at lambda = %.3e", risks[index], lambdas[index]);
1133 return lambdas[index];
1137 template <
typename InputT>
1139 if (includeHmat ==
true) {
1140 return this->
_mMat + _lambda * _hMat;
1147 template <
typename InputT>
1150 LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.solve",
1151 "cMat is %d x %d; vVec is %d; iVec is %d; hMat is %d x %d",
1153 this->
_iVec.size(), _hMat.rows(), _hMat.cols());
1221 std::string lambdaType = _ps->getAsString(
"lambdaType");
1222 if (lambdaType ==
"absolute") {
1223 _lambda = _ps->getAsDouble(
"lambdaValue");
1225 else if (lambdaType ==
"relative") {
1226 _lambda = this->
_mMat.trace() / this->_hMat.trace();
1227 _lambda *= _ps->getAsDouble(
"lambdaScaling");
1229 else if (lambdaType ==
"minimizeBiasedRisk") {
1230 double tol = _ps->getAsDouble(
"maxConditionNumber");
1233 else if (lambdaType ==
"minimizeUnbiasedRisk") {
1240 LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.solve",
1241 "Applying kernel regularization with lambda = %.2e", _lambda);
1254 template <
typename InputT>
1258 std::string lambdaStepType = _ps->getAsString(
"lambdaStepType");
1259 if (lambdaStepType ==
"linear") {
1260 double lambdaLinMin = _ps->getAsDouble(
"lambdaLinMin");
1261 double lambdaLinMax = _ps->getAsDouble(
"lambdaLinMax");
1262 double lambdaLinStep = _ps->getAsDouble(
"lambdaLinStep");
1263 for (
double l = lambdaLinMin; l <= lambdaLinMax; l += lambdaLinStep) {
1267 else if (lambdaStepType ==
"log") {
1268 double lambdaLogMin = _ps->getAsDouble(
"lambdaLogMin");
1269 double lambdaLogMax = _ps->getAsDouble(
"lambdaLogMax");
1270 double lambdaLogStep = _ps->getAsDouble(
"lambdaLogStep");
1271 for (
double l = lambdaLogMin; l <= lambdaLogMax; l += lambdaLogStep) {
1290 _spatialKernelFunction(spatialKernelFunction),
1291 _constantFirstTerm(false),
1301 bool isAlardLupton = _ps->getAsString(
"kernelBasisSet") ==
"alard-lupton";
1302 bool usePca = _ps->getAsBool(
"usePcaForSpatialKernel");
1303 if (isAlardLupton || usePca) {
1304 _constantFirstTerm =
true;
1308 _nbases = basisList.
size();
1309 _nkt = _spatialKernelFunction->getParameters().size();
1312 if (_constantFirstTerm) {
1313 _nt = (_nbases - 1) * _nkt + 1 + _nbt;
1315 _nt = _nbases * _nkt + _nbt;
1318 Eigen::MatrixXd mMat(_nt, _nt);
1319 Eigen::VectorXd bVec(_nt);
1330 LOGL_DEBUG(
"TRACE3.ip.diffim.SpatialKernelSolution",
1331 "Initializing with size %d %d %d and constant first term = %s",
1333 _constantFirstTerm ?
"true" :
"false");
1338 Eigen::MatrixXd
const& qMat,
1339 Eigen::VectorXd
const& wVec) {
1341 LOGL_DEBUG(
"TRACE5.ip.diffim.SpatialKernelSolution.addConstraint",
1342 "Adding candidate at %f, %f", xCenter, yCenter);
1346 Eigen::VectorXd pK(_nkt);
1348 for (
int idx = 0; idx < _nkt; idx++) { paramsK[idx] = 0.0; }
1349 for (
int idx = 0; idx < _nkt; idx++) {
1351 _spatialKernelFunction->setParameters(paramsK);
1352 pK(idx) = (*_spatialKernelFunction)(xCenter, yCenter);
1355 Eigen::MatrixXd pKpKt = (pK * pK.transpose());
1358 Eigen::MatrixXd pBpBt;
1359 Eigen::MatrixXd pKpBt;
1361 pB = Eigen::VectorXd(_nbt);
1365 for (
int idx = 0; idx < _nbt; idx++) { paramsB[idx] = 0.0; }
1366 for (
int idx = 0; idx < _nbt; idx++) {
1368 _background->setParameters(paramsB);
1369 pB(idx) = (*_background)(xCenter, yCenter);
1372 pBpBt = (pB * pB.transpose());
1375 pKpBt = (pK * pB.transpose());
1398 int mb = _nt - _nbt;
1400 if (_constantFirstTerm) {
1404 _mMat(0, 0) += qMat(0,0);
1405 for(
int m2 = 1; m2 < _nbases; m2++) {
1406 _mMat.block(0, m2*_nkt-dm, 1, _nkt) += qMat(0,m2) * pK.transpose();
1408 _bVec(0) += wVec(0);
1411 _mMat.block(0, mb, 1, _nbt) += qMat(0,_nbases) * pB.transpose();
1416 for(
int m1 = m0; m1 < _nbases; m1++) {
1418 _mMat.block(m1*_nkt-dm, m1*_nkt-dm, _nkt, _nkt) +=
1419 (pKpKt * qMat(m1,m1)).triangularView<Eigen::Upper>();
1422 for(
int m2 = m1+1; m2 < _nbases; m2++) {
1423 _mMat.block(m1*_nkt-dm, m2*_nkt-dm, _nkt, _nkt) += qMat(m1,m2) * pKpKt;
1428 _mMat.block(m1*_nkt-dm, mb, _nkt, _nbt) += qMat(m1,_nbases) * pKpBt;
1432 _bVec.segment(m1*_nkt-dm, _nkt) += wVec(m1) * pK;
1437 _mMat.block(mb, mb, _nbt, _nbt) +=
1438 (pBpBt * qMat(_nbases,_nbases)).triangularView<Eigen::Upper>();
1439 _bVec.segment(mb, _nbt) += wVec(_nbases) * pB;
1457 (void)_kernel->computeImage(*image,
false, pos[0], pos[1]);
1463 for (
int i = 0; i < _nt; i++) {
1464 for (
int j = i+1; j < _nt; j++) {
1488 void SpatialKernelSolution::_setKernel() {
1497 for (
int i = 0; i < _nbases; i++) {
1502 "I. Unable to determine spatial kernel solution %d (nan). Condition number = %.3e") % i % cNumber));
1504 kCoeffs[i] =
_aVec(i);
1509 new afwMath::LinearCombinationKernel(basisList, kCoeffs)
1517 for (
int i = 0, idx = 0; i < _nbases; i++) {
1521 if ((i == 0) && (_constantFirstTerm)) {
1526 "II. Unable to determine spatial kernel solution %d (nan). Condition number = %.3e") % idx % cNumber));
1528 kCoeffs[i][0] =
_aVec(idx++);
1531 for (
int j = 0; j < _nkt; j++) {
1536 "III. Unable to determine spatial kernel solution %d (nan). Condition number = %.3e") % idx % cNumber));
1538 kCoeffs[i][j] =
_aVec(idx++);
1542 _kernel->setSpatialParameters(kCoeffs);
1547 _kSum = _kernel->computeImage(*image,
false);
1552 for (
int i = 0; i < _nbt; i++) {
1553 int idx = _nt - _nbt + i;
1557 "Unable to determine spatial background solution %d (nan)") % (idx)));
1559 bgCoeffs[i] =
_aVec(idx);
1565 _background->setParameters(bgCoeffs);
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
RegularizedKernelSolution(lsst::afw::math::KernelList const &basisList, bool fitForBackground, Eigen::MatrixXd const &hMat, lsst::daf::base::PropertySet const &ps)
int getHeight() const noexcept
Eigen::MatrixXd _cMat
K_i x R.
Eigen::MatrixXi maskToEigenMatrix(lsst::afw::image::Mask< lsst::afw::image::MaskPixel > const &mask)
virtual std::pair< std::shared_ptr< lsst::afw::math::Kernel >, double > getSolutionPair()
Eigen::VectorXd _bVec
Derived least squares B vector.
virtual std::shared_ptr< lsst::afw::image::Image< lsst::afw::math::Kernel::Pixel > > makeKernelImage()
std::shared_ptr< lsst::afw::math::Function2< double > > SpatialFunctionPtr
Use (pixels & (given mask))
A Threshold is used to pass a threshold value to detection algorithms.
KernelSolvedBy _solvedBy
Type of algorithm used to make solution.
Provides consistent interface for LSST exceptions.
StaticKernelSolution(lsst::afw::math::KernelList const &basisList, bool fitForBackground)
double _background
Derived differential background estimate.
Eigen::VectorXd _iVec
Vectorized I.
#define LOGL_DEBUG(logger, message...)
Log a debug-level message using a varargs/printf style interface.
Eigen::VectorXd _ivVec
Inverse variance.
A class to evaluate image statistics.
virtual double getBackground()
std::pair< std::shared_ptr< lsst::afw::math::LinearCombinationKernel >, lsst::afw::math::Kernel::SpatialFunctionPtr > getSolutionPair()
Declaration of classes to store the solution for convolution kernels.
iterator end() const
Return an STL compliant iterator to the end of the image.
LSST DM logging module built on log4cxx.
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)
void _setKernel()
Set kernel after solution.
virtual std::shared_ptr< lsst::afw::math::Kernel > getKernel()
A base class for image defects.
static int _SolutionId
Unique identifier for solution.
void _setKernelUncertainty()
Not implemented.
bool _fitForBackground
Background terms included in fit.
lsst::geom::Box2I getBBox(ImageOrigin origin=PARENT) const
Represent a 2-dimensional array of bitmask pixels.
lsst::afw::image::Image< lsst::afw::math::Kernel::Pixel > ImageT
int getMaxY() const noexcept
virtual double getConditionNumber(ConditionNumberType conditionType)
int _id
Unique ID for object.
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)
A kernel that is a linear combination of fixed basis kernels.
int getWidth() const noexcept
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)
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)
static MaskPixelT getPlaneBitMask(const std::vector< std::string > &names)
Return the bitmask corresponding to a vector of plane names OR'd together.
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...
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)
int getMaxX() const noexcept
double getValue(Property const prop=NOTHING) const
Return the value of the desired property (if specified in the constructor)
Eigen::MatrixXd _mMat
Derived least squares M matrix.
int getMinX() const noexcept
lsst::geom::Point2I getXY0() const
Return the image's origin.
double _kSum
Derived kernel sum.
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
std::shared_ptr< lsst::afw::image::Image< lsst::afw::math::Kernel::Pixel > > makeKernelImage(lsst::geom::Point2D const &pos)
MaskedKernelSolution(lsst::afw::math::KernelList const &basisList, bool fitForBackground)
void addConstraint(float xCenter, float yCenter, Eigen::MatrixXd const &qMat, Eigen::VectorXd const &wVec)
Class for storing generic metadata.
Reports invalid arguments.
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)
iterator begin() const
Return an STL compliant iterator to the start of the image.
Eigen::MatrixXd const & getM()
double estimateRisk(double maxCond)
Eigen::VectorXd _aVec
Derived least squares solution matrix.
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's size; useful for passing to constructors.
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects...
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)
#define LSST_EXCEPT_ADD(e, m)
Add the current location and a message to an existing exception before rethrowing it...
An integer coordinate rectangle.
A class to represent a 2-dimensional array of pixels.
Image Subtraction helper functions.
int getMinY() const noexcept