lsst.afw  22.0.1-22-gf1d71818e+ba3de87e18
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/format.hpp"
35 #include "lsst/log/Log.h"
36 #include "lsst/pex/exceptions.h"
37 
39 #include "lsst/afw/fits.h"
41 
42 namespace lsst {
43 namespace afw {
44 namespace image {
45 
46 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
48  MaskPlaneDict const& planeDict)
49  : _image(new Image(width, height)),
50  _mask(new Mask(width, height, planeDict)),
51  _variance(new Variance(width, height)) {
52  *_image = 0;
53  *_mask = 0x0;
54  *_variance = 0;
55 }
56 
57 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
59  MaskPlaneDict const& planeDict)
60  : _image(new Image(dimensions)),
61  _mask(new Mask(dimensions, planeDict)),
62  _variance(new Variance(dimensions)) {
63  *_image = 0;
64  *_mask = 0x0;
65  *_variance = 0;
66 }
67 
68 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
70  MaskPlaneDict const& planeDict)
71  : _image(new Image(bbox)), _mask(new Mask(bbox, planeDict)), _variance(new Variance(bbox)) {
72  *_image = 0;
73  *_mask = 0x0;
74  *_variance = 0;
75 }
76 
77 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
79  std::string const& fileName, std::shared_ptr<daf::base::PropertySet> metadata,
80  lsst::geom::Box2I const& bbox, ImageOrigin origin, bool conformMasks, bool needAllHdus,
83  std::shared_ptr<daf::base::PropertySet> varianceMetadata, bool allowUnsafe)
84  : _image(), _mask(), _variance() {
85  MaskedImageFitsReader reader(fileName);
86  *this = reader.read<ImagePixelT, MaskPixelT, VariancePixelT>(bbox, origin, conformMasks, needAllHdus,
87  allowUnsafe);
88  if (metadata) {
89  metadata->combine(reader.readPrimaryMetadata());
90  }
91  if (imageMetadata) {
92  imageMetadata->combine(reader.readImageMetadata());
93  }
94  if (maskMetadata) {
95  maskMetadata->combine(reader.readMaskMetadata());
96  }
97  if (varianceMetadata) {
98  varianceMetadata->combine(reader.readVarianceMetadata());
99  }
100 }
101 
102 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
105  lsst::geom::Box2I const& bbox, ImageOrigin origin, bool conformMasks, bool needAllHdus,
108  std::shared_ptr<daf::base::PropertySet> varianceMetadata, bool allowUnsafe)
109  : _image(), _mask(), _variance() {
110  MaskedImageFitsReader reader(manager);
111  *this = reader.read<ImagePixelT, MaskPixelT, VariancePixelT>(bbox, origin, conformMasks, needAllHdus,
112  allowUnsafe);
113  if (metadata) {
114  metadata->combine(reader.readPrimaryMetadata());
115  }
116  if (imageMetadata) {
117  imageMetadata->combine(reader.readImageMetadata());
118  }
119  if (maskMetadata) {
120  maskMetadata->combine(reader.readMaskMetadata());
121  }
122  if (varianceMetadata) {
123  varianceMetadata->combine(reader.readVarianceMetadata());
124  }
125 }
126 
127 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
130  ImageOrigin origin, bool conformMasks, bool needAllHdus,
133  std::shared_ptr<daf::base::PropertySet> varianceMetadata, bool allowUnsafe)
134  : _image(), _mask(), _variance() {
135  MaskedImageFitsReader reader(&fitsFile);
136  *this = reader.read<ImagePixelT, MaskPixelT, VariancePixelT>(bbox, origin, conformMasks, needAllHdus,
137  allowUnsafe);
138  if (metadata) {
139  metadata->combine(reader.readPrimaryMetadata());
140  }
141  if (imageMetadata) {
142  imageMetadata->combine(reader.readImageMetadata());
143  }
144  if (maskMetadata) {
145  maskMetadata->combine(reader.readMaskMetadata());
146  }
147  if (varianceMetadata) {
148  varianceMetadata->combine(reader.readVarianceMetadata());
149  }
150 }
151 
152 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
155  : _image(image), _mask(mask), _variance(variance) {
156  conformSizes();
157 }
158 
159 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
161  : _image(rhs._image), _mask(rhs._mask), _variance(rhs._variance) {
162  if (deep) {
163  _image = std::shared_ptr<Image>(new Image(*rhs.getImage(), deep));
164  _mask = std::shared_ptr<Mask>(new Mask(*rhs.getMask(), deep));
165  _variance = std::shared_ptr<Variance>(new Variance(*rhs.getVariance(), deep));
166  }
167  conformSizes();
168 }
169 
170 // Delegate to copy-constructor for backwards compatibility
171 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
173  : MaskedImage(rhs, false) {}
174 
175 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
177  const lsst::geom::Box2I& bbox,
178  ImageOrigin const origin, bool deep
179 
180  )
181  : _image(new Image(*rhs.getImage(), bbox, origin, deep)),
182  _mask(rhs._mask ? new Mask(*rhs.getMask(), bbox, origin, deep) : static_cast<Mask*>(NULL)),
183  _variance(rhs._variance ? new Variance(*rhs.getVariance(), bbox, origin, deep)
184  : static_cast<Variance*>(NULL)) {
185  conformSizes();
186 }
187 
188 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
190 operator=(MaskedImage const& rhs) = default;
191 
192 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
194 operator=(MaskedImage&& rhs) = default;
195 
196 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
198  using std::swap; // See Meyers, Effective C++, Item 25
199 
200  _image.swap(rhs._image);
201  _mask.swap(rhs._mask);
202  _variance.swap(rhs._variance);
203 }
204 
205 // Operators
206 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
208 operator=(MaskedImage::Pixel const& rhs) {
209  *_image = rhs.image();
210  *_mask = rhs.mask();
211  *_variance = rhs.variance();
212 
213  return *this;
214 }
215 
216 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
219  *_image = rhs.image();
220  *_mask = rhs.mask();
221  *_variance = rhs.variance();
222 
223  return *this;
224 }
225 
226 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
228  lsst::geom::Box2I const& bbox,
229  ImageOrigin origin) {
230  _image->assign(*rhs.getImage(), bbox, origin);
231  _mask->assign(*rhs.getMask(), bbox, origin);
232  _variance->assign(*rhs.getVariance(), bbox, origin);
233 }
234 
235 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
237 operator+=(MaskedImage const& rhs) {
238  *_image += *rhs.getImage();
239  *_mask |= *rhs.getMask();
240  *_variance += *rhs.getVariance();
241  return *this;
242 }
243 
244 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
246  MaskedImage const& rhs) {
247  (*_image).scaledPlus(c, *rhs.getImage());
248  *_mask |= *rhs.getMask();
249  (*_variance).scaledPlus(c * c, *rhs.getVariance());
250 }
251 
252 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
254 operator+=(ImagePixelT const rhs) {
255  *_image += rhs;
256  return *this;
257 }
258 
259 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
261 operator-=(MaskedImage const& rhs) {
262  *_image -= *rhs.getImage();
263  *_mask |= *rhs.getMask();
264  *_variance += *rhs.getVariance();
265  return *this;
266 }
267 
268 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
270  MaskedImage const& rhs) {
271  (*_image).scaledMinus(c, *rhs.getImage());
272  *_mask |= *rhs.getMask();
273  (*_variance).scaledPlus(c * c, *rhs.getVariance());
274 }
275 
276 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
278 operator-=(ImagePixelT const rhs) {
279  *_image -= rhs;
280  return *this;
281 }
282 
283 namespace {
285 template <typename ImagePixelT, typename VariancePixelT>
286 struct productVariance {
287  double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
288  return lhs * lhs * varRhs + rhs * rhs * varLhs;
289  }
290 };
291 
294 template <typename ImagePixelT, typename VariancePixelT>
295 struct scaledProductVariance {
296  double _c;
297  scaledProductVariance(double const c) : _c(c) {}
298  double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
299  return _c * _c * (lhs * lhs * varRhs + rhs * rhs * varLhs);
300  }
301 };
302 } // namespace
303 
304 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
306 operator*=(MaskedImage const& rhs) {
307  // Must do variance before we modify the image values
308  if (_image->getDimensions() != rhs._image->getDimensions()) {
310  boost::str(boost::format("Images are of different size, %dx%d v %dx%d") %
311  _image->getWidth() % _image->getHeight() % rhs._image->getWidth() % rhs._image->getHeight()));
312  }
313  transform_pixels(_image->_getRawView(), // lhs
314  rhs._image->_getRawView(), // rhs,
315  _variance->_getRawView(), // Var(lhs),
316  rhs._variance->_getRawView(), // Var(rhs)
317  _variance->_getRawView(), // result
318  productVariance<ImagePixelT, VariancePixelT>());
319 
320  *_image *= *rhs.getImage();
321  *_mask |= *rhs.getMask();
322  return *this;
323 }
324 
325 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
327  MaskedImage const& rhs) {
328  // Must do variance before we modify the image values
329  if (_image->getDimensions() != rhs._image->getDimensions()) {
331  boost::str(boost::format("Images are of different size, %dx%d v %dx%d") %
332  _image->getWidth() % _image->getHeight() % rhs._image->getWidth() % rhs._image->getHeight()));
333  }
334  transform_pixels(_image->_getRawView(), // lhs
335  rhs._image->_getRawView(), // rhs,
336  _variance->_getRawView(), // Var(lhs),
337  rhs._variance->_getRawView(), // Var(rhs)
338  _variance->_getRawView(), // result
339  scaledProductVariance<ImagePixelT, VariancePixelT>(c));
340 
341  (*_image).scaledMultiplies(c, *rhs.getImage());
342  *_mask |= *rhs.getMask();
343 }
344 
345 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
347 operator*=(ImagePixelT const rhs) {
348  *_image *= rhs;
349  *_variance *= rhs * rhs;
350  return *this;
351 }
352 
353 namespace {
355 template <typename ImagePixelT, typename VariancePixelT>
356 struct quotientVariance {
357  double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
358  ImagePixelT const rhs2 = rhs * rhs;
359  return (lhs * lhs * varRhs + rhs2 * varLhs) / (rhs2 * rhs2);
360  }
361 };
364 template <typename ImagePixelT, typename VariancePixelT>
365 struct scaledQuotientVariance {
366  double _c;
367  scaledQuotientVariance(double c) : _c(c) {}
368  double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
369  ImagePixelT const rhs2 = rhs * rhs;
370  return (lhs * lhs * varRhs + rhs2 * varLhs) / (_c * _c * rhs2 * rhs2);
371  }
372 };
373 } // namespace
374 
375 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
377 operator/=(MaskedImage const& rhs) {
378  // Must do variance before we modify the image values
379  if (_image->getDimensions() != rhs._image->getDimensions()) {
381  boost::str(boost::format("Images are of different size, %dx%d v %dx%d") %
382  _image->getWidth() % _image->getHeight() % rhs._image->getWidth() % rhs._image->getHeight()));
383  }
384  transform_pixels(_image->_getRawView(), // lhs
385  rhs._image->_getRawView(), // rhs,
386  _variance->_getRawView(), // Var(lhs),
387  rhs._variance->_getRawView(), // Var(rhs)
388  _variance->_getRawView(), // result
389  quotientVariance<ImagePixelT, VariancePixelT>());
390 
391  *_image /= *rhs.getImage();
392  *_mask |= *rhs.getMask();
393  return *this;
394 }
395 
396 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
398  MaskedImage const& rhs) {
399  // Must do variance before we modify the image values
400  if (_image->getDimensions() != rhs._image->getDimensions()) {
402  str(boost::format("Images are of different size, %dx%d v %dx%d") %
403  _image->getWidth() % _image->getHeight() % rhs._image->getWidth() % rhs._image->getHeight()));
404  }
405  transform_pixels(_image->_getRawView(), // lhs
406  rhs._image->_getRawView(), // rhs,
407  _variance->_getRawView(), // Var(lhs),
408  rhs._variance->_getRawView(), // Var(rhs)
409  _variance->_getRawView(), // result
410  scaledQuotientVariance<ImagePixelT, VariancePixelT>(c));
411 
412  (*_image).scaledDivides(c, *rhs.getImage());
413  *_mask |= *rhs._mask;
414 }
415 
416 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
418 operator/=(ImagePixelT const rhs) {
419  *_image /= rhs;
420  *_variance /= rhs * rhs;
421  return *this;
422 }
423 
424 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
429  std::shared_ptr<daf::base::PropertySet const> varianceMetadata) const {
430  fits::Fits fitsfile(fileName, "w", fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
431  writeFits(fitsfile, metadata, imageMetadata, maskMetadata, varianceMetadata);
432 }
433 
434 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
439  std::shared_ptr<daf::base::PropertySet const> varianceMetadata) const {
440  fits::Fits fitsfile(manager, "w", fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
441  writeFits(fitsfile, metadata, imageMetadata, maskMetadata, varianceMetadata);
442 }
443 
444 namespace {
445 
446 void processPlaneMetadata(std::shared_ptr<daf::base::PropertySet const> metadata,
447  std::shared_ptr<daf::base::PropertySet>& hdr, char const* exttype) {
448  if (metadata) {
449  hdr = metadata->deepCopy();
450  } else {
451  hdr.reset(new daf::base::PropertyList());
452  }
453  hdr->set("INHERIT", true);
454  hdr->set("EXTTYPE", exttype);
455  hdr->set("EXTNAME", exttype);
456 }
457 
458 } // namespace
459 
460 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
465  std::shared_ptr<daf::base::PropertySet const> varianceMetadata) const {
466  writeFits(fitsfile, fits::ImageWriteOptions(*_image), fits::ImageWriteOptions(*_mask),
467  fits::ImageWriteOptions(*_variance), metadata, imageMetadata, maskMetadata, varianceMetadata);
468 }
469 
470 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
472  std::string const& fileName, fits::ImageWriteOptions const& imageOptions,
473  fits::ImageWriteOptions const& maskOptions, fits::ImageWriteOptions const& varianceOptions,
477  std::shared_ptr<daf::base::PropertySet const> varianceMetadata) const {
478  fits::Fits fitsfile(fileName, "w", fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
479  writeFits(fitsfile, imageOptions, maskOptions, varianceOptions, metadata, imageMetadata, maskMetadata,
480  varianceMetadata);
481 }
482 
483 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
485  fits::MemFileManager& manager, fits::ImageWriteOptions const& imageOptions,
486  fits::ImageWriteOptions const& maskOptions, fits::ImageWriteOptions const& varianceOptions,
490  std::shared_ptr<daf::base::PropertySet const> varianceMetadata) const {
491  fits::Fits fitsfile(manager, "w", fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
492  writeFits(fitsfile, imageOptions, maskOptions, varianceOptions, metadata, imageMetadata, maskMetadata,
493  varianceMetadata);
494 }
495 
496 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
498  fits::Fits& fitsfile, fits::ImageWriteOptions const& imageOptions,
499  fits::ImageWriteOptions const& maskOptions, fits::ImageWriteOptions const& varianceOptions,
503  std::shared_ptr<daf::base::PropertySet const> varianceMetadata) const {
505  if (metadata) {
506  header = metadata->deepCopy();
507  } else {
508  header = std::make_shared<daf::base::PropertyList>();
509  }
510 
511  if (fitsfile.countHdus() != 0) {
513  "MaskedImage::writeFits can only write to an empty file");
514  }
515  if (fitsfile.getHdu() < 1) {
516  // Don't ever write images to primary; instead we make an empty primary.
517  fitsfile.createEmpty();
518  } else {
519  fitsfile.setHdu(0);
520  }
521  fitsfile.writeMetadata(*header);
522 
523  processPlaneMetadata(imageMetadata, header, "IMAGE");
524  _image->writeFits(fitsfile, imageOptions, header, _mask);
525 
526  processPlaneMetadata(maskMetadata, header, "MASK");
527  _mask->writeFits(fitsfile, maskOptions, header);
528 
529  processPlaneMetadata(varianceMetadata, header, "VARIANCE");
530  _variance->writeFits(fitsfile, varianceOptions, header, _mask);
531 }
532 
533 // private function conformSizes() ensures that the Mask and Variance have the same dimensions
534 // as Image. If Mask and/or Variance have non-zero dimensions that conflict with the size of Image,
535 // a lsst::pex::exceptions::LengthError is thrown.
536 
537 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
539  if (!_mask || _mask->getWidth() == 0 || _mask->getHeight() == 0) {
540  _mask = MaskPtr(new Mask(_image->getBBox()));
541  *_mask = 0;
542  } else {
543  if (_mask->getDimensions() != _image->getDimensions()) {
544  throw LSST_EXCEPT(
546  (boost::format("Dimension mismatch: Image %dx%d v. Mask %dx%d") % _image->getWidth() %
547  _image->getHeight() % _mask->getWidth() % _mask->getHeight())
548  .str());
549  }
550  }
551 
552  if (!_variance || _variance->getWidth() == 0 || _variance->getHeight() == 0) {
553  _variance = VariancePtr(new Variance(_image->getBBox()));
554  *_variance = 0;
555  } else {
556  if (_variance->getDimensions() != _image->getDimensions()) {
557  throw LSST_EXCEPT(
558  pex::exceptions::LengthError,
559  (boost::format("Dimension mismatch: Image %dx%d v. Variance %dx%d") % _image->getWidth() %
560  _image->getHeight() % _variance->getWidth() % _variance->getHeight())
561  .str());
562  }
563  }
564 }
565 
566 //
567 // Iterators and locators
568 //
569 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
572 #if 0 // this doesn't compile; why?
573  return iterator(_image->begin(), _mask->begin(), _variance->begin());
574 #else
575  typename Image::iterator imageBegin = _image->begin();
576  typename Mask::iterator maskBegin = _mask->begin();
577  typename Variance::iterator varianceBegin = _variance->begin();
578 
579  return iterator(imageBegin, maskBegin, varianceBegin);
580 #endif
581 }
582 
583 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
586  typename Image::iterator imageEnd = getImage()->end();
587  typename Mask::iterator maskEnd = getMask()->end();
588  typename Variance::iterator varianceEnd = getVariance()->end();
589 
590  return iterator(imageEnd, maskEnd, varianceEnd);
591 }
592 
593 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
596  typename Image::iterator imageEnd = getImage()->at(x, y);
597  typename Mask::iterator maskEnd = getMask()->at(x, y);
598  typename Variance::iterator varianceEnd = getVariance()->at(x, y);
599 
600  return iterator(imageEnd, maskEnd, varianceEnd);
601 }
602 
603 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
606  typename Image::reverse_iterator imageBegin = _image->rbegin();
607  typename Mask::reverse_iterator maskBegin = _mask->rbegin();
608  typename Variance::reverse_iterator varianceBegin = _variance->rbegin();
609 
610  return reverse_iterator(imageBegin, maskBegin, varianceBegin);
611 }
612 
613 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
616  typename Image::reverse_iterator imageEnd = getImage()->rend();
617  typename Mask::reverse_iterator maskEnd = getMask()->rend();
618  typename Variance::reverse_iterator varianceEnd = getVariance()->rend();
619 
620  return reverse_iterator(imageEnd, maskEnd, varianceEnd);
621 }
622 
623 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
626  typename Image::x_iterator imageBegin = _image->row_begin(y);
627  typename Mask::x_iterator maskBegin = _mask->row_begin(y);
628  typename Variance::x_iterator varianceBegin = _variance->row_begin(y);
629 
630  return x_iterator(imageBegin, maskBegin, varianceBegin);
631 }
632 
633 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
636  typename Image::x_iterator imageEnd = getImage()->row_end(y);
637  typename Mask::x_iterator maskEnd = getMask()->row_end(y);
638  typename Variance::x_iterator varianceEnd = getVariance()->row_end(y);
639 
640  return x_iterator(imageEnd, maskEnd, varianceEnd);
641 }
642 
643 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
646  typename Image::y_iterator imageBegin = _image->col_begin(x);
647  typename Mask::y_iterator maskBegin = _mask->col_begin(x);
648  typename Variance::y_iterator varianceBegin = _variance->col_begin(x);
649 
650  return y_iterator(imageBegin, maskBegin, varianceBegin);
651 }
652 
653 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
656  typename Image::y_iterator imageEnd = getImage()->col_end(x);
657  typename Mask::y_iterator maskEnd = getMask()->col_end(x);
658  typename Variance::y_iterator varianceEnd = getVariance()->col_end(x);
659 
660  return y_iterator(imageEnd, maskEnd, varianceEnd);
661 }
662 
663 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
666  typename Image::fast_iterator imageBegin = _image->begin(contiguous);
667  typename Mask::fast_iterator maskBegin = _mask->begin(contiguous);
668  typename Variance::fast_iterator varianceBegin = _variance->begin(contiguous);
669 
670  return fast_iterator(imageBegin, maskBegin, varianceBegin);
671 }
672 
673 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
676  typename Image::fast_iterator imageEnd = getImage()->end(contiguous);
677  typename Mask::fast_iterator maskEnd = getMask()->end(contiguous);
678  typename Variance::fast_iterator varianceEnd = getVariance()->end(contiguous);
679 
680  return fast_iterator(imageEnd, maskEnd, varianceEnd);
681 }
682 
683 template <typename ImagePixelT1, typename ImagePixelT2>
686  return imagesOverlap(*image1.getImage(), *image2.getImage()) ||
687  imagesOverlap(*image1.getVariance(), *image2.getVariance()) ||
688  imagesOverlap(*image1.getMask(), *image2.getMask());
689 }
690 
691 //
692 // Explicit instantiations
693 //
694 #define INSTANTIATE2(ImagePixelT1, ImagePixelT2) \
695  template bool imagesOverlap<ImagePixelT1, ImagePixelT2>(MaskedImage<ImagePixelT1> const&, \
696  MaskedImage<ImagePixelT2> const&);
697 
698 template class MaskedImage<std::uint16_t>;
699 template class MaskedImage<int>;
700 template class MaskedImage<float>;
701 template class MaskedImage<double>;
702 template class MaskedImage<std::uint64_t>;
703 
709 
711 INSTANTIATE2(int, int);
712 INSTANTIATE2(int, float);
713 INSTANTIATE2(int, double);
715 
717 INSTANTIATE2(float, int);
718 INSTANTIATE2(float, float);
719 INSTANTIATE2(float, double);
721 
723 INSTANTIATE2(double, int);
724 INSTANTIATE2(double, float);
725 INSTANTIATE2(double, double);
727 
733 
734 } // namespace image
735 } // namespace afw
736 } // 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:296
#define INSTANTIATE2(ImagePixelT1, ImagePixelT2)
Definition: MaskedImage.cc:694
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:245
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:425
MaskedImage(unsigned int width, unsigned int height, MaskPlaneDict const &planeDict=MaskPlaneDict())
Construct from a supplied dimensions.
Definition: MaskedImage.cc:47
lsst::afw::image::Image< VariancePixelT > Variance
Definition: MaskedImage.h:84
void scaledDivides(double const c, MaskedImage const &rhs)
Definition: MaskedImage.cc:397
MaskedImageIterator< typename Image::reverse_iterator, typename Mask::reverse_iterator, typename Variance::reverse_iterator > reverse_iterator
Definition: MaskedImage.h:547
MaskedImageIterator< typename Image::y_iterator, typename Mask::y_iterator, typename Variance::y_iterator > y_iterator
An iterator to a column of a MaskedImage.
Definition: MaskedImage.h:568
iterator begin() const
Return an iterator to the start of the image.
Definition: MaskedImage.cc:571
reverse_iterator rbegin() const
Return a reverse_iterator to the start of the image.
Definition: MaskedImage.cc:605
y_iterator col_end(int x) const
Return an y_iterator to the end of the image.
Definition: MaskedImage.cc:655
void scaledMinus(double const c, MaskedImage const &rhs)
Subtract a scaled MaskedImage c*rhs from a MaskedImage.
Definition: MaskedImage.cc:269
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:278
x_iterator row_end(int y) const
Return an x_iterator to the end of the image.
Definition: MaskedImage.cc:635
void scaledMultiplies(double const c, MaskedImage const &rhs)
Definition: MaskedImage.cc:326
iterator end() const
Return an iterator to the end of the image.
Definition: MaskedImage.cc:585
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:227
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:625
void swap(MaskedImage &rhs)
Definition: MaskedImage.cc:197
y_iterator col_begin(int x) const
Return an y_iterator to the start of the image.
Definition: MaskedImage.cc:645
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:615
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:254
MaskedImage & operator*=(ImagePixelT const rhs)
Definition: MaskedImage.cc:347
iterator at(int const x, int const y) const
Return an iterator at the point (x, y)
Definition: MaskedImage.cc:595
MaskedImage & operator/=(ImagePixelT const rhs)
Definition: MaskedImage.cc:418
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:705
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)