LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
Psf.cc
Go to the documentation of this file.
1 // -*- LSST-C++ -*-
2 #include <limits>
3 #include <cmath>
4 #include <memory>
5 
6 #include "lsst/utils/Cache.h"
10 
11 namespace lsst {
12 namespace afw {
13 
16 
17 namespace detection {
18 namespace detail {
19 
20 // Key for caching PSFs with lsst::utils::Cache
21 //
22 // We cache PSFs by their x,y position. Although there are placeholders
23 // in the `Psf` class and here for `image::Color`, these are not used
24 // in the cache because `image::Color` is not currently well-defined
25 // or used.
26 struct PsfCacheKey {
29 
31  : position(position_), color(color_) {}
32 
33  bool operator==(PsfCacheKey const &other) const {
34  return position == other.position; // Currently don't care about color
35  }
36 
37  friend std::ostream &operator<<(std::ostream &os, PsfCacheKey const &key) { return os << key.position; }
38 };
39 
40 } // namespace detail
41 } // namespace detection
42 } // namespace afw
43 } // namespace lsst
44 
45 namespace std {
46 
47 // Template specialisation for hashing PsfCacheKey
48 //
49 // We currently ignore the color, consistent with operator==.
50 template <>
55  return std::hash<lsst::geom::Point2D>()(key.position);
56  }
57 };
58 
59 } // namespace std
60 
61 namespace lsst {
62 namespace afw {
63 namespace detection {
64 
65 namespace {
66 
67 bool isPointNull(lsst::geom::Point2D const &p) { return std::isnan(p.getX()) && std::isnan(p.getY()); }
68 
69 } // namespace
70 
71 Psf::Psf(bool isFixed, std::size_t capacity) : _isFixed(isFixed) {
72  _imageCache = std::make_unique<PsfCache>(capacity);
73  _kernelImageCache = std::make_unique<PsfCache>(capacity);
74 }
75 
76 Psf::~Psf() = default;
77 
78 Psf::Psf(Psf const &other) : Psf(other._isFixed, other.getCacheCapacity()) {}
79 
80 Psf::Psf(Psf &&other)
81  : _isFixed(other._isFixed),
82  _imageCache(std::move(other._imageCache)),
83  _kernelImageCache(std::move(other._kernelImageCache)) {}
84 
86  lsst::geom::Point2D const &position,
87  std::string const &warpAlgorithm,
88  unsigned int warpBuffer) {
89  // "ir" : (integer, residual)
90  std::pair<int, double> const irX = image::positionToIndex(position.getX(), true);
91  std::pair<int, double> const irY = image::positionToIndex(position.getY(), true);
92 
93  if (irX.second != 0.0 || irY.second != 0.0) {
94  im = math::offsetImage(*im, irX.second, irY.second, warpAlgorithm, warpBuffer);
95  }
96 
97  im->setXY0(irX.first + im->getX0(), irY.first + im->getY0());
98  return im;
99 }
100 
102  return computeImage(makeNullPoint());
103 }
104 
106  ImageOwnerEnum owner) const {
107  if (isPointNull(position)) position = getAveragePosition();
108  if (color.isIndeterminate()) color = getAverageColor();
109  std::shared_ptr<Psf::Image> result = (*_imageCache)(
110  detail::PsfCacheKey(position, color),
111  [this](detail::PsfCacheKey const &key) { return doComputeImage(key.position, key.color); });
112  if (owner == COPY) {
113  result = std::make_shared<Image>(*result, true);
114  }
115  return result;
116 }
117 
119  return computeKernelImage(makeNullPoint());
120 }
121 
123  ImageOwnerEnum owner) const {
124  if (_isFixed || isPointNull(position)) position = getAveragePosition();
125  if (_isFixed || color.isIndeterminate()) color = getAverageColor();
126  std::shared_ptr<Psf::Image> result = (*_kernelImageCache)(
127  detail::PsfCacheKey(position, color),
128  [this](detail::PsfCacheKey const &key) { return doComputeKernelImage(key.position, key.color); });
129  if (owner == COPY) {
130  result = std::make_shared<Image>(*result, true);
131  }
132  return result;
133 }
134 
136  return computeBBox(makeNullPoint());
137 }
138 
140  if (isPointNull(position)) position = getAveragePosition();
141  if (color.isIndeterminate()) color = getAverageColor();
142  return doComputeBBox(position, color);
143 }
144 
146  return computeImageBBox(makeNullPoint());
147 }
148 
150  if (isPointNull(position)) position = getAveragePosition();
151  if (color.isIndeterminate()) color = getAverageColor();
152  return doComputeImageBBox(position, color);
153 }
154 
156  return getLocalKernel(makeNullPoint());
157 }
158 
160  image::Color color) const {
161  if (isPointNull(position)) position = getAveragePosition();
162  if (color.isIndeterminate()) color = getAverageColor();
163  // FixedKernel ctor will deep copy image, so we can use INTERNAL.
165  return std::make_shared<math::FixedKernel>(*image);
166 }
167 
168 double Psf::computePeak() const {
169  return computePeak(makeNullPoint());
170 }
171 
172 double Psf::computePeak(lsst::geom::Point2D position, image::Color color) const {
173  if (isPointNull(position)) position = getAveragePosition();
174  if (color.isIndeterminate()) color = getAverageColor();
176  return (*image)(-image->getX0(), -image->getY0());
177 }
178 
179 double Psf::computeApertureFlux(double radius) const {
180  return computeApertureFlux(radius, makeNullPoint());
181 }
182 
183 double Psf::computeApertureFlux(double radius, lsst::geom::Point2D position, image::Color color) const {
184  if (isPointNull(position)) position = getAveragePosition();
185  if (color.isIndeterminate()) color = getAverageColor();
186  return doComputeApertureFlux(radius, position, color);
187 }
188 
190  return computeShape(makeNullPoint());
191 }
192 
194  if (isPointNull(position)) position = getAveragePosition();
195  if (color.isIndeterminate()) color = getAverageColor();
196  return doComputeShape(position, color);
197 }
198 
200  image::Color const &color) const {
201  std::shared_ptr<Psf::Image> im = computeKernelImage(position, color, COPY);
202  return recenterKernelImage(im, position);
203 }
204 
206  image::Color const& color) const {
207  std::shared_ptr<Psf::Image> im = computeImage(position, color, INTERNAL);
208  return im->getBBox();
209 }
210 
212 
213 std::size_t Psf::getCacheCapacity() const { return _kernelImageCache->capacity(); }
214 
216  _imageCache->reserve(capacity);
217  _kernelImageCache->reserve(capacity);
218 }
219 
220 } // namespace detection
221 } // namespace afw
222 } // namespace lsst
py::object result
Definition: _schema.cc:429
std::ostream * os
Definition: Schema.cc:557
A polymorphic base class for representing an image's Point Spread Function.
Definition: Psf.h:76
static std::shared_ptr< Image > recenterKernelImage(std::shared_ptr< Image > im, lsst::geom::Point2D const &position, std::string const &warpAlgorithm="lanczos5", unsigned int warpBuffer=5)
Helper function for Psf::doComputeImage(): converts a kernel image (centered at (0,...
Definition: Psf.cc:85
lsst::geom::Box2I computeBBox() const
Definition: Psf.cc:135
virtual std::shared_ptr< Image > doComputeImage(lsst::geom::Point2D const &position, image::Color const &color) const
These virtual members are protected (rather than private) so that python-implemented derived classes ...
Definition: Psf.cc:199
lsst::geom::Box2I computeImageBBox() const
Definition: Psf.cc:145
std::size_t getCacheCapacity() const
Return the capacity of the caches.
Definition: Psf.cc:213
virtual std::shared_ptr< Image > doComputeKernelImage(lsst::geom::Point2D const &position, image::Color const &color) const =0
These virtual member functions are private, not protected, because we only want derived classes to im...
double computeApertureFlux(double radius, lsst::geom::Point2D position, image::Color color=image::Color()) const
Compute the "flux" of the Psf model within a circular aperture of the given radius.
Definition: Psf.cc:183
std::shared_ptr< Image > computeImage() const
Definition: Psf.cc:101
std::shared_ptr< Image > computeKernelImage() const
Definition: Psf.cc:118
std::shared_ptr< math::Kernel const > getLocalKernel() const
Definition: Psf.cc:155
Psf(Psf const &)
Definition: Psf.cc:78
double computePeak() const
Definition: Psf.cc:168
image::Color getAverageColor() const
Return the average Color of the stars used to construct the Psf.
Definition: Psf.h:274
virtual lsst::geom::Box2I doComputeImageBBox(lsst::geom::Point2D const &position, image::Color const &color) const
Definition: Psf.cc:205
ImageOwnerEnum
Enum passed to computeImage and computeKernelImage to determine image ownership.
Definition: Psf.h:86
@ COPY
The image will be copied before returning; caller will own it.
Definition: Psf.h:87
@ INTERNAL
An internal image will be returned without copying.
Definition: Psf.h:88
virtual lsst::geom::Box2I doComputeBBox(lsst::geom::Point2D const &position, image::Color const &color) const =0
void setCacheCapacity(std::size_t capacity)
Set the capacity of the caches.
Definition: Psf.cc:215
geom::ellipses::Quadrupole computeShape() const
Definition: Psf.cc:189
virtual double doComputeApertureFlux(double radius, lsst::geom::Point2D const &position, image::Color const &color) const =0
virtual lsst::geom::Point2D getAveragePosition() const
Return the average position of the stars used to construct the Psf.
Definition: Psf.cc:211
virtual geom::ellipses::Quadrupole doComputeShape(lsst::geom::Point2D const &position, image::Color const &color) const =0
An ellipse core with quadrupole moments as parameters.
Definition: Quadrupole.h:47
Describe the colour of a source.
Definition: Color.h:26
bool isIndeterminate() const noexcept
Whether the color is the special value that indicates that it is unspecified.
Definition: Color.h:37
static std::shared_ptr< T > dynamicCast(std::shared_ptr< Persistable > const &ptr)
Dynamically cast a shared_ptr.
Definition: Persistable.cc:18
An integer coordinate rectangle.
Definition: Box.h:55
T isnan(T... args)
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
int positionToIndex(double pos)
Convert image position to nearest integer index.
Definition: ImageUtils.h:69
std::shared_ptr< ImageT > offsetImage(ImageT const &image, float dx, float dy, std::string const &algorithmName="lanczos5", unsigned int buffer=0)
Return an image offset by (dx, dy) using the specified algorithm.
Definition: offsetImage.cc:41
Point< double, 2 > Point2D
Definition: Point.h:324
A base class for image defects.
STL namespace.
friend std::ostream & operator<<(std::ostream &os, PsfCacheKey const &key)
Definition: Psf.cc:37
lsst::geom::Point2D const position
Definition: Psf.cc:27
bool operator==(PsfCacheKey const &other) const
Definition: Psf.cc:33
PsfCacheKey(lsst::geom::Point2D const &position_, image::Color color_=image::Color())
Definition: Psf.cc:30
std::size_t operator()(lsst::afw::detection::detail::PsfCacheKey const &key) const noexcept
Definition: Psf.cc:54