diff --git a/python/lsst/pipe/tasks/maskStreaks.py b/python/lsst/pipe/tasks/maskStreaks.py index 9cf75fee0f..7a0f7ce9b8 100644 --- a/python/lsst/pipe/tasks/maskStreaks.py +++ b/python/lsst/pipe/tasks/maskStreaks.py @@ -359,7 +359,7 @@ def _lineChi2(self, line, grad=True): reducedHessianChi = hessianChi2 / self.lineMaskSize return reducedChi, reducedDChi, reducedHessianChi - def fit(self, dChi2Tol=0.1, maxIter=100): + def fit(self, dChi2Tol=0.1, maxIter=100, log=None): """Perform Newton-Raphson minimization to find line parameters. This method takes advantage of having known derivative and Hessian of @@ -378,6 +378,7 @@ def fit(self, dChi2Tol=0.1, maxIter=100): Maximum number of fit iterations allowed. The fit should converge in ~10 iterations, depending on the value of dChi2Tol, but this maximum provides a backup. + log : TODO Returns ------- @@ -407,14 +408,17 @@ def line_search(c, dx): if chi2 == 0: break if not np.isfinite(A).all(): - # TODO: DM-30797 Add warning here. fitFailure = True + if log is not None: + log.warning("Hessian matrix has non-finite elements.") break dChi2 = oldChi2 - chi2 try: cholesky = scipy.linalg.cho_factor(A) except np.linalg.LinAlgError: fitFailure = True + if log is not None: + log.warning("Hessian matrix is not invertible.") break dx = scipy.linalg.cho_solve(cholesky, b) @@ -651,6 +655,7 @@ def _runKHT(self, image): self.config.clusterMinimumDeviation, self.config.delta, self.config.minimumKernelHeight, self.config.nSigma, self.config.absMinimumKernelHeight) + self.log.info("The Kernel Hough Transform detected %s line(s)", len(lines)) return LineCollection(lines.rho, lines.theta) @@ -701,6 +706,7 @@ def _findClusters(self, lines): finalRhos = finalClusters[0] * self.config.rhoBinSize finalThetas = finalClusters[1] * self.config.thetaBinSize result = LineCollection(finalRhos, finalThetas) + self.log.info("Lines were grouped into %s potential streak(s)", len(finalRhos)) return result @@ -732,6 +738,7 @@ def _fitProfile(self, lines, maskedImage): lineFits = LineCollection([], []) finalLineMasks = [np.zeros(data.shape, dtype=bool)] + nFinalLines = 0 for line in lines: line.sigma = self.config.invSigma**-1 lineModel = LineProfile(data, weights, line=line) @@ -739,17 +746,23 @@ def _fitProfile(self, lines, maskedImage): if lineModel.lineMaskSize == 0: continue - fit, chi2, fitFailure = lineModel.fit(dChi2Tol=self.config.dChi2Tolerance) + fit, chi2, fitFailure = lineModel.fit(dChi2Tol=self.config.dChi2Tolerance, log=self.log) + if fitFailure: + self.log.warning("Streak fit failed.") # Initial estimate should be quite close: fit is deemed unsuccessful if rho or theta # change more than the allowed bin in rho or theta: if ((abs(fit.rho - line.rho) > 2 * self.config.rhoBinSize) or (abs(fit.theta - line.theta) > 2 * self.config.thetaBinSize)): fitFailure = True + self.log.warning("Streak fit moved too far from initial estimate. Line will be dropped.") if fitFailure: continue + self.log.debug("Best fit streak parameters are rho=%.2f, theta=%.2f, and sigma=%.2f", fit.rho, + fit.theta, fit.sigma) + # Make mask lineModel.setLineMask(fit) finalModel = lineModel.makeProfile(fit) @@ -763,7 +776,12 @@ def _fitProfile(self, lines, maskedImage): fit.finalModelMax = finalModelMax lineFits.append(fit) finalLineMasks.append(finalLineMask) + nFinalLines += 1 finalMask = np.array(finalLineMasks).any(axis=0) + nMaskedPixels = finalMask.sum() + percentMasked = (nMaskedPixels / finalMask.size) * 100 + self.log.info("%d streak(s) fit, with %d pixels masked (%0.2f%% of image)", nFinalLines, nMaskedPixels, + percentMasked) return lineFits, finalMask