Skip to content

Commit 0dc45fd

Browse files
authored
Merge pull request #138 from lsst-camera-dh/LSSTTD-1580_fe55_gain_fitting_improvements
Lssttd 1580 fe55 gain fitting improvements
2 parents 9b20acc + a011cde commit 0dc45fd

3 files changed

Lines changed: 37 additions & 10 deletions

File tree

python/lsst/eotest/sensor/MaskedCCD.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
@author J. Chiang <jchiang@slac.stanford.edu>
77
"""
88
import warnings
9+
import numpy as np
910
import astropy.io.fits as fits
1011
from astropy.utils.exceptions import AstropyWarning, AstropyUserWarning
1112
from lsst.eotest.fitsTools import fitsWriteto
@@ -227,7 +228,9 @@ def bias_image(self, amp, overscan=None, **kwargs):
227228
return my_image.Factory(my_image, deep=True)
228229
return self.bias_image_using_overscan(amp, overscan=overscan, **kwargs)
229230

230-
def bias_subtracted_image(self, amp, overscan=None, **kwargs):
231+
def bias_subtracted_image(self, amp, overscan=None,
232+
max_pca_reduced_chisq=None,
233+
**kwargs):
231234
"""
232235
Subtract a bias image to correct for the offset. A bias correction is also
233236
applied if a base_frame is passed. The bias image with the offset values is
@@ -252,18 +255,24 @@ def bias_subtracted_image(self, amp, overscan=None, **kwargs):
252255
# Make a deep copy of the bias frame.
253256
bias = self.bias_frame[amp].Factory(self.bias_frame[amp], deep=True)
254257
# Subtract x-independent component using overscan.
255-
bias -= \
256-
self.bias_frame.bias_image_using_overscan(amp,
257-
overscan=overscan, **kwargs)
258+
bias -= self.bias_frame.bias_image_using_overscan(
259+
amp, overscan=overscan, **kwargs)
258260
# Subtract x-independent component of image for this amp
259261
# using overscan.
260262
my_image -= \
261263
self.bias_image_using_overscan(amp, overscan=overscan, **kwargs)
262264
# Subtract structured, x-dependent part.
263265
my_image -= bias
264266
elif self.ccd_pcas is not None:
265-
my_image.getImage().array[:] \
266-
-= self.ccd_pcas.pca_bias_correction(amp, my_image.getImage().array)
267+
bias_model = self.ccd_pcas.pca_bias_correction(amp, my_image.getImage().array)
268+
bias_image = afwImage.ImageF(np.array(bias_model, dtype=np.float32))
269+
bbox = self.amp_geom.serial_overscan
270+
chisq = self.ccd_pcas.bbox_chisq(my_image.getImage(), bias_image,
271+
bbox)
272+
if (max_pca_reduced_chisq is not None and
273+
chisq/bbox.area > max_pca_reduced_chisq):
274+
raise MaskedCCDBiasImageException
275+
my_image.getImage().array[:] -= bias_model
267276
else:
268277
my_image -= self.bias_image(amp, overscan, **kwargs)
269278

python/lsst/eotest/sensor/ccd_bias_pca.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,18 @@ def pca_bias_correction(self, amp, image_array):
490490

491491
return bias_model
492492

493+
@staticmethod
494+
def bbox_chisq(amp_image, bias_model, bbox):
495+
"""
496+
Compute the chi-square for the pixels in the provided bounding box,
497+
using the bias_model value as the variance.
498+
"""
499+
data = amp_image.Factory(amp_image, bbox, deep=True)
500+
model = bias_model.Factory(bias_model, bbox)
501+
data -= model
502+
chisq = np.sum(data.array*data.array/model.array)
503+
return chisq
504+
493505
def make_bias_frame(self, raw_file, outfile, residuals_file=None,
494506
amps=None):
495507
"""

python/lsst/eotest/sensor/fe55_psf.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,14 @@ def cluster_moments(dn, pos):
5353
sum_y2 = np.sum(vy*vy*dn)
5454
mean_x = sum_x / sum_0
5555
mean_y = sum_y / sum_0
56-
std_x = np.sqrt((sum_x2 / sum_0) - (mean_x * mean_x))
57-
std_y = np.sqrt((sum_y2 / sum_0) - (mean_y * mean_y))
56+
var_x = (sum_x2 / sum_0) - (mean_x * mean_x)
57+
if var_x < 0:
58+
raise RuntimeError
59+
std_x = np.sqrt(var_x)
60+
var_y = (sum_y2 / sum_0) - (mean_y * mean_y)
61+
if var_y < 0:
62+
raise RuntimeError
63+
std_y = np.sqrt(var_y)
5864
return (mean_x, mean_y, std_x, std_y, sum_0)
5965

6066

@@ -183,14 +189,14 @@ def _bg_image(self, image, ccd, nx, ny):
183189
return bg.getImageF()
184190

185191
def process_image(self, ccd, amp, sigma0=0.36, dn0=1590./5.,
186-
bg_reg=(10, 10), logger=None, seqnum=0):
192+
bg_reg=(10, 40), logger=None, seqnum=0):
187193
"""
188194
Process a segment and accumulate the fit results for each
189195
charge cluster. The dn0 and sigma0 parameters are the
190196
starting values used for each fit.
191197
"""
192198
try:
193-
image = ccd.bias_subtracted_image(amp)
199+
image = ccd.bias_subtracted_image(amp, max_pca_reduced_chisq=1)
194200
except MaskedCCDBiasImageException:
195201
print("DM stack error encountered when generating bias image ")
196202
print("from inferred overscan region.")

0 commit comments

Comments
 (0)