33 #include "boost/iterator/iterator_adaptor.hpp" 34 #include "boost/iterator/transform_iterator.hpp" 35 #include "ndarray/eigen.h" 49 namespace algorithms {
60 explicit AvgPosItem(
double wx_ = 0.0,
double wy_ = 0.0,
double w_ = 0.0) : wx(wx_), wy(wy_), w(w_) {}
66 bool operator<(AvgPosItem
const &
other)
const {
return w < other.w; }
68 AvgPosItem &
operator+=(AvgPosItem
const &other) {
75 AvgPosItem &
operator-=(AvgPosItem
const &other) {
82 friend AvgPosItem
operator+(AvgPosItem
a, AvgPosItem
const &
b) {
return a +=
b; }
84 friend AvgPosItem
operator-(AvgPosItem a, AvgPosItem
const &b) {
return a -=
b; }
88 afw::geom::SkyWcs
const &
coaddWcs, afw::table::Key<double> weightKey) {
89 afw::table::Key<int> goodPixKey;
91 goodPixKey = catalog.getSchema()[
"goodpix"];
92 }
catch (pex::exceptions::NotFoundError &) {
97 geom::Point2D p = coaddWcs.skyToPixel(i->getWcs()->pixelToSky(i->getPsf()->getAveragePosition()));
98 AvgPosItem item(p.getX(), p.getY(), i->get(weightKey));
99 if (goodPixKey.isValid()) {
100 item.w *= i->get(goodPixKey);
115 catalog.subsetContaining(result.getPoint(),
coaddWcs,
true).empty(); ++iter) {
116 if (iter == items.
end()) {
121 "Could not find a valid average position for CoaddPsf");
125 return result.getPoint();
132 : _coaddWcs(coaddWcs),
133 _warpingKernelName(warpingKernelName),
134 _warpingControl(
std::make_shared<afw::math::WarpingControl>(warpingKernelName,
"", cacheSize)) {
141 mapper.addMapping(goodPixKey,
true);
148 _weightKey =
mapper.addMapping(weightKey, weightField);
153 record->assign(*i,
mapper);
156 _averagePosition = computeAveragePosition(_catalog, _coaddWcs, _weightKey);
171 for (
unsigned int i = 0; i < imgVector.size(); i++) {
184 assert(imgVector.size() == weightVector.
size());
185 for (
unsigned int i = 0; i < imgVector.size(); i++) {
187 double weight = weightVector[i];
188 double sum = ndarray::asEigenMatrix(componentImg->getArray()).sum();
200 targetSubImage.
scaledPlus(weight / sum, cSubImage);
206 if (subcat.
empty()) {
209 (boost::format(
"Cannot compute BBox at point %s; no input images at that point.") % ccdXY)
214 for (
auto const &exposureRecord : subcat) {
218 geom::Box2I componentBBox = warpedPsf.computeBBox(ccdXY, color);
229 if (subcat.
empty()) {
232 (boost::format(
"Cannot compute CoaddPsf at point %s; no input images at that point.") % ccdXY)
235 double weightSum = 0.0;
243 for (
auto const &exposureRecord : subcat) {
251 LSST_EXCEPT_ADD(exc, (boost::format(
"Computing WarpedPsf kernel image for id=%d") %
252 exposureRecord.getId())
256 imgVector.push_back(componentImg);
257 weightSum += exposureRecord.get(_weightKey);
258 weightVector.
push_back(exposureRecord.get(_weightKey));
277 return _catalog[index].getPsf();
284 return *_catalog[index].getWcs();
291 return _catalog[index].getValidPolygon();
298 return _catalog[index].
get(_weightKey);
305 return _catalog[index].getId();
312 return _catalog[index].getBBox();
324 class CoaddPsfPersistenceHelper {
332 static CoaddPsfPersistenceHelper
const &
get() {
333 static CoaddPsfPersistenceHelper
const instance;
338 CoaddPsfPersistenceHelper()
340 coaddWcs(schema.addField<
int>(
"coaddwcs",
"archive ID of the coadd's WCS")),
341 cacheSize(schema.addField<
int>(
"cachesize",
"size of the warping cache")),
343 schema,
"avgpos",
"PSF accessors default position",
"pixel")),
345 schema.addField<
std::string>(
"warpingkernelname",
"warping kernel name", 32)) {
346 schema.getCitizen().markPersistent();
356 if (catalogs.size() == 1u) {
360 return readV0(archive, catalogs);
363 CoaddPsfPersistenceHelper
const &keys1 = CoaddPsfPersistenceHelper::get();
369 record1.get(keys1.averagePosition), record1.get(keys1.warpingKernelName),
370 record1.get(keys1.cacheSize)));
382 auto coaddWcs = internalCat.back().getWcs();
383 internalCat.pop_back();
389 weightKey = internalCat.getSchema()[
"weight"];
392 auto averagePos = computeAveragePosition(internalCat, *coaddWcs, weightKey);
401 std::string getCoaddPsfPersistenceName() {
return "CoaddPsf"; }
412 CoaddPsfPersistenceHelper
const &keys1 = CoaddPsfPersistenceHelper::get();
415 auto coaddWcsPtr = std::make_shared<afw::geom::SkyWcs>(_coaddWcs);
416 record1->set(keys1.coaddWcs, handle.put(coaddWcsPtr));
417 record1->set(keys1.cacheSize, _warpingControl->getCacheSize());
418 record1->set(keys1.averagePosition, _averagePosition);
419 record1->set(keys1.warpingKernelName, _warpingKernelName);
420 handle.saveCatalog(cat1);
421 _catalog.writeToArchive(handle,
false);
428 _weightKey(_catalog.getSchema()[
"weight"]),
429 _averagePosition(averagePosition),
430 _warpingKernelName(warpingKernelName),
431 _warpingControl(new afw::math::WarpingControl(warpingKernelName,
"", cacheSize)) {}
afw::table::Key< std::string > warpingKernelName
double getWeight(int index)
Get the weight of the component image at index.
ExposureCatalogT subsetContaining(lsst::geom::SpherePoint const &coord, bool includeValidPolygon=false) const
#define LSST_ARCHIVE_ASSERT(EXPR)
std::vector< SchemaItem< Flag > > * items
std::shared_ptr< Table > getTable() const
virtual std::string getPythonModule() const
geom::Box2I getBBox(int index)
Get the bounding box (in component image Pixel coordinates) of the component image at index...
static PointKey addFields(Schema &schema, std::string const &name, std::string const &doc, std::string const &unit)
static Schema makeMinimalSchema()
constexpr Angle operator+(Angle a, Angle d) noexcept
Extent< double, N > & operator+=(Extent< double, N > &lhs, Extent< int, N > const &rhs) noexcept
ItemVariant const * other
boost::shared_ptr< afw::detection::Psf::Image > doComputeKernelImage(geom::Point2D const &ccdXY, afw::image::Color const &color) const
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
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.
afw::table::Key< int > cacheSize
virtual void write(OutputArchiveHandle &handle) const
afw::table::Schema schema
Point< double, 2 > Point2D
int getComponentCount() const
Return the number of component Psfs in this CoaddPsf.
Factory(std::string const &name)
Extent< double, N > & operator-=(Extent< double, N > &lhs, Extent< int, N > const &rhs) noexcept
constexpr Angle operator-(Angle a, Angle d) noexcept
void push_back(Record const &r)
afw::table::Key< int > coaddWcs
lsst::geom::Box2I getBBox(ImageOrigin origin=PARENT) const
afw::table::PointKey< double > averagePosition
CoaddPsf is the Psf derived to be used for non-PSF-matched Coadd images.
virtual geom::Box2I doComputeBBox(geom::Point2D const &position, afw::image::Color const &color) const
std::shared_ptr< afw::table::io::Persistable > readV0(InputArchive const &archive, CatalogVector const &catalogs) const
void scaledPlus(double const c, Image< PixelT > const &rhs)
std::unique_ptr< SchemaItem< U > > result
std::shared_ptr< TransformPoint2ToPoint2 > makeWcsPairTransform(SkyWcs const &src, SkyWcs const &dst)
#define LSST_EXCEPT(type,...)
Base::const_iterator const_iterator
void include(Point2I const &point)
afw::geom::SkyWcs getWcs(int index)
Get the Wcs of the component image at index.
geom::Box2I getOverallBBox(std::vector< boost::shared_ptr< afw::image::Image< double > >> const &imgVector)
virtual boost::shared_ptr< afw::detection::Psf > clone() const
Polymorphic deep copy. Usually unnecessary, as Psfs are immutable.
static ExposureCatalogT readFromArchive(io::InputArchive const &archive, BaseCatalog const &catalog)
void clip(Box2I const &other) noexcept
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< Image > computeKernelImage(lsst::geom::Point2D position=makeNullPoint(), image::Color color=image::Color(), ImageOwnerEnum owner=COPY) const
std::shared_ptr< RecordT > const get(size_type i) const
io::OutputArchiveHandle OutputArchiveHandle
afw::table::Key< double > b
afw::table::Key< double > weight
ExposureCatalogT< ExposureRecord > ExposureCatalog
#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< BaseRecord > addNew()