Skip to content

Commit

Permalink
Ensure that the gain is properly applied/not applied in isrTaskLSST C…
Browse files Browse the repository at this point in the history
…TI correction
  • Loading branch information
Alex-Broughton committed Sep 18, 2024
1 parent b8f139f commit 9d88ca9
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 14 deletions.
3 changes: 1 addition & 2 deletions python/lsst/ip/isr/deferredCharge.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ def readout(self, serial_overscan_width=10, parallel_overscan_width=0):
released_charge = trap.release_charge()
free_charge += released_charge

return image
return image/float(self.output_amplifier.gain)


class FloatingOutputAmplifier:
Expand Down Expand Up @@ -1105,7 +1105,6 @@ def run(self, exposure, ctiCalib, gains=None):

# The algorithm expects that the readout corner is in
# the lower left corner. Flip it to be so:

ampData = self.flipData(ampImage.array, amp)

if ctiCalib.driftScale[ampName] > 0.0:
Expand Down
47 changes: 36 additions & 11 deletions python/lsst/ip/isr/isrMock.py
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ def makeImage(self):
return exposure

# afw primatives to construct the image structure
def getCamera(self):
def getCamera(self, isForAssembly=False):
"""Construct a test camera object.
Returns
Expand All @@ -557,7 +557,7 @@ def getCamera(self):
cameraWrapper = afwTestUtils.CameraWrapper(
plateScale=self.config.plateScale,
radialDistortion=self.config.radialDistortion,
isLsstLike=self.config.isLsstLike,
isLsstLike=self.config.isLsstLike and isForAssembly,
)
camera = cameraWrapper.camera
return camera
Expand Down Expand Up @@ -585,14 +585,16 @@ def getExposure(self, isTrimmed=None):
else:
_isTrimmed = isTrimmed

camera = self.getCamera()
camera = self.getCamera(isForAssembly=self.config.isLsstLike)
detector = camera[self.config.detectorIndex]
image = afwUtils.makeImageFromCcd(detector,
isTrimmed=_isTrimmed,
showAmpGain=False,
rcMarkSize=0,
binSize=1,
imageFactory=afwImage.ImageF)
image = afwUtils.makeImageFromCcd(
detector,
isTrimmed=_isTrimmed,
showAmpGain=False,
rcMarkSize=0,
binSize=1,
imageFactory=afwImage.ImageF,
)

var = afwImage.ImageF(image.getDimensions())
mask = afwImage.Mask(image.getDimensions())
Expand Down Expand Up @@ -622,27 +624,50 @@ def getExposure(self, isTrimmed=None):
'UR': ReadoutCorner.UR,
'UL': ReadoutCorner.UL,
}

for amp in ccd:
newAmp = amp.rebuild()
newAmp.setLinearityCoeffs((0., 1., 0., 0.))
newAmp.setLinearityType("Polynomial")
newAmp.setGain(self.config.gain)
newAmp.setSuspectLevel(25000.0)
newAmp.setSaturation(32000.0)
readoutCorner = amp.getReadoutCorner().name

# Apply flips to bbox where needed
imageBBox = amp.getRawDataBBox()
rawBbox = amp.getRawBBox()
parallelOscanBBox = amp.getRawParallelOverscanBBox()
serialOscanBBox = amp.getRawSerialOverscanBBox()
prescanBBox = amp.getRawPrescanBBox()
readoutCorner = amp.getReadoutCorner().name

if self.config.isLsstLike:
# This follows cameraGeom.testUtils
xoffset, yoffset = amp.getRawXYOffset()
offext = lsst.geom.Extent2I(xoffset, yoffset)
flipx = bool(amp.getRawFlipX())
flipy = bool(amp.getRawFlipY())
if flipx:
xExt = rawBbox.getDimensions().getX()
rawBbox.flipLR(xExt)
imageBBox.flipLR(xExt)
parallelOscanBBox.flipLR(xExt)
serialOscanBBox.flipLR(xExt)
prescanBBox.flipLR(xExt)
if flipy:
yExt = rawBbox.getDimensions().getY()
rawBbox.flipTB(yExt)
imageBBox.flipTB(yExt)
parallelOscanBBox.flipTB(yExt)
serialOscanBBox.flipTB(yExt)
prescanBBox.flipTB(yExt)
if not flipx and not flipy:
readoutCorner = 'LL'
elif flipx and not flipy:
readoutCorner = 'LR'
elif flipx and flipy:
readoutCorner = 'UR'
elif not flipx and flipy:
readoutCorner = 'UL'
rawBbox.shift(offext)
imageBBox.shift(offext)
parallelOscanBBox.shift(offext)
Expand Down
10 changes: 9 additions & 1 deletion python/lsst/ip/isr/isrTaskLSST.py
Original file line number Diff line number Diff line change
Expand Up @@ -1634,7 +1634,15 @@ def run(self, ccdExposure, *, dnlLUT=None, bias=None, deferredChargeCalib=None,
# Output units: electron (adu if doBootstrap=True)
if self.config.doDeferredCharge:
self.log.info("Applying deferred charge/CTI correction.")
self.deferredChargeCorrection.run(ccdExposure, deferredChargeCalib)
if exposureMetadata["LSST ISR UNITS"] == "electron":
self.deferredChargeCorrection.config.useGains = False
else:
self.deferredChargeCorrection.config.useGains = True
self.deferredChargeCorrection.run(
ccdExposure,
deferredChargeCalib,
gains=gains
)

# Assemble/trim
# Output units: electron (adu if doBootstrap=True)
Expand Down

0 comments on commit 9d88ca9

Please sign in to comment.