34 #include "boost/format.hpp"
54 template <
typename MaskPixelT>
55 void Mask<MaskPixelT>::_initializePlanes(
MaskPlaneDict const& planeDefs) {
56 LOGL_DEBUG(
"afw.image.Mask",
"Number of mask planes: %d", getNumPlanesMax());
61 template <
typename MaskPixelT>
64 _initializePlanes(planeDefs);
68 template <
typename MaskPixelT>
72 _initializePlanes(planeDefs);
76 template <
typename MaskPixelT>
79 _initializePlanes(planeDefs);
83 template <
typename MaskPixelT>
87 _initializePlanes(planeDefs);
91 template <
typename MaskPixelT>
94 _initializePlanes(planeDefs);
98 template <
typename MaskPixelT>
101 _initializePlanes(planeDefs);
102 *
this = initialValue;
105 template <
typename MaskPixelT>
108 :
ImageBase<MaskPixelT>(rhs,
bbox, origin, deep), _maskDict(rhs._maskDict) {}
110 template <
typename MaskPixelT>
112 :
ImageBase<MaskPixelT>(rhs, deep), _maskDict(rhs._maskDict) {}
114 template <
typename MaskPixelT>
117 template <
typename MaskPixelT>
120 template <
typename MaskPixelT>
123 :
image::
ImageBase<MaskPixelT>(array, deep, xy0), _maskDict(detail::MaskDict::getDefault()) {}
125 template <
typename PixelT>
130 swap(_maskDict, rhs._maskDict);
133 template <
typename PixelT>
138 template <
typename MaskPixelT>
146 template <
typename MaskPixelT>
151 template <
typename MaskPixelT>
153 fill_pixels(_getRawView(), rhs);
160 template <
typename MaskPixelT>
163 :
ImageBase<MaskPixelT>(), _maskDict(detail::MaskDict::getDefault()) {
165 *
this = reader.read<MaskPixelT>(
bbox, origin, conformMasks, allowUnsafe);
167 metadata->combine(reader.readMetadata());
171 template <
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());
183 template <
typename MaskPixelT>
187 : ImageBase<MaskPixelT>(), _maskDict(detail::MaskDict::getDefault()) {
189 *
this = reader.read<MaskPixelT>(
bbox, origin, conformMasks, allowUnsafe);
191 metadata->combine(reader.readMetadata());
195 template <
typename MaskPixelT>
203 template <
typename MaskPixelT>
211 template <
typename MaskPixelT>
214 writeFits(fitsfile, fits::ImageWriteOptions(*
this), metadata);
217 template <
typename MaskPixelT>
225 template <
typename MaskPixelT>
233 template <
typename MaskPixelT>
237 header ? header->deepCopy() : std::make_shared<dafBase::PropertySet>();
238 addMaskPlanesToMetadata(useHeader);
239 fitsfile.writeImage(*
this, options, useHeader);
244 template <
typename MaskPixelT>
247 MaskPlaneDict const& mpd = _maskPlaneDict()->getMaskPlaneDict();
248 for (
auto const &
iter : mpd) {
249 if (value & getBitMask(
iter.second)) {
259 template <
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()));
279 template <
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);
292 template <
typename MaskPixelT>
294 return _maskDict->getMaskPlaneDict();
297 template <
typename MaskPixelT>
305 _maskPlaneDict()->erase(
name);
308 template <
typename MaskPixelT>
312 clearMaskPlane(getMaskPlane(
name));
317 _maskDict = _maskDict->clone();
320 _maskDict->erase(
name);
323 removeMaskPlane(
name);
327 template <
typename MaskPixelT>
329 return (planeId >= 0 && planeId < getNumPlanesMax()) ? (1 << planeId) : 0;
332 template <
typename MaskPixelT>
333 MaskPixelT 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);
349 template <
typename MaskPixelT>
351 int const plane = getMaskPlaneNoThrow(
name);
361 template <
typename MaskPixelT>
366 template <
typename MaskPixelT>
368 return getBitMask(getMaskPlane(
name));
371 template <
typename MaskPixelT>
373 MaskPixelT mpix = 0x0;
374 for (
auto const &it :
name) {
375 mpix |= getBitMask(getMaskPlane(it));
380 template <
typename MaskPixelT>
382 return _maskPlaneDict()->size();
385 template <
typename MaskPixelT>
387 _maskPlaneDict()->clear();
390 template <
typename MaskPixelT>
395 template <
typename MaskPixelT>
397 *
this &= ~getBitMask(planeId);
400 template <
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) {
442 MaskPixelT newPixel =
pixel & keepBitmask;
443 for (
int i = 0; i < numReMap; i++) {
444 if (
pixel & currentMask[i]) newPixel |= canonicalMask[i];
456 template <
typename MaskPixelT>
461 template <
typename MaskPixelT>
467 template <
typename MaskPixelT>
472 template <
typename MaskPixelT>
478 template <
typename MaskPixelT>
484 template <
typename MaskPixelT>
490 template <
typename MaskPixelT>
492 if (*_maskDict != *other._maskDict) {
497 template <
typename MaskPixelT>
499 transform_pixels(_getRawView(), _getRawView(),
500 [&
val](MaskPixelT
const& l) -> MaskPixelT {
return l |
val; });
504 template <
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; });
518 template <
typename MaskPixelT>
520 transform_pixels(_getRawView(), _getRawView(), [&
val](MaskPixelT
const& l) {
return l &
val; });
524 template <
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; });
538 template <
typename MaskPixelT>
540 transform_pixels(_getRawView(), _getRawView(),
541 [&
val](MaskPixelT
const& l) -> MaskPixelT {
return l ^
val; });
545 template <
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; });
559 template <
typename MaskPixelT>
561 MaskPixelT
const bitMask = getBitMask(planeId);
563 for (
int x = x0;
x <= x1;
x++) {
564 operator()(
x,
y) = operator()(
x,
y) | bitMask;
568 template <
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);
596 template <
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;
637 template <
typename MaskPixelT>
645 template <
typename MaskPixelT>
648 template <
typename MaskPixelT>
656 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.
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) ...
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, stamps, metadata, type_name, write_mask, write_variance, write_archive=False)
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
A base class for image defects.