33 #include "boost/iterator/iterator_adaptor.hpp"
34 #include "boost/iterator/transform_iterator.hpp"
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 &) {}
97 std::vector<AvgPosItem> items;
98 items.reserve(catalog.size());
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);
111 items.push_back(item);
117 std::sort(items.begin(), items.end());
118 AvgPosItem result = std::accumulate(items.begin(), items.end(), AvgPosItem());
122 std::vector<AvgPosItem>::iterator
iter = items.begin();
123 catalog.subsetContaining(result.getPoint(),
coaddWcs,
true).empty();
126 if (
iter == items.end()) {
131 pex::exceptions::RuntimeError,
132 "Could not find a valid average position for CoaddPsf"
137 return result.getPoint();
145 std::string
const & weightFieldName,
149 _coaddWcs(coaddWcs.clone()),
150 _warpingKernelName(warpingKernelName),
151 _warpingControl(boost::make_shared<afw::math::WarpingControl>(warpingKernelName,
"", cacheSize))
159 mapper.addMapping(goodPixKey,
true);
160 }
catch (pex::exceptions::NotFoundError &) {}
165 _weightKey = mapper.addMapping(weightKey, weightField);
170 record->assign(*i, mapper);
177 return boost::make_shared<CoaddPsf>(*this);
187 for (
unsigned int i = 0; i < imgVector.size(); i ++) {
201 std::vector<double>
const & weightVector
203 assert(imgVector.size() == weightVector.size());
204 for (
unsigned int i = 0; i < imgVector.size(); i ++) {
206 double weight = weightVector[i];
207 double sum = componentImg->getArray().asEigen().sum();
219 targetSubImage.
scaledPlus(weight/sum, cSubImage);
225 afw::geom::
Point2D const & ccdXY,
226 afw::image::Color const & color
230 if (subcat.
empty()) {
232 pex::exceptions::InvalidParameterError,
233 (
boost::format(
"Cannot compute CoaddPsf at point %s; no input images at that point.")
237 double weightSum = 0.0;
242 std::vector<PTR(afw::image::Image<double>)> imgVector;
243 std::vector<double> weightVector;
251 imgVector.push_back(componentImg);
252 weightSum += i->get(_weightKey);
253 weightVector.push_back(i->get(_weightKey));
271 if (index < 0 || index > getComponentCount()) {
272 throw LSST_EXCEPT(pex::exceptions::RangeError,
"index of CoaddPsf component out of range");
274 return _catalog[index].getPsf();
278 if (index < 0 || index > getComponentCount()) {
279 throw LSST_EXCEPT(pex::exceptions::RangeError,
"index of CoaddPsf component out of range");
281 return _catalog[index].getWcs();
285 if (index < 0 || index > getComponentCount()) {
286 throw LSST_EXCEPT(pex::exceptions::RangeError,
"index of CoaddPsf component out of range");
288 return _catalog[index].getValidPolygon();
293 throw LSST_EXCEPT(pex::exceptions::RangeError,
"index of CoaddPsf component out of range");
300 throw LSST_EXCEPT(pex::exceptions::RangeError,
"index of CoaddPsf component out of range");
307 throw LSST_EXCEPT(pex::exceptions::RangeError,
"index of CoaddPsf component out of range");
320 namespace tbl = afw::table;
323 class CoaddPsfPersistenceHelper {
331 static CoaddPsfPersistenceHelper
const &
get() {
332 static CoaddPsfPersistenceHelper
const instance;
337 CoaddPsfPersistenceHelper() :
339 coaddWcs(
schema.addField<int>(
"coaddwcs",
"archive ID of the coadd's WCS")),
340 cacheSize(
schema.addField<int>(
"cachesize",
"size of the warping cache")),
342 schema,
"avgpos",
"PSF accessors default position",
"pixels"
346 schema.getCitizen().markPersistent();
355 virtual PTR(tbl::io::Persistable)
356 read(InputArchive const & archive, CatalogVector const & catalogs)
const {
357 CoaddPsfPersistenceHelper
const & keys1 = CoaddPsfPersistenceHelper::get();
363 tbl::ExposureCatalog::readFromArchive(archive, catalogs.back()),
365 record1.get(keys1.averagePosition),
366 record1.get(keys1.warpingKernelName),
367 record1.get(keys1.cacheSize)
372 Factory(std::string
const &
name) : tbl::io::PersistableFactory(name) {}
378 std::string getCoaddPsfPersistenceName() {
return "CoaddPsf"; }
380 CoaddPsf::Factory registration(getCoaddPsfPersistenceName());
389 CoaddPsfPersistenceHelper
const & keys1 = CoaddPsfPersistenceHelper::get();
407 _catalog(catalog), _coaddWcs(coaddWcs), _weightKey(_catalog.getSchema()[
"weight"]),
408 _averagePosition(averagePosition), _warpingKernelName(warpingKernelName),
409 _warpingControl(new afw::math::WarpingControl(warpingKernelName,
"", cacheSize))
afw::geom::Box2I getOverallBBox(std::vector< boost::shared_ptr< afw::image::Image< double > >> const &imgVector)
boost::shared_ptr< Image > computeKernelImage(geom::Point2D position=makeNullPoint(), image::Color color=image::Color(), ImageOwnerEnum owner=COPY) const
Return an Image of the PSF, in a form suitable for convolution.
int put(Persistable const *obj, bool permissive=false)
Save a nested Persistable to the same archive.
table::Key< std::string > name
Eigen matrix objects that present a view into an ndarray::Array.
tbl::Key< double > weight
afw::geom::Box2I getBBox(int index)
An object passed to Persistable::write to allow it to persist itself.
double getWeight(int index)
A custom container class for records, based on std::vector.
afw::table::Schema schema
Include files required for standard LSST Exception handling.
A mapping between the keys of two Schemas, used to copy data between them.
void include(Point2I const &point)
Expand this to ensure that this->contains(point).
memId getId() const
Return the Citizen's ID.
afw::geom::Point2D _averagePosition
static Schema makeMinimalSchema()
Return a minimal schema for Exposure tables and records.
Point< double, 2 > Point2D
std::string _warpingKernelName
boost::shared_ptr< afw::image::Wcs const > _coaddWcs
geom::Box2I getBBox(ImageOrigin origin=PARENT) const
Extent< double, N > & operator+=(Extent< double, N > &lhs, Extent< int, N > const &rhs)
void writeToArchive(io::OutputArchiveHandle &handle, bool ignoreUnpersistable=true) const
Convenience output function for Persistables that contain an ExposureCatalog.
afw::table::Key< double > _weightKey
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.
Implementation of the WCS standard for a any projection.
Extent< double, N > & operator-=(Extent< double, N > &lhs, Extent< int, N > const &rhs)
size_type size() const
Return the number of elements in the catalog.
boost::enable_if< typename ExpressionTraits< Scalar >::IsScalar, Scalar >::type sum(Scalar const &scalar)
An integer coordinate rectangle.
tbl::Key< int > cacheSize
table::Key< table::Array< Kernel::Pixel > > image
Factory(std::string const &name)
virtual std::string getPersistenceName() const
Return the unique name used to persist this object and look up its factory.
const Angle operator+(Angle const a, Angle const d)
void scaledPlus(double const c, Image< PixelT >const &rhs)
Add Image c*rhs to lhs.
bool empty() const
Return true if the catalog has no records.
void push_back(Record const &r)
Add a copy of the given record to the end of the catalog.
afw::table::ExposureCatalog _catalog
CoaddPsf is the Psf derived to be used for non-PSF-matched Coadd images.
Iterator class for CatalogT.
int getComponentCount() const
Return the number of component Psfs in this CoaddPsf.
A description of a field in a table.
virtual boost::shared_ptr< tbl::io::Persistable > read(InputArchive const &archive, CatalogVector const &catalogs) const
ExposureCatalogT subsetContaining(Coord const &coord, bool includeValidPolygon=false) const
Return a shallow subset of the catalog with only those records that contain the given point...
boost::shared_ptr< afw::math::WarpingControl const > _warpingControl
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
lsst::afw::image::Wcs Wcs
#define LSST_EXCEPT(type,...)
tbl::Key< std::string > warpingKernelName
Base class for all records.
boost::shared_ptr< RecordT > const get(size_type i) const
Return a pointer to the record at index i.
Base::const_iterator const_iterator
void addMinimalSchema(Schema const &minimal, bool doMap=true)
Add the given minimal schema to the output schema.
boost::shared_ptr< Table > getTable() const
Return the table associated with the catalog.
Custom catalog class for ExposureRecord/Table.
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)
boost::shared_ptr< RecordT > addNew()
Create a new record, add it to the end of the catalog, and return a pointer to it.
Compute Image Statistics.
afw::table::Key< double > b
Record class used to store exposure metadata.
virtual void write(OutputArchiveHandle &handle) const
Write the object to one or more catalogs.
tbl::PointKey< double > averagePosition
void clip(Box2I const &other)
Shrink this to ensure that other.contains(*this).
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
ExposureCatalogT< ExposureRecord > ExposureCatalog
virtual std::string getPythonModule() const
Return the fully-qualified Python module that should be imported to guarantee that its factory is reg...
A polymorphic base class for representing an image's Point Spread Function.
A class to represent a 2-dimensional array of pixels.
const Angle operator-(Angle const a, Angle const d)
Schema getSchema() const
Return the schema associated with the catalog's table.
boost::int64_t RecordId
Type used for unique IDs for records.
A Psf class that maps an arbitrary Psf through a coordinate transformation.