Skip to content

Commit

Permalink
Merge pull request #311 from lsst/tickets/DM-13325
Browse files Browse the repository at this point in the history
Tickets/DM-13325: warpExposure does not propagate visitInfo

The requested changes were made, and the build passes Jenkins: https://ci.lsst.codes/blue/organizations/jenkins/stack-os-matrix/detail/stack-os-matrix/27399/pipeline/
  • Loading branch information
isullivan committed Jan 27, 2018
2 parents 3ec8770 + 064b153 commit 278b058
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 51 deletions.
99 changes: 48 additions & 51 deletions include/lsst/afw/math/warpExposure.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,17 @@ class Wcs;
namespace math {

/**
* Lanczos warping: accurate but slow and can introduce ringing artifacts.
*
* This kernel is the product of two 1-dimensional Lanczos functions.
* The number of minima and maxima in the 1-dimensional Lanczos function is 2*order + 1.
* The kernel has one pixel per function minimum or maximum; but as applied to warping,
* the first or last pixel is always zero and can be omitted. Thus the kernel size is 2*order x 2*order.
*
* For more information about warping kernels see makeWarpingKernel
*
* @todo: make a new class WarpingKernel and make this a subclass.
*/
* Lanczos warping: accurate but slow and can introduce ringing artifacts.
*
* This kernel is the product of two 1-dimensional Lanczos functions.
* The number of minima and maxima in the 1-dimensional Lanczos function is 2*order + 1.
* The kernel has one pixel per function minimum or maximum; but as applied to warping,
* the first or last pixel is always zero and can be omitted. Thus the kernel size is 2*order x 2*order.
*
* For more information about warping kernels see makeWarpingKernel
*
* @todo: make a new class WarpingKernel and make this a subclass.
*/
class LanczosWarpingKernel : public SeparableKernel {
public:
explicit LanczosWarpingKernel(int order ///< order of Lanczos function
Expand All @@ -73,23 +73,23 @@ class LanczosWarpingKernel : public SeparableKernel {
virtual std::shared_ptr<Kernel> clone() const;

/**
* get the order of the kernel
*/
* get the order of the kernel
*/
int getOrder() const;

protected:
virtual void setKernelParameter(unsigned int ind, double value) const;
};

/**
* Bilinear warping: fast; good for undersampled data.
*
* The kernel size is 2 x 2.
*
* For more information about warping kernels see makeWarpingKernel
*
* @todo: make a new class WarpingKernel and make this a subclass.
*/
* Bilinear warping: fast; good for undersampled data.
*
* The kernel size is 2 x 2.
*
* For more information about warping kernels see makeWarpingKernel
*
* @todo: make a new class WarpingKernel and make this a subclass.
*/
class BilinearWarpingKernel : public SeparableKernel {
public:
explicit BilinearWarpingKernel()
Expand Down Expand Up @@ -141,14 +141,14 @@ class BilinearWarpingKernel : public SeparableKernel {
};

/**
* Nearest neighbor warping: fast; good for undersampled data.
*
* The kernel size is 2 x 2.
*
* For more information about warping kernels see makeWarpingKernel
*
* @todo: make a new class WarpingKernel and make this a subclass.
*/
* Nearest neighbor warping: fast; good for undersampled data.
*
* The kernel size is 2 x 2.
*
* For more information about warping kernels see makeWarpingKernel
*
* @todo: make a new class WarpingKernel and make this a subclass.
*/
class NearestWarpingKernel : public SeparableKernel {
public:
explicit NearestWarpingKernel() : SeparableKernel(2, 2, NearestFunction1(0.0), NearestFunction1(0.0)) {}
Expand Down Expand Up @@ -277,7 +277,7 @@ class WarpingControl {
* Note the new cache is not computed until getWarpingKernel or getMaskWarpingKernel is called.
*/
void setCacheSize(int cacheSize ///< cache size
) {
) {
_cacheSize = cacheSize;
};

Expand All @@ -295,7 +295,7 @@ class WarpingControl {
* (and so is only intended for unit tests)
*/
void setInterpLength(int interpLength ///< interpolation length (pixels)
) {
) {
_interpLength = interpLength;
};

Expand All @@ -308,15 +308,15 @@ class WarpingControl {
* set the warping kernel by name
*/
void setWarpingKernelName(std::string const &warpingKernelName ///< name of warping kernel
);
);

/**
* set the warping kernel
*
* @throws lsst::pex::exceptions::InvalidParameterError if new kernel pointer is empty.
*/
void setWarpingKernel(SeparableKernel const &warpingKernel ///< warping kernel
);
);

/**
* get the mask warping kernel
Expand All @@ -333,15 +333,15 @@ class WarpingControl {
*/
void setMaskWarpingKernelName(std::string const &maskWarpingKernelName
///< name of mask warping kernel; use "" to clear the kernel
);
);

/**
* set the mask warping kernel
*
* @note To clear the mask warping kernel use setMaskWarpingKernelName("").
*/
void setMaskWarpingKernel(SeparableKernel const &maskWarpingKernel ///< mask warping kernel
);
);

/**
* get mask bits to grow to full width of image/variance kernel
Expand All @@ -353,7 +353,7 @@ class WarpingControl {
*/
void setGrowFullMask(lsst::afw::image::MaskPixel growFullMask ///< mask bits to grow to full width
///< of image/variance kernel
) {
) {
_growFullMask = growFullMask;
}

Expand Down Expand Up @@ -383,7 +383,7 @@ class WarpingControl {
template <typename DestExposureT, typename SrcExposureT>
int warpExposure(
DestExposureT &destExposure, ///< Remapped exposure. Wcs and xy0 are read, MaskedImage is set,
///< and Calib and Filter are copied from srcExposure.
///< and Calib, Filter, and visitInfo, are copied from srcExposure.
///< All other attributes are left alone (including Detector and Psf)
SrcExposureT const &srcExposure, ///< Source exposure
WarpingControl const &control, ///< control parameters
Expand All @@ -392,7 +392,7 @@ int warpExposure(
typename lsst::afw::image::detail::image_traits<
typename DestExposureT::MaskedImageT>::image_category())
///< use this value for undefined (edge) pixels
);
);

/**
* @brief Warp an Image or MaskedImage to a new Wcs. See also convenience function
Expand Down Expand Up @@ -443,7 +443,7 @@ int warpImage(DestImageT &destImage, ///< remapped %image
typename DestImageT::SinglePixel padValue = lsst::afw::math::edgePixel<DestImageT>(
typename lsst::afw::image::detail::image_traits<DestImageT>::image_category())
///< use this value for undefined (edge) pixels
);
);

/**
* @brief A variant of warpImage that uses an XYTransform instead of a pair of WCS
Expand All @@ -458,7 +458,7 @@ int warpImage(DestImageT &destImage, ///< remapped %i
typename DestImageT::SinglePixel padValue = lsst::afw::math::edgePixel<DestImageT>(
typename lsst::afw::image::detail::image_traits<DestImageT>::image_category())
///< use this value for undefined (edge) pixels
);
);

/**
* @brief A variant of warpImage that uses a TransformPoint2ToPoint2
Expand All @@ -474,14 +474,11 @@ int warpImage(DestImageT &destImage, ///< remapped %i
* @return the number of good pixels
*/
template <typename DestImageT, typename SrcImageT>
int warpImage(DestImageT &destImage,
SrcImageT const &srcImage,
geom::Transform<geom::Point2Endpoint, geom::Point2Endpoint> const & destToSrc,
int warpImage(DestImageT &destImage, SrcImageT const &srcImage,
geom::Transform<geom::Point2Endpoint, geom::Point2Endpoint> const &destToSrc,
WarpingControl const &control,
typename DestImageT::SinglePixel padValue = lsst::afw::math::edgePixel<DestImageT>(
typename lsst::afw::image::detail::image_traits<DestImageT>::image_category())
);

typename lsst::afw::image::detail::image_traits<DestImageT>::image_category()));

/**
* Warp an image with a LinearTranform about a specified point.
Expand All @@ -498,7 +495,7 @@ int warpCenteredImage(
typename DestImageT::SinglePixel padValue = lsst::afw::math::edgePixel<DestImageT>(
typename lsst::afw::image::detail::image_traits<DestImageT>::image_category())
///< use this value for undefined (edge) pixels
);
);

namespace details {
template <typename A, typename B>
Expand All @@ -510,9 +507,9 @@ template <typename A>
bool isSameObject(A const &a, A const &b) {
return &a == &b;
}
}
}
}
} // lsst::afw::math
} // namespace details
} // namespace math
} // namespace afw
} // namespace lsst

#endif // !defined(LSST_AFW_MATH_WARPEXPOSURE_H)
1 change: 1 addition & 0 deletions src/math/warpExposure.cc
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ int warpExposure(DestExposureT &destExposure, SrcExposureT const &srcExposure, W
std::shared_ptr<image::Calib> calibCopy(new image::Calib(*srcExposure.getCalib()));
destExposure.setCalib(calibCopy);
destExposure.setFilter(srcExposure.getFilter());
destExposure.getInfo()->setVisitInfo(srcExposure.getInfo()->getVisitInfo());
return warpImage(mi, *destExposure.getWcs(), srcExposure.getMaskedImage(), *srcExposure.getWcs(), control,
padValue);
}
Expand Down
23 changes: 23 additions & 0 deletions tests/test_warpExposure.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"""Test warpExposure
"""
from __future__ import absolute_import, division, print_function

import math
import os
import unittest
Expand Down Expand Up @@ -112,6 +113,25 @@ def makeWcs(pixelScale, crPixPos, crValCoord, posAng=afwGeom.Angle(0.0), doFlipX
return afwImage.makeWcs(ps)


def makeVisitInfo():
"""Return a non-NaN visitInfo."""
return afwImage.VisitInfo(exposureId=10313423,
exposureTime=10.01,
darkTime=11.02,
date=dafBase.DateTime(65321.1, dafBase.DateTime.MJD, dafBase.DateTime.TAI),
ut1=12345.1,
era=45.1*afwGeom.degrees,
boresightRaDec=afwCoord.IcrsCoord(23.1*afwGeom.degrees, 73.2*afwGeom.degrees),
boresightAzAlt=afwCoord.Coord(134.5*afwGeom.degrees, 33.3*afwGeom.degrees),
boresightAirmass=1.73,
boresightRotAngle=73.2*afwGeom.degrees,
rotType=afwImage.RotType.SKY,
observatory=afwCoord.Observatory(
11.1*afwGeom.degrees, 22.2*afwGeom.degrees, 0.333),
weather=afwCoord.Weather(1.1, 2.2, 34.5),
)


class WarpExposureTestCase(lsst.utils.tests.TestCase):
"""Test case for warpExposure
"""
Expand All @@ -135,6 +155,7 @@ def testNullWarpExposure(self, interpLength=10):
imageUtils.defineFiltersFromPolicy(filterPolicy, reset=True)

originalExposure = afwImage.ExposureF(originalExposurePath)
originalExposure.getInfo().setVisitInfo(makeVisitInfo())
originalFilter = afwImage.Filter("i")
originalCalib = afwImage.Calib()
originalCalib.setFluxMag0(1.0e5, 1.0e3)
Expand All @@ -154,6 +175,8 @@ def testNullWarpExposure(self, interpLength=10):
originalFilter.getName())
self.assertEqual(afwWarpedExposure.getCalib().getFluxMag0(),
originalCalib.getFluxMag0())
self.assertEqual(afwWarpedExposure.getInfo().getVisitInfo(),
originalExposure.getInfo().getVisitInfo())

afwWarpedMaskedImage = afwWarpedExposure.getMaskedImage()
afwWarpedMask = afwWarpedMaskedImage.getMask()
Expand Down

0 comments on commit 278b058

Please sign in to comment.