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>
125template <
typename PixelT>
130 swap(_maskDict, rhs._maskDict);
133template <
typename PixelT>
138template <
typename MaskPixelT>
146template <
typename MaskPixelT>
151template <
typename MaskPixelT>
160template <
typename MaskPixelT>
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>
185 lsst::geom::Box2I
const& bbox,
ImageOrigin const origin,
bool const conformMasks,
189 *
this = reader.read<MaskPixelT>(bbox, origin, conformMasks, allowUnsafe);
191 metadata->combine(*reader.readMetadata());
195template <
typename MaskPixelT>
197 daf::base::PropertySet
const * metadata_i,
198 std::string
const& mode)
const {
200 writeFits(fitsfile, metadata_i);
204template <
typename MaskPixelT>
206 daf::base::PropertySet
const * metadata_i,
207 std::string
const& mode)
const {
209 writeFits(fitsfile, metadata_i);
213template <
typename MaskPixelT>
215 daf::base::PropertySet
const * metadata)
const {
216 writeFits(fitsfile,
nullptr, metadata);
219template <
typename MaskPixelT>
221 std::string
const& mode,
222 daf::base::PropertySet
const * header)
const {
224 writeFits(fitsfile, options, header);
228template <
typename MaskPixelT>
230 std::string
const& mode,
231 daf::base::PropertySet
const * header)
const {
233 writeFits(fitsfile, options, header);
237template <
typename MaskPixelT>
248template <
typename MaskPixelT>
252 for (
auto const &iter : mpd) {
253 if (value & getBitMask(iter.second)) {
257 result += iter.first;
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>
321 _maskDict = _maskDict->clone();
324 _maskDict->erase(name);
331template <
typename MaskPixelT>
332MaskPixelT Mask<MaskPixelT>::getBitMaskNoThrow(
int planeId) {
333 return (planeId >= 0 && planeId <
getNumPlanesMax()) ? (1 << planeId) : 0;
336template <
typename MaskPixelT>
337MaskPixelT Mask<MaskPixelT>::getBitMask(
int planeId) {
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>
366int Mask<MaskPixelT>::getMaskPlaneNoThrow(
const std::string& name) {
367 return _maskPlaneDict()->getMaskPlane(name);
370template <
typename MaskPixelT>
375template <
typename MaskPixelT>
377 MaskPixelT mpix = 0x0;
378 for (
auto const &it : name) {
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) {
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) {
444 MaskPixelT
const pixel = *ptr;
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>
495void Mask<MaskPixelT>::checkMaskDictionaries(
Mask<MaskPixelT> const& other) {
496 if (*_maskDict != *other._maskDict) {
501template <
typename MaskPixelT>
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>
528template <
typename MaskPixelT>
530 checkMaskDictionaries(rhs);
534 str(boost::format(
"Images are of different size, %dx%d v %dx%d") %
538 [](MaskPixelT
const& l, MaskPixelT
const& r) -> MaskPixelT {
return l & r; });
542template <
typename MaskPixelT>
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") %
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++) {
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));
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>;
#define LSST_EXCEPT(type,...)
#define LOGL_DEBUG(logger, message...)
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.
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.
lsst::geom::Extent2I getDimensions() const
x_iterator row_begin(int y) const
x_iterator row_end(int y) const
typename _view_t::x_iterator x_iterator
_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.
detail::MaskPlaneDict MaskPlaneDict
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 >)
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)
static int getNumPlanesMax()
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)
virtual std::shared_ptr< PropertySet > deepCopy() const
std::map< std::string, int > MaskPlaneDict
void swap(Image< PixelT > &a, Image< PixelT > &b)
Extent< int, 2 > Extent2I
Options controlling image compression with FITS.