14 #include "boost/timer.hpp"
16 #include "lsst/pex/exceptions/Exception.h"
17 #include "lsst/pex/policy/Policy.h"
18 #include "lsst/afw/geom.h"
19 #include "lsst/afw/image.h"
20 #include "lsst/afw/math.h"
21 #include "lsst/log/Log.h"
24 namespace pexExcept = lsst::pex::exceptions;
25 namespace afwGeom = lsst::afw::geom;
26 namespace afwImage = lsst::afw::image;
27 namespace afwMath = lsst::afw::math;
46 lsst::afw::math::KernelList
51 if ((width < 1) || (height < 1)) {
52 throw LSST_EXCEPT(pexExcept::Exception,
"nRows and nCols must be positive");
54 const int signedWidth =
static_cast<int>(width);
55 const int signedHeight =
static_cast<int>(height);
56 afwMath::KernelList kernelBasisList;
57 for (
int row = 0; row < signedHeight; ++row) {
58 for (
int col = 0; col < signedWidth; ++col) {
59 std::shared_ptr<afwMath::Kernel>
60 kernelPtr(
new afwMath::DeltaFunctionKernel(width, height, afwGeom::Point2I(col,row)));
61 kernelBasisList.push_back(kernelPtr);
64 return kernelBasisList;
77 lsst::afw::math::KernelList
81 std::vector<double>
const &sigGauss,
82 std::vector<int>
const °Gauss
84 typedef afwMath::Kernel::Pixel Pixel;
85 typedef afwImage::Image<Pixel> Image;
88 throw LSST_EXCEPT(pexExcept::Exception,
"halfWidth must be positive");
90 if (nGauss != static_cast<int>(sigGauss.size())) {
91 throw LSST_EXCEPT(pexExcept::Exception,
"sigGauss does not have enough entries");
93 if (nGauss != static_cast<int>(degGauss.size())) {
94 throw LSST_EXCEPT(pexExcept::Exception,
"degGauss does not have enough entries");
96 int fullWidth = 2 * halfWidth + 1;
97 Image image(afwGeom::Extent2I(fullWidth, fullWidth));
99 afwMath::KernelList kernelBasisList;
100 for (
int i = 0; i < nGauss; i++) {
104 double sig = sigGauss[i];
105 int deg = degGauss[i];
107 LOGL_DEBUG(
"TRACE1.ip.diffim.BasisLists.makeAlardLuptonBasisList",
108 "Gaussian %d : sigma %.2f degree %d", i, sig, deg);
110 afwMath::GaussianFunction2<Pixel> gaussian(sig, sig);
111 afwMath::AnalyticKernel kernel(fullWidth, fullWidth, gaussian);
112 afwMath::PolynomialFunction2<Pixel> polynomial(deg);
114 for (
int j = 0, n = 0; j <= deg; j++) {
115 for (
int k = 0; k <= (deg - j); k++, n++) {
117 (void)kernel.computeImage(image,
true);
119 std::shared_ptr<afwMath::Kernel>
120 kernelPtr(
new afwMath::FixedKernel(image));
121 kernelBasisList.push_back(kernelPtr);
126 polynomial.setParameter(n, 1.);
127 (void)kernel.computeImage(image,
true);
128 for (
int y = 0, v = -halfWidth; y < image.getHeight(); y++, v++) {
130 for (Image::xy_locator ptr = image.xy_at(0, y),
131 end = image.xy_at(image.getWidth(), y);
132 ptr != end; ++ptr.x(), u++) {
134 *ptr = *ptr * polynomial(u/static_cast<double>(halfWidth),
135 v/static_cast<double>(halfWidth));
138 std::shared_ptr<afwMath::Kernel>
139 kernelPtr(
new afwMath::FixedKernel(image));
140 kernelBasisList.push_back(kernelPtr);
141 polynomial.setParameter(n, 0.);
150 lsst::pex::policy::Policy policy
183 std::string regularizationType = policy.getString(
"regularizationType");
184 int width = policy.getInt(
"kernelSize");
185 int height = policy.getInt(
"kernelSize");
186 float borderPenalty = policy.getDouble(
"regularizationBorderPenalty");
187 bool fitForBackground = policy.getBool(
"fitForBackground");
189 Eigen::MatrixXd bMat;
190 if (regularizationType ==
"centralDifference") {
191 int stencil = policy.getInt(
"centralRegularizationStencil");
194 else if (regularizationType ==
"forwardDifference") {
195 std::vector<int> orders = policy.getIntArray(
"forwardRegularizationOrders");
199 throw LSST_EXCEPT(pexExcept::Exception,
"regularizationType not recognized");
202 Eigen::MatrixXd hMat = bMat.transpose() * bMat;
214 bool fitForBackground
237 if (borderPenalty < 0)
238 throw LSST_EXCEPT(pexExcept::Exception,
"Only border penalty of >= 0 allowed");
240 std::vector<std::vector<float> >
241 coeffs(3, std::vector<float>(3,0));
258 else if (stencil == 9) {
260 coeffs[0][0] = 1. / 6.;
261 coeffs[0][1] = 4. / 6.;
262 coeffs[0][2] = 1. / 6.;
263 coeffs[1][0] = 4. / 6.;
264 coeffs[1][1] = -20. / 6.;
265 coeffs[1][2] = 4. / 6.;
266 coeffs[2][0] = 1. / 6.;
267 coeffs[2][1] = 4. / 6.;
268 coeffs[2][2] = 1. / 6.;
271 throw LSST_EXCEPT(pexExcept::Exception,
"Only 5- or 9-point Laplacian stencils allowed");
274 int nBgTerms = fitForBackground ? 1 : 0;
275 Eigen::MatrixXd bMat = Eigen::MatrixXd::Zero(width * height + nBgTerms, width * height + nBgTerms);
277 for (
int i = 0; i < width*height; i++) {
278 int const x0 = i % width;
279 int const y0 = i / width;
280 int const distX = width - x0 - 1;
281 int const distY = height - y0 - 1;
283 if ( (x0 > 0) && (y0 > 0) && (distX > 0) && (distY > 0) ) {
284 for (
int dx = -1; dx < 2; dx += 1) {
285 for (
int dy = -1; dy < 2; dy += 1) {
286 bMat(i, i + dx + dy * width) += coeffs[dx+1][dy+1];
291 bMat(i, i) = borderPenalty;
295 if (fitForBackground) {
297 if (bMat.col(width*height).sum() != 0.) {
298 throw LSST_EXCEPT(pexExcept::Exception,
"Error 1 in regularization matrix");
300 if (bMat.row(width*height).sum() != 0.) {
301 throw LSST_EXCEPT(pexExcept::Exception,
"Error 2 in regularization matrix");
314 std::vector<int>
const& orders,
316 bool fitForBackground
335 if (borderPenalty < 0)
336 throw LSST_EXCEPT(pexExcept::Exception,
"Only border penalty of >= 0 allowed");
338 std::vector<std::vector<float> >
339 coeffs(4, std::vector<float>(4,0));
342 coeffs[0][0] = borderPenalty;
359 int nBgTerms = fitForBackground ? 1 : 0;
360 Eigen::MatrixXd bTot = Eigen::MatrixXd::Zero(width * height + nBgTerms, width * height + nBgTerms);
362 std::vector<int>::const_iterator order;
363 for (order = orders.begin(); order != orders.end(); order++) {
364 if ((*order < 1) || (*order > 3))
365 throw LSST_EXCEPT(pexExcept::Exception,
"Only orders 1..3 allowed");
367 Eigen::MatrixXd bMatX = Eigen::MatrixXd::Zero(width * height + nBgTerms,
368 width * height + nBgTerms);
369 Eigen::MatrixXd bMatY = Eigen::MatrixXd::Zero(width * height + nBgTerms,
370 width * height + nBgTerms);
372 for (
int i = 0; i < width*height; i++) {
373 int const x0 = i % width;
374 int const y0 = i / width;
376 int distX = width - x0 - 1;
377 int orderToUseX = std::min(distX, *order);
378 for (
int j = 0; j < orderToUseX+1; j++) {
379 bMatX(i, i + j) = coeffs[orderToUseX][j];
382 int distY = height - y0 - 1;
383 int orderToUseY = std::min(distY, *order);
384 for (
int j = 0; j < orderToUseY+1; j++) {
385 bMatY(i, i + j * width) = coeffs[orderToUseY][j];
392 if (fitForBackground) {
394 if (bTot.col(width*height).sum() != 0.) {
395 throw LSST_EXCEPT(pexExcept::Exception,
"Error in regularization matrix");
397 if (bTot.row(width*height).sum() != 0.) {
398 throw LSST_EXCEPT(pexExcept::Exception,
"Error in regularization matrix");
413 lsst::afw::math::KernelList
415 lsst::afw::math::KernelList
const &kernelListIn
417 typedef afwMath::Kernel::Pixel Pixel;
418 typedef afwImage::Image<Pixel> Image;
444 afwMath::KernelList kernelListOut;
445 if (kernelListIn.size() == 0) {
446 return kernelListOut;
449 Image image0(kernelListIn[0]->getDimensions());
450 for (
unsigned int i = 0; i < kernelListIn.size(); i++) {
453 (void)kernelListIn[i]->computeImage(image0,
true);
454 std::shared_ptr<afwMath::Kernel>
455 kernelPtr(
new afwMath::FixedKernel(image0));
456 kernelListOut.push_back(kernelPtr);
462 Image image(kernelListIn[i]->getDimensions());
463 (void)kernelListIn[i]->computeImage(image,
false);
468 for (
int y = 0; y < image.getHeight(); y++) {
469 for (Image::xy_locator ptr = image.xy_at(0, y), end = image.xy_at(image.getWidth(), y);
470 ptr != end; ++ptr.x()) {
481 if (fabs(kSum) > std::numeric_limits<float>::epsilon()) {
488 for (
int y = 0; y < image.getHeight(); y++) {
489 for (Image::xy_locator ptr = image.xy_at(0, y), end = image.xy_at(image.getWidth(), y);
490 ptr != end; ++ptr.x()) {
494 image /= std::sqrt(kSum);
497 std::shared_ptr<afwMath::Kernel>
498 kernelPtr(
new afwMath::FixedKernel(image));
499 kernelListOut.push_back(kernelPtr);
501 return kernelListOut;
513 unsigned int boundary_style,
514 unsigned int difference_style,
518 if (order > 2)
throw LSST_EXCEPT(pexExcept::Exception,
"Only orders 0..2 allowed");
520 if (boundary_style > 2) {
521 throw LSST_EXCEPT(pexExcept::Exception,
"Boundary styles 0..2 defined");
523 if (difference_style > 1) {
524 throw LSST_EXCEPT(pexExcept::Exception,
"Only forward(0), and central(1) difference types defined");
557 std::vector<std::vector<std::vector<float> > >
558 coeffs(3, std::vector<std::vector<float> >(5, std::vector<float>(5,0)));
559 unsigned int x_cen = 0, y_cen = 0;
560 unsigned int x_cen1 = 0, y_cen1 = 0;
561 unsigned int x_cen2 = 0, y_cen2 = 0;
562 unsigned int x_size = 0, y_size = 0;
565 if (difference_style == 0) {
571 x_size = y_size = order + 2;
575 coeffs[0][0][0] = -2;
581 coeffs[1][0][0] = -2;
583 coeffs[1][0][2] = -1;
587 coeffs[1][2][0] = -1;
592 coeffs[2][0][0] = -2;
594 coeffs[2][0][2] = -3;
600 coeffs[2][2][0] = -3;
611 if (difference_style == 1) {
620 coeffs[0][0][1] = -1;
623 coeffs[0][1][0] = -1;
644 coeffs[1][1][1] = -4;
661 coeffs[2][0][2] = -1;
671 coeffs[2][2][0] = -1;
674 coeffs[2][2][3] = -2;
679 coeffs[2][3][2] = -2;
693 Eigen::MatrixXd bMat = Eigen::MatrixXd::Zero(width*height+1, width*height+1);
696 for (
unsigned int i = 0; i < width*height; i++) {
698 unsigned int const x0 = i % width;
699 unsigned int const y0 = i / width;
701 unsigned int x_edge_distance = (x0 > (width - x0 - 1)) ? width - x0 - 1 : x0;
702 unsigned int y_edge_distance = (y0 > (height - y0 - 1)) ? height - y0 - 1 : y0;
703 unsigned int edge_distance = (x_edge_distance < y_edge_distance) ? x_edge_distance :
706 for (
unsigned int dx = 0; dx < x_size; dx++) {
707 for (
unsigned int dy = 0; dy < y_size; dy++) {
715 double this_coeff = 0;
718 if (boundary_style == 0) {
721 if (y > height - 1 || x > width - 1) {
724 this_coeff = coeffs[order][dx][dy];
727 }
else if (boundary_style == 1) {
728 x = (width + x0 + dx - x_cen) % width;
729 y = (height + y0 + dy - y_cen) % height;
730 this_coeff = coeffs[order][dx][dy];
734 }
else if (boundary_style == 2) {
737 if (edge_distance == 0) {
743 else if (edge_distance == 1 && order > 0) {
744 x = (width + x0 + dx - x_cen1) % width;
745 y = (height + y0 + dy - y_cen1) % height;
746 if ((dx < 3) && (dy < 3)) { this_coeff = coeffs[1][dx][dy]; }
749 else if (edge_distance == 2 && order > 1){
750 x = (width + x0 + dx - x_cen2) % width;
751 y = (height + y0 + dy - y_cen2) % height;
752 if ((dx < 5) && (dy < 5)) { this_coeff = coeffs[2][dx][dy]; }
755 else if (edge_distance > order) {
756 x = (width + x0 + dx - x_cen) % width;
757 y = (height + y0 + dy - y_cen) % height;
758 this_coeff = coeffs[order][dx][dy];
763 bMat(i, y*width + x) = this_coeff;
772 std::cout << bMat << std::endl;
775 Eigen::MatrixXd hMat = bMat.transpose() * bMat;
lsst::afw::math::KernelList renormalizeKernelList(lsst::afw::math::KernelList const &kernelListIn)
Renormalize a list of basis kernels.
Eigen::MatrixXd makeForwardDifferenceMatrix(int width, int height, std::vector< int > const &orders, float borderPenalty, bool fitForBackground)
Build a forward difference regularization matrix for Delta function kernels.
Eigen::MatrixXd makeRegularizationMatrix(lsst::pex::policy::Policy policy)
Build a regularization matrix for Delta function kernels.
Eigen::MatrixXd makeCentralDifferenceMatrix(int width, int height, int stencil, float borderPenalty, bool fitForBackground)
Build a central difference Laplacian regularization matrix for Delta function kernels.
Eigen::MatrixXd makeFiniteDifferenceRegularizationDeprecated(unsigned int width, unsigned int height, unsigned int order, unsigned int boundary_style, unsigned int difference_style, bool printB)
Generate regularization matrix for delta function kernels.
lsst::afw::math::KernelList makeDeltaFunctionBasisList(int width, int height)
Build a set of Delta Function basis kernels.
Subroutines associated with generating, normalising, and regularising Basis functions.
lsst::afw::math::KernelList makeAlardLuptonBasisList(int halfWidth, int nGauss, std::vector< double > const &sigGauss, std::vector< int > const °Gauss)
Build a set of Alard/Lupton basis kernels.