LSST Applications g04c3c9f7ca+2075667efa,g1e125bf412+5f448d5fcf,g2079a07aa2+3e9fd84d81,g2305ad1205+b635cf1488,g2bbee38e9b+6c6beb4891,g337abbeb29+6c6beb4891,g33d1c0ed96+6c6beb4891,g3a166c0a6a+6c6beb4891,g50ff169b8f+96c6868917,g52b1c1532d+585e252eca,g591dd9f2cf+42f171e1e6,g5c3423f6d4+d536b04327,g607f77f49a+d536b04327,g6f43f06aed+ca1339dc19,g858d7b2824+d536b04327,g8ee334c5b4+d7f9608c2f,g9963eaa53e+b3dc1655d3,g998f4353bf+d536b04327,g99cad8db69+8ef2408349,g9ddcbc5298+9a081db1e4,ga1e77700b3+2cbb763275,gadfd92a7e4+aec2f3b930,gae0086650b+585e252eca,gb0e22166c9+0e73c8378f,gb3b7280ab2+cb5fdb229e,gbb8dafda3b+a327199e22,gc120e1dc64+88074880ea,gc28159a63d+6c6beb4891,gcdd4ae20e8+bd241b2308,gcde1bda545+903e937d91,gcf0d15dbbd+bd241b2308,gdaeeff99f8+f9a426f77a,gddc38dedce+585e252eca,ge79ae78c31+6c6beb4891,gfbcc870c63+b310236976,w.2024.23
LSST Data Management Base Package
Loading...
Searching...
No Matches
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 {
45 return a->getCandidateRating() > b->getCandidateRating();
46 }
47};
48} // namespace
49
50int SpatialCellCandidate::_CandidateId = 0;
51
53 switch (status) {
54 case GOOD:
55 case UNKNOWN:
56 _status = status;
57 return;
58 case BAD:
59 _status = status;
60 return;
61 }
62
64 (boost::format("Saw unknown status %d") % status).str());
65}
66
67int SpatialCellImageCandidate::_width = 0;
68
69int SpatialCellImageCandidate::_height = 0;
70
72 CandidateList const &candidateList)
73 : _label(label), _bbox(bbox), _candidateList(candidateList), _ignoreBad(true) {
74 LOGL_DEBUG("lsst.afw.math.SpatialCell", "Cell %s : created with %d candidates", this->_label.c_str(),
75 this->_candidateList.size());
77}
78
79void SpatialCell::sortCandidates() { sort(_candidateList.begin(), _candidateList.end(), CandidatePtrMore()); }
80
82 CandidateList::iterator pos =
83 std::lower_bound(_candidateList.begin(), _candidateList.end(), candidate, CandidatePtrMore());
84 _candidateList.insert(pos, candidate);
85}
86
88 CandidateList::iterator pos = std::find(_candidateList.begin(), _candidateList.end(), candidate);
89 if (pos == _candidateList.end()) {
90 throw LSST_EXCEPT(
92 (boost::format("Unable to find candidate with ID == %d") % candidate->getId()).str());
93 }
94 _candidateList.erase(pos);
95}
96
97bool SpatialCell::empty() const {
98 // Cast away const; end is only non-const as it provides access to the Candidates
99 // and we don't (yet) have SpatialCellCandidateConstIterator
100 SpatialCell *mthis = const_cast<SpatialCell *>(this);
101
102 for (auto && mthi : *mthis) {
103 if (!(_ignoreBad && (mthi)->isBad())) { // found a good candidate, or don't care
104 return false;
105 }
106 }
107
108 return true;
109}
110
111size_t SpatialCell::size() const {
112 // Cast away const; begin/end is only non-const as they provide access to the Candidates
113 // and we don't (yet) have SpatialCellCandidateConstIterator
114 SpatialCell *mthis = const_cast<SpatialCell *>(this);
115
116 return mthis->end() - mthis->begin();
117}
118
120 for (SpatialCellCandidateIterator ptr = begin(), end = this->end(); ptr != end; ++ptr) {
121 if ((*ptr)->getId() == id) {
122 return *ptr;
123 }
124 }
125
126 if (noThrow) {
128 } else {
130 (boost::format("Unable to find object with ID == %d") % id).str());
131 }
132}
133
134void SpatialCell::visitCandidates(CandidateVisitor *visitor, int const nMaxPerCell,
135
136 bool const ignoreExceptions, bool const reset) {
137 if (reset) {
138 visitor->reset();
139 }
140
141 int i = 0;
142 for (SpatialCell::iterator candidate = begin(), candidateEnd = end(); candidate != candidateEnd;
143 ++candidate, ++i) {
144 if (nMaxPerCell > 0 && i == nMaxPerCell) { // we've processed all the candidates we want
145 return;
146 }
147
148 try {
149 visitor->processCandidate((*candidate).get());
151 if (ignoreExceptions) {
152 --i; // Don't count the candidate if it raises an exception
153 } else {
154 LSST_EXCEPT_ADD(e, "Visiting candidate");
155 throw e;
156 }
157 }
158 }
159}
160
161void SpatialCell::visitCandidates(CandidateVisitor *visitor, int const nMaxPerCell,
162 bool const ignoreExceptions, bool const reset) const {
163#if 1
164 //
165 // This const_cast must go!
166 //
167 SpatialCell *mthis = const_cast<SpatialCell *>(this);
168 mthis->visitCandidates(visitor, nMaxPerCell, ignoreExceptions, reset);
169#else
170 int i = 0;
171 for (SpatialCell::const_iterator candidate = (*cell)->begin(), candidateEnd = (*cell)->end();
172 candidate != candidateEnd; ++candidate, ++i) {
173 if (i == nMaxPerCell) { // we've processed all the candidates we want
174 return;
175 }
176
177 try {
178 visitor->processCandidate((*candidate).get());
180 if (ignoreExceptions) {
181 ;
182 } else {
183 LSST_EXCEPT_ADD(e, "Visiting candidate");
184 throw e;
185 }
186 }
187 }
188#endif
189}
190
191void SpatialCell::visitAllCandidates(CandidateVisitor *visitor, bool const ignoreExceptions,
192 bool const reset) {
193 if (reset) {
194 visitor->reset();
195 }
196
197 int i = 0;
198 for (SpatialCell::iterator candidate = begin(false), candidateEnd = end(false); candidate != candidateEnd;
199 ++candidate, ++i) {
200 try {
201 visitor->processCandidate((*candidate).get());
203 if (ignoreExceptions) {
204 ;
205 } else {
206 LSST_EXCEPT_ADD(e, "Visiting candidate");
207 throw e;
208 }
209 }
210 }
211}
212
213void SpatialCell::visitAllCandidates(CandidateVisitor *visitor, bool const ignoreExceptions,
214 bool const reset) const {
215#if 1
216 //
217 // This const_cast must go!
218 //
219 SpatialCell *mthis = const_cast<SpatialCell *>(this);
220 mthis->visitAllCandidates(visitor, ignoreExceptions, reset);
221#else
222 int i = 0;
223 for (SpatialCell::const_iterator candidate = (*cell)->begin(false), candidateEnd = (*cell)->end(false);
224 candidate != candidateEnd; ++candidate, ++i) {
225 try {
226 visitor->processCandidate((*candidate).get());
228 if (ignoreExceptions) {
229 ;
230 } else {
231 LSST_EXCEPT_ADD(e, "Visiting candidate");
232 throw e;
233 }
234 }
235 }
236#endif
237}
238
240 CandidateList::iterator end, bool ignoreBad)
241 : _iterator(iterator), _end(end), _ignoreBad(ignoreBad) {
242 for (; _iterator != _end; ++_iterator) {
243 (*_iterator)->instantiate();
244
245 if (!(_ignoreBad && (*_iterator)->isBad())) { // found a good candidate, or don't care
246 return;
247 }
248 }
249}
250
252 CandidateList::iterator end, bool ignoreBad, bool)
253 : _iterator(end), _end(end), _ignoreBad(ignoreBad) {
254 if (ignoreBad) {
255 // We could decrement end if there are bad Candidates at the end of the list, but it's probably
256 // not worth the trouble
257 }
258}
259
261 if (_iterator != _end) {
262 ++_iterator;
263 }
264
265 for (; _iterator != _end; ++_iterator) {
266 (*_iterator)->instantiate();
267
268 if (!(_ignoreBad && (*_iterator)->isBad())) { // found a good candidate, or don't care
269 return;
270 }
271 }
272}
273
275 size_t n = 0;
276 for (SpatialCellCandidateIterator ptr = rhs; ptr != *this; ++ptr) {
277 if (!(_ignoreBad && (*ptr)->isBad())) { // found a good candidate, or don't care
278 ++n;
279 }
280 }
281
282 return n;
283}
284
286 if (_iterator == _end) {
287 throw LSST_EXCEPT(lsst::pex::exceptions::NotFoundError, "Iterator points to end");
288 }
289
290 return *_iterator;
291}
292
294 if (_iterator == _end) {
295 throw LSST_EXCEPT(lsst::pex::exceptions::NotFoundError, "Iterator points to end");
296 }
297
298 return *_iterator;
299}
300
301SpatialCellSet::SpatialCellSet(lsst::geom::Box2I const &region, int xSize, int ySize)
302 : _region(region), _cellList(CellList()) {
303 if (ySize == 0) {
304 ySize = xSize;
305 }
306
307 if (xSize <= 0 || ySize <= 0) {
308 throw LSST_EXCEPT(
310 (boost::format("Please specify cells that contain pixels, not %dx%d") % xSize % ySize).str());
311 }
312
313 int nx = region.getWidth() / xSize;
314 if (nx * xSize != region.getWidth()) {
315 nx++;
316 }
317
318 int ny = region.getHeight() / ySize;
319 if (ny * ySize != region.getHeight()) {
320 ny++;
321 }
322 //
323 // N.b. the SpatialCells will be sorted in y at the end of this
324 //
325 int y0 = region.getMinY();
326 for (int y = 0; y < ny; ++y) {
327 // ny may not be a factor of height
328 int const y1 = (y == ny - 1) ? region.getMaxY() : y0 + ySize - 1;
329 int x0 = region.getMinX();
330 for (int x = 0; x < nx; ++x) {
331 // nx may not be a factor of width
332 int const x1 = (x == nx - 1) ? region.getMaxX() : x0 + xSize - 1;
334 std::string label = (boost::format("Cell %dx%d") % x % y).str();
335
336 _cellList.push_back(std::make_shared<SpatialCell>(label, bbox));
337
338 x0 = x1 + 1;
339 }
340 y0 = y1 + 1;
341 }
342}
343
344namespace {
345struct CellContains {
346 CellContains(std::shared_ptr<SpatialCellCandidate> candidate) : _candidate(candidate) {}
347
348 bool operator()(std::shared_ptr<SpatialCell> cell) {
349 return cell->getBBox().contains(
350 lsst::geom::Point2I(image::positionToIndex(_candidate->getXCenter()),
351 image::positionToIndex(_candidate->getYCenter())));
352 }
353
354private:
356};
357} // namespace
358
360 CellList::iterator pos = std::find_if(_cellList.begin(), _cellList.end(), CellContains(candidate));
361
362 if (pos == _cellList.end()) {
364 (boost::format("Unable to insert a candidate at (%.2f, %.2f)") %
365 candidate->getXCenter() % candidate->getYCenter())
366 .str());
367 }
368
369 (*pos)->insertCandidate(candidate);
370}
371
373 for (auto const &cell : _cellList) {
374 cell->sortCandidates();
375 }
376}
377
378void SpatialCellSet::visitCandidates(CandidateVisitor *visitor, int const nMaxPerCell,
379 bool const ignoreExceptions) {
380 visitor->reset();
381
382 for (auto const &cell : _cellList) {
383 cell->visitCandidates(visitor, nMaxPerCell, ignoreExceptions, false);
384 }
385}
386
387void SpatialCellSet::visitCandidates(CandidateVisitor *visitor, int const nMaxPerCell,
388 bool const ignoreExceptions) const {
389 visitor->reset();
390
391 for (auto const &cell : _cellList) {
392 SpatialCell const *ccell = cell.get(); // the SpatialCellSet's SpatialCells should be const too
393 ccell->visitCandidates(visitor, nMaxPerCell, ignoreExceptions, false);
394 }
395}
396
397void SpatialCellSet::visitAllCandidates(CandidateVisitor *visitor, bool const ignoreExceptions) {
398 visitor->reset();
399
400 for (auto const &cell : _cellList) {
401 cell->visitAllCandidates(visitor, ignoreExceptions, false);
402 }
403}
404
405void SpatialCellSet::visitAllCandidates(CandidateVisitor *visitor, bool const ignoreExceptions) const {
406 visitor->reset();
407
408 for (auto const &cell : _cellList) {
409 SpatialCell const *ccell = cell.get(); // the SpatialCellSet's SpatialCells should be const too
410 ccell->visitAllCandidates(visitor, ignoreExceptions, false);
411 }
412}
413
415 for (auto const &cell : _cellList) {
416 std::shared_ptr<SpatialCellCandidate> cand = cell->getCandidateById(id, true);
417
418 if (cand) {
419 return cand;
420 }
421 }
422
423 if (noThrow) {
425 } else {
427 (boost::format("Unable to find object with ID == %d") % id).str());
428 }
429}
430
431void SpatialCellSet::setIgnoreBad(bool ignoreBad) {
432 for (auto const &cell : _cellList) {
433 cell->setIgnoreBad(ignoreBad);
434 }
435}
436} // namespace math
437} // namespace afw
438} // namespace lsst
AmpInfoBoxKey bbox
Definition Amplifier.cc:117
int end
#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
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:95
int y
Definition SpanSet.cc:48
table::Key< int > b
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.
An iterator that only returns usable members of the SpatialCell.
SpatialCellCandidateIterator(CandidateList::iterator iterator, CandidateList::iterator end, bool ignoreBad)
ctor; designed to be used to pass begin to SpatialCellCandidateIterator
void operator++()
Advance the iterator, maybe skipping over candidates labelled BAD.
size_t operator-(SpatialCellCandidateIterator const &rhs) const
Return the number of candidate between this and rhs.
std::shared_ptr< SpatialCellCandidate const > operator*() const
Dereference the iterator to return the Candidate (if there is one)
Class to ensure constraints for spatial modeling.
SpatialCellCandidateIterator end()
Return an iterator to (one after) the end of the Candidates.
size_t size() const
Return number of usable candidates in Cell.
void sortCandidates()
Rearrange the candidates to reflect their current ratings.
void removeCandidate(std::shared_ptr< SpatialCellCandidate > candidate)
Remove a candidate from the list.
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.
SpatialCellCandidateIterator begin()
Return an iterator to the beginning of the Candidates.
bool empty() const
Determine if cell has no usable candidates.
std::shared_ptr< SpatialCellCandidate > getCandidateById(int id, bool noThrow=false)
Return the SpatialCellCandidate with the specified id.
SpatialCell(std::string const &label, lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), CandidateList const &candidateList=CandidateList())
Constructor.
void visitAllCandidates(CandidateVisitor *visitor, bool const ignoreExceptions=false, bool const reset=true)
Call the visitor's processCandidate method for every Candidate in the SpatialCell.
void insertCandidate(std::shared_ptr< SpatialCellCandidate > candidate)
Add a candidate to the list, preserving ranking.
void sortCandidates()
Rearrange the Candidates in all SpatialCells to reflect their current ratings.
void visitAllCandidates(CandidateVisitor *visitor, bool const ignoreExceptions=false)
Call the visitor's processCandidate method for every Candidate in the SpatialCellSet.
void setIgnoreBad(bool ignoreBad)
Set whether we should omit BAD candidates from candidate list when traversing.
void insertCandidate(std::shared_ptr< SpatialCellCandidate > candidate)
Insert a candidate into the correct cell.
std::shared_ptr< SpatialCellCandidate > getCandidateById(int id, bool noThrow=false)
Return the SpatialCellCandidate with the specified id.
void visitCandidates(CandidateVisitor *visitor, int const nMaxPerCell=-1, bool const ignoreExceptions=false)
Call the visitor's processCandidate method for each Candidate in the SpatialCellSet.
SpatialCellSet(lsst::geom::Box2I const &region, int xSize, int ySize=0)
Constructor.
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)
int positionToIndex(double pos)
Convert image position to nearest integer index.
Definition ImageUtils.h:69
T push_back(T... args)