57 int nx = im.getWidth();
58 int ny = im.getHeight();
61 out->setXY0(im.getX0() - xPad, im.getY0() - yPad);
74 static const double maxTransformCoeff = 200.0;
77 throw LSST_EXCEPT(pex::exceptions::RangeError,
"Unexpectedly large transform passed to WarpedPsf");
85 auto const in_corners = in_box_fp.
getCorners();
86 for (
auto const & in_corner : in_corners) {
87 auto out_corner = t(in_corner);
116 afw::math::WarpingControl
const &wc) {
120 afw::math::SeparableKernel
const &kernel = *wc.getWarpingKernel();
122 int const xPad =
std::max(center.getX(), kernel.getWidth() - center.getX());
123 int const yPad =
std::max(center.getY(), kernel.getHeight() - center.getY());
126 geom::Box2I bbox = computeBBoxFromTransform(im.getBBox(), srcToDest);
145struct PreparedTransforms {
147 static PreparedTransforms compute(
148 afw::detection::Psf
const & src_psf,
155 *distortion.inverted(),
170 auto src_position = dest_to_src(rounded_dest_position);
176 auto src_to_dest_unrounded = unround * src_to_dest;
177 return PreparedTransforms{src_position, src_to_dest_unrounded};
192 _warpingControl(control) {
202 _warpingControl(new
afw::
math::WarpingControl(kernelName,
"", cache)) {
206void WarpedPsf::_init() {
209 "Undistorted Psf passed to WarpedPsf must not be None/NULL");
214 if (!_warpingControl) {
216 "WarpingControl passed to WarpedPsf must not be None/NULL");
241 prepared_transforms.src_to_dest_unrounded,
245 double normFactor = 1.0;
251 for (
int y = 0; y != ret->getHeight(); ++y) {
254 normFactor += *imPtr;
257 if (normFactor == 0.0) {
266 auto src_bbox =
_undistortedPsf->computeImageBBox(prepared_transforms.src_position, color);
267 return computeBBoxFromTransform(src_bbox, prepared_transforms.src_to_dest_unrounded);
272struct PersistenceHelper {
278 static PersistenceHelper
const &get() {
279 static PersistenceHelper
const instance;
286 psfIndex(schema.addField<int>(
"psfIndex",
"archive ID of nested Psf object")),
287 transformIndex(schema.addField<int>(
"transformIndex",
"archive ID of nested Transform object")),
289 schema.addField<int>(
"controlIndex",
"archive ID of nested WarpingControl object")) {}
292std::string _getPersistenceName() {
return "WarpedPsf"; }
294class :
public afw::table::io::PersistableFactory {
296 virtual std::shared_ptr<afw::table::io::Persistable>
read(
297 afw::table::io::InputArchive
const &archive,
298 afw::table::io::CatalogVector
const &catalogs)
const {
299 static PersistenceHelper
const &
keys = PersistenceHelper::get();
302 afw::table::BaseRecord
const &record =
catalogs.front().front();
305 archive.get<afw::detection::Psf>(record.get(
keys.psfIndex)),
307 archive.get<afw::math::WarpingControl>(record.get(
keys.controlIndex)));
311} warpedPsfFactory(_getPersistenceName());
319 static PersistenceHelper
const &keys = PersistenceHelper::get();
325 record->set(keys.controlIndex, handle.
put(_warpingControl));
#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.
image::Image< Pixel > Image
Image type returned by computeImage.
Describe the colour of a source.
typename _view_t::x_iterator x_iterator
A class used as a handle to a particular field in a table.
Defines the fields and offsets for a table.
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.
PersistableFactory(std::string const &name)
Constructor for the factory.
io::OutputArchiveHandle OutputArchiveHandle
A floating-point coordinate rectangle geometry.
Extent2D const getDimensions() const noexcept
1-d interval accessors
void include(Point2D const &point) noexcept
Expand this to ensure that this->contains(point).
std::vector< Point2D > getCorners() const
Get the corner points.
An integer coordinate rectangle.
void include(Point2I const &point)
Expand this to ensure that this->contains(point).
Box2I dilatedBy(Extent const &buffer) const
Increase the size of the box by the given amount(s) on all sides (returning a new object).
ImagePsf(bool isFixed=false)
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
std::shared_ptr< afw::detection::Psf > resized(int width, int height) const override
Return a clone with specified kernel dimensions.
geom::Point2D getAveragePosition() const override
Return the average of the positions of the stars that went into this Psf.
geom::Box2I doComputeBBox(geom::Point2D const &position, afw::image::Color const &color) const override
std::shared_ptr< afw::detection::Psf::Image > doComputeKernelImage(geom::Point2D const &position, 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::TransformPoint2ToPoint2 const > _distortion
std::shared_ptr< afw::detection::Psf const > _undistortedPsf
WarpedPsf(std::shared_ptr< afw::detection::Psf const > undistortedPsf, std::shared_ptr< afw::geom::TransformPoint2ToPoint2 const > distortion, std::shared_ptr< afw::math::WarpingControl const > control)
Construct WarpedPsf from unwarped psf and distortion.
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.
std::string getPythonModule() const override
Return the fully-qualified Python module that should be imported to guarantee that its factory is reg...
Reports invalid arguments.
Reports errors in the logical structure of the program.
std::shared_ptr< TransformPoint2ToPoint2 > makeTransform(lsst::geom::AffineTransform const &affine)
Wrap an lsst::geom::AffineTransform as a Transform.
Transform< Point2Endpoint, Point2Endpoint > TransformPoint2ToPoint2
lsst::geom::AffineTransform linearizeTransform(TransformPoint2ToPoint2 const &original, lsst::geom::Point2D const &inPoint)
Approximate a Transform by its local linearization.
int warpImage(DestImageT &destImage, geom::SkyWcs const &destWcs, SrcImageT const &srcImage, geom::SkyWcs const &srcWcs, WarpingControl const &control, typename DestImageT::SinglePixel padValue=lsst::afw::math::edgePixel< DestImageT >(typename lsst::afw::image::detail::image_traits< DestImageT >::image_category()))
Warp an Image or MaskedImage to a new Wcs.
CatalogT< BaseRecord > BaseCatalog
Extent< int, N > floor(Extent< double, N > const &input) noexcept
Return the component-wise floor (round towards more negative).
Point< double, 2 > PointD
Extent< double, 2 > Extent2D
Point< double, 2 > Point2D
Extent< int, 2 > Extent2I
std::shared_ptr< table::io::Persistable > read(table::io::InputArchive const &archive, table::io::CatalogVector const &catalogs) const override