LSSTApplications  11.0-13-gbb96280,12.1+18,12.1+7,12.1-1-g14f38d3+72,12.1-1-g16c0db7+5,12.1-1-g5961e7a+84,12.1-1-ge22e12b+23,12.1-11-g06625e2+4,12.1-11-g0d7f63b+4,12.1-19-gd507bfc,12.1-2-g7dda0ab+38,12.1-2-gc0bc6ab+81,12.1-21-g6ffe579+2,12.1-21-gbdb6c2a+4,12.1-24-g941c398+5,12.1-3-g57f6835+7,12.1-3-gf0736f3,12.1-37-g3ddd237,12.1-4-gf46015e+5,12.1-5-g06c326c+20,12.1-5-g648ee80+3,12.1-5-gc2189d7+4,12.1-6-ga608fc0+1,12.1-7-g3349e2a+5,12.1-7-gfd75620+9,12.1-9-g577b946+5,12.1-9-gc4df26a+10
LSSTDataManagementBasePackage
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 
29 #include <cstdint>
30 #include <typeinfo>
31 #include <sys/stat.h>
32 #pragma clang diagnostic push
33 #pragma clang diagnostic ignored "-Wunused-variable"
34 #pragma clang diagnostic pop
35 #include "boost/regex.hpp"
36 #include "boost/filesystem/path.hpp"
37 #include "lsst/log/Log.h"
38 #include "lsst/pex/exceptions.h"
39 #include "boost/algorithm/string/trim.hpp"
40 
43 #include "lsst/afw/fits.h"
44 
45 namespace image = lsst::afw::image;
46 
51 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
53  unsigned int width,
54  unsigned int height,
55  MaskPlaneDict const& planeDict
56 ) :
57  lsst::daf::base::Citizen(typeid(this)),
58  _image(new Image(width, height)),
59  _mask(new Mask(width, height, planeDict)),
60  _variance(new Variance(width, height)) {
61  *_image = 0;
62  *_mask = 0x0;
63  *_variance = 0;
64 }
65 
70 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
72  geom::Extent2I const & dimensions,
73  MaskPlaneDict const& planeDict
74 ) :
75  lsst::daf::base::Citizen(typeid(this)),
76  _image(new Image(dimensions)),
77  _mask(new Mask(dimensions, planeDict)),
78  _variance(new Variance(dimensions)) {
79  *_image = 0;
80  *_mask = 0x0;
81  *_variance = 0;
82 }
83 
92 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
94  geom::Box2I const & bbox,
95  MaskPlaneDict const& planeDict
96 ) :
97  lsst::daf::base::Citizen(typeid(this)),
98  _image(new Image(bbox)),
99  _mask(new Mask(bbox, planeDict)),
100  _variance(new Variance(bbox)) {
101  *_image = 0;
102  *_mask = 0x0;
103  *_variance = 0;
104 }
105 
106 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
108  std::string const & fileName, PTR(daf::base::PropertySet) metadata,
109  geom::Box2I const & bbox, ImageOrigin origin, bool conformMasks, bool needAllHdus,
110  PTR(daf::base::PropertySet) imageMetadata,
111  PTR(daf::base::PropertySet) maskMetadata,
112  PTR(daf::base::PropertySet) varianceMetadata
113 ) : lsst::daf::base::Citizen(typeid(this)),
114  _image(), _mask(), _variance()
115 {
116  fits::Fits fitsfile(fileName, "r", fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
117  *this = MaskedImage(fitsfile, metadata, bbox, origin, conformMasks, needAllHdus,
118  imageMetadata, maskMetadata, varianceMetadata);
119  }
120 
121 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
123  fits::MemFileManager & manager, PTR(daf::base::PropertySet) metadata,
124  geom::Box2I const & bbox, ImageOrigin origin, bool conformMasks, bool needAllHdus,
125  PTR(daf::base::PropertySet) imageMetadata,
126  PTR(daf::base::PropertySet) maskMetadata,
127  PTR(daf::base::PropertySet) varianceMetadata
128 ) : lsst::daf::base::Citizen(typeid(this)),
129  _image(), _mask(), _variance()
130 {
131  fits::Fits fitsfile(manager, "r", fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
132  *this = MaskedImage(fitsfile, metadata, bbox, origin, conformMasks, needAllHdus,
133  imageMetadata, maskMetadata, varianceMetadata);
134 }
135 
136 namespace {
137 
138 // Helper functions for MaskedImage FITS ctor.
139 
140 void checkExtType(
141  lsst::afw::fits::Fits & fitsfile,
143  std::string const & expected
144 ) {
145  try {
146  std::string exttype = boost::algorithm::trim_right_copy(metadata->getAsString("EXTTYPE"));
147  if (exttype != "" && exttype != expected) {
148  throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
149  (boost::format("Reading %s (hdu %d) Expected EXTTYPE==\"%s\", saw \"%s\"") %
150  expected % fitsfile.getFileName() % fitsfile.getHdu() % exttype).str());
151  }
152  metadata->remove("EXTTYPE");
153  } catch(lsst::pex::exceptions::NotFoundError) {
154  LOGLS_WARN("afw.image.MaskedImage", "Expected extension type not found: " << expected);
155  }
156 }
157 
158 void ensureMetadata(PTR(lsst::daf::base::PropertySet) & metadata) {
159  if (!metadata) {
160  metadata.reset(new lsst::daf::base::PropertyList());
161  }
162 }
163 
164 } // anonymous
165 
166 
167 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
169  fits::Fits & fitsfile, PTR(daf::base::PropertySet) metadata,
170  geom::Box2I const & bbox, ImageOrigin origin, bool conformMasks, bool needAllHdus,
171  PTR(daf::base::PropertySet) imageMetadata,
172  PTR(daf::base::PropertySet) maskMetadata,
173  PTR(daf::base::PropertySet) varianceMetadata
174 ) : lsst::daf::base::Citizen(typeid(this)),
175  _image(), _mask(), _variance()
176 {
177  // When reading a standard Masked Image, we expect four HDUs:
178  // * The primary (HDU 1) is empty;
179  // * The first extension (HDU 2) contains the image data;
180  // * The second extension (HDU 3) contains mask data;
181  // * The third extension (HDU 4) contains the variance.
182  //
183  // If the image HDU is unreadable, we will throw.
184  //
185  // If the user has specified a non-default HDU, we load image data from
186  // that HDU, but do not attempt to load mask/variance data; rather, log a
187  // warning and return (blank) defaults.
188  //
189  // If the mask and/or variance is unreadable, we log a warning and return
190  // (blank) defaults.
191 
192  LOG_LOGGER _log = LOG_GET("afw.image.MaskedImage");
193 
194  enum class Hdu {
195  Primary = 1,
196  Image,
197  Mask,
198  Variance
199  };
200 
201  // If the user has requested a non-default HDU and we require all HDUs, we fail.
202  if (needAllHdus && fitsfile.getHdu() > static_cast<int>(Hdu::Image)) {
203  throw LSST_EXCEPT(fits::FitsError,
204  "Cannot read all HDUs starting from non-default");
205  }
206 
207  if (metadata) {
208  // Read primary metadata - only if user asks for it.
209  // If the primary HDU is not empty, this may be the same as imageMetadata.
210  auto prevHdu = fitsfile.getHdu();
211  fitsfile.setHdu(static_cast<int>(Hdu::Primary));
212  fitsfile.readMetadata(*metadata);
213  fitsfile.setHdu(prevHdu);
214  }
215 
216  // setHdu(0) jumps to the first extension iff the primary HDU is both
217  // empty and currently selected.
218  fitsfile.setHdu(0);
219  ensureMetadata(imageMetadata);
220  _image.reset(new Image(fitsfile, imageMetadata, bbox, origin));
221  checkExtType(fitsfile, imageMetadata, "IMAGE");
222 
223  if (fitsfile.getHdu() != static_cast<int>(Hdu::Image)) {
224  // Reading the image from a non-default HDU means we do not attempt to
225  // read mask and variance.
226  _mask.reset(new Mask(_image->getBBox()));
227  _variance.reset(new Variance(_image->getBBox()));
228  } else {
229  try {
230  fitsfile.setHdu(static_cast<int>(Hdu::Mask));
231  ensureMetadata(maskMetadata);
232  _mask.reset(new Mask(fitsfile, maskMetadata, bbox, origin, conformMasks));
233  checkExtType(fitsfile, maskMetadata, "MASK");
234  } catch(fits::FitsError &e) {
235  if (needAllHdus) {
236  LSST_EXCEPT_ADD(e, "Reading Mask");
237  throw e;
238  }
239  LOGLS_WARN(_log, "Mask unreadable; using default");
240  // By resetting the status we are able to read the next HDU (the variance).
241  fitsfile.status = 0;
242  _mask.reset(new Mask(_image->getBBox()));
243  }
244 
245  try {
246  fitsfile.setHdu(static_cast<int>(Hdu::Variance));
247  ensureMetadata(varianceMetadata);
248  _variance.reset(new Variance(fitsfile, varianceMetadata, bbox, origin));
249  checkExtType(fitsfile, varianceMetadata, "VARIANCE");
250  } catch(fits::FitsError &e) {
251  if (needAllHdus) {
252  LSST_EXCEPT_ADD(e, "Reading Variance");
253  throw e;
254  }
255  LOGLS_WARN(_log, "Variance unreadable; using default");
256  fitsfile.status = 0;
257  _variance.reset(new Variance(_image->getBBox()));
258  }
259  }
260 }
261 
266 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
268  ImagePtr image,
269  MaskPtr mask,
270  VariancePtr variance
271 ) :
272  lsst::daf::base::Citizen(typeid(this)),
273  _image(image),
274  _mask(mask),
275  _variance(variance) {
276  conformSizes();
277 }
278 
282 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
284  MaskedImage const& rhs,
285  bool deep
286 ) :
287  lsst::daf::base::Citizen(typeid(this)),
288  _image(rhs._image), _mask(rhs._mask), _variance(rhs._variance) {
289  if (deep) {
290  _image = typename Image::Ptr(new Image(*rhs.getImage(), deep));
291  _mask = typename Mask::Ptr(new Mask(*rhs.getMask(), deep));
292  _variance = typename Variance::Ptr(new Variance(*rhs.getVariance(), deep));
293  }
294  conformSizes();
295 }
296 
300 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
302  MaskedImage const& rhs,
303  const geom::Box2I& bbox,
304  ImageOrigin const origin,
305  bool deep
306 ) :
308  lsst::daf::base::Citizen(typeid(this)),
309  _image(new Image(*rhs.getImage(), bbox, origin, deep)),
310  _mask(rhs._mask ? new Mask(*rhs.getMask(), bbox, origin, deep) : static_cast<Mask *>(NULL)),
311  _variance(rhs._variance ? new Variance(*rhs.getVariance(), bbox, origin, deep) : static_cast<Variance *>(NULL)) {
312  conformSizes();
313 }
314 
315 #if defined(DOXYGEN)
316 
323 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
325  ) {}
326 #endif
327 
328 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
330  using std::swap; // See Meyers, Effective C++, Item 25
331 
332  _image.swap(rhs._image);
333  _mask.swap(rhs._mask);
334  _variance.swap(rhs._variance);
335 }
336 // Use compiler generated version of:
337 // MaskedImage<ImagePixelT, MaskPixelT> &operator=(const MaskedImage<ImagePixelT, MaskPixelT>& rhs);
338 
339 /************************************************************************************************************/
340 // Operators
344 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
347  *_image = rhs.image();
348  *_mask = rhs.mask();
349  *_variance = rhs.variance();
350 
351  return *this;
352 }
353 
357 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
360  *_image = rhs.image();
361  *_mask = rhs.mask();
362  *_variance = rhs.variance();
363 
364  return *this;
365 }
366 
374 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
376  assign(rhs);
377 }
378 
390 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
392  geom::Box2I const &bbox, ImageOrigin origin) {
393  _image->assign(*rhs.getImage(), bbox, origin);
394  _mask->assign(*rhs.getMask(), bbox, origin);
395  _variance->assign(*rhs.getVariance(), bbox, origin);
396 }
397 
405 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
407  *_image += *rhs.getImage();
408  *_mask |= *rhs.getMask();
409  *_variance += *rhs.getVariance();
410 }
411 
419 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
421  MaskedImage const& rhs) {
422  (*_image).scaledPlus(c, *rhs.getImage());
423  *_mask |= *rhs.getMask();
424  (*_variance).scaledPlus(c*c, *rhs.getVariance());
425 }
426 
428 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
430  *_image += rhs;
431 }
432 
438 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
440  *_image -= *rhs.getImage();
441  *_mask |= *rhs.getMask();
442  *_variance += *rhs.getVariance();
443 }
444 
450 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
452  MaskedImage const& rhs) {
453  (*_image).scaledMinus(c, *rhs.getImage());
454  *_mask |= *rhs.getMask();
455  (*_variance).scaledPlus(c*c, *rhs.getVariance());
456 }
457 
459 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
461  *_image -= rhs;
462 }
463 
464 namespace {
466  template<typename ImagePixelT, typename VariancePixelT>
467  struct productVariance {
468  double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
469  return lhs*lhs*varRhs + rhs*rhs*varLhs;
470  }
471  };
472 
474  template<typename ImagePixelT, typename VariancePixelT>
475  struct scaledProductVariance {
476  double _c;
477  scaledProductVariance(double const c) : _c(c) {}
478  double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
479  return _c*_c*(lhs*lhs*varRhs + rhs*rhs*varLhs);
480  }
481  };
482 }
483 
484 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
486  // Must do variance before we modify the image values
487  transform_pixels(_image->_getRawView(), // lhs
488  rhs._image->_getRawView(), // rhs,
489  _variance->_getRawView(), // Var(lhs),
490  rhs._variance->_getRawView(), // Var(rhs)
491  _variance->_getRawView(), // result
492  productVariance<ImagePixelT, VariancePixelT>());
493 
494  *_image *= *rhs.getImage();
495  *_mask |= *rhs.getMask();
496 }
497 
498 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
500  MaskedImage const& rhs) {
501  // Must do variance before we modify the image values
502  transform_pixels(_image->_getRawView(), // lhs
503  rhs._image->_getRawView(), // rhs,
504  _variance->_getRawView(), // Var(lhs),
505  rhs._variance->_getRawView(), // Var(rhs)
506  _variance->_getRawView(), // result
507  scaledProductVariance<ImagePixelT, VariancePixelT>(c));
508 
509  (*_image).scaledMultiplies(c, *rhs.getImage());
510  *_mask |= *rhs.getMask();
511 }
512 
513 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
515  *_image *= rhs;
516  *_variance *= rhs*rhs;
517 }
518 
519 
520 namespace {
522  template<typename ImagePixelT, typename VariancePixelT>
523  struct quotientVariance {
524  double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
525  ImagePixelT const rhs2 = rhs*rhs;
526  return (lhs*lhs*varRhs + rhs2*varLhs)/(rhs2*rhs2);
527  }
528  };
530  template<typename ImagePixelT, typename VariancePixelT>
531  struct scaledQuotientVariance {
532  double _c;
533  scaledQuotientVariance(double c) : _c(c) {}
534  double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
535  ImagePixelT const rhs2 = rhs*rhs;
536  return (lhs*lhs*varRhs + rhs2*varLhs)/(_c*_c*rhs2*rhs2);
537  }
538  };
539 }
540 
541 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
543  // Must do variance before we modify the image values
544  transform_pixels(_image->_getRawView(), // lhs
545  rhs._image->_getRawView(), // rhs,
546  _variance->_getRawView(), // Var(lhs),
547  rhs._variance->_getRawView(), // Var(rhs)
548  _variance->_getRawView(), // result
549  quotientVariance<ImagePixelT, VariancePixelT>());
550 
551  *_image /= *rhs.getImage();
552  *_mask |= *rhs.getMask();
553 }
554 
555 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
557  MaskedImage const& rhs) {
558  // Must do variance before we modify the image values
559  transform_pixels(_image->_getRawView(), // lhs
560  rhs._image->_getRawView(), // rhs,
561  _variance->_getRawView(), // Var(lhs),
562  rhs._variance->_getRawView(), // Var(rhs)
563  _variance->_getRawView(), // result
564  scaledQuotientVariance<ImagePixelT, VariancePixelT>(c));
565 
566  (*_image).scaledDivides(c, *rhs.getImage());
567  *_mask |= *rhs._mask;
568 }
569 
570 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
572  *_image /= rhs;
573  *_variance /= rhs*rhs;
574 }
575 
576 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
578  std::string const& fileName,
580  CONST_PTR(daf::base::PropertySet) imageMetadata,
581  CONST_PTR(daf::base::PropertySet) maskMetadata,
582  CONST_PTR(daf::base::PropertySet) varianceMetadata
583 ) const {
584  fits::Fits fitsfile(fileName, "w", fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
585  writeFits(fitsfile, metadata, imageMetadata, maskMetadata, varianceMetadata);
586 }
587 
588 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
590  fits::MemFileManager & manager,
592  CONST_PTR(daf::base::PropertySet) imageMetadata,
593  CONST_PTR(daf::base::PropertySet) maskMetadata,
594  CONST_PTR(daf::base::PropertySet) varianceMetadata
595 ) const {
596  fits::Fits fitsfile(manager, "w", fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
597  writeFits(fitsfile, metadata, imageMetadata, maskMetadata, varianceMetadata);
598 }
599 
600 namespace {
601 
602 void processPlaneMetadata(
605  char const * exttype
606 ) {
607  if (metadata) {
608  hdr = metadata->deepCopy();
609  } else {
610  hdr.reset(new lsst::daf::base::PropertyList());
611  }
612  hdr->set("INHERIT", true);
613  hdr->set("EXTTYPE", exttype);
614 }
615 
616 } // anonymous
617 
618 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
620  fits::Fits & fitsfile,
622  CONST_PTR(daf::base::PropertySet) imageMetadata,
623  CONST_PTR(daf::base::PropertySet) maskMetadata,
624  CONST_PTR(daf::base::PropertySet) varianceMetadata
625 ) const {
626 
628  if (metadata) {
629  hdr = metadata->deepCopy();
630  } else {
631  hdr.reset(new daf::base::PropertyList());
632  }
633 
634  if (fitsfile.countHdus() != 0) {
635  throw LSST_EXCEPT(
636  pex::exceptions::LogicError,
637  "MaskedImage::writeFits can only write to an empty file"
638  );
639  }
640  if (fitsfile.getHdu() <= 1) {
641  // Don't ever write images to primary; instead we make an empty primary.
642  fitsfile.createEmpty();
643  } else {
644  fitsfile.setHdu(1);
645  }
646  fitsfile.writeMetadata(*hdr);
647 
648  processPlaneMetadata(imageMetadata, hdr, "IMAGE");
649  _image->writeFits(fitsfile, hdr);
650 
651  processPlaneMetadata(maskMetadata, hdr, "MASK");
652  _mask->writeFits(fitsfile, hdr);
653 
654  processPlaneMetadata(varianceMetadata, hdr, "VARIANCE");
655  _variance->writeFits(fitsfile, hdr);
656 }
657 
658 /************************************************************************************************************/
659 // private function conformSizes() ensures that the Mask and Variance have the same dimensions
660 // as Image. If Mask and/or Variance have non-zero dimensions that conflict with the size of Image,
661 // a lsst::pex::exceptions::LengthError is thrown.
662 
663 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
665 
666  if (!_mask || _mask->getWidth() == 0 || _mask->getHeight() == 0) {
667  _mask = MaskPtr(new Mask(_image->getBBox()));
668  *_mask = 0;
669  } else {
670  if (_mask->getDimensions() != _image->getDimensions()) {
671  throw LSST_EXCEPT(
672  lsst::pex::exceptions::LengthError,
673  (boost::format("Dimension mismatch: Image %dx%d v. Mask %dx%d") %
674  _image->getWidth() % _image->getHeight() %
675  _mask->getWidth() % _mask->getHeight()
676  ).str()
677  );
678  }
679  }
680 
681  if (!_variance || _variance->getWidth() == 0 || _variance->getHeight() == 0) {
682  _variance = VariancePtr(new Variance(_image->getBBox()));
683  *_variance = 0;
684  } else {
685  if (_variance->getDimensions() != _image->getDimensions()) {
686  throw LSST_EXCEPT(
687  lsst::pex::exceptions::LengthError,
688  (boost::format("Dimension mismatch: Image %dx%d v. Variance %dx%d") %
689  _image->getWidth() % _image->getHeight() %
690  _variance->getWidth() % _variance->getHeight()
691  ).str()
692  );
693  }
694  }
695 }
696 
697 /************************************************************************************************************/
698 //
699 // Iterators and locators
700 //
702 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
704 #if 0 // this doesn't compile; why?
705  return iterator(_image->begin(), _mask->begin(), _variance->begin());
706 #else
707  typename Image::iterator imageBegin = _image->begin();
708  typename Mask::iterator maskBegin = _mask->begin();
709  typename Variance::iterator varianceBegin = _variance->begin();
710 
711  return iterator(imageBegin, maskBegin, varianceBegin);
712 #endif
713 }
714 
716 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
718  typename Image::iterator imageEnd = getImage()->end();
719  typename Mask::iterator maskEnd = getMask()->end();
720  typename Variance::iterator varianceEnd = getVariance()->end();
721 
722  return iterator(imageEnd, maskEnd, varianceEnd);
723 }
724 
726 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
728  typename Image::iterator imageEnd = getImage()->at(x, y);
729  typename Mask::iterator maskEnd = getMask()->at(x, y);
730  typename Variance::iterator varianceEnd = getVariance()->at(x, y);
731 
732  return iterator(imageEnd, maskEnd, varianceEnd);
733 }
734 
736 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
738  typename Image::reverse_iterator imageBegin = _image->rbegin();
739  typename Mask::reverse_iterator maskBegin = _mask->rbegin();
740  typename Variance::reverse_iterator varianceBegin = _variance->rbegin();
741 
742  return reverse_iterator(imageBegin, maskBegin, varianceBegin);
743 }
744 
746 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
748  typename Image::reverse_iterator imageEnd = getImage()->rend();
749  typename Mask::reverse_iterator maskEnd = getMask()->rend();
750  typename Variance::reverse_iterator varianceEnd = getVariance()->rend();
751 
752  return reverse_iterator(imageEnd, maskEnd, varianceEnd);
753 }
754 
756 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
758  typename Image::x_iterator imageBegin = _image->row_begin(y);
759  typename Mask::x_iterator maskBegin = _mask->row_begin(y);
760  typename Variance::x_iterator varianceBegin = _variance->row_begin(y);
761 
762  return x_iterator(imageBegin, maskBegin, varianceBegin);
763 }
764 
766 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
768  typename Image::x_iterator imageEnd = getImage()->row_end(y);
769  typename Mask::x_iterator maskEnd = getMask()->row_end(y);
770  typename Variance::x_iterator varianceEnd = getVariance()->row_end(y);
771 
772  return x_iterator(imageEnd, maskEnd, varianceEnd);
773 }
774 
775 /************************************************************************************************************/
776 
778 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
780  typename Image::y_iterator imageBegin = _image->col_begin(x);
781  typename Mask::y_iterator maskBegin = _mask->col_begin(x);
782  typename Variance::y_iterator varianceBegin = _variance->col_begin(x);
783 
784  return y_iterator(imageBegin, maskBegin, varianceBegin);
785 }
786 
788 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
790  typename Image::y_iterator imageEnd = getImage()->col_end(x);
791  typename Mask::y_iterator maskEnd = getMask()->col_end(x);
792  typename Variance::y_iterator varianceEnd = getVariance()->col_end(x);
793 
794  return y_iterator(imageEnd, maskEnd, varianceEnd);
795 }
796 
797 /************************************************************************************************************/
805 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
808  bool contiguous
809  ) const {
810  typename Image::fast_iterator imageBegin = _image->begin(contiguous);
811  typename Mask::fast_iterator maskBegin = _mask->begin(contiguous);
812  typename Variance::fast_iterator varianceBegin = _variance->begin(contiguous);
813 
814  return fast_iterator(imageBegin, maskBegin, varianceBegin);
815 }
816 
822 template<typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
825  bool contiguous
826  ) const {
827  typename Image::fast_iterator imageEnd = getImage()->end(contiguous);
828  typename Mask::fast_iterator maskEnd = getMask()->end(contiguous);
829  typename Variance::fast_iterator varianceEnd = getVariance()->end(contiguous);
830 
831  return fast_iterator(imageEnd, maskEnd, varianceEnd);
832 }
833 
834 /************************************************************************************************************/
835 //
836 // Explicit instantiations
837 //
838 template class image::MaskedImage<std::uint16_t>;
839 template class image::MaskedImage<int>;
840 template class image::MaskedImage<float>;
841 template class image::MaskedImage<double>;
842 template class image::MaskedImage<std::uint64_t>;
843 
#define LOGLS_WARN(logger, message)
Log a warn-level message using an iostream-based interface.
Definition: Log.h:657
int y
x_iterator row_begin(int y) const
Return an x_iterator to the start of the image.
Definition: MaskedImage.cc:757
VariancePixelT variance() const
Return the variance part of a Pixel.
Definition: Pixel.h:204
Image< VariancePixelT >::Ptr VariancePtr
shared pointer to the variance Image
Definition: MaskedImage.h:86
void scaledDivides(double const c, MaskedImage const &rhs)
Definition: MaskedImage.cc:556
int getHdu()
Return the current HDU (1-indexed; 1 is the Primary HDU).
x_iterator fast_iterator
A fast STL compliant iterator for contiguous images N.b.
Definition: Image.h:153
#define LOG_LOGGER
Definition: Log.h:712
_view_t::reverse_iterator reverse_iterator
An STL compliant reverse iterator.
Definition: Image.h:146
void writeMetadata(daf::base::PropertySet const &metadata)
Read a FITS header into a PropertySet or PropertyList.
iterator begin() const
Return an iterator to the start of the image.
Definition: MaskedImage.cc:703
void set(std::string const &name, T const &value)
Replace all values for a property name (possibly hierarchical) with a new value.
Definition: PropertySet.cc:581
virtual Ptr deepCopy(void) const
Copy the PropertySet and all of its contents.
Definition: PropertySet.cc:70
void operator<<=(MaskedImage const &rhs)
Copy the pixels from the rhs to the lhs.
Definition: MaskedImage.cc:375
Class for storing ordered metadata with comments.
Definition: PropertyList.h:82
VariancePixelT variance() const
Definition: Pixel.h:83
Include files required for standard LSST Exception handling.
void operator/=(ImagePixelT const rhs)
Definition: MaskedImage.cc:571
void scaledPlus(double const c, MaskedImage const &rhs)
Add a scaled MaskedImage c*rhs to a MaskedImage.
Definition: MaskedImage.cc:420
void writeFits(std::string const &fileName, boost::shared_ptr< daf::base::PropertySet const > metadata=boost::shared_ptr< daf::base::PropertySet const >(), boost::shared_ptr< daf::base::PropertySet const > imageMetadata=boost::shared_ptr< daf::base::PropertySet const >(), boost::shared_ptr< daf::base::PropertySet const > maskMetadata=boost::shared_ptr< daf::base::PropertySet const >(), boost::shared_ptr< daf::base::PropertySet const > varianceMetadata=boost::shared_ptr< daf::base::PropertySet const >()) const
Write a MaskedImage to a regular FITS file.
Definition: MaskedImage.cc:577
iterator at(int const x, int const y) const
Return an iterator at the point (x, y)
Definition: MaskedImage.cc:727
_view_t::x_iterator x_iterator
An iterator for traversing the pixels in a row.
Definition: Image.h:150
x_iterator row_end(int y) const
Return an x_iterator to the end of the image.
Definition: MaskedImage.cc:767
ImagePtr getImage(bool const noThrow=false) const
Return a (Ptr to) the MaskedImage&#39;s image.
Definition: MaskedImage.h:875
A single pixel of the same type as a MaskedImage.
Definition: Pixel.h:64
MaskPixelT mask() const
Return the mask part of a Pixel.
Definition: Pixel.h:202
void swap(Mask< PixelT > &a, Mask< PixelT > &b)
Definition: Mask.cc:524
void swap(MaskedImage &rhs)
Definition: MaskedImage.cc:329
A simple struct that combines the two arguments that must be passed to most cfitsio routines and cont...
Definition: fits.h:202
lsst::afw::image::Mask< MaskPixelT > Mask
Definition: MaskedImage.h:95
int countHdus()
Return the number of HDUs in the file.
MaskedImage(unsigned int width, unsigned int height, MaskPlaneDict const &planeDict=MaskPlaneDict())
Constructors.
Definition: MaskedImage.cc:52
MaskPixelT mask() const
Definition: Pixel.h:82
void operator-=(ImagePixelT const rhs)
Subtract a scalar rhs from a MaskedImage.
Definition: MaskedImage.cc:460
void operator+=(ImagePixelT const rhs)
Add a scalar rhs to a MaskedImage.
Definition: MaskedImage.cc:429
An integer coordinate rectangle.
Definition: Box.h:53
Mask< MaskPixelT >::MaskPlaneDict MaskPlaneDict
The Mask&#39;s MaskPlaneDict.
Definition: MaskedImage.h:91
VariancePtr getVariance(bool const noThrow=false) const
Return a (Ptr to) the MaskedImage&#39;s variance.
Definition: MaskedImage.h:896
table::Key< table::Array< Kernel::Pixel > > image
Definition: FixedKernel.cc:117
LSST DM logging module built on log4cxx.
_view_t::iterator iterator
An STL compliant iterator.
Definition: Image.h:142
afw::table::PointKey< int > dimensions
Definition: GaussianPsf.cc:42
reverse_iterator rbegin() const
Return a reverse_iterator to the start of the image.
Definition: MaskedImage.cc:737
void ImageT ImageT int float saturatedPixelValue int const width
Definition: saturated.cc:44
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:92
Lifetime-management for memory that goes into FITS memory files.
Definition: fits.h:106
iterator end() const
Return an iterator to the end of the image.
Definition: MaskedImage.cc:717
MaskPtr getMask(bool const noThrow=false) const
Return a (Ptr to) the MaskedImage&#39;s mask.
Definition: MaskedImage.h:885
A class to manipulate images, masks, and variance as a single object.
Definition: MaskedImage.h:78
_view_t::y_iterator y_iterator
An iterator for traversing the pixels in a column.
Definition: Image.h:159
ImagePixelT image() const
Return the image part of a Pixel.
Definition: Pixel.h:200
std::shared_ptr< Image< ImagePixelT > > Ptr
Definition: Image.h:419
double x
reverse_iterator rend() const
Return a reverse_iterator to the end of the image.
Definition: MaskedImage.cc:747
y_iterator col_end(int x) const
Return an y_iterator to the end of the image.
Definition: MaskedImage.cc:789
ImagePixelT image() const
Definition: Pixel.h:81
void scaledMultiplies(double const c, MaskedImage const &rhs)
Definition: MaskedImage.cc:499
void setHdu(int hdu, bool relative=false)
Set the current HDU.
void ImageT ImageT int float saturatedPixelValue int const height
Definition: saturated.cc:44
Image< ImagePixelT >::Ptr ImagePtr
shared pointer to the Image
Definition: MaskedImage.h:82
Utilities for working with FITS files.
lsst::afw::image::Image< VariancePixelT > Variance
Definition: MaskedImage.h:93
std::shared_ptr< Mask > Ptr
Definition: Mask.h:94
#define LSST_EXCEPT(type,...)
Create an exception with a given type and message and optionally other arguments (dependent on the ty...
Definition: Exception.h:46
A pixel of a MaskedImage.
Definition: Pixel.h:138
Mask< MaskPixelT >::Ptr MaskPtr
shared pointer to the Mask
Definition: MaskedImage.h:84
void assign(MaskedImage const &rsh, geom::Box2I const &bbox=geom::Box2I(), ImageOrigin origin=PARENT)
Copy pixels from another masked image to a specified subregion of this masked image.
Definition: MaskedImage.cc:391
#define PTR(...)
Definition: base.h:41
Class for storing generic metadata.
Definition: PropertySet.h:82
void createEmpty()
Create an empty image HDU with NAXIS=0 at the end of the file.
void readMetadata(daf::base::PropertySet &metadata, bool strip=false)
Read a FITS header into a PropertySet or PropertyList.
void operator*=(ImagePixelT const rhs)
Definition: MaskedImage.cc:514
y_iterator col_begin(int x) const
Return an y_iterator to the start of the image.
Definition: MaskedImage.cc:779
Implementation of the Class MaskedImage.
virtual void remove(std::string const &name)
Removes all values for a property name (possibly hierarchical).
Definition: PropertySet.cc:754
lsst::afw::image::Image< ImagePixelT > Image
Definition: MaskedImage.h:94
#define CONST_PTR(...)
A shared pointer to a const object.
Definition: base.h:47
#define LOG_GET(logger)
Returns a Log object associated with logger.
Definition: Log.h:83
std::string getFileName() const
Return the file name associated with the FITS object or &quot;&lt;unknown&gt;&quot; if there is none.
#define LSST_EXCEPT_ADD(e, m)
Add the current location and a message to an existing exception before rethrowing it...
Definition: Exception.h:51
MaskedImage & operator=(MaskedImage const &rhs)
Make the lhs use the rhs&#39;s pixels.
Definition: MaskedImage.cc:324
std::string getAsString(std::string const &name) const
Get the last value for a string property name (possibly hierarchical).
Definition: PropertySet.cc:444
void scaledMinus(double const c, MaskedImage const &rhs)
Subtract a scaled MaskedImage c*rhs from a MaskedImage.
Definition: MaskedImage.cc:451