17 #include "boost/timer.hpp" 20 #include "Eigen/Cholesky" 23 #include "Eigen/Eigenvalues" 37 #include "ndarray/eigen.h" 39 #define DEBUG_MATRIX 0 40 #define DEBUG_MATRIX2 0 65 _fitForBackground(fitForBackground)
98 switch (conditionType) {
101 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eVecValues(mMat);
102 Eigen::VectorXd eValues = eVecValues.eigenvalues();
103 double eMax = eValues.maxCoeff();
104 double eMin = eValues.minCoeff();
105 LOGL_DEBUG(
"TRACE3.ip.diffim.KernelSolution.getConditionNumber",
106 "EIGENVALUE eMax / eMin = %.3e", eMax / eMin);
107 return (eMax / eMin);
112 Eigen::VectorXd sValues = mMat.jacobiSvd().singularValues();
113 double sMax = sValues.maxCoeff();
114 double sMin = sValues.minCoeff();
115 LOGL_DEBUG(
"TRACE3.ip.diffim.KernelSolution.getConditionNumber",
116 "SVD eMax / eMin = %.3e", sMax / sMin);
117 return (sMax / sMin);
123 "Undefined ConditionNumberType : only EIGENVALUE, SVD allowed.");
130 Eigen::VectorXd
const& bVec) {
139 Eigen::VectorXd aVec = Eigen::VectorXd::Zero(bVec.size());
144 LOGL_DEBUG(
"TRACE2.ip.diffim.KernelSolution.solve",
145 "Solving for kernel");
147 Eigen::FullPivLU<Eigen::MatrixXd> lu(mMat);
148 if (lu.isInvertible()) {
149 aVec = lu.solve(bVec);
151 LOGL_DEBUG(
"TRACE3.ip.diffim.KernelSolution.solve",
152 "Unable to determine kernel via LU");
157 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eVecValues(mMat);
158 Eigen::MatrixXd
const& rMat = eVecValues.eigenvectors();
159 Eigen::VectorXd eValues = eVecValues.eigenvalues();
161 for (
int i = 0; i != eValues.rows(); ++i) {
162 if (eValues(i) != 0.0) {
163 eValues(i) = 1.0/eValues(i);
167 aVec = rMat * eValues.asDiagonal() * rMat.transpose() * bVec;
171 LOGL_DEBUG(
"TRACE3.ip.diffim.KernelSolution.solve",
172 "Unable to determine kernel via eigen-values");
178 double time = t.elapsed();
179 LOGL_DEBUG(
"TRACE3.ip.diffim.KernelSolution.solve",
180 "Compute time for matrix math : %.2f s", time);
192 template <
typename InputT>
195 bool fitForBackground
212 template <
typename InputT>
220 template <
typename InputT>
228 (void)
_kernel->computeImage(*image,
false);
232 template <
typename InputT>
240 template <
typename InputT>
248 template <
typename InputT>
258 template <
typename InputT>
268 "Error: variance less than 0.0");
272 "Error: variance equals 0.0, cannot inverse variance weight");
278 unsigned int const nKernelParameters = basisList.
size();
280 unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
317 unsigned int const startCol = goodBBox.
getMinX();
318 unsigned int const startRow = goodBBox.
getMinY();
320 unsigned int endCol = goodBBox.
getMaxX() + 1;
321 unsigned int endRow = goodBBox.
getMaxY() + 1;
336 startRow, startCol, endRow-startRow, endCol-startCol
337 ).array().inverse().matrix();
340 eigenTemplate.resize(eigenTemplate.rows()*eigenTemplate.cols(), 1);
341 eigenScience.resize(eigenScience.rows()*eigenScience.cols(), 1);
342 eigeniVariance.resize(eigeniVariance.rows()*eigeniVariance.cols(), 1);
353 for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
360 cMat.resize(cMat.size(), 1);
365 double time = t.elapsed();
366 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.build",
367 "Total compute time to do basis convolutions : %.2f s", time);
374 Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
377 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
378 cMat.col(kidxj) = eiterj->col(0);
382 cMat.col(nParameters-1).fill(1.);
385 _ivVec = eigeniVariance.col(0);
386 _iVec = eigenScience.col(0);
393 template <
typename InputT>
395 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.solve",
396 "mMat is %d x %d; bVec is %d; cMat is %d x %d; vVec is %d; iVec is %d",
419 template <
typename InputT>
425 unsigned int const nParameters =
_aVec.size();
427 unsigned int const nKernelParameters =
429 if (nParameters != (nKernelParameters + nBackgroundParameters))
434 for (
unsigned int idx = 0; idx < nKernelParameters; idx++) {
439 kValues[idx] =
_aVec(idx);
441 _kernel->setKernelParameters(kValues);
459 template <
typename InputT>
489 template <
typename InputT>
492 bool fitForBackground
497 template <
typename InputT>
508 "Error: variance less than 0.0");
512 "Error: variance equals 0.0, cannot inverse variance weight");
535 int growPix = (*kiter)->getCtr().getX();
539 for (
typename afwDet::FootprintSet::FootprintList::iterator
545 afwDet::setMaskFromFootprint(finalMask,
552 for (
auto const & foot : *(maskedFpSetGrown.
getFootprints())) {
556 finalMask.writeFits(
"finalmask.fits");
559 ndarray::Array<int, 1, 1> maskArray =
560 ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
561 fullFp->getSpans()->flatten(maskArray, finalMask.getArray(), templateImage.
getXY0());
562 auto maskEigen = ndarray::asEigenMatrix(maskArray);
564 ndarray::Array<InputT, 1, 1> arrayTemplate =
565 ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
566 fullFp->getSpans()->flatten(arrayTemplate, templateImage.
getArray(), templateImage.
getXY0());
567 auto eigenTemplate0 = ndarray::asEigenMatrix(arrayTemplate);
569 ndarray::Array<InputT, 1, 1> arrayScience =
570 ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
571 fullFp->getSpans()->flatten(arrayScience, scienceImage.
getArray(), scienceImage.
getXY0());
572 auto eigenScience0 = ndarray::asEigenMatrix(arrayScience);
574 ndarray::Array<afwImage::VariancePixel, 1, 1> arrayVariance =
575 ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
576 fullFp->getSpans()->flatten(arrayVariance, varianceEstimate.
getArray(), varianceEstimate.
getXY0());
577 auto eigenVariance0 = ndarray::asEigenMatrix(arrayVariance);
580 for (
int i = 0; i < maskEigen.size(); i++) {
581 if (maskEigen(i) == 0.0)
585 Eigen::VectorXd eigenTemplate(nGood);
586 Eigen::VectorXd eigenScience(nGood);
587 Eigen::VectorXd eigenVariance(nGood);
589 for (
int i = 0; i < maskEigen.size(); i++) {
590 if (maskEigen(i) == 0.0) {
591 eigenTemplate(nUsed) = eigenTemplate0(i);
592 eigenScience(nUsed) = eigenScience0(i);
593 eigenVariance(nUsed) = eigenVariance0(i);
602 unsigned int const nKernelParameters = basisList.size();
604 unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
616 for (kiter = basisList.begin(); kiter != basisList.end(); ++kiter, ++eiter) {
619 ndarray::Array<InputT, 1, 1> arrayC =
620 ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
621 fullFp->getSpans()->flatten(arrayC, cimage.getArray(), cimage.getXY0());
622 auto eigenC0 = ndarray::asEigenMatrix(arrayC);
624 Eigen::VectorXd eigenC(nGood);
626 for (
int i = 0; i < maskEigen.size(); i++) {
627 if (maskEigen(i) == 0.0) {
628 eigenC(nUsed) = eigenC0(i);
635 double time = t.elapsed();
636 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.buildWithMask",
637 "Total compute time to do basis convolutions : %.2f s", time);
641 Eigen::MatrixXd cMat(eigenTemplate.size(), nParameters);
644 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
645 cMat.block(0, kidxj, eigenTemplate.size(), 1) =
646 Eigen::MatrixXd(*eiterj).block(0, 0, eigenTemplate.size(), 1);
650 cMat.col(nParameters-1).fill(1.);
653 this->
_ivVec = eigenVariance.array().inverse().matrix();
654 this->
_iVec = eigenScience;
662 template <
typename InputT>
673 "Error: variance less than 0.0");
677 "Error: variance equals 0.0, cannot inverse variance weight");
693 unsigned int const nKernelParameters = basisList.
size();
695 unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
703 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
704 "Limits of good pixels after convolution: %d,%d -> %d,%d (local)",
709 unsigned int startCol = shrunkLocalBBox.
getMinX();
710 unsigned int startRow = shrunkLocalBBox.
getMinY();
711 unsigned int endCol = shrunkLocalBBox.
getMaxX();
712 unsigned int endRow = shrunkLocalBBox.
getMaxY();
735 startRow, startCol, endRow-startRow, endCol-startCol
736 ).array().inverse().matrix();
739 eMask.resize(eMask.rows()*eMask.cols(), 1);
740 eigenTemplate.resize(eigenTemplate.rows()*eigenTemplate.cols(), 1);
741 eigenScience.resize(eigenScience.rows()*eigenScience.cols(), 1);
742 eigeniVariance.resize(eigeniVariance.rows()*eigeniVariance.cols(), 1);
745 Eigen::MatrixXd maskedEigenTemplate(eigenTemplate.rows(), 1);
746 Eigen::MatrixXd maskedEigenScience(eigenScience.rows(), 1);
747 Eigen::MatrixXd maskedEigeniVariance(eigeniVariance.rows(), 1);
749 for (
int i = 0; i < eMask.rows(); i++) {
750 if (eMask(i, 0) == 0) {
751 maskedEigenTemplate(nGood, 0) = eigenTemplate(i, 0);
752 maskedEigenScience(nGood, 0) = eigenScience(i, 0);
753 maskedEigeniVariance(nGood, 0) = eigeniVariance(i, 0);
758 eigenTemplate = maskedEigenTemplate.block(0, 0, nGood, 1);
759 eigenScience = maskedEigenScience.block(0, 0, nGood, 1);
760 eigeniVariance = maskedEigeniVariance.block(0, 0, nGood, 1);
772 for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
779 cMat.resize(cMat.size(), 1);
782 Eigen::MatrixXd maskedcMat(cMat.rows(), 1);
784 for (
int i = 0; i < eMask.rows(); i++) {
785 if (eMask(i, 0) == 0) {
786 maskedcMat(nGood, 0) = cMat(i, 0);
790 cMat = maskedcMat.block(0, 0, nGood, 1);
794 double time = t.elapsed();
795 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.build",
796 "Total compute time to do basis convolutions : %.2f s", time);
803 Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
806 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
807 cMat.col(kidxj) = eiterj->col(0);
811 cMat.col(nParameters-1).fill(1.);
814 this->
_ivVec = eigeniVariance.col(0);
815 this->
_iVec = eigenScience.col(0);
825 template <
typename InputT>
836 "Error: variance less than 0.0");
840 "Error: variance equals 0.0, cannot inverse variance weight");
846 unsigned int const nKernelParameters = basisList.
size();
848 unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
878 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
879 "Limits of good pixels after convolution: %d,%d -> %d,%d",
883 unsigned int const startCol = shrunkBBox.
getMinX();
884 unsigned int const startRow = shrunkBBox.
getMinY();
885 unsigned int const endCol = shrunkBBox.
getMaxX();
886 unsigned int const endRow = shrunkBBox.
getMaxY();
905 int maskStartCol = maskBox.
getMinX();
906 int maskStartRow = maskBox.
getMinY();
907 int maskEndCol = maskBox.
getMaxX();
908 int maskEndRow = maskBox.
getMaxY();
941 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
942 "Upper good pixel region: %d,%d -> %d,%d",
944 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
945 "Bottom good pixel region: %d,%d -> %d,%d",
947 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
948 "Left good pixel region: %d,%d -> %d,%d",
950 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
951 "Right good pixel region: %d,%d -> %d,%d",
956 boxArray.push_back(bBox);
957 boxArray.push_back(lBox);
958 boxArray.push_back(rBox);
965 Eigen::MatrixXd eigenTemplate(totalSize, 1);
966 Eigen::MatrixXd eigenScience(totalSize, 1);
967 Eigen::MatrixXd eigeniVariance(totalSize, 1);
968 eigenTemplate.setZero();
969 eigenScience.setZero();
970 eigeniVariance.setZero();
977 for (; biter != boxArray.
end(); ++biter) {
978 int area = (*biter).getWidth() * (*biter).getHeight();
986 Eigen::MatrixXd eiVarEstimate =
imageToEigenMatrix(sVarEstimate).array().inverse().matrix();
988 eTemplate.resize(area, 1);
989 eScience.resize(area, 1);
990 eiVarEstimate.resize(area, 1);
992 eigenTemplate.block(nTerms, 0, area, 1) = eTemplate.block(0, 0, area, 1);
993 eigenScience.block(nTerms, 0, area, 1) = eScience.block(0, 0, area, 1);
994 eigeniVariance.block(nTerms, 0, area, 1) = eiVarEstimate.block(0, 0, area, 1);
1004 for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
1006 Eigen::MatrixXd cMat(totalSize, 1);
1011 for (; biter != boxArray.
end(); ++biter) {
1012 int area = (*biter).
getWidth() * (*biter).getHeight();
1016 esubimage.resize(area, 1);
1017 cMat.block(nTerms, 0, area, 1) = esubimage.block(0, 0, area, 1);
1026 double time = t.elapsed();
1027 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
1028 "Total compute time to do basis convolutions : %.2f s", time);
1035 Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
1038 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
1039 cMat.col(kidxj) = eiterj->col(0);
1043 cMat.col(nParameters-1).fill(1.);
1046 this->
_ivVec = eigeniVariance.col(0);
1047 this->
_iVec = eigenScience.col(0);
1056 template <
typename InputT>
1059 bool fitForBackground,
1060 Eigen::MatrixXd
const& hMat,
1069 template <
typename InputT>
1071 Eigen::MatrixXd vMat = this->
_cMat.jacobiSvd().matrixV();
1072 Eigen::MatrixXd vMatvMatT = vMat * vMat.transpose();
1075 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eVecValues(this->
_mMat);
1076 Eigen::MatrixXd
const& rMat = eVecValues.eigenvectors();
1077 Eigen::VectorXd eValues = eVecValues.eigenvalues();
1078 double eMax = eValues.maxCoeff();
1079 for (
int i = 0; i != eValues.rows(); ++i) {
1080 if (eValues(i) == 0.0) {
1083 else if ((eMax / eValues(i)) > maxCond) {
1084 LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.estimateRisk",
1085 "Truncating eValue %d; %.5e / %.5e = %.5e vs. %.5e",
1086 i, eMax, eValues(i), eMax / eValues(i), maxCond);
1090 eValues(i) = 1.0 / eValues(i);
1093 Eigen::MatrixXd mInv = rMat * eValues.asDiagonal() * rMat.transpose();
1097 for (
unsigned int i = 0; i < lambdas.
size(); i++) {
1098 double l = lambdas[i];
1099 Eigen::MatrixXd mLambda = this->
_mMat + l * _hMat;
1107 Eigen::VectorXd term1 = (this->
_aVec.transpose() * vMatvMatT * this->
_aVec);
1108 if (term1.size() != 1)
1111 double term2a = (vMatvMatT * mLambda.inverse()).
trace();
1113 Eigen::VectorXd term2b = (this->
_aVec.transpose() * (mInv * this->
_bVec));
1114 if (term2b.size() != 1)
1117 double risk = term1(0) + 2 * (term2a - term2b(0));
1118 LOGL_DEBUG(
"TRACE4.ip.diffim.RegularizedKernelSolution.estimateRisk",
1119 "Lambda = %.3f, Risk = %.5e",
1121 LOGL_DEBUG(
"TRACE5.ip.diffim.RegularizedKernelSolution.estimateRisk",
1122 "%.5e + 2 * (%.5e - %.5e)",
1123 term1(0), term2a, term2b(0));
1128 LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.estimateRisk",
1129 "Minimum Risk = %.3e at lambda = %.3e", risks[index], lambdas[index]);
1131 return lambdas[index];
1135 template <
typename InputT>
1137 if (includeHmat ==
true) {
1138 return this->
_mMat + _lambda * _hMat;
1145 template <
typename InputT>
1148 LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.solve",
1149 "cMat is %d x %d; vVec is %d; iVec is %d; hMat is %d x %d",
1151 this->
_iVec.size(), _hMat.rows(), _hMat.cols());
1220 if (lambdaType ==
"absolute") {
1221 _lambda = _policy.
getDouble(
"lambdaValue");
1223 else if (lambdaType ==
"relative") {
1224 _lambda = this->
_mMat.trace() / this->_hMat.trace();
1225 _lambda *= _policy.
getDouble(
"lambdaScaling");
1227 else if (lambdaType ==
"minimizeBiasedRisk") {
1231 else if (lambdaType ==
"minimizeUnbiasedRisk") {
1238 LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.solve",
1239 "Applying kernel regularization with lambda = %.2e", _lambda);
1252 template <
typename InputT>
1257 if (lambdaStepType ==
"linear") {
1258 double lambdaLinMin = _policy.
getDouble(
"lambdaLinMin");
1259 double lambdaLinMax = _policy.
getDouble(
"lambdaLinMax");
1260 double lambdaLinStep = _policy.
getDouble(
"lambdaLinStep");
1261 for (
double l = lambdaLinMin; l <= lambdaLinMax; l += lambdaLinStep) {
1265 else if (lambdaStepType ==
"log") {
1266 double lambdaLogMin = _policy.
getDouble(
"lambdaLogMin");
1267 double lambdaLogMax = _policy.
getDouble(
"lambdaLogMax");
1268 double lambdaLogStep = _policy.
getDouble(
"lambdaLogStep");
1269 for (
double l = lambdaLogMin; l <= lambdaLogMax; l += lambdaLogStep) {
1288 _spatialKernelFunction(spatialKernelFunction),
1289 _constantFirstTerm(false),
1299 bool isAlardLupton = _policy.
getString(
"kernelBasisSet") ==
"alard-lupton";
1300 bool usePca = _policy.
getBool(
"usePcaForSpatialKernel");
1301 if (isAlardLupton || usePca) {
1302 _constantFirstTerm =
true;
1306 _nbases = basisList.
size();
1307 _nkt = _spatialKernelFunction->getParameters().size();
1310 if (_constantFirstTerm) {
1311 _nt = (_nbases - 1) * _nkt + 1 + _nbt;
1313 _nt = _nbases * _nkt + _nbt;
1316 Eigen::MatrixXd mMat(_nt, _nt);
1317 Eigen::VectorXd bVec(_nt);
1328 LOGL_DEBUG(
"TRACE3.ip.diffim.SpatialKernelSolution",
1329 "Initializing with size %d %d %d and constant first term = %s",
1331 _constantFirstTerm ?
"true" :
"false");
1336 Eigen::MatrixXd
const& qMat,
1337 Eigen::VectorXd
const& wVec) {
1339 LOGL_DEBUG(
"TRACE5.ip.diffim.SpatialKernelSolution.addConstraint",
1340 "Adding candidate at %f, %f", xCenter, yCenter);
1344 Eigen::VectorXd pK(_nkt);
1346 for (
int idx = 0; idx < _nkt; idx++) { paramsK[idx] = 0.0; }
1347 for (
int idx = 0; idx < _nkt; idx++) {
1349 _spatialKernelFunction->setParameters(paramsK);
1350 pK(idx) = (*_spatialKernelFunction)(xCenter, yCenter);
1353 Eigen::MatrixXd pKpKt = (pK * pK.transpose());
1356 Eigen::MatrixXd pBpBt;
1357 Eigen::MatrixXd pKpBt;
1359 pB = Eigen::VectorXd(_nbt);
1363 for (
int idx = 0; idx < _nbt; idx++) { paramsB[idx] = 0.0; }
1364 for (
int idx = 0; idx < _nbt; idx++) {
1366 _background->setParameters(paramsB);
1367 pB(idx) = (*_background)(xCenter, yCenter);
1370 pBpBt = (pB * pB.transpose());
1373 pKpBt = (pK * pB.transpose());
1396 int mb = _nt - _nbt;
1398 if (_constantFirstTerm) {
1402 _mMat(0, 0) += qMat(0,0);
1403 for(
int m2 = 1; m2 < _nbases; m2++) {
1404 _mMat.block(0, m2*_nkt-dm, 1, _nkt) += qMat(0,m2) * pK.transpose();
1406 _bVec(0) += wVec(0);
1409 _mMat.block(0, mb, 1, _nbt) += qMat(0,_nbases) * pB.transpose();
1414 for(
int m1 = m0; m1 < _nbases; m1++) {
1416 _mMat.block(m1*_nkt-dm, m1*_nkt-dm, _nkt, _nkt) +=
1417 (pKpKt * qMat(m1,m1)).triangularView<Eigen::Upper>();
1420 for(
int m2 = m1+1; m2 < _nbases; m2++) {
1421 _mMat.block(m1*_nkt-dm, m2*_nkt-dm, _nkt, _nkt) += qMat(m1,m2) * pKpKt;
1426 _mMat.block(m1*_nkt-dm, mb, _nkt, _nbt) += qMat(m1,_nbases) * pKpBt;
1430 _bVec.segment(m1*_nkt-dm, _nkt) += wVec(m1) * pK;
1435 _mMat.block(mb, mb, _nbt, _nbt) +=
1436 (pBpBt * qMat(_nbases,_nbases)).triangularView<Eigen::Upper>();
1437 _bVec.segment(mb, _nbt) += wVec(_nbases) * pB;
1455 (void)_kernel->computeImage(*image,
false, pos[0], pos[1]);
1461 for (
int i = 0; i < _nt; i++) {
1462 for (
int j = i+1; j < _nt; j++) {
1486 void SpatialKernelSolution::_setKernel() {
1495 for (
int i = 0; i < _nbases; i++) {
1500 "I. Unable to determine spatial kernel solution %d (nan). Condition number = %.3e") % i % cNumber));
1502 kCoeffs[i] =
_aVec(i);
1507 new afwMath::LinearCombinationKernel(basisList, kCoeffs)
1515 for (
int i = 0, idx = 0; i < _nbases; i++) {
1519 if ((i == 0) && (_constantFirstTerm)) {
1524 "II. Unable to determine spatial kernel solution %d (nan). Condition number = %.3e") % idx % cNumber));
1526 kCoeffs[i][0] =
_aVec(idx++);
1529 for (
int j = 0; j < _nkt; j++) {
1534 "III. Unable to determine spatial kernel solution %d (nan). Condition number = %.3e") % idx % cNumber));
1536 kCoeffs[i][j] =
_aVec(idx++);
1540 _kernel->setSpatialParameters(kCoeffs);
1545 _kSum = _kernel->computeImage(*image,
false);
1550 for (
int i = 0; i < _nbt; i++) {
1551 int idx = _nt - _nbt + i;
1555 "Unable to determine spatial background solution %d (nan)") % (idx)));
1557 bgCoeffs[i] =
_aVec(idx);
1563 _background->setParameters(bgCoeffs);
int getHeight() const noexcept
Eigen::MatrixXd _cMat
K_i x R.
Eigen::MatrixXi maskToEigenMatrix(lsst::afw::image::Mask< lsst::afw::image::MaskPixel > const &mask)
a container for holding hierarchical configuration data in memory.
virtual std::pair< std::shared_ptr< lsst::afw::math::Kernel >, double > getSolutionPair()
Eigen::VectorXd _bVec
Derived least squares B vector.
SpatialKernelSolution(lsst::afw::math::KernelList const &basisList, lsst::afw::math::Kernel::SpatialFunctionPtr spatialKernelFunction, lsst::afw::math::Kernel::SpatialFunctionPtr background, lsst::pex::policy::Policy policy)
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.
const std::string getString(const std::string &name) const
return a string value associated with the given name .
#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.
RegularizedKernelSolution(lsst::afw::math::KernelList const &basisList, bool fitForBackground, Eigen::MatrixXd const &hMat, lsst::pex::policy::Policy policy)
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.
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
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...
std::shared_ptr< lsst::afw::image::Image< lsst::afw::math::Kernel::Pixel > > makeKernelImage(lsst::afw::geom::Point2D const &pos)
int getMaxX() const noexcept
double getValue(Property const prop=NOTHING) const
Return the value of the desired property (if specified in the constructor)
bool getBool(const std::string &name) const
return a boolean value associated with the given name.
Eigen::MatrixXd _mMat
Derived least squares M matrix.
double getDouble(const std::string &name) const
return a double value associated with the given name.
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.
MaskedKernelSolution(lsst::afw::math::KernelList const &basisList, bool fitForBackground)
void addConstraint(float xCenter, float yCenter, Eigen::MatrixXd const &qMat, Eigen::VectorXd const &wVec)
Reports invalid arguments.
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)
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...
#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