30#include "boost/format.hpp"
51 _kernelImagePtrList(),
54 _isDeltaFunctionBasis(false) {}
58 :
Kernel(kernelList[0]->getWidth(), kernelList[0]->getHeight(), kernelList.size()),
60 _kernelImagePtrList(),
62 _kernelParams(kernelParameters),
63 _isDeltaFunctionBasis(false) {
64 if (kernelList.
size() != kernelParameters.
size()) {
66 os <<
"kernelList.size() = " << kernelList.
size() <<
" != " << kernelParameters.
size() <<
" = "
67 <<
"kernelParameters.size()";
71 _setKernelList(kernelList);
76 :
Kernel(kernelList[0]->getWidth(), kernelList[0]->getHeight(), kernelList.size(), spatialFunction),
78 _kernelImagePtrList(),
80 _kernelParams(
std::vector<double>(kernelList.size())),
81 _isDeltaFunctionBasis(false) {
83 _setKernelList(kernelList);
88 :
Kernel(kernelList[0]->getWidth(), kernelList[0]->getHeight(), spatialFunctionList),
90 _kernelImagePtrList(),
92 _kernelParams(
std::vector<double>(kernelList.size())),
93 _isDeltaFunctionBasis(false) {
94 if (kernelList.
size() != spatialFunctionList.
size()) {
96 os <<
"kernelList.size() = " << kernelList.
size() <<
" != " << spatialFunctionList.
size() <<
" = "
97 <<
"spatialFunctionList.size()";
101 _setKernelList(kernelList);
111 retPtr->setCtr(this->
getCtr());
119 kernelList.
push_back(kIter->resized(width, height));
126 retPtr = std::make_shared<LinearCombinationKernel>(kernelList, _kernelParams);
133 if (kernelList.
size() < 1) {
140 for (
unsigned int ii = 0; ii < kernelList.
size(); ++ii) {
143 (boost::format(
"kernel %d has different size than kernel 0") % ii).str());
145 if (kernelList[ii]->
getCtr() != ctr0) {
147 (boost::format(
"kernel %d has different center than kernel 0") % ii).str());
151 (boost::format(
"kernel %d is spatially varying") % ii).str());
177 KernelImageList newKernelImagePtrList;
178 newKernelImagePtrList.reserve(nSpatialParameters);
179 for (
int i = 0; i < nSpatialParameters; ++i) {
180 KernelImagePtr kernelImagePtr(
new KernelImage(this->
getDimensions()));
181 newKernelImagePtrList.push_back(kernelImagePtr);
184 std::vector<Kernel::SpatialFunctionPtr>::const_iterator spFuncPtrIter =
186 KernelList::const_iterator kIter = _kernelList.
begin();
187 KernelList::const_iterator
const kEnd = _kernelList.
end();
188 auto &firstSpFunc = *firstSpFuncPtr;
189 auto &firstType =
typeid(firstSpFunc);
190 for (; kIter != kEnd; ++kIter, ++spFuncPtrIter) {
191 auto &spFunc = **spFuncPtrIter;
192 if (
typeid(spFunc) != firstType) {
196 (**kIter).computeImage(kernelImage,
false);
197 for (
int i = 0; i < nSpatialParameters; ++i) {
198 double spParam = (*spFuncPtrIter)->getParameter(i);
199 newKernelImagePtrList[i]->scaledPlus(spParam, kernelImage);
207 newKernelList.
reserve(nSpatialParameters);
208 KernelImageList::iterator newKImPtrIter = newKernelImagePtrList.begin();
209 KernelImageList::iterator
const newKImPtrEnd = newKernelImagePtrList.end();
210 for (; newKImPtrIter != newKImPtrEnd; ++newKImPtrIter) {
214 for (
int i = 0; i < nSpatialParameters; ++i) {
216 newSpParameters[i] = 1.0;
219 newSpFunctionPtrList.
push_back(newSpFunctionPtr);
223 refactoredKernel->setCtr(this->
getCtr());
224 return refactoredKernel;
231 for (
auto const &i : _kernelList) {
232 os << i->toString(
prefix +
"\t");
234 os <<
"..parameters: [ ";
235 for (std::vector<double>::const_iterator i = _kernelParams.
begin(); i != _kernelParams.
end(); ++i) {
236 if (i != _kernelParams.
begin()) os <<
", ";
251 _kernelImagePtrList.
begin();
252 std::vector<double>::const_iterator kSumIter = _kernelSumList.
begin();
253 std::vector<double>::const_iterator kParIter = _kernelParams.
begin();
254 for (; kImPtrIter != _kernelImagePtrList.
end(); ++kImPtrIter, ++kSumIter, ++kParIter) {
255 image.scaledPlus(*kParIter, **kImPtrIter);
256 imSum += (*kSumIter) * (*kParIter);
271 this->_kernelParams[ind] = value;
277void LinearCombinationKernel::_setKernelList(
KernelList const &kernelList) {
278 _kernelSumList.
clear();
279 _kernelImagePtrList.
clear();
281 _isDeltaFunctionBasis =
true;
282 for (
auto const &kIter : kernelList) {
285 _isDeltaFunctionBasis =
false;
289 _kernelSumList.
push_back(basisKernelPtr->computeImage(*kernelImagePtr,
false));
290 _kernelImagePtrList.
push_back(kernelImagePtr);
298struct LinearCombinationKernelPersistenceHelper :
public Kernel::PersistenceHelper {
302 LinearCombinationKernelPersistenceHelper(
int nComponents,
bool isSpatiallyVarying)
303 : Kernel::PersistenceHelper(isSpatiallyVarying ? nComponents : 0),
304 components(schema.addField<table::Array<int>>(
"components",
"archive IDs of component kernel",
306 if (!isSpatiallyVarying) {
307 amplitudes = schema.addField<table::Array<double>>(
"amplitudes",
"amplitudes component kernel",
312 LinearCombinationKernelPersistenceHelper(table::Schema
const &schema_)
313 : Kernel::PersistenceHelper(schema_),
components(schema[
"components"]) {
314 if (!spatialFunctions.isValid()) {
331 LinearCombinationKernelPersistenceHelper
const keys(catalogs.front().getSchema());
336 componentList[i] = archive.
get<
Kernel>(record[keys.components[i]]);
339 if (keys.spatialFunctions.isValid()) {
345 kernelParameters[i] = record[keys.amplitudes[i]];
359std::string getLinearCombinationKernelPersistenceName() {
return "LinearCombinationKernel"; }
361LinearCombinationKernel::Factory registration(getLinearCombinationKernelPersistenceName());
366 return getLinearCombinationKernelPersistenceName();
371 LinearCombinationKernelPersistenceHelper
const keys(
getNBasisKernels(), isVarying);
374 for (
std::size_t n = 0; n < keys.components.getSize(); ++n) {
375 record->set(keys.components[n], handle.
put(_kernelList[n]));
379 for (
std::size_t n = 0; n < keys.components.getSize(); ++n) {
380 record->set(keys.components[n], handle.
put(_kernelList[n]));
381 record->set(keys.amplitudes[n], _kernelParams[n]);
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
afw::table::PointKey< int > dimensions
table::Key< table::Array< int > > components
table::Key< table::Array< double > > amplitudes
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
A class to represent a 2-dimensional array of pixels.
A kernel that has only one non-zero pixel (of value 1)
A kernel created from an Image.
virtual std::shared_ptr< Function2< ReturnT > > clone() const =0
Return a pointer to a deep copy of this function.
virtual bool isLinearCombination() const noexcept
Is the function a linear combination of its parameters?
void setParameters(std::vector< double > const ¶ms)
Set all function parameters.
Kernels are used for convolution with MaskedImages and (eventually) Images.
lsst::geom::Extent2I const getDimensions() const
Return the Kernel's dimensions (width, height)
std::vector< SpatialFunctionPtr > _spatialFunctionList
lsst::geom::Point2I getCtr() const
Return index of kernel's center.
int getNSpatialParameters() const
Return the number of spatial parameters (0 if not spatially varying)
virtual std::string toString(std::string const &prefix="") const
Return a string representation of the kernel.
bool isSpatiallyVarying() const
Return true iff the kernel is spatially varying (has a spatial function)
Factory(std::string const &name)
std::shared_ptr< afw::table::io::Persistable > read(InputArchive const &archive, CatalogVector const &catalogs) const override
Construct a new object from the given InputArchive and vector of catalogs.
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
std::shared_ptr< Kernel > resized(int width, int height) const override
Return a pointer to a clone with specified kernel dimensions.
std::vector< double > getKernelSumList() const
Get the sum of the pixels of each fixed basis kernel.
std::shared_ptr< Kernel > refactor() const
Refactor the kernel as a linear combination of N bases where N is the number of parameters for the sp...
virtual KernelList const & getKernelList() const
Get the fixed basis kernels.
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
LinearCombinationKernel()
Construct an empty LinearCombinationKernel of size 0x0.
std::shared_ptr< Kernel > clone() const override
Return a pointer to a deep copy of this kernel.
void setKernelParameter(unsigned int ind, double value) const override
Set one kernel parameter.
void checkKernelList(const KernelList &kernelList) const
Check that all kernels have the same size and center and that none are spatially varying.
double doComputeImage(lsst::afw::image::Image< Pixel > &image, bool doNormalize) const override
Low-level version of computeImage.
int getNBasisKernels() const
Get the number of basis kernels.
std::vector< double > getKernelParameters() const override
Return the current kernel parameters.
std::string toString(std::string const &prefix="") const override
Return a string representation of the kernel.
Base class for all records.
Field< T >::Value get(Key< T > const &key) const
Return the value of a field for the given key.
A vector of catalogs used by Persistable.
An object passed to Persistable::write to allow it to persist itself.
int put(Persistable const *obj, bool permissive=false)
Save an object to the archive and return a unique ID that can be used to retrieve it from an InputArc...
A base class for factory classes used to reconstruct objects from records.
Reports invalid arguments.
Reports when the result of an arithmetic operation is too large for the destination type.