LSSTApplications  11.0-13-gbb96280,12.1.rc1,12.1.rc1+1,12.1.rc1+2,12.1.rc1+5,12.1.rc1+8,12.1.rc1-1-g06d7636+1,12.1.rc1-1-g253890b+5,12.1.rc1-1-g3d31b68+7,12.1.rc1-1-g3db6b75+1,12.1.rc1-1-g5c1385a+3,12.1.rc1-1-g83b2247,12.1.rc1-1-g90cb4cf+6,12.1.rc1-1-g91da24b+3,12.1.rc1-2-g3521f8a,12.1.rc1-2-g39433dd+4,12.1.rc1-2-g486411b+2,12.1.rc1-2-g4c2be76,12.1.rc1-2-gc9c0491,12.1.rc1-2-gda2cd4f+6,12.1.rc1-3-g3391c73+2,12.1.rc1-3-g8c1bd6c+1,12.1.rc1-3-gcf4b6cb+2,12.1.rc1-4-g057223e+1,12.1.rc1-4-g19ed13b+2,12.1.rc1-4-g30492a7
LSSTDataManagementBasePackage
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 
32 #include <algorithm>
33 
35 #include "lsst/afw/image/Utils.h"
36 
38 #include "lsst/log/Log.h"
40 
41 namespace image = lsst::afw::image;
42 
43 namespace lsst {
44 namespace afw {
45 namespace math {
46 
47 namespace {
48  struct CandidatePtrMore : public std::binary_function<SpatialCellCandidate::Ptr,
49  SpatialCellCandidate::Ptr,
50  bool> {
52  return a->getCandidateRating() > b->getCandidateRating();
53  }
54  };
55 }
56 
59 
62  switch (status) {
63  case GOOD:
64  case UNKNOWN:
65  _status = status;
66  return;
67  case BAD:
68  _status = status;
69  return;
70  }
71 
72  throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
73  (boost::format("Saw unknown status %d") % status).str());
74 }
75 
76 /************************************************************************************************************/
80 SpatialCell::SpatialCell(std::string const& label,
81  geom::Box2I const& bbox,
82  CandidateList const& candidateList
83  ) :
84  _label(label),
85  _bbox(bbox),
86  _candidateList(candidateList),
87  _ignoreBad(true)
88 {
89  LOGL_DEBUG("afw.math.SpatialCell", "Cell %s : created with %d candidates",
90  this->_label.c_str(), this->_candidateList.size());
92 }
93 
94 /************************************************************************************************************/
99 {
100  sort(_candidateList.begin(), _candidateList.end(), CandidatePtrMore());
101 }
102 
103 /************************************************************************************************************/
108  CandidateList::iterator pos = std::lower_bound(_candidateList.begin(), _candidateList.end(),
109  candidate, CandidatePtrMore());
110  _candidateList.insert(pos, candidate);
111 }
112 
114 {
115  CandidateList::iterator pos = std::find(_candidateList.begin(), _candidateList.end(), candidate);
116  if (pos == _candidateList.end()) {
117  throw LSST_EXCEPT(lsst::pex::exceptions::NotFoundError,
118  (boost::format("Unable to find candidate with ID == %d") %
119  candidate->getId()).str());
120  }
121  _candidateList.erase(pos);
122 }
123 
127 bool SpatialCell::empty() const {
128  // Cast away const; end is only non-const as it provides access to the Candidates
129  // and we don't (yet) have SpatialCellCandidateConstIterator
130  SpatialCell *mthis = const_cast<SpatialCell *>(this);
131 
132  for (SpatialCellCandidateIterator ptr = mthis->begin(), end = mthis->end(); ptr != end; ++ptr) {
133  if (!(_ignoreBad && (*ptr)->isBad())) { // found a good candidate, or don't care
134  return false;
135  }
136  }
137 
138  return true;
139 }
140 
144 size_t SpatialCell::size() const {
145  // Cast away const; begin/end is only non-const as they provide access to the Candidates
146  // and we don't (yet) have SpatialCellCandidateConstIterator
147  SpatialCell *mthis = const_cast<SpatialCell *>(this);
148 
149  return mthis->end() - mthis->begin();
150 }
151 
152 /************************************************************************************************************/
159  bool noThrow
160  ) {
161  for (SpatialCellCandidateIterator ptr = begin(), end = this->end(); ptr != end; ++ptr) {
162  if ((*ptr)->getId() == id) {
163  return *ptr;
164  }
165  }
166 
167  if (noThrow) {
168  return SpatialCellCandidate::Ptr();
169  } else {
170  throw LSST_EXCEPT(lsst::pex::exceptions::NotFoundError,
171  (boost::format("Unable to find object with ID == %d") % id).str());
172  }
173 }
174 
183  int const nMaxPerCell,
184  bool const ignoreExceptions,
186  bool const reset
188  ) {
189  if (reset) {
190  visitor->reset();
191  }
192 
193  int i = 0;
194  for (SpatialCell::iterator candidate = begin(), candidateEnd = end();
195  candidate != candidateEnd; ++candidate, ++i) {
196  if (nMaxPerCell > 0 && i == nMaxPerCell) { // we've processed all the candidates we want
197  return;
198  }
199 
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 
222  CandidateVisitor * visitor,
223  int const nMaxPerCell,
224  bool const ignoreExceptions,
225  bool const reset
226  ) const {
227 #if 1
228  //
229  // This const_cast must go!
230  //
231  SpatialCell *mthis = const_cast<SpatialCell *>(this);
232  mthis->visitCandidates(visitor, nMaxPerCell, ignoreExceptions, reset);
233 #else
234  int i = 0;
235  for (SpatialCell::const_iterator candidate = (*cell)->begin(), candidateEnd = (*cell)->end();
236  candidate != candidateEnd; ++candidate, ++i) {
237  if (i == nMaxPerCell) { // we've processed all the candidates we want
238  return;
239  }
240 
241  try {
242  visitor->processCandidate((*candidate).get());
243  } catch(lsst::pex::exceptions::LengthError &e) {
244  if (ignoreExceptions) {
245  ;
246  } else {
247  LSST_EXCEPT_ADD(e, "Visiting candidate");
248  throw e;
249  }
250  }
251  }
252 #endif
253 }
254 
261  bool const ignoreExceptions,
262  bool const reset
263  ) {
264  if (reset) {
265  visitor->reset();
266  }
267 
268  int i = 0;
269  for (SpatialCell::iterator candidate = begin(false), candidateEnd = end(false);
270  candidate != candidateEnd; ++candidate, ++i) {
271  try {
272  visitor->processCandidate((*candidate).get());
273  } catch(lsst::pex::exceptions::LengthError &e) {
274  if (ignoreExceptions) {
275  ;
276  } else {
277  LSST_EXCEPT_ADD(e, "Visiting candidate");
278  throw e;
279  }
280  }
281  }
282 }
283 
293  CandidateVisitor * visitor,
294  bool const ignoreExceptions,
295  bool const reset
296  ) const {
297 #if 1
298  //
299  // This const_cast must go!
300  //
301  SpatialCell *mthis = const_cast<SpatialCell *>(this);
302  mthis->visitAllCandidates(visitor, ignoreExceptions, reset);
303 #else
304  int i = 0;
305  for (SpatialCell::const_iterator candidate = (*cell)->begin(false), candidateEnd = (*cell)->end(false);
306  candidate != candidateEnd; ++candidate, ++i) {
307  try {
308  visitor->processCandidate((*candidate).get());
309  } catch(lsst::pex::exceptions::LengthError &e) {
310  if (ignoreExceptions) {
311  ;
312  } else {
313  LSST_EXCEPT_ADD(e, "Visiting candidate");
314  throw e;
315  }
316  }
317  }
318 #endif
319 }
320 
321 /************************************************************************************************************/
324  CandidateList::iterator iterator,
325  CandidateList::iterator end,
326  bool ignoreBad
327  )
328  : _iterator(iterator), _end(end), _ignoreBad(ignoreBad) {
329  for (; _iterator != _end; ++_iterator) {
330  (*_iterator)->instantiate();
331 
332  if (!(_ignoreBad && (*_iterator)->isBad())) { // found a good candidate, or don't care
333  return;
334  }
335  }
336 }
337 
340  CandidateList::iterator,
341  CandidateList::iterator end,
342  bool ignoreBad,
343  bool
344  )
345  : _iterator(end), _end(end), _ignoreBad(ignoreBad) {
346  if (ignoreBad) {
347  // We could decrement end if there are bad Candidates at the end of the list, but it's probably
348  // not worth the trouble
349  }
350 }
351 
356  if (_iterator != _end) {
357  ++_iterator;
358  }
359 
360  for (; _iterator != _end; ++_iterator) {
361  (*_iterator)->instantiate();
362 
363  if (!(_ignoreBad && (*_iterator)->isBad())) { // found a good candidate, or don't care
364  return;
365  }
366  }
367 }
368 
373  size_t n = 0;
374  for (SpatialCellCandidateIterator ptr = rhs; ptr != *this; ++ptr) {
375  if (!(_ignoreBad && (*ptr)->isBad())) { // found a good candidate, or don't care
376  ++n;
377  }
378  }
379 
380  return n;
381 }
382 
389  if (_iterator == _end) {
390  throw LSST_EXCEPT(lsst::pex::exceptions::NotFoundError, "Iterator points to end");
391  }
392 
393  return *_iterator;
394 }
395 
398  if (_iterator == _end) {
399  throw LSST_EXCEPT(lsst::pex::exceptions::NotFoundError, "Iterator points to end");
400  }
401 
402  return *_iterator;
403 }
404 
405 /************************************************************************************************************/
406 
413  int xSize,
414  int ySize
415  ) :
416  _region(region), _cellList(CellList()) {
417  if (ySize == 0) {
418  ySize = xSize;
419  }
420 
421  if (xSize <= 0 || ySize <= 0) {
422  throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
423  (boost::format("Please specify cells that contain pixels, not %dx%d") %
424  xSize % ySize).str());
425  }
426 
427  int nx = region.getWidth()/xSize;
428  if (nx*xSize != region.getWidth()) {
429  nx++;
430  }
431 
432  int ny = region.getHeight()/ySize;
433  if (ny*ySize != region.getHeight()) {
434  ny++;
435  }
436  //
437  // N.b. the SpatialCells will be sorted in y at the end of this
438  //
439  int y0 = region.getMinY();
440  for (int y = 0; y < ny; ++y) {
441  // ny may not be a factor of height
442  int const y1 = (y == ny - 1) ? region.getMaxY() : y0 + ySize - 1;
443  int x0 = region.getMinX();
444  for (int x = 0; x < nx; ++x) {
445  // nx may not be a factor of width
446  int const x1 = (x == nx - 1) ? region.getMaxX() : x0 + xSize - 1;
447  geom::Box2I bbox(geom::Point2I(x0, y0), geom::Point2I(x1, y1));
448  std::string label = (boost::format("Cell %dx%d") % x % y).str();
449 
450  _cellList.push_back(SpatialCell::Ptr(new SpatialCell(label, bbox)));
451 
452  x0 = x1 + 1;
453  }
454  y0 = y1 + 1;
455  }
456 }
457 
458 /************************************************************************************************************/
459 
460 namespace {
461  struct CellContains : public std::unary_function<SpatialCell::Ptr,
462  bool> {
463  CellContains(SpatialCellCandidate::Ptr candidate) : _candidate(candidate) {}
464 
465  bool operator()(SpatialCell::Ptr cell) {
466  return cell->getBBox().contains(geom::Point2I(image::positionToIndex(_candidate->getXCenter()),
467  image::positionToIndex(_candidate->getYCenter())));
468  }
469  private:
471  };
472 }
473 
478  CellList::iterator pos = std::find_if(_cellList.begin(), _cellList.end(), CellContains(candidate));
479 
480  if (pos == _cellList.end()) {
481  throw LSST_EXCEPT(lsst::pex::exceptions::OutOfRangeError,
482  (boost::format("Unable to insert a candidate at (%.2f, %.2f)") %
483  candidate->getXCenter() % candidate->getYCenter()).str());
484  }
485 
486  (*pos)->insertCandidate(candidate);
487 }
488 
489 
490 /************************************************************************************************************/
495 {
496  for (CellList::iterator cell = _cellList.begin(), end = _cellList.end(); cell != end; ++cell) {
497  (*cell)->sortCandidates();
498  }
499 }
500 
501 /************************************************************************************************************/
510  CandidateVisitor *visitor,
511  int const nMaxPerCell,
512  bool const ignoreExceptions
513  ) {
514  visitor->reset();
515 
516  for (CellList::iterator cell = _cellList.begin(), end = _cellList.end(); cell != end; ++cell) {
517  (*cell)->visitCandidates(visitor, nMaxPerCell, ignoreExceptions, false);
518  }
519 }
520 
527  CandidateVisitor *visitor,
528  int const nMaxPerCell,
529  bool const ignoreExceptions
530  ) const {
531  visitor->reset();
532 
533  for (CellList::const_iterator cell = _cellList.begin(), end = _cellList.end(); cell != end; ++cell) {
534  SpatialCell const *ccell = cell->get(); // the SpatialCellSet's SpatialCells should be const too
535  ccell->visitCandidates(visitor, nMaxPerCell, ignoreExceptions, false);
536  }
537 }
538 
539 /************************************************************************************************************/
546  CandidateVisitor *visitor,
547  bool const ignoreExceptions
548  ) {
549  visitor->reset();
550 
551  for (CellList::iterator cell = _cellList.begin(), end = _cellList.end(); cell != end; ++cell) {
552  (*cell)->visitAllCandidates(visitor, ignoreExceptions, false);
553  }
554 }
555 
562  CandidateVisitor *visitor,
563  bool const ignoreExceptions
564  ) const {
565  visitor->reset();
566 
567  for (CellList::const_iterator cell = _cellList.begin(), end = _cellList.end(); cell != end; ++cell) {
568  SpatialCell const *ccell = cell->get(); // the SpatialCellSet's SpatialCells should be const too
569  ccell->visitAllCandidates(visitor, ignoreExceptions, false);
570  }
571 }
572 
573 /************************************************************************************************************/
581  bool noThrow
582  ) {
583  for (CellList::iterator cell = _cellList.begin(), end = _cellList.end(); cell != end; ++cell) {
584  SpatialCellCandidate::Ptr cand = (*cell)->getCandidateById(id, true);
585 
586  if (cand) {
587  return cand;
588  }
589  }
590 
591  if (noThrow) {
592  return SpatialCellCandidate::Ptr();
593  } else {
594  throw LSST_EXCEPT(lsst::pex::exceptions::NotFoundError,
595  (boost::format("Unable to find object with ID == %d") % id).str());
596  }
597 }
598 
600 void SpatialCellSet::setIgnoreBad(bool ignoreBad) {
601  for (CellList::iterator cell = _cellList.begin(), end = _cellList.end(); cell != end; ++cell) {
602  (*cell)->setIgnoreBad(ignoreBad);
603  }
604 }
605 
606 }}}
int y
void setStatus(Status status)
Set the candidate&#39;s status.
Definition: SpatialCell.cc:61
int getMaxY() const
Definition: Box.h:129
void visitAllCandidates(CandidateVisitor *visitor, bool const ignoreExceptions=false, bool const reset=true)
Definition: SpatialCell.cc:260
void insertCandidate(boost::shared_ptr< SpatialCellCandidate > candidate)
Definition: SpatialCell.cc:477
A set of classes of general utility in connection with images.
#define LOGL_DEBUG(logger, message...)
Definition: Log.h:513
SpatialCellCandidateIterator end()
Definition: SpatialCell.h:325
int positionToIndex(double pos)
Convert image position to nearest integer index.
Definition: ImageUtils.h:69
SpatialCellSet(lsst::afw::geom::Box2I const &region, int xSize, int ySize=0)
Definition: SpatialCell.cc:412
std::shared_ptr< const SpatialCellCandidate > ConstPtr
Definition: SpatialCell.h:77
std::vector< boost::shared_ptr< SpatialCell > > CellList
Definition: SpatialCell.h:383
size_t operator-(SpatialCellCandidateIterator const &rhs) const
Definition: SpatialCell.cc:372
static int _CandidateId
Unique identifier for candidates; useful for preserving current candidate following insertion...
Definition: SpatialCell.h:123
std::shared_ptr< SpatialCellCandidate > Ptr
Definition: SpatialCell.h:76
void setIgnoreBad(bool ignoreBad)
Set whether we should omit BAD candidates from candidate list when traversing.
Definition: SpatialCell.cc:600
SpatialCellCandidateIterator(CandidateList::iterator iterator, CandidateList::iterator end, bool ignoreBad)
ctor; designed to be used to pass begin to SpatialCellCandidateIterator
Definition: SpatialCell.cc:323
virtual void processCandidate(SpatialCellCandidate *)
Definition: SpatialCell.h:67
SpatialCellCandidate::Ptr _candidate
Definition: SpatialCell.cc:470
int const x0
Definition: saturated.cc:45
Image utility functions.
An integer coordinate rectangle.
Definition: Box.h:53
table::Key< table::Array< Kernel::Pixel > > image
Definition: FixedKernel.cc:117
boost::shared_ptr< SpatialCellCandidate > getCandidateById(int id, bool noThrow=false)
Definition: SpatialCell.cc:158
boost::shared_ptr< SpatialCellCandidate > getCandidateById(int id, bool noThrow=false)
Definition: SpatialCell.cc:580
std::vector< boost::shared_ptr< SpatialCellCandidate > > CandidateList
Definition: SpatialCell.h:294
void removeCandidate(boost::shared_ptr< SpatialCellCandidate > candidate)
Definition: SpatialCell.cc:113
SpatialCell(std::string const &label, lsst::afw::geom::Box2I const &bbox=lsst::afw::geom::Box2I(), CandidateList const &candidateList=CandidateList())
Definition: SpatialCell.cc:80
int getMinY() const
Definition: Box.h:125
geom::Box2I const & _bbox
Definition: fits_io_mpl.h:80
boost::shared_ptr< SpatialCellCandidate const > operator*() const
Definition: SpatialCell.cc:388
void visitCandidates(CandidateVisitor *visitor, int const nMaxPerCell=-1, bool const ignoreExceptions=false, bool const reset=true)
Definition: SpatialCell.cc:182
int getMinX() const
Definition: Box.h:124
double x
int getWidth() const
Definition: Box.h:154
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
std::shared_ptr< SpatialCell > Ptr
Definition: SpatialCell.h:292
int getHeight() const
Definition: Box.h:155
int status
Class to ensure constraints for spatial modeling.
Definition: SpatialCell.h:290
int id
Definition: CR.cc:157
Class to ensure constraints for spatial modeling.
afw::table::Key< double > b
void visitAllCandidates(CandidateVisitor *visitor, bool const ignoreExceptions=false)
Definition: SpatialCell.cc:545
int getMaxX() const
Definition: Box.h:128
int const y0
Definition: saturated.cc:45
#define LSST_EXCEPT_ADD(e, m)
Definition: Exception.h:51
void visitCandidates(CandidateVisitor *visitor, int const nMaxPerCell=-1, bool const ignoreExceptions=false)
Definition: SpatialCell.cc:509
void insertCandidate(boost::shared_ptr< SpatialCellCandidate > candidate)
Definition: SpatialCell.cc:107
SpatialCellCandidateIterator begin()
Definition: SpatialCell.h:315
An iterator that only returns usable members of the SpatialCell.
Definition: SpatialCell.h:247