33 #include "boost/iterator/iterator_adaptor.hpp" 34 #include "boost/iterator/transform_iterator.hpp" 35 #include "ndarray/eigen.h" 48 namespace algorithms {
59 explicit AvgPosItem(
double wx_=0.0,
double wy_=0.0,
double w_=0.0) : wx(wx_), wy(wy_), w(w_) {}
65 bool operator<(AvgPosItem
const & other)
const {
69 AvgPosItem &
operator+=(AvgPosItem
const & other) {
76 AvgPosItem &
operator-=(AvgPosItem
const & other) {
83 friend AvgPosItem
operator+(AvgPosItem a, AvgPosItem
const &
b) {
return a +=
b; }
85 friend AvgPosItem
operator-(AvgPosItem a, AvgPosItem
const & b) {
return a -=
b; }
91 afw::table::Key<double> weightKey
93 afw::table::Key<int> goodPixKey;
95 goodPixKey = catalog.getSchema()[
"goodpix"];
96 }
catch (pex::exceptions::NotFoundError &) {}
101 *i->getWcs()->pixelToSky(
102 i->getPsf()->getAveragePosition()
105 AvgPosItem item(p.getX(), p.getY(), i->get(weightKey));
106 if (goodPixKey.isValid()) {
107 item.w *= i->get(goodPixKey);
123 catalog.subsetContaining(result.getPoint(),
coaddWcs,
true).empty();
131 pex::exceptions::RuntimeError,
132 "Could not find a valid average position for CoaddPsf" 137 return result.getPoint();
149 _coaddWcs(coaddWcs.
clone()),
150 _warpingKernelName(warpingKernelName),
151 _warpingControl(
std::make_shared<afw::
math::WarpingControl>(warpingKernelName,
"", cacheSize))
159 mapper.addMapping(goodPixKey,
true);
165 _weightKey = mapper.addMapping(weightKey, weightField);
170 record->assign(*i, mapper);
173 _averagePosition = computeAveragePosition(_catalog, *_coaddWcs, _weightKey);
177 return std::make_shared<CoaddPsf>(*this);
191 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 = componentImg->getArray().asEigen().sum();
223 targetSubImage.
scaledPlus(weight/sum, cSubImage);
233 if (subcat.
empty()) {
236 (boost::format(
"Cannot compute BBox at point %s; no input images at that point.")
241 for (
auto const & exposureRecord : subcat) {
258 if (subcat.
empty()) {
261 (boost::format(
"Cannot compute CoaddPsf at point %s; no input images at that point.")
265 double weightSum = 0.0;
273 for (
auto const & exposureRecord : subcat) {
282 LSST_EXCEPT_ADD(exc, (boost::format(
"Computing WarpedPsf kernel image for id=%d") %
283 exposureRecord.getId()).str());
286 imgVector.push_back(componentImg);
287 weightSum += exposureRecord.get(_weightKey);
288 weightVector.
push_back(exposureRecord.get(_weightKey));
302 return _catalog.
size();
309 return _catalog[index].getPsf();
316 return _catalog[index].getWcs();
323 return _catalog[index].getValidPolygon();
330 return _catalog[index].
get(_weightKey);
337 return _catalog[index].getId();
344 return _catalog[index].getBBox();
355 namespace tbl = afw::table;
358 class CoaddPsfPersistenceHelper {
366 static CoaddPsfPersistenceHelper
const &
get() {
367 static CoaddPsfPersistenceHelper
const instance;
372 CoaddPsfPersistenceHelper() :
374 coaddWcs(schema.addField<
int>(
"coaddwcs",
"archive ID of the coadd's WCS")),
375 cacheSize(schema.addField<
int>(
"cachesize",
"size of the warping cache")),
377 schema,
"avgpos",
"PSF accessors default position",
"pixel" 381 schema.getCitizen().markPersistent();
390 virtual PTR(tbl::io::Persistable)
391 read(InputArchive const & archive, CatalogVector const & catalogs)
const {
392 if (catalogs.size() == 1u) {
396 return readV0(archive, catalogs);
399 CoaddPsfPersistenceHelper
const & keys1 = CoaddPsfPersistenceHelper::get();
404 tbl::ExposureCatalog::readFromArchive(archive, catalogs.back()),
406 record1.get(keys1.averagePosition),
407 record1.get(keys1.warpingKernelName),
408 record1.get(keys1.cacheSize)
420 readV0(InputArchive
const & archive, CatalogVector
const & catalogs)
const {
421 auto internalCat = tbl::ExposureCatalog::readFromArchive(archive, catalogs.front());
423 auto coaddWcs = internalCat.back().getWcs();
424 internalCat.pop_back();
430 weightKey = internalCat.getSchema()[
"weight"];
432 auto averagePos = computeAveragePosition(internalCat, *coaddWcs, weightKey);
442 std::string getCoaddPsfPersistenceName() {
return "CoaddPsf"; }
453 CoaddPsfPersistenceHelper
const & keys1 = CoaddPsfPersistenceHelper::get();
456 record1->set(keys1.coaddWcs, handle.put(_coaddWcs));
457 record1->set(keys1.cacheSize, _warpingControl->getCacheSize());
458 record1->set(keys1.averagePosition, _averagePosition);
459 record1->set(keys1.warpingKernelName, _warpingKernelName);
460 handle.saveCatalog(cat1);
461 _catalog.writeToArchive(handle,
false);
471 _catalog(catalog), _coaddWcs(coaddWcs), _weightKey(_catalog.getSchema()[
"weight"]),
472 _averagePosition(averagePosition), _warpingKernelName(warpingKernelName),
473 _warpingControl(new afw::
math::WarpingControl(warpingKernelName,
"", cacheSize))
afw::geom::Box2I getOverallBBox(std::vector< boost::shared_ptr< afw::image::Image< double > >> const &imgVector)
tbl::Key< double > weight
geom::Box2I getBBox(ImageOrigin origin=PARENT) const
afw::geom::Box2I getBBox(int index)
Get the bounding box (in component image Pixel coordinates) of the component image at index...
double getWeight(int index)
Get the weight of the component image at index.
#define LSST_ARCHIVE_ASSERT(EXPR)
void include(Point2I const &point)
std::shared_ptr< Table > getTable() const
virtual std::string getPythonModule() const
static Schema makeMinimalSchema()
boost::shared_ptr< afw::image::Wcs const > getWcs(int index)
Get the Wcs of the component image at index.
CoaddPsf(afw::table::ExposureCatalog const &catalog, afw::image::Wcs const &coaddWcs, std::string const &weightFieldName="weight", std::string const &warpingKernelName="lanczos3", int cacheSize=10000)
Main constructors for CoaddPsf.
constexpr Angle operator+(Angle a, Angle d) noexcept
virtual boost::shared_ptr< afw::detection::Psf > resized(int width, int height) const
Return a clone with specified kernel dimensions.
virtual std::string getPersistenceName() const
virtual void write(OutputArchiveHandle &handle) const
tbl::Key< int > cacheSize
int getComponentCount() const
Return the number of component Psfs in this CoaddPsf.
Factory(std::string const &name)
virtual afw::geom::Box2I doComputeBBox(afw::geom::Point2D const &position, afw::image::Color const &color) const
void push_back(Record const &r)
Point< double, 2 > Point2D
CoaddPsf is the Psf derived to be used for non-PSF-matched Coadd images.
void scaledPlus(double const c, Image< PixelT > const &rhs)
boost::shared_ptr< afw::detection::Psf::Image > doComputeKernelImage(afw::geom::Point2D const &ccdXY, afw::image::Color const &color) const
ExposureCatalogT subsetContaining(Coord const &coord, bool includeValidPolygon=false) const
Extent< double, N > & operator+=(Extent< double, N > &lhs, Extent< int, N > const &rhs)
#define LSST_EXCEPT(type,...)
tbl::Key< std::string > warpingKernelName
Base::const_iterator const_iterator
void addMinimalSchema(Schema const &minimal, bool doMap=true)
constexpr Angle operator-(Angle a, Angle d) noexcept
virtual boost::shared_ptr< afw::detection::Psf > clone() const
Polymorphic deep copy. Usually unnecessary, as Psfs are immutable.
void addToImage(boost::shared_ptr< afw::image::Image< double > > image, std::vector< boost::shared_ptr< afw::image::Image< double > >> const &imgVector, std::vector< double > const &weightVector)
std::shared_ptr< RecordT > const get(size_type i) const
io::OutputArchiveHandle OutputArchiveHandle
afw::table::Key< double > b
tbl::PointKey< double > averagePosition
void clip(Box2I const &other)
geom::Box2I computeBBox(geom::Point2D position=makeNullPoint(), image::Color color=image::Color()) const
ExposureCatalogT< ExposureRecord > ExposureCatalog
std::shared_ptr< Image > computeKernelImage(geom::Point2D position=makeNullPoint(), image::Color color=image::Color(), ImageOwnerEnum owner=COPY) const
Extent< double, N > & operator-=(Extent< double, N > &lhs, Extent< int, N > const &rhs)
std::shared_ptr< tbl::io::Persistable > readV0(InputArchive const &archive, CatalogVector const &catalogs) const
#define LSST_EXCEPT_ADD(e, m)
A Psf class that maps an arbitrary Psf through a coordinate transformation.
boost::shared_ptr< afw::detection::Psf const > getPsf(int index)
Get the Psf of the component image at index.
boost::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< RecordT > addNew()