33#include "boost/iterator/iterator_adaptor.hpp"
34#include "boost/iterator/transform_iterator.hpp"
35#include "ndarray/eigen.h"
54template std::shared_ptr<meas::algorithms::CoaddPsf>
72 explicit AvgPosItem(
double wx_ = 0.0,
double wy_ = 0.0,
double w_ = 0.0) : wx(wx_), wy(wy_), w(w_) {}
78 bool operator<(AvgPosItem
const &other)
const {
return w < other.w; }
80 AvgPosItem &
operator+=(AvgPosItem
const &other) {
87 AvgPosItem &
operator-=(AvgPosItem
const &other) {
94 friend AvgPosItem
operator+(AvgPosItem a, AvgPosItem
const &b) {
return a += b; }
96 friend AvgPosItem
operator-(AvgPosItem a, AvgPosItem
const &b) {
return a -= b; }
103 goodPixKey = catalog.getSchema()[
"goodpix"];
106 std::vector<AvgPosItem>
items;
107 items.reserve(catalog.size());
109 geom::Point2D p = coaddWcs.skyToPixel(i->getWcs()->pixelToSky(i->getPsf()->getAveragePosition()));
110 AvgPosItem item(p.getX(), p.getY(), i->get(weightKey));
111 if (goodPixKey.isValid()) {
112 item.w *= i->get(goodPixKey);
116 items.push_back(item);
126 for (std::vector<AvgPosItem>::iterator iter =
items.begin();
127 catalog.subsetContaining(result.getPoint(), coaddWcs,
true).empty(); ++iter) {
128 if (iter ==
items.end()) {
133 "Could not find a valid average position for CoaddPsf");
137 return result.getPoint();
144 : _coaddWcs(coaddWcs),
145 _warpingKernelName(warpingKernelName),
146 _warpingControl(
std::make_shared<
afw::
math::WarpingControl>(warpingKernelName,
"", cacheSize)) {
160 _weightKey = mapper.
addMapping(weightKey, weightField);
165 record->assign(*i, mapper);
166 _catalog.push_back(record);
168 _averagePosition = computeAveragePosition(_catalog, _coaddWcs, _weightKey);
175 _weightKey(_catalog.getSchema()[
"weight"]),
176 _averagePosition(averagePosition),
177 _warpingKernelName(warpingKernelName),
178 _warpingControl(new
afw::
math::WarpingControl(warpingKernelName,
"", cacheSize)) {}
192 for (
unsigned int i = 0; i < imgVector.size(); i++) {
207 assert(imgVector.size() == weightVector.
size());
208 for (
unsigned int i = 0; i < imgVector.size(); i++) {
210 double weight = weightVector[i];
211 double sum = ndarray::asEigenMatrix(componentImg->getArray()).sum();
218 overlap.clip(image->getBBox());
223 targetSubImage.scaledPlus(weight / sum, cSubImage);
231 if (subcat.
empty()) {
234 (boost::format(
"Cannot compute BBox at point %s; no input images at that point.") % ccdXY)
239 for (
auto const &exposureRecord : subcat) {
242 WarpedPsf warpedPsf =
WarpedPsf(exposureRecord.getPsf(), exposureToCoadd, _warpingControl);
254 if (subcat.
empty()) {
257 (boost::format(
"Cannot compute CoaddPsf at point %s; no input images at that point.") % ccdXY)
260 double weightSum = 0.0;
268 for (
auto const &exposureRecord : subcat) {
273 WarpedPsf warpedPsf =
WarpedPsf(exposureRecord.getPsf(), exposureToCoadd, _warpingControl);
276 LSST_EXCEPT_ADD(exc, (boost::format(
"Computing WarpedPsf kernel image for id=%d") %
277 exposureRecord.getId())
282 weightSum += exposureRecord.get(_weightKey);
283 weightVector.
push_back(exposureRecord.get(_weightKey));
291 addToImage(
image, imgVector, weightVector);
302 return _catalog[index].getPsf();
309 return *_catalog[index].getWcs();
316 return _catalog[index].getValidPolygon();
323 return _catalog[index].
get(_weightKey);
330 return _catalog[index].getId();
337 return _catalog[index].getBBox();
349class CoaddPsfPersistenceHelper {
357 static CoaddPsfPersistenceHelper
const &get() {
358 static CoaddPsfPersistenceHelper
const instance;
363 CoaddPsfPersistenceHelper()
365 coaddWcs(schema.addField<int>(
"coaddwcs",
"archive ID of the coadd's WCS")),
366 cacheSize(schema.addField<int>(
"cachesize",
"size of the warping cache")),
367 averagePosition(
afw::table::PointKey<double>::addFields(
368 schema,
"avgpos",
"PSF accessors default position",
"pixel")),
370 schema.addField<
std::string>(
"warpingkernelname",
"warping kernel name", 32)) {}
379 if (catalogs.
size() == 1u) {
383 return readV0(archive, catalogs);
386 CoaddPsfPersistenceHelper
const &keys1 = CoaddPsfPersistenceHelper::get();
392 record1.
get(keys1.averagePosition), record1.
get(keys1.warpingKernelName),
393 record1.
get(keys1.cacheSize)));
405 auto coaddWcs = internalCat.back().getWcs();
406 internalCat.pop_back();
412 weightKey = internalCat.getSchema()[
"weight"];
415 auto averagePos = computeAveragePosition(internalCat, *coaddWcs, weightKey);
424std::string getCoaddPsfPersistenceName() {
return "CoaddPsf"; }
426CoaddPsf::Factory registration(getCoaddPsfPersistenceName());
435 CoaddPsfPersistenceHelper
const &keys1 = CoaddPsfPersistenceHelper::get();
439 record1->set(keys1.coaddWcs, handle.put(coaddWcsPtr));
440 record1->set(keys1.cacheSize, _warpingControl->getCacheSize());
441 record1->set(keys1.averagePosition, _averagePosition);
442 record1->set(keys1.warpingKernelName, _warpingKernelName);
443 handle.saveCatalog(cat1);
444 _catalog.writeToArchive(handle,
false);
#define LSST_EXCEPT_ADD(e, m)
#define LSST_EXCEPT(type,...)
#define LSST_ARCHIVE_ASSERT(EXPR)
lsst::geom::Box2I computeBBox(lsst::geom::Point2D position, image::Color color=image::Color()) const
std::shared_ptr< Image > computeKernelImage(lsst::geom::Point2D position, image::Color color=image::Color(), ImageOwnerEnum owner=COPY) const
Field< T >::Value get(Key< T > const &key) const
std::shared_ptr< RecordT > addNew()
typename Base::const_iterator const_iterator
static ExposureCatalogT readFromArchive(io::InputArchive const &archive, BaseCatalog const &catalog)
static Schema makeMinimalSchema()
Schema const getOutputSchema() const
Key< T > addMapping(Key< T > const &inputKey, bool doReplace=false)
void addMinimalSchema(Schema const &minimal, bool doMap=true)
static std::shared_ptr< T > dynamicCast(std::shared_ptr< Persistable > const &ptr)
io::CatalogVector CatalogVector
io::InputArchive InputArchive
PersistableFactory(std::string const &name)
io::OutputArchiveHandle OutputArchiveHandle
void include(Point2I const &point)
std::shared_ptr< afw::table::io::Persistable > readV0(InputArchive const &archive, CatalogVector const &catalogs) const
virtual std::shared_ptr< afw::table::io::Persistable > read(InputArchive const &archive, CatalogVector const &catalogs) const
Factory(std::string const &name)
std::string getPersistenceName() const override
std::shared_ptr< afw::detection::Psf > clone() const override
Polymorphic deep copy. Usually unnecessary, as Psfs are immutable.
void write(OutputArchiveHandle &handle) const override
std::string getPythonModule() const override
double getWeight(int index)
Get the weight of the component image at index.
std::shared_ptr< afw::detection::Psf const > getPsf(int index)
Get the Psf of the component image at index.
afw::table::RecordId getId(int index)
Get the exposure ID of the component image at index.
geom::Box2I getBBox(int index)
Get the bounding box (in component image Pixel coordinates) of the component image at index.
std::shared_ptr< afw::detection::Psf::Image > doComputeKernelImage(geom::Point2D const &ccdXY, afw::image::Color const &color) const override
std::shared_ptr< afw::geom::polygon::Polygon const > getValidPolygon(int index)
Get the validPolygon (in component image Pixel coordinates) of the component image at index.
std::shared_ptr< afw::detection::Psf > resized(int width, int height) const override
Return a clone with specified kernel dimensions.
CoaddPsf(afw::table::ExposureCatalog const &catalog, afw::geom::SkyWcs const &coaddWcs, std::string const &weightFieldName="weight", std::string const &warpingKernelName="lanczos3", int cacheSize=10000)
Main constructors for CoaddPsf.
geom::Box2I doComputeBBox(geom::Point2D const &position, afw::image::Color const &color) const override
int getComponentCount() const
Return the number of component Psfs in this CoaddPsf.
afw::geom::SkyWcs getWcs(int index)
Get the Wcs of the component image at index.
A Psf class that maps an arbitrary Psf through a coordinate transformation.
std::shared_ptr< TransformPoint2ToPoint2 > makeWcsPairTransform(SkyWcs const &src, SkyWcs const &dst)
ExposureCatalogT< ExposureRecord > ExposureCatalog
CatalogT< BaseRecord > BaseCatalog
Extent< double, N > & operator+=(Extent< double, N > &lhs, Extent< int, N > const &rhs) noexcept
constexpr Angle operator+(Angle a, Angle d) noexcept
constexpr Angle operator-(Angle a, Angle d) noexcept
Point< double, 2 > Point2D
Extent< double, N > & operator-=(Extent< double, N > &lhs, Extent< int, N > const &rhs) noexcept
geom::Box2I getOverallBBox(std::vector< std::shared_ptr< afw::image::Image< double > > > const &imgVector)