New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DM-10429: Write a version of the warper that uses SkyWcs and compare performance #228
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, except that the interpolation section is a bit long.
|
||
# | ||
# LSST Data Management System | ||
# Copyright 2008, 2009, 2010 LSST Corporation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update copyright
int warpImage( | ||
DestMaskedImageT &destMaskedImage, | ||
SrcMaskedImageT const &srcMaskedImage, | ||
SeparableKernel &warpingKernel, int const interpLength=0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this C++ signature doing in Python code? Is this common?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left in by accident
def run(): | ||
if len(sys.argv) < 2: | ||
srcExposure = afwImage.ExposureF(InputExposurePath) | ||
if True: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this check? Just to have block scope? If so please indicate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It intended to allow warping the whole image (slower) instead of a subregion. I added a global constant to this and timeWarpExposure.py
to clarify this.
for interpLength in (0, 1, 5, 10): | ||
for scaleFac in (1.2,): | ||
destScale = srcScale / scaleFac | ||
for offset_deg_arcsec in ((0.0, 0.0),): # ((0.0, 0.0), (-35.0, 10.5)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uses different convention for variable naming.
include/lsst/afw/math/warpExposure.h
Outdated
* @param[in,out] destImage Destination image; all pixels are set | ||
* @param[in] srcImage Source image | ||
* @param[in] srcFromDest Transformation from destination to source parent pixel position | ||
* This can be computed as srcWcs.getInverse().of(destWcs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find this confusing, but that is probably just due to a lack of understanding on my part.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why source parent instead of just source?
I would find something like srcWcs.transformationFrom(destWcs)
more readable. But that might be incorrect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is also confusing in the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm afraid that's how it's done. Warping requires a transformation from destination pixel position to source. I could name it destToSrc but the same math is still required to derive it. Once our old image.Wcs
class is replaced with geom.SkyWcs
you can call the override of warpImage that takes the source and destination WCS directly, or call warpExposure
, and not have to think about it at all.
src/math/warpExposure.cc
Outdated
} | ||
return 0; | ||
} | ||
std::shared_ptr<SeparableKernel> warpingKernelPtr = control.getWarpingKernel(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why get it twice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or is it this call that can fail?
src/math/warpExposure.cc
Outdated
|
||
int const destWidth = destImage.getWidth(); | ||
int const destHeight = destImage.getHeight(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove (inconsistent) newline
tests/testWarpExposure.py
Outdated
warpedSkyWcs = afwGeom.SkyWcs(swarpedMetadata) | ||
|
||
# original image is source, warped image is destination | ||
srcFromDest = originalSkyWcs.getInverse().of(warpedSkyWcs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, this is confusing. See also the previous comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want it to be less confusing I fear some syntactic sugar may be required. I'm reluctant to fatten the API of SkyWcs
until we are further along, preferring to document what's going on, especially since (as I say above) few users will ever need to do this. The overload being tested will not be the main way anyone warps things when they are using WCS to specify the warping. It will primary be used for simple transformations such as shifts and rotations, and as the implementation for the usual overrides.
tests/testWarpExposure.py
Outdated
|
||
numGoodPix = afwMath.warpImage(afwWarpedMaskedImage, originalMaskedImage, | ||
srcFromDest, warpingControl) | ||
self.assertGreater(numGoodPix, 50) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why 50?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make sure that some pixels were warped.
|
||
detail::WarpAtOnePoint<DestImageT, SrcImageT> warpAtOnePoint(srcImage, control, padValue); | ||
|
||
if (interpLength > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The part in this branch can definitely benefit from some refactoring.
It looks ok, but there is way too much going on, I would suggest factoring some steps out into helper functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, but this situation is temporary and I couldn't see an easy way to share code between the two blocks. Once SkyWcs and Transform are adopted, the similar code that handles XYTransform will disappear, leaving only the new code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't thinking about sharing code between the blocks, but rather separating part of the one long block out a bit. It really is quite long. But there is no pressing need for it. Just feel like it would make it easier to grok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll take a stab at it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pschella I pushed an additional commit with some refactoring of the interpolated warping code. It's not a big change, but it cleans up some code and avoids messing with tight loops where performance is a concern.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to withdraw my most recent change. It needlessly caches row information that can be computed on the fly. A clever implementation could compute the end row/column of each band and the fractional width on the fly (storing almost nothing) because all bands except the last are the same width. But that's more cleverness than I want to code.
6371990
to
94d193b
Compare
src/math/warpExposure.cc
Outdated
} // for col | ||
// move points from srcPosList to prevSrcPosList (we don't care about what ends up in srcPosList | ||
// because it will be reallocated anyway) | ||
std::swap(srcPosList, prevSrcPosList); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally prefer using std::swap
to support user defined swap
operations. In this case it is a std::vector
so it doesn't matter, but we might change the type later :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. I hate how that makes it hard to tell where swap
is defined, but it does appear to be standard.
Added Endpoint.h and Transform.h to geom.h
Replace "if True" with a global variable to control whether `timeWarpExposure.py warps a subregion or the whole image
Add an overload of warpImage that uses a Transform<Point2Endpoint, Point2Endpoint> to describe the transform.
No description provided.