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-14527: change origin for image accessors #369

Merged
merged 17 commits into from Jul 6, 2018
Merged

Conversation

TallJimbo
Copy link
Member

No description provided.

Copy link
Contributor

@fred3m fred3m left a comment

Choose a reason for hiding this comment

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

For the most part everything looks good. I think there are a few extra _get and _set methods that are unnecessary, but I like that you placed a number of functions in slicing.py that I can use for the multiband classes (to ensure consistency).

The only real API change I recommend is allowing negative indexing for images with origin = PARENT as long as XY0 > (0,0). See my comments below.

I also recommend removing a lot of the afwImage.PARENT arguments in the tests, since that is the default value and should work as expected without them.


.. currentmodule:: lsst.afw.image

LSST's image classes (`Image`, `Mask`, `MaskedImage`, and `Exposure`) use a pixel indexing convention that is different from both the convention used by `numpy.ndarray` objects and the convention used in FITS images.
Copy link
Contributor

Choose a reason for hiding this comment

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

I would make this and the next paragraph a warning to catch the readers attention.

Copy link
Member Author

Choose a reason for hiding this comment

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

Given that it's the first paragraph and the first thing readers on this page are going to see anyway, I think I disagree; warnings in docs are usually an aside, not the main text.

Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps, but I feel like there should be a warning to catch the careless reader's attention. Most of the "bug" reports that we've received for scarlet are people misinterpreting the coordinate convention, and as an often careless reader myself, I like it when people go out of their way to highlight potentially confusing conventions.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, maybe it'd work best if I added a warning box with new text, rather than stealing the old text for that.

>>> print(sub1.getBBox(LOCAL))
Box2I(minimum=Point2I(0, 0), dimensions=Extent2I(6, 7))

Note that the `PARENT` bounding box's minimum point is ``xy0``, while the `PARENT` bounding box's minimum point is ``(0, 0)``; this is *always* true.
Copy link
Contributor

Choose a reason for hiding this comment

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

This might want to be an actual .. note::

As in the previous case, when we make a subimage using a box in `PARENT`coordinates, the PARENT bounding box of the result is that same box.
When we make a subimage using a box in `LOCAL` coordinates, that input box is different from both the resulting subimage's `LOCAL` bounding box and its `PARENT` bounding box.

We strongly recommend using the `PARENT` convention whenever possible (which usually just means not explicitly selecting `LOCAL`, of course, since `PARENT` is the default).
Copy link
Contributor

Choose a reason for hiding this comment

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

note?

}}}} // namespace lsst::afw::image::python

#endif //! LSST_AFW_IMAGE_PYTHON_INDEXING_H

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure why this has to be implemented in C++. Wouldn't it be easier (and more straightforward) to just implement this method in python, or at the very least in the pybind11 wrapper?

Copy link
Member Author

@TallJimbo TallJimbo Jul 5, 2018

Choose a reason for hiding this comment

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

It is actually only used in the pybind11 wrappers (its in a header because it's used by multiple pybind11 wrappers), and it's there rather than in Python so we don't need to have both an unsafe _ method defined in pybind11 and a safe non-_ method defined in pure Python.


cls.def("set", [](ImageBase<PixelT> &img, PixelT val) { img = val; });
cls.def(
"_set",
Copy link
Contributor

Choose a reason for hiding this comment

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

I feel like _get and _set are unnecessary, since they could both be implemented as a single line in __getitem__ and __setitem__ in slicing.py or subset could be overloaded to take a Point2I and return a scalar.

Copy link
Member Author

Choose a reason for hiding this comment

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

The issue is that _get and _set are implemented differently for different types; they provide the common interface that allows slicing.py to not specialize for Image vs. MaskedImage vs. Exposure.

Copy link
Contributor

Choose a reason for hiding this comment

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

Right. I knew that was true for Exposure, which is enough to warrant a special method.

@@ -69,7 +69,7 @@ def makeRampImage(width, height, imgClass=afwImage.ImageF):
val = 0
for yInd in range(height):
for xInd in range(width):
im.set(xInd, yInd, val)
im[xInd, yInd, afwImage.PARENT] = val
Copy link
Contributor

Choose a reason for hiding this comment

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

see comment in test_background.py. There's no need to include the origin since PARENT is the default value.

@@ -140,10 +140,10 @@ def testArrays(self):
def testInitializeMasks(self):
val = 0x1234
msk = afwImage.Mask(lsst.geom.ExtentI(10, 10), val)
self.assertEqual(msk.get(0, 0), val)
self.assertEqual(msk[0, 0, afwImage.PARENT], val)
Copy link
Contributor

Choose a reason for hiding this comment

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

see comment in test_background.py. There's no need to include the origin since PARENT is the default value.

@@ -54,7 +54,7 @@ def testIo(self):
image = Image(self.cols, self.rows)
for x in range(0, self.cols):
for y in range(0, self.rows):
image.set(x, y, x + y)
image[x, y, afwImage.PARENT] = x + y
Copy link
Contributor

Choose a reason for hiding this comment

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

see comment in test_background.py. There's no need to include the origin since PARENT is the default value.

@@ -140,10 +140,10 @@ def testArrays(self):
def testInitializeMasks(self):
val = 0x1234
msk = afwImage.Mask(lsst.geom.ExtentI(10, 10), val)
self.assertEqual(msk.get(0, 0), val)
self.assertEqual(msk[0, 0, afwImage.PARENT], val)
Copy link
Contributor

Choose a reason for hiding this comment

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

see comment in test_background.py. There's no need to include the origin since PARENT is the default value.

@@ -145,7 +145,7 @@ def checkMaskedImage(self, mi):
mi1 = mi.Factory(mi, True)
plane0 = getattr(mi0, getName)()
plane1 = getattr(mi1, getName)()
plane1[2, 2] = errVal
plane1[2, 2, afwImage.PARENT] = errVal
Copy link
Contributor

Choose a reason for hiding this comment

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

see comment in test_background.py. There's no need to include the origin since PARENT is the default value.

@fred3m
Copy link
Contributor

fred3m commented Jul 6, 2018

Looks good, but it might be useful to update the docs regarding negative indices before merging.

@TallJimbo TallJimbo merged commit 7160de8 into master Jul 6, 2018
@jonathansick
Copy link
Member

Feel free to bring me into future documentation PRs for style feedback.

@ktlim ktlim deleted the tickets/DM-14527 branch August 25, 2018 06:44
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