"""
Chromatic Adaptation by Reflectance Reconstruction (Prep Fcn, xy)
================================================================
Creates preparatory arrays to pass to adaptation.py, which
predicts how tristimulus values will change when moving from one
illuminant to another, given the white points of the two
illuminants. Illuminant white points are specified as chromaticity
coordinates, xy.
Version 2020_01_24 Scott Allen Burns
"""
import numpy as np
from method_2 import method_2
def adaptation_prep_xy(cmfs, xy_wps, xy_wpd, degree=1):
"""
Creates preparatory arrays to pass to adaptation.py, which
predicts how tristimulus values will change when moving from
one illuminant to another, given the white points of the two
illuminants. Optionally, a degree of adaptation (0-1) can be
specified. This version operates on illuminant white point
tristimulus values.
Parameters
----------
cmfs: nx3 array of color matching functions, where n is the
number of wavelength bins (rows) of cmfs.
xy_wps: two-element vector of source illuminant white point
chromaticity coordinates, (x,y).
xy_wpd: two-element vector of destination illuminant white
point chromaticity coordinates (x,y).
degree: a value in the range [0-1] that indicates the degree
of adaptation. Degree=1 is full adaptation.
Returns
-------
d: nxn array of finite differencing constants (n is the number
of wavelength bins (rows) used in the CMFs).
cmfs_s: nx3 array of source-illuminant-referenced CMFs.
cmfs_d: nx3 array of destination-illuminant-referenced CMFs.
Notes
-----
A list of xy chromaticity coordinates for various standard
illuminants can be found at Wikipedia:
https://en.wikipedia.org/wiki/Standard_illuminant
This chromatic adaptation transform (CAT) is based on smoothest
reflectance reconstruction (References [1] and [2]) and is
developed and compared to existing CATs (Bradford, CAT02, CAT16)
in Reference [3].
References
----------
[1] Burns SA. Numerical methods for smoothest reflectance
reconstruction. Color Research & Application, Vol 45,
No 1, 2020, pp 8-21.
[2] Generating Reflectance Curves from sRGB Triplets, 2015
http://scottburns.us/reflectance-curves-from-srgb/#LLSS
[3] Burns SA. Chromatic adaptation transform by spectral
reconstruction. Color Research & Application, Vol 44,
No 5, 2019, pp 682-693.
Acknowledgements
----------------
Thanks to Adam J. Burns and Mark (kram1032) for assistance
with translating from MATLAB to Python.
"""
# determine number of wavelength bins
n = cmfs.shape[0]
# build tri-diagonal array of finite differencing constants
d = np.eye(n, n, k=-1)*-2 + np.eye(n, n)*4 + np.eye(n, n, k=1)*-2
d[0, 0] = 2
d[n-1, n-1] = 2
# compute the illuminant white point tristimulus values
XYZ_wps = np.zeros(3)
XYZ_wps[0] = xy_wps[0]/xy_wps[1]
XYZ_wps[1] = 1
XYZ_wps[2] = (1-xy_wps[0]-xy_wps[1])/xy_wps[1]
XYZ_wpd = np.zeros(3)
XYZ_wpd[0] = xy_wpd[0]/xy_wpd[1]
XYZ_wpd[1] = 1
XYZ_wpd[2] = (1-xy_wpd[0]-xy_wpd[1])/xy_wpd[1]
# adjust destination illum for degree
XYZ_wpd = degree * XYZ_wpd + (1 - degree) * XYZ_wps
# build source-illuminant-referenced cmfs
ws = method_2(d, cmfs, XYZ_wps)
cmfs_s = np.diag(ws).dot(cmfs)
# build destination-illuminant-referenced cmfs
wd = method_2(d, cmfs, XYZ_wpd)
cmfs_d = np.diag(wd).dot(cmfs)
return d, cmfs_s, cmfs_d