29 #include "boost/format.hpp" 51 _kernelImagePtrList(),
54 _isDeltaFunctionBasis(false) {}
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);
78 _kernelImagePtrList(),
80 _kernelParams(
std::vector<double>(kernelList.size())),
81 _isDeltaFunctionBasis(false) {
83 _setKernelList(kernelList);
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());
167 if (!firstSpFuncPtr->isLinearCombination()) {
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);
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;
218 newSpFunctionPtr->setParameters(newSpParameters);
219 newSpFunctionPtrList.
push_back(newSpFunctionPtr);
223 refactoredKernel->setCtr(this->
getCtr());
224 return refactoredKernel;
229 os << prefix <<
"LinearCombinationKernel:" <<
std::endl;
230 os << prefix <<
"..Kernels:" <<
std::endl;
231 for (KernelList::const_iterator i = _kernelList.
begin(); i != _kernelList.
end(); ++i) {
232 os << (*i)->toString(prefix +
"\t");
234 os <<
"..parameters: [ ";
236 if (i != _kernelParams.
begin()) os <<
", ";
251 _kernelImagePtrList.
begin();
254 for (; kImPtrIter != _kernelImagePtrList.
end(); ++kImPtrIter, ++kSumIter, ++kParIter) {
256 imSum += (*kSumIter) * (*kParIter);
271 this->_kernelParams[ind] = value;
277 void LinearCombinationKernel::_setKernelList(
KernelList const &kernelList) {
278 _kernelSumList.
clear();
279 _kernelImagePtrList.
clear();
281 _isDeltaFunctionBasis =
true;
282 for (KernelList::const_iterator kIter = kernelList.
begin(), kEnd = kernelList.
end(); kIter != kEnd;
285 if (dynamic_cast<DeltaFunctionKernel const *>(&(*basisKernelPtr)) == 0) {
286 _isDeltaFunctionBasis =
false;
290 _kernelSumList.
push_back(basisKernelPtr->computeImage(*kernelImagePtr,
false));
291 _kernelImagePtrList.
push_back(kernelImagePtr);
304 :
Kernel::PersistenceHelper(isSpatiallyVarying ? nComponents : 0),
305 components(
schema.addField<table::Array<int>>(
"components",
"archive IDs of component kernel",
307 if (!isSpatiallyVarying) {
308 amplitudes =
schema.addField<table::Array<double>>(
"amplitudes",
"amplitudes component kernel",
313 LinearCombinationKernelPersistenceHelper(table::Schema
const &schema_)
315 if (!spatialFunctions.isValid()) {
316 amplitudes =
schema[
"amplitudes"];
332 LinearCombinationKernelPersistenceHelper
const keys(catalogs.
front().getSchema());
336 for (
std::size_t i = 0; i < componentList.size(); ++i) {
337 componentList[i] = archive.
get<
Kernel>(record[
keys.components[i]]);
340 if (
keys.spatialFunctions.isValid()) {
345 for (
std::size_t i = 0; i < kernelParameters.size(); ++i) {
346 kernelParameters[i] = record[
keys.amplitudes[i]];
351 result->setCtr(record.get(
keys.center));
360 std::string getLinearCombinationKernelPersistenceName() {
return "LinearCombinationKernel"; }
367 return getLinearCombinationKernelPersistenceName();
375 for (
int n = 0; n < keys.components.getSize(); ++n) {
376 record->set(keys.components[n], handle.
put(_kernelList[n]));
380 for (
int n = 0; n < keys.components.getSize(); ++n) {
381 record->set(keys.components[n], handle.
put(_kernelList[n]));
382 record->set(keys.amplitudes[n], _kernelParams[n]);
table::Key< table::Array< int > > components
int getHeight() const
Return the Kernel's height.
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
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...
void checkKernelList(const KernelList &kernelList) const
Check that all kernels have the same size and center and that none are spatially varying.
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.
A base class for factory classes used to reconstruct objects from records.
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
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.
table::Key< table::Array< double > > amplitudes
std::shared_ptr< Kernel > clone() const override
Return a pointer to a deep copy of this kernel.
A Function taking two arguments.
LinearCombinationKernel()
Construct an empty LinearCombinationKernel of size 0x0.
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
int getNBasisKernels() const
Get the number of basis kernels.
afw::table::PointKey< int > dimensions
bool isSpatiallyVarying() const
Return true iff the kernel is spatially varying (has a spatial function)
A base class for image defects.
Reports when the result of an arithmetic operation is too large for the destination type...
lsst::geom::Point2I getCtr() const
Return index of kernel's center.
void scaledPlus(double const c, Image< PixelT > const &rhs)
Add Image c*rhs to lhs.
double doComputeImage(lsst::afw::image::Image< Pixel > &image, bool doNormalize) const override
Low-level version of computeImage.
std::vector< double > getKernelParameters() const override
Return the current kernel parameters.
int getWidth() const
Return the Kernel's width.
lsst::geom::Extent2I const getDimensions() const
Return the Kernel's dimensions (width, height)
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
A vector of catalogs used by Persistable.
std::vector< double > getKernelSumList() const
Get the sum of the pixels of each fixed basis kernel.
Base class for all records.
std::vector< SpatialFunctionPtr > _spatialFunctionList
Kernel()
Construct a null Kernel of size 0,0.
Factory(std::string const &name)
int getNSpatialParameters() const
Return the number of spatial parameters (0 if not spatially varying)
Reports invalid arguments.
virtual KernelList const & getKernelList() const
Get the fixed basis kernels.
std::shared_ptr< Kernel > resized(int width, int height) const override
Return a pointer to a clone with specified kernel dimensions.
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects...
void setKernelParameter(unsigned int ind, double value) const override
Set one kernel parameter.
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...
Kernels are used for convolution with MaskedImages and (eventually) Images.
A class to represent a 2-dimensional array of pixels.
std::string toString(std::string const &prefix="") const override
Return a string representation of the kernel.
virtual std::string toString(std::string const &prefix="") const
Return a string representation of the kernel.
A kernel created from an Image.