Example: fixed pattern noise (hdrldemo_pyfpn)

This page sketches the hdrldemo recipe hdrldemo_pyfpn, which wraps hdrl.func.fpn_compute. Algorithm behaviour is documented in Fixed Pattern Noise.

Role of the recipe

For each SOF frame tagged RAW, the recipe:

  1. Loads one image (extension from ext-r).

  2. Optionally loads a POWERSPEC_MASK (extension from ext-mask).

  3. Calls hdrl.func.fpn_compute.

  4. Writes the power spectrum and its attached mask as products, with QC keywords for std and std_mad.

Parameters used by PyHDRL

Two parameters control FITS loading and two are passed to fpn_compute:

Recipe parameter

Role

ext-r

FITS extension for cpl.core.Image.load

ext-mask

Extension for the optional cpl.core.Mask.load

dc_mask_x

dc_mask_x argument (≥ 1)

dc_mask_y

dc_mask_y argument (≥ 1)

Reading data

img_in = cpl.core.Image.load(
    raw_frame.file,
    cpl.core.Type.DOUBLE,
    extension=ext_r,
    plane=0,
)

mask_in = None
if mask_frame is not None:
    mask_in = cpl.core.Mask.load(
        mask_frame.file,
        extension=ext_mask,
        plane=0,
    )

Using keyword arguments here avoids confusing the extension and plane positions in the PyCPL loading functions.

The input image must not already contain rejected (bad) pixels; fpn_compute raises if it does.

Calling PyHDRL

result = hdrl.func.fpn_compute(img_in, mask_in, dc_mask_x, dc_mask_y)
power_spectrum = result.power_spectrum  # cpl.core.Image
std = result.std
std_mad = result.std_mad

result is a hdrl.func.FpnResult. The combined DC / user mask used for the statistics is attached as power_spectrum.bpm.

Saving products

The demo recipe writes two products per RAW frame:

  • HDRLDEMO_FPN — power spectrum via cpl.dfs.save_image, with QC ESO QC FPN STD and ESO QC FPN STDMAD.

  • HDRLDEMO_FPN_MASK — integer image built from power_spectrum.bpm, also via cpl.dfs.save_image.

Both calls pass the full SOF, the recipe ParameterList, a usedframes frameset (the RAW that was processed), the recipe name, and the pipeline id string expected by DFS.

Minimal core

Stripping the DFS and SOF bookkeeping, the PyHDRL core is:

result = hdrl.func.fpn_compute(image, mask, dc_mask_x, dc_mask_y)
# save result.power_spectrum; publish result.std / result.std_mad as QC