LSST Applications g0b6bd0c080+a72a5dd7e6,g1182afd7b4+2a019aa3bb,g17e5ecfddb+2b8207f7de,g1d67935e3f+06cf436103,g38293774b4+ac198e9f13,g396055baef+6a2097e274,g3b44f30a73+6611e0205b,g480783c3b1+98f8679e14,g48ccf36440+89c08d0516,g4b93dc025c+98f8679e14,g5c4744a4d9+a302e8c7f0,g613e996a0d+e1c447f2e0,g6c8d09e9e7+25247a063c,g7271f0639c+98f8679e14,g7a9cd813b8+124095ede6,g9d27549199+a302e8c7f0,ga1cf026fa3+ac198e9f13,ga32aa97882+7403ac30ac,ga786bb30fb+7a139211af,gaa63f70f4e+9994eb9896,gabf319e997+ade567573c,gba47b54d5d+94dc90c3ea,gbec6a3398f+06cf436103,gc6308e37c7+07dd123edb,gc655b1545f+ade567573c,gcc9029db3c+ab229f5caf,gd01420fc67+06cf436103,gd877ba84e5+06cf436103,gdb4cecd868+6f279b5b48,ge2d134c3d5+cc4dbb2e3f,ge448b5faa6+86d1ceac1d,gecc7e12556+98f8679e14,gf3ee170dca+25247a063c,gf4ac96e456+ade567573c,gf9f5ea5b4d+ac198e9f13,gff490e6085+8c2580be5c,w.2022.27
LSST Data Management Base Package
SpatialCell.cc
Go to the documentation of this file.
1// -*- lsst-c++ -*-
2
3/*
4 * LSST Data Management System
5 * Copyright 2008, 2009, 2010 LSST Corporation.
6 *
7 * This product includes software developed by the
8 * LSST Project (http://www.lsst.org/).
9 *
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the LSST License Statement and
21 * the GNU General Public License along with this program. If not,
22 * see <http://www.lsstcorp.org/LegalNotices/>.
23 */
24
25/*
26 * Implementation of SpatialCell class
27 */
28#include <algorithm>
29#include <memory>
30
32
33#include "lsst/log/Log.h"
35
36namespace image = lsst::afw::image;
37
38namespace lsst {
39namespace afw {
40namespace math {
41
42namespace {
43struct CandidatePtrMore : public std::binary_function<std::shared_ptr<SpatialCellCandidate>,
44 std::shared_ptr<SpatialCellCandidate>, bool> {
46 return a->getCandidateRating() > b->getCandidateRating();
47 }
48};
49} // namespace
50
51int SpatialCellCandidate::_CandidateId = 0;
52
54 switch (status) {
55 case GOOD:
56 case UNKNOWN:
57 _status = status;
58 return;
59 case BAD:
60 _status = status;
61 return;
62 }
63
65 (boost::format("Saw unknown status %d") % status).str());
66}
67
68int SpatialCellImageCandidate::_width = 0;
69
70int SpatialCellImageCandidate::_height = 0;
71
73 CandidateList const &candidateList)
74 : _label(label), _bbox(bbox), _candidateList(candidateList), _ignoreBad(true) {
75 LOGL_DEBUG("lsst.afw.math.SpatialCell", "Cell %s : created with %d candidates", this->_label.c_str(),
76 this->_candidateList.size());
78}
79
80void SpatialCell::sortCandidates() { sort(_candidateList.begin(), _candidateList.end(), CandidatePtrMore()); }
81
83 CandidateList::iterator pos =
84 std::lower_bound(_candidateList.begin(), _candidateList.end(), candidate, CandidatePtrMore());
85 _candidateList.insert(pos, candidate);
86}
87
89 CandidateList::iterator pos = std::find(_candidateList.begin(), _candidateList.end(), candidate);
90 if (pos == _candidateList.end()) {
91 throw LSST_EXCEPT(
93 (boost::format("Unable to find candidate with ID == %d") % candidate->getId()).str());
94 }
95 _candidateList.erase(pos);
96}
97
98bool SpatialCell::empty() const {
99 // Cast away const; end is only non-const as it provides access to the Candidates
100 // and we don't (yet) have SpatialCellCandidateConstIterator
101 SpatialCell *mthis = const_cast<SpatialCell *>(this);
102
103 for (auto && mthi : *mthis) {
104 if (!(_ignoreBad && (mthi)->isBad())) { // found a good candidate, or don't care
105 return false;
106 }
107 }
108
109 return true;
110}
111
112size_t SpatialCell::size() const {
113 // Cast away const; begin/end is only non-const as they provide access to the Candidates
114 // and we don't (yet) have SpatialCellCandidateConstIterator
115 SpatialCell *mthis = const_cast<SpatialCell *>(this);
116
117 return mthis->end() - mthis->begin();
118}
119
121 for (SpatialCellCandidateIterator ptr = begin(), end = this->end(); ptr != end; ++ptr) {
122 if ((*ptr)->getId() == id) {
123 return *ptr;
124 }
125 }
126
127 if (noThrow) {
129 } else {
131 (boost::format("Unable to find object with ID == %d") % id).str());
132 }
133}
134
135void SpatialCell::visitCandidates(CandidateVisitor *visitor, int const nMaxPerCell,
136
137 bool const ignoreExceptions, bool const reset) {
138 if (reset) {
139 visitor->reset();
140 }
141
142 int i = 0;
143 for (SpatialCell::iterator candidate = begin(), candidateEnd = end(); candidate != candidateEnd;
144 ++candidate, ++i) {
145 if (nMaxPerCell > 0 && i == nMaxPerCell) { // we've processed all the candidates we want
146 return;
147 }
148
149 try {
150 visitor->processCandidate((*candidate).get());
152 if (ignoreExceptions) {
153 ;
154 } else {
155 LSST_EXCEPT_ADD(e, "Visiting candidate");
156 throw e;
157 }
158 }
159 }
160}
161
162void SpatialCell::visitCandidates(CandidateVisitor *visitor, int const nMaxPerCell,
163 bool const ignoreExceptions, bool const reset) const {
164#if 1
165 //
166 // This const_cast must go!
167 //
168 SpatialCell *mthis = const_cast<SpatialCell *>(this);
169 mthis->visitCandidates(visitor, nMaxPerCell, ignoreExceptions, reset);
170#else
171 int i = 0;
172 for (SpatialCell::const_iterator candidate = (*cell)->begin(), candidateEnd = (*cell)->end();
173 candidate != candidateEnd; ++candidate, ++i) {
174 if (i == nMaxPerCell) { // we've processed all the candidates we want
175 return;
176 }
177
178 try {
179 visitor->processCandidate((*candidate).get());
181 if (ignoreExceptions) {
182 ;
183 } else {
184 LSST_EXCEPT_ADD(e, "Visiting candidate");
185 throw e;
186 }
187 }
188 }
189#endif
190}
191
192void SpatialCell::visitAllCandidates(CandidateVisitor *visitor, bool const ignoreExceptions,
193 bool const reset) {
194 if (reset) {
195 visitor->reset();
196 }
197
198 int i = 0;
199 for (SpatialCell::iterator candidate = begin(false), candidateEnd = end(false); candidate != candidateEnd;
200 ++candidate, ++i) {
201 try {
202 visitor->processCandidate((*candidate).get());
204 if (ignoreExceptions) {
205 ;
206 } else {
207 LSST_EXCEPT_ADD(e, "Visiting candidate");
208 throw e;
209 }
210 }
211 }
212}
213
214void SpatialCell::visitAllCandidates(CandidateVisitor *visitor, bool const ignoreExceptions,
215 bool const reset) const {
216#if 1
217 //
218 // This const_cast must go!
219 //
220 SpatialCell *mthis = const_cast<SpatialCell *>(this);
221 mthis->visitAllCandidates(visitor, ignoreExceptions, reset);
222#else
223 int i = 0;
224 for (SpatialCell::const_iterator candidate = (*cell)->begin(false), candidateEnd = (*cell)->end(false);
225 candidate != candidateEnd; ++candidate, ++i) {
226 try {
227 visitor->processCandidate((*candidate).get());
229 if (ignoreExceptions) {
230 ;
231 } else {
232 LSST_EXCEPT_ADD(e, "Visiting candidate");
233 throw e;
234 }
235 }
236 }
237#endif
238}
239
241 CandidateList::iterator end, bool ignoreBad)
242 : _iterator(iterator), _end(end), _ignoreBad(ignoreBad) {
243 for (; _iterator != _end; ++_iterator) {
244 (*_iterator)->instantiate();
245
246 if (!(_ignoreBad && (*_iterator)->isBad())) { // found a good candidate, or don't care
247 return;
248 }
249 }
250}
251
253 CandidateList::iterator end, bool ignoreBad, bool)
254 : _iterator(end), _end(end), _ignoreBad(ignoreBad) {
255 if (ignoreBad) {
256 // We could decrement end if there are bad Candidates at the end of the list, but it's probably
257 // not worth the trouble
258 }
259}
260
262 if (_iterator != _end) {
263 ++_iterator;
264 }
265
266 for (; _iterator != _end; ++_iterator) {
267 (*_iterator)->instantiate();
268
269 if (!(_ignoreBad && (*_iterator)->isBad())) { // found a good candidate, or don't care
270 return;
271 }
272 }
273}
274
276 size_t n = 0;
277 for (SpatialCellCandidateIterator ptr = rhs; ptr != *this; ++ptr) {
278 if (!(_ignoreBad && (*ptr)->isBad())) { // found a good candidate, or don't care
279 ++n;
280 }
281 }
282
283 return n;
284}
285
287 if (_iterator == _end) {
288 throw LSST_EXCEPT(lsst::pex::exceptions::NotFoundError, "Iterator points to end");
289 }
290
291 return *_iterator;
292}
293
295 if (_iterator == _end) {
296 throw LSST_EXCEPT(lsst::pex::exceptions::NotFoundError, "Iterator points to end");
297 }
298
299 return *_iterator;
300}
301
302SpatialCellSet::SpatialCellSet(lsst::geom::Box2I const &region, int xSize, int ySize)
303 : _region(region), _cellList(CellList()) {
304 if (ySize == 0) {
305 ySize = xSize;
306 }
307
308 if (xSize <= 0 || ySize <= 0) {
309 throw LSST_EXCEPT(
311 (boost::format("Please specify cells that contain pixels, not %dx%d") % xSize % ySize).str());
312 }
313
314 int nx = region.getWidth() / xSize;
315 if (nx * xSize != region.getWidth()) {
316 nx++;
317 }
318
319 int ny = region.getHeight() / ySize;
320 if (ny * ySize != region.getHeight()) {
321 ny++;
322 }
323 //
324 // N.b. the SpatialCells will be sorted in y at the end of this
325 //
326 int y0 = region.getMinY();
327 for (int y = 0; y < ny; ++y) {
328 // ny may not be a factor of height
329 int const y1 = (y == ny - 1) ? region.getMaxY() : y0 + ySize - 1;
330 int x0 = region.getMinX();
331 for (int x = 0; x < nx; ++x) {
332 // nx may not be a factor of width
333 int const x1 = (x == nx - 1) ? region.getMaxX() : x0 + xSize - 1;
335 std::string label = (boost::format("Cell %dx%d") % x % y).str();
336
337 _cellList.push_back(std::make_shared<SpatialCell>(label, bbox));
338
339 x0 = x1 + 1;
340 }
341 y0 = y1 + 1;
342 }
343}
344
345namespace {
346struct CellContains : public std::unary_function<std::shared_ptr<SpatialCell>, bool> {
347 CellContains(std::shared_ptr<SpatialCellCandidate> candidate) : _candidate(candidate) {}
348
349 bool operator()(std::shared_ptr<SpatialCell> cell) {
350 return cell->getBBox().contains(
351 lsst::geom::Point2I(image::positionToIndex(_candidate->getXCenter()),
352 image::positionToIndex(_candidate->getYCenter())));
353 }
354
355private:
357};
358} // namespace
359
361 CellList::iterator pos = std::find_if(_cellList.begin(), _cellList.end(), CellContains(candidate));
362
363 if (pos == _cellList.end()) {
365 (boost::format("Unable to insert a candidate at (%.2f, %.2f)") %
366 candidate->getXCenter() % candidate->getYCenter())
367 .str());
368 }
369
370 (*pos)->insertCandidate(candidate);
371}
372
374 for (auto const &cell : _cellList) {
375 cell->sortCandidates();
376 }
377}
378
379void SpatialCellSet::visitCandidates(CandidateVisitor *visitor, int const nMaxPerCell,
380 bool const ignoreExceptions) {
381 visitor->reset();
382
383 for (auto const &cell : _cellList) {
384 cell->visitCandidates(visitor, nMaxPerCell, ignoreExceptions, false);
385 }
386}
387
388void SpatialCellSet::visitCandidates(CandidateVisitor *visitor, int const nMaxPerCell,
389 bool const ignoreExceptions) const {
390 visitor->reset();
391
392 for (auto const &cell : _cellList) {
393 SpatialCell const *ccell = cell.get(); // the SpatialCellSet's SpatialCells should be const too
394 ccell->visitCandidates(visitor, nMaxPerCell, ignoreExceptions, false);
395 }
396}
397
398void SpatialCellSet::visitAllCandidates(CandidateVisitor *visitor, bool const ignoreExceptions) {
399 visitor->reset();
400
401 for (auto const &cell : _cellList) {
402 cell->visitAllCandidates(visitor, ignoreExceptions, false);
403 }
404}
405
406void SpatialCellSet::visitAllCandidates(CandidateVisitor *visitor, bool const ignoreExceptions) const {
407 visitor->reset();
408
409 for (auto const &cell : _cellList) {
410 SpatialCell const *ccell = cell.get(); // the SpatialCellSet's SpatialCells should be const too
411 ccell->visitAllCandidates(visitor, ignoreExceptions, false);
412 }
413}
414
416 for (auto const &cell : _cellList) {
417 std::shared_ptr<SpatialCellCandidate> cand = cell->getCandidateById(id, true);
418
419 if (cand) {
420 return cand;
421 }
422 }
423
424 if (noThrow) {
426 } else {
428 (boost::format("Unable to find object with ID == %d") % id).str());
429 }
430}
431
432void SpatialCellSet::setIgnoreBad(bool ignoreBad) {
433 for (auto const &cell : _cellList) {
434 cell->setIgnoreBad(ignoreBad);
435 }
436}
437} // namespace math
438} // namespace afw
439} // namespace lsst
AmpInfoBoxKey bbox
Definition: Amplifier.cc:117
int end
double x
#define LSST_EXCEPT_ADD(e, m)
Add the current location and a message to an existing exception before rethrowing it.
Definition: Exception.h:54
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
afw::table::Key< afw::table::Array< ImagePixelT > > image
LSST DM logging module built on log4cxx.
#define LOGL_DEBUG(logger, message...)
Log a debug-level message using a varargs/printf style interface.
Definition: Log.h:515
uint64_t * ptr
Definition: RangeSet.cc:88
int y
Definition: SpanSet.cc:48
table::Key< int > b
table::Key< int > a
T begin(T... args)
T c_str(T... args)
virtual void processCandidate(SpatialCellCandidate *)
Definition: SpatialCell.h:64
void setStatus(Status status)
Set the candidate's status.
Definition: SpatialCell.cc:53
An iterator that only returns usable members of the SpatialCell.
Definition: SpatialCell.h:159
SpatialCellCandidateIterator(CandidateList::iterator iterator, CandidateList::iterator end, bool ignoreBad)
ctor; designed to be used to pass begin to SpatialCellCandidateIterator
Definition: SpatialCell.cc:240
void operator++()
Advance the iterator, maybe skipping over candidates labelled BAD.
Definition: SpatialCell.cc:261
size_t operator-(SpatialCellCandidateIterator const &rhs) const
Return the number of candidate between this and rhs.
Definition: SpatialCell.cc:275
std::shared_ptr< SpatialCellCandidate const > operator*() const
Dereference the iterator to return the Candidate (if there is one)
Definition: SpatialCell.cc:286
Class to ensure constraints for spatial modeling.
Definition: SpatialCell.h:223
SpatialCellCandidateIterator end()
Return an iterator to (one after) the end of the Candidates.
Definition: SpatialCell.h:273
size_t size() const
Return number of usable candidates in Cell.
Definition: SpatialCell.cc:112
void sortCandidates()
Rearrange the candidates to reflect their current ratings.
Definition: SpatialCell.cc:80
void removeCandidate(std::shared_ptr< SpatialCellCandidate > candidate)
Remove a candidate from the list.
Definition: SpatialCell.cc:88
void visitCandidates(CandidateVisitor *visitor, int const nMaxPerCell=-1, bool const ignoreExceptions=false, bool const reset=true)
Call the visitor's processCandidate method for each Candidate in the SpatialCell.
Definition: SpatialCell.cc:135
SpatialCellCandidateIterator begin()
Return an iterator to the beginning of the Candidates.
Definition: SpatialCell.h:263
bool empty() const
Determine if cell has no usable candidates.
Definition: SpatialCell.cc:98
std::shared_ptr< SpatialCellCandidate > getCandidateById(int id, bool noThrow=false)
Return the SpatialCellCandidate with the specified id.
Definition: SpatialCell.cc:120
SpatialCell(std::string const &label, lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), CandidateList const &candidateList=CandidateList())
Constructor.
Definition: SpatialCell.cc:72
void visitAllCandidates(CandidateVisitor *visitor, bool const ignoreExceptions=false, bool const reset=true)
Call the visitor's processCandidate method for every Candidate in the SpatialCell.
Definition: SpatialCell.cc:192
void insertCandidate(std::shared_ptr< SpatialCellCandidate > candidate)
Add a candidate to the list, preserving ranking.
Definition: SpatialCell.cc:82
void sortCandidates()
Rearrange the Candidates in all SpatialCells to reflect their current ratings.
Definition: SpatialCell.cc:373
void visitAllCandidates(CandidateVisitor *visitor, bool const ignoreExceptions=false)
Call the visitor's processCandidate method for every Candidate in the SpatialCellSet.
Definition: SpatialCell.cc:398
void setIgnoreBad(bool ignoreBad)
Set whether we should omit BAD candidates from candidate list when traversing.
Definition: SpatialCell.cc:432
void insertCandidate(std::shared_ptr< SpatialCellCandidate > candidate)
Insert a candidate into the correct cell.
Definition: SpatialCell.cc:360
std::shared_ptr< SpatialCellCandidate > getCandidateById(int id, bool noThrow=false)
Return the SpatialCellCandidate with the specified id.
Definition: SpatialCell.cc:415
void visitCandidates(CandidateVisitor *visitor, int const nMaxPerCell=-1, bool const ignoreExceptions=false)
Call the visitor's processCandidate method for each Candidate in the SpatialCellSet.
Definition: SpatialCell.cc:379
SpatialCellSet(lsst::geom::Box2I const &region, int xSize, int ySize=0)
Constructor.
Definition: SpatialCell.cc:302
An integer coordinate rectangle.
Definition: Box.h:55
int getMinY() const noexcept
Definition: Box.h:158
int getHeight() const noexcept
Definition: Box.h:188
int getMinX() const noexcept
Definition: Box.h:157
int getWidth() const noexcept
Definition: Box.h:187
int getMaxX() const noexcept
Definition: Box.h:161
int getMaxY() const noexcept
Definition: Box.h:162
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
Reports invalid arguments.
Definition: Runtime.h:66
Reports attempts to exceed implementation-defined length limits for some classes.
Definition: Runtime.h:76
Reports attempts to access elements using an invalid key.
Definition: Runtime.h:151
Reports attempts to access elements outside a valid range of indices.
Definition: Runtime.h:89
T end(T... args)
T erase(T... args)
T find(T... args)
T get(T... args)
T insert(T... args)
T lower_bound(T... args)
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
int positionToIndex(double pos)
Convert image position to nearest integer index.
Definition: ImageUtils.h:69
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:174
A base class for image defects.
T push_back(T... args)