lsst.afw  21.0.0-37-gade869a9e+fb0e51fe34
MaskedImage.cc
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2008-2016 AURA/LSST.
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  * Implementation for MaskedImage
27  */
28 #include <cstdint>
29 #include <typeinfo>
30 #include <sys/stat.h>
31 #pragma clang diagnostic push
32 #pragma clang diagnostic ignored "-Wunused-variable"
33 #pragma clang diagnostic pop
34 #include "boost/regex.hpp"
35 #include "boost/filesystem/path.hpp"
36 #include "boost/format.hpp"
37 #include "lsst/log/Log.h"
38 #include "lsst/pex/exceptions.h"
39 
41 #include "lsst/afw/fits.h"
43 
44 namespace lsst {
45 namespace afw {
46 namespace image {
47 
48 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
50  MaskPlaneDict const& planeDict)
51  : _image(new Image(width, height)),
52  _mask(new Mask(width, height, planeDict)),
53  _variance(new Variance(width, height)) {
54  *_image = 0;
55  *_mask = 0x0;
56  *_variance = 0;
57 }
58 
59 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
61  MaskPlaneDict const& planeDict)
62  : _image(new Image(dimensions)),
63  _mask(new Mask(dimensions, planeDict)),
64  _variance(new Variance(dimensions)) {
65  *_image = 0;
66  *_mask = 0x0;
67  *_variance = 0;
68 }
69 
70 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
72  MaskPlaneDict const& planeDict)
73  : _image(new Image(bbox)), _mask(new Mask(bbox, planeDict)), _variance(new Variance(bbox)) {
74  *_image = 0;
75  *_mask = 0x0;
76  *_variance = 0;
77 }
78 
79 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
81  std::string const& fileName, std::shared_ptr<daf::base::PropertySet> metadata,
82  lsst::geom::Box2I const& bbox, ImageOrigin origin, bool conformMasks, bool needAllHdus,
85  std::shared_ptr<daf::base::PropertySet> varianceMetadata, bool allowUnsafe)
86  : _image(), _mask(), _variance() {
87  MaskedImageFitsReader reader(fileName);
88  *this = reader.read<ImagePixelT, MaskPixelT, VariancePixelT>(bbox, origin, conformMasks, needAllHdus,
89  allowUnsafe);
90  if (metadata) {
91  metadata->combine(reader.readPrimaryMetadata());
92  }
93  if (imageMetadata) {
94  imageMetadata->combine(reader.readImageMetadata());
95  }
96  if (maskMetadata) {
97  maskMetadata->combine(reader.readMaskMetadata());
98  }
99  if (varianceMetadata) {
100  varianceMetadata->combine(reader.readVarianceMetadata());
101  }
102 }
103 
104 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
107  lsst::geom::Box2I const& bbox, ImageOrigin origin, bool conformMasks, bool needAllHdus,
110  std::shared_ptr<daf::base::PropertySet> varianceMetadata, bool allowUnsafe)
111  : _image(), _mask(), _variance() {
112  MaskedImageFitsReader reader(manager);
113  *this = reader.read<ImagePixelT, MaskPixelT, VariancePixelT>(bbox, origin, conformMasks, needAllHdus,
114  allowUnsafe);
115  if (metadata) {
116  metadata->combine(reader.readPrimaryMetadata());
117  }
118  if (imageMetadata) {
119  imageMetadata->combine(reader.readImageMetadata());
120  }
121  if (maskMetadata) {
122  maskMetadata->combine(reader.readMaskMetadata());
123  }
124  if (varianceMetadata) {
125  varianceMetadata->combine(reader.readVarianceMetadata());
126  }
127 }
128 
129 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
132  ImageOrigin origin, bool conformMasks, bool needAllHdus,
135  std::shared_ptr<daf::base::PropertySet> varianceMetadata, bool allowUnsafe)
136  : _image(), _mask(), _variance() {
137  MaskedImageFitsReader reader(&fitsFile);
138  *this = reader.read<ImagePixelT, MaskPixelT, VariancePixelT>(bbox, origin, conformMasks, needAllHdus,
139  allowUnsafe);
140  if (metadata) {
141  metadata->combine(reader.readPrimaryMetadata());
142  }
143  if (imageMetadata) {
144  imageMetadata->combine(reader.readImageMetadata());
145  }
146  if (maskMetadata) {
147  maskMetadata->combine(reader.readMaskMetadata());
148  }
149  if (varianceMetadata) {
150  varianceMetadata->combine(reader.readVarianceMetadata());
151  }
152 }
153 
154 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
157  : _image(image), _mask(mask), _variance(variance) {
158  conformSizes();
159 }
160 
161 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
163  : _image(rhs._image), _mask(rhs._mask), _variance(rhs._variance) {
164  if (deep) {
165  _image = std::shared_ptr<Image>(new Image(*rhs.getImage(), deep));
166  _mask = std::shared_ptr<Mask>(new Mask(*rhs.getMask(), deep));
167  _variance = std::shared_ptr<Variance>(new Variance(*rhs.getVariance(), deep));
168  }
169  conformSizes();
170 }
171 
172 // Delegate to copy-constructor for backwards compatibility
173 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
175  : MaskedImage(rhs, false) {}
176 
177 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
179  const lsst::geom::Box2I& bbox,
180  ImageOrigin const origin, bool deep
181 
182  )
183  : _image(new Image(*rhs.getImage(), bbox, origin, deep)),
184  _mask(rhs._mask ? new Mask(*rhs.getMask(), bbox, origin, deep) : static_cast<Mask*>(NULL)),
185  _variance(rhs._variance ? new Variance(*rhs.getVariance(), bbox, origin, deep)
186  : static_cast<Variance*>(NULL)) {
187  conformSizes();
188 }
189 
190 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
192 operator=(MaskedImage const& rhs) = default;
193 
194 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
196 operator=(MaskedImage&& rhs) = default;
197 
198 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
200  using std::swap; // See Meyers, Effective C++, Item 25
201 
202  _image.swap(rhs._image);
203  _mask.swap(rhs._mask);
204  _variance.swap(rhs._variance);
205 }
206 
207 // Operators
208 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
210 operator=(MaskedImage::Pixel const& rhs) {
211  *_image = rhs.image();
212  *_mask = rhs.mask();
213  *_variance = rhs.variance();
214 
215  return *this;
216 }
217 
218 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
221  *_image = rhs.image();
222  *_mask = rhs.mask();
223  *_variance = rhs.variance();
224 
225  return *this;
226 }
227 
228 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
230  lsst::geom::Box2I const& bbox,
231  ImageOrigin origin) {
232  _image->assign(*rhs.getImage(), bbox, origin);
233  _mask->assign(*rhs.getMask(), bbox, origin);
234  _variance->assign(*rhs.getVariance(), bbox, origin);
235 }
236 
237 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
239 operator+=(MaskedImage const& rhs) {
240  *_image += *rhs.getImage();
241  *_mask |= *rhs.getMask();
242  *_variance += *rhs.getVariance();
243  return *this;
244 }
245 
246 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
248  MaskedImage const& rhs) {
249  (*_image).scaledPlus(c, *rhs.getImage());
250  *_mask |= *rhs.getMask();
251  (*_variance).scaledPlus(c * c, *rhs.getVariance());
252 }
253 
254 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
256 operator+=(ImagePixelT const rhs) {
257  *_image += rhs;
258  return *this;
259 }
260 
261 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
263 operator-=(MaskedImage const& rhs) {
264  *_image -= *rhs.getImage();
265  *_mask |= *rhs.getMask();
266  *_variance += *rhs.getVariance();
267  return *this;
268 }
269 
270 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
272  MaskedImage const& rhs) {
273  (*_image).scaledMinus(c, *rhs.getImage());
274  *_mask |= *rhs.getMask();
275  (*_variance).scaledPlus(c * c, *rhs.getVariance());
276 }
277 
278 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
280 operator-=(ImagePixelT const rhs) {
281  *_image -= rhs;
282  return *this;
283 }
284 
285 namespace {
287 template <typename ImagePixelT, typename VariancePixelT>
288 struct productVariance {
289  double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
290  return lhs * lhs * varRhs + rhs * rhs * varLhs;
291  }
292 };
293 
296 template <typename ImagePixelT, typename VariancePixelT>
297 struct scaledProductVariance {
298  double _c;
299  scaledProductVariance(double const c) : _c(c) {}
300  double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
301  return _c * _c * (lhs * lhs * varRhs + rhs * rhs * varLhs);
302  }
303 };
304 } // namespace
305 
306 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
308 operator*=(MaskedImage const& rhs) {
309  // Must do variance before we modify the image values
310  if (_image->getDimensions() != rhs._image->getDimensions()) {
312  boost::str(boost::format("Images are of different size, %dx%d v %dx%d") %
313  _image->getWidth() % _image->getHeight() % rhs._image->getWidth() % rhs._image->getHeight()));
314  }
315  transform_pixels(_image->_getRawView(), // lhs
316  rhs._image->_getRawView(), // rhs,
317  _variance->_getRawView(), // Var(lhs),
318  rhs._variance->_getRawView(), // Var(rhs)
319  _variance->_getRawView(), // result
320  productVariance<ImagePixelT, VariancePixelT>());
321 
322  *_image *= *rhs.getImage();
323  *_mask |= *rhs.getMask();
324  return *this;
325 }
326 
327 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
329  MaskedImage const& rhs) {
330  // Must do variance before we modify the image values
331  if (_image->getDimensions() != rhs._image->getDimensions()) {
333  boost::str(boost::format("Images are of different size, %dx%d v %dx%d") %
334  _image->getWidth() % _image->getHeight() % rhs._image->getWidth() % rhs._image->getHeight()));
335  }
336  transform_pixels(_image->_getRawView(), // lhs
337  rhs._image->_getRawView(), // rhs,
338  _variance->_getRawView(), // Var(lhs),
339  rhs._variance->_getRawView(), // Var(rhs)
340  _variance->_getRawView(), // result
341  scaledProductVariance<ImagePixelT, VariancePixelT>(c));
342 
343  (*_image).scaledMultiplies(c, *rhs.getImage());
344  *_mask |= *rhs.getMask();
345 }
346 
347 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
349 operator*=(ImagePixelT const rhs) {
350  *_image *= rhs;
351  *_variance *= rhs * rhs;
352  return *this;
353 }
354 
355 namespace {
357 template <typename ImagePixelT, typename VariancePixelT>
358 struct quotientVariance {
359  double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
360  ImagePixelT const rhs2 = rhs * rhs;
361  return (lhs * lhs * varRhs + rhs2 * varLhs) / (rhs2 * rhs2);
362  }
363 };
366 template <typename ImagePixelT, typename VariancePixelT>
367 struct scaledQuotientVariance {
368  double _c;
369  scaledQuotientVariance(double c) : _c(c) {}
370  double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
371  ImagePixelT const rhs2 = rhs * rhs;
372  return (lhs * lhs * varRhs + rhs2 * varLhs) / (_c * _c * rhs2 * rhs2);
373  }
374 };
375 } // namespace
376 
377 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
379 operator/=(MaskedImage const& rhs) {
380  // Must do variance before we modify the image values
381  if (_image->getDimensions() != rhs._image->getDimensions()) {
383  boost::str(boost::format("Images are of different size, %dx%d v %dx%d") %
384  _image->getWidth() % _image->getHeight() % rhs._image->getWidth() % rhs._image->getHeight()));
385  }
386  transform_pixels(_image->_getRawView(), // lhs
387  rhs._image->_getRawView(), // rhs,
388  _variance->_getRawView(), // Var(lhs),
389  rhs._variance->_getRawView(), // Var(rhs)
390  _variance->_getRawView(), // result
391  quotientVariance<ImagePixelT, VariancePixelT>());
392 
393  *_image /= *rhs.getImage();
394  *_mask |= *rhs.getMask();
395  return *this;
396 }
397 
398 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
400  MaskedImage const& rhs) {
401  // Must do variance before we modify the image values
402  if (_image->getDimensions() != rhs._image->getDimensions()) {
404  str(boost::format("Images are of different size, %dx%d v %dx%d") %
405  _image->getWidth() % _image->getHeight() % rhs._image->getWidth() % rhs._image->getHeight()));
406  }
407  transform_pixels(_image->_getRawView(), // lhs
408  rhs._image->_getRawView(), // rhs,
409  _variance->_getRawView(), // Var(lhs),
410  rhs._variance->_getRawView(), // Var(rhs)
411  _variance->_getRawView(), // result
412  scaledQuotientVariance<ImagePixelT, VariancePixelT>(c));
413 
414  (*_image).scaledDivides(c, *rhs.getImage());
415  *_mask |= *rhs._mask;
416 }
417 
418 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
420 operator/=(ImagePixelT const rhs) {
421  *_image /= rhs;
422  *_variance /= rhs * rhs;
423  return *this;
424 }
425 
426 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
431  std::shared_ptr<daf::base::PropertySet const> varianceMetadata) const {
432  fits::Fits fitsfile(fileName, "w", fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
433  writeFits(fitsfile, metadata, imageMetadata, maskMetadata, varianceMetadata);
434 }
435 
436 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
441  std::shared_ptr<daf::base::PropertySet const> varianceMetadata) const {
442  fits::Fits fitsfile(manager, "w", fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
443  writeFits(fitsfile, metadata, imageMetadata, maskMetadata, varianceMetadata);
444 }
445 
446 namespace {
447 
448 void processPlaneMetadata(std::shared_ptr<daf::base::PropertySet const> metadata,
449  std::shared_ptr<daf::base::PropertySet>& hdr, char const* exttype) {
450  if (metadata) {
451  hdr = metadata->deepCopy();
452  } else {
453  hdr.reset(new daf::base::PropertyList());
454  }
455  hdr->set("INHERIT", true);
456  hdr->set("EXTTYPE", exttype);
457  hdr->set("EXTNAME", exttype);
458 }
459 
460 } // namespace
461 
462 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
467  std::shared_ptr<daf::base::PropertySet const> varianceMetadata) const {
468  writeFits(fitsfile, fits::ImageWriteOptions(*_image), fits::ImageWriteOptions(*_mask),
469  fits::ImageWriteOptions(*_variance), metadata, imageMetadata, maskMetadata, varianceMetadata);
470 }
471 
472 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
474  std::string const& fileName, fits::ImageWriteOptions const& imageOptions,
475  fits::ImageWriteOptions const& maskOptions, fits::ImageWriteOptions const& varianceOptions,
479  std::shared_ptr<daf::base::PropertySet const> varianceMetadata) const {
480  fits::Fits fitsfile(fileName, "w", fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
481  writeFits(fitsfile, imageOptions, maskOptions, varianceOptions, metadata, imageMetadata, maskMetadata,
482  varianceMetadata);
483 }
484 
485 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
487  fits::MemFileManager& manager, fits::ImageWriteOptions const& imageOptions,
488  fits::ImageWriteOptions const& maskOptions, fits::ImageWriteOptions const& varianceOptions,
492  std::shared_ptr<daf::base::PropertySet const> varianceMetadata) const {
493  fits::Fits fitsfile(manager, "w", fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
494  writeFits(fitsfile, imageOptions, maskOptions, varianceOptions, metadata, imageMetadata, maskMetadata,
495  varianceMetadata);
496 }
497 
498 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
500  fits::Fits& fitsfile, fits::ImageWriteOptions const& imageOptions,
501  fits::ImageWriteOptions const& maskOptions, fits::ImageWriteOptions const& varianceOptions,
505  std::shared_ptr<daf::base::PropertySet const> varianceMetadata) const {
507  if (metadata) {
508  header = metadata->deepCopy();
509  } else {
510  header = std::make_shared<daf::base::PropertyList>();
511  }
512 
513  if (fitsfile.countHdus() != 0) {
515  "MaskedImage::writeFits can only write to an empty file");
516  }
517  if (fitsfile.getHdu() < 1) {
518  // Don't ever write images to primary; instead we make an empty primary.
519  fitsfile.createEmpty();
520  } else {
521  fitsfile.setHdu(0);
522  }
523  fitsfile.writeMetadata(*header);
524 
525  processPlaneMetadata(imageMetadata, header, "IMAGE");
526  _image->writeFits(fitsfile, imageOptions, header, _mask);
527 
528  processPlaneMetadata(maskMetadata, header, "MASK");
529  _mask->writeFits(fitsfile, maskOptions, header);
530 
531  processPlaneMetadata(varianceMetadata, header, "VARIANCE");
532  _variance->writeFits(fitsfile, varianceOptions, header, _mask);
533 }
534 
535 // private function conformSizes() ensures that the Mask and Variance have the same dimensions
536 // as Image. If Mask and/or Variance have non-zero dimensions that conflict with the size of Image,
537 // a lsst::pex::exceptions::LengthError is thrown.
538 
539 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
541  if (!_mask || _mask->getWidth() == 0 || _mask->getHeight() == 0) {
542  _mask = MaskPtr(new Mask(_image->getBBox()));
543  *_mask = 0;
544  } else {
545  if (_mask->getDimensions() != _image->getDimensions()) {
546  throw LSST_EXCEPT(
548  (boost::format("Dimension mismatch: Image %dx%d v. Mask %dx%d") % _image->getWidth() %
549  _image->getHeight() % _mask->getWidth() % _mask->getHeight())
550  .str());
551  }
552  }
553 
554  if (!_variance || _variance->getWidth() == 0 || _variance->getHeight() == 0) {
555  _variance = VariancePtr(new Variance(_image->getBBox()));
556  *_variance = 0;
557  } else {
558  if (_variance->getDimensions() != _image->getDimensions()) {
559  throw LSST_EXCEPT(
560  pex::exceptions::LengthError,
561  (boost::format("Dimension mismatch: Image %dx%d v. Variance %dx%d") % _image->getWidth() %
562  _image->getHeight() % _variance->getWidth() % _variance->getHeight())
563  .str());
564  }
565  }
566 }
567 
568 //
569 // Iterators and locators
570 //
571 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
574 #if 0 // this doesn't compile; why?
575  return iterator(_image->begin(), _mask->begin(), _variance->begin());
576 #else
577  typename Image::iterator imageBegin = _image->begin();
578  typename Mask::iterator maskBegin = _mask->begin();
579  typename Variance::iterator varianceBegin = _variance->begin();
580 
581  return iterator(imageBegin, maskBegin, varianceBegin);
582 #endif
583 }
584 
585 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
588  typename Image::iterator imageEnd = getImage()->end();
589  typename Mask::iterator maskEnd = getMask()->end();
590  typename Variance::iterator varianceEnd = getVariance()->end();
591 
592  return iterator(imageEnd, maskEnd, varianceEnd);
593 }
594 
595 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
598  typename Image::iterator imageEnd = getImage()->at(x, y);
599  typename Mask::iterator maskEnd = getMask()->at(x, y);
600  typename Variance::iterator varianceEnd = getVariance()->at(x, y);
601 
602  return iterator(imageEnd, maskEnd, varianceEnd);
603 }
604 
605 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
608  typename Image::reverse_iterator imageBegin = _image->rbegin();
609  typename Mask::reverse_iterator maskBegin = _mask->rbegin();
610  typename Variance::reverse_iterator varianceBegin = _variance->rbegin();
611 
612  return reverse_iterator(imageBegin, maskBegin, varianceBegin);
613 }
614 
615 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
618  typename Image::reverse_iterator imageEnd = getImage()->rend();
619  typename Mask::reverse_iterator maskEnd = getMask()->rend();
620  typename Variance::reverse_iterator varianceEnd = getVariance()->rend();
621 
622  return reverse_iterator(imageEnd, maskEnd, varianceEnd);
623 }
624 
625 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
628  typename Image::x_iterator imageBegin = _image->row_begin(y);
629  typename Mask::x_iterator maskBegin = _mask->row_begin(y);
630  typename Variance::x_iterator varianceBegin = _variance->row_begin(y);
631 
632  return x_iterator(imageBegin, maskBegin, varianceBegin);
633 }
634 
635 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
638  typename Image::x_iterator imageEnd = getImage()->row_end(y);
639  typename Mask::x_iterator maskEnd = getMask()->row_end(y);
640  typename Variance::x_iterator varianceEnd = getVariance()->row_end(y);
641 
642  return x_iterator(imageEnd, maskEnd, varianceEnd);
643 }
644 
645 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
648  typename Image::y_iterator imageBegin = _image->col_begin(x);
649  typename Mask::y_iterator maskBegin = _mask->col_begin(x);
650  typename Variance::y_iterator varianceBegin = _variance->col_begin(x);
651 
652  return y_iterator(imageBegin, maskBegin, varianceBegin);
653 }
654 
655 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
658  typename Image::y_iterator imageEnd = getImage()->col_end(x);
659  typename Mask::y_iterator maskEnd = getMask()->col_end(x);
660  typename Variance::y_iterator varianceEnd = getVariance()->col_end(x);
661 
662  return y_iterator(imageEnd, maskEnd, varianceEnd);
663 }
664 
665 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
668  typename Image::fast_iterator imageBegin = _image->begin(contiguous);
669  typename Mask::fast_iterator maskBegin = _mask->begin(contiguous);
670  typename Variance::fast_iterator varianceBegin = _variance->begin(contiguous);
671 
672  return fast_iterator(imageBegin, maskBegin, varianceBegin);
673 }
674 
675 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
678  typename Image::fast_iterator imageEnd = getImage()->end(contiguous);
679  typename Mask::fast_iterator maskEnd = getMask()->end(contiguous);
680  typename Variance::fast_iterator varianceEnd = getVariance()->end(contiguous);
681 
682  return fast_iterator(imageEnd, maskEnd, varianceEnd);
683 }
684 
685 template <typename ImagePixelT1, typename ImagePixelT2>
688  return imagesOverlap(*image1.getImage(), *image2.getImage()) ||
689  imagesOverlap(*image1.getVariance(), *image2.getVariance()) ||
690  imagesOverlap(*image1.getMask(), *image2.getMask());
691 }
692 
693 //
694 // Explicit instantiations
695 //
696 #define INSTANTIATE2(ImagePixelT1, ImagePixelT2) \
697  template bool imagesOverlap<ImagePixelT1, ImagePixelT2>(MaskedImage<ImagePixelT1> const&, \
698  MaskedImage<ImagePixelT2> const&);
699 
700 template class MaskedImage<std::uint16_t>;
701 template class MaskedImage<int>;
702 template class MaskedImage<float>;
703 template class MaskedImage<double>;
704 template class MaskedImage<std::uint64_t>;
705 
711 
713 INSTANTIATE2(int, int);
714 INSTANTIATE2(int, float);
715 INSTANTIATE2(int, double);
717 
719 INSTANTIATE2(float, int);
720 INSTANTIATE2(float, float);
721 INSTANTIATE2(float, double);
723 
725 INSTANTIATE2(double, int);
726 INSTANTIATE2(double, float);
727 INSTANTIATE2(double, double);
729 
735 
736 } // namespace image
737 } // namespace afw
738 } // namespace lsst
AmpInfoBoxKey bbox
Definition: Amplifier.cc:117
double x
#define LSST_EXCEPT(type,...)
afw::table::PointKey< int > dimensions
Definition: GaussianPsf.cc:49
afw::table::Key< afw::table::Array< MaskPixelT > > mask
afw::table::Key< afw::table::Array< VariancePixelT > > variance
double _c
Definition: MaskedImage.cc:298
#define INSTANTIATE2(ImagePixelT1, ImagePixelT2)
Definition: MaskedImage.cc:696
int y
Definition: SpanSet.cc:49
A simple struct that combines the two arguments that must be passed to most cfitsio routines and cont...
Definition: fits.h:297
void createEmpty()
Create an empty image HDU with NAXIS=0 at the end of the file.
Definition: fits.cc:1240
void setHdu(int hdu, bool relative=false)
Set the current HDU.
Definition: fits.cc:513
int countHdus()
Return the number of HDUs in the file.
Definition: fits.cc:534
int getHdu()
Return the current HDU (0-indexed; 0 is the Primary HDU).
Definition: fits.cc:507
void writeMetadata(daf::base::PropertySet const &metadata)
Read a FITS header into a PropertySet or PropertyList.
Definition: fits.cc:1095
Lifetime-management for memory that goes into FITS memory files.
Definition: fits.h:121
_view_t::reverse_iterator reverse_iterator
An STL compliant reverse iterator.
Definition: ImageBase.h:129
x_iterator fast_iterator
A fast STL compliant iterator for contiguous images N.b.
Definition: ImageBase.h:137
_view_t::iterator iterator
An STL compliant iterator.
Definition: ImageBase.h:125
_view_t::y_iterator y_iterator
An iterator for traversing the pixels in a column.
Definition: ImageBase.h:143
_view_t::x_iterator x_iterator
An iterator for traversing the pixels in a row.
Definition: ImageBase.h:133
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:58
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:77
A FITS reader class for MaskedImages and their components.
std::shared_ptr< daf::base::PropertyList > readImageMetadata()
Read the FITS header of one of the HDUs.
std::shared_ptr< daf::base::PropertyList > readPrimaryMetadata()
Read the FITS header of one of the HDUs.
std::shared_ptr< daf::base::PropertyList > readMaskMetadata()
Read the FITS header of one of the HDUs.
std::shared_ptr< daf::base::PropertyList > readVarianceMetadata()
Read the FITS header of one of the HDUs.
MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > read(lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT, bool conformMasks=false, bool needAllHdus=false, bool allowUnsafe=false)
Read the full MaskedImage.
A class to manipulate images, masks, and variance as a single object.
Definition: MaskedImage.h:73
void scaledPlus(double const c, MaskedImage const &rhs)
Add a scaled MaskedImage c*rhs to a MaskedImage.
Definition: MaskedImage.cc:247
void writeFits(std::string const &fileName, std::shared_ptr< daf::base::PropertySet const > metadata=std::shared_ptr< daf::base::PropertySet const >(), std::shared_ptr< daf::base::PropertySet const > imageMetadata=std::shared_ptr< daf::base::PropertySet const >(), std::shared_ptr< daf::base::PropertySet const > maskMetadata=std::shared_ptr< daf::base::PropertySet const >(), std::shared_ptr< daf::base::PropertySet const > varianceMetadata=std::shared_ptr< daf::base::PropertySet const >()) const
Write a MaskedImage to a regular FITS file.
Definition: MaskedImage.cc:427
MaskedImage(unsigned int width, unsigned int height, MaskPlaneDict const &planeDict=MaskPlaneDict())
Construct from a supplied dimensions.
Definition: MaskedImage.cc:49
lsst::afw::image::Image< VariancePixelT > Variance
Definition: MaskedImage.h:84
void scaledDivides(double const c, MaskedImage const &rhs)
Definition: MaskedImage.cc:399
iterator begin() const
Return an iterator to the start of the image.
Definition: MaskedImage.cc:573
reverse_iterator rbegin() const
Return a reverse_iterator to the start of the image.
Definition: MaskedImage.cc:607
y_iterator col_end(int x) const
Return an y_iterator to the end of the image.
Definition: MaskedImage.cc:657
void scaledMinus(double const c, MaskedImage const &rhs)
Subtract a scaled MaskedImage c*rhs from a MaskedImage.
Definition: MaskedImage.cc:271
lsst::afw::image::Image< ImagePixelT > Image
Definition: MaskedImage.h:85
MaskedImage & operator-=(ImagePixelT const rhs)
Subtract a scalar rhs from a MaskedImage.
Definition: MaskedImage.cc:280
x_iterator row_end(int y) const
Return an x_iterator to the end of the image.
Definition: MaskedImage.cc:637
void scaledMultiplies(double const c, MaskedImage const &rhs)
Definition: MaskedImage.cc:328
iterator end() const
Return an iterator to the end of the image.
Definition: MaskedImage.cc:587
void assign(MaskedImage const &rhs, lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT)
Copy pixels from another masked image to a specified subregion of this masked image.
Definition: MaskedImage.cc:229
VariancePtr getVariance() const
Return a (shared_ptr to) the MaskedImage's variance.
Definition: MaskedImage.h:1079
MaskedImage & operator=(MaskedImage const &rhs)
Make the lhs use the rhs's pixels.
x_iterator row_begin(int y) const
Return an x_iterator to the start of the image.
Definition: MaskedImage.cc:627
void swap(MaskedImage &rhs)
Definition: MaskedImage.cc:199
y_iterator col_begin(int x) const
Return an y_iterator to the start of the image.
Definition: MaskedImage.cc:647
lsst::afw::image::Mask< MaskPixelT > Mask
Definition: MaskedImage.h:86
reverse_iterator rend() const
Return a reverse_iterator to the end of the image.
Definition: MaskedImage.cc:617
MaskedImageIterator< typename Image::iterator, typename Mask::iterator, typename Variance::iterator > iterator
Definition: MaskedImage.h:539
MaskedImage & operator+=(ImagePixelT const rhs)
Add a scalar rhs to a MaskedImage.
Definition: MaskedImage.cc:256
MaskedImage & operator*=(ImagePixelT const rhs)
Definition: MaskedImage.cc:349
iterator at(int const x, int const y) const
Return an iterator at the point (x, y)
Definition: MaskedImage.cc:597
MaskedImage & operator/=(ImagePixelT const rhs)
Definition: MaskedImage.cc:420
MaskPtr getMask() const
Return a (shared_ptr to) the MaskedImage's mask.
Definition: MaskedImage.h:1058
ImagePtr getImage() const
Return a (shared_ptr to) the MaskedImage's image.
Definition: MaskedImage.h:1046
MaskedImageIterator< typename Image::x_iterator, typename Mask::x_iterator, typename Variance::x_iterator > x_iterator
An iterator to a row of a MaskedImage.
Definition: MaskedImage.h:556
A pixel of a MaskedImage.
Definition: Pixel.h:148
MaskPixelT mask() const
Return the mask part of a Pixel.
Definition: Pixel.h:219
ImagePixelT image() const
Return the image part of a Pixel.
Definition: Pixel.h:217
VariancePixelT variance() const
Return the variance part of a Pixel.
Definition: Pixel.h:221
A single pixel of the same type as a MaskedImage.
Definition: Pixel.h:73
VariancePixelT variance() const
Definition: Pixel.h:96
MaskPixelT mask() const
Definition: Pixel.h:95
ImagePixelT image() const
Definition: Pixel.h:94
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
bool imagesOverlap(ImageBase< T1 > const &image1, ImageBase< T2 > const &image2)
Return true if the pixels for two images or masks overlap in memory.
Definition: Image.cc:706
A base class for image defects.
T reset(T... args)
Options for writing an image to FITS.
Definition: fits.h:219
T swap(T... args)