35 #pragma clang diagnostic push
36 #pragma clang diagnostic ignored "-Wunused-variable"
37 #pragma clang diagnostic pop
38 #include "boost/format.hpp"
39 #include "boost/filesystem/path.hpp"
41 #include "boost/functional/hash.hpp"
61 template <
typename MaskPixelT>
62 void Mask<MaskPixelT>::_initializePlanes(
MaskPlaneDict const& planeDefs) {
63 LOGL_DEBUG(
"afw.image.Mask",
"Number of mask planes: %d", getNumPlanesMax());
68 template <
typename MaskPixelT>
71 _initializePlanes(planeDefs);
75 template <
typename MaskPixelT>
79 _initializePlanes(planeDefs);
83 template <
typename MaskPixelT>
86 _initializePlanes(planeDefs);
90 template <
typename MaskPixelT>
94 _initializePlanes(planeDefs);
98 template <
typename MaskPixelT>
101 _initializePlanes(planeDefs);
105 template <
typename MaskPixelT>
108 _initializePlanes(planeDefs);
109 *
this = initialValue;
112 template <
typename MaskPixelT>
115 :
ImageBase<MaskPixelT>(rhs,
bbox, origin, deep), _maskDict(rhs._maskDict) {}
117 template <
typename MaskPixelT>
119 :
ImageBase<MaskPixelT>(rhs, deep), _maskDict(rhs._maskDict) {}
121 template <
typename MaskPixelT>
124 template <
typename MaskPixelT>
127 template <
typename MaskPixelT>
130 :
image::
ImageBase<MaskPixelT>(array, deep, xy0), _maskDict(detail::MaskDict::getDefault()) {}
132 template <
typename PixelT>
137 swap(_maskDict, rhs._maskDict);
140 template <
typename PixelT>
145 template <
typename MaskPixelT>
153 template <
typename MaskPixelT>
158 template <
typename MaskPixelT>
160 fill_pixels(_getRawView(), rhs);
167 template <
typename MaskPixelT>
170 :
ImageBase<MaskPixelT>(), _maskDict(detail::MaskDict::getDefault()) {
172 *
this = reader.read<MaskPixelT>(
bbox, origin, conformMasks, allowUnsafe);
174 metadata->combine(reader.readMetadata());
178 template <
typename MaskPixelT>
181 ImageOrigin origin,
bool conformMasks,
bool allowUnsafe)
182 : ImageBase<MaskPixelT>(), _maskDict(detail::MaskDict::getDefault()) {
184 *
this = reader.read<MaskPixelT>(
bbox, origin, conformMasks, allowUnsafe);
186 metadata->combine(reader.readMetadata());
190 template <
typename MaskPixelT>
194 : ImageBase<MaskPixelT>(), _maskDict(detail::MaskDict::getDefault()) {
196 *
this = reader.read<MaskPixelT>(
bbox, origin, conformMasks, allowUnsafe);
198 metadata->combine(reader.readMetadata());
202 template <
typename MaskPixelT>
210 template <
typename MaskPixelT>
218 template <
typename MaskPixelT>
221 writeFits(fitsfile, fits::ImageWriteOptions(*
this), metadata);
224 template <
typename MaskPixelT>
232 template <
typename MaskPixelT>
240 template <
typename MaskPixelT>
244 header ? header->deepCopy() : std::make_shared<dafBase::PropertySet>();
245 addMaskPlanesToMetadata(useHeader);
246 fitsfile.writeImage(*
this, options, useHeader);
251 template <
typename MaskPixelT>
254 MaskPlaneDict const& mpd = _maskPlaneDict()->getMaskPlaneDict();
256 if (value & getBitMask(
iter->second)) {
266 template <
typename MaskPixelT>
268 int id = getMaskPlaneNoThrow(
name);
271 id = _maskPlaneDict()->getUnusedPlane();
276 if (
id >= getNumPlanesMax()) {
278 str(
boost::format(
"Max number of planes (%1%) already used") % getNumPlanesMax()));
286 template <
typename MaskPixelT>
288 if (planeId < 0 || planeId >= getNumPlanesMax()) {
291 str(
boost::format(
"mask plane ID must be between 0 and %1%") % (getNumPlanesMax() - 1)));
294 _maskPlaneDict()->add(
name, planeId);
299 template <
typename MaskPixelT>
301 return _maskDict->getMaskPlaneDict();
304 template <
typename MaskPixelT>
312 _maskPlaneDict()->erase(
name);
315 template <
typename MaskPixelT>
319 clearMaskPlane(getMaskPlane(
name));
324 _maskDict = _maskDict->clone();
327 _maskDict->erase(
name);
330 removeMaskPlane(
name);
334 template <
typename MaskPixelT>
336 return (planeId >= 0 && planeId < getNumPlanesMax()) ? (1 << planeId) : 0;
339 template <
typename MaskPixelT>
340 MaskPixelT Mask<MaskPixelT>::getBitMask(
int planeId) {
341 MaskPlaneDict const& mpd = _maskPlaneDict()->getMaskPlaneDict();
343 for (MaskPlaneDict::const_iterator i = mpd.begin(); i != mpd.end(); ++i) {
344 if (planeId == i->second) {
345 MaskPixelT
const bitmask = getBitMaskNoThrow(planeId);
356 template <
typename MaskPixelT>
358 int const plane = getMaskPlaneNoThrow(
name);
368 template <
typename MaskPixelT>
373 template <
typename MaskPixelT>
375 return getBitMask(getMaskPlane(
name));
378 template <
typename MaskPixelT>
380 MaskPixelT mpix = 0x0;
382 mpix |= getBitMask(getMaskPlane(*it));
387 template <
typename MaskPixelT>
389 return _maskPlaneDict()->size();
392 template <
typename MaskPixelT>
394 _maskPlaneDict()->clear();
397 template <
typename MaskPixelT>
402 template <
typename MaskPixelT>
404 *
this &= ~getBitMask(planeId);
407 template <
typename MaskPixelT>
411 if (*_maskDict == *currentMD) {
419 MaskPixelT keepBitmask = 0;
420 MaskPixelT canonicalMask[
sizeof(MaskPixelT) * 8];
421 MaskPixelT currentMask[
sizeof(MaskPixelT) * 8];
424 for (MaskPlaneDict::const_iterator i = currentPlaneDict.
begin(); i != currentPlaneDict.
end(); i++) {
426 int const currentPlaneNumber = i->second;
427 int canonicalPlaneNumber = getMaskPlaneNoThrow(
name);
429 if (canonicalPlaneNumber < 0) {
430 canonicalPlaneNumber = addMaskPlane(
name);
433 if (canonicalPlaneNumber == currentPlaneNumber) {
434 keepBitmask |= getBitMask(canonicalPlaneNumber);
436 canonicalMask[numReMap] = getBitMask(canonicalPlaneNumber);
437 currentMask[numReMap] = getBitMaskNoThrow(currentPlaneNumber);
444 for (
int r = 0; r != this->getHeight(); ++r) {
449 MaskPixelT newPixel =
pixel & keepBitmask;
450 for (
int i = 0; i < numReMap; i++) {
451 if (
pixel & currentMask[i]) newPixel |= canonicalMask[i];
463 template <
typename MaskPixelT>
468 template <
typename MaskPixelT>
474 template <
typename MaskPixelT>
479 template <
typename MaskPixelT>
485 template <
typename MaskPixelT>
491 template <
typename MaskPixelT>
497 template <
typename MaskPixelT>
499 if (*_maskDict != *
other._maskDict) {
504 template <
typename MaskPixelT>
506 transform_pixels(_getRawView(), _getRawView(),
507 [&
val](MaskPixelT
const& l) -> MaskPixelT {
return l |
val; });
511 template <
typename MaskPixelT>
513 checkMaskDictionaries(rhs);
517 str(
boost::format(
"Images are of different size, %dx%d v %dx%d") %
520 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
521 [](MaskPixelT
const& l, MaskPixelT
const& r) -> MaskPixelT {
return l | r; });
525 template <
typename MaskPixelT>
527 transform_pixels(_getRawView(), _getRawView(), [&
val](MaskPixelT
const& l) {
return l &
val; });
531 template <
typename MaskPixelT>
533 checkMaskDictionaries(rhs);
537 str(
boost::format(
"Images are of different size, %dx%d v %dx%d") %
540 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
541 [](MaskPixelT
const& l, MaskPixelT
const& r) -> MaskPixelT {
return l & r; });
545 template <
typename MaskPixelT>
547 transform_pixels(_getRawView(), _getRawView(),
548 [&
val](MaskPixelT
const& l) -> MaskPixelT {
return l ^
val; });
552 template <
typename MaskPixelT>
554 checkMaskDictionaries(rhs);
558 str(
boost::format(
"Images are of different size, %dx%d v %dx%d") %
561 transform_pixels(_getRawView(), rhs.
_getRawView(), _getRawView(),
562 [](MaskPixelT
const& l, MaskPixelT
const& r) -> MaskPixelT {
return l ^ r; });
566 template <
typename MaskPixelT>
568 MaskPixelT
const bitMask = getBitMask(planeId);
570 for (
int x = x0;
x <= x1;
x++) {
571 operator()(
x,
y) = operator()(
x,
y) | bitMask;
575 template <
typename MaskPixelT>
583 NameList paramNames = metadata->paramNames(
false);
584 for (NameList::const_iterator i = paramNames.begin(); i != paramNames.end(); ++i) {
585 if (i->compare(0, maskPlanePrefix.size(), maskPlanePrefix) == 0) {
586 metadata->remove(*i);
590 MaskPlaneDict const& mpd = _maskPlaneDict()->getMaskPlaneDict();
593 for (MaskPlaneDict::const_iterator i = mpd.
begin(); i != mpd.
end(); ++i) {
595 int const planeNumber = i->second;
597 if (planeName !=
"") {
598 metadata->add(maskPlanePrefix + planeName, planeNumber);
603 template <
typename MaskPixelT>
610 NameList paramNames = metadata->paramNames(
false);
611 int numPlanesUsed = 0;
614 for (NameList::const_iterator i = paramNames.begin(); i != paramNames.end(); ++i) {
615 if (i->compare(0, maskPlanePrefix.size(), maskPlanePrefix) == 0) {
618 int const planeId = metadata->getAsInt(*i);
620 MaskPlaneDict::const_iterator plane = newDict.
find(planeName);
621 if (plane != newDict.
end() && planeId != plane->second) {
624 for (MaskPlaneDict::const_iterator j = newDict.
begin(); j != newDict.
end(); ++j) {
625 if (planeId == j->second) {
627 str(
boost::format(
"File specifies plane %s has same value (%d) as %s") %
628 planeName % planeId % j->first));
632 if (numPlanesUsed >= getNumPlanesMax()) {
636 str(
boost::format(
"Max number of planes (%1%) already used") % getNumPlanesMax()));
638 newDict[planeName] = planeId;
644 template <
typename MaskPixelT>
652 template <
typename MaskPixelT>
655 template <
typename MaskPixelT>
663 template 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.
ItemVariant const * other
A class used to request that array accesses be checked.
The base class for all image classed (Image, Mask, MaskedImage, ...)
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.
ConstReference< PixelT >::type PixelConstReference
A ConstReference to a PixelT.
_view_t _getRawView() const
_view_t::x_iterator x_iterator
An iterator for traversing the pixels in a row.
void swap(ImageBase &rhs)
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) ...
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)
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.
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)
def writeFits(filename, stamp_ims, metadata, type_name, write_mask, write_variance)
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
A base class for image defects.