Skip to content
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

Merged
merged 4 commits into from May 17, 2017

Conversation

r-owen
Copy link
Contributor

@r-owen r-owen commented May 15, 2017

No description provided.

Copy link

@pschella pschella left a 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.

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);

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?

Copy link
Contributor Author

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:

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.

Copy link
Contributor Author

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)):

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.

* @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)

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.

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.

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.

Copy link
Contributor Author

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.

}
return 0;
}
std::shared_ptr<SeparableKernel> warpingKernelPtr = control.getWarpingKernel();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why get it twice?

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?


int const destWidth = destImage.getWidth();
int const destHeight = destImage.getHeight();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove (inconsistent) newline

warpedSkyWcs = afwGeom.SkyWcs(swarpedMetadata)

# original image is source, warped image is destination
srcFromDest = originalSkyWcs.getInverse().of(warpedSkyWcs)

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.

Copy link
Contributor Author

@r-owen r-owen May 15, 2017

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.


numGoodPix = afwMath.warpImage(afwWarpedMaskedImage, originalMaskedImage,
srcFromDest, warpingControl)
self.assertGreater(numGoodPix, 50)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why 50?

Copy link
Contributor Author

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) {

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.

Copy link
Contributor Author

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.

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

@r-owen r-owen May 17, 2017

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.

@r-owen r-owen force-pushed the tickets/DM-10429 branch 4 times, most recently from 6371990 to 94d193b Compare May 16, 2017 00:06
} // 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);

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 :)

Copy link
Contributor Author

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.
@r-owen r-owen merged commit 05b99cd into master May 17, 2017
@ktlim ktlim deleted the tickets/DM-10429 branch August 25, 2018 06:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants