lsst.afw g5dde539398+76be3eb1da
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 ;
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
double x
#define LSST_EXCEPT_ADD(e, m)
#define LSST_EXCEPT(type,...)
#define LOGL_DEBUG(logger, message...)
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:52
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:239
void operator++()
Advance the iterator, maybe skipping over candidates labelled BAD.
Definition: SpatialCell.cc:260
size_t operator-(SpatialCellCandidateIterator const &rhs) const
Return the number of candidate between this and rhs.
Definition: SpatialCell.cc:274
std::shared_ptr< SpatialCellCandidate const > operator*() const
Dereference the iterator to return the Candidate (if there is one)
Definition: SpatialCell.cc:285
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:111
void sortCandidates()
Rearrange the candidates to reflect their current ratings.
Definition: SpatialCell.cc:79
void removeCandidate(std::shared_ptr< SpatialCellCandidate > candidate)
Remove a candidate from the list.
Definition: SpatialCell.cc:87
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:134
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:97
std::shared_ptr< SpatialCellCandidate > getCandidateById(int id, bool noThrow=false)
Return the SpatialCellCandidate with the specified id.
Definition: SpatialCell.cc:119
SpatialCell(std::string const &label, lsst::geom::Box2I const &bbox=lsst::geom::Box2I(), CandidateList const &candidateList=CandidateList())
Constructor.
Definition: SpatialCell.cc:71
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:191
void insertCandidate(std::shared_ptr< SpatialCellCandidate > candidate)
Add a candidate to the list, preserving ranking.
Definition: SpatialCell.cc:81
void sortCandidates()
Rearrange the Candidates in all SpatialCells to reflect their current ratings.
Definition: SpatialCell.cc:372
void visitAllCandidates(CandidateVisitor *visitor, bool const ignoreExceptions=false)
Call the visitor's processCandidate method for every Candidate in the SpatialCellSet.
Definition: SpatialCell.cc:397
void setIgnoreBad(bool ignoreBad)
Set whether we should omit BAD candidates from candidate list when traversing.
Definition: SpatialCell.cc:431
void insertCandidate(std::shared_ptr< SpatialCellCandidate > candidate)
Insert a candidate into the correct cell.
Definition: SpatialCell.cc:359
std::shared_ptr< SpatialCellCandidate > getCandidateById(int id, bool noThrow=false)
Return the SpatialCellCandidate with the specified id.
Definition: SpatialCell.cc:414
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:378
SpatialCellSet(lsst::geom::Box2I const &region, int xSize, int ySize=0)
Constructor.
Definition: SpatialCell.cc:301
int getMinY() const noexcept
int getHeight() const noexcept
int getMinX() const noexcept
int getWidth() const noexcept
int getMaxX() const noexcept
int getMaxY() const noexcept
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)