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,
204template <
typename MaskPixelT>
206 daf::base::PropertySet
const * metadata_i,
213template <
typename MaskPixelT>
215 daf::base::PropertySet
const * metadata)
const {
216 writeFits(fitsfile, fits::ImageWriteOptions(*
this), metadata);
219template <
typename MaskPixelT>
222 daf::base::PropertySet
const * header)
const {
228template <
typename MaskPixelT>
233 writeFits(fitsfile, options, header);
237template <
typename MaskPixelT>
241 header ? header->
deepCopy() : std::make_shared<dafBase::PropertySet>();
242 addMaskPlanesToMetadata(useHeader);
248template <
typename MaskPixelT>
252 for (
auto const &iter : mpd) {
253 if (value & getBitMask(iter.second)) {
263template <
typename MaskPixelT>
265 int id = getMaskPlaneNoThrow(
name);
268 id = _maskPlaneDict()->getUnusedPlane();
273 if (
id >= getNumPlanesMax()) {
275 str(boost::format(
"Max number of planes (%1%) already used") % getNumPlanesMax()));
283template <
typename MaskPixelT>
285 if (planeId < 0 || planeId >= getNumPlanesMax()) {
288 str(boost::format(
"mask plane ID must be between 0 and %1%") % (getNumPlanesMax() - 1)));
291 _maskPlaneDict()->add(
name, planeId);
296template <
typename MaskPixelT>
298 return _maskDict->getMaskPlaneDict();
301template <
typename MaskPixelT>
305 str(boost::format(
"Plane %s doesn't exist in the default Mask") %
name));
309 _maskPlaneDict()->erase(
name);
312template <
typename MaskPixelT>
316 clearMaskPlane(getMaskPlane(
name));
321 _maskDict = _maskDict->clone();
324 _maskDict->erase(
name);
327 removeMaskPlane(
name);
331template <
typename MaskPixelT>
332MaskPixelT Mask<MaskPixelT>::getBitMaskNoThrow(
int planeId) {
333 return (planeId >= 0 && planeId < getNumPlanesMax()) ? (1 << planeId) : 0;
336template <
typename MaskPixelT>
338 MaskPlaneDict
const& mpd = _maskPlaneDict()->getMaskPlaneDict();
340 for (
auto const &i : mpd) {
341 if (planeId == i.second) {
342 MaskPixelT
const bitmask = getBitMaskNoThrow(planeId);
350 str(boost::format(
"Invalid mask plane ID: %d") % planeId));
353template <
typename MaskPixelT>
355 int const plane = getMaskPlaneNoThrow(
name);
359 str(boost::format(
"Invalid mask plane name: %s") %
name));
365template <
typename MaskPixelT>
370template <
typename MaskPixelT>
372 return getBitMask(getMaskPlane(
name));
375template <
typename MaskPixelT>
377 MaskPixelT mpix = 0x0;
378 for (
auto const &it :
name) {
379 mpix |= getBitMask(getMaskPlane(it));
384template <
typename MaskPixelT>
386 return _maskPlaneDict()->size();
389template <
typename MaskPixelT>
391 _maskPlaneDict()->clear();
394template <
typename MaskPixelT>
399template <
typename MaskPixelT>
401 *
this &= ~getBitMask(planeId);
404template <
typename MaskPixelT>
408 if (*_maskDict == *currentMD) {
416 MaskPixelT keepBitmask = 0;
417 MaskPixelT canonicalMask[
sizeof(MaskPixelT) * 8];
418 MaskPixelT currentMask[
sizeof(MaskPixelT) * 8];
421 for (
auto const &i : currentPlaneDict) {
423 int const currentPlaneNumber = i.second;
424 int canonicalPlaneNumber = getMaskPlaneNoThrow(
name);
426 if (canonicalPlaneNumber < 0) {
427 canonicalPlaneNumber = addMaskPlane(
name);
430 if (canonicalPlaneNumber == currentPlaneNumber) {
431 keepBitmask |= getBitMask(canonicalPlaneNumber);
433 canonicalMask[numReMap] = getBitMask(canonicalPlaneNumber);
434 currentMask[numReMap] = getBitMaskNoThrow(currentPlaneNumber);
441 for (
int r = 0; r != this->getHeight(); ++r) {
446 MaskPixelT newPixel =
pixel & keepBitmask;
447 for (
int i = 0; i < numReMap; i++) {
448 if (
pixel & currentMask[i]) newPixel |= canonicalMask[i];
460template <
typename MaskPixelT>
465template <
typename MaskPixelT>
471template <
typename MaskPixelT>
476template <
typename MaskPixelT>
482template <
typename MaskPixelT>
488template <
typename MaskPixelT>
494template <
typename MaskPixelT>
496 if (*_maskDict != *other._maskDict) {
501template <
typename MaskPixelT>
503 transform_pixels(_getRawView(), _getRawView(),
504 [&
val](MaskPixelT
const& l) -> MaskPixelT {
return l |
val; });
508template <
typename MaskPixelT>
510 checkMaskDictionaries(rhs);
514 str(boost::format(
"Images are of different size, %dx%d v %dx%d") %
517 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
518 [](MaskPixelT
const& l, MaskPixelT
const& r) -> MaskPixelT {
return l | r; });
522template <
typename MaskPixelT>
524 transform_pixels(_getRawView(), _getRawView(), [&
val](MaskPixelT
const& l) {
return l &
val; });
528template <
typename MaskPixelT>
530 checkMaskDictionaries(rhs);
534 str(boost::format(
"Images are of different size, %dx%d v %dx%d") %
537 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
538 [](MaskPixelT
const& l, MaskPixelT
const& r) -> MaskPixelT {
return l & r; });
542template <
typename MaskPixelT>
544 transform_pixels(_getRawView(), _getRawView(),
545 [&
val](MaskPixelT
const& l) -> MaskPixelT {
return l ^
val; });
549template <
typename MaskPixelT>
551 checkMaskDictionaries(rhs);
555 str(boost::format(
"Images are of different size, %dx%d v %dx%d") %
558 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
559 [](MaskPixelT
const& l, MaskPixelT
const& r) -> MaskPixelT {
return l ^ r; });
563template <
typename MaskPixelT>
565 MaskPixelT
const bitMask = getBitMask(planeId);
567 for (
int x = x0;
x <= x1;
x++) {
568 operator()(
x,
y) = operator()(
x,
y) | bitMask;
572template <
typename MaskPixelT>
580 NameList paramNames = metadata->paramNames(
false);
581 for (
auto const ¶mName : paramNames) {
582 if (paramName.compare(0, maskPlanePrefix.size(), maskPlanePrefix) == 0) {
583 metadata->remove(paramName);
587 MaskPlaneDict const& mpd = _maskPlaneDict()->getMaskPlaneDict();
590 for (
auto const &i : mpd) {
592 int const planeNumber = i.second;
594 if (planeName !=
"") {
595 metadata->add(maskPlanePrefix + planeName, planeNumber);
600template <
typename MaskPixelT>
607 NameList paramNames = metadata->paramNames(
false);
608 int numPlanesUsed = 0;
611 for (
auto const ¶mName : paramNames) {
612 if (paramName.compare(0, maskPlanePrefix.size(), maskPlanePrefix) == 0) {
615 int const planeId = metadata->getAsInt(paramName);
617 MaskPlaneDict::const_iterator plane = newDict.
find(planeName);
618 if (plane != newDict.
end() && planeId != plane->second) {
621 for (MaskPlaneDict::const_iterator j = newDict.
begin(); j != newDict.
end(); ++j) {
622 if (planeId == j->second) {
624 str(boost::format(
"File specifies plane %s has same value (%d) as %s") %
625 planeName % planeId % j->first));
629 if (numPlanesUsed >= getNumPlanesMax()) {
633 str(boost::format(
"Max number of planes (%1%) already used") % getNumPlanesMax()));
635 newDict[planeName] = planeId;
641template <
typename MaskPixelT>
649template <
typename MaskPixelT>
652template <
typename MaskPixelT>
660template 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.
writeFits(filename, stamps, metadata, type_name, write_mask, write_variance, write_archive=False)
Options for writing an image to FITS.