LSSTApplications  16.0-10-g0ee56ad+5,16.0-11-ga33d1f2+5,16.0-12-g3ef5c14+3,16.0-12-g71e5ef5+18,16.0-12-gbdf3636+3,16.0-13-g118c103+3,16.0-13-g8f68b0a+3,16.0-15-gbf5c1cb+4,16.0-16-gfd17674+3,16.0-17-g7c01f5c+3,16.0-18-g0a50484+1,16.0-20-ga20f992+8,16.0-21-g0e05fd4+6,16.0-21-g15e2d33+4,16.0-22-g62d8060+4,16.0-22-g847a80f+4,16.0-25-gf00d9b8+1,16.0-28-g3990c221+4,16.0-3-gf928089+3,16.0-32-g88a4f23+5,16.0-34-gd7987ad+3,16.0-37-gc7333cb+2,16.0-4-g10fc685+2,16.0-4-g18f3627+26,16.0-4-g5f3a788+26,16.0-5-gaf5c3d7+4,16.0-5-gcc1f4bb+1,16.0-6-g3b92700+4,16.0-6-g4412fcd+3,16.0-6-g7235603+4,16.0-69-g2562ce1b+2,16.0-8-g14ebd58+4,16.0-8-g2df868b+1,16.0-8-g4cec79c+6,16.0-8-gadf6c7a+1,16.0-8-gfc7ad86,16.0-82-g59ec2a54a+1,16.0-9-g5400cdc+2,16.0-9-ge6233d7+5,master-g2880f2d8cf+3,v17.0.rc1
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 
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 "lsst/log/Log.h"
37 #include "lsst/pex/exceptions.h"
38 
40 #include "lsst/afw/fits.h"
42 
43 namespace lsst {
44 namespace afw {
45 namespace image {
46 
47 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
49  MaskPlaneDict const& planeDict)
50  : daf::base::Citizen(typeid(this)),
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  : daf::base::Citizen(typeid(this)),
63  _image(new Image(dimensions)),
64  _mask(new Mask(dimensions, planeDict)),
65  _variance(new Variance(dimensions)) {
66  *_image = 0;
67  *_mask = 0x0;
68  *_variance = 0;
69 }
70 
71 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
73  MaskPlaneDict const& planeDict)
74  : daf::base::Citizen(typeid(this)),
75  _image(new Image(bbox)),
76  _mask(new Mask(bbox, planeDict)),
77  _variance(new Variance(bbox)) {
78  *_image = 0;
79  *_mask = 0x0;
80  *_variance = 0;
81 }
82 
83 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
85  std::string const& fileName, std::shared_ptr<daf::base::PropertySet> metadata,
86  lsst::geom::Box2I const& bbox, ImageOrigin origin, bool conformMasks, bool needAllHdus,
89  std::shared_ptr<daf::base::PropertySet> varianceMetadata, bool allowUnsafe)
90  : daf::base::Citizen(typeid(this)), _image(), _mask(), _variance() {
91  MaskedImageFitsReader reader(fileName);
92  *this = reader.read<ImagePixelT, MaskPixelT, VariancePixelT>(bbox, origin, conformMasks, needAllHdus,
93  allowUnsafe);
94  if (metadata) {
95  metadata->combine(reader.readPrimaryMetadata());
96  }
97  if (imageMetadata) {
98  imageMetadata->combine(reader.readImageMetadata());
99  }
100  if (maskMetadata) {
101  maskMetadata->combine(reader.readMaskMetadata());
102  }
103  if (varianceMetadata) {
104  varianceMetadata->combine(reader.readVarianceMetadata());
105  }
106 }
107 
108 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
111  lsst::geom::Box2I const& bbox, ImageOrigin origin, bool conformMasks, bool needAllHdus,
115  bool allowUnsafe)
116  : daf::base::Citizen(typeid(this)), _image(), _mask(), _variance() {
117  MaskedImageFitsReader reader(manager);
118  *this = reader.read<ImagePixelT, MaskPixelT, VariancePixelT>(bbox, origin, conformMasks, needAllHdus,
119  allowUnsafe);
120  if (metadata) {
121  metadata->combine(reader.readPrimaryMetadata());
122  }
123  if (imageMetadata) {
124  imageMetadata->combine(reader.readImageMetadata());
125  }
126  if (maskMetadata) {
127  maskMetadata->combine(reader.readMaskMetadata());
128  }
129  if (varianceMetadata) {
130  varianceMetadata->combine(reader.readVarianceMetadata());
131  }
132 }
133 
134 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
137  ImageOrigin origin, bool conformMasks, bool needAllHdus,
141  bool allowUnsafe)
142  : daf::base::Citizen(typeid(this)), _image(), _mask(), _variance() {
143  MaskedImageFitsReader reader(&fitsFile);
144  *this = reader.read<ImagePixelT, MaskPixelT, VariancePixelT>(bbox, origin, conformMasks, needAllHdus,
145  allowUnsafe);
146  if (metadata) {
147  metadata->combine(reader.readPrimaryMetadata());
148  }
149  if (imageMetadata) {
150  imageMetadata->combine(reader.readImageMetadata());
151  }
152  if (maskMetadata) {
153  maskMetadata->combine(reader.readMaskMetadata());
154  }
155  if (varianceMetadata) {
156  varianceMetadata->combine(reader.readVarianceMetadata());
157  }
158 }
159 
160 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
163  : daf::base::Citizen(typeid(this)), _image(image), _mask(mask), _variance(variance) {
164  conformSizes();
165 }
166 
167 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
169  : daf::base::Citizen(typeid(this)), _image(rhs._image), _mask(rhs._mask), _variance(rhs._variance) {
170  if (deep) {
171  _image = std::shared_ptr<Image>(new Image(*rhs.getImage(), deep));
172  _mask = std::shared_ptr<Mask>(new Mask(*rhs.getMask(), deep));
173  _variance = std::shared_ptr<Variance>(new Variance(*rhs.getVariance(), deep));
174  }
175  conformSizes();
176 }
177 
178 // Delegate to copy-constructor for backwards compatibility
179 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
181  : MaskedImage(rhs, false) {}
182 
183 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
185  const lsst::geom::Box2I& bbox,
186  ImageOrigin const origin, bool deep
187 
188  )
189  : daf::base::Citizen(typeid(this)),
190  _image(new Image(*rhs.getImage(), bbox, origin, deep)),
191  _mask(rhs._mask ? new Mask(*rhs.getMask(), bbox, origin, deep) : static_cast<Mask*>(NULL)),
192  _variance(rhs._variance ? new Variance(*rhs.getVariance(), bbox, origin, deep)
193  : static_cast<Variance*>(NULL)) {
194  conformSizes();
195 }
196 
197 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
199 operator=(MaskedImage const& rhs) = default;
200 
201 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
203 operator=(MaskedImage&& rhs) = default;
204 
205 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
207  using std::swap; // See Meyers, Effective C++, Item 25
208 
209  _image.swap(rhs._image);
210  _mask.swap(rhs._mask);
211  _variance.swap(rhs._variance);
212 }
213 
214 // Operators
215 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
218  *_image = rhs.image();
219  *_mask = rhs.mask();
220  *_variance = rhs.variance();
221 
222  return *this;
223 }
224 
225 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
228  *_image = rhs.image();
229  *_mask = rhs.mask();
230  *_variance = rhs.variance();
231 
232  return *this;
233 }
234 
235 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
238  assign(rhs);
239  return *this;
240 }
241 
242 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
244  lsst::geom::Box2I const& bbox,
245  ImageOrigin origin) {
246  _image->assign(*rhs.getImage(), bbox, origin);
247  _mask->assign(*rhs.getMask(), bbox, origin);
248  _variance->assign(*rhs.getVariance(), bbox, origin);
249 }
250 
251 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
253 operator+=(MaskedImage const& rhs) {
254  *_image += *rhs.getImage();
255  *_mask |= *rhs.getMask();
256  *_variance += *rhs.getVariance();
257  return *this;
258 }
259 
260 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
262  MaskedImage const& rhs) {
263  (*_image).scaledPlus(c, *rhs.getImage());
264  *_mask |= *rhs.getMask();
265  (*_variance).scaledPlus(c * c, *rhs.getVariance());
266 }
267 
268 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
270 operator+=(ImagePixelT const rhs) {
271  *_image += rhs;
272  return *this;
273 }
274 
275 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
277 operator-=(MaskedImage const& rhs) {
278  *_image -= *rhs.getImage();
279  *_mask |= *rhs.getMask();
280  *_variance += *rhs.getVariance();
281  return *this;
282 }
283 
284 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
286  MaskedImage const& rhs) {
287  (*_image).scaledMinus(c, *rhs.getImage());
288  *_mask |= *rhs.getMask();
289  (*_variance).scaledPlus(c * c, *rhs.getVariance());
290 }
291 
292 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
294 operator-=(ImagePixelT const rhs) {
295  *_image -= rhs;
296  return *this;
297 }
298 
299 namespace {
301 template <typename ImagePixelT, typename VariancePixelT>
302 struct productVariance {
303  double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
304  return lhs * lhs * varRhs + rhs * rhs * varLhs;
305  }
306 };
307 
310 template <typename ImagePixelT, typename VariancePixelT>
311 struct scaledProductVariance {
312  double _c;
313  scaledProductVariance(double const c) : _c(c) {}
314  double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
315  return _c * _c * (lhs * lhs * varRhs + rhs * rhs * varLhs);
316  }
317 };
318 } // namespace
319 
320 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
321 MaskedImage<ImagePixelT, MaskPixelT, VariancePixelT>& MaskedImage<ImagePixelT, MaskPixelT, VariancePixelT>::
322 operator*=(MaskedImage const& rhs) {
323  // Must do variance before we modify the image values
324  transform_pixels(_image->_getRawView(), // lhs
325  rhs._image->_getRawView(), // rhs,
326  _variance->_getRawView(), // Var(lhs),
327  rhs._variance->_getRawView(), // Var(rhs)
328  _variance->_getRawView(), // result
329  productVariance<ImagePixelT, VariancePixelT>());
330 
331  *_image *= *rhs.getImage();
332  *_mask |= *rhs.getMask();
333  return *this;
334 }
335 
336 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
338  MaskedImage const& rhs) {
339  // Must do variance before we modify the image values
340  transform_pixels(_image->_getRawView(), // lhs
341  rhs._image->_getRawView(), // rhs,
342  _variance->_getRawView(), // Var(lhs),
343  rhs._variance->_getRawView(), // Var(rhs)
344  _variance->_getRawView(), // result
345  scaledProductVariance<ImagePixelT, VariancePixelT>(c));
346 
347  (*_image).scaledMultiplies(c, *rhs.getImage());
348  *_mask |= *rhs.getMask();
349 }
350 
351 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
353 operator*=(ImagePixelT const rhs) {
354  *_image *= rhs;
355  *_variance *= rhs * rhs;
356  return *this;
357 }
358 
359 namespace {
361 template <typename ImagePixelT, typename VariancePixelT>
362 struct quotientVariance {
363  double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
364  ImagePixelT const rhs2 = rhs * rhs;
365  return (lhs * lhs * varRhs + rhs2 * varLhs) / (rhs2 * rhs2);
366  }
367 };
370 template <typename ImagePixelT, typename VariancePixelT>
371 struct scaledQuotientVariance {
372  double _c;
373  scaledQuotientVariance(double c) : _c(c) {}
374  double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
375  ImagePixelT const rhs2 = rhs * rhs;
376  return (lhs * lhs * varRhs + rhs2 * varLhs) / (_c * _c * rhs2 * rhs2);
377  }
378 };
379 } // namespace
380 
381 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
383 operator/=(MaskedImage const& rhs) {
384  // Must do variance before we modify the image values
385  transform_pixels(_image->_getRawView(), // lhs
386  rhs._image->_getRawView(), // rhs,
387  _variance->_getRawView(), // Var(lhs),
388  rhs._variance->_getRawView(), // Var(rhs)
389  _variance->_getRawView(), // result
390  quotientVariance<ImagePixelT, VariancePixelT>());
391 
392  *_image /= *rhs.getImage();
393  *_mask |= *rhs.getMask();
394  return *this;
395 }
396 
397 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
399  MaskedImage const& rhs) {
400  // Must do variance before we modify the image values
401  transform_pixels(_image->_getRawView(), // lhs
402  rhs._image->_getRawView(), // rhs,
403  _variance->_getRawView(), // Var(lhs),
404  rhs._variance->_getRawView(), // Var(rhs)
405  _variance->_getRawView(), // result
406  scaledQuotientVariance<ImagePixelT, VariancePixelT>(c));
407 
408  (*_image).scaledDivides(c, *rhs.getImage());
409  *_mask |= *rhs._mask;
410 }
411 
412 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
414 operator/=(ImagePixelT const rhs) {
415  *_image /= rhs;
416  *_variance /= rhs * rhs;
417  return *this;
418 }
419 
420 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
425  std::shared_ptr<daf::base::PropertySet const> varianceMetadata) const {
426  fits::Fits fitsfile(fileName, "w", fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
427  writeFits(fitsfile, metadata, imageMetadata, maskMetadata, varianceMetadata);
428 }
429 
430 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
435  std::shared_ptr<daf::base::PropertySet const> varianceMetadata) const {
436  fits::Fits fitsfile(manager, "w", fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
437  writeFits(fitsfile, metadata, imageMetadata, maskMetadata, varianceMetadata);
438 }
439 
440 namespace {
441 
442 void processPlaneMetadata(std::shared_ptr<daf::base::PropertySet const> metadata,
443  std::shared_ptr<daf::base::PropertySet>& hdr, char const* exttype) {
444  if (metadata) {
445  hdr = metadata->deepCopy();
446  } else {
447  hdr.reset(new daf::base::PropertyList());
448  }
449  hdr->set("INHERIT", true);
450  hdr->set("EXTTYPE", exttype);
451 }
452 
453 } // namespace
454 
455 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
460  std::shared_ptr<daf::base::PropertySet const> varianceMetadata) const {
461  writeFits(fitsfile, fits::ImageWriteOptions(*_image), fits::ImageWriteOptions(*_mask),
462  fits::ImageWriteOptions(*_variance), metadata, imageMetadata, maskMetadata, varianceMetadata);
463 }
464 
465 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
467  std::string const& fileName, fits::ImageWriteOptions const& imageOptions,
468  fits::ImageWriteOptions const& maskOptions, fits::ImageWriteOptions const& varianceOptions,
472  std::shared_ptr<daf::base::PropertySet const> varianceMetadata) const {
473  fits::Fits fitsfile(fileName, "w", fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
474  writeFits(fitsfile, imageOptions, maskOptions, varianceOptions, metadata, imageMetadata, maskMetadata,
475  varianceMetadata);
476 }
477 
478 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
480  fits::MemFileManager& manager, fits::ImageWriteOptions const& imageOptions,
481  fits::ImageWriteOptions const& maskOptions, fits::ImageWriteOptions const& varianceOptions,
485  std::shared_ptr<daf::base::PropertySet const> varianceMetadata) const {
486  fits::Fits fitsfile(manager, "w", fits::Fits::AUTO_CLOSE | fits::Fits::AUTO_CHECK);
487  writeFits(fitsfile, imageOptions, maskOptions, varianceOptions, metadata, imageMetadata, maskMetadata,
488  varianceMetadata);
489 }
490 
491 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
493  fits::Fits& fitsfile, fits::ImageWriteOptions const& imageOptions,
494  fits::ImageWriteOptions const& maskOptions, fits::ImageWriteOptions const& varianceOptions,
498  std::shared_ptr<daf::base::PropertySet const> varianceMetadata) const {
500  if (metadata) {
501  header = metadata->deepCopy();
502  } else {
503  header = std::make_shared<daf::base::PropertyList>();
504  }
505 
506  if (fitsfile.countHdus() != 0) {
508  "MaskedImage::writeFits can only write to an empty file");
509  }
510  if (fitsfile.getHdu() < 1) {
511  // Don't ever write images to primary; instead we make an empty primary.
512  fitsfile.createEmpty();
513  } else {
514  fitsfile.setHdu(0);
515  }
516  fitsfile.writeMetadata(*header);
517 
518  processPlaneMetadata(imageMetadata, header, "IMAGE");
519  _image->writeFits(fitsfile, imageOptions, header, _mask);
520 
521  processPlaneMetadata(maskMetadata, header, "MASK");
522  _mask->writeFits(fitsfile, maskOptions, header);
523 
524  processPlaneMetadata(varianceMetadata, header, "VARIANCE");
525  _variance->writeFits(fitsfile, varianceOptions, header, _mask);
526 }
527 
528 // private function conformSizes() ensures that the Mask and Variance have the same dimensions
529 // as Image. If Mask and/or Variance have non-zero dimensions that conflict with the size of Image,
530 // a lsst::pex::exceptions::LengthError is thrown.
531 
532 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
534  if (!_mask || _mask->getWidth() == 0 || _mask->getHeight() == 0) {
535  _mask = MaskPtr(new Mask(_image->getBBox()));
536  *_mask = 0;
537  } else {
538  if (_mask->getDimensions() != _image->getDimensions()) {
539  throw LSST_EXCEPT(
541  (boost::format("Dimension mismatch: Image %dx%d v. Mask %dx%d") % _image->getWidth() %
542  _image->getHeight() % _mask->getWidth() % _mask->getHeight())
543  .str());
544  }
545  }
546 
547  if (!_variance || _variance->getWidth() == 0 || _variance->getHeight() == 0) {
548  _variance = VariancePtr(new Variance(_image->getBBox()));
549  *_variance = 0;
550  } else {
551  if (_variance->getDimensions() != _image->getDimensions()) {
552  throw LSST_EXCEPT(
554  (boost::format("Dimension mismatch: Image %dx%d v. Variance %dx%d") % _image->getWidth() %
555  _image->getHeight() % _variance->getWidth() % _variance->getHeight())
556  .str());
557  }
558  }
559 }
560 
561 //
562 // Iterators and locators
563 //
564 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
567 #if 0 // this doesn't compile; why?
568  return iterator(_image->begin(), _mask->begin(), _variance->begin());
569 #else
570  typename Image::iterator imageBegin = _image->begin();
571  typename Mask::iterator maskBegin = _mask->begin();
572  typename Variance::iterator varianceBegin = _variance->begin();
573 
574  return iterator(imageBegin, maskBegin, varianceBegin);
575 #endif
576 }
577 
578 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
581  typename Image::iterator imageEnd = getImage()->end();
582  typename Mask::iterator maskEnd = getMask()->end();
583  typename Variance::iterator varianceEnd = getVariance()->end();
584 
585  return iterator(imageEnd, maskEnd, varianceEnd);
586 }
587 
588 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
591  typename Image::iterator imageEnd = getImage()->at(x, y);
592  typename Mask::iterator maskEnd = getMask()->at(x, y);
593  typename Variance::iterator varianceEnd = getVariance()->at(x, y);
594 
595  return iterator(imageEnd, maskEnd, varianceEnd);
596 }
597 
598 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
601  typename Image::reverse_iterator imageBegin = _image->rbegin();
602  typename Mask::reverse_iterator maskBegin = _mask->rbegin();
603  typename Variance::reverse_iterator varianceBegin = _variance->rbegin();
604 
605  return reverse_iterator(imageBegin, maskBegin, varianceBegin);
606 }
607 
608 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
611  typename Image::reverse_iterator imageEnd = getImage()->rend();
612  typename Mask::reverse_iterator maskEnd = getMask()->rend();
613  typename Variance::reverse_iterator varianceEnd = getVariance()->rend();
614 
615  return reverse_iterator(imageEnd, maskEnd, varianceEnd);
616 }
617 
618 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
621  typename Image::x_iterator imageBegin = _image->row_begin(y);
622  typename Mask::x_iterator maskBegin = _mask->row_begin(y);
623  typename Variance::x_iterator varianceBegin = _variance->row_begin(y);
624 
625  return x_iterator(imageBegin, maskBegin, varianceBegin);
626 }
627 
628 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
631  typename Image::x_iterator imageEnd = getImage()->row_end(y);
632  typename Mask::x_iterator maskEnd = getMask()->row_end(y);
633  typename Variance::x_iterator varianceEnd = getVariance()->row_end(y);
634 
635  return x_iterator(imageEnd, maskEnd, varianceEnd);
636 }
637 
638 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
641  typename Image::y_iterator imageBegin = _image->col_begin(x);
642  typename Mask::y_iterator maskBegin = _mask->col_begin(x);
643  typename Variance::y_iterator varianceBegin = _variance->col_begin(x);
644 
645  return y_iterator(imageBegin, maskBegin, varianceBegin);
646 }
647 
648 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
651  typename Image::y_iterator imageEnd = getImage()->col_end(x);
652  typename Mask::y_iterator maskEnd = getMask()->col_end(x);
653  typename Variance::y_iterator varianceEnd = getVariance()->col_end(x);
654 
655  return y_iterator(imageEnd, maskEnd, varianceEnd);
656 }
657 
658 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
661  typename Image::fast_iterator imageBegin = _image->begin(contiguous);
662  typename Mask::fast_iterator maskBegin = _mask->begin(contiguous);
663  typename Variance::fast_iterator varianceBegin = _variance->begin(contiguous);
664 
665  return fast_iterator(imageBegin, maskBegin, varianceBegin);
666 }
667 
668 template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
671  typename Image::fast_iterator imageEnd = getImage()->end(contiguous);
672  typename Mask::fast_iterator maskEnd = getMask()->end(contiguous);
673  typename Variance::fast_iterator varianceEnd = getVariance()->end(contiguous);
674 
675  return fast_iterator(imageEnd, maskEnd, varianceEnd);
676 }
677 
678 template <typename ImagePixelT1, typename ImagePixelT2>
681  return imagesOverlap(*image1.getImage(), *image2.getImage()) ||
682  imagesOverlap(*image1.getVariance(), *image2.getVariance()) ||
683  imagesOverlap(*image1.getMask(), *image2.getMask());
684 }
685 
686 //
687 // Explicit instantiations
688 //
689 #define INSTANTIATE2(ImagePixelT1, ImagePixelT2) \
690  template bool imagesOverlap<ImagePixelT1, ImagePixelT2>(MaskedImage<ImagePixelT1> const&, \
691  MaskedImage<ImagePixelT2> const&);
692 
693 template class MaskedImage<std::uint16_t>;
694 template class MaskedImage<int>;
695 template class MaskedImage<float>;
696 template class MaskedImage<double>;
697 template class MaskedImage<std::uint64_t>;
698 
702 INSTANTIATE2(std::uint16_t, double);
704 
706 INSTANTIATE2(int, int);
707 INSTANTIATE2(int, float);
708 INSTANTIATE2(int, double);
710 
712 INSTANTIATE2(float, int);
713 INSTANTIATE2(float, float);
714 INSTANTIATE2(float, double);
716 
717 INSTANTIATE2(double, std::uint16_t);
718 INSTANTIATE2(double, int);
719 INSTANTIATE2(double, float);
720 INSTANTIATE2(double, double);
721 INSTANTIATE2(double, std::uint64_t);
722 
726 INSTANTIATE2(std::uint64_t, double);
728 
729 } // namespace image
730 } // namespace afw
731 } // namespace lsst
VariancePtr getVariance() const
Return a (shared_ptr to) the MaskedImage&#39;s variance.
Definition: MaskedImage.h:1091
afw::table::PointKey< int > dimensions
Definition: GaussianPsf.cc:49
std::shared_ptr< daf::base::PropertyList > readVarianceMetadata()
Read the FITS header of one of the HDUs.
void scaledPlus(OutImageT &outImage, double c1, InImageT const &inImage1, double c2, InImageT const &inImage2)
Compute the scaled sum of two images.
VariancePixelT variance() const
Return the variance part of a Pixel.
Definition: Pixel.h:221
x_iterator fast_iterator
A fast STL compliant iterator for contiguous images N.b.
Definition: ImageBase.h:138
_view_t::reverse_iterator reverse_iterator
An STL compliant reverse iterator.
Definition: ImageBase.h:130
Image< LhsPixelT > & operator+=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Add lhs to Image rhs (i.e. pixel-by-pixel addition) where types are different.
Definition: Image.cc:680
void writeMetadata(daf::base::PropertySet const &metadata)
Read a FITS header into a PropertySet or PropertyList.
Definition: fits.cc:988
x_iterator fast_iterator
A fast STL compliant iterator for contiguous images N.b.
Definition: MaskedImage.h:565
T swap(T... args)
Class for storing ordered metadata with comments.
Definition: PropertyList.h:68
afw::table::Key< afw::table::Array< VariancePixelT > > variance
iterator at(int const x, int const y) const
Return an iterator at the point (x, y)
Definition: MaskedImage.cc:590
VariancePixelT variance() const
Definition: Pixel.h:96
Reports attempts to exceed implementation-defined length limits for some classes. ...
Definition: Runtime.h:76
Options for writing an image to FITS.
Definition: fits.h:218
_view_t::x_iterator x_iterator
An iterator for traversing the pixels in a row.
Definition: ImageBase.h:134
int y
Definition: SpanSet.cc:49
std::shared_ptr< daf::base::PropertyList > readMaskMetadata()
Read the FITS header of one of the HDUs.
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:557
MaskPixelT mask() const
Definition: Pixel.h:95
A single pixel of the same type as a MaskedImage.
Definition: Pixel.h:73
A simple struct that combines the two arguments that must be passed to most cfitsio routines and cont...
Definition: fits.h:296
MaskedImage(unsigned int width, unsigned int height, MaskPlaneDict const &planeDict=MaskPlaneDict())
Construct from a supplied dimensions.
Definition: MaskedImage.cc:48
void createEmpty()
Create an empty image HDU with NAXIS=0 at the end of the file.
Definition: fits.cc:1133
MaskedImageIterator< typename Image::iterator, typename Mask::iterator, typename Variance::iterator > iterator
Definition: MaskedImage.h:540
ImagePtr getImage() const
Return a (shared_ptr to) the MaskedImage&#39;s image.
Definition: MaskedImage.h:1058
STL class.
LSST DM logging module built on log4cxx.
_view_t::iterator iterator
An STL compliant iterator.
Definition: ImageBase.h:126
reverse_iterator rend() const
Return a reverse_iterator to the end of the image.
Definition: MaskedImage.cc:610
ImagePixelT image() const
Definition: Pixel.h:94
A base class for image defects.
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:78
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:569
Lifetime-management for memory that goes into FITS memory files.
Definition: fits.h:120
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:168
MaskPixelT mask() const
Return the mask part of a Pixel.
Definition: Pixel.h:219
A class to manipulate images, masks, and variance as a single object.
Definition: MaskedImage.h:74
_view_t::y_iterator y_iterator
An iterator for traversing the pixels in a column.
Definition: ImageBase.h:144
ImagePixelT image() const
Return the image part of a Pixel.
Definition: Pixel.h:217
std::shared_ptr< daf::base::PropertyList > readPrimaryMetadata()
Read the FITS header of one of the HDUs.
MaskedImageIterator< typename Image::reverse_iterator, typename Mask::reverse_iterator, typename Variance::reverse_iterator > reverse_iterator
Definition: MaskedImage.h:548
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:715
T reset(T... args)
Reports errors in the logical structure of the program.
Definition: Runtime.h:46
table::Box2IKey bbox
Definition: Detector.cc:166
double x
void setHdu(int hdu, bool relative=false)
Set the current HDU.
Definition: fits.cc:492
x_iterator row_end(int y) const
Return an x_iterator to the end of the image.
Definition: MaskedImage.cc:630
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.
MaskPtr getMask() const
Return a (shared_ptr to) the MaskedImage&#39;s mask.
Definition: MaskedImage.h:1070
void swap(Image< PixelT > &a, Image< PixelT > &b)
Definition: Image.cc:465
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
afw::table::Key< afw::table::Array< MaskPixelT > > mask
A pixel of a MaskedImage.
Definition: Pixel.h:148
Image< LhsPixelT > & operator*=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Multiply lhs by Image rhs (i.e. pixel-by-pixel multiplication) where types are different.
Definition: Image.cc:692
Image< LhsPixelT > & operator-=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Subtract lhs from Image rhs (i.e. pixel-by-pixel subtraction) where types are different.
Definition: Image.cc:686
y_iterator col_end(int x) const
Return an y_iterator to the end of the image.
Definition: MaskedImage.cc:650
double _c
Definition: MaskedImage.cc:312
A FITS reader class for MaskedImages and their components.
Image< LhsPixelT > & operator/=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Divide lhs by Image rhs (i.e. pixel-by-pixel division) where types are different. ...
Definition: Image.cc:698
std::shared_ptr< daf::base::PropertyList > readImageMetadata()
Read the FITS header of one of the HDUs.
int getHdu()
Return the current HDU (0-indexed; 0 is the Primary HDU).
Definition: fits.cc:486
An integer coordinate rectangle.
Definition: Box.h:54
#define INSTANTIATE2(ImagePixelT1, ImagePixelT2)
Definition: MaskedImage.cc:689
int end
void scaledMinus(double const c, MaskedImage const &rhs)
Subtract a scaled MaskedImage c*rhs from a MaskedImage.
Definition: MaskedImage.cc:285
int countHdus()
Return the number of HDUs in the file.
Definition: fits.cc:513