LSST Applications  21.0.0+04719a4bac,21.0.0-1-ga51b5d4+f5e6047307,21.0.0-11-g2b59f77+a9c1acf22d,21.0.0-11-ga42c5b2+86977b0b17,21.0.0-12-gf4ce030+76814010d2,21.0.0-13-g1721dae+760e7a6536,21.0.0-13-g3a573fe+768d78a30a,21.0.0-15-g5a7caf0+f21cbc5713,21.0.0-16-g0fb55c1+b60e2d390c,21.0.0-19-g4cded4ca+71a93a33c0,21.0.0-2-g103fe59+bb20972958,21.0.0-2-g45278ab+04719a4bac,21.0.0-2-g5242d73+3ad5d60fb1,21.0.0-2-g7f82c8f+8babb168e8,21.0.0-2-g8f08a60+06509c8b61,21.0.0-2-g8faa9b5+616205b9df,21.0.0-2-ga326454+8babb168e8,21.0.0-2-gde069b7+5e4aea9c2f,21.0.0-2-gecfae73+1d3a86e577,21.0.0-2-gfc62afb+3ad5d60fb1,21.0.0-25-g1d57be3cd+e73869a214,21.0.0-3-g357aad2+ed88757d29,21.0.0-3-g4a4ce7f+3ad5d60fb1,21.0.0-3-g4be5c26+3ad5d60fb1,21.0.0-3-g65f322c+e0b24896a3,21.0.0-3-g7d9da8d+616205b9df,21.0.0-3-ge02ed75+a9c1acf22d,21.0.0-4-g591bb35+a9c1acf22d,21.0.0-4-g65b4814+b60e2d390c,21.0.0-4-gccdca77+0de219a2bc,21.0.0-4-ge8a399c+6c55c39e83,21.0.0-5-gd00fb1e+05fce91b99,21.0.0-6-gc675373+3ad5d60fb1,21.0.0-64-g1122c245+4fb2b8f86e,21.0.0-7-g04766d7+cd19d05db2,21.0.0-7-gdf92d54+04719a4bac,21.0.0-8-g5674e7b+d1bd76f71f,master-gac4afde19b+a9c1acf22d,w.2021.13
LSST Data Management Base Package
KernelImagesForRegion.cc
Go to the documentation of this file.
1 // -*- LSST-C++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2008, 2009, 2010 LSST Corporation.
6  *
7  * This product includes software developed by the
8  * LSST Project (http://www.lsst.org/).
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the LSST License Statement and
21  * the GNU General Public License along with this program. If not,
22  * see <http://www.lsstcorp.org/LegalNotices/>.
23  */
24 
25 /*
26  * Definition of KernelImagesForRegion class declared in detail/ConvolveImage.h
27  */
28 #include <algorithm>
29 #include <cmath>
30 #include <iostream>
31 #include <sstream>
32 #include <vector>
33 
34 #include "boost/assign/list_of.hpp"
35 
36 #include "lsst/pex/exceptions.h"
37 #include "lsst/log/Log.h"
38 #include "lsst/geom.h"
41 
43 
44 namespace lsst {
45 namespace afw {
46 namespace math {
47 namespace detail {
48 
50  lsst::geom::Point2I const &xy0, bool doNormalize)
51  : _kernelPtr(kernelPtr), _bbox(bbox), _xy0(xy0), _doNormalize(doNormalize), _imagePtrList(4) {
52  if (!_kernelPtr) {
53  throw LSST_EXCEPT(pexExcept::InvalidParameterError, "kernelPtr is null");
54  }
55  LOGL_DEBUG("TRACE5.afw.math.convolve.KernelImagesForRegion",
56  "KernelImagesForRegion(bbox(minimum=(%d, %d), extent=(%d, %d)), xy0=(%d, %d), doNormalize=%d, "
57  "images...)",
58  _bbox.getMinX(), _bbox.getMinY(), _bbox.getWidth(), _bbox.getHeight(), _xy0[0], _xy0[1],
59  _doNormalize);
60 }
61 
63  lsst::geom::Point2I const &xy0, bool doNormalize,
64  ImagePtr bottomLeftImagePtr, ImagePtr bottomRightImagePtr,
65  ImagePtr topLeftImagePtr, ImagePtr topRightImagePtr)
66  : _kernelPtr(kernelPtr), _bbox(bbox), _xy0(xy0), _doNormalize(doNormalize), _imagePtrList(4) {
67  if (!_kernelPtr) {
68  throw LSST_EXCEPT(pexExcept::InvalidParameterError, "kernelPtr is null");
69  }
70  _insertImage(BOTTOM_LEFT, bottomLeftImagePtr);
71  _insertImage(BOTTOM_RIGHT, bottomRightImagePtr);
72  _insertImage(TOP_LEFT, topLeftImagePtr);
73  _insertImage(TOP_RIGHT, topRightImagePtr);
74  LOGL_DEBUG("TRACE5.afw.math.convolve.KernelImagesForRegion",
75  "KernelImagesForRegion(bbox(minimum=(%d, %d), extent=(%d, %d)), xy0=(%d, %d), doNormalize=%d, "
76  "images...)",
77  _bbox.getMinX(), _bbox.getMinY(), _bbox.getWidth(), _bbox.getHeight(), _xy0[0], _xy0[1],
78  _doNormalize);
79 }
80 
82  if (_imagePtrList[location]) {
83  return _imagePtrList[location];
84  }
85 
86  ImagePtr imagePtr(new Image(_kernelPtr->getDimensions()));
87  _imagePtrList[location] = imagePtr;
88  _computeImage(location);
89  return imagePtr;
90 }
91 
93  switch (location) {
94  case BOTTOM_LEFT:
95  return _bbox.getMin();
96  break; // paranoia
97  case BOTTOM_RIGHT:
98  return lsst::geom::Point2I(_bbox.getMaxX() + 1, _bbox.getMinY());
99  break; // paranoia
100  case TOP_LEFT:
101  return lsst::geom::Point2I(_bbox.getMinX(), _bbox.getMaxY() + 1);
102  break; // paranoia
103  case TOP_RIGHT:
104  return lsst::geom::Point2I(_bbox.getMaxX() + 1, _bbox.getMaxY() + 1);
105  break; // paranoia
106  default: {
108  os << "Bug: unhandled location = " << location;
110  }
111  }
112 }
113 
115  if (regionRow.isLastRow()) {
116  return false;
117  }
118 
119  bool hasData = regionRow.hasData();
120  int startY;
121  if (hasData) {
122  startY = regionRow.front()->getBBox().getMaxY() + 1;
123  } else {
124  startY = this->_bbox.getMinY();
125  }
126 
127  int yInd = regionRow.incrYInd();
128  int remHeight = 1 + this->_bbox.getMaxY() - startY;
129  int remYDiv = regionRow.getNY() - yInd;
130  int height = _computeNextSubregionLength(remHeight, remYDiv);
131 
132  if (hasData) {
133  // Move each region up one segment
134  bool isFirst = true;
135  for (RowOfKernelImagesForRegion::Iterator rgnIter = regionRow.begin(), rgnEnd = regionRow.end();
136  rgnIter != rgnEnd; ++rgnIter) {
137  (*rgnIter)->_moveUp(isFirst, height);
138  isFirst = false;
139  }
140 
141  } else {
142  ImagePtr blImagePtr = getImage(BOTTOM_LEFT);
143  ImagePtr brImagePtr;
144  ImagePtr tlImagePtr;
145  ImagePtr const trImageNullPtr;
146 
147  lsst::geom::Point2I blCorner = lsst::geom::Point2I(this->_bbox.getMinX(), startY);
148 
149  int remWidth = this->_bbox.getWidth();
150  int remXDiv = regionRow.getNX();
151  for (RowOfKernelImagesForRegion::Iterator rgnIter = regionRow.begin(), rgnEnd = regionRow.end();
152  rgnIter != rgnEnd; ++rgnIter) {
153  int width = _computeNextSubregionLength(remWidth, remXDiv);
154  --remXDiv;
155  remWidth -= width;
156 
158  _kernelPtr, lsst::geom::Box2I(blCorner, lsst::geom::Extent2I(width, height)), _xy0,
159  _doNormalize, blImagePtr, brImagePtr, tlImagePtr, trImageNullPtr));
160  *rgnIter = regionPtr;
161 
162  if (!tlImagePtr) {
163  regionPtr->getImage(TOP_LEFT);
164  }
165 
166  blCorner += lsst::geom::Extent2I(width, 0);
167  blImagePtr = regionPtr->getImage(BOTTOM_RIGHT);
168  tlImagePtr = regionPtr->getImage(TOP_RIGHT);
169  }
170  }
171  return true;
172 }
173 
174 void KernelImagesForRegion::_computeImage(Location location) const {
175  ImagePtr imagePtr = _imagePtrList[location];
176  if (!imagePtr) {
178  os << "Null imagePtr at location " << location;
180  }
181 
182  lsst::geom::Point2I pixelIndex = getPixelIndex(location);
183  _kernelPtr->computeImage(*imagePtr, _doNormalize, image::indexToPosition(pixelIndex.getX() + _xy0[0]),
184  image::indexToPosition(pixelIndex.getY() + _xy0[1]));
185 }
186 
187 std::vector<int> KernelImagesForRegion::_computeSubregionLengths(int length, int nDivisions) {
188  if ((nDivisions > length) || (nDivisions < 1)) {
190  os << "nDivisions = " << nDivisions << " not in range [1, " << length << " = length]";
192  }
193  std::vector<int> regionLengths;
194  int remLength = length;
195  for (int remNDiv = nDivisions; remNDiv > 0; --remNDiv) {
196  int subLength = _computeNextSubregionLength(remLength, remNDiv);
197  if (subLength < 1) {
199  os << "Bug! _computeSubregionLengths(length=" << length << ", nDivisions=" << nDivisions
200  << ") computed sublength = " << subLength << " < 0; remLength = " << remLength;
201  throw LSST_EXCEPT(pexExcept::RuntimeError, os.str());
202  }
203  regionLengths.push_back(subLength);
204  remLength -= subLength;
205  }
206  return regionLengths;
207 }
208 
209 void KernelImagesForRegion::_moveUp(bool isFirst, int newHeight) {
210  // move bbox up (this must be done before recomputing the top kernel images)
211  _bbox = lsst::geom::Box2I(lsst::geom::Point2I(_bbox.getMinX(), _bbox.getMaxY() + 1),
212  lsst::geom::Extent2I(_bbox.getWidth(), newHeight));
213 
214  // swap top and bottom image pointers
215  _imagePtrList[BOTTOM_RIGHT].swap(_imagePtrList[TOP_RIGHT]);
216  _imagePtrList[BOTTOM_LEFT].swap(_imagePtrList[TOP_LEFT]);
217 
218  // recompute top right, and if the first image also recompute top left
219  _computeImage(TOP_RIGHT);
220  if (isFirst) {
221  _computeImage(TOP_LEFT);
222  }
223 }
224 
225 int const KernelImagesForRegion::_MinInterpolationSize = 10;
226 
228  : _nx(nx), _ny(ny), _yInd(-1), _regionList(nx) {
229  if ((nx < 1) || (ny < 1)) {
231  os << "nx = " << nx << " and/or ny = " << ny << " < 1";
233  };
234 }
235 } // namespace detail
236 } // namespace math
237 } // namespace afw
238 } // namespace lsst
AmpInfoBoxKey bbox
Definition: Amplifier.cc:117
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
LSST DM logging module built on log4cxx.
#define LOGL_DEBUG(logger, message...)
Log a debug-level message using a varargs/printf style interface.
Definition: Log.h:504
std::ostream * os
Definition: Schema.cc:746
lsst::geom::Extent2I const getDimensions() const
Return the Kernel's dimensions (width, height)
Definition: Kernel.h:213
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.
Definition: Kernel.cc:85
Location
locations of various points in the region
Definition: Convolve.h:192
KernelImagesForRegion(KernelConstPtr kernelPtr, lsst::geom::Box2I const &bbox, lsst::geom::Point2I const &xy0, bool doNormalize)
Construct a KernelImagesForRegion.
bool computeNextRow(RowOfKernelImagesForRegion &regionRow) const
Compute next row of subregions.
lsst::geom::Point2I getPixelIndex(Location location) const
Compute pixel index of a given location, relative to the parent image (thus offset by bottom left cor...
ImagePtr getImage(Location location) const
Return the image and sum at the specified location.
lsst::afw::image::Image< lsst::afw::math::Kernel::Pixel > Image
Definition: Convolve.h:175
RowOfKernelImagesForRegion(int nx, int ny)
Construct a RowOfKernelImagesForRegion.
std::shared_ptr< KernelImagesForRegion > front()
Return the first region in the list.
Definition: Convolve.h:366
RegionList::const_iterator begin() const
Return the begin iterator for the list.
Definition: Convolve.h:350
RegionList::const_iterator end() const
Return the end iterator for the list.
Definition: Convolve.h:354
An integer coordinate rectangle.
Definition: Box.h:55
int getMinY() const noexcept
Definition: Box.h:158
int getHeight() const noexcept
Definition: Box.h:188
Point2I const getMin() const noexcept
Definition: Box.h:156
int getMinX() const noexcept
Definition: Box.h:157
int getWidth() const noexcept
Definition: Box.h:187
int getMaxX() const noexcept
Definition: Box.h:161
int getMaxY() const noexcept
Definition: Box.h:162
Reports invalid arguments.
Definition: Runtime.h:66
Reports attempts to access elements using an invalid key.
Definition: Runtime.h:151
Reports errors that are due to events beyond the control of the program.
Definition: Runtime.h:104
double indexToPosition(double ind)
Convert image index to image position.
Definition: ImageUtils.h:55
Extent< int, 2 > Extent2I
Definition: Extent.h:397
Point< int, 2 > Point2I
Definition: Point.h:321
A base class for image defects.
T push_back(T... args)