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-12447: Remove TransformMap.transform, Camera.transform and Detector.transform #321
Conversation
b9bad62
to
864d052
Compare
Can you state the reason for the removal in the commit log? |
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 think we absolutely need a method that will do getTransform
followed by applyForward
.
detPixelsSys = det.makeCameraSys(cameraGeom.PIXELS) | ||
detPointOnSpecifiedDetector = camera.transform(fieldPoint, detPixelsSys) | ||
detPointOnFoundDetector = camera.transform(fieldPoint, cameraGeom.PIXELS) | ||
assert detPointOnFoundDetector.getCameraSys() == detPixelsSys # same detector |
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 is this gone? Does this represent loss of functionality?
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.
Having Camera.transform
search for a detector is gone. I don't think it's practical to implement it with CameraPoint
gone. In my opinion it was never a good idea, as it could be quite slow, which could surprise users. I would much rather have users explicitly search for a detector if necessary.
Note that I found no instances where this feature was used, other than this example.
/** | ||
* A Point2D with associated camera coordinate system | ||
*/ | ||
class CameraPoint { |
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.
This used to be viewed as an important element of the design that made sure the user knew which coordinate system the points are in. Please explain in the commit log message why it is now being jettisoned.
"""!Transform a CameraPoint with a CameraSys to another CameraSys. | ||
return det.getTransformMap().getTransform(fromSys, toSys) | ||
else: | ||
return self.getTransformMap().getTransform(fromSys, toSys) |
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 think the logic above should be refactored to eliminate duplicated code:
det = self
if fromSys.hasDetectorName():
det = self[fromSys.getDetectorName()]
elif toSys.hasDetectorName():
det = self[toSys.getDetectorName()]
return det.getTransformMap().getTransform(fromSys, toSys)
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.
Your suggested new code does not do the same thing because the else
clause handles the camera's own transform map, not a detector's transform map.
I suppose we could retrieve the transform map. It will be a bit awkward since we then have to assume the code will never leave the transform map equal to None (which will be true initially, but perhaps not if the code evolves) or check for None even though it should be impossible. That is why I chose to use the current technique.
cameraPoint, self._nativeCameraSys) | ||
# convert `point` to the native coordinate system | ||
transform = self._getTransformFromOneTransformMap(cameraSys, self._nativeCameraSys) | ||
nativePoint = transform.applyForward(point) | ||
|
||
detectorList = [] |
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 is there a list of detectors, as if a point could be on multiple detectors?
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.
Because a point can be on multiple detectors. I don't believe any instruments presently use that capability, but an imaging instrument with a beamsplitter certainly would.
Note that this is a pre-existing capability that has been retained.
@@ -196,31 +156,19 @@ def getTransformMap(self): | |||
""" | |||
return self._transformMap | |||
|
|||
def transform(self, cameraPoint, toSys): |
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.
Don't want a camera.transform(point, fromSys, toSys)
?
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 added that in a subsequent commit.
fa58ac7
to
df0a8ae
Compare
What is the functionality that you've removed (the one that you didn't find in the live)?
|
@RobertLuptonTheGood Having Camera.transform search for a detector (if a camera system prefix was specified). It is a very expensive operation and it is doubtful that anyone reading the code would realize that. |
* | ||
* @tparam FromSysT Class of fromSys: one of CameraSys or CameraSysPrefix | ||
* @tparam ToSysT Class of toSys: one of CameraSys or CameraSysPrefix | ||
* @param[in] point Camera point to transform |
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.
points
, plural.
* @tparam FromSysT Class of fromSys: one of CameraSys or CameraSysPrefix | ||
* @tparam ToSysT Class of toSys: one of CameraSys or CameraSysPrefix | ||
* @param[in] point Camera point to transform | ||
* @param[in] fromSys Camera coordinate system of `point` |
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.
Ditto.
python/lsst/afw/cameraGeom/camera.py
Outdated
@@ -173,3 +165,25 @@ def getTransform(self, fromSys, toSys): | |||
fromSysToNative = self._getTransformFromOneTransformMap(fromSys, self._nativeCameraSys) | |||
nativeToToSys = self._getTransformFromOneTransformMap(self._nativeCameraSys, toSys) | |||
return fromSysToNative.then(nativeToToSys) | |||
|
|||
def getTransformMap(self): |
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 a getter instead of the more pythonic property
?
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.
That is existing functionality (I think github is a bit confused about what changed).
It's a good idea, but I'd rather that be a separate RFC and ticket.
@@ -70,7 +102,7 @@ PYBIND11_PLUGIN(_detector) { | |||
table::AmpInfoCatalog const &, Orientation const &, geom::Extent2D const &, | |||
TransformMap::Transforms const &, Detector::CrosstalkMatrix const &>(), | |||
"name"_a, "id"_a, "type"_a, "serial"_a, "bbox"_a, "ampInfoCatalog"_a, "orientation"_a, | |||
"pixelSize"_a, "transforms"_a, "crosstalk"_a=Detector::CrosstalkMatrix()); | |||
"pixelSize"_a, "transforms"_a, "crosstalk"_a = Detector::CrosstalkMatrix()); |
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.
Formatting change shouldn't be included.
python/lsst/afw/cameraGeom/utils.py
Outdated
posFocalPlane = fieldAngleToFocalPlane.applyForward(posFieldAngle) | ||
|
||
# compute focal plane positions corresponding to field angles field_gridx, field_gridy | ||
posFieldAngleRadiansList = [afwGeom.Point2D(x.asRadians(), y.asRadians()) |
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 think you're turning Hungarian... Having such long variable names isn't good.
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 am Hungarian. But I'll get rid of "Radians"
python/lsst/afw/cameraGeom/utils.py
Outdated
# compute focal plane positions corresponding to field angles field_gridx, field_gridy | ||
posFieldAngleRadiansList = [afwGeom.Point2D(x.asRadians(), y.asRadians()) | ||
for x, y in zip(field_gridx, field_gridy)] | ||
posFocalPlaneList = camera.transform(posFieldAngleRadiansList, FIELD_ANGLE, FOCAL_PLANE) |
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 isn't std::pair<Angle, Angle>
not a supported endpoint type?
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 think that adds too much complexity, especially because it also requires adding support for std::vector<std::pair<Angle, Angle>>
and adding a new Endpoint type. In any case it is clearly out of scope for this ticket.
std::vector<geom::Point2D> Detector::transform(std::vector<geom::Point2D> const &points, | ||
FromSysT const &fromSys, ToSysT const &toSys) const { | ||
return _transformMap.transform(points, makeCameraSys(fromSys), makeCameraSys(toSys)); | ||
} |
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 surprised these aren't defined in the header, since they're so simple.
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 prefer to define functions in the .cc file unless there's a good reason to do otherwse (e.g. inlining a method. It reduces clutter in the header saves on compilation time if something changes.
template std::shared_ptr<geom::TransformPoint2ToPoint2> Detector::getTransform(FROMSYS const &, \ | ||
TOSYS const &) const; \ | ||
template geom::Point2D Detector::transform(geom::Point2D const &, FROMSYS const &, TOSYS const &) const; \ | ||
template std::vector<geom::Point2D> Detector::transform(std::vector<geom::Point2D> const &, \ |
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.
For the same reason we don't line up equal signs in a list of equations, I suggest not spacing out the backslashes.
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.
clang-format
tests/test_detector.py
Outdated
pixPoint = dw.detector.transform(fpPoint, cameraGeom.FOCAL_PLANE, cameraGeom.PIXELS) | ||
for i in range(2): | ||
self.assertAlmostEqual( | ||
fpPoint[i]/dw.pixelSize[i] + pixOffset[i], pixPoint[i]) |
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.
Instead of iteration, can't you do this with Point
and Extent
arithmetic?
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.
Interesting idea. I tried fpPoint/dw.pixelSize + pixOffset
but it was rejected with TypeError: unsupported operand type(s) for /: 'lsst.afw.geom.coordinates.coordinates.Point2D' and 'lsst.afw.geom.coordinates.coordinates.Extent2D'
I'll stick to this for now -- it is existing code and known to work.
df0a8ae
to
2802a1a
Compare
Remove `CameraPoint` Add support for transforming lists of points. Remove support for `Camera.transform` searching for a suitable detector. It was very inefficient and it would be difficult to tell that code was using it. Fortunately it was not used anywhere.
Also fix broken links.
2802a1a
to
607a0d2
Compare
I rebased my changes |
and CameraPoint