def eotf_correction_calculation()

in src/open_vp_cal/core/calibrate.py [0:0]


def eotf_correction_calculation(
        grey_ramp_screen, grey_signal_value_rgb, deltaE_grey_ramp, avoid_clipping=True,
        peak_lum=None, deltaE_threshold=20):
    """ Compute a LUT to correct the EOTF as measured from grey patches. Any grey patches with a delta E greater than
        the deltaE_threshold are ignored.

        Args:
            deltaE_threshold: The threshold for delta E values to be considered
            grey_ramp_screen (array-like): Grey ramp in Screen Colour Space
            grey_signal_value_rgb: Reference Signal Values For The EOTF as RGB values
            deltaE_grey_ramp: Delta E Values For The Grey Ramp
            avoid_clipping: If we want to avoid clipping of values on the led wall we scale any values
            using the peak lum if values go above this
            peak_lum: The peak luminance of the led wall

        Returns:
            lut_r (array-like): 1D LUT with elements as (y,x)
            lut_g (array-like): 1D LUT with elements as (y,x)
            lut_b (array-like): 1D LUT with elements as (y,x)

    """
    num_steps = len(grey_ramp_screen)
    assert num_steps > 1
    assert len(grey_signal_value_rgb) == num_steps
    assert len(deltaE_grey_ramp) == num_steps

    grey_ramp_screen = np.maximum(0, grey_ramp_screen)

    lut_r, lut_g, lut_b = [], [], []

    for idx, grey_ramp_screen_value in enumerate(grey_ramp_screen):
        if deltaE_grey_ramp[idx] > deltaE_threshold:
            continue

        lut_r.append([grey_ramp_screen_value[0], grey_signal_value_rgb[idx][0]])
        lut_g.append([grey_ramp_screen_value[1], grey_signal_value_rgb[idx][1]])
        lut_b.append([grey_ramp_screen_value[2], grey_signal_value_rgb[idx][2]])

    # The first value should be black we know if the wall is a mess then the black level is a mess
    # so we hard pin the first step in the ramp to 0,0
    lut_r[0] = [0.0, 0.0]
    lut_g[0] = [0.0, 0.0]
    lut_b[0] = [0.0, 0.0]

    lut_r = np.array(lut_r)
    lut_g = np.array(lut_g)
    lut_b = np.array(lut_b)


    if avoid_clipping:
        if not peak_lum:
            raise OpenVPCalException("Peak luminance must be provided if avoid_clipping is True")

        max_r = np.max(np.max(lut_r[:, 0]))
        max_g = np.max(np.max(lut_g[:, 0]))
        max_b = np.max(np.max(lut_b[:, 0]))
        min_value = min(max_r, max_g, max_b)
        if min_value > peak_lum:
            scale_factor = peak_lum / min_value

            lut_r[:, 0] *= scale_factor
            lut_g[:, 0] *= scale_factor
            lut_b[:, 0] *= scale_factor

    return lut_r, lut_g, lut_b