fe55#

msfc_ccd.cte.fe55(images, threshold=5, threshold_split=3, gain_min=<Quantity 2. electron / DN>, gain_max=<Quantity 5. electron / DN>, source=None)[source]#

Estimate the charge transfer efficiency of each tap from Fe 55 images.

Every \(^{55}\text{Fe}\) K-\(\alpha\) X-ray releases the same charge, but an event far from the amplifier is transferred more times before it is read out, and loses a little of its charge to each imperfect transfer. The single-pixel events found by hits() are pooled over every axis except the two tap axes, and fit with the model used by msfc_ccd.gain.fe55(), except that the center of each line falls linearly with the number of serial and parallel transfers of the event,

\[q = q_0 \left(1 - \text{CTI}_x n_x - \text{CTI}_y n_y \right),\]

where \(n_x\) counts the blank columns as well as the active columns between the event and the amplifier, and \(n_y\) counts the rows.

Only the center pixel of each single-pixel event is used, which is the standard form of the method. MSFC summed the \(3 \times 3\) region around each event, which recovers the charge left in the neighboring pixel and so hides the loss; their fits gave a charge transfer efficiency above 100 percent.

The result is a vector for each tap, whose \(x\) component is the serial charge transfer efficiency and whose \(y\) component is the parallel charge transfer efficiency.

The loss is tiny, about a data number across the whole tap, so this function needs thousands of events per tap, or several hundred images from the ESIS cameras.

Subtract a master dark from the images first, using msfc_ccd.dark.master(). The dark level of the ESIS cameras rises by 0.3 to 0.4 DN from the first row read out to the last, which the median removed by hits() cannot follow, and which would otherwise look like a negative parallel inefficiency of about \(10^{-6}\).

The fit also averages over any columns with charge traps. On a sensor with many of them, the traps dominate the result, and the serial component should be taken from eper() instead.

Parameters:
  • images (TapDataT) – Several hundred Fe 55 exposures from each tap, such as the taps of a sequence of images.

  • threshold (float) – How many readout noises above the dark level a pixel must be to start an event.

  • threshold_split (float) – How many readout noises above the dark level each of the eight neighbors of an event must stay below for it to count as a single-pixel event.

  • gain_min (Quantity) – The smallest gain allowed, which sets where the K-\(\alpha\) peak can be.

  • gain_max (Quantity) – The largest gain allowed.

  • source (None | Fe55) – The properties of the \(^{55}\text{Fe}\) source. If None, the default msfc_ccd.Fe55 is used.

Returns:

  • A copy of images, of the same type, whose outputs are the serial and

  • parallel charge transfer efficiency of each tap,

  • as the \(x\) and \(y\) components of a

  • named_arrays.Cartesian2dVectorArray,

  • or numpy.nan for a tap with too few events to fit.

Raises:
  • TypeError – If images is not the images from each tap.

  • ValueError – If gain_min is not smaller than gain_max.

Return type:

TapDataT

Examples

Estimate the charge transfer efficiency of the ESIS channel 3 camera from four Fe 55 exposures. Four images are far too few for a precise result, so this only shows how the function is called.

import numpy as np
import named_arrays as na
import msfc_ccd

path = na.ScalarArray(
    ndarray=np.array(msfc_ccd.samples.paths_fe55_esis3),
    axes="time",
)
images = msfc_ccd.fits.open(path)

cte = msfc_ccd.cte.fe55(images.taps).outputs

# The serial charge transfer efficiency
cte.x.ndarray
\[[[100.00125,~100.00062],~ [100.00252,~100.00098]] \; \mathrm{\%}\]
# The parallel charge transfer efficiency
cte.y.ndarray
\[[[99.999858,~99.993758],~ [99.998152,~100.00099]] \; \mathrm{\%}\]