LSST Applications  21.0.0-147-g0e635eb1+1acddb5be5,22.0.0+052faf71bd,22.0.0+1ea9a8b2b2,22.0.0+6312710a6c,22.0.0+729191ecac,22.0.0+7589c3a021,22.0.0+9f079a9461,22.0.1-1-g7d6de66+b8044ec9de,22.0.1-1-g87000a6+536b1ee016,22.0.1-1-g8e32f31+6312710a6c,22.0.1-10-gd060f87+016f7cdc03,22.0.1-12-g9c3108e+df145f6f68,22.0.1-16-g314fa6d+c825727ab8,22.0.1-19-g93a5c75+d23f2fb6d8,22.0.1-19-gb93eaa13+aab3ef7709,22.0.1-2-g8ef0a89+b8044ec9de,22.0.1-2-g92698f7+9f079a9461,22.0.1-2-ga9b0f51+052faf71bd,22.0.1-2-gac51dbf+052faf71bd,22.0.1-2-gb66926d+6312710a6c,22.0.1-2-gcb770ba+09e3807989,22.0.1-20-g32debb5+b8044ec9de,22.0.1-23-gc2439a9a+fb0756638e,22.0.1-3-g496fd5d+09117f784f,22.0.1-3-g59f966b+1e6ba2c031,22.0.1-3-g849a1b8+f8b568069f,22.0.1-3-gaaec9c0+c5c846a8b1,22.0.1-32-g5ddfab5d3+60ce4897b0,22.0.1-4-g037fbe1+64e601228d,22.0.1-4-g8623105+b8044ec9de,22.0.1-5-g096abc9+d18c45d440,22.0.1-5-g15c806e+57f5c03693,22.0.1-7-gba73697+57f5c03693,master-g6e05de7fdc+c1283a92b8,master-g72cdda8301+729191ecac,w.2021.39
LSST Data Management Base Package
WarpAtOnePoint.h
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 #include <vector>
25 
26 #include "lsst/afw/math/Kernel.h"
27 #include "lsst/afw/image/Image.h"
29 #include "lsst/geom/Point.h"
30 
31 namespace lsst {
32 namespace afw {
33 namespace math {
34 namespace detail {
35 
39 template <typename DestImageT, typename SrcImageT>
41 public:
42  WarpAtOnePoint(SrcImageT const &srcImage, WarpingControl const &control,
43  typename DestImageT::SinglePixel padValue)
44  : _srcImage(srcImage),
45  _kernelPtr(control.getWarpingKernel()),
46  _maskKernelPtr(control.getMaskWarpingKernel()),
47  _hasMaskKernel(control.getMaskWarpingKernel()),
48  _kernelCtr(_kernelPtr->getCtr()),
49  _maskKernelCtr(_maskKernelPtr ? _maskKernelPtr->getCtr() : lsst::geom::Point2I(0, 0)),
50  _growFullMask(control.getGrowFullMask()),
51  _xList(_kernelPtr->getWidth()),
52  _yList(_kernelPtr->getHeight()),
53  _maskXList(_maskKernelPtr ? _maskKernelPtr->getWidth() : 0),
54  _maskYList(_maskKernelPtr ? _maskKernelPtr->getHeight() : 0),
55  _padValue(padValue),
56  _srcGoodBBox(_kernelPtr->shrinkBBox(srcImage.getBBox(lsst::afw::image::LOCAL))){};
57 
63  bool operator()(typename DestImageT::x_iterator &destXIter, lsst::geom::Point2D const &srcPos,
64  double relativeArea, lsst::afw::image::detail::Image_tag) {
65  // Compute associated source pixel index as integer and nonnegative fractional parts;
66  // the latter is used to compute the remapping kernel.
67  std::pair<int, double> srcIndFracX = _srcImage.positionToIndex(srcPos[0], lsst::afw::image::X);
68  std::pair<int, double> srcIndFracY = _srcImage.positionToIndex(srcPos[1], lsst::afw::image::Y);
69  if (srcIndFracX.second < 0) {
70  ++srcIndFracX.second;
71  --srcIndFracX.first;
72  }
73  if (srcIndFracY.second < 0) {
74  ++srcIndFracY.second;
75  --srcIndFracY.first;
76  }
77 
78  if (_srcGoodBBox.contains(lsst::geom::Point2I(srcIndFracX.first, srcIndFracY.first))) {
79  // Offset source pixel index from kernel center to kernel corner (0, 0)
80  // so we can convolveAtAPoint the pixels that overlap between source and kernel
81  int srcStartX = srcIndFracX.first - _kernelCtr[0];
82  int srcStartY = srcIndFracY.first - _kernelCtr[1];
83 
84  // Compute warped pixel
85  double kSum = _setFracIndex(srcIndFracX.second, srcIndFracY.second);
86 
87  typename SrcImageT::const_xy_locator srcLoc = _srcImage.xy_at(srcStartX, srcStartY);
88 
89  *destXIter = lsst::afw::math::convolveAtAPoint<DestImageT, SrcImageT>(srcLoc, _xList, _yList);
90  *destXIter *= relativeArea / kSum;
91  return true;
92  } else {
93  // Edge pixel
94  *destXIter = _padValue;
95  return false;
96  }
97  }
98 
105  bool operator()(typename DestImageT::x_iterator &destXIter, lsst::geom::Point2D const &srcPos,
106  double relativeArea, lsst::afw::image::detail::MaskedImage_tag) {
107  // Compute associated source pixel index as integer and nonnegative fractional parts;
108  // the latter is used to compute the remapping kernel.
109  std::pair<int, double> srcIndFracX = _srcImage.positionToIndex(srcPos[0], lsst::afw::image::X);
110  std::pair<int, double> srcIndFracY = _srcImage.positionToIndex(srcPos[1], lsst::afw::image::Y);
111  if (srcIndFracX.second < 0) {
112  ++srcIndFracX.second;
113  --srcIndFracX.first;
114  }
115  if (srcIndFracY.second < 0) {
116  ++srcIndFracY.second;
117  --srcIndFracY.first;
118  }
119 
120  if (_srcGoodBBox.contains(lsst::geom::Point2I(srcIndFracX.first, srcIndFracY.first))) {
121  // Offset source pixel index from kernel center to kernel corner (0, 0)
122  // so we can convolveAtAPoint the pixels that overlap between source and kernel
123  int srcStartX = srcIndFracX.first - _kernelCtr[0];
124  int srcStartY = srcIndFracY.first - _kernelCtr[1];
125 
126  // Compute warped pixel
127  double kSum = _setFracIndex(srcIndFracX.second, srcIndFracY.second);
128 
129  typename SrcImageT::const_xy_locator srcLoc = _srcImage.xy_at(srcStartX, srcStartY);
130 
131  *destXIter = lsst::afw::math::convolveAtAPoint<DestImageT, SrcImageT>(srcLoc, _xList, _yList);
132  *destXIter *= relativeArea / kSum;
133 
134  if (_hasMaskKernel) {
135  // compute mask value based on the mask kernel (replacing the value computed above)
136  int maskStartX = srcIndFracX.first - _maskKernelCtr[0];
137  int maskStartY = srcIndFracY.first - _maskKernelCtr[1];
138 
139  typename SrcImageT::Mask::const_xy_locator srcMaskLoc =
140  _srcImage.getMask()->xy_at(maskStartX, maskStartY);
141 
143 
144  typename DestImageT::Mask::SinglePixel destMaskValue = 0;
145  for (double kValY : _maskYList) {
146  typename DestImageT::Mask::SinglePixel destMaskValueY = 0;
147  for (k_iter kernelXIter = _maskXList.begin(), xEnd = _maskXList.end();
148  kernelXIter != xEnd; ++kernelXIter, ++srcMaskLoc.x()) {
149  typename lsst::afw::math::Kernel::Pixel const kValX = *kernelXIter;
150  if (kValX != 0) {
151  destMaskValueY |= *srcMaskLoc;
152  }
153  }
154 
155  if (kValY != 0) {
156  destMaskValue |= destMaskValueY;
157  }
158 
159  srcMaskLoc += lsst::afw::image::detail::difference_type(-_maskXList.size(), 1);
160  }
161 
162  destXIter.mask() = (destXIter.mask() & _growFullMask) | destMaskValue;
163  }
164  return true;
165  } else {
166  // Edge pixel
167  *destXIter = _padValue;
168  return false;
169  }
170  }
171 
172 private:
178  double _setFracIndex(double xFrac, double yFrac) {
179  std::pair<double, double> srcFracInd(xFrac, yFrac);
180  _kernelPtr->setKernelParameters(srcFracInd);
181  double kSum = _kernelPtr->computeVectors(_xList, _yList, false);
182  if (_maskKernelPtr) {
183  _maskKernelPtr->setKernelParameters(srcFracInd);
184  _maskKernelPtr->computeVectors(_maskXList, _maskYList, false);
185  }
186  return kSum;
187  }
188 
189  SrcImageT _srcImage;
192  bool _hasMaskKernel;
193  lsst::geom::Point2I _kernelCtr;
194  lsst::geom::Point2I _maskKernelCtr;
195  lsst::afw::image::MaskPixel _growFullMask;
196  std::vector<double> _xList;
197  std::vector<double> _yList;
198  std::vector<double> _maskXList;
199  std::vector<double> _maskYList;
200  typename DestImageT::SinglePixel _padValue;
201  lsst::geom::Box2I const _srcGoodBBox;
202 };
203 } // namespace detail
204 } // namespace math
205 } // namespace afw
206 } // namespace lsst
T begin(T... args)
void setKernelParameters(std::vector< double > const &params)
Set the kernel parameters of a spatially invariant kernel.
Definition: Kernel.h:341
double computeVectors(std::vector< Pixel > &colList, std::vector< Pixel > &rowList, bool doNormalize, double x=0.0, double y=0.0) const
Compute the column and row arrays in place, where kernel(col, row) = colList(col) * rowList(row)
Parameters to control convolution.
Definition: warpExposure.h:276
A functor that computes one warped pixel.
bool operator()(typename DestImageT::x_iterator &destXIter, lsst::geom::Point2D const &srcPos, double relativeArea, lsst::afw::image::detail::Image_tag)
Compute one warped pixel, Image specialization.
bool operator()(typename DestImageT::x_iterator &destXIter, lsst::geom::Point2D const &srcPos, double relativeArea, lsst::afw::image::detail::MaskedImage_tag)
Compute one warped pixel, MaskedImage specialization.
WarpAtOnePoint(SrcImageT const &srcImage, WarpingControl const &control, typename DestImageT::SinglePixel padValue)
An integer coordinate rectangle.
Definition: Box.h:55
bool contains(Point2I const &point) const noexcept
Return true if the box contains the point.
Definition: Box.cc:114
T end(T... args)
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
class[[deprecated("Removed with no replacement (but see lsst::afw::image::TransmissionCurve). Will be " "removed after v22.")]] FilterProperty final
Describe the properties of a Filter (e.g.
Definition: Filter.h:53
Point< int, 2 > Point2I
Definition: Point.h:321
A base class for image defects.
T size(T... args)
A traits class for MaskedImage.
Definition: MaskedImage.h:50