34#include "boost/format.hpp"
54template <
typename MaskPixelT>
55void Mask<MaskPixelT>::_initializePlanes(MaskPlaneDict
const& planeDefs) {
56 LOGL_DEBUG(
"lsst.afw.image.Mask",
"Number of mask planes: %d", getNumPlanesMax());
61template <
typename MaskPixelT>
64 _initializePlanes(planeDefs);
68template <
typename MaskPixelT>
72 _initializePlanes(planeDefs);
76template <
typename MaskPixelT>
79 _initializePlanes(planeDefs);
83template <
typename MaskPixelT>
87 _initializePlanes(planeDefs);
91template <
typename MaskPixelT>
94 _initializePlanes(planeDefs);
98template <
typename MaskPixelT>
101 _initializePlanes(planeDefs);
102 *
this = initialValue;
105template <
typename MaskPixelT>
108 :
ImageBase<MaskPixelT>(rhs,
bbox, origin, deep), _maskDict(rhs._maskDict) {}
110template <
typename MaskPixelT>
112 :
ImageBase<MaskPixelT>(rhs, deep), _maskDict(rhs._maskDict) {}
114template <
typename MaskPixelT>
117template <
typename MaskPixelT>
120template <
typename MaskPixelT>
123 :
image::
ImageBase<MaskPixelT>(array, deep, xy0), _maskDict(detail::MaskDict::getDefault()) {}
125template <
typename PixelT>
130 swap(_maskDict, rhs._maskDict);
133template <
typename PixelT>
138template <
typename MaskPixelT>
146template <
typename MaskPixelT>
151template <
typename MaskPixelT>
153 fill_pixels(_getRawView(), rhs);
160template <
typename MaskPixelT>
163 :
ImageBase<MaskPixelT>(), _maskDict(detail::MaskDict::getDefault()) {
165 *
this = reader.read<MaskPixelT>(
bbox, origin, conformMasks, allowUnsafe);
167 metadata->combine(*reader.readMetadata());
171template <
typename MaskPixelT>
174 ImageOrigin origin,
bool conformMasks,
bool allowUnsafe)
175 : ImageBase<MaskPixelT>(), _maskDict(detail::MaskDict::getDefault()) {
177 *
this = reader.read<MaskPixelT>(
bbox, origin, conformMasks, allowUnsafe);
179 metadata->combine(*reader.readMetadata());
183template <
typename MaskPixelT>
187 : ImageBase<MaskPixelT>(), _maskDict(detail::MaskDict::getDefault()) {
189 *
this = reader.read<MaskPixelT>(
bbox, origin, conformMasks, allowUnsafe);
191 metadata->combine(*reader.readMetadata());
195template <
typename MaskPixelT>
197 daf::base::PropertySet
const * metadata_i,
203template <
typename MaskPixelT>
210template <
typename MaskPixelT>
212 daf::base::PropertySet
const * metadata_i,
218template <
typename MaskPixelT>
225template <
typename MaskPixelT>
227 daf::base::PropertySet
const * metadata)
const {
228 writeFits(fitsfile, fits::ImageWriteOptions(*
this), metadata);
231template <
typename MaskPixelT>
234 writeFits(fitsfile, metadata.
get());
237template <
typename MaskPixelT>
242 writeFits(fitsfile, options, header);
245template <
typename MaskPixelT>
249 writeFits(filename, options, mode, header.
get());
252template <
typename MaskPixelT>
257 writeFits(fitsfile, options, header);
260template <
typename MaskPixelT>
264 writeFits(manager, options, mode, header.
get());
267template <
typename MaskPixelT>
271 header ? header->
deepCopy() : std::make_shared<dafBase::PropertySet>();
272 addMaskPlanesToMetadata(useHeader);
276template <
typename MaskPixelT>
279 writeFits(fitsfile, options, header.
get());
284template <
typename MaskPixelT>
287 MaskPlaneDict const& mpd = _maskPlaneDict()->getMaskPlaneDict();
288 for (
auto const &iter : mpd) {
289 if (value & getBitMask(iter.second)) {
299template <
typename MaskPixelT>
301 int id = getMaskPlaneNoThrow(
name);
304 id = _maskPlaneDict()->getUnusedPlane();
309 if (
id >= getNumPlanesMax()) {
311 str(boost::format(
"Max number of planes (%1%) already used") % getNumPlanesMax()));
319template <
typename MaskPixelT>
321 if (planeId < 0 || planeId >= getNumPlanesMax()) {
324 str(boost::format(
"mask plane ID must be between 0 and %1%") % (getNumPlanesMax() - 1)));
327 _maskPlaneDict()->add(
name, planeId);
332template <
typename MaskPixelT>
334 return _maskDict->getMaskPlaneDict();
337template <
typename MaskPixelT>
341 str(boost::format(
"Plane %s doesn't exist in the default Mask") %
name));
345 _maskPlaneDict()->erase(
name);
348template <
typename MaskPixelT>
352 clearMaskPlane(getMaskPlane(
name));
357 _maskDict = _maskDict->clone();
360 _maskDict->erase(
name);
363 removeMaskPlane(
name);
367template <
typename MaskPixelT>
369 return (planeId >= 0 && planeId < getNumPlanesMax()) ? (1 << planeId) : 0;
372template <
typename MaskPixelT>
373MaskPixelT Mask<MaskPixelT>::getBitMask(
int planeId) {
374 MaskPlaneDict
const& mpd = _maskPlaneDict()->getMaskPlaneDict();
376 for (
auto const &i : mpd) {
377 if (planeId == i.second) {
378 MaskPixelT
const bitmask = getBitMaskNoThrow(planeId);
386 str(boost::format(
"Invalid mask plane ID: %d") % planeId));
389template <
typename MaskPixelT>
391 int const plane = getMaskPlaneNoThrow(
name);
395 str(boost::format(
"Invalid mask plane name: %s") %
name));
401template <
typename MaskPixelT>
406template <
typename MaskPixelT>
408 return getBitMask(getMaskPlane(
name));
411template <
typename MaskPixelT>
413 MaskPixelT mpix = 0x0;
414 for (
auto const &it :
name) {
415 mpix |= getBitMask(getMaskPlane(it));
420template <
typename MaskPixelT>
422 return _maskPlaneDict()->size();
425template <
typename MaskPixelT>
427 _maskPlaneDict()->clear();
430template <
typename MaskPixelT>
435template <
typename MaskPixelT>
437 *
this &= ~getBitMask(planeId);
440template <
typename MaskPixelT>
444 if (*_maskDict == *currentMD) {
452 MaskPixelT keepBitmask = 0;
453 MaskPixelT canonicalMask[
sizeof(MaskPixelT) * 8];
454 MaskPixelT currentMask[
sizeof(MaskPixelT) * 8];
457 for (
auto const &i : currentPlaneDict) {
459 int const currentPlaneNumber = i.second;
460 int canonicalPlaneNumber = getMaskPlaneNoThrow(
name);
462 if (canonicalPlaneNumber < 0) {
463 canonicalPlaneNumber = addMaskPlane(
name);
466 if (canonicalPlaneNumber == currentPlaneNumber) {
467 keepBitmask |= getBitMask(canonicalPlaneNumber);
469 canonicalMask[numReMap] = getBitMask(canonicalPlaneNumber);
470 currentMask[numReMap] = getBitMaskNoThrow(currentPlaneNumber);
477 for (
int r = 0; r != this->getHeight(); ++r) {
482 MaskPixelT newPixel =
pixel & keepBitmask;
483 for (
int i = 0; i < numReMap; i++) {
484 if (
pixel & currentMask[i]) newPixel |= canonicalMask[i];
496template <
typename MaskPixelT>
501template <
typename MaskPixelT>
507template <
typename MaskPixelT>
512template <
typename MaskPixelT>
518template <
typename MaskPixelT>
524template <
typename MaskPixelT>
530template <
typename MaskPixelT>
532 if (*_maskDict != *other._maskDict) {
537template <
typename MaskPixelT>
539 transform_pixels(_getRawView(), _getRawView(),
540 [&
val](MaskPixelT
const& l) -> MaskPixelT {
return l |
val; });
544template <
typename MaskPixelT>
546 checkMaskDictionaries(rhs);
550 str(boost::format(
"Images are of different size, %dx%d v %dx%d") %
553 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
554 [](MaskPixelT
const& l, MaskPixelT
const& r) -> MaskPixelT {
return l | r; });
558template <
typename MaskPixelT>
560 transform_pixels(_getRawView(), _getRawView(), [&
val](MaskPixelT
const& l) {
return l &
val; });
564template <
typename MaskPixelT>
566 checkMaskDictionaries(rhs);
570 str(boost::format(
"Images are of different size, %dx%d v %dx%d") %
573 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
574 [](MaskPixelT
const& l, MaskPixelT
const& r) -> MaskPixelT {
return l & r; });
578template <
typename MaskPixelT>
580 transform_pixels(_getRawView(), _getRawView(),
581 [&
val](MaskPixelT
const& l) -> MaskPixelT {
return l ^
val; });
585template <
typename MaskPixelT>
587 checkMaskDictionaries(rhs);
591 str(boost::format(
"Images are of different size, %dx%d v %dx%d") %
594 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
595 [](MaskPixelT
const& l, MaskPixelT
const& r) -> MaskPixelT {
return l ^ r; });
599template <
typename MaskPixelT>
601 MaskPixelT
const bitMask = getBitMask(planeId);
603 for (
int x = x0;
x <= x1;
x++) {
604 operator()(
x,
y) = operator()(
x,
y) | bitMask;
608template <
typename MaskPixelT>
616 NameList paramNames = metadata->paramNames(
false);
617 for (
auto const ¶mName : paramNames) {
618 if (paramName.compare(0, maskPlanePrefix.size(), maskPlanePrefix) == 0) {
619 metadata->remove(paramName);
623 MaskPlaneDict const& mpd = _maskPlaneDict()->getMaskPlaneDict();
626 for (
auto const &i : mpd) {
628 int const planeNumber = i.second;
630 if (planeName !=
"") {
631 metadata->add(maskPlanePrefix + planeName, planeNumber);
636template <
typename MaskPixelT>
643 NameList paramNames = metadata->paramNames(
false);
644 int numPlanesUsed = 0;
647 for (
auto const ¶mName : paramNames) {
648 if (paramName.compare(0, maskPlanePrefix.size(), maskPlanePrefix) == 0) {
651 int const planeId = metadata->getAsInt(paramName);
653 MaskPlaneDict::const_iterator plane = newDict.
find(planeName);
654 if (plane != newDict.
end() && planeId != plane->second) {
657 for (MaskPlaneDict::const_iterator j = newDict.
begin(); j != newDict.
end(); ++j) {
658 if (planeId == j->second) {
660 str(boost::format(
"File specifies plane %s has same value (%d) as %s") %
661 planeName % planeId % j->first));
665 if (numPlanesUsed >= getNumPlanesMax()) {
669 str(boost::format(
"Max number of planes (%1%) already used") % getNumPlanesMax()));
671 newDict[planeName] = planeId;
677template <
typename MaskPixelT>
685template <
typename MaskPixelT>
688template <
typename MaskPixelT>
696template class Mask<MaskPixel>;
table::Key< std::string > name
table::PointKey< int > pixel
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
afw::table::PointKey< int > dimensions
LSST DM logging module built on log4cxx.
#define LOGL_DEBUG(logger, message...)
Log a debug-level message using a varargs/printf style interface.
A simple struct that combines the two arguments that must be passed to most cfitsio routines and cont...
void writeImage(ndarray::Array< T const, N, C > const &array)
Write an ndarray::Array to a FITS image HDU.
Lifetime-management for memory that goes into FITS memory files.
A class used to request that array accesses be checked.
The base class for all image classed (Image, Mask, MaskedImage, ...)
typename Reference< PixelT >::type PixelReference
A Reference to a PixelT.
PixelReference operator()(int x, int y)
Return a reference to the pixel (x, y) in LOCAL coordinates.
int getWidth() const
Return the number of columns in the image.
lsst::geom::Extent2I getDimensions() const
Return the image's size; useful for passing to constructors.
int getHeight() const
Return the number of rows in the image.
typename _view_t::x_iterator x_iterator
An iterator for traversing the pixels in a row.
_view_t _getRawView() const
void swap(ImageBase &rhs)
typename ConstReference< PixelT >::type PixelConstReference
A ConstReference to a PixelT.
A FITS reader class for Masks.
Represent a 2-dimensional array of bitmask pixels.
Mask & operator=(MaskPixelT const rhs)
friend class MaskFitsReader
void printMaskPlanes() const
print the mask plane dictionary to std::cout
static int getMaskPlane(const std::string &name)
Return the mask plane number corresponding to a plane name.
static std::string interpret(MaskPixelT value)
Interpret a mask value as a comma-separated list of mask plane names.
static void removeMaskPlane(const std::string &name)
void removeAndClearMaskPlane(const std::string &name, bool const removeFromDefault=false)
Clear all pixels of the specified mask and remove the plane from the mask plane dictionary; optionall...
static void clearMaskPlaneDict()
Reset the maskPlane dictionary.
void setMaskPlaneValues(const int plane, const int x0, const int x1, const int y)
Set the bit specified by "planeId" for pixels (x0, y) ... (x1, y)
static void addMaskPlanesToMetadata(std::shared_ptr< lsst::daf::base::PropertySet >)
Given a PropertySet, replace any existing MaskPlane assignments with the current ones.
ImageBase< MaskPixelT >::PixelReference operator()(int x, int y)
get a reference to the specified pixel
Mask & operator^=(Mask const &rhs)
XOR a Mask into a Mask.
static int addMaskPlane(const std::string &name)
static MaskPixelT getPlaneBitMask(const std::vector< std::string > &names)
Return the bitmask corresponding to a vector of plane names OR'd together.
Mask(unsigned int width, unsigned int height, MaskPlaneDict const &planeDefs=MaskPlaneDict())
Construct a Mask initialized to 0x0.
MaskPlaneDict const & getMaskPlaneDict() const
Return the Mask's maskPlaneDict.
void conformMaskPlanes(const MaskPlaneDict &masterPlaneDict)
Adjust this mask to conform to the standard Mask class's mask plane dictionary, adding any new mask p...
Mask & operator|=(Mask const &rhs)
OR a Mask into a Mask.
static MaskPlaneDict parseMaskPlaneMetadata(std::shared_ptr< lsst::daf::base::PropertySet const > metadata)
Given a PropertySet that contains the MaskPlane assignments, setup the MaskPlanes.
void clearAllMaskPlanes()
Clear all the pixels.
static int getNumPlanesUsed()
void clearMaskPlane(int plane)
Clear the specified bit in all pixels.
void writeFits(std::string const &fileName, daf::base::PropertySet const *metadata=nullptr, std::string const &mode="w") const
Write a mask to a regular FITS file.
Mask & operator&=(Mask const &rhs)
AND a Mask into a Mask.
static void addAllMasksPlane(std::string const &name, int bitId)
static std::shared_ptr< MaskDict > detachDefault()
static std::shared_ptr< MaskDict > getDefault()
static std::shared_ptr< MaskDict > copyOrGetDefault(MaskPlaneDict const &dict)
Class for storing generic metadata.
virtual std::shared_ptr< PropertySet > deepCopy() const
Make a deep copy of the PropertySet and all of its contents.
An integer coordinate rectangle.
Reports invalid arguments.
Reports attempts to exceed implementation-defined length limits for some classes.
Reports when the result of an operation cannot be represented by the destination type.
Reports errors that are due to events beyond the control of the program.
def writeFits(filename, stamps, metadata, type_name, write_mask, write_variance, write_archive=False)
Options for writing an image to FITS.