34#include "boost/format.hpp"
54template <
typename MaskPixelT>
55void Mask<MaskPixelT>::_initializePlanes(
MaskPlaneDict const& planeDefs) {
56 LOGL_DEBUG(
"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>
200 writeFits(fitsfile, metadata_i);
203template <
typename MaskPixelT>
208 writeFits(fitsfile, metadata_i);
211template <
typename MaskPixelT>
214 writeFits(fitsfile, fits::ImageWriteOptions(*
this), metadata);
217template <
typename MaskPixelT>
222 writeFits(fitsfile, options, header);
225template <
typename MaskPixelT>
230 writeFits(fitsfile, options, header);
233template <
typename MaskPixelT>
237 header ? header->deepCopy() : std::make_shared<dafBase::PropertySet>();
238 addMaskPlanesToMetadata(useHeader);
239 fitsfile.writeImage(*
this, options, useHeader);
244template <
typename MaskPixelT>
247 MaskPlaneDict const& mpd = _maskPlaneDict()->getMaskPlaneDict();
248 for (
auto const &
iter : mpd) {
249 if (value & getBitMask(
iter.second)) {
250 if (result.
size() > 0) {
253 result +=
iter.first;
259template <
typename MaskPixelT>
261 int id = getMaskPlaneNoThrow(
name);
264 id = _maskPlaneDict()->getUnusedPlane();
269 if (
id >= getNumPlanesMax()) {
271 str(boost::format(
"Max number of planes (%1%) already used") % getNumPlanesMax()));
279template <
typename MaskPixelT>
281 if (planeId < 0 || planeId >= getNumPlanesMax()) {
284 str(boost::format(
"mask plane ID must be between 0 and %1%") % (getNumPlanesMax() - 1)));
287 _maskPlaneDict()->add(
name, planeId);
292template <
typename MaskPixelT>
294 return _maskDict->getMaskPlaneDict();
297template <
typename MaskPixelT>
301 str(boost::format(
"Plane %s doesn't exist in the default Mask") %
name));
305 _maskPlaneDict()->erase(
name);
308template <
typename MaskPixelT>
312 clearMaskPlane(getMaskPlane(
name));
317 _maskDict = _maskDict->clone();
320 _maskDict->erase(
name);
323 removeMaskPlane(
name);
327template <
typename MaskPixelT>
329 return (planeId >= 0 && planeId < getNumPlanesMax()) ? (1 << planeId) : 0;
332template <
typename MaskPixelT>
333MaskPixelT Mask<MaskPixelT>::getBitMask(
int planeId) {
334 MaskPlaneDict const& mpd = _maskPlaneDict()->getMaskPlaneDict();
336 for (
auto const &i : mpd) {
337 if (planeId == i.second) {
338 MaskPixelT
const bitmask = getBitMaskNoThrow(planeId);
346 str(boost::format(
"Invalid mask plane ID: %d") % planeId));
349template <
typename MaskPixelT>
351 int const plane = getMaskPlaneNoThrow(
name);
355 str(boost::format(
"Invalid mask plane name: %s") %
name));
361template <
typename MaskPixelT>
366template <
typename MaskPixelT>
368 return getBitMask(getMaskPlane(
name));
371template <
typename MaskPixelT>
373 MaskPixelT mpix = 0x0;
374 for (
auto const &it :
name) {
375 mpix |= getBitMask(getMaskPlane(it));
380template <
typename MaskPixelT>
382 return _maskPlaneDict()->size();
385template <
typename MaskPixelT>
387 _maskPlaneDict()->clear();
390template <
typename MaskPixelT>
395template <
typename MaskPixelT>
397 *
this &= ~getBitMask(planeId);
400template <
typename MaskPixelT>
404 if (*_maskDict == *currentMD) {
412 MaskPixelT keepBitmask = 0;
413 MaskPixelT canonicalMask[
sizeof(MaskPixelT) * 8];
414 MaskPixelT currentMask[
sizeof(MaskPixelT) * 8];
417 for (
auto const &i : currentPlaneDict) {
419 int const currentPlaneNumber = i.second;
420 int canonicalPlaneNumber = getMaskPlaneNoThrow(
name);
422 if (canonicalPlaneNumber < 0) {
423 canonicalPlaneNumber = addMaskPlane(
name);
426 if (canonicalPlaneNumber == currentPlaneNumber) {
427 keepBitmask |= getBitMask(canonicalPlaneNumber);
429 canonicalMask[numReMap] = getBitMask(canonicalPlaneNumber);
430 currentMask[numReMap] = getBitMaskNoThrow(currentPlaneNumber);
437 for (
int r = 0; r != this->getHeight(); ++r) {
440 MaskPixelT
const pixel = *ptr;
442 MaskPixelT newPixel =
pixel & keepBitmask;
443 for (
int i = 0; i < numReMap; i++) {
444 if (
pixel & currentMask[i]) newPixel |= canonicalMask[i];
456template <
typename MaskPixelT>
461template <
typename MaskPixelT>
467template <
typename MaskPixelT>
472template <
typename MaskPixelT>
478template <
typename MaskPixelT>
484template <
typename MaskPixelT>
490template <
typename MaskPixelT>
492 if (*_maskDict != *other._maskDict) {
497template <
typename MaskPixelT>
499 transform_pixels(_getRawView(), _getRawView(),
500 [&val](MaskPixelT
const& l) -> MaskPixelT {
return l | val; });
504template <
typename MaskPixelT>
506 checkMaskDictionaries(rhs);
510 str(boost::format(
"Images are of different size, %dx%d v %dx%d") %
513 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
514 [](MaskPixelT
const& l, MaskPixelT
const& r) -> MaskPixelT {
return l | r; });
518template <
typename MaskPixelT>
520 transform_pixels(_getRawView(), _getRawView(), [&val](MaskPixelT
const& l) {
return l & val; });
524template <
typename MaskPixelT>
526 checkMaskDictionaries(rhs);
530 str(boost::format(
"Images are of different size, %dx%d v %dx%d") %
533 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
534 [](MaskPixelT
const& l, MaskPixelT
const& r) -> MaskPixelT {
return l & r; });
538template <
typename MaskPixelT>
540 transform_pixels(_getRawView(), _getRawView(),
541 [&val](MaskPixelT
const& l) -> MaskPixelT {
return l ^ val; });
545template <
typename MaskPixelT>
547 checkMaskDictionaries(rhs);
551 str(boost::format(
"Images are of different size, %dx%d v %dx%d") %
554 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
555 [](MaskPixelT
const& l, MaskPixelT
const& r) -> MaskPixelT {
return l ^ r; });
559template <
typename MaskPixelT>
561 MaskPixelT
const bitMask = getBitMask(planeId);
563 for (
int x = x0;
x <= x1;
x++) {
564 operator()(
x,
y) = operator()(
x,
y) | bitMask;
568template <
typename MaskPixelT>
576 NameList paramNames = metadata->paramNames(
false);
577 for (
auto const ¶mName : paramNames) {
578 if (paramName.compare(0, maskPlanePrefix.size(), maskPlanePrefix) == 0) {
579 metadata->remove(paramName);
583 MaskPlaneDict const& mpd = _maskPlaneDict()->getMaskPlaneDict();
586 for (
auto const &i : mpd) {
588 int const planeNumber = i.second;
590 if (planeName !=
"") {
591 metadata->add(maskPlanePrefix + planeName, planeNumber);
596template <
typename MaskPixelT>
603 NameList paramNames = metadata->paramNames(
false);
604 int numPlanesUsed = 0;
607 for (
auto const ¶mName : paramNames) {
608 if (paramName.compare(0, maskPlanePrefix.size(), maskPlanePrefix) == 0) {
611 int const planeId = metadata->getAsInt(paramName);
613 MaskPlaneDict::const_iterator plane = newDict.
find(planeName);
614 if (plane != newDict.
end() && planeId != plane->second) {
617 for (MaskPlaneDict::const_iterator j = newDict.
begin(); j != newDict.
end(); ++j) {
618 if (planeId == j->second) {
620 str(boost::format(
"File specifies plane %s has same value (%d) as %s") %
621 planeName % planeId % j->first));
625 if (numPlanesUsed >= getNumPlanesMax()) {
629 str(boost::format(
"Max number of planes (%1%) already used") % getNumPlanesMax()));
631 newDict[planeName] = planeId;
637template <
typename MaskPixelT>
645template <
typename MaskPixelT>
648template <
typename MaskPixelT>
656template class Mask<MaskPixel>;
table::Key< std::string > name
table::PointKey< int > pixel
#define LSST_EXCEPT(type,...)
afw::table::PointKey< int > dimensions
#define LOGL_DEBUG(logger, message...)
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.
void writeFits(std::string const &fileName, std::shared_ptr< lsst::daf::base::PropertySet const > metadata=std::shared_ptr< lsst::daf::base::PropertySet >(), std::string const &mode="w") const
Write a mask to a regular FITS file.
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.
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)
std::map< std::string, int > MaskPlaneDict
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
void swap(Image< PixelT > &a, Image< PixelT > &b)
A base class for image defects.