lsst.ip.diffim  13.0-28-gf4bc96c+3
KernelSumVisitor.cc
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
11 #include <limits>
12 
13 #include "lsst/afw/math.h"
14 #include "lsst/log/Log.h"
15 #include "lsst/pex/policy/Policy.h"
16 #include "lsst/pex/exceptions/Runtime.h"
17 
20 
21 namespace afwMath = lsst::afw::math;
22 namespace pexPolicy = lsst::pex::policy;
23 namespace pexExcept = lsst::pex::exceptions;
24 
25 namespace lsst {
26 namespace ip {
27 namespace diffim {
28 namespace detail {
29 
64  template<typename PixelT>
66  lsst::pex::policy::Policy const& policy
67  ) :
68  afwMath::CandidateVisitor(),
69  _mode(AGGREGATE),
70  _kSums(std::vector<double>()),
71  _kSumMean(0.),
72  _kSumStd(0.),
73  _dkSumMax(0.),
74  _kSumNpts(0),
75  _nRejected(0),
76  _policy(policy)
77  {};
78 
79  template<typename PixelT>
81  _kSums.clear();
82  _kSumMean = 0.;
83  _kSumStd = 0.;
84  _dkSumMax = 0.;
85  _kSumNpts = 0;
86  _nRejected = 0;
87  }
88 
89  template<typename PixelT>
90  void KernelSumVisitor<PixelT>::processCandidate(lsst::afw::math::SpatialCellCandidate
91  *candidate) {
92 
93  KernelCandidate<PixelT> *kCandidate = dynamic_cast<KernelCandidate<PixelT> *>(candidate);
94  if (kCandidate == NULL) {
95  throw LSST_EXCEPT(pexExcept::LogicError,
96  "Failed to cast SpatialCellCandidate to KernelCandidate");
97  }
98  LOGL_DEBUG("TRACE5.ip.diffim.KernelSumVisitor.processCandidate",
99  "Processing candidate %d, mode %d", kCandidate->getId(), _mode);
100 
101  /* Grab all kernel sums and look for outliers */
102  if (_mode == AGGREGATE) {
103  _kSums.push_back(kCandidate->getKernelSolution(KernelCandidate<PixelT>::ORIG)->getKsum());
104  }
105  else if (_mode == REJECT) {
106  if (_policy.getBool("kernelSumClipping")) {
107  double kSum =
108  kCandidate->getKernelSolution(KernelCandidate<PixelT>::ORIG)->getKsum();
109 
110  if (fabs(kSum - _kSumMean) > _dkSumMax) {
111  kCandidate->setStatus(afwMath::SpatialCellCandidate::BAD);
112  LOGL_DEBUG("TRACE3.ip.diffim.KernelSumVisitor.processCandidate",
113  "Rejecting candidate %d; bad source kernel sum : (%.2f)",
114  kCandidate->getId(),
115  kSum);
116  _nRejected += 1;
117  }
118  }
119  else {
120  LOGL_DEBUG("TRACE5.ip.diffim.KernelSumVisitor.processCandidate",
121  "Sigma clipping not enabled");
122  }
123  }
124  }
125 
126  template<typename PixelT>
128  if (_kSums.size() == 0) {
129  throw LSST_EXCEPT(pexExcept::Exception,
130  "Unable to determine kernel sum; 0 candidates");
131  }
132  else if (_kSums.size() == 1) {
133  LOGL_DEBUG("TRACE1.ip.diffim.KernelSumVisitor.processKsumDistribution",
134  "WARNING: only 1 kernel candidate");
135 
136  _kSumMean = _kSums[0];
137  _kSumStd = 0.0;
138  _kSumNpts = 1;
139  }
140  else {
141  try {
142  afwMath::Statistics stats = afwMath::makeStatistics(_kSums,
143  afwMath::NPOINT |
144  afwMath::MEANCLIP |
145  afwMath::STDEVCLIP);
146  _kSumMean = stats.getValue(afwMath::MEANCLIP);
147  _kSumStd = stats.getValue(afwMath::STDEVCLIP);
148  _kSumNpts = static_cast<int>(stats.getValue(afwMath::NPOINT));
149  } catch (pexExcept::Exception &e) {
150  LSST_EXCEPT_ADD(e, "Unable to calculate kernel sum statistics");
151  throw e;
152  }
153  if (std::isnan(_kSumMean)) {
154  throw LSST_EXCEPT(pexExcept::Exception,
155  str(boost::format("Mean kernel sum returns NaN (%d points)")
156  % _kSumNpts));
157  }
158  if (std::isnan(_kSumStd)) {
159  throw LSST_EXCEPT(pexExcept::Exception,
160  str(boost::format("Kernel sum stdev returns NaN (%d points)")
161  % _kSumNpts));
162  }
163  }
164  _dkSumMax = _policy.getDouble("maxKsumSigma") * _kSumStd;
165  LOGL_DEBUG("TRACE1.ip.diffim.KernelSumVisitor.processCandidate",
166  "Kernel Sum Distribution : %.3f +/- %.3f (%d points)",
168  }
169 
170  typedef float PixelT;
171 
172  template class KernelSumVisitor<PixelT>;
173 
174  template std::shared_ptr<KernelSumVisitor<PixelT> >
175  makeKernelSumVisitor<PixelT>(lsst::pex::policy::Policy const&);
176 
177 }}}} // end of namespace lsst::ip::diffim::detail
int _kSumNpts
Number of points used in the statistics.
Mode _mode
Processing mode; AGGREGATE or REJECT.
Class stored in SpatialCells for spatial Kernel fitting.
Declaration of KernelSumVisitor.
std::shared_ptr< StaticKernelSolution< PixelT > > getKernelSolution(CandidateSwitch cand) const
STL namespace.
double _kSumMean
Clipped mean of the kernel sums.
A class to accumulate kernel sums across SpatialCells.
void processCandidate(lsst::afw::math::SpatialCellCandidate *candidate)
double _dkSumMax
Maximum acceptable deviation from mean sum.
Class used by SpatialModelCell for spatial Kernel fitting.
double _kSumStd
Clipped standard deviation of kernel sums.
template std::shared_ptr< KernelSumVisitor< PixelT > > makeKernelSumVisitor< PixelT >(lsst::pex::policy::Policy const &)
std::vector< double > _kSums
List of all candidate kernel sums.
KernelSumVisitor(lsst::pex::policy::Policy const &policy)
int _nRejected
Number of candidates rejected during processCandidate()
lsst::pex::policy::Policy _policy
Policy controlling behavior.