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;
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");
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);
444 _catalog.writeToArchive(handle,
false);
#define LSST_EXCEPT_ADD(e, m)
Add the current location and a message to an existing exception before rethrowing it.
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
An exception thrown when we have an invalid PSF.
lsst::geom::Box2I computeBBox(lsst::geom::Point2D position, image::Color color=image::Color()) const
Return the bounding box of the image returned by computeKernelImage()
std::shared_ptr< Image > computeKernelImage(lsst::geom::Point2D position, image::Color color=image::Color(), ImageOwnerEnum owner=COPY) const
Return an Image of the PSF, in a form suitable for convolution.
A 2-dimensional celestial WCS that transform pixels to ICRS RA/Dec, using the LSST standard for pixel...
Describe the colour of a source.
A class to represent a 2-dimensional array of pixels.
Base class for all records.
Field< T >::Value get(Key< T > const &key) const
Return the value of a field for the given key.
bool empty() const
Return true if the catalog has no records.
std::shared_ptr< RecordT > addNew()
Create a new record, add it to the end of the catalog, and return a pointer to it.
typename Base::const_iterator const_iterator
static ExposureCatalogT readFromArchive(io::InputArchive const &archive, BaseCatalog const &catalog)
static Schema makeMinimalSchema()
Return a minimal schema for Exposure tables and records.
A class used as a handle to a particular field in a table.
A FunctorKey used to get or set a lsst::geom::Point from an (x,y) pair of int or double Keys.
Defines the fields and offsets for a table.
A mapping between the keys of two Schemas, used to copy data between them.
Schema const getOutputSchema() const
Return the output schema (copy-on-write).
Key< T > addMapping(Key< T > const &inputKey, bool doReplace=false)
Add a new field to the output Schema that is a copy of a field in the input Schema.
void addMinimalSchema(Schema const &minimal, bool doMap=true)
Add the given minimal schema to the output schema.
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
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...
static std::shared_ptr< T > dynamicCast(std::shared_ptr< Persistable > const &ptr)
Dynamically cast a shared_ptr.
A base class for factory classes used to reconstruct objects from records.
io::CatalogVector CatalogVector
io::InputArchive InputArchive
PersistableFactory(std::string const &name)
Constructor for the factory.
io::OutputArchiveHandle OutputArchiveHandle
An integer coordinate rectangle.
void include(Point2I const &point)
Expand this to ensure that this->contains(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
Construct a new object from the given InputArchive and vector of catalogs.
Factory(std::string const &name)
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
std::shared_ptr< afw::detection::Psf > clone() const override
Polymorphic deep copy. Usually unnecessary, as Psfs are immutable.
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
std::string getPythonModule() const override
Return the fully-qualified Python module that should be imported to guarantee that its factory is reg...
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
These virtual member functions are private, not protected, because we only want derived classes to im...
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.
Reports errors in the logical structure of the program.
Reports attempts to access elements using an invalid key.
Reports when the result of an operation cannot be represented by the destination type.
Reports errors that are due to events beyond the control of the program.
bool operator<(const String &lhs, const String &rhs)
std::shared_ptr< TransformPoint2ToPoint2 > makeWcsPairTransform(SkyWcs const &src, SkyWcs const &dst)
A Transform obtained by putting two SkyWcs objects "back to back".
std::shared_ptr< Image< PixelT > > operator+(Image< PixelT > const &img, ImageSlice< PixelT > const &slc)
Overload operator+()
Image< LhsPixelT > & operator+=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Add lhs to Image rhs (i.e. pixel-by-pixel addition) where types are different.
Image< LhsPixelT > & operator-=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Subtract lhs from Image rhs (i.e. pixel-by-pixel subtraction) where types are different.
std::shared_ptr< Image< PixelT > > operator-(Image< PixelT > const &img, ImageSlice< PixelT > const &slc)
Overload operator-()
ExposureCatalogT< ExposureRecord > ExposureCatalog
CatalogT< BaseRecord > BaseCatalog
std::int64_t RecordId
Type used for unique IDs for records.
Point< double, 2 > Point2D
geom::Box2I getOverallBBox(std::vector< std::shared_ptr< afw::image::Image< double > > > const &imgVector)
A description of a field in a table.