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