lsst.afw  v23.0.x-g89e8071bfa+60ce4897b0
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 <sstream>
29 #include <vector>
30 
31 
32 #include "lsst/pex/exceptions.h"
33 #include "lsst/log/Log.h"
34 #include "lsst/geom.h"
37 
39 
40 namespace lsst {
41 namespace afw {
42 namespace math {
43 namespace detail {
44 
46  lsst::geom::Point2I const &xy0, bool doNormalize)
47  : _kernelPtr(kernelPtr), _bbox(bbox), _xy0(xy0), _doNormalize(doNormalize), _imagePtrList(4) {
48  if (!_kernelPtr) {
49  throw LSST_EXCEPT(pexExcept::InvalidParameterError, "kernelPtr is null");
50  }
51  LOGL_DEBUG("TRACE5.afw.math.convolve.KernelImagesForRegion",
52  "KernelImagesForRegion(bbox(minimum=(%d, %d), extent=(%d, %d)), xy0=(%d, %d), doNormalize=%d, "
53  "images...)",
54  _bbox.getMinX(), _bbox.getMinY(), _bbox.getWidth(), _bbox.getHeight(), _xy0[0], _xy0[1],
55  _doNormalize);
56 }
57 
59  lsst::geom::Point2I const &xy0, bool doNormalize,
60  ImagePtr bottomLeftImagePtr, ImagePtr bottomRightImagePtr,
61  ImagePtr topLeftImagePtr, ImagePtr topRightImagePtr)
62  : _kernelPtr(kernelPtr), _bbox(bbox), _xy0(xy0), _doNormalize(doNormalize), _imagePtrList(4) {
63  if (!_kernelPtr) {
64  throw LSST_EXCEPT(pexExcept::InvalidParameterError, "kernelPtr is null");
65  }
66  _insertImage(BOTTOM_LEFT, bottomLeftImagePtr);
67  _insertImage(BOTTOM_RIGHT, bottomRightImagePtr);
68  _insertImage(TOP_LEFT, topLeftImagePtr);
69  _insertImage(TOP_RIGHT, topRightImagePtr);
70  LOGL_DEBUG("TRACE5.afw.math.convolve.KernelImagesForRegion",
71  "KernelImagesForRegion(bbox(minimum=(%d, %d), extent=(%d, %d)), xy0=(%d, %d), doNormalize=%d, "
72  "images...)",
73  _bbox.getMinX(), _bbox.getMinY(), _bbox.getWidth(), _bbox.getHeight(), _xy0[0], _xy0[1],
74  _doNormalize);
75 }
76 
78  if (_imagePtrList[location]) {
79  return _imagePtrList[location];
80  }
81 
82  ImagePtr imagePtr(new Image(_kernelPtr->getDimensions()));
83  _imagePtrList[location] = imagePtr;
84  _computeImage(location);
85  return imagePtr;
86 }
87 
89  switch (location) {
90  case BOTTOM_LEFT:
91  return _bbox.getMin();
92  break; // paranoia
93  case BOTTOM_RIGHT:
94  return lsst::geom::Point2I(_bbox.getMaxX() + 1, _bbox.getMinY());
95  break; // paranoia
96  case TOP_LEFT:
97  return lsst::geom::Point2I(_bbox.getMinX(), _bbox.getMaxY() + 1);
98  break; // paranoia
99  case TOP_RIGHT:
100  return lsst::geom::Point2I(_bbox.getMaxX() + 1, _bbox.getMaxY() + 1);
101  break; // paranoia
102  default: {
104  os << "Bug: unhandled location = " << location;
106  }
107  }
108 }
109 
111  if (regionRow.isLastRow()) {
112  return false;
113  }
114 
115  bool hasData = regionRow.hasData();
116  int startY;
117  if (hasData) {
118  startY = regionRow.front()->getBBox().getMaxY() + 1;
119  } else {
120  startY = this->_bbox.getMinY();
121  }
122 
123  int yInd = regionRow.incrYInd();
124  int remHeight = 1 + this->_bbox.getMaxY() - startY;
125  int remYDiv = regionRow.getNY() - yInd;
126  int height = _computeNextSubregionLength(remHeight, remYDiv);
127 
128  if (hasData) {
129  // Move each region up one segment
130  bool isFirst = true;
131  for (auto & rgnIter : regionRow) {
132  rgnIter->_moveUp(isFirst, height);
133  isFirst = false;
134  }
135 
136  } else {
137  ImagePtr blImagePtr = getImage(BOTTOM_LEFT);
138  ImagePtr brImagePtr;
139  ImagePtr tlImagePtr;
140  ImagePtr const trImageNullPtr;
141 
142  lsst::geom::Point2I blCorner = lsst::geom::Point2I(this->_bbox.getMinX(), startY);
143 
144  int remWidth = this->_bbox.getWidth();
145  int remXDiv = regionRow.getNX();
146  for (auto & rgnIter : regionRow) {
147  int width = _computeNextSubregionLength(remWidth, remXDiv);
148  --remXDiv;
149  remWidth -= width;
150 
152  _kernelPtr, lsst::geom::Box2I(blCorner, lsst::geom::Extent2I(width, height)), _xy0,
153  _doNormalize, blImagePtr, brImagePtr, tlImagePtr, trImageNullPtr));
154  rgnIter = regionPtr;
155 
156  if (!tlImagePtr) {
157  regionPtr->getImage(TOP_LEFT);
158  }
159 
160  blCorner += lsst::geom::Extent2I(width, 0);
161  blImagePtr = regionPtr->getImage(BOTTOM_RIGHT);
162  tlImagePtr = regionPtr->getImage(TOP_RIGHT);
163  }
164  }
165  return true;
166 }
167 
168 void KernelImagesForRegion::_computeImage(Location location) const {
169  ImagePtr imagePtr = _imagePtrList[location];
170  if (!imagePtr) {
172  os << "Null imagePtr at location " << location;
174  }
175 
176  lsst::geom::Point2I pixelIndex = getPixelIndex(location);
177  _kernelPtr->computeImage(*imagePtr, _doNormalize, image::indexToPosition(pixelIndex.getX() + _xy0[0]),
178  image::indexToPosition(pixelIndex.getY() + _xy0[1]));
179 }
180 
181 std::vector<int> KernelImagesForRegion::_computeSubregionLengths(int length, int nDivisions) {
182  if ((nDivisions > length) || (nDivisions < 1)) {
184  os << "nDivisions = " << nDivisions << " not in range [1, " << length << " = length]";
186  }
187  std::vector<int> regionLengths;
188  int remLength = length;
189  for (int remNDiv = nDivisions; remNDiv > 0; --remNDiv) {
190  int subLength = _computeNextSubregionLength(remLength, remNDiv);
191  if (subLength < 1) {
193  os << "Bug! _computeSubregionLengths(length=" << length << ", nDivisions=" << nDivisions
194  << ") computed sublength = " << subLength << " < 0; remLength = " << remLength;
195  throw LSST_EXCEPT(pexExcept::RuntimeError, os.str());
196  }
197  regionLengths.push_back(subLength);
198  remLength -= subLength;
199  }
200  return regionLengths;
201 }
202 
203 void KernelImagesForRegion::_moveUp(bool isFirst, int newHeight) {
204  // move bbox up (this must be done before recomputing the top kernel images)
205  _bbox = lsst::geom::Box2I(lsst::geom::Point2I(_bbox.getMinX(), _bbox.getMaxY() + 1),
206  lsst::geom::Extent2I(_bbox.getWidth(), newHeight));
207 
208  // swap top and bottom image pointers
209  _imagePtrList[BOTTOM_RIGHT].swap(_imagePtrList[TOP_RIGHT]);
210  _imagePtrList[BOTTOM_LEFT].swap(_imagePtrList[TOP_LEFT]);
211 
212  // recompute top right, and if the first image also recompute top left
213  _computeImage(TOP_RIGHT);
214  if (isFirst) {
215  _computeImage(TOP_LEFT);
216  }
217 }
218 
219 int const KernelImagesForRegion::_MinInterpolationSize = 10;
220 
222  : _nx(nx), _ny(ny), _yInd(-1), _regionList(nx) {
223  if ((nx < 1) || (ny < 1)) {
225  os << "nx = " << nx << " and/or ny = " << ny << " < 1";
227  };
228 }
229 } // namespace detail
230 } // namespace math
231 } // namespace afw
232 } // namespace lsst
AmpInfoBoxKey bbox
Definition: Amplifier.cc:117
#define LSST_EXCEPT(type,...)
#define LOGL_DEBUG(logger, message...)
std::ostream * os
Definition: Schema.cc:557
lsst::geom::Extent2I const getDimensions() const
Return the Kernel's dimensions (width, height)
Definition: Kernel.h:212
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:76
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
int getMinY() const noexcept
int getHeight() const noexcept
Point2I const getMin() const noexcept
int getMinX() const noexcept
int getWidth() const noexcept
int getMaxX() const noexcept
int getMaxY() const noexcept
def length(self)
double indexToPosition(double ind)
Convert image index to image position.
Definition: ImageUtils.h:55
Extent< int, 2 > Extent2I
Point< int, 2 > Point2I
A base class for image defects.
T push_back(T... args)