LSSTApplications  1.1.2+25,10.0+13,10.0+132,10.0+133,10.0+224,10.0+41,10.0+8,10.0-1-g0f53050+14,10.0-1-g4b7b172+19,10.0-1-g61a5bae+98,10.0-1-g7408a83+3,10.0-1-gc1e0f5a+19,10.0-1-gdb4482e+14,10.0-11-g3947115+2,10.0-12-g8719d8b+2,10.0-15-ga3f480f+1,10.0-2-g4f67435,10.0-2-gcb4bc6c+26,10.0-28-gf7f57a9+1,10.0-3-g1bbe32c+14,10.0-3-g5b46d21,10.0-4-g027f45f+5,10.0-4-g86f66b5+2,10.0-4-gc4fccf3+24,10.0-40-g4349866+2,10.0-5-g766159b,10.0-5-gca2295e+25,10.0-6-g462a451+1
LSSTDataManagementBasePackage
PsfCandidate.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 
34 #include "lsst/afw/geom/Point.h"
35 #include "lsst/afw/geom/Extent.h"
36 #include "lsst/afw/geom/Box.h"
40 
41 namespace afwDetection = lsst::afw::detection;
42 namespace afwGeom = lsst::afw::geom;
43 namespace afwImage = lsst::afw::image;
44 namespace afwMath = lsst::afw::math;
45 namespace measAlg = lsst::meas::algorithms;
46 
47 /************************************************************************************************************/
48 /*
49  * PsfCandidate's members
50  */
51 template <typename PixelT>
53 template <typename PixelT>
55 template <typename PixelT>
57 template <typename PixelT>
59 
60 /************************************************************************************************************/
61 namespace {
62  template<typename T> // functor used by makeImageFromMask to return inputMask
63  struct noop : public afwImage::pixelOp1<T> {
64  T operator()(T x) const { return x; }
65  };
66 
67  template<typename T> // functor used by makeImageFromMask to return (inputMask & mask)
68  struct andMask : public afwImage::pixelOp1<T> {
69  andMask(T mask) : _mask(mask) {}
70  T operator()(T x) const { return (x & _mask); }
71  private:
72  T _mask;
73  };
74 
75  template<typename T>
76  andMask<T> makeAndMask(T val) {
77  return andMask<T>(val);
78  }
79 
80  /*
81  * Return an Image initialized from a Mask (possibly modified by func)
82  */
83  template<typename LhsT, typename RhsT>
85  makeImageFromMask(afwImage::Mask<RhsT> const& rhs,
86  afwImage::pixelOp1<RhsT> const& func=noop<RhsT>()
87  )
88  {
89  typename afwImage::Image<LhsT>::Ptr lhs =
90  boost::make_shared<afwImage::Image<LhsT> >(rhs.getDimensions());
91  lhs->setXY0(rhs.getXY0());
92 
93  for (int y = 0; y != lhs->getHeight(); ++y) {
95 
96  for (typename afwImage::Image<LhsT>::x_iterator lhsPtr = lhs->row_begin(y),
97  lhsEnd = lhs->row_end(y); lhsPtr != lhsEnd; ++rhsPtr, ++lhsPtr) {
98  *lhsPtr = func(*rhsPtr);
99  }
100  }
101 
102  return lhs;
103  }
104 
106  double distanceSquared(double x, double y, afwDetection::Peak const& peak) {
107  return std::pow(peak.getIx() - x, 2) + std::pow(peak.getIy() - y, 2);
108  }
109 
114  template <typename PixelT>
115  class BlendedFunctor : public afwDetection::FootprintFunctor<afwImage::MaskedImage<PixelT> > {
116  public:
117  typedef typename afwImage::MaskedImage<PixelT> Image;
118  typedef typename Image::Mask Mask;
119  typedef typename afwDetection::FootprintFunctor<Image> Super;
120  BlendedFunctor(
121  Image const& image,
122  Mask & mask,
123  afwDetection::Peak const& central,
124  afwDetection::Footprint::PeakList const& peaks,
125  afwImage::MaskPixel turnOff,
126  afwImage::MaskPixel turnOn
127  ) :
128  Super(image),
129  _central(central),
130  _peaks(peaks),
131  _mask(mask),
132  _turnOff(~turnOff),
133  _turnOn(turnOn)
134  {}
135 
137  virtual void operator()(typename Image::xy_locator loc, int x, int y) {
138  double const central = distanceSquared(x, y, _central);
139  int const xImage = x - getImage().getX0();
140  int const yImage = y - getImage().getY0();
141  for (afwDetection::Footprint::PeakList::const_iterator iter = _peaks.begin(), end = _peaks.end();
142  iter != end; ++iter) {
143  double const dist2 = distanceSquared(x, y, **iter);
144  if (dist2 < central) {
145  (_mask)(xImage, yImage) &= _turnOff;
146  (_mask)(xImage, yImage) |= _turnOn;
147  return;
148  }
149  }
150  }
151 
152  using Super::getImage;
153 
154  private:
155  afwDetection::Peak const& _central;
156  afwDetection::Footprint::PeakList const& _peaks;
157  Mask & _mask;
158  afwImage::MaskPixel const _turnOff;
159  afwImage::MaskPixel const _turnOn;
160  };
161 
162 } // anonymous namespace
163 
182 template <typename PixelT>
184 measAlg::PsfCandidate<PixelT>::extractImage(
185  unsigned int width, // Width of image
186  unsigned int height // Height of image
187 ) const {
188  afwGeom::Point2I const cen(afwImage::positionToIndex(getXCenter()),
189  afwImage::positionToIndex(getYCenter()));
190  afwGeom::Point2I const llc(cen[0] - width/2 - _parentExposure->getX0(),
191  cen[1] - height/2 - _parentExposure->getY0());
192 
193  afwGeom::BoxI bbox(llc, afwGeom::ExtentI(width, height));
194 
196  try {
197  MaskedImageT mimg = _parentExposure->getMaskedImage();
198  image.reset(new MaskedImageT(mimg, bbox, afwImage::LOCAL, true)); // a deep copy
199  } catch(lsst::pex::exceptions::LengthError &e) {
200  LSST_EXCEPT_ADD(e, "Extracting image of PSF candidate");
201  throw e;
202  }
203 
204  //
205  // Set INTRP and unset DETECTED for any pixels we don't want to deal with.
206  //
207  afwImage::MaskPixel const intrp = MaskedImageT::Mask::getPlaneBitMask("INTRP"); // mask bit for bad pixels
208  afwImage::MaskPixel const detected = MaskedImageT::Mask::getPlaneBitMask("DETECTED"); // object pixels
209 
210  // Mask out blended objects
211  if (getMaskBlends()) {
212  CONST_PTR(afwDetection::Footprint) foot = getSource()->getFootprint();
213  typedef afwDetection::Footprint::PeakList PeakList;
214  PeakList const& peaks = foot->getPeaks();
215  if (peaks.size() > 1) {
216  // Mask all pixels in the footprint except for those closest to the central peak
217  double best = std::numeric_limits<double>::infinity();
218  CONST_PTR(afwDetection::Peak) central;
219  for (PeakList::const_iterator iter = peaks.begin(), end = peaks.end(); iter != end; ++iter) {
220  double const dist2 = distanceSquared(getXCenter(), getYCenter(), **iter);
221  if (dist2 < best) {
222  best = dist2;
223  central = *iter;
224  }
225  }
226  assert(central); // We must have found something
227 
228  PeakList others;
229  others.reserve(peaks.size() - 1);
230  for (PeakList::const_iterator iter = peaks.begin(), end = peaks.end(); iter != end; ++iter) {
231  if (central != *iter) {
232  others.push_back(*iter);
233  }
234  }
235 
236  BlendedFunctor<PixelT> functor(*image, *image->getMask(), *central, others, detected, intrp);
237  functor.apply(*foot);
238  }
239  }
240 
241  /*
242  * Mask any DETECTED pixels other than the one in the center of the object;
243  * we grow the Footprint a bit first
244  */
246 
247  PTR(afwImage::Image<int>) mim = makeImageFromMask<int>(*image->getMask(), makeAndMask(detected));
249  boost::make_shared<afwDetection::FootprintSet>(*mim, afwDetection::Threshold(1));
250  CONST_PTR(FootprintList) feet = fs->getFootprints();
251 
252  if (feet->size() > 1) {
253  int const ngrow = 3; // number of pixels to grow bad Footprints
254  //
255  // Go through Footprints looking for ones that don't contain cen
256  //
257  for (FootprintList::const_iterator fiter = feet->begin(); fiter != feet->end(); ++fiter) {
258  PTR(afwDetection::Footprint) foot = *fiter;
259  if (foot->contains(cen)) {
260  continue;
261  }
262 
264  afwDetection::clearMaskFromFootprint(image->getMask().get(), *bigfoot, detected);
265  afwDetection::setMaskFromFootprint(image->getMask().get(), *bigfoot, intrp);
266  }
267  }
268 
269  // Mask high pixels unconnected to the center
270  if (_pixelThreshold > 0.0) {
272  boost::make_shared<afwDetection::FootprintSet>(*image,
274  for (FootprintList::const_iterator fpIter = fpSet->getFootprints()->begin();
275  fpIter != fpSet->getFootprints()->end(); ++fpIter) {
276  CONST_PTR(afwDetection::Footprint) fp = *fpIter;
277  if (!fp->contains(cen)) {
278  afwDetection::clearMaskFromFootprint(image->getMask().get(), *fp, detected);
279  afwDetection::setMaskFromFootprint(image->getMask().get(), *fp, intrp);
280  }
281  }
282  }
283 
284  return image;
285 }
286 
287 
293 template <typename PixelT>
295 measAlg::PsfCandidate<PixelT>::getMaskedImage(int width, int height) const {
296 
297 
298  if (_haveImage && (width != _image->getWidth() || height != _image->getHeight())) {
299  _haveImage = false;
300  }
301 
302  if (!_haveImage) {
303  _image = extractImage(width, height);
304  _haveImage = true;
305  }
306 
307  return _image;
308 }
309 
315 template <typename PixelT>
316 CONST_PTR(afwImage::MaskedImage<PixelT>) measAlg::PsfCandidate<PixelT>::getMaskedImage() const {
317 
318  int const width = getWidth() == 0 ? _defaultWidth : getWidth();
319  int const height = getHeight() == 0 ? _defaultWidth : getHeight();
320 
321  return getMaskedImage(width, height);
322 
323 }
324 
330 template <typename PixelT>
332 measAlg::PsfCandidate<PixelT>::getOffsetImage(
333  std::string const algorithm, // Warping algorithm to use
334  unsigned int buffer // Buffer for warping
335 ) const {
336  unsigned int const width = getWidth() == 0 ? _defaultWidth : getWidth();
337  unsigned int const height = getHeight() == 0 ? _defaultWidth : getHeight();
338  if (_offsetImage && static_cast<unsigned int>(_offsetImage->getWidth()) == width + 2*buffer &&
339  static_cast<unsigned int>(_offsetImage->getHeight()) == height + 2*buffer) {
340  return _offsetImage;
341  }
342 
343  PTR(MaskedImageT) image = extractImage(width + 2*buffer, height + 2*buffer);
344 
345  double const xcen = getXCenter(), ycen = getYCenter();
346  double const dx = afwImage::positionToIndex(xcen, true).second;
347  double const dy = afwImage::positionToIndex(ycen, true).second;
348 
349  PTR(MaskedImageT) offset = afwMath::offsetImage(*image, -dx, -dy, algorithm);
350  afwGeom::Point2I llc(buffer, buffer);
351  afwGeom::Extent2I dims(width, height);
352  afwGeom::Box2I box(llc, dims);
353  _offsetImage.reset(new MaskedImageT(*offset, box, afwImage::LOCAL, true)); // Deep copy
354 
355  return _offsetImage;
356 }
357 
358 
359 
360 
361 /************************************************************************************************************/
362 //
363 // Explicit instantiations
364 //
366 typedef float Pixel;
367 //template class measAlg::PsfCandidate<afwImage::MaskedImage<Pixel> >;
368 template class measAlg::PsfCandidate<Pixel>;
int y
int iter
boost::uint16_t MaskPixel
#define CONST_PTR(...)
Definition: base.h:47
double dx
Definition: ImageUtils.cc:90
Represent a set of pixels of an arbitrary shape and size.
x_iterator row_begin(int y) const
Definition: Image.h:319
std::vector< Peak::Ptr > PeakList
Definition: Footprint.h:80
x_iterator row_end(int y) const
Return an x_iterator to the end of the y&#39;th row.
Definition: Image.h:324
int positionToIndex(double pos)
Convert image position to nearest integer index.
Definition: ImageUtils.h:69
boost::shared_ptr< FootprintList > feet
Definition: saturated.cc:81
Use number of sigma given per-pixel s.d.
Definition: Threshold.h:52
std::vector< Footprint::Ptr > FootprintList
The FootprintSet&#39;s set of Footprints.
Definition: FootprintSet.h:57
A Threshold is used to pass a threshold value to detection algorithms.
Definition: Threshold.h:44
#define PTR(...)
Definition: base.h:41
double dy
Definition: ImageUtils.cc:90
An integer coordinate rectangle.
Definition: Box.h:53
table::Key< table::Array< Kernel::Pixel > > image
Definition: FixedKernel.cc:117
boost::shared_ptr< Footprint > growFootprint(Footprint const &foot, int nGrow, bool isotropic=true)
A peak in an image.
Definition: Peak.h:51
Class used by SpatialCell for spatial PSF fittig.
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:93
int getIx() const
Return the column pixel position.
Definition: Peak.h:98
A class to manipulate images, masks, and variance as a single object.
Definition: MaskedImage.h:77
int getIy() const
Definition: Peak.h:99
detection::FootprintSet::FootprintList FootprintList
Definition: saturated.cc:80
A set of pixels in an Image.
Definition: Footprint.h:70
Support for functors over Image&#39;s pixels.
MaskT clearMaskFromFootprint(lsst::afw::image::Mask< MaskT > *mask, Footprint const &footprint, MaskT const bitmask)
(AND ~bitmask) all the Mask&#39;s pixels that are in the Footprint; that is, set to zero in the Mask-inte...
int x
A coordinate class intended to represent absolute positions.
void setXY0(geom::Point2I const origin)
Definition: Image.h:362
ImageT::Ptr 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:55
A set of Footprints, associated with a MaskedImage.
Definition: FootprintSet.h:53
MaskT setMaskFromFootprint(lsst::afw::image::Mask< MaskT > *mask, Footprint const &footprint, MaskT const bitmask)
OR bitmask into all the Mask&#39;s pixels that are in the Footprint.
geom::Point2I getXY0() const
Definition: Image.h:264
int getHeight() const
Return the number of rows in the image.
Definition: Image.h:239
A coordinate class intended to represent offsets and dimensions.
#define LSST_EXCEPT_ADD(e, m)
Definition: Exception.h:51
A functor class to allow users to process all the pixels in a Footprint.
ImageT val
Definition: CR.cc:154
geom::Extent2I getDimensions() const
Return the image&#39;s size; useful for passing to constructors.
Definition: Image.h:298
A class to represent a 2-dimensional array of pixels.
Definition: PSF.h:43
Class stored in SpatialCells for spatial Psf fitting.
Definition: PsfCandidate.h:57