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.
double getValue(Property const prop=NOTHING) const
Return the value of the desired property (if specified in the constructor)
boost::uint16_t MaskPixel
Class used by SpatialCell for spatial PSF fittig.
int getWidth() const
Return the Kernel's width.
A coordinate class intended to represent absolute positions.
void setAmplitude(double amplitude)
Set the best-fit amplitude.
boost::shared_ptr< lsst::afw::math::Function2< double > > SpatialFunctionPtr
afwImage::Exposure< PixelT > Exposure
table::Key< std::string > name
void setErrorDef(double def)
virtual KernelList const & getKernelList() const
Get the fixed basis kernels.
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)
int getHeight() const
Return the Kernel's height.
ImageList const & getEigenImages() const
Return Eigen images.
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.
void visitCandidates(CandidateVisitor *visitor, int const nMaxPerCell=-1, bool const ignoreExceptions=false)
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)
SelectEigenView< T >::Type copy(Eigen::EigenBase< T > const &other)
Copy an arbitrary Eigen expression into a new EigenView.
unsigned int getNKernelParameters() const
Return the number of kernel parameters (0 if none)
Define a collection of useful Functions.
int getNSpatialParameters() const
Return the number of spatial parameters (0 if not spatially varying)
void setStatus(Status status)
Set the candidate's status.
evalChi2Visitor(afwMath::Kernel const &kernel, double lambda)
find sum of pixels in the image
boost::shared_ptr< MaskedImage > Ptr
shared pointer to a MaskedImage
afwImage::Image< PixelT > Image
SpatialFunctionPtr getSpatialFunction(unsigned int index) const
Return a clone of the specified spatial function (one component of the spatial model) ...
boost::shared_ptr< Image< PixelT > > Ptr
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
boost::shared_ptr< Kernel > Ptr
An integer coordinate rectangle.
table::Key< table::Array< Kernel::Pixel > > image
int const _nSpatialParams
Eigen::MatrixXd _basisDotBasis
boost::shared_ptr< FixedKernel > Ptr
static void setHeight(int height)
Set the height of the image that getImage should return.
A collection of SpatialCells covering an entire image.
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.
static MaskPixelT getPlaneBitMask(const std::vector< std::string > &names)
Return the bitmask corresponding to a vector of plane names OR'd together.
Class used by SpatialCell for spatial PSF fittig.
void setNanSafe(bool isNanSafe)
afwMath::LinearCombinationKernel const & _kernel
std::vector< double > const & getEigenValues() const
Return Eigen values.
A kernel that is a linear combination of fixed basis kernels.
A class to manipulate images, masks, and variance as a single object.
evalChi2Visitor< PixelT > & _chi2Visitor
geom::Extent2I const getDimensions() const
Return the Kernel's dimensions (width, height)
void setSpatialParameters(afwMath::Kernel *kernel, std::vector< double > const &coeffs)
static void setWidth(int width)
Set the width of the image that getImage should return.
void setChi2(double chi2)
Set the candidate's chi^2.
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,...)
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.
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.
Class to ensure constraints for spatial modeling.
afw::table::Key< double > b
boost::shared_ptr< const MaskedImage > ConstPtr
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)
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...
std::vector< boost::shared_ptr< Kernel > > KernelList
A floating-point coordinate rectangle geometry.
A polymorphic base class for representing an image's Point Spread Function.
void visitAllCandidates(CandidateVisitor *visitor, bool const ignoreExceptions=false)
Class for doing PCA on PSF stars.
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.
virtual double updateBadPixels(unsigned long mask, int const ncomp)
void setSpatialParameters(const std::vector< std::vector< double > > params)
Set the parameters of all spatial functions.
boost::shared_ptr< LinearCombinationKernel > Ptr
Class stored in SpatialCells for spatial Psf fitting.
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.
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.