29 #include "boost/format.hpp"
37 namespace pexExcept = lsst::pex::exceptions;
38 namespace afwMath = lsst::afw::math;
40 namespace afwGeom = lsst::afw::geom;
46 _kernelImagePtrList(),
49 _isDeltaFunctionBasis(false)
54 std::vector<double>
const &kernelParameters
56 Kernel(kernelList[0]->getWidth(), kernelList[0]->getHeight(), kernelList.size()),
58 _kernelImagePtrList(),
60 _kernelParams(kernelParameters),
61 _isDeltaFunctionBasis(false)
63 if (kernelList.size() != kernelParameters.size()) {
64 std::ostringstream os;
65 os <<
"kernelList.size() = " << kernelList.size()
66 <<
" != " << kernelParameters.size() <<
" = " <<
"kernelParameters.size()";
67 throw LSST_EXCEPT(pexExcept::InvalidParameterError, os.str());
77 Kernel(kernelList[0]->getWidth(), kernelList[0]->getHeight(), kernelList.size(), spatialFunction),
79 _kernelImagePtrList(),
81 _kernelParams(std::vector<double>(kernelList.size())),
82 _isDeltaFunctionBasis(false)
90 std::vector<Kernel::SpatialFunctionPtr>
const &spatialFunctionList
92 Kernel(kernelList[0]->getWidth(), kernelList[0]->getHeight(), spatialFunctionList),
94 _kernelImagePtrList(),
96 _kernelParams(std::vector<double>(kernelList.size())),
97 _isDeltaFunctionBasis(false)
99 if (kernelList.size() != spatialFunctionList.size()) {
100 std::ostringstream os;
101 os <<
"kernelList.size() = " << kernelList.size()
102 <<
" != " << spatialFunctionList.size() <<
" = " <<
"spatialFunctionList.size()";
103 throw LSST_EXCEPT(pexExcept::InvalidParameterError, os.str());
111 if (this->isSpatiallyVarying()) {
116 retPtr->setCtr(this->getCtr());
121 if (kernelList.size() < 1) {
122 throw LSST_EXCEPT(pexExcept::InvalidParameterError,
"kernelList has no elements");
128 for (
unsigned int ii = 0; ii < kernelList.size(); ++ii) {
129 if (kernelList[ii]->getDimensions() != dim0) {
130 throw LSST_EXCEPT(pexExcept::InvalidParameterError,
131 (
boost::format(
"kernel %d has different size than kernel 0") % ii).str());
133 if (kernelList[ii]->getCtr() != ctr0) {
134 throw LSST_EXCEPT(pexExcept::InvalidParameterError,
135 (
boost::format(
"kernel %d has different center than kernel 0") % ii).str());
137 if (kernelList[ii]->isSpatiallyVarying()) {
138 throw LSST_EXCEPT(pexExcept::InvalidParameterError,
139 (
boost::format(
"kernel %d is spatially varying") % ii).str());
149 return _kernelSumList;
153 return _kernelParams;
157 if (!this->isSpatiallyVarying()) {
161 if (!firstSpFuncPtr->isLinearCombination()) {
166 typedef std::shared_ptr<KernelImage> KernelImagePtr;
167 typedef std::vector<KernelImagePtr> KernelImageList;
170 int const nSpatialParameters = this->getNSpatialParameters();
171 KernelImageList newKernelImagePtrList;
172 newKernelImagePtrList.reserve(nSpatialParameters);
173 for (
int i = 0; i < nSpatialParameters; ++i) {
174 KernelImagePtr kernelImagePtr(
new KernelImage(this->getDimensions()));
175 newKernelImagePtrList.push_back(kernelImagePtr);
177 KernelImage kernelImage(this->getDimensions());
178 std::vector<Kernel::SpatialFunctionPtr>::const_iterator spFuncPtrIter =
179 this->_spatialFunctionList.begin();
180 afwMath::KernelList::const_iterator kIter = _kernelList.begin();
181 afwMath::KernelList::const_iterator
const kEnd = _kernelList.end();
182 for ( ; kIter != kEnd; ++kIter, ++spFuncPtrIter) {
183 if (
typeid(**spFuncPtrIter) !=
typeid(*firstSpFuncPtr)) {
187 (**kIter).computeImage(kernelImage,
false);
188 for (
int i = 0; i < nSpatialParameters; ++i) {
189 double spParam = (*spFuncPtrIter)->getParameter(i);
190 newKernelImagePtrList[i]->scaledPlus(spParam, kernelImage);
198 newKernelList.reserve(nSpatialParameters);
199 KernelImageList::iterator newKImPtrIter = newKernelImagePtrList.begin();
200 KernelImageList::iterator
const newKImPtrEnd = newKernelImagePtrList.end();
201 for ( ; newKImPtrIter != newKImPtrEnd; ++newKImPtrIter) {
204 std::vector<SpatialFunctionPtr> newSpFunctionPtrList;
205 for (
int i = 0; i < nSpatialParameters; ++i) {
206 std::vector<double> newSpParameters(nSpatialParameters, 0.0);
207 newSpParameters[i] = 1.0;
209 newSpFunctionPtr->setParameters(newSpParameters);
210 newSpFunctionPtrList.push_back(newSpFunctionPtr);
214 refactoredKernel->setCtr(this->getCtr());
215 return refactoredKernel;
219 std::ostringstream os;
220 os << prefix <<
"LinearCombinationKernel:" << std::endl;
221 os << prefix <<
"..Kernels:" << std::endl;
222 for (KernelList::const_iterator i = _kernelList.begin(); i != _kernelList.end(); ++i) {
223 os << (*i)->toString(prefix +
"\t");
225 os <<
"..parameters: [ ";
226 for (std::vector<double>::const_iterator i = _kernelParams.begin(); i != _kernelParams.end(); ++i) {
227 if (i != _kernelParams.begin()) os <<
", ";
230 os <<
" ]" << std::endl;
244 std::vector<PTR(afwImage::Image<Pixel>)>::const_iterator kImPtrIter = _kernelImagePtrList.
begin();
245 std::vector<double>::const_iterator kSumIter = _kernelSumList.begin();
246 std::vector<double>::const_iterator kParIter = _kernelParams.begin();
247 for ( ; kImPtrIter != _kernelImagePtrList.end(); ++kImPtrIter, ++kSumIter, ++kParIter) {
249 imSum += (*kSumIter) * (*kParIter);
254 throw LSST_EXCEPT(pexExcept::OverflowError,
"Cannot normalize; kernel sum is 0");
264 this->_kernelParams[ind] = value;
271 _kernelSumList.clear();
272 _kernelImagePtrList.clear();
274 _isDeltaFunctionBasis =
true;
275 for (KernelList::const_iterator kIter = kernelList.begin(), kEnd = kernelList.end();
276 kIter != kEnd; ++kIter) {
277 PTR(
Kernel) basisKernelPtr = (*kIter)->clone();
278 if (dynamic_cast<afwMath::DeltaFunctionKernel const *>(&(*basisKernelPtr)) == 0) {
279 _isDeltaFunctionBasis =
false;
281 _kernelList.push_back(basisKernelPtr);
283 _kernelSumList.push_back(basisKernelPtr->computeImage(*kernelImagePtr,
false));
284 _kernelImagePtrList.push_back(kernelImagePtr);
290 namespace lsst {
namespace afw {
namespace math {
298 LinearCombinationKernelPersistenceHelper(
int nComponents,
bool isSpatiallyVarying) :
299 Kernel::PersistenceHelper(isSpatiallyVarying ? nComponents : 0),
301 schema.addField< table::Array<int> >(
"components",
"archive IDs of component kernel",
305 if (!isSpatiallyVarying) {
306 amplitudes =
schema.addField< table::Array<double> >(
"amplitudes",
"amplitudes component kernel",
311 LinearCombinationKernelPersistenceHelper(table::Schema
const & schema_) :
314 if (!spatialFunctions.isValid()) {
333 LinearCombinationKernelPersistenceHelper
const keys(catalogs.front().getSchema());
336 std::vector<PTR(Kernel)> componentList(keys.components.getSize());
337 for (std::size_t i = 0; i < componentList.size(); ++i) {
338 componentList[i] = archive.get<
Kernel>(record[keys.components[i]]);
341 if (keys.spatialFunctions.isValid()) {
342 std::vector<SpatialFunctionPtr> spatialFunctionList = keys.readSpatialFunctions(archive, record);
345 std::vector<double> kernelParameters(keys.amplitudes.getSize());
346 for (std::size_t i = 0; i < kernelParameters.size(); ++i) {
347 kernelParameters[i] = record[keys.amplitudes[i]];
352 result->setCtr(record.get(keys.center));
361 std::string getLinearCombinationKernelPersistenceName() {
return "LinearCombinationKernel"; }
363 LinearCombinationKernel::Factory registration(getLinearCombinationKernelPersistenceName());
368 return getLinearCombinationKernelPersistenceName();
372 bool isVarying = isSpatiallyVarying();
373 LinearCombinationKernelPersistenceHelper
const keys(getNBasisKernels(), isVarying);
376 for (
int n = 0;
n < keys.components.getSize(); ++
n) {
377 record->set(keys.components[
n], handle.
put(_kernelList[
n]));
378 record->set(keys.spatialFunctions[n], handle.
put(_spatialFunctionList[n]));
381 for (
int n = 0;
n < keys.components.getSize(); ++
n) {
382 record->set(keys.components[
n], handle.
put(_kernelList[
n]));
383 record->set(keys.amplitudes[n], _kernelParams[n]);
std::vector< double > getKernelSumList() const
Get the sum of the pixels of each fixed basis kernel.
boost::shared_ptr< lsst::afw::math::Function2< double > > SpatialFunctionPtr
An include file to include the header files for lsst::afw::geom.
Declare the Kernel class and subclasses.
table::Key< std::string > name
An object passed to Persistable::write to allow it to persist itself.
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
afw::table::Schema schema
Include files required for standard LSST Exception handling.
A base class for factory classes used to reconstruct objects from records.
virtual std::string toString(std::string const &prefix="") const
Return a string representation of the kernel.
Define a collection of useful Functions.
A Function taking two arguments.
LinearCombinationKernel()
Construct an empty LinearCombinationKernel of size 0x0.
void checkKernelList(const KernelList &kernelList) const
Check that all kernels have the same size and center and that none are spatially varying.
table::Key< table::Array< Kernel::Pixel > > image
A base class for objects that can be persisted via afw::table::io Archive classes.
void scaledPlus(double const c, Image< PixelT >const &rhs)
Add Image c*rhs to lhs.
table::Key< table::Array< double > > amplitudes
virtual std::vector< double > getKernelParameters() const
Return the current kernel parameters.
afw::table::PointKey< int > dimensions
metadata import lsst afw display as afwDisplay n
virtual std::string toString(std::string const &prefix="") const
Return a string representation of the kernel.
std::map< Citizen const *, CitizenInfo > table
virtual KernelList const & getKernelList() const
Get the fixed basis kernels.
A kernel that is a linear combination of fixed basis kernels.
virtual void setKernelParameter(unsigned int ind, double value) const
Set one kernel parameter.
table::Key< table::Array< int > > components
#define LSST_EXCEPT(type,...)
Create an exception with a given type and message and optionally other arguments (dependent on the ty...
A vector of catalogs used by Persistable.
Base class for all records.
Factory(std::string const &name)
void _setKernelList(KernelList const &kernelList)
Set _kernelList by cloning each input kernel and update the kernel image cache.
int put(Persistable const *obj, bool permissive=false)
Save a nested Persistable to the same archive.
virtual double doComputeImage(lsst::afw::image::Image< Pixel > &image, bool doNormalize) const
Low-level version of computeImage.
virtual std::string getPersistenceName() const
Return the unique name used to persist this object and look up its factory.
iterator begin() const
Return an STL compliant iterator to the start of the image.
Kernels are used for convolution with MaskedImages and (eventually) Images.
A class to represent a 2-dimensional array of pixels.
virtual void write(OutputArchiveHandle &handle) const
Write the object to one or more catalogs.
A kernel created from an Image.
std::vector< boost::shared_ptr< Kernel > > KernelList