Charge Transfer Efficiency#
A CCD is read out by moving charge from pixel to pixel. Every row is shifted down the columns into the serial register, which is a parallel transfer, and the serial register then shifts each pixel of the row along to the amplifier, which is a serial transfer. Each transfer leaves a small fraction of the charge behind, the charge transfer inefficiency (CTI), and the charge transfer efficiency is \(\text{CTE} = 1 - \text{CTI}\).
For the ESIS cameras the inefficiency is about one part in a million per transfer. A pixel far from the amplifier goes through about a thousand transfers of each kind, so it loses about a tenth of a percent of its charge on the way.
This report measures the serial efficiency of the ESIS channel 1 camera from a single image of a diffuse LED source, and then summarizes what the rest of the 2017 camera tests show.
[1]:
import numpy as np
import matplotlib.pyplot as plt
import astropy.units as u
import named_arrays as na
import msfc_ccd
Load the sample image and split it into taps. It was gathered by the MSFC sounding rocket team on 2017-07-12, during a test of the linearity of the cameras.
[2]:
image = msfc_ccd.fits.open(msfc_ccd.samples.path_led_esis1)
taps = image.taps
axis_x = taps.axis_x
axis_y = taps.axis_y
axis_tap_x = taps.axis_tap_x
axis_tap_y = taps.axis_tap_y
sensor = taps.camera.sensor
The first few rows of each tap are masked, and hold charge from the frame store rather than from the image, so they are left out of everything below. The rest of each tap is uniformly illuminated to a level of a few tens of thousands of electrons.
[3]:
rows = {axis_y: slice(sensor.num_masked, None)}
signal = taps.unbiased.active.outputs[rows].mean(taps.axis_xy)
signal.ndarray
[3]:
The charge left behind#
The serial register reads out each row in order: first the blank columns, then the active columns, and last the two overscan columns. Nothing is collected in the overscan columns, so any charge found there was left behind by the transfers of the pixels before them.
Averaging each column over the rows of the image shows that charge as a step down by about three orders of magnitude at the end of the active pixels.
[4]:
columns = taps.unbiased.outputs[rows].mean(axis_y)
num_x = taps.num_x
num_last = num_x - sensor.num_overscan
index = np.arange(num_x - 12, num_x) - num_last
fig, ax = plt.subplots(constrained_layout=True)
for i in range(taps.shape[axis_tap_y]):
for j in range(taps.shape[axis_tap_x]):
tap = {axis_tap_y: i, axis_tap_x: j}
ax.plot(
index,
columns[tap][{axis_x: slice(num_x - 12, None)}].ndarray.value,
marker=".",
label=taps.amplifier[tap].ndarray,
)
ax.axvline(-0.5, color="gray", linestyle="--")
ax.set_yscale("log")
ax.set_xlabel("column, relative to the first overscan column")
ax.set_ylabel("mean signal (DN)")
ax.legend();
The charge in the overscan columns is the charge the last active pixel of each row lost to its serial transfers. That pixel was transferred once for each column read out before the overscan, blank or active, so for a flat at a signal of \(S\),
where \(Q_o\) is the charge in the overscan columns and \(N\) is the
number of blank and active columns.
This is the extended pixel edge response (EPER) method,
and msfc_ccd.cte.eper() computes it for each tap.
[5]:
cte = msfc_ccd.cte.eper(taps).outputs
cti = (1 - cte).to(u.dimensionless_unscaled)
for i in range(taps.shape[axis_tap_y]):
for j in range(taps.shape[axis_tap_x]):
tap = {axis_tap_y: i, axis_tap_x: j}
print(
f"{taps.amplifier[tap].ndarray}"
f" CTE {cte[tap].ndarray:0.6f}"
f" CTI {1e6 * cti[tap].ndarray.value:0.2f} x 10^-6"
)
1/E CTE 99.999900 % CTI 1.00 x 10^-6
4/F CTE 99.999645 % CTI 3.55 x 10^-6
2/H CTE 99.999807 % CTI 1.93 x 10^-6
3/G CTE 99.999865 % CTI 1.35 x 10^-6
MSFC measured this camera with the same method, using only the first overscan column and counting only the active columns as transfers. Those two choices change the result in opposite directions and nearly cancel: on the images MSFC used, gathered a few minutes before the sample image, this method reproduces their efficiencies of 99.99971 to 99.99991 percent to within 0.00002 percent on every tap.
The inefficiency depends on the signal#
The same test stepped the LED through 37 levels of illumination. Repeating the measurement at a few of them, after subtracting the overscan level of a dark image, which is within 0.4 DN of the bias, gives the serial inefficiency of each tap, in units of \(10^{-6}\),
signal (DN) |
1/E |
4/F |
2/H |
3/G |
|---|---|---|---|---|
230 to 380 |
2.6 |
5.7 |
9.6 |
4.2 |
1,000 to 1,700 |
1.5 |
3.5 |
4.5 |
2.8 |
4,500 to 7,400 |
1.1 |
2.9 |
2.7 |
1.8 |
14,000 to 23,000 |
1.1 |
3.6 |
1.9 |
1.4 |
30,000 to 48,000 |
1.1 |
3.0 |
1.6 |
1.3 |
where the first number of each signal range is for the 1/E and 4/F taps and the second for the 2/H and 3/G taps, which the LED lit more brightly.
Above a thousand data numbers, the 1/E tap loses a nearly constant fraction of its charge, the 2/H and 3/G taps lose a fraction that falls steadily as the signal rises, and the 4/F tap lies in between. Every tap loses a larger fraction of a faint signal. The result of this method therefore describes the camera at the signal level of the flat.
Parallel transfers#
The cameras read out no overscan rows,
so there is nothing for the EPER method to use in the parallel direction.
Instead, msfc_ccd.cte.fe55() uses the X-rays from an
\(^{55}\text{Fe}\) source.
Every K-\(\alpha\) X-ray releases the same charge,
but an event far from the amplifier goes through more transfers and arrives
with a little less of it,
so the inefficiency is the slope of the event charge against the number of
transfers.
The loss is only about a data number across a whole tap,
so the slope takes thousands of events per tap to measure,
far more than the samples included with this package.
On 800 images from the channel 4 camera during the same test, with a master dark subtracted from each, the single-pixel events give, in units of \(10^{-6}\),
tap |
serial |
parallel |
serial EPER |
|---|---|---|---|
1/E |
1.0 ± 0.5 |
0.3 ± 1.1 |
1.3 |
4/F |
1.4 ± 0.5 |
1.7 ± 0.2 |
1.0 |
2/H |
1.4 ± 0.8 |
1.8 ± 0.7 |
1.1 |
3/G |
1.0 ± 0.7 |
1.1 ± 2.0 |
1.2 |
where the last column is the EPER method on the same camera at about the same signal as an event, around a thousand data numbers. The two methods agree on the serial inefficiency, and the parallel inefficiency is below about two parts in a million.
The master dark matters here. The dark level of these cameras rises by 0.3 to 0.4 DN from the first row read out to the last, which, left in, makes the parallel inefficiency look about \(10^{-6}\) smaller than it is.
MSFC summed the \(3 \times 3\) region around each event instead of taking the center pixel alone. The sum recovers the charge left behind in the neighboring pixel, which hides the loss, and their fits gave an efficiency above 100 percent.
Summary#
The serial inefficiency of the ESIS cameras is one to a few parts in a million at the signals of a typical flat, and the parallel inefficiency is below about two parts in a million. Both efficiencies are therefore above 99.9996 percent, better than the typical value of 99.9995 percent on the CCD230-42 datasheet, and well inside the ESIS requirements of 99.999 percent for serial transfers and 99.995 percent for parallel transfers.