Example: limiting magnitude (hdrldemo_pymaglim)

This page sketches the hdrldemo recipe hdrldemo_pymaglim, which wraps hdrl.func.Maglim. Algorithm behaviour is documented in Limiting magnitude.

Role of the recipe

For each SOF frame tagged RAW (image or cube), and optionally a matching RAW_BPM, the recipe:

  1. Loads data as a cpl.core.ImageList (one plane per cube slice).

  2. Applies the BPM / non-finite pixel rejection.

  3. Builds a hdrl.func.Maglim from recipe parameters (including a Collapse.Mode parameter object).

  4. Calls maglim.compute(plane) for each accepted plane.

  5. Saves QC keywords (ESO QC ABMAG, zeropoint, FWHM) with cpl.dfs.save_propertylist. Cubes append one extension per plane.

Parameters used by PyHDRL

Recipe parameter

PyHDRL usage

zero-point

Maglim(..., zeropoint=...)

convolution.fwhm

fwhm

convolution.kernel-size-x

kernel_size_x

convolution.kernel-size-y

kernel_size_y

convolution.boundary

REFLECT → ImageExtendMethod.Mirror; NEAREST → ImageExtendMethod.Nearest

mode.*

hdrl.func.Collapse.Mode(...)

bad-pixel-fraction-reject

Recipe-side skip; not a Maglim argument

Reading data

dlist = cpl.core.ImageList.load(raw_frame.file, cpl.core.Type.DOUBLE, ext_raw)

if bpm_frame is not None:
    qlist = cpl.core.ImageList.load(bpm_frame.file, cpl.core.Type.INT, ext_bpm)
    for k in range(len(dlist)):
        mask = cpl.core.Mask.threshold_image(qlist[k], 0, float("inf"), False)
        dlist[k].reject_from_mask(~mask)

Maglim.compute takes a single cpl.core.Image, so cubes are handled by looping over planes in the recipe.

Calling PyHDRL

Build the mode parameter, then the Maglim object, then compute:

mode_param = hdrl.func.Collapse.Mode(
    histo_min, histo_max, bin_size, method, error_niter
)
maglim = hdrl.func.Maglim(
    zeropoint=zero_point,
    fwhm=kernel_fwhm,
    kernel_size_x=kernel_size_x,
    kernel_size_y=kernel_size_y,
    extend_method=convolution_boundary,
    mode_param=mode_param,
)
limiting_magnitude = maglim.compute(data)  # float

method is a hdrl.func.Collapse.Method enum value (for example Median, Weighted, Fit), typically derived from a string recipe parameter.

Saving products

The demo product category is HDRLDEMO_ABMAGLIM. Only QC / header information is stored (no image plane):

qclist = cpl.core.PropertyList()
qclist.append(cpl.core.Property("ESO QC ABMAG", cpl.core.Type.DOUBLE, limiting_magnitude))
qclist.append(cpl.core.Property("ESO PRO CATG", cpl.core.Type.STRING, "HDRLDEMO_ABMAGLIM"))

cpl.dfs.save_propertylist(
    frameset, parameters, usedframes,
    RECIPE_NAME, qclist, PIPE_ID, outfile,
)

For cubes, the first plane creates the FITS file; later planes append extensions with qclist.save(outfile, cpl.core.io.EXTEND).

Minimal core

maglim = hdrl.func.Maglim(
    zeropoint, fwhm, kx, ky, extend_method, mode_param
)
abmaglim = maglim.compute(image)
# publish abmaglim as QC via cpl.dfs.save_propertylist