Loading [MathJax]/extensions/tex2jax.js
LSST Applications g04dff08e69+42feea4ef2,g0fba68d861+a0b9de4ea6,g1ec0fe41b4+f536777771,g1fd858c14a+42269675ea,g35bb328faa+fcb1d3bbc8,g4af146b050+bbef1ba6f0,g4d2262a081+8f21adb3a6,g53246c7159+fcb1d3bbc8,g5a012ec0e7+b20b785ecb,g60b5630c4e+43e3f0d37c,g6273192d42+e9a7147bac,g67b6fd64d1+4086c0989b,g78460c75b0+2f9a1b4bcd,g786e29fd12+cf7ec2a62a,g7b71ed6315+fcb1d3bbc8,g7bbe65ff3e+43e3f0d37c,g8352419a5c+fcb1d3bbc8,g87b7deb4dc+43704db330,g8852436030+eb2388797a,g89139ef638+4086c0989b,g9125e01d80+fcb1d3bbc8,g94187f82dc+43e3f0d37c,g989de1cb63+4086c0989b,g9d31334357+43e3f0d37c,g9f33ca652e+9b312035f9,gabe3b4be73+1e0a283bba,gabf8522325+fa80ff7197,gb1101e3267+61f2793e68,gb58c049af0+f03b321e39,gb89ab40317+4086c0989b,gc0bb628dac+834c1753f9,gcf25f946ba+eb2388797a,gd6cbbdb0b4+af3c3595f5,gde0f65d7ad+9e0145b227,ge278dab8ac+d65b3c2b70,ge410e46f29+4086c0989b,gf23fb2af72+37a5db1cfd,gf67bdafdda+4086c0989b,v29.0.0.rc7
LSST Data Management Base Package
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
MaskDict.cc
Go to the documentation of this file.
1/*
2 * Developed for the LSST Data Management System.
3 * This product includes software developed by the LSST Project
4 * (https://www.lsst.org).
5 * See the COPYRIGHT file at the top-level directory of this distribution
6 * for details of code ownership.
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22#include <mutex>
23#include <set>
24
25#include "boost/functional/hash.hpp"
27
28namespace lsst {
29namespace afw {
30namespace image {
31namespace detail {
32
33// A thread-safe singleton that manages MaskDict's global state.
35public:
36 static GlobalState &get() {
37 static GlobalState instance;
38 return instance;
39 }
40
43 if (!mpd.empty()) {
44 std::shared_ptr<MaskDict> dict(new MaskDict(mpd));
45 _allMaskDicts.insert(dict);
46 return dict;
47 }
48 return _defaultMaskDict;
49 }
50
51 std::shared_ptr<MaskDict> copy(MaskDict const &dict) {
53 std::shared_ptr<MaskDict> result(new MaskDict(dict));
54 _allMaskDicts.insert(result);
55 return result;
56 }
57
58 std::shared_ptr<MaskDict> getDefault() const noexcept { return _defaultMaskDict; }
59
60 void setDefault(std::shared_ptr<MaskDict> dict) { _defaultMaskDict = std::move(dict); }
61
64 _defaultMaskDict = copy(*_defaultMaskDict);
65 return _defaultMaskDict;
66 }
67
68 template <typename Functor>
69 void forEachMaskDict(Functor functor) {
71 _prune(); // guarantees dereference below is safe
72 for (auto const &ptr : _allMaskDicts) {
73 functor(*ptr.lock());
74 }
75 }
76
77private:
78 GlobalState() : _defaultMaskDict(new MaskDict()) {
79 _allMaskDicts.insert(_defaultMaskDict);
80 _defaultMaskDict->_addInitialMaskPlanes();
81 }
82
83 GlobalState(GlobalState const &) = delete;
84 GlobalState(GlobalState &&) = delete;
85
86 GlobalState &operator=(GlobalState const &) = delete;
87 GlobalState &operator=(GlobalState &&) = delete;
88
89 ~GlobalState() = default;
90
91 // Prune expired weak_ptrs from _allMaskDicts. Not thread safe; should
92 // only be called by routines that have already locked the mutex.
93 void _prune() {
94 for (auto iter = _allMaskDicts.begin(); iter != _allMaskDicts.end();) {
95 if (iter->expired()) {
96 iter = _allMaskDicts.erase(iter);
97 } else {
98 ++iter;
99 }
100 }
101 }
102
103 std::recursive_mutex _mutex; // guards _allMaskDicts and synchronizes updates to it and _defaultMaskDict
105 std::shared_ptr<MaskDict> _defaultMaskDict;
106};
107
111
113
115
117
118void MaskDict::addAllMasksPlane(std::string const &name, int bitId) {
119 GlobalState::get().forEachMaskDict([&name, bitId](MaskDict &dict) {
120 auto const found = std::find_if(dict.begin(), dict.end(),
121 [bitId](auto const &item) { return item.second == bitId; });
122 if (found == dict.end()) {
123 // is name already in use?
124 if (dict.find(name) == dict.end()) {
125 dict.add(name, bitId);
126 }
127 }
128 });
129}
130
131MaskDict::~MaskDict() noexcept = default;
132
133std::shared_ptr<MaskDict> MaskDict::clone() const { return GlobalState::get().copy(*this); }
134
136 if (empty()) {
137 return 0;
138 }
139
140 auto const maxIter = std::max_element(begin(), end(),
141 [](auto const &a, auto const &b) { return a.second < b.second; });
142 assert(maxIter != end());
143 int id = maxIter->second + 1; // The maskPlane to use if there are no gaps
144
145 for (int i = 0; i < id; ++i) {
146 // is i already used in this Mask?
147 auto const sameIter =
148 std::find_if(begin(), end(), [i](auto const &item) { return item.second == i; });
149 if (sameIter == end()) { // Not used; so we'll use it
150 return i;
151 }
152 }
153
154 return id;
155}
156
157int MaskDict::getMaskPlane(std::string const &name) const {
158 auto iter = find(name);
159 return (iter == end()) ? -1 : iter->second;
160}
161
162void MaskDict::print() const {
163 for (auto const &item : *this) {
164 std::cout << "Plane " << item.second << " -> " << item.first << std::endl;
165 }
166}
167
168bool MaskDict::operator==(MaskDict const &rhs) const {
169 return this == &rhs || (_hash == rhs._hash && _dict == rhs._dict);
170}
171
172void MaskDict::add(std::string const &name, int bitId) {
173 _dict[name] = bitId;
174 _hash = boost::hash<MaskPlaneDict>()(_dict);
175}
176
177void MaskDict::erase(std::string const &name) {
178 _dict.erase(name);
179 _hash = boost::hash<MaskPlaneDict>()(_dict);
180}
181
183 _dict.clear();
184 _hash = 0x0;
185}
186
187void MaskDict::_addInitialMaskPlanes() {
188 int i = -1;
189 _dict["BAD"] = ++i;
190 _dict["SAT"] = ++i;
191 _dict["INTRP"] = ++i;
192 _dict["CR"] = ++i;
193 _dict["EDGE"] = ++i;
194 _dict["DETECTED"] = ++i;
195 _dict["DETECTED_NEGATIVE"] = ++i;
196 _dict["SUSPECT"] = ++i;
197 _dict["NO_DATA"] = ++i;
198 _dict["VIGNETTED"] = ++i;
199 _dict["STREAK"] = ++i;
200 _hash = boost::hash<MaskPlaneDict>()(_dict);
201}
202
203MaskDict::MaskDict() : _dict(), _hash(0x0) {}
204
205MaskDict::MaskDict(MaskPlaneDict const &dict) : _dict(dict), _hash(boost::hash<MaskPlaneDict>()(_dict)) {}
206
207} // namespace detail
208} // namespace image
209} // namespace afw
210} // namespace lsst
std::shared_ptr< MaskDict > getDefault() const noexcept
Definition MaskDict.cc:58
std::shared_ptr< MaskDict > copyOrGetDefault(MaskPlaneDict const &mpd)
Definition MaskDict.cc:41
std::shared_ptr< MaskDict > copy(MaskDict const &dict)
Definition MaskDict.cc:51
void setDefault(std::shared_ptr< MaskDict > dict)
Definition MaskDict.cc:60
std::shared_ptr< MaskDict > detachDefault()
Definition MaskDict.cc:62
int getMaskPlane(std::string const &name) const
Definition MaskDict.cc:157
const_iterator begin() const noexcept
Definition MaskDict.h:131
static void addAllMasksPlane(std::string const &name, int bitId)
Definition MaskDict.cc:118
static std::shared_ptr< MaskDict > detachDefault()
Definition MaskDict.cc:116
const_iterator end() const noexcept
Definition MaskDict.h:132
static std::shared_ptr< MaskDict > getDefault()
Definition MaskDict.cc:112
std::shared_ptr< MaskDict > clone() const
Definition MaskDict.cc:133
static void setDefault(std::shared_ptr< MaskDict > dict)
Definition MaskDict.cc:114
bool operator==(MaskDict const &rhs) const
Definition MaskDict.cc:168
const_iterator find(std::string const &name) const
Definition MaskDict.h:135
void add(std::string const &name, int bitId)
Definition MaskDict.cc:172
static std::shared_ptr< MaskDict > copyOrGetDefault(MaskPlaneDict const &dict)
Definition MaskDict.cc:108
bool empty() const noexcept
Definition MaskDict.h:141
void erase(std::string const &name)
Definition MaskDict.cc:177
T empty(T... args)
T endl(T... args)
T find_if(T... args)
T max_element(T... args)
T move(T... args)
std::map< std::string, int > MaskPlaneDict
Definition Mask.h:58
STL namespace.