LSST Applications g02d81e74bb+86cf3d8bc9,g180d380827+7a4e862ed4,g2079a07aa2+86d27d4dc4,g2305ad1205+e1ca1c66fa,g29320951ab+012e1474a1,g295015adf3+341ea1ce94,g2bbee38e9b+0e5473021a,g337abbeb29+0e5473021a,g33d1c0ed96+0e5473021a,g3a166c0a6a+0e5473021a,g3ddfee87b4+c429d67c83,g48712c4677+f88676dd22,g487adcacf7+27e1e21933,g50ff169b8f+96c6868917,g52b1c1532d+585e252eca,g591dd9f2cf+b41db86c35,g5a732f18d5+53520f316c,g64a986408d+86cf3d8bc9,g858d7b2824+86cf3d8bc9,g8a8a8dda67+585e252eca,g99cad8db69+84912a7fdc,g9ddcbc5298+9a081db1e4,ga1e77700b3+15fc3df1f7,ga8c6da7877+a2b54eae19,gb0e22166c9+60f28cb32d,gba4ed39666+c2a2e4ac27,gbb8dafda3b+6681f309db,gc120e1dc64+f0fcc2f6d8,gc28159a63d+0e5473021a,gcf0d15dbbd+c429d67c83,gdaeeff99f8+f9a426f77a,ge6526c86ff+0433e6603d,ge79ae78c31+0e5473021a,gee10cc3b42+585e252eca,gff1a9f87cc+86cf3d8bc9,w.2024.17
LSST Data Management Base Package
Loading...
Searching...
No Matches
MaskedImage.h
Go to the documentation of this file.
1// -*- lsst-c++ -*-
2
3/*
4 * LSST Data Management System
5 * Copyright 2008, 2009, 2010 LSST Corporation.
6 *
7 * This product includes software developed by the
8 * LSST Project (http://www.lsst.org/).
9 *
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the LSST License Statement and
21 * the GNU General Public License along with this program. If not,
22 * see <http://www.lsstcorp.org/LegalNotices/>.
23 */
24
25/*
26 * Implementation of the Class MaskedImage
27 */
28
29#ifndef LSST_IMAGE_MASKEDIMAGE_H
30#define LSST_IMAGE_MASKEDIMAGE_H
31
32#include <list>
33#include <map>
34#include <memory>
35#include <ostream>
36#include <string>
37
38#include "boost/mpl/at.hpp"
39#include "boost/mpl/vector.hpp"
40#include "boost/iterator/zip_iterator.hpp"
41#include "boost/tuple/tuple.hpp" // cannot convert to std::tuple (yet) because of use with boost::gil
42
44#include "lsst/afw/image/Mask.h"
45
46namespace lsst {
47namespace afw {
48namespace image {
49namespace detail {
51struct MaskedImage_tag : public basic_tag {};
54
56std::string const fitsFile_RE = "\\.fits(\\.[fg]z)?$";
59} // namespace detail
60} // namespace image
61} // namespace afw
62} // namespace lsst
63
66
67namespace lsst {
68namespace afw {
69namespace image {
70
72template <typename ImagePixelT, typename MaskPixelT = lsst::afw::image::MaskPixel,
73 typename VariancePixelT = lsst::afw::image::VariancePixel>
75public:
84
88
90
92 template <typename ImagePT = ImagePixelT, typename MaskPT = MaskPixelT, typename VarPT = VariancePixelT>
97
99 template <typename, typename, typename>
102 template <typename, typename, typename>
105 template <typename, typename, typename>
106 class MaskedImageLocator;
108 template <typename, typename, typename>
110
115
117 template <typename ImageIterator, typename MaskIterator, typename VarianceIterator,
118 template <typename> class Ref = Reference>
120 using IMV_iterator_tuple = boost::tuple<ImageIterator, MaskIterator, VarianceIterator>;
121
122 public:
126 using IMV_tuple = typename boost::zip_iterator<IMV_iterator_tuple>::reference;
130 template <typename, typename, typename>
133 using type = Pixel;
134
136 MaskedImageIteratorBase(ImageIterator const& img, MaskIterator const& msk,
137 VarianceIterator const& var)
138 : _iter(boost::make_zip_iterator(boost::make_tuple(img, msk, var))) {}
140 typename Ref<ImagePixelT>::type image() { return _iter->template get<0>()[0]; }
141
143 typename Ref<MaskPixelT>::type mask() { return _iter->template get<1>()[0]; }
144
146 typename Ref<VariancePixelT>::type variance() { return _iter->template get<2>()[0]; }
147
151 const IMV_iterator_tuple get_iterator_tuple() const { return _iter.get_iterator_tuple(); }
152
155 ) {
156 _iter += delta;
157 return *this;
158 }
161 ) {
162 _iter -= delta;
163 return *this;
164 }
167 ++_iter;
168 return *this;
169 }
172 MaskedImageIteratorBase tmp(*this);
173 _iter++;
174 return tmp;
175 }
178 return &this->_iter->template get<0>() - &rhs._iter->template get<0>();
179 }
182 return &this->_iter->template get<0>() == &rhs._iter->template get<0>();
183 }
186 return &this->_iter->template get<0>() != &rhs._iter->template get<0>();
187 }
190 return &this->_iter->template get<0>() < &rhs._iter->template get<0>();
191 }
193 operator Pixel() const {
194 return Pixel(_iter->template get<0>()[0], _iter->template get<1>()[0],
195 _iter->template get<2>()[0]);
196 }
197
199 Pixel operator*() { return Pixel(image(), mask(), variance()); }
201 const Pixel operator*() const { return Pixel(image(), mask(), variance()); }
202
203 protected:
204 typename boost::zip_iterator<IMV_iterator_tuple> _iter;
205 };
206
208 template <typename ImageIterator, typename MaskIterator, typename VarianceIterator>
210 : public MaskedImageIteratorBase<ImageIterator, MaskIterator, VarianceIterator> {
212
213 public:
214 MaskedImageIterator(ImageIterator& img, MaskIterator& msk, VarianceIterator& var)
215 : MaskedImageIteratorBase_t(img, msk, var) {}
218 MaskedImageIterator lhs = *this;
219 lhs += delta;
220
221 return lhs;
222 }
223 };
224
226 template <typename ImageIterator, typename MaskIterator, typename VarianceIterator>
228 : public MaskedImageIteratorBase<typename detail::const_iterator_type<ImageIterator>::type,
229 typename detail::const_iterator_type<MaskIterator>::type,
230 typename detail::const_iterator_type<VarianceIterator>::type,
231 ConstReference> {
232 using const_ImageIterator = typename detail::const_iterator_type<ImageIterator>::type;
233 using const_MaskIterator = typename detail::const_iterator_type<MaskIterator>::type;
234 using const_VarianceIterator = typename detail::const_iterator_type<VarianceIterator>::type;
235
237
238 public:
242 const_ImageIterator(iter.get_iterator_tuple().template get<0>()),
243 const_MaskIterator(iter.get_iterator_tuple().template get<1>()),
244 const_VarianceIterator(iter.get_iterator_tuple().template get<2>())) {
245 ;
246 }
249 const_MaskedImageIterator lhs = *this;
250 lhs += delta;
251
252 return lhs;
253 }
254 };
255
257 template <typename ImageLocator, typename MaskLocator, typename VarianceLocator,
258 template <typename> class Ref = Reference>
260 using IMVLocator = typename boost::tuple<ImageLocator, MaskLocator, VarianceLocator>;
261 //
262 // A class to provide _[xy]_iterator for MaskedImageLocator. We can't just use
263 // a zip_iterator as moving this iterator must be the same as moving the locator
264 // itself, for consistency with {Image,Mask}::xy_locator
265 //
266 template <template <typename> class X_OR_Y>
267 class _x_or_y_iterator {
268 public:
269 _x_or_y_iterator(MaskedImageLocatorBase* mil) : _mil(mil) {}
270
271 _x_or_y_iterator& operator+=(const int di) {
272 // Equivalent to "_mil->_loc.template get<0>().x() += di;"
273 X_OR_Y<ImageLocator>(_mil->_loc.template get<0>())() += di;
274 X_OR_Y<MaskLocator>(_mil->_loc.template get<1>())() += di;
275 X_OR_Y<VarianceLocator>(_mil->_loc.template get<2>())() += di;
276 return *this;
277 }
278
279 _x_or_y_iterator& operator++() { // prefix
280 // Equivalent to "++_mil->_loc.template get<0>().x();"
281 ++X_OR_Y<ImageLocator>(_mil->_loc.template get<0>())();
282 ++X_OR_Y<MaskLocator>(_mil->_loc.template get<1>())();
283 ++X_OR_Y<VarianceLocator>(_mil->_loc.template get<2>())();
284 return *this;
285 }
286
287 bool operator==(_x_or_y_iterator const& rhs) {
288 return X_OR_Y<ImageLocator>(_mil->_loc.template get<0>())() ==
289 X_OR_Y<ImageLocator>(rhs._mil->_loc.template get<0>())();
290 }
291 bool operator!=(_x_or_y_iterator const& rhs) {
292 return X_OR_Y<ImageLocator>(_mil->_loc.template get<0>())() !=
293 X_OR_Y<ImageLocator>(rhs._mil->_loc.template get<0>())();
294 }
295 bool operator<(_x_or_y_iterator const& rhs) {
296 return X_OR_Y<ImageLocator>(_mil->_loc.template get<0>())() <
297 X_OR_Y<ImageLocator>(rhs._mil->_loc.template get<0>())();
298 }
299
300 Pixel operator*() {
301 return Pixel((*(X_OR_Y<ImageLocator>(_mil->_loc.template get<0>())()))[0],
302 (*(X_OR_Y<MaskLocator>(_mil->_loc.template get<1>())()))[0],
303 (*(X_OR_Y<VarianceLocator>(_mil->_loc.template get<2>())()))[0]);
304 }
305
306 typename Ref<ImagePixelT>::type image() {
307 // Equivalent to "return (*_mil->_loc.template get<0>().x())[0];"
308
309 return (*(X_OR_Y<ImageLocator>(_mil->_loc.template get<0>())()))[0];
310 }
311 typename Ref<MaskPixelT>::type mask() {
312 return (*(X_OR_Y<MaskLocator>(_mil->_loc.template get<1>())()))[0];
313 }
314 typename Ref<VariancePixelT>::type variance() {
315 return (*(X_OR_Y<VarianceLocator>(_mil->_loc.template get<2>())()))[0];
316 }
317
318 protected:
320 };
321
322 // Two classes to provide .x() and .y() in _x_or_y_iterator
323 template <typename LocT>
324 class apply_x {
325 using IterT = typename LocT::x_iterator;
326
327 public:
328 apply_x(LocT& loc) : _loc(loc) {}
329 IterT& operator()() { return _loc.x(); }
330
331 private:
332 LocT& _loc;
333 };
334
335 template <typename LocT>
336 class apply_y {
337 using IterT = typename LocT::y_iterator;
338
339 public:
340 apply_y(LocT& loc) : _loc(loc) {}
341 IterT& operator()() { return _loc.y(); }
342
343 private:
344 LocT& _loc;
345 };
346
347 public:
348 using IMVCachedLocation = typename boost::tuple<typename ImageLocator::cached_location_t, typename MaskLocator::cached_location_t, typename VarianceLocator::cached_location_t>;
350 using x_iterator = _x_or_y_iterator<apply_x>;
352 using y_iterator = _x_or_y_iterator<apply_y>;
355 public:
356 // template<typename, typename, typename, template<typename> class> friend class
357 // MaskedImageLocatorBase;
358 template <typename, typename, typename>
360
362 cached_location_t(IMVLocator const& loc, int x, int y)
363 : _imv(loc.template get<0>().cache_location(x, y),
364 loc.template get<1>().cache_location(x, y),
365 loc.template get<2>().cache_location(x, y)) {
366 ;
367 }
368 // protected:
370 };
372 MaskedImageLocatorBase(ImageLocator const& img, MaskLocator const& msk, VarianceLocator const& var)
373 : _loc(img, msk, var) {
374 ;
375 }
376
379 return Pixel(_loc.template get<0>().x()[0][0], _loc.template get<1>().x()[0][0],
380 _loc.template get<2>().x()[0][0]);
381 }
382
384 Pixel operator()(int x, int y) {
385 return Pixel(_loc.template get<0>()(x, y)[0], _loc.template get<1>()(x, y)[0],
386 _loc.template get<2>()(x, y)[0]);
387 }
388
391 Pixel operator[](cached_location_t const& cached_loc) {
392 return Pixel(_loc.template get<0>()[cached_loc._imv.template get<0>()][0],
393 _loc.template get<1>()[cached_loc._imv.template get<1>()][0],
394 _loc.template get<2>()[cached_loc._imv.template get<2>()][0]);
395 }
400 x_iterator x() { return x_iterator(this); }
401
406 y_iterator y() { return y_iterator(this); }
407
410 //
411 // We don't want to duplicate code for image/mask/variance -- but the boost::mpl stuff isn't pretty
412 // as we can't say int_<N> within a template<int N>. So define a set of functions apply_IMV
413 // to do the dirty work
414 //
415 using PixelTVec = typename boost::mpl::vector<ImagePixelT, MaskPixelT, VariancePixelT>;
416
417 template <typename N>
418 typename Ref<typename boost::mpl::at<PixelTVec, N>::type>::type apply_IMV(
419 cached_location_t const& cached_loc) {
420 return _loc.template get<N::value>()[cached_loc._imv.template get<N::value>()][0];
421 }
422
423 template <typename N>
424 typename Ref<typename boost::mpl::at<PixelTVec, N>::type>::type apply_IMV() {
425 return _loc.template get<N::value>()[0][0];
426 }
427
428 template <typename N>
429 typename Ref<typename boost::mpl::at<PixelTVec, N>::type>::type apply_IMV(int x, int y) {
430 return _loc.template get<N::value>()(x, y)[0];
431 }
432 //
433 // Use those templated classes to implement image/mask/variance
434 //
436 typename Ref<ImagePixelT>::type image(cached_location_t const& cached_loc) {
437 return apply_IMV<boost::mpl::int_<0>>(cached_loc);
438 }
440 typename Ref<ImagePixelT>::type image() { return apply_IMV<boost::mpl::int_<0>>(); }
442 typename Ref<ImagePixelT>::type image(int x, int y) { return apply_IMV<boost::mpl::int_<0>>(x, y); }
443
445 typename Ref<MaskPixelT>::type mask(cached_location_t const& cached_loc) {
446 return apply_IMV<boost::mpl::int_<1>>(cached_loc);
447 }
449 typename Ref<MaskPixelT>::type mask() { return apply_IMV<boost::mpl::int_<1>>(); }
451 typename Ref<MaskPixelT>::type mask(int x, int y) { return apply_IMV<boost::mpl::int_<1>>(x, y); }
452
454 typename Ref<VariancePixelT>::type variance(cached_location_t const& cached_loc) {
455 return apply_IMV<boost::mpl::int_<2>>(cached_loc);
456 }
458 typename Ref<VariancePixelT>::type variance() { return apply_IMV<boost::mpl::int_<2>>(); }
460 typename Ref<VariancePixelT>::type variance(int x, int y) {
461 return apply_IMV<boost::mpl::int_<2>>(x, y);
462 }
463
466 return _loc.template get<0>() == rhs._loc.template get<0>();
467 }
469 bool operator!=(MaskedImageLocatorBase const& rhs) { return !(*this == rhs); }
472 return _loc.template get<0>() < rhs._loc.template get<0>();
473 }
474
477 return operator+=(detail::difference_type(p.first, p.second));
478 }
479
481 MaskedImageLocatorBase& operator+=(detail::difference_type p) {
482 _loc.template get<0>() += p;
483 _loc.template get<1>() += p;
484 _loc.template get<2>() += p;
485
486 return *this;
487 }
488
489 // Workaround for DM-5590: clang-3.8 cannot access _loc from
490 // friend class const_MaskedImageLocator.
491 IMVLocator const& getLoc() const { return _loc; }
492
493 protected:
494 IMVLocator _loc;
495 };
496
498 template <typename ImageLocator, typename MaskLocator, typename VarianceLocator>
499 class MaskedImageLocator : public MaskedImageLocatorBase<ImageLocator, MaskLocator, VarianceLocator> {
501
502 public:
503 MaskedImageLocator(ImageLocator& img, MaskLocator& msk, VarianceLocator& var)
504 : MaskedImageLocatorBase_t(img, msk, var) {}
505 };
506
508 template <typename ImageLocator, typename MaskLocator, typename VarianceLocator>
510 : public MaskedImageLocatorBase<typename detail::const_locator_type<ImageLocator>::type,
511 typename detail::const_locator_type<MaskLocator>::type,
512 typename detail::const_locator_type<VarianceLocator>::type,
513 ConstReference> {
514 using const_ImageLocator = typename detail::const_locator_type<ImageLocator>::type;
515 using const_MaskLocator = typename detail::const_locator_type<MaskLocator>::type;
516 using const_VarianceLocator = typename detail::const_locator_type<VarianceLocator>::type;
517
519
520 public:
522 : MaskedImageLocatorBase_t(const_ImageLocator(iter.getLoc().template get<0>()),
523 const_MaskLocator(iter.getLoc().template get<1>()),
524 const_VarianceLocator(iter.getLoc().template get<2>())) {
525 ;
526 }
527 };
528
529 // An iterator to a MaskedImage
531 // A const_iterator to a MaskedImage
533 // A reverse_iterator to a MaskedImage
535#if 0 // doesn't compile. I should fix this, but it's low priority. RHL
537 typedef const_MaskedImageIterator<typename Image::reverse_iterator,
538 typename Mask::reverse_iterator, typename Variance::reverse_iterator> const_reverse_iterator;
539#endif
552
557
562
563 // Constructors
571 explicit MaskedImage(unsigned int width, unsigned int height,
572 MaskPlaneDict const& planeDict = MaskPlaneDict());
579 explicit MaskedImage(lsst::geom::Extent2I const& dimensions = lsst::geom::Extent2I(),
580 MaskPlaneDict const& planeDict = MaskPlaneDict());
601 explicit MaskedImage(lsst::geom::Box2I const& bbox, MaskPlaneDict const& planeDict = MaskPlaneDict());
602
620 explicit MaskedImage(
621 std::string const& fileName,
623 lsst::geom::Box2I const& bbox = lsst::geom::Box2I(), ImageOrigin origin = PARENT,
624 bool conformMasks = false, bool needAllHdus = false,
629 bool allowUnsafe = false);
630
648 explicit MaskedImage(
649 fits::MemFileManager& manager,
651 lsst::geom::Box2I const& bbox = lsst::geom::Box2I(), ImageOrigin origin = PARENT,
652 bool conformMasks = false, bool needAllHdus = false,
657 bool allowUnsafe = false);
658
676 explicit MaskedImage(
677 fits::Fits& fitsfile,
679 lsst::geom::Box2I const& bbox = lsst::geom::Box2I(), ImageOrigin origin = PARENT,
680 bool conformMasks = false, bool needAllHdus = false,
685 bool allowUnsafe = false);
686
693 MaskedImage(MaskedImage const& rhs, bool const deep = false);
695
705 MaskedImage(MaskedImage const& rhs, lsst::geom::Box2I const& bbox, ImageOrigin const origin = PARENT,
706 bool const deep = false);
712 template <typename OtherPixelT>
714
715 const bool deep
716 )
717 : _image(), _mask(), _variance() {
718 if (!deep) {
720 "Only deep copies are permitted for MaskedImages with different pixel types");
721 }
722
723 _image = ImagePtr(new Image(*rhs.getImage(), deep));
724 _mask = MaskPtr(new Mask(*rhs.getMask(), deep));
725 _variance = VariancePtr(new Variance(*rhs.getVariance(), deep));
726 }
727
739
740 virtual ~MaskedImage() = default;
741
742 void swap(MaskedImage& rhs);
743
744 // Operators
746 MaskedImage& operator=(Pixel const& rhs);
748 MaskedImage& operator=(SinglePixel const& rhs);
749
763 MaskedImage subset(lsst::geom::Box2I const& bbox, ImageOrigin origin = PARENT) const {
764 return MaskedImage(*this, bbox, origin, false);
765 }
766
769
781 void assign(MaskedImage const& rhs, lsst::geom::Box2I const& bbox = lsst::geom::Box2I(),
782 ImageOrigin origin = PARENT);
783
785 MaskedImage& operator+=(ImagePixelT const rhs);
797 *_image += rhs;
798 return *this;
799 }
801 *_image += function;
802 return *this;
803 }
812 void scaledPlus(double const c, MaskedImage const& rhs);
813
815 MaskedImage& operator-=(ImagePixelT const rhs);
824 *_image -= rhs;
825 return *this;
826 }
828 *_image -= function;
829 return *this;
830 }
837 void scaledMinus(double const c, MaskedImage const& rhs);
838
839 MaskedImage& operator*=(ImagePixelT const rhs);
842 *_image *= rhs;
843 *_variance *= rhs; // yes, multiply twice
844 *_variance *= rhs;
845 return *this;
846 }
847 void scaledMultiplies(double const c, MaskedImage const& rhs);
848
849 MaskedImage& operator/=(ImagePixelT const rhs);
852 *_image /= rhs;
853 *_variance /= rhs; // yes, divide twice
854 *_variance /= rhs;
855 return *this;
856 }
857 void scaledDivides(double const c, MaskedImage const& rhs);
858
873 void writeFits(std::string const& fileName,
882
896 void writeFits(fits::MemFileManager& manager,
905
919 void writeFits(fits::Fits& fitsfile,
928
945 void writeFits(std::string const& fileName, fits::ImageWriteOptions const& imageOptions,
946 fits::ImageWriteOptions const& maskOptions, fits::ImageWriteOptions const& varianceOptions,
948 std::shared_ptr<daf::base::PropertySet const> imageMetadata = nullptr,
950 std::shared_ptr<daf::base::PropertySet const> varianceMetadata = nullptr) const;
951
968 void writeFits(fits::MemFileManager& manager, fits::ImageWriteOptions const& imageOptions,
969 fits::ImageWriteOptions const& maskOptions, fits::ImageWriteOptions const& varianceOptions,
971 std::shared_ptr<daf::base::PropertySet const> imageMetadata = nullptr,
973 std::shared_ptr<daf::base::PropertySet const> varianceMetadata = nullptr) const;
974
991 void writeFits(fits::Fits& fitsfile, fits::ImageWriteOptions const& imageOptions,
992 fits::ImageWriteOptions const& maskOptions, fits::ImageWriteOptions const& varianceOptions,
994 std::shared_ptr<daf::base::PropertySet const> imageMetadata = nullptr,
996 std::shared_ptr<daf::base::PropertySet const> varianceMetadata = nullptr) const;
997
1003 static MaskedImage readFits(std::string const& filename) {
1005 }
1006
1015
1016 // Getters
1017
1019 ImagePtr getImage() const { return _image; }
1020
1028 void setImage(Image const& other) { _image->assign(other); }
1029
1031 MaskPtr getMask() const { return _mask; }
1032
1040 void setMask(Mask const& other) { _mask->assign(other); }
1041
1049 void setVariance(Variance const& other) { _variance->assign(other); }
1050
1052 VariancePtr getVariance() const { return _variance; }
1053
1055 int getWidth() const { return _image->getWidth(); }
1057 int getHeight() const { return _image->getHeight(); }
1059 lsst::geom::Box2I getBBox(ImageOrigin const origin = PARENT) const { return _image->getBBox(origin); }
1067 int getX0() const { return _image->getX0(); }
1075 int getY0() const { return _image->getY0(); }
1083 lsst::geom::Point2I getXY0() const { return _image->getXY0(); }
1084
1093 void setXY0(int const x0, int const y0) { setXY0(lsst::geom::Point2I(x0, y0)); }
1094
1103 void setXY0(lsst::geom::Point2I const origin) {
1104 if (_image) {
1105 _image->setXY0(origin);
1106 }
1107
1108 if (_mask) {
1109 _mask->setXY0(origin);
1110 }
1111
1112 if (_variance) {
1113 _variance->setXY0(origin);
1114 }
1115 }
1116
1122 inline double indexToPosition(double ind,
1123 lsst::afw::image::xOrY const xy
1124 ) const {
1125 return getImage()->indexToPosition(ind, xy);
1126 }
1127
1134 double const pos,
1135 lsst::afw::image::xOrY const xy
1136 ) const {
1137 return getImage()->positionToIndex(pos, xy);
1138 }
1139
1140 //
1141 // Iterators and Locators
1142 //
1144 iterator begin() const;
1146 iterator end() const;
1148 iterator at(int const x, int const y) const;
1150 reverse_iterator rbegin() const;
1152 reverse_iterator rend() const;
1153
1164 fast_iterator begin(bool contiguous) const;
1173 fast_iterator end(bool contiguous) const;
1174
1176 x_iterator row_begin(int y) const;
1178 x_iterator row_end(int y) const;
1179
1181 x_iterator x_at(int x, int y) const {
1182#if 0
1183 typename Image::x_iterator imageEnd = getImage()->x_at(x, y);
1184 typename Mask::x_iterator maskEnd = getMask()->x_at(x, y);
1185 typename Variance::x_iterator varianceEnd = getVariance()->x_at(x, y);
1186#else // bypass checks for non-NULL pointers
1187 typename Image::x_iterator imageEnd = _image->x_at(x, y);
1188 typename Mask::x_iterator maskEnd = _mask->x_at(x, y);
1189 typename Variance::x_iterator varianceEnd = _variance->x_at(x, y);
1190#endif
1191
1192 return x_iterator(imageEnd, maskEnd, varianceEnd);
1193 }
1194
1196 y_iterator col_begin(int x) const;
1198 y_iterator col_end(int x) const;
1199
1201 y_iterator y_at(int x, int y) const {
1202#if 0
1203 typename Image::y_iterator imageEnd = getImage()->y_at(x, y);
1204 typename Mask::y_iterator maskEnd = getMask()->y_at(x, y);
1205 typename Variance::y_iterator varianceEnd = getVariance()->y_at(x, y);
1206#else // bypass checks for non-NULL pointers
1207 typename Image::y_iterator imageEnd = _image->y_at(x, y);
1208 typename Mask::y_iterator maskEnd = _mask->y_at(x, y);
1209 typename Variance::y_iterator varianceEnd = _variance->y_at(x, y);
1210#endif
1211 return y_iterator(imageEnd, maskEnd, varianceEnd);
1212 }
1213
1215 xy_locator xy_at(int x, int y) const {
1216#if 0
1217 typename Image::xy_locator imageEnd = getImage()->xy_at(x, y);
1218 typename Mask::xy_locator maskEnd = getMask()->xy_at(x, y);
1219 typename Variance::xy_locator varianceEnd = getVariance()->xy_at(x, y);
1220#else // bypass checks for non-NULL pointers
1221 typename Image::xy_locator imageEnd = _image->xy_at(x, y);
1222 typename Mask::xy_locator maskEnd = _mask->xy_at(x, y);
1223 typename Variance::xy_locator varianceEnd = _variance->xy_at(x, y);
1224#endif
1225
1226 return xy_locator(imageEnd, maskEnd, varianceEnd);
1227 }
1228
1229private:
1230 void conformSizes();
1231
1232 ImagePtr _image;
1233 MaskPtr _mask;
1234 VariancePtr _variance;
1235};
1236
1240template <typename ImagePixelT, typename MaskPixelT, typename VariancePixelT>
1248
1252template <typename ImagePixelT1, typename ImagePixelT2>
1253bool imagesOverlap(MaskedImage<ImagePixelT1, MaskPixel, VariancePixel> const& image1,
1254 MaskedImage<ImagePixelT2, MaskPixel, VariancePixel> const& image2);
1255
1256/*
1257 * Some metafunctions to extract an Image pointer from a MaskedImage pointer (or return the original Image
1258 * pointer)
1259 *
1260 * GetImage is the public interface (it forwards the tag --- just for the sake of the UI); the real work
1261 * is in GetImage_ which defines a typedef for the Image and a static function, getImage
1262 *
1263 * E.g.
1264 * In the function
1265 *
1266 * template<typename ImageT>
1267 * void func(shared_ptr<ImageT> image) {
1268 * typename shared_ptr<GetImage<ImageT>::type> im = GetImage<ImageT>::getImage(image);
1269 * }
1270 *
1271 * "im" is a shared_ptr<Image> irrespective of whether ImageT is Masked or not.
1272 */
1273namespace {
1274template <typename ImageT, typename TagT>
1275struct GetImage_ {
1276 using type = ImageT;
1277 static std::shared_ptr<type> getImage(std::shared_ptr<ImageT> image) { return image; }
1278};
1279
1280template <typename ImageT>
1281struct GetImage_<ImageT, typename image::detail::MaskedImage_tag> {
1282 using type = typename ImageT::Image;
1283 static std::shared_ptr<type> getImage(std::shared_ptr<ImageT> image) { return image->getImage(); }
1284};
1285} // anonymous namespace
1286
1287template <typename ImageT>
1288struct GetImage : public GetImage_<ImageT, typename ImageT::image_category> {};
1289} // namespace image
1290} // namespace afw
1291} // namespace lsst
1292
1293#endif // LSST_IMAGE_MASKEDIMAGE_H
AmpInfoBoxKey bbox
Definition Amplifier.cc:117
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition Exception.h:48
afw::table::Key< afw::table::Array< MaskPixelT > > mask
afw::table::Key< afw::table::Array< VariancePixelT > > variance
int y
Definition SpanSet.cc:48
A simple struct that combines the two arguments that must be passed to most cfitsio routines and cont...
Definition fits.h:308
Lifetime-management for memory that goes into FITS memory files.
Definition fits.h:125
void setXY0(lsst::geom::Point2I const origin)
Set the ImageBase's origin.
Definition ImageBase.h:434
y_iterator y_at(int x, int y) const
Return an y_iterator to the point (x, y) in the image.
Definition ImageBase.h:419
int getX0() const
Return the image's column-origin.
Definition ImageBase.h:306
xy_locator xy_at(int x, int y) const
Return an xy_locator at the point (x, y) in the image.
Definition ImageBase.h:425
typename _view_t::xy_locator xy_locator
An xy_locator.
Definition ImageBase.h:121
int getWidth() const
Return the number of columns in the image.
Definition ImageBase.h:294
lsst::geom::Box2I getBBox(ImageOrigin origin=PARENT) const
Definition ImageBase.h:445
int getY0() const
Return the image's row-origin.
Definition ImageBase.h:314
x_iterator x_at(int x, int y) const
Return an x_iterator to the point (x, y) in the image.
Definition ImageBase.h:407
lsst::geom::Extent2I getDimensions() const
Return the image's size; useful for passing to constructors.
Definition ImageBase.h:356
void assign(ImageBase const &rhs, lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), ImageOrigin origin=PARENT)
Copy pixels from another image to a specified subregion of this image.
Definition Image.cc:153
std::pair< int, double > positionToIndex(double const pos, lsst::afw::image::xOrY const xy) const
Convert image position to index (nearest integer and fractional parts)
Definition ImageBase.h:330
typename _view_t::reverse_iterator reverse_iterator
An STL compliant reverse iterator.
Definition ImageBase.h:129
int getHeight() const
Return the number of rows in the image.
Definition ImageBase.h:296
double indexToPosition(double ind, lsst::afw::image::xOrY const xy) const
Convert image index to image position.
Definition ImageBase.h:349
typename _view_t::x_iterator x_iterator
An iterator for traversing the pixels in a row.
Definition ImageBase.h:133
typename _view_t::y_iterator y_iterator
An iterator for traversing the pixels in a column.
Definition ImageBase.h:143
lsst::geom::Point2I getXY0() const
Return the image's origin.
Definition ImageBase.h:323
A class to represent a 2-dimensional array of pixels.
Definition Image.h:51
Represent a 2-dimensional array of bitmask pixels.
Definition Mask.h:77
The base class for MaskedImageIterators (const and non-const)
bool operator==(MaskedImageIteratorBase const &rhs)
Return true if the lhs equals the rhs.
MaskedImageIteratorBase operator++(int)
Increment the iterator (postfix)
const Pixel operator*() const
Dereference the iterator, returning a const Pixel.
std::ptrdiff_t operator-(MaskedImageIteratorBase const &rhs)
Return the distance between two iterators.
MaskedImageIteratorBase & operator++()
Increment the iterator (prefix)
bool operator!=(MaskedImageIteratorBase const &rhs)
Return true if the lhs doesn't equal the rhs.
boost::zip_iterator< IMV_iterator_tuple > _iter
Ref< ImagePixelT >::type image()
Return (a reference to) the image part of the Pixel pointed at by the iterator.
Ref< MaskPixelT >::type mask()
Return (a reference to) the mask part of the Pixel pointed at by the iterator.
Ref< VariancePixelT >::type variance()
Return (a reference to) the variance part of the Pixel pointed at by the iterator.
Pixel operator*()
Dereference the iterator, returning a Pixel.
MaskedImageIteratorBase & operator-=(std::ptrdiff_t delta)
Decrement the iterator by delta
typename boost::zip_iterator< IMV_iterator_tuple >::reference IMV_tuple
The underlying iterator tuple.
MaskedImageIteratorBase(ImageIterator const &img, MaskIterator const &msk, VarianceIterator const &var)
Construct a MaskedImageIteratorBase from the image/mask/variance iterators.
bool operator<(MaskedImageIteratorBase const &rhs)
Return true if the lhs is less than the rhs.
MaskedImageIteratorBase & operator+=(std::ptrdiff_t delta)
Increment the iterator by delta
const IMV_iterator_tuple get_iterator_tuple() const
Return the underlying iterator tuple.
MaskedImageIterator(ImageIterator &img, MaskIterator &msk, VarianceIterator &var)
MaskedImageIterator operator+(std::ptrdiff_t delta)
Return a MaskedImageIterator that's delta beyond this.
A saved relative position, providing efficient access to neighbouring pixels.
cached_location_t(IMVLocator const &loc, int x, int y)
Create a cached_location_t that can be used to access pixels (x, y) away from loc
The base class for MaskedImageLocators (const and non-const)
typename boost::tuple< typename ImageLocator::cached_location_t, typename MaskLocator::cached_location_t, typename VarianceLocator::cached_location_t > IMVCachedLocation
Ref< typenameboost::mpl::at< PixelTVec, N >::type >::type apply_IMV(cached_location_t const &cached_loc)
Pixel operator*()
Dereference a locator, returning a Pixel.
_x_or_y_iterator< apply_y > y_iterator
A y_iterator that provides a view of the xy_locator (i.e. advancing one advances the other)
Pixel operator[](cached_location_t const &cached_loc)
Dereference a locator, returning a Pixel offset by the amount set when we created the cached_location...
Ref< MaskPixelT >::type mask(int x, int y)
Return a reference to the mask offset by (x, y) from the current position of the locator.
cached_location_t cache_location(int x, int y) const
Create a cached_location_t offset by (x, y) from locator.
Ref< VariancePixelT >::type variance(int x, int y)
Return a reference to the variance offset by (x, y) from the current position of the locator.
Ref< VariancePixelT >::type variance()
Return a reference to the variance at the current position of the locator.
MaskedImageLocatorBase & operator+=(pair2I const &p)
Increment the locator's x and y positions by p
Ref< ImagePixelT >::type image()
Return a reference to the image at the current position of the locator.
_x_or_y_iterator< apply_x > x_iterator
An x_iterator that provides a view of the xy_locator (i.e. advancing one advances the other)
Ref< ImagePixelT >::type image(cached_location_t const &cached_loc)
Return a reference to the image at the offset set when we created the cached_location_t
MaskedImageLocatorBase & operator+=(detail::difference_type p)
Increment the locator's x and y positions by p
Pixel operator()(int x, int y)
Dereference a locator, returning a Pixel offset by (x, y) from the locator.
y_iterator y()
Return an iterator that can be used to move (or dereference) a locator.
bool operator==(MaskedImageLocatorBase const &rhs)
Return true iff two locators are equal.
Ref< MaskPixelT >::type mask(cached_location_t const &cached_loc)
Return a reference to the mask at the offset set when we created the cached_location_t
Ref< typenameboost::mpl::at< PixelTVec, N >::type >::type apply_IMV()
Ref< typenameboost::mpl::at< PixelTVec, N >::type >::type apply_IMV(int x, int y)
Ref< ImagePixelT >::type image(int x, int y)
Return a reference to the image offset by (x, y) from the current position of the locator.
Ref< MaskPixelT >::type mask()
Return a reference to the mask at the current position of the locator.
bool operator!=(MaskedImageLocatorBase const &rhs)
Return true iff two locators are not equal.
typename boost::mpl::vector< ImagePixelT, MaskPixelT, VariancePixelT > PixelTVec
Ref< VariancePixelT >::type variance(cached_location_t const &cached_loc)
Return a reference to the variance at the offset set when we created the cached_location_t
bool operator<(MaskedImageLocatorBase const &rhs)
Return true iff lhs is less than rhs.
MaskedImageLocatorBase(ImageLocator const &img, MaskLocator const &msk, VarianceLocator const &var)
Construct a MaskedImageLocator from image/mask/variance locators.
x_iterator x()
Return an iterator that can be used to move (or dereference) a locator.
MaskedImageLocator(ImageLocator &img, MaskLocator &msk, VarianceLocator &var)
const_MaskedImageIterator & operator+(std::ptrdiff_t delta)
Return a const_MaskedImageIterator that's delta beyond this.
const_MaskedImageIterator(MaskedImageIterator< ImageIterator, MaskIterator, VarianceIterator > const &iter)
const_MaskedImageLocator(MaskedImageLocator< ImageLocator, MaskLocator, VarianceLocator > const &iter)
A class to manipulate images, masks, and variance as a single object.
Definition MaskedImage.h:74
void scaledPlus(double const c, MaskedImage const &rhs)
Add a scaled MaskedImage c*rhs to a MaskedImage.
lsst::afw::image::Image< VariancePixelT > Variance
Definition MaskedImage.h:85
MaskedImage operator[](lsst::geom::Box2I const &bbox) const
Return a subimage corresponding to the given box (interpreted as PARENT coordinates).
MaskedImage & operator-=(lsst::afw::math::Function2< double > const &function)
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.
int getX0() const
Return the image's column-origin.
std::pair< int, double > positionToIndex(double const pos, lsst::afw::image::xOrY const xy) const
Convert image position to index (see Image::positionToIndex)
MaskedImage(unsigned int width, unsigned int height, MaskPlaneDict const &planeDict=MaskPlaneDict())
Construct from a supplied dimensions.
void setXY0(lsst::geom::Point2I const origin)
Set the MaskedImage's origin.
lsst::geom::Box2I getBBox(ImageOrigin const origin=PARENT) const
MaskedImage & operator*=(lsst::afw::image::Image< ImagePixelT > const &rhs)
void setVariance(Variance const &other)
Set the variance plane's pixel values to those of another Image.
void setXY0(int const x0, int const y0)
Set the MaskedImage's origin.
static MaskedImage readFits(fits::MemFileManager &manager)
Read a MaskedImage from a FITS RAM file.
void scaledDivides(double const c, MaskedImage const &rhs)
typename MaskedImageLocator< typename Image::xy_locator, typename Mask::xy_locator, typename Variance::xy_locator >::y_iterator xy_y_iterator
an y_iterator associated with an xy_locator
MaskedImage(MaskedImage< OtherPixelT, MaskPixelT, VariancePixelT > const &rhs, const bool deep)
generalised copy constructor; defined here in the header so that the compiler can instantiate N(N-1)/...
MaskedImageIterator< typename Image::y_iterator, typename Mask::y_iterator, typename Variance::y_iterator > y_iterator
An iterator to a column of a MaskedImage.
int getHeight() const
Return the number of rows in the image.
typename Mask< MaskPixelT >::MaskPlaneDict MaskPlaneDict
The Mask's MaskPlaneDict.
Definition MaskedImage.h:83
int getY0() const
Return the image's row-origin.
virtual ~MaskedImage()=default
MaskedImage & operator=(MaskedImage &&rhs)
lsst::afw::image::pixel::Pixel< ImagePixelT, MaskPixelT, VariancePixelT > Pixel
A Pixel in the MaskedImage.
iterator begin() const
Return an iterator to the start of the image.
reverse_iterator rbegin() const
Return a reverse_iterator to the start of the image.
std::shared_ptr< image::Mask< MaskPixelT > > MaskPtr
shared pointer to the Mask
Definition MaskedImage.h:79
MaskedImageIterator< typename Image::x_iterator, typename Mask::x_iterator, typename Variance::x_iterator > x_iterator
An iterator to a row of a MaskedImage.
void setMask(Mask const &other)
Set the mask plane's pixel values to those of another Mask.
lsst::afw::image::Mask< MaskPixelT > Mask
Definition MaskedImage.h:87
y_iterator col_end(int x) const
Return an y_iterator to the end of the image.
void scaledMinus(double const c, MaskedImage const &rhs)
Subtract a scaled MaskedImage c*rhs from a MaskedImage.
x_iterator fast_iterator
A fast STL compliant iterator for contiguous images N.b.
std::shared_ptr< image::Image< ImagePixelT > > ImagePtr
shared pointer to the Image
Definition MaskedImage.h:77
MaskedImageLocator< typename Image::xy_locator, typename Mask::xy_locator, typename Variance::xy_locator > xy_locator
A locator for a MaskedImage.
lsst::geom::Extent2I getDimensions() const
lsst::geom::Point2I getXY0() const
Return the image's origin.
MaskedImageIterator< typename Image::reverse_iterator, typename Mask::reverse_iterator, typename Variance::reverse_iterator > reverse_iterator
MaskedImageIterator< typename Image::iterator, typename Mask::iterator, typename Variance::iterator > iterator
xy_locator xy_at(int x, int y) const
Return an xy_locator at the point (x, y)
MaskedImage & operator-=(ImagePixelT const rhs)
Subtract a scalar rhs from a MaskedImage.
int getWidth() const
Return the number of columns in the image.
x_iterator row_end(int y) const
Return an x_iterator to the end of the image.
MaskedImage subset(lsst::geom::Box2I const &bbox, ImageOrigin origin=PARENT) const
Return a subimage corresponding to the given box.
void scaledMultiplies(double const c, MaskedImage const &rhs)
iterator end() const
Return an iterator to the end of the image.
MaskedImage & operator/=(lsst::afw::image::Image< ImagePixelT > const &rhs)
typename MaskedImageLocator< typename Image::xy_locator, typename Mask::xy_locator, typename Variance::xy_locator >::x_iterator xy_x_iterator
an x_iterator associated with an xy_locator
MaskedImage & operator-=(lsst::afw::image::Image< ImagePixelT > const &rhs)
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.
VariancePtr getVariance() const
Return a (shared_ptr to) the MaskedImage's variance.
MaskedImage & operator+=(lsst::afw::image::Image< ImagePixelT > const &rhs)
MaskedImage & operator=(MaskedImage const &rhs)
Make the lhs use the rhs's pixels.
lsst::afw::image::Image< ImagePixelT > Image
Definition MaskedImage.h:86
x_iterator row_begin(int y) const
Return an x_iterator to the start of the image.
void swap(MaskedImage &rhs)
double indexToPosition(double ind, lsst::afw::image::xOrY const xy) const
Convert image index to image position (see Image::indexToPosition)
void setImage(Image const &other)
Set the image plane's pixel values to those of another Image.
y_iterator col_begin(int x) const
Return an y_iterator to the start of the image.
std::shared_ptr< image::Image< VariancePixelT > > VariancePtr
shared pointer to the variance Image
Definition MaskedImage.h:81
reverse_iterator rend() const
Return a reverse_iterator to the end of the image.
static MaskedImage readFits(std::string const &filename)
Read a MaskedImage from a regular FITS file.
MaskedImage & operator+=(ImagePixelT const rhs)
Add a scalar rhs to a MaskedImage.
x_iterator x_at(int x, int y) const
Return an x_iterator at the point (x, y)
MaskedImage & operator*=(ImagePixelT const rhs)
iterator at(int const x, int const y) const
Return an iterator at the point (x, y)
MaskedImage & operator/=(ImagePixelT const rhs)
y_iterator y_at(int x, int y) const
Return an y_iterator at the point (x, y)
MaskPtr getMask() const
Return a (shared_ptr to) the MaskedImage's mask.
MaskedImage & operator+=(lsst::afw::math::Function2< double > const &function)
ImagePtr getImage() const
Return a (shared_ptr to) the MaskedImage's image.
A pixel of a MaskedImage.
Definition Pixel.h:148
A single pixel of the same type as a MaskedImage.
Definition Pixel.h:73
A Function taking two arguments.
Definition Function.h:259
An integer coordinate rectangle.
Definition Box.h:55
Reports invalid arguments.
Definition Runtime.h:66
std::string const fitsFile_RE
regexp to identify when MaskedImages should be written as MEFs
Definition MaskedImage.h:56
std::string const compressedFileNoMEF_RE
regexp to identify compressed files that we can't write MEFs to
Definition MaskedImage.h:58
std::int32_t MaskPixel
default type for Masks and MaskedImage Masks
float VariancePixel
default type for MaskedImage variance images
MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > * makeMaskedImage(typename std::shared_ptr< Image< ImagePixelT > > image, typename std::shared_ptr< Mask< MaskPixelT > > mask=Mask< MaskPixelT >(), typename std::shared_ptr< Image< VariancePixelT > > variance=Image< VariancePixelT >())
A function to return a MaskedImage of the correct type (cf.
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:693
Options for writing an image to FITS.
Definition fits.h:223
A templated class to return this classes' type (present in Image/Mask/MaskedImage)
Definition MaskedImage.h:93
metafunction to extract reference type from PixelT
Definition ImageBase.h:85
A traits class for MaskedImage.
Definition MaskedImage.h:51
A class used to identify classes that represent MaskedImage pixels.
Definition MaskedImage.h:53