35 # include "Minuit2/FCNBase.h"
36 # include "Minuit2/FunctionMinimum.h"
37 # include "Minuit2/MnMigrad.h"
38 # include "Minuit2/MnMinos.h"
39 # include "Minuit2/MnPrint.h"
43 #include "Eigen/Cholesky"
55 namespace afwDetection = lsst::afw::detection;
56 namespace afwGeom = lsst::afw::geom;
58 namespace afwMath = lsst::afw::math;
62 namespace algorithms {
66 int const WARP_BUFFER(1);
67 std::string
const WARP_ALGORITHM(
"lanczos5");
71 template<
typename PixelT>
77 explicit SetPcaImageVisitor(
78 PsfImagePca<MaskedImageT> *imagePca,
79 unsigned int const mask=0
x0
81 afwMath::CandidateVisitor(),
89 PsfCandidate<PixelT> *imCandidate =
dynamic_cast<PsfCandidate<PixelT> *
>(candidate);
90 if (imCandidate == NULL) {
91 throw LSST_EXCEPT(lsst::pex::exceptions::LogicError,
92 "Failed to cast SpatialCellCandidate to PsfCandidate");
109 throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError,
111 % imCandidate->getXCenter() % imCandidate->getYCenter()));
116 throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError,
117 str(
boost::format(
"Variance of Image at %d, %d contains NaN")
118 % imCandidate->getXCenter() % imCandidate->getYCenter()));
121 _imagePca->addImage(im, imCandidate->getSource()->getPsfFlux());
122 }
catch(lsst::pex::exceptions::LengthError &) {
132 template<
typename PixelT>
145 PsfCandidate<PixelT> *imCandidate =
dynamic_cast<PsfCandidate<PixelT> *
>(candidate);
146 if (imCandidate == NULL) {
147 throw LSST_EXCEPT(lsst::pex::exceptions::LogicError,
148 "Failed to cast SpatialCellCandidate to PsfCandidate");
152 imCandidate->getMaskedImage();
153 }
catch(lsst::pex::exceptions::LengthError &) {
161 double getN()
const {
return _n; }
172 template<
typename ImageT>
173 std::vector<typename ImageT::Ptr> offsetKernel(
179 unsigned int const nKernel = kernels.size();
180 std::vector<typename ImageT::Ptr> kernelImages(nKernel);
182 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
183 "Kernel has no components");
187 for (
unsigned int i = 0; i != nKernel; ++i) {
188 kernels[i]->computeImage(scratch,
false);
205 template<
typename PixelT>
210 int const nEigenComponents,
211 int const spatialOrder,
213 int const nStarPerCell,
214 bool const constantWeight,
236 SetPcaImageVisitor<PixelT> importStarVisitor(&imagePca);
237 bool const ignoreExceptions =
true;
238 psfCells.
visitCandidates(&importStarVisitor, nStarPerCell, ignoreExceptions);
247 double deltaLim = 10.0;
252 for (
int i = 0; i != niter; ++i) {
253 int const ncomp = (i == 0) ? 0 :
254 ((nEigenComponents == 0) ? imagePca.
getEigenImages().size() : nEigenComponents);
256 if (i > 0 && delta < deltaLim) {
263 std::vector<typename MaskedImageT::Ptr> eigenImages = imagePca.
getEigenImages();
265 int const nEigen =
static_cast<int>(eigenValues.size());
267 int const ncomp = (nEigenComponents <= 0 || nEigen < nEigenComponents) ? nEigen : nEigenComponents;
273 for (
int k = 0; k != ncomp; ++k) {
274 ImageT
const& im = *eigenImages[k]->getImage();
277 if (bkg_border > im.getWidth()) {
278 bkg_border = im.getWidth() / 2;
280 if (bkg_border > im.getHeight()) {
281 bkg_border = im.getHeight() / 2;
286 for (
int i = 0; i != bkg_border; ++i) {
287 typename ImageT::const_x_iterator
288 ptrB = im.row_begin(i), ptrT = im.row_begin(im.getHeight() - i - 1);
289 for (
int j = 0; j != im.getWidth(); ++j, ++ptrB, ++ptrT) {
290 sum += *ptrB + *ptrT;
293 for (
int i = bkg_border; i < im.getHeight() - bkg_border; ++i) {
295 typename ImageT::const_x_iterator
296 ptrL = im.row_begin(i), ptrR = im.row_begin(i) + im.getWidth() - bkg_border;
297 for (
int j = 0; j != bkg_border; ++j, ++ptrL, ++ptrR) {
298 sum += *ptrL + *ptrR;
301 sum /= 2*(bkg_border*im.getWidth() + bkg_border*(im.getHeight() - 2*bkg_border));
303 *eigenImages[k] -=
sum;
310 std::vector<afwMath::Kernel::SpatialFunctionPtr> spatialFunctionList;
313 for (
int i = 0; i != ncomp; ++i) {
318 ImageT&
image = *eigenImages[i]->getImage();
319 double sum = std::accumulate(image.begin(
true), image.end(
true), 0.0);
323 for (
typename ImageT::fast_iterator ptr0 = eigenImages[0]->getImage()->begin(
true),
324 ptr1 = image.begin(
true), end = image.end(
true); ptr1 != end; ++ptr0, ++ptr1) {
325 *ptr1 = *ptr1 / sum - *ptr0;
337 spatialFunction->setParameter(0, 1.0);
338 spatialFunctionList.push_back(spatialFunction);
344 return std::make_pair(psf, eigenValues);
351 template<
typename PixelT>
353 int const nStarPerCell)
355 countVisitor<PixelT> counter;
358 return counter.getN();
368 template<
typename ModelImageT,
typename DataImageT>
369 std::pair<double, double>
370 fitKernel(ModelImageT
const& mImage,
371 DataImageT
const& data,
373 bool detected =
true,
376 assert(data.getDimensions() == mImage.getDimensions());
381 double sumMM = 0.0, sumMD = 0.0, sumDD = 0.0;
383 for (
int y = 0;
y != data.getHeight(); ++
y) {
384 typename ModelImageT::x_iterator mptr = mImage.row_begin(
y);
385 for (
typename DataImageT::x_iterator ptr = data.row_begin(
y), end = data.row_end(
y);
386 ptr != end; ++ptr, ++mptr) {
387 double const m = (*mptr)[0];
388 double const d = ptr.image();
389 double const var = ptr.variance() + lambda*d;
390 if (detected && !(ptr.mask() & DETECTED)) {
393 if (ptr.mask() & BAD) {
397 double const iVar = 1.0/var;
407 throw LSST_EXCEPT(lsst::pex::exceptions::RangeError,
"No good pixels");
410 throw LSST_EXCEPT(lsst::pex::exceptions::RangeError,
"sum(data*data)/var == 0");
413 double const amp = sumMD/sumMM;
414 double const chi2 = (sumDD - 2*amp*sumMD + amp*amp*sumMM)/(npix - 1);
421 int y = data.getHeight()/2;
422 int x = data.getWidth()/2;
425 for (
int ii = -hsize; ii <= hsize; ++ii) {
426 for (
int jj = -hsize; jj <= hsize; ++jj) {
427 printf(
"%7.1f ", data.at(x + jj, y - ii).image());
430 for (
int jj = -hsize; jj <= hsize; ++jj) {
431 printf(
"%7.1f ", amp*(*(mImage.at(x + jj, y - ii)))[0]);
435 printf(
"%g %.1f\n", amp, chi2);
439 return std::make_pair(chi2, amp);
448 template<
typename PixelT>
471 if (imCandidate == NULL) {
472 throw LSST_EXCEPT(lsst::pex::exceptions::LogicError,
473 "Failed to cast SpatialCellCandidate to PsfCandidate");
476 double const xcen = imCandidate->
getSource()->getX();
477 double const ycen = imCandidate->
getSource()->getY();
483 }
catch(lsst::pex::exceptions::LengthError &) {
488 std::pair<double, double> result = fitKernel(*
_kImage, *data,
_lambda,
false,
491 double dchi2 = result.first;
492 double const amp = result.second;
498 }
catch(lsst::pex::exceptions::RangeError &e) {
500 imCandidate->
setChi2(std::numeric_limits<double>::quiet_NaN());
501 imCandidate->
setAmplitude(std::numeric_limits<double>::quiet_NaN());
521 std::vector<double>
const& coeffs
527 assert (nComponents*nSpatialParams == static_cast<long>(coeffs.size()));
529 std::vector<std::vector<double> > kCoeffs;
530 kCoeffs.reserve(nComponents);
531 for (
int i = 0; i != nComponents; ++i) {
532 kCoeffs.push_back(std::vector<double>(nSpatialParams));
533 std::copy(coeffs.begin() + i*nSpatialParams,
534 coeffs.begin() + (i + 1)*nSpatialParams, kCoeffs[i].begin());
545 Eigen::VectorXd
const& vec
551 assert (nComponents*nSpatialParams == vec.size());
553 std::vector<std::vector<double> > kCoeffs;
554 kCoeffs.reserve(nComponents);
555 for (
int i = 0; i != nComponents; ++i) {
556 std::vector<double> spatialCoeffs(nSpatialParams);
557 for (
int j = 0; j != nSpatialParams; ++j) {
558 spatialCoeffs[j] = vec[i*nSpatialParams + j];
560 kCoeffs.push_back(spatialCoeffs);
569 template<
typename PixelT>
619 template<
typename PixelT>
620 std::pair<bool, double>
624 int const nStarPerCell,
625 double const tolerance,
639 std::vector<double> coeffs;
640 coeffs.assign(nComponents*nSpatialParams, 0.0);
642 std::vector<double> stepSize;
643 stepSize.assign(nComponents*nSpatialParams, 100);
647 ROOT::Minuit2::MnUserParameters fitPar;
648 std::vector<std::string> paramNames;
649 paramNames.reserve(nComponents*nSpatialParams);
651 for (
int i = 0, c = 0; c != nComponents; ++c) {
653 for (
int s = 0; s != nSpatialParams; ++s, ++i) {
654 paramNames.push_back((
boost::format(
"C%d:%d") % c % s).str());
655 fitPar.Add(paramNames[i].c_str(), coeffs[i], stepSize[i]);
662 MinimizeChi2<PixelT> minimizerFunc(getChi2, kernel, psfCells, nStarPerCell, nComponents, nSpatialParams);
664 double const errorDef = 1.0;
669 ROOT::Minuit2::MnMigrad migrad(minimizerFunc, fitPar);
674 ROOT::Minuit2::FunctionMinimum min =
675 migrad(maxFnCalls, tolerance/(1e-4*errorDef));
677 float minChi2 = min.Fval();
678 bool const isValid = min.IsValid() &&
std::isfinite(minChi2);
680 if (
true || isValid) {
681 for (
int i = 0; i != nComponents*nSpatialParams; ++i) {
682 coeffs[i] = min.UserState().Value(i);
688 #if 0 // Estimate errors; we don't really need this
689 ROOT::Minuit2::MnMinos minos(minimizerFunc, min);
690 for (
int i = 0, c = 0; c != nComponents; ++c) {
691 for (
int s = 0; s != nSpatialParams; ++s, ++i) {
692 char const *
name = paramNames[i].c_str();
693 printf(
"%s %g", name, min.UserState().Value(name));
694 if (isValid && !fitPar.Parameter(fitPar.Index(name)).IsFixed()) {
695 printf(
" (%g+%g)\n", minos(i).first, minos(i).second);
707 return std::make_pair(isValid, minChi2);
751 template<
typename PixelT>
762 afwMath::CandidateVisitor(),
782 kernels[i]->computeImage(*
_basisImgs[i],
false);
792 PsfCandidate<PixelT>::getBorderWidth());
801 PsfCandidate<PixelT> *imCandidate =
dynamic_cast<PsfCandidate<PixelT> *
>(candidate);
802 if (imCandidate == NULL) {
803 throw LSST_EXCEPT(lsst::pex::exceptions::LogicError,
804 "Failed to cast SpatialCellCandidate to PsfCandidate");
810 }
catch(lsst::pex::exceptions::LengthError &) {
813 double const xcen = imCandidate->getXCenter();
814 double const ycen = imCandidate->getYCenter();
819 double const amp = imCandidate->getAmplitude();
830 std::pair<afwMath::Kernel::Ptr, std::pair<double, double> > ret =
832 double const amp = ret.second.first;
835 double const var = imCandidate->getVar();
836 double const ivar = 1/(var +
_tau2);
844 std::vector<typename KImage::Ptr> basisImages = offsetKernel<KImage>(
_kernel, dx, dy);
848 typename Image::Ptr dataImage(
new Image(*data->getImage(),
true));
851 dPtr != end; ++dPtr, ++bPtr) {
852 *dPtr = *dPtr / amp - *bPtr;
857 PsfCandidate<PixelT>::getBorderWidth());
859 _b(i) += ivar*params[ic][is]*basisDotData;
871 Eigen::MatrixXd
const& getA()
const {
return _A; }
872 Eigen::VectorXd
const& getB()
const {
return _b; }
887 template<
typename PixelT>
894 PsfCandidate<PixelT> *imCandidate =
dynamic_cast<PsfCandidate<PixelT> *
>(candidate);
895 if (imCandidate == NULL) {
896 throw LSST_EXCEPT(lsst::pex::exceptions::LogicError,
897 "Failed to cast SpatialCellCandidate to PsfCandidate");
907 template<
typename PixelT>
908 std::pair<bool, double>
912 bool const doNonLinearFit,
913 int const nStarPerCell,
914 double const tolerance,
918 if (doNonLinearFit) {
919 return fitSpatialKernelFromPsfCandidates<PixelT>(kernel, psfCells, nStarPerCell, tolerance);
922 double const tau = 0;
927 throw LSST_EXCEPT(lsst::pex::exceptions::LogicError,
928 "Failed to cast Kernel to LinearCombinationKernel while building spatial PSF model");
934 setAmplitudeVisitor<PixelT> setAmplitude;
940 FillABVisitor<PixelT> getAB(*lcKernel, tau);
948 Eigen::MatrixXd
const& A = getAB.getA();
949 Eigen::VectorXd
const&
b = getAB.getB();
950 Eigen::VectorXd
x0(b.size());
951 x0 = A.jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(b);
953 std::cout <<
"A " << A << std::endl;
954 std::cout <<
"b " << b.transpose() << std::endl;
955 std::cout <<
"x " << x.transpose() << std::endl;
958 for (
int j = 0; j < b.size(); ++j) {
959 for (
int i = 0; i < b.size(); ++i) {
963 img.writeFits(
"a.fits");
966 for (
int i = 0; i != 6; ++i) {
967 double xcen = 25;
double ycen = 35 + 35*i;
968 std::cout <<
"x, y " << xcen <<
" , " << ycen <<
" b "
969 << (x[3] + xcen*x[4] + ycen*x[5])/(x[0] + xcen*x[1] + ycen*x[2]) << std::endl;
991 return std::make_pair(
true, getChi2.
getValue());
998 template<
typename MaskedImageT>
1007 return std::numeric_limits<double>::quiet_NaN();
1020 typename MaskedImageT::Ptr subData(
new MaskedImageT(*data, bbox,
afwImage::PARENT,
false));
1024 double lambda = 0.0;
1030 std::pair<double, double> result = fitKernel(*kImage, *subData, lambda,
true);
1031 chi2 = result.first;
1032 amp = result.second;
1034 chi2 = std::numeric_limits<double>::quiet_NaN();
1040 typename MaskedImageT::Image::Ptr
1041 kImageF(
new typename MaskedImageT::Image(*kImage,
true));
1044 *subData->getImage() -= *kImageF;
1047 }
catch(lsst::pex::exceptions::RangeError &e) {
1059 template<
typename Image>
1070 int const nKernel = kernels.size();
1073 throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
1074 "Your kernel must have at least one component");
1081 std::vector<KernelT::Ptr> kernelImages = offsetKernel<KernelT>(kernel, pos[0], pos[1]);
1089 Eigen::MatrixXd A(nKernel, nKernel);
1090 Eigen::VectorXd
b(nKernel);
1092 for (
int i = 0; i != nKernel; ++i) {
1095 for (
int j = i; j != nKernel; ++j) {
1099 Eigen::VectorXd
x(nKernel);
1102 x(0) =
b(0)/A(0, 0);
1104 x = A.jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(b);
1108 int const x0 = kernelImages[0]->getX0(),
y0 = kernelImages[0]->getY0();
1111 std::vector<double> params(nKernel);
1112 for (
int i = 0; i != nKernel; ++i) {
1114 newKernel->setCtrX(x0 + static_cast<int>(newKernel->getWidth()/2));
1115 newKernel->setCtrY(
y0 + static_cast<int>(newKernel->getHeight()/2));
1118 newKernels[i] = newKernel;
1121 return std::make_pair(params, newKernels);
1131 template<
typename Image>
1132 std::pair<afwMath::Kernel::Ptr, std::pair<double, double> >
1141 std::vector<double> params = fit.first;
1143 int const nKernel = params.size();
1144 assert(kernels.size() ==
static_cast<unsigned int>(nKernel));
1147 for (
int i = 0; i != nKernel; ++i) {
1150 amp += params[i] * k->getSum();
1155 outputKernel->setCtrX(kernels[0]->getCtrX());
1156 outputKernel->setCtrY(kernels[0]->getCtrY());
1158 return std::make_pair(outputKernel, std::make_pair(amp, chisq));
1167 typedef float Pixel;
1170 std::pair<afwMath::LinearCombinationKernel::Ptr, std::vector<double> >
1173 int const,
bool const,
int const);
1178 std::pair<bool, double>
1180 int const,
double const,
double const);
1182 std::pair<bool, double>
1184 int const,
double const,
double const);
1195 std::pair<afwMath::Kernel::Ptr, std::pair<double, double> >
afwImage::MaskedImage< PixelT > MaskedImage
2-dimensional weighted sum of Chebyshev polynomials of the first kind.
Class for doing PCA on PSF stars.
boost::shared_ptr< lsst::afw::math::Function2< double > > SpatialFunctionPtr
Class used by SpatialCell for spatial PSF fittig.
void setStatus(Status status)
Set the candidate's status.
A coordinate class intended to represent absolute positions.
void setAmplitude(double amplitude)
Set the best-fit amplitude.
geom::Extent2I const getDimensions() const
Return the Kernel's dimensions (width, height)
std::vector< double > const & getEigenValues() const
Return Eigen values.
afwImage::Exposure< PixelT > Exposure
table::Key< std::string > name
void setErrorDef(double def)
afwImage::Image< afwMath::Kernel::Pixel > KImage
int positionToIndex(double pos)
Convert image position to nearest integer index.
std::vector< typename KImage::Ptr > _basisImgs
void processCandidate(afwMath::SpatialCellCandidate *candidate)
int countPsfCandidates(lsst::afw::math::SpatialCellSet const &psfCells, int const nStarPerCell=-1)
boost::shared_ptr< afw::table::SourceRecord > getSource() const
Return the original Source.
A class to contain the data, WCS, and other information needed to describe an image of the sky...
A coordinate class intended to represent offsets and dimensions.
boost::uint16_t MaskPixel
double innerProduct(Image1T const &lhs, Image2T const &rhs, int const border=0)
double subtractPsf(lsst::afw::detection::Psf const &psf, ImageT *data, double x, double y, double psfFlux=std::numeric_limits< double >::quiet_NaN())
MinimizeChi2(evalChi2Visitor< PixelT > &chi2Visitor, afwMath::Kernel *kernel, afwMath::SpatialCellSet const &psfCells, int nStarPerCell, int nComponents, int nSpatialParams)
boost::shared_ptr< Image > computeImage(geom::Point2D position=makeNullPoint(), image::Color color=image::Color(), ImageOwnerEnum owner=COPY) const
Return an Image of the PSF, in a form that can be compared directly with star images.
SelectEigenView< T >::Type copy(Eigen::EigenBase< T > const &other)
Copy an arbitrary Eigen expression into a new EigenView.
int getNSpatialParameters() const
Return the number of spatial parameters (0 if not spatially varying)
boost::shared_ptr< LinearCombinationKernel > Ptr
Define a collection of useful Functions.
boost::shared_ptr< const MaskedImage > ConstPtr
evalChi2Visitor(afwMath::Kernel const &kernel, double lambda)
afwImage::Image< PixelT > Image
std::pair< std::vector< double >, lsst::afw::math::KernelList > fitKernelParamsToImage(lsst::afw::math::LinearCombinationKernel const &kernel, Image const &image, lsst::afw::geom::Point2D const &pos)
boost::enable_if< typename ExpressionTraits< Scalar >::IsScalar, Scalar >::type sum(Scalar const &scalar)
afwMath::Kernel const & _kernel
An integer coordinate rectangle.
int getHeight() const
Return the Kernel's height.
table::Key< table::Array< Kernel::Pixel > > image
int const _nSpatialParams
int getWidth() const
Return the Kernel's width.
double getValue(Property const prop=NOTHING) const
Return the value of the desired property (if specified in the constructor)
Eigen::MatrixXd _basisDotBasis
boost::shared_ptr< Kernel > Ptr
A collection of SpatialCells covering an entire image.
ImageList const & getEigenImages() const
Return Eigen images.
Pass parameters to a Statistics objectA class to pass parameters which control how the stats are calc...
A class to pass around to all our PsfCandidates to evaluate the PSF fit's X^2.
Class used by SpatialCell for spatial PSF fittig.
unsigned int getNKernelParameters() const
Return the number of kernel parameters (0 if none)
afwMath::LinearCombinationKernel const & _kernel
virtual KernelList const & getKernelList() const
Get the fixed basis kernels.
double computeImage(lsst::afw::image::Image< Pixel > &image, bool doNormalize, double x=0.0, double y=0.0) const
Compute an image (pixellized representation of the kernel) in place.
A kernel that is a linear combination of fixed basis kernels.
A class to manipulate images, masks, and variance as a single object.
boost::shared_ptr< MaskedImage > Ptr
shared pointer to a MaskedImage
evalChi2Visitor< PixelT > & _chi2Visitor
boost::shared_ptr< Image< PixelT > > Ptr
static MaskPixelT getPlaneBitMask(const std::vector< std::string > &names)
Return the bitmask corresponding to a vector of plane names OR'd together.
void setSpatialParameters(const std::vector< std::vector< double > > params)
Set the parameters of all spatial functions.
void setSpatialParameters(afwMath::Kernel *kernel, std::vector< double > const &coeffs)
ImageT::Ptr offsetImage(ImageT const &image, float dx, float dy, std::string const &algorithmName="lanczos5", unsigned int buffer=0)
Return an image offset by (dx, dy) using the specified algorithm.
#define LSST_EXCEPT(type,...)
void setNanSafe(bool isNanSafe)
SpatialFunctionPtr getSpatialFunction(unsigned int index) const
Return a clone of the specified spatial function (one component of the spatial model) ...
boost::shared_ptr< FixedKernel > Ptr
static void setWidth(int width)
Set the width of the image that getImage should return.
afwMath::Kernel * _kernel
afwMath::SpatialCellSet const & _psfCells
Statistics makeStatistics(afwImage::Mask< afwImage::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl)
Specialization to handle Masks.
Class to ensure constraints for spatial modeling.
afw::table::Key< double > b
std::pair< lsst::afw::math::Kernel::Ptr, std::pair< double, double > > fitKernelToImage(lsst::afw::math::LinearCombinationKernel const &kernel, Image const &image, lsst::afw::geom::Point2D const &pos)
static void setHeight(int height)
Set the height of the image that getImage should return.
void visitAllCandidates(CandidateVisitor *visitor, bool const ignoreExceptions=false)
double operator()(const std::vector< double > &coeffs) const
boost::shared_ptr< afw::image::MaskedImage< PixelT > > getOffsetImage(std::string const algorithm, unsigned int buffer) const
Return an offset version of the image of the source. The returned image has been offset to put the ce...
void setChi2(double chi2)
Set the candidate's chi^2.
find sum of pixels in the image
A floating-point coordinate rectangle geometry.
A polymorphic base class for representing an image's Point Spread Function.
std::pair< lsst::afw::math::LinearCombinationKernel::Ptr, std::vector< double > > createKernelFromPsfCandidates(lsst::afw::math::SpatialCellSet const &psfCells, lsst::afw::geom::Extent2I const &dims, lsst::afw::geom::Point2I const &xy0, int const nEigenComponents, int const spatialOrder, int const ksize, int const nStarPerCell=-1, bool const constantWeight=true, int const border=3)
#define LSST_EXCEPT_ADD(e, m)
Kernels are used for convolution with MaskedImages and (eventually) Images.
void visitCandidates(CandidateVisitor *visitor, int const nMaxPerCell=-1, bool const ignoreExceptions=false)
A class to represent a 2-dimensional array of pixels.
Class stored in SpatialCells for spatial Psf fitting.
virtual double updateBadPixels(unsigned long mask, int const ncomp)
PsfImagePca< MaskedImageT > * _imagePca
std::pair< bool, double > fitSpatialKernelFromPsfCandidates(lsst::afw::math::Kernel *kernel, lsst::afw::math::SpatialCellSet const &psfCells, int const nStarPerCell=-1, double const tolerance=1e-5, double const lambda=0.0)
A kernel created from an Image.
std::vector< boost::shared_ptr< Kernel > > KernelList