31 #pragma clang diagnostic push
32 #pragma clang diagnostic ignored "-Wunused-variable"
33 #include "boost/lambda/lambda.hpp"
34 #pragma clang diagnostic pop
35 #include "boost/regex.hpp"
36 #include "boost/filesystem/path.hpp"
39 #include "boost/algorithm/string/trim.hpp"
45 namespace bl = boost::lambda;
52 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
58 lsst::daf::base::Citizen(typeid(this)),
59 _image(new
Image(width, height)),
60 _mask(new
Mask(width, height, planeDict)),
61 _variance(new
Variance(width, height)) {
71 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
76 lsst::daf::base::Citizen(typeid(this)),
77 _image(new
Image(dimensions)),
78 _mask(new
Mask(dimensions, planeDict)),
79 _variance(new
Variance(dimensions)) {
93 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
98 lsst::daf::base::Citizen(typeid(this)),
99 _image(new
Image(bbox)),
100 _mask(new
Mask(bbox, planeDict)),
107 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
114 ) : lsst::daf::base::Citizen(typeid(this)),
115 _image(), _mask(), _variance()
118 *
this =
MaskedImage(fitsfile, metadata, bbox, origin, conformMasks, needAllHdus,
119 imageMetadata, maskMetadata, varianceMetadata);
122 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
129 ) : lsst::daf::base::Citizen(typeid(this)),
130 _image(), _mask(), _variance()
133 *
this =
MaskedImage(fitsfile, metadata, bbox, origin, conformMasks, needAllHdus,
134 imageMetadata, maskMetadata, varianceMetadata);
144 std::string
const & expected
147 std::string exttype = boost::algorithm::trim_right_copy(metadata->
getAsString(
"EXTTYPE"));
148 if (exttype !=
"" && exttype != expected) {
149 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
150 (
boost::format(
"Reading %s (hdu %d) Expected EXTTYPE==\"%s\", saw \"%s\"") %
153 metadata->
remove(
"EXTTYPE");
154 }
catch(lsst::pex::exceptions::NotFoundError) {
156 log.warn(
boost::format(
"Expected extension type not found: %s") % expected);
169 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
176 ) : lsst::daf::base::Citizen(typeid(this)),
177 _image(), _mask(), _variance()
206 if (needAllHdus && fitsfile.
getHdu() >
static_cast<int>(Hdu::Image)) {
208 "Cannot read all HDUs starting from non-default");
214 auto prevHdu = fitsfile.
getHdu();
215 fitsfile.
setHdu(static_cast<int>(Hdu::Primary));
223 ensureMetadata(imageMetadata);
224 _image.reset(
new Image(fitsfile, imageMetadata, bbox, origin));
225 checkExtType(fitsfile, imageMetadata,
"IMAGE");
227 if (fitsfile.
getHdu() !=
static_cast<int>(Hdu::Image)) {
234 fitsfile.
setHdu(static_cast<int>(Hdu::Mask));
235 ensureMetadata(maskMetadata);
236 _mask.reset(
new Mask(fitsfile, maskMetadata, bbox, origin, conformMasks));
237 checkExtType(fitsfile, maskMetadata,
"MASK");
238 }
catch(fits::FitsError &e) {
243 log.
warn(
"Mask unreadable; using default");
250 fitsfile.
setHdu(static_cast<int>(Hdu::Variance));
251 ensureMetadata(varianceMetadata);
253 checkExtType(fitsfile, varianceMetadata,
"VARIANCE");
254 }
catch(fits::FitsError &e) {
259 log.
warn(
"Variance unreadable; using default");
270 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
276 lsst::daf::base::Citizen(typeid(this)),
279 _variance(variance) {
286 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
291 lsst::daf::base::Citizen(typeid(this)),
292 _image(rhs._image), _mask(rhs._mask), _variance(rhs._variance) {
304 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
312 lsst::daf::base::Citizen(typeid(this)),
313 _image(new
Image(*rhs.getImage(), bbox, origin, deep)),
314 _mask(rhs._mask ? new
Mask(*rhs.getMask(), bbox, origin, deep) : static_cast<
Mask *>(NULL)),
315 _variance(rhs._variance ? new
Variance(*rhs.getVariance(), bbox, origin, deep) : static_cast<
Variance *>(NULL)) {
327 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
332 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
337 _mask.swap(rhs.
_mask);
348 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
351 *_image = rhs.
image();
361 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
364 *_image = rhs.
image();
376 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
390 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
404 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
407 (*_image).scaledPlus(c, *rhs.
getImage());
413 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
423 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
435 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
438 (*_image).scaledMinus(c, *rhs.
getImage());
444 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
451 template<
typename ImagePixelT,
typename VariancePixelT>
452 struct productVariance {
453 double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
454 return lhs*lhs*varRhs + rhs*rhs*varLhs;
459 template<
typename ImagePixelT,
typename VariancePixelT>
460 struct scaledProductVariance {
462 scaledProductVariance(
double const c) : _c(c) {}
463 double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
464 return _c*_c*(lhs*lhs*varRhs + rhs*rhs*varLhs);
469 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
472 transform_pixels(_image->_getRawView(),
473 rhs.
_image->_getRawView(),
474 _variance->_getRawView(),
476 _variance->_getRawView(),
477 productVariance<ImagePixelT, VariancePixelT>());
483 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
487 transform_pixels(_image->_getRawView(),
488 rhs.
_image->_getRawView(),
489 _variance->_getRawView(),
491 _variance->_getRawView(),
492 scaledProductVariance<ImagePixelT, VariancePixelT>(c));
494 (*_image).scaledMultiplies(c, *rhs.
getImage());
498 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
501 *_variance *= rhs*rhs;
507 template<
typename ImagePixelT,
typename VariancePixelT>
508 struct quotientVariance {
509 double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
510 ImagePixelT
const rhs2 = rhs*rhs;
511 return (lhs*lhs*varRhs + rhs2*varLhs)/(rhs2*rhs2);
515 template<
typename ImagePixelT,
typename VariancePixelT>
516 struct scaledQuotientVariance {
518 scaledQuotientVariance(
double c) : _c(c) {}
519 double operator()(ImagePixelT lhs, ImagePixelT rhs, VariancePixelT varLhs, VariancePixelT varRhs) {
520 ImagePixelT
const rhs2 = rhs*rhs;
521 return (lhs*lhs*varRhs + rhs2*varLhs)/(_c*_c*rhs2*rhs2);
526 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
529 transform_pixels(_image->_getRawView(),
530 rhs.
_image->_getRawView(),
531 _variance->_getRawView(),
533 _variance->_getRawView(),
534 quotientVariance<ImagePixelT, VariancePixelT>());
540 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
544 transform_pixels(_image->_getRawView(),
545 rhs.
_image->_getRawView(),
546 _variance->_getRawView(),
548 _variance->_getRawView(),
549 scaledQuotientVariance<ImagePixelT, VariancePixelT>(c));
551 (*_image).scaledDivides(c, *rhs.
getImage());
552 *_mask |= *rhs.
_mask;
555 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
558 *_variance /= rhs*rhs;
561 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
563 std::string
const& fileName,
570 writeFits(fitsfile, metadata, imageMetadata, maskMetadata, varianceMetadata);
573 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
582 writeFits(fitsfile, metadata, imageMetadata, maskMetadata, varianceMetadata);
587 void processPlaneMetadata(
597 hdr->
set(
"INHERIT",
true);
598 hdr->
set(
"EXTTYPE", exttype);
603 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
621 pex::exceptions::LogicError,
622 "MaskedImage::writeFits can only write to an empty file"
625 if (fitsfile.
getHdu() <= 1) {
633 processPlaneMetadata(imageMetadata, hdr,
"IMAGE");
634 _image->writeFits(fitsfile, hdr);
636 processPlaneMetadata(maskMetadata, hdr,
"MASK");
637 _mask->writeFits(fitsfile, hdr);
639 processPlaneMetadata(varianceMetadata, hdr,
"VARIANCE");
640 _variance->writeFits(fitsfile, hdr);
648 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
651 if (!_mask || _mask->getWidth() == 0 || _mask->getHeight() == 0) {
655 if (_mask->getDimensions() != _image->getDimensions()) {
657 lsst::pex::exceptions::LengthError,
658 (
boost::format(
"Dimension mismatch: Image %dx%d v. Mask %dx%d") %
659 _image->getWidth() % _image->getHeight() %
660 _mask->getWidth() % _mask->getHeight()
666 if (!_variance || _variance->getWidth() == 0 || _variance->getHeight() == 0) {
670 if (_variance->getDimensions() != _image->getDimensions()) {
672 lsst::pex::exceptions::LengthError,
673 (
boost::format(
"Dimension mismatch: Image %dx%d v. Variance %dx%d") %
674 _image->getWidth() % _image->getHeight() %
675 _variance->getWidth() % _variance->getHeight()
687 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
689 #if 0 // this doesn't compile; why?
690 return iterator(_image->begin(), _mask->begin(), _variance->begin());
696 return iterator(imageBegin, maskBegin, varianceBegin);
701 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
707 return iterator(imageEnd, maskEnd, varianceEnd);
711 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
717 return iterator(imageEnd, maskEnd, varianceEnd);
721 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
731 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
741 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
747 return x_iterator(imageBegin, maskBegin, varianceBegin);
751 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
757 return x_iterator(imageEnd, maskEnd, varianceEnd);
763 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
769 return y_iterator(imageBegin, maskBegin, varianceBegin);
773 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
779 return y_iterator(imageEnd, maskEnd, varianceEnd);
790 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
807 template<
typename ImagePixelT,
typename MaskPixelT,
typename VariancePixelT>
void createEmpty()
Create an empty image HDU with NAXIS=0 at the end of the file.
Mask< MaskPixelT >::Ptr MaskPtr
shared pointer to the Mask
ImagePtr getImage(bool const noThrow=false) const
Return a (Ptr to) the MaskedImage's image.
Image< VariancePixelT >::Ptr VariancePtr
shared pointer to the variance Image
Mask< MaskPixelT >::MaskPlaneDict MaskPlaneDict
The Mask's MaskPlaneDict.
void setHdu(int hdu, bool relative=false)
Set the current HDU.
void swap(ImageBase< PixelT > &a, ImageBase< PixelT > &b)
iterator end() const
Return an iterator to the end of the image.
void scaledDivides(double const c, MaskedImage const &rhs)
virtual void remove(std::string const &name)
Class for storing ordered metadata with comments.
VariancePixelT variance() const
Return the variance part of a Pixel.
void readMetadata(daf::base::PropertySet &metadata, bool strip=false)
Read a FITS header into a PropertySet or PropertyList.
iterator at(int const x, int const y) const
Return an iterator at the point (x, y)
void operator-=(ImagePixelT const rhs)
Subtract a scalar rhs from a MaskedImage.
y_iterator col_begin(int x) const
Return an y_iterator to the start of the image.
_view_t::y_iterator y_iterator
An iterator for traversing the pixels in a column.
definition of the Trace messaging facilities
MaskedImage(unsigned int width, unsigned int height, MaskPlaneDict const &planeDict=MaskPlaneDict())
Construct from a supplied dimensions. The Image, Mask, and Variance will be set to zero...
A single pixel of the same type as a MaskedImage.
x_iterator row_end(int y) const
Return an x_iterator to the end of the image.
A simple struct that combines the two arguments that must be passed to most cfitsio routines and cont...
lsst::afw::image::Mask< MaskPixelT > Mask
boost::shared_ptr< Image< PixelT > > Ptr
void set(std::string const &name, T const &value)
a place to record messages and descriptions of the state of processing.
static Log & getDefaultLog()
ImagePixelT image() const
void swap(MaskedImage &rhs)
ImagePixelT image() const
Return the image part of a Pixel.
boost::shared_ptr< Mask > Ptr
An integer coordinate rectangle.
table::Key< table::Array< Kernel::Pixel > > image
_view_t::iterator iterator
An STL compliant iterator.
An iterator to the MaskedImage.
VariancePtr getVariance(bool const noThrow=false) const
Return a (Ptr to) the MaskedImage's variance.
std::string getFileName() const
Return the file name associated with the FITS object or "<unknown>" if there is none.
afw::table::PointKey< int > dimensions
lsst::afw::image::Image< ImagePixelT > Image
Represent a 2-dimensional array of bitmask pixels.
Lifetime-management for memory that goes into FITS memory files.
lsst::afw::image::Image< VariancePixelT > Variance
int getHdu()
Return the current HDU (1-indexed; 1 is the Primary HDU).
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.
void operator*=(ImagePixelT const rhs)
A class to manipulate images, masks, and variance as a single object.
_view_t::reverse_iterator reverse_iterator
An STL compliant reverse iterator.
Image< ImagePixelT >::Ptr ImagePtr
shared pointer to the Image
void operator/=(ImagePixelT const rhs)
MaskedImage & operator=(MaskedImage const &rhs)
Make the lhs use the rhs's pixels.
void operator<<=(MaskedImage const &rhs)
#define LSST_EXCEPT(type,...)
A pixel of a MaskedImage.
MaskPixelT mask() const
Return the mask part of a Pixel.
MaskPtr getMask(bool const noThrow=false) const
Return a (Ptr to) the MaskedImage's mask.
VariancePixelT variance() const
void scaledMultiplies(double const c, MaskedImage const &rhs)
_view_t::x_iterator x_iterator
An iterator for traversing the pixels in a row.
Class for storing generic metadata.
void warn(const std::string &message, const lsst::daf::base::PropertySet &properties)
virtual Ptr deepCopy(void) const
std::string getAsString(std::string const &name) const
reverse_iterator rbegin() const
Return a reverse_iterator to the start of the image.
int countHdus()
Return the number of HDUs in the file.
x_iterator row_begin(int y) const
Return an x_iterator to the start of the image.
Implementation of the Class MaskedImage.
void operator+=(ImagePixelT const rhs)
Add a scalar rhs to a MaskedImage.
reverse_iterator rend() const
Return a reverse_iterator to the end of the image.
#define LSST_EXCEPT_ADD(e, m)
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)
void scaledPlus(double const c, MaskedImage const &rhs)
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.
Include files required for standard LSST Exception handling.