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-19256: Work for Aaron #131

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion policy/cameraHeader.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ CCD_E2V : &CCD_E2V

CCD_ITL : &CCD_ITL
detectorType : 0
refpos : [2036.5, 2000.5]
refpos : [2035.5, 1999.5]
offset : [.nan, .nan]
# This is the orientation we need to put the serial direction along the x-axis
bbox : [[0, 0], [4071, 3999]]
Expand Down
35 changes: 13 additions & 22 deletions python/lsst/obs/lsst/cameraTransforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,24 +366,18 @@ def ampPixelToCcdPixel(x, y, detector, channel):
"""

amp = channelToAmp(detector, channel)
rawBBox, rawDataBBox = amp.getRawBBox(), amp.getRawDataBBox()
bbox = amp.getRawDataBBox()

# Allow for flips (due e.g. to physical location of the amplifiers)
w, h = rawBBox.getDimensions()
x, y = geom.PointI(x, y) # definitely ints
w, h = bbox.getDimensions()
if amp.getRawFlipX():
rawBBox.flipLR(w)
rawDataBBox.flipLR(w)

x = rawBBox.getWidth() - x - 1
x = w - x - 1

if amp.getRawFlipY():
rawBBox.flipTB(h)
rawDataBBox.flipTB(h)

y = rawBBox.getHeight() - y - 1

dxy = rawBBox.getBegin() - rawDataBBox.getBegin() # correction for overscan etc.
y = h - y - 1

return amp.getBBox().getBegin() + dxy + geom.ExtentI(x, y)
return amp.getBBox().getBegin() + geom.ExtentI(x, y)


def ccdPixelToAmpPixel(xy, detector):
Expand Down Expand Up @@ -411,31 +405,28 @@ def ccdPixelToAmpPixel(xy, detector):
RuntimeError
If the requested pixel doesn't lie on the detector
"""
xy = geom.PointI(xy) # use pixel coordinates

found = False
for amp in detector:
if geom.BoxD(amp.getBBox()).contains(xy):
if amp.getBBox().contains(xy):
x, y = xy - amp.getBBox().getBegin() # coordinates within data segment
found = True
xy = geom.PointI(xy) # pixel coordinates as ints
break

if not found:
raise RuntimeError("Point (%g, %g) does not lie on detector %s" % (xy[0], xy[1], detector.getName()))

x, y = xy - amp.getBBox().getBegin() # offset from origin of amp's data segment

# Allow for flips (due e.g. to physical location of the amplifiers)
w, h = amp.getRawDataBBox().getDimensions()
w, h = amp.getBBox().getDimensions()

if amp.getRawFlipX():
x = w - x - 1

if amp.getRawFlipY():
y = h - y - 1

dxy = amp.getRawBBox().getBegin() - amp.getRawDataBBox().getBegin() # correction for overscan etc.
xy = geom.ExtentI(x, y) - dxy

return amp, xy
return amp, geom.PointI(x, y)


def focalMmToCcdPixel(camera, focalPlaneXY):
Expand Down
59 changes: 58 additions & 1 deletion tests/test_lsstCam.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@
import unittest

import lsst.utils.tests
from lsst.geom import arcseconds, Extent2I
from lsst.geom import arcseconds, Extent2I, PointD, PointI
import lsst.afw.image
from lsst.obs.lsst.cameraTransforms import LsstCameraTransforms

from lsst.obs.lsst.testHelper import ObsLsstButlerTests, ObsLsstObsBaseOverrides

Expand Down Expand Up @@ -162,6 +163,62 @@ def testDetectorName(self):
with self.assertRaises(RuntimeError):
self.mapper._extractDetectorName({'visit': 1})

def testCameraTransforms(self):
"""Test the geometry routines requested by the camera team

These are found in cameraTransforms.py"""

camera = self.butler.get('camera', immediate=True)

raft = 'R22'
sensor = 'S11'
ccdid = f"{raft}_{sensor}"

lct = LsstCameraTransforms(camera)

# check that we can map ccd pixels to amp pixels
for cxy, apTrue in [
((0, 0), (1, 508, 0)), # noqa: E241
((509, 0), (2, 508, 0)),
]:
ap = lct.ccdPixelToAmpPixel(*cxy, ccdid)
self.assertEqual(ap, apTrue)

# check inverse mapping
for ap, cpTrue in [
((508, 0, 1), (0, 0)),
((0, 0, 9), (4071, 3999)),
]:
cp = lct.ampPixelToCcdPixel(*ap, ccdid)
self.assertEqual(cp, PointI(*cpTrue))

# check round-tripping
ampX, ampY, channel = 2, 0, 1
cx, cy = lct.ampPixelToCcdPixel(ampX, ampY, channel, ccdid)
finalChannel, finalAmpX, finalAmpY = lct.ccdPixelToAmpPixel(cx, cy, ccdid)
self.assertEqual((finalAmpX, finalAmpY, finalChannel), (ampX, ampY, channel))

# Check that four amp pixels near the camera's centre are
# indeed close in focal plane coords
for ap, fpTrue in [
((508, 1999, 5), ( 0.005, -0.005)), # noqa: E201,E241
((0, 1999, 4), (-0.005, -0.005)), # noqa: E201,E241
((0, 1999, 13), (-0.005, 0.005)), # noqa: E201,E241
((508, 1999, 12), ( 0.005, 0.005)), # noqa: E201,E241
]:
fp = lct.ampPixelToFocalMm(*ap, ccdid)
self.assertAlmostEqual((fp - PointD(*fpTrue)).computeNorm(), 0.0)

# and for ccd coordinates:
for cp, fpTrue in [
((2035, 1999), (-0.005, -0.005)), # noqa: E201,E241
((2036, 1999), ( 0.005, -0.005)), # noqa: E201,E241
((2035, 2000), (-0.005, 0.005)), # noqa: E201,E241
((2036, 2000), ( 0.005, 0.005)), # noqa: E201,E241
]:
fp = lct.ccdPixelToFocalMm(*cp, ccdid)
self.assertAlmostEqual((fp - PointD(*fpTrue)).computeNorm(), 0.0)


class MemoryTester(lsst.utils.tests.MemoryTestCase):
pass
Expand Down