28 #include <boost/math/tools/minima.hpp>
63 size_t nval = chi2List.
size();
64 if (nval == 0)
return 0;
66 double median = (nval & 1) ? chi2List[nval / 2].chi2
67 : 0.5 * (chi2List[nval / 2 - 1].chi2 + chi2List[nval / 2].chi2);
69 LOGLS_DEBUG(
_log,
"findOutliers chi2 stat: mean/median/sigma " << averageAndSigma.first <<
'/' << median
70 <<
'/' << averageAndSigma.second);
71 double cut = averageAndSigma.first + nSigmaCut * averageAndSigma.second;
77 Eigen::VectorXi affectedParams(
_nParTot);
78 affectedParams.setZero();
82 for (
auto chi2 = chi2List.
rbegin(); chi2 != chi2List.
rend(); ++chi2) {
83 if (chi2->chi2 < cut)
break;
88 auto measuredStar = std::dynamic_pointer_cast<MeasuredStar>(chi2->star);
90 if (measuredStar ==
nullptr) {
92 fittedStar = std::dynamic_pointer_cast<FittedStar>(chi2->star);
93 if (fittedStar->getMeasurementCount() == 0) {
94 LOGLS_WARN(
_log,
"FittedStar with no measuredStars found as an outlier: " << *fittedStar);
99 indices.
push_back(fittedStar->getIndexInMatrix());
100 LOGLS_TRACE(
_log,
"Removing refStar " << *(fittedStar->getRefStar()) <<
" chi2: " << chi2->chi2);
105 auto tempFittedStar = measuredStar->getFittedStar();
106 if (tempFittedStar->getMeasurementCount() == 1 && tempFittedStar->getRefStar() ==
nullptr) {
107 LOGLS_WARN(
_log,
"FittedStar with 1 measuredStar and no refStar found as an outlier: "
112 LOGLS_TRACE(
_log,
"Removing measStar " << *measuredStar <<
" chi2: " << chi2->chi2);
120 for (
auto const &i : indices) {
121 if (affectedParams(i) != 0) {
128 if (measuredStar ==
nullptr) {
136 for (
auto const &i : indices) {
142 LOGLS_INFO(
_log,
"findOutliers: found " << msOutliers.
size() <<
" meas outliers and " << fsOutliers.
size()
143 <<
" ref outliers ");
152 jacobian.setFromTriplets(tripletList.
begin(), tripletList.
end());
153 return jacobian * jacobian.transpose();
157 void dumpMatrixAndGradient(
SparseMatrixD const &matrix, Eigen::VectorXd
const &grad,
160 Eigen::MatrixXd matrixDense(matrix);
161 std::string dumpMatrixPath = dumpFile +
"-mat" + ext;
164 std::string dumpGradPath = dumpFile +
"-grad" + ext;
167 LOGLS_INFO(_log,
"Dumped Hessian, gradient to: '" << dumpMatrixPath <<
"', '" << dumpGradPath <<
"'");
172 bool const doLineSearch,
std::string const &dumpMatrixFile) {
194 << hessian.rows() <<
" non-zeros=" << hessian.nonZeros()
195 <<
" filling-frac = " << hessian.nonZeros() /
std::pow(hessian.rows(), 2));
197 if (dumpMatrixFile !=
"") {
198 if (hessian.rows() * hessian.cols() > 2e8) {
199 LOGLS_WARN(
_log,
"Hessian matrix is too big to dump to file, with rows, columns: "
200 << hessian.rows() <<
", " << hessian.cols());
202 dumpMatrixAndGradient(hessian, grad, dumpMatrixFile,
_log);
207 if (chol.info() != Eigen::Success) {
217 Eigen::VectorXd delta = chol.solve(grad);
219 scale = _lineSearch(delta);
225 LOGL_ERROR(
_log,
"chi2 is not finite. Aborting outlier rejection.");
229 if (currentChi2.
chi2 > oldChi2 && totalMeasOutliers + totalRefOutliers != 0) {
230 LOGL_WARN(
_log,
"chi2 went up, skipping outlier rejection loop");
234 oldChi2 = currentChi2.
chi2;
236 if (nSigmaCut == 0)
break;
241 totalMeasOutliers += msOutliers.
size();
242 totalRefOutliers += fsOutliers.
size();
243 if (nOutliers == 0)
break;
254 H.setFromTriplets(outlierTriplets.
begin(), outlierTriplets.
end());
268 hessian = createHessian(
_nParTot, nextTripletList);
269 nextTripletList.
clear();
272 "Restarting factorization, hessian: dim="
273 << hessian.rows() <<
" non-zeros=" << hessian.nonZeros()
274 <<
" filling-frac = " << hessian.nonZeros() /
std::pow(hessian.rows(), 2));
275 chol.compute(hessian);
276 if (chol.info() != Eigen::Success) {
284 if (nSigmaCut != 0) {
285 LOGLS_INFO(
_log,
"Number of outliers (Measured + Reference = Total): "
286 << totalMeasOutliers <<
" + " << totalRefOutliers <<
" = "
287 << totalMeasOutliers + totalRefOutliers);
294 for (
auto &outlier : msOutliers) {
297 const CcdImage &ccdImage = outlier->getCcdImage();
304 for (
auto &measuredStar : outliers) {
305 auto fittedStar = measuredStar->getFittedStar();
306 measuredStar->setValid(
false);
307 fittedStar->getMeasurementCount()--;
312 for (
auto &fittedStar : outliers) {
313 fittedStar->setRefStar(
nullptr);
319 for (
auto const &ccdImage : ccdImageList) {
327 auto pos = baseName.
find(replaceStr);
329 measFilename.
replace(pos, replaceStr.
size(),
"-meas.csv");
331 refFilename.
replace(pos, replaceStr.
size(),
"-ref.csv");
336 double FitterBase::_lineSearch(Eigen::VectorXd
const &delta) {
337 auto func = [
this, &delta](
double scale) {
338 auto offset =
scale * delta;
347 auto result = boost::math::tools::brent_find_minima(func, -1.0, 2.0, bits);
Eigen::SparseMatrix< double, 0, Eigen::Index > SparseMatrixD
LSST DM logging module built on log4cxx.
#define LOGLS_WARN(logger, message)
Log a warn-level message using an iostream-based interface.
#define LOGL_WARN(logger, message...)
Log a warn-level message using a varargs/printf style interface.
#define LOGLS_INFO(logger, message)
Log a info-level message using an iostream-based interface.
#define LOGLS_ERROR(logger, message)
Log a error-level message using an iostream-based interface.
#define LOGL_ERROR(logger, message...)
Log a error-level message using a varargs/printf style interface.
#define LOGLS_DEBUG(logger, message)
Log a debug-level message using an iostream-based interface.
#define LOGLS_TRACE(logger, message)
Log a trace-level message using an iostream-based interface.
void update(SparseMatrixD const &H, bool UpOrDown)
Handler of an actual image from a single CCD.
Structure to accumulate the chi2 contributions per each star (to help find outliers).
std::pair< double, double > computeAverageAndSigma()
Compute the average and std-deviation of these chisq values.
Simple structure to accumulate chi2 and ndof.
A list of FittedStar s. Such a list is typically constructed by Associations.
void leastSquareDerivatives(TripletList &tripletList, Eigen::VectorXd &grad) const
Evaluates the chI^2 derivatives (Jacobian and gradient) for the current whatToFit setting.
void removeRefOutliers(FittedStarList &outliers)
Remove refStar outliers from the fit. No Refit done.
virtual void getIndicesOfMeasuredStar(MeasuredStar const &measuredStar, IndexVector &indices) const =0
Set the indices of a measured star from the full matrix, for outlier removal.
Chi2Statistic computeChi2() const
Returns the chi2 for the current state.
virtual void saveChi2MeasContributions(std::string const &filename) const =0
Save a CSV file containing residuals of measurement terms.
virtual void leastSquareDerivativesReference(FittedStarList const &fittedStarList, TripletList &tripletList, Eigen::VectorXd &grad) const =0
Compute the derivatives of the reference terms.
MinimizeResult minimize(std::string const &whatToFit, double const nSigmaCut=0, bool const doRankUpdate=true, bool const doLineSearch=false, std::string const &dumpMatrixFile="")
Does a 1 step minimization, assuming a linear model.
virtual void saveChi2Contributions(std::string const &baseName) const
Save the full chi2 term per star that was used in the minimization, for debugging.
Eigen::Index _nMeasuredStars
virtual void assignIndices(std::string const &whatToFit)=0
Set parameters to fit and assign indices in the big matrix.
virtual void offsetParams(Eigen::VectorXd const &delta)=0
Offset the parameters by the requested quantities.
std::shared_ptr< Associations > _associations
virtual void accumulateStatRefStars(Chi2Accumulator &accum) const =0
Compute the chi2 (per star or total, depending on which Chi2Accumulator is used) for RefStars.
std::size_t findOutliers(double nSigmaCut, MeasuredStarList &msOutliers, FittedStarList &fsOutliers) const
Find Measurements and references contributing more than a cut, computed as.
virtual void saveChi2RefContributions(std::string const &filename) const =0
Save a CSV file containing residuals of reference terms.
virtual void leastSquareDerivativesMeasurement(CcdImage const &ccdImage, TripletList &tripletList, Eigen::VectorXd &grad, MeasuredStarList const *measuredStarList=nullptr) const =0
Compute the derivatives of the measured stars and model for one CcdImage.
void outliersContributions(MeasuredStarList &msOutliers, FittedStarList &fsOutliers, TripletList &tripletList, Eigen::VectorXd &grad)
Contributions to derivatives from (presumably) outlier terms.
virtual void accumulateStatImageList(CcdImageList const &ccdImageList, Chi2Accumulator &accum) const =0
Compute the chi2 (per star or total, depending on which Chi2Accumulator is used) for measurements.
void removeMeasOutliers(MeasuredStarList &outliers)
Remove measuredStar outliers from the fit. No Refit done.
A list of MeasuredStar. They are usually filled in Associations::createCcdImage.
Eigen::Index getNextFreeIndex() const
def scale(algorithm, min, max=None, frame=None)
MinimizeResult
Return value of minimize()
A base class for image defects.