Color sub-package

py:
  • __init__.py

namespace:

luxpy

utils/

py:
  • __init__.py

  • plotters.py

namespace:

luxpy


luxpy.color.utils.get_cmap(N, cmap_name='jet')[source]

Get an ndarray of rgba values representing a linearly sampled matplotlib colormap.

Args:
N:
Number of rgba values in returned cmap.
cmap_name:
‘jet’, optional
Matplotlib color map name to sample from.
Returns:
cmap:
ndarray with rgba values.
luxpy.color.utils.get_subplot_layout(N, min_1xncols=3)[source]

Calculate layout of multiple subplots.

Args:
N:
Number of plots.
min_1xncols:
Minimum number of columns before splitting over multiple rows.
Returns:
nrows, ncols:

luxpy.color.utils.plotSL(cieobs='1931_2', cspace='Yuv', DL=False, BBL=True, D65=False, EEW=False, cctlabels=False, axh=None, show=True, cspace_pars={}, formatstr='k-', diagram_colors=False, diagram_samples=100, diagram_opacity=1.0, diagram_lightness=0.25, **kwargs)[source]

Plot spectrum locus for cieobs in cspace.

Args:
DL:
True or False, optional
True plots Daylight Locus as well.
BBL:
True or False, optional
True plots BlackBody Locus as well.
D65:
False or True, optional
True plots D65 chromaticity as well.
EEW:
False or True, optional
True plots Equi-Energy-White chromaticity as well.
cctlabels:
False or True, optional
Add cct text labels at various points along the blackbody locus.
axh:
None or axes handle, optional
Determines axes to plot data in.
None: make new figure.
show:
True or False, optional
Invoke matplotlib.pyplot.show() right after plotting
cieobs:
luxpy._CIEOBS or str, optional
Determines CMF set to calculate spectrum locus or other.
cspace:
luxpy._CSPACE or str, optional
Determines color space / chromaticity diagram to plot data in.
Note that data is expected to be in specified :cspace:
formatstr:
‘k-’ or str, optional
Format str for plotting (see ?matplotlib.pyplot.plot)
cspace_pars:
{} or dict, optional
Dict with parameters required by color space specified in :cspace:
(for use with luxpy.colortf())
diagram_colors:
False, optional
True: plot colored chromaticity diagram.
diagram_samples:
256, optional
Sampling resolution of color space.
diagram_opacity:
1.0, optional
Sets opacity of chromaticity diagram
diagram_lightness:
0.25, optional
Sets lightness of chromaticity diagram
kwargs:
additional keyword arguments for use with matplotlib.pyplot.
Returns:
returns:
handle to current axes (:show: == False)
luxpy.color.utils.plotDL(ccts=None, cieobs='1931_2', cspace='Yuv', axh=None, show=True, force_daylight_below4000K=False, cspace_pars={}, formatstr='k-', **kwargs)[source]

Plot daylight locus.

Args:
ccts:
None or list[float], optional
None defaults to [4000 K to 1e11 K] in 100 steps on a log10 scale.
force_daylight_below4000K:
False or True, optional
CIE daylight phases are not defined below 4000 K.
If True plot anyway.
axh:
None or axes handle, optional
Determines axes to plot data in.
None: make new figure.
show:
True or False, optional
Invoke matplotlib.pyplot.show() right after plotting
cieobs:
luxpy._CIEOBS or str, optional
Determines CMF set to calculate spectrum locus or other.
cspace:
luxpy._CSPACE or str, optional
Determines color space / chromaticity diagram to plot data in.
Note that data is expected to be in specified :cspace:
formatstr:
‘k-’ or str, optional
Format str for plotting (see ?matplotlib.pyplot.plot)
cspace_pars:
{} or dict, optional
Dict with parameters required by color space specified in :cspace:
(for use with luxpy.colortf())
kwargs:
additional keyword arguments for use with matplotlib.pyplot.
Returns:
returns:
handle to current axes (:show: == False)
luxpy.color.utils.plotBB(ccts=None, cieobs='1931_2', cspace='Yuv', axh=None, cctlabels=True, show=True, cspace_pars={}, formatstr='k-', **kwargs)[source]

Plot blackbody locus.

Args:
ccts:
None or list[float], optional
None defaults to [1000 to 1e19 K].
Range:
[1000,1500,2000,2500,3000,3500,4000,5000,6000,8000,10000]
+ [15000 K to 1e11 K] in 100 steps on a log10 scale
cctlabels:
True or False, optional
Add cct text labels at various points along the blackbody locus.
axh:
None or axes handle, optional
Determines axes to plot data in.
None: make new figure.
show:
True or False, optional
Invoke matplotlib.pyplot.show() right after plotting
cieobs:
luxpy._CIEOBS or str, optional
Determines CMF set to calculate spectrum locus or other.
cspace:
luxpy._CSPACE or str, optional
Determines color space / chromaticity diagram to plot data in.
Note that data is expected to be in specified :cspace:
formatstr:
‘k-’ or str, optional
Format str for plotting (see ?matplotlib.pyplot.plot)
cspace_pars:
{} or dict, optional
Dict with parameters required by color space specified in :cspace:
(for use with luxpy.colortf())
kwargs:
additional keyword arguments for use with matplotlib.pyplot.
Returns:
returns:
handle to current axes (:show: == False)
luxpy.color.utils.plot_color_data(x, y, z=None, axh=None, show=True, cieobs='1931_2', cspace='Yuv', formatstr='k-', legend_loc=None, **kwargs)[source]

Plot color data from x,y [,z].

Args:
x:
float or ndarray with x-coordinate data
y:
float or ndarray with y-coordinate data
z:
None or float or ndarray with Z-coordinate data, optional
If None: make 2d plot.
axh:
None or axes handle, optional
Determines axes to plot data in.
None: make new figure.
show:
True or False, optional
Invoke matplotlib.pyplot.show() right after plotting
cieobs:
luxpy._CIEOBS or str, optional
Determines CMF set to calculate spectrum locus or other.
cspace:
luxpy._CSPACE or str or None, optional
Determines color space / chromaticity diagram to plot data in.
Note that data is expected to be in specified :cspace:
If None: don’t do any formatting of x,y [z] axes.
formatstr:
‘k-’ or str, optional
Format str for plotting (see ?matplotlib.pyplot.plot)
kwargs:
additional keyword arguments for use with matplotlib.pyplot.
Returns:
returns:
handle to current axes (:show: == False)
luxpy.color.utils.plotceruleanline(cieobs='1931_2', cspace='Yuv', axh=None, formatstr='ko-', cspace_pars={})[source]

Plot cerulean (yellow (577 nm) - blue (472 nm)) line

Kuehni, CRA, 2014:
Table II: spectral lights.
Args:
axh:
None or axes handle, optional
Determines axes to plot data in.
None: make new figure.
cieobs:
luxpy._CIEOBS or str, optional
Determines CMF set to calculate spectrum locus or other.
cspace:
luxpy._CSPACE or str, optional
Determines color space / chromaticity diagram to plot data in.
Note that data is expected to be in specified :cspace:
formatstr:
‘k-’ or str, optional
Format str for plotting (see ?matplotlib.pyplot.plot)
cspace_pars:
{} or dict, optional
Dict with parameters required by color space specified in :cspace:
(for use with luxpy.colortf())
kwargs:
additional keyword arguments for use with matplotlib.pyplot.
Returns:
returns:
handle to cerulean line
References:

1. Kuehni, R. G. (2014). Unique hues and their stimuli—state of the art. Color Research & Application, 39(3), 279–287. (see Table II, IV)

luxpy.color.utils.plotUH(xyz0=None, uhues=[0, 1, 2, 3], cieobs='1931_2', cspace='Yuv', axh=None, formatstr=['yo-.', 'bo-.', 'ro-.', 'go-.'], excludefromlegend='', cspace_pars={})[source]

Plot unique hue lines from color space center point xyz0.

Kuehni, CRA, 2014:
uY,uB,uG: Table II: spectral lights;
uR: Table IV: Xiao data.
Args:
xyz0:
None, optional
Center of color space (unique hue lines are expected to cross here)
None defaults to equi-energy-white.
uhues:
[0,1,2,3], optional
Unique hue lines to plot [0:’yellow’,1:’blue’,2:’red’,3:’green’]
axh:
None or axes handle, optional
Determines axes to plot data in.
None: make new figure.
cieobs:
luxpy._CIEOBS or str, optional
Determines CMF set to calculate spectrum locus or other.
cspace:
luxpy._CSPACE or str, optional
Determines color space / chromaticity diagram to plot data in.
Note that data is expected to be in specified :cspace:
formatstr:
[‘yo-.’,’bo-.’,’ro-.’,’go-.’] or list[str], optional
Format str for plotting the different unique lines
(see also ?matplotlib.pyplot.plot)
excludefromlegend:
‘’ or str, optional
To exclude certain hues from axes legend.
cspace_pars:
{} or dict, optional
Dict with parameters required by color space specified in :cspace:
(for use with luxpy.colortf())
Returns:
returns:
list[handles] to unique hue lines
References:

1. Kuehni, R. G. (2014). Unique hues and their stimuli—state of the art. Color Research & Application, 39(3), 279–287. (see Table II, IV)

luxpy.color.utils.plotcircle(center=array([[0.0000e+00, 0.0000e+00]]), radii=array([0, 10, 20, 30, 40, 50]), angles=array([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340]), color='k', linestyle='--', out=None, axh=None, **kwargs)[source]

Plot one or more concentric circles.

Args:
center:
np.array([[0.,0.]]) or ndarray with center coordinates, optional
radii:
np.arange(0,60,10) or ndarray with radii of circle(s), optional
angles:
np.arange(0,350,10) or ndarray with angles (°), optional
color:
‘k’, optional
Color for plotting.
linestyle:
‘–’, optional
Linestyle of circles.
out:
None, optional
If None: plot circles, return (x,y) otherwise.
luxpy.color.utils.plotellipse(v, cspace_in='Yxy', cspace_out=None, nsamples=100, show=True, axh=None, line_color='darkgray', line_style=':', line_width=1, line_marker='', line_markersize=4, plot_center=False, center_marker='o', center_color='darkgray', center_markersize=4, show_grid=False, llabel='', label_fontname='Times New Roman', label_fontsize=12, out=None)[source]

Plot ellipse(s) given in v-format [Rmax,Rmin,xc,yc,theta].

Args:
v:
(Nx5) ndarray
ellipse parameters [Rmax,Rmin,xc,yc,theta]
cspace_in:
‘Yxy’, optional
Color space of v.
If None: no color space assumed. Axis labels assumed (‘x’,’y’).
cspace_out:
None, optional
Color space to plot ellipse(s) in.
If None: plot in cspace_in.
nsamples:
100 or int, optional
Number of points (samples) in ellipse boundary
show:
True or boolean, optional
Plot ellipse(s) (True) or not (False)
axh:
None, optional
Ax-handle to plot ellipse(s) in.
If None: create new figure with axes.
line_color:
‘darkgray’, optional
Color to plot ellipse(s) in.
line_style:
‘:’, optional
Linestyle of ellipse(s).
line_width’:
1, optional
Width of ellipse boundary line.
line_marker:
‘none’, optional
Marker for ellipse boundary.
line_markersize:
4, optional
Size of markers in ellipse boundary.
plot_center:
False, optional
Plot center of ellipse: yes (True) or no (False)
center_color:
‘darkgray’, optional
Color to plot ellipse center in.
center_marker:
‘o’, optional
Marker for ellipse center.
center_markersize:
4, optional
Size of marker of ellipse center.
show_grid:
False, optional
Show grid (True) or not (False)
llabel:
None,optional
Legend label for ellipse boundary.
label_fontname:
‘Times New Roman’, optional
Sets font type of axis labels.
label_fontsize:
12, optional
Sets font size of axis labels.
out:
None, optional
Output of function
If None: returns None. Can be used to output axh of newly created
figure axes or to return Yxys an ndarray with coordinates of
ellipse boundaries in cspace_out (shape = (nsamples,3,N))
Returns:
returns:

None, or whatever set by :out:.

luxpy.color.utils.plot_chromaticity_diagram_colors(diagram_samples=256, diagram_opacity=1.0, diagram_lightness=0.25, cieobs='1931_2', cspace='Yxy', cspace_pars={}, show=True, axh=None, show_grid=False, label_fontname='Times New Roman', label_fontsize=12, **kwargs)[source]

Plot the chromaticity diagram colors.

Args:
diagram_samples:
256, optional
Sampling resolution of color space.
diagram_opacity:
1.0, optional
Sets opacity of chromaticity diagram
diagram_lightness:
0.25, optional
Sets lightness of chromaticity diagram
axh:
None or axes handle, optional
Determines axes to plot data in.
None: make new figure.
show:
True or False, optional
Invoke matplotlib.pyplot.show() right after plotting
cieobs:
luxpy._CIEOBS or str, optional
Determines CMF set to calculate spectrum locus or other.
cspace:
luxpy._CSPACE or str, optional
Determines color space / chromaticity diagram to plot data in.
Note that data is expected to be in specified :cspace:
cspace_pars:
{} or dict, optional
Dict with parameters required by color space specified in :cspace:
(for use with luxpy.colortf())
show_grid:
False, optional
Show grid (True) or not (False)
label_fontname:
‘Times New Roman’, optional
Sets font type of axis labels.
label_fontsize:
12, optional
Sets font size of axis labels.
kwargs:
additional keyword arguments for use with matplotlib.pyplot.

Returns:

luxpy.color.utils.plot_spectrum_colors(spd=None, spdmax=None, wavelength_height=-0.05, wavelength_opacity=1.0, wavelength_lightness=1.0, cieobs='1931_2', show=True, axh=None, show_grid=False, ylabel='Spectral intensity (a.u.)', xlim=None, **kwargs)[source]

Plot the spectrum colors.

Args:
spd:
None, optional
Spectrum
spdmax:
None, optional
max ylim is set at 1.05 or (1+abs(wavelength_height)*spdmax)
wavelength_opacity:
1.0, optional
Sets opacity of wavelength rectangle.
wavelength_lightness:
1.0, optional
Sets lightness of wavelength rectangle.
wavelength_height:
-0.05 or ‘spd’, optional
Determine wavelength bar height
if not ‘spd’: x% of spd.max()
axh:
None or axes handle, optional
Determines axes to plot data in.
None: make new figure.
show:
True or False, optional
Invoke matplotlib.pyplot.show() right after plotting
cieobs:
luxpy._CIEOBS or str, optional
Determines CMF set to calculate spectrum locus or other.
show_grid:
False, optional
Show grid (True) or not (False)
ylabel:
‘Spectral intensity (a.u.)’ or str, optional
Set y-axis label.
xlim:
None, optional
list or ndarray with xlimits.
kwargs:
additional keyword arguments for use with matplotlib.pyplot.

Returns:

luxpy.color.utils.plot_rfl_color_patches(rfl, spd=None, cieobs='1931_2', patch_shape=(100, 100), patch_layout=None, ax=None, show=True)[source]

Create (and plot) an image with colored patches representing a set of reflectance spectra illuminated by a specified illuminant.

Args:
rfl:
ndarray with reflectance spectra
spd:
None, optional
ndarray with illuminant spectral power distribution
If None: _CIE_D65 is used.
cieobs:
‘1931_2’, optional
CIE standard observer to use when converting rfl to xyz.
patch_shape:
(100,100), optional
shape of each of the patches in the image
patch_layout:
None, optional
If None: layout is calculated automatically to give a ‘good’ aspect ratio
ax:
None, optional
Axes to plot the image in. If None: a new axes is created.
show:
True, optional
If True: plot image in axes and return axes handle; else: return ndarray with image.
Return:
ax:

or :imagae: | Axes is returned if show == True, else: ndarray with rgb image is returned.

luxpy.color.utils.plot_rgb_color_patches(rgb, patch_shape=(100, 100), patch_layout=None, ax=None, show=True)[source]

Create (and plot) an image with patches with specified rgb values.

Args:
rgb:
ndarray with rgb values for each of the patches
patch_shape:
(100,100), optional
shape of each of the patches in the image
patch_layout:
None, optional
If None: layout is calculated automatically to give a ‘good’ aspect ratio
ax:
None, optional
Axes to plot the image in. If None: a new axes is created.
show:
True, optional
If True: plot image in axes and return axes handle; else: return ndarray with image.
Return:
ax:

or :imagae: | Axes is returned if show == True, else: ndarray with rgb image is returned.

luxpy.color.utils.plot_cmfs(cmfs, cmf_symbols=['x', 'y', 'z'], cmf_label='', ylabel='Sensitivity', wavelength_bar=True, colors=['r', 'g', 'b'], axh=None, legend=True, **kwargs)[source]

Plot CMFs.

Args:
cmfs:
ndarray with a set of CMFs.
cmf_symbols:
[‘x,’y’,’z], optional
Symbols of the CMFs
If not a list but a string, the same label will be used for all CMF
and the same color will be used (‘k’ if colors is a list)
cmf_label:
‘’, optional
Additional label that will be added in front of the cmf symbols.
ylabel:
‘Sensitivity’, optional
label for y-axis.
wavelength_bar:
True, optional
Add a colored wavelength bar with spectral colors.
colors:
[‘r’,’g’,’b’], optional
Color for plotting each of the individual CMF.
axh:
None, optional
Axes to plot the image in. If None: a new axes is created.
kwargs:
additional kwargs for plt.plot().
Returns:
axh:
figure axes handle.

ctf/

py:
  • __init__.py

  • colortransformations.py

  • colortf.py

namespace:

luxpy

luxpy.color.ctf.colortransforms.xyz_to_Yxy(xyz, **kwargs)[source]

Convert XYZ tristimulus values CIE Yxy chromaticity values.

Args:
xyz:
ndarray with tristimulus values
Returns:
Yxy:
ndarray with Yxy chromaticity values
(Y value refers to luminance or luminance factor)
luxpy.color.ctf.colortransforms.Yxy_to_xyz(Yxy, **kwargs)[source]

Convert CIE Yxy chromaticity values to XYZ tristimulus values.

Args:
Yxy:
ndarray with Yxy chromaticity values
(Y value refers to luminance or luminance factor)
Returns:
xyz:
ndarray with tristimulus values
luxpy.color.ctf.colortransforms.xyz_to_Yuv(xyz, **kwargs)[source]

Convert XYZ tristimulus values CIE 1976 Y,u’,v’ chromaticity values.

Args:
xyz:
ndarray with tristimulus values
Returns:
Yuv:
ndarray with CIE 1976 Y,u’,v’ chromaticity values
(Y value refers to luminance or luminance factor)
luxpy.color.ctf.colortransforms.Yuv_to_xyz(Yuv, **kwargs)[source]

Convert CIE 1976 Y,u’,v’ chromaticity values to XYZ tristimulus values.

Args:
Yuv:
ndarray with CIE 1976 Y,u’,v’ chromaticity values
(Y value refers to luminance or luminance factor)
Returns:
xyz:
ndarray with tristimulus values
luxpy.color.ctf.colortransforms.xyz_to_Yuv76(xyz, **kwargs)

Convert XYZ tristimulus values CIE 1976 Y,u’,v’ chromaticity values.

Args:
xyz:
ndarray with tristimulus values
Returns:
Yuv:
ndarray with CIE 1976 Y,u’,v’ chromaticity values
(Y value refers to luminance or luminance factor)
luxpy.color.ctf.colortransforms.Yuv76_to_xyz(Yuv, **kwargs)

Convert CIE 1976 Y,u’,v’ chromaticity values to XYZ tristimulus values.

Args:
Yuv:
ndarray with CIE 1976 Y,u’,v’ chromaticity values
(Y value refers to luminance or luminance factor)
Returns:
xyz:
ndarray with tristimulus values
luxpy.color.ctf.colortransforms.xyz_to_Yuv60(xyz, **kwargs)[source]

Convert XYZ tristimulus values CIE 1960 Y,u,v chromaticity values.

Args:
xyz:
ndarray with tristimulus values
Returns:
Yuv:
ndarray with CIE 1960 Y,u,v chromaticity values
(Y value refers to luminance or luminance factor)
luxpy.color.ctf.colortransforms.Yuv60_to_xyz(Yuv60, **kwargs)[source]

Convert CIE 1976 Y,u,v chromaticity values to XYZ tristimulus values.

Args:
Yuv:
ndarray with CIE 1976 Yu’v’ chromaticity values
(Y value refers to luminance or luminance factor)
Returns:
xyz:
ndarray with tristimulus values
luxpy.color.ctf.colortransforms.xyz_to_wuv(xyz, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), **kwargs)[source]

Convert XYZ tristimulus values CIE 1964 U*V*W* color space.

Args:
xyz:
ndarray with tristimulus values
xyzw:
ndarray with tristimulus values of white point, optional
(Defaults to luxpy._COLORTF_DEFAULT_WHITE_POINT)
Returns:
wuv:
ndarray with W*U*V* values
luxpy.color.ctf.colortransforms.wuv_to_xyz(wuv, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), **kwargs)[source]

Convert CIE 1964 U*V*W* color space coordinates to XYZ tristimulus values.

Args:
wuv:
ndarray with W*U*V* values
xyzw:
ndarray with tristimulus values of white point, optional
(Defaults to luxpy._COLORTF_DEFAULT_WHITE_POINT)
Returns:
xyz:
ndarray with tristimulus values
luxpy.color.ctf.colortransforms.xyz_to_xyz(xyz, **kwargs)[source]

Convert XYZ tristimulus values to XYZ tristimulus values.

Args:
xyz:
ndarray with tristimulus values
Returns:
xyz:
ndarray with tristimulus values
luxpy.color.ctf.colortransforms.xyz_to_lms(xyz, cieobs='1931_2', M=None, **kwargs)[source]

Convert XYZ tristimulus values to LMS cone fundamental responses.

Args:
xyz:
ndarray with tristimulus values
cieobs:
_CIEOBS or str, optional
M:
None, optional
Conversion matrix for xyz to lms.
If None: use the one defined by :cieobs:
Returns:
lms:
ndarray with LMS cone fundamental responses
luxpy.color.ctf.colortransforms.lms_to_xyz(lms, cieobs='1931_2', M=None, **kwargs)[source]

Convert LMS cone fundamental responses to XYZ tristimulus values.

Args:
lms:
ndarray with LMS cone fundamental responses
cieobs:
_CIEOBS or str, optional
M:
None, optional
Conversion matrix for xyz to lms.
If None: use the one defined by :cieobs:
Returns:
xyz:
ndarray with tristimulus values
luxpy.color.ctf.colortransforms.xyz_to_lab(xyz, xyzw=None, cieobs='1931_2', **kwargs)[source]

Convert XYZ tristimulus values to CIE 1976 L*a*b* (CIELAB) coordinates.

Args:
xyz:
ndarray with tristimulus values
xyzw:
None or ndarray with tristimulus values of white point, optional
None defaults to xyz of CIE D65 using the :cieobs: observer.
cieobs:
luxpy._CIEOBS, optional
CMF set to use when calculating xyzw.
Returns:
lab:
ndarray with CIE 1976 L*a*b* (CIELAB) color coordinates
luxpy.color.ctf.colortransforms.lab_to_xyz(lab, xyzw=None, cieobs='1931_2', **kwargs)[source]

Convert CIE 1976 L*a*b* (CIELAB) color coordinates to XYZ tristimulus values.

Args:
lab:
ndarray with CIE 1976 L*a*b* (CIELAB) color coordinates
xyzw:
None or ndarray with tristimulus values of white point, optional
None defaults to xyz of CIE D65 using the :cieobs: observer.
cieobs:
luxpy._CIEOBS, optional
CMF set to use when calculating xyzw.
Returns:
xyz:
ndarray with tristimulus values
luxpy.color.ctf.colortransforms.xyz_to_luv(xyz, xyzw=None, cieobs='1931_2', **kwargs)[source]

Convert XYZ tristimulus values to CIE 1976 L*u*v* (CIELUV) coordinates.

Args:
xyz:
ndarray with tristimulus values
xyzw:
None or ndarray with tristimulus values of white point, optional
None defaults to xyz of CIE D65 using the :cieobs: observer.
cieobs:
luxpy._CIEOBS, optional
CMF set to use when calculating xyzw.
Returns:
luv:
ndarray with CIE 1976 L*u*v* (CIELUV) color coordinates
luxpy.color.ctf.colortransforms.luv_to_xyz(luv, xyzw=None, cieobs='1931_2', **kwargs)[source]

Convert CIE 1976 L*u*v* (CIELUVB) coordinates to XYZ tristimulus values.

Args:
luv:
ndarray with CIE 1976 L*u*v* (CIELUV) color coordinates
xyzw:
None or ndarray with tristimulus values of white point, optional
None defaults to xyz of CIE D65 using the :cieobs: observer.
cieobs:
luxpy._CIEOBS, optional
CMF set to use when calculating xyzw.
Returns:
xyz:
ndarray with tristimulus values
luxpy.color.ctf.colortransforms.xyz_to_Vrb_mb(xyz, cieobs='1931_2', scaling=[1, 1], M=None, **kwargs)[source]

Convert XYZ tristimulus values to V,r,b (Macleod-Boynton) color coordinates.

Macleod Boynton: V = R+G, r = R/V, b = B/V
Note that R,G,B ~ L,M,S
Args:
xyz:
ndarray with tristimulus values
cieobs:
luxpy._CIEOBS, optional
CMF set to use when getting the default M, which is the xyz to lms conversion matrix.
scaling:
list of scaling factors for r and b dimensions.
M:
None, optional
Conversion matrix for going from XYZ to RGB (LMS)
If None, :cieobs: determines the M (function does inversion)
Returns:
Vrb:
ndarray with V,r,b (Macleod-Boynton) color coordinates
Reference:
  1. MacLeod DI, and Boynton RM (1979). Chromaticity diagram showing cone excitation by stimuli of equal luminance. J. Opt. Soc. Am. 69, 1183–1186.

luxpy.color.ctf.colortransforms.Vrb_mb_to_xyz(Vrb, cieobs='1931_2', scaling=[1, 1], M=None, Minverted=False, **kwargs)[source]

Convert V,r,b (Macleod-Boynton) color coordinates to XYZ tristimulus values.

Macleod Boynton: V = R+G, r = R/V, b = B/V
Note that R,G,B ~ L,M,S
Args:
Vrb:
ndarray with V,r,b (Macleod-Boynton) color coordinates
cieobs:
luxpy._CIEOBS, optional
CMF set to use when getting the default M, which is
the xyz to lms conversion matrix.
scaling:
list of scaling factors for r and b dimensions.
M:
None, optional
Conversion matrix for going from XYZ to RGB (LMS)
If None, :cieobs: determines the M (function does inversion)
Minverted:
False, optional
Bool that determines whether M should be inverted.
Returns:
xyz:
ndarray with tristimulus values
Reference:
  1. MacLeod DI, and Boynton RM (1979). Chromaticity diagram showing cone excitation by stimuli of equal luminance. J. Opt. Soc. Am. 69, 1183–1186.

luxpy.color.ctf.colortransforms.xyz_to_ipt(xyz, cieobs='1931_2', xyzw=None, M=None, **kwargs)[source]

Convert XYZ tristimulus values to IPT color coordinates.

I: Lightness axis, P, red-green axis, T: yellow-blue axis.
Args:
xyz:
ndarray with tristimulus values
xyzw:
None or ndarray with tristimulus values of white point, optional
None defaults to xyz of CIE D65 using the :cieobs: observer.
cieobs:
luxpy._CIEOBS, optional
CMF set to use when calculating xyzw for rescaling M
(only when not None).
M:
None, optional
None defaults to xyz to lms conversion matrix determined by :cieobs:
Returns:
ipt:
ndarray with IPT color coordinates
Note:
xyz:

is assumed to be under D65 viewing conditions! If necessary perform chromatic adaptation !

Reference:
  1. Ebner F, and Fairchild MD (1998). Development and testing of a color space (IPT) with improved hue uniformity. In IS&T 6th Color Imaging Conference, (Scottsdale, Arizona, USA), pp. 8–13.

luxpy.color.ctf.colortransforms.ipt_to_xyz(ipt, cieobs='1931_2', xyzw=None, M=None, **kwargs)[source]

Convert XYZ tristimulus values to IPT color coordinates.

I: Lightness axis, P, red-green axis, T: yellow-blue axis.
Args:
ipt:
ndarray with IPT color coordinates
xyzw:
None or ndarray with tristimulus values of white point, optional
None defaults to xyz of CIE D65 using the :cieobs: observer.
cieobs:
luxpy._CIEOBS, optional
CMF set to use when calculating xyzw for rescaling Mxyz2lms
(only when not None).
M:
None, optional
None defaults to xyz to lms conversion matrix determined by:cieobs:
Returns:
xyz:
ndarray with tristimulus values
Note:
xyz:

is assumed to be under D65 viewing conditions! If necessary perform chromatic adaptation !

Reference:
  1. Ebner F, and Fairchild MD (1998). Development and testing of a color space (IPT) with improved hue uniformity. In IS&T 6th Color Imaging Conference, (Scottsdale, Arizona, USA), pp. 8–13.

luxpy.color.ctf.colortransforms.xyz_to_Ydlep(xyz, cieobs='1931_2', xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), flip_axes=False, SL_max_lambda=None, **kwargs)[source]

Convert XYZ tristimulus values to Y, dominant (complementary) wavelength and excitation purity.

Args:
xyz:
ndarray with tristimulus values
xyzw:
None or ndarray with tristimulus values of a single (!) native white point, optional
None defaults to xyz of CIE D65 using the :cieobs: observer.
cieobs:
luxpy._CIEOBS, optional
CMF set to use when calculating spectrum locus coordinates.
flip_axes:
False, optional
If True: flip axis 0 and axis 1 in Ydelep to increase speed of loop in function.
(single xyzw with is not flipped!)
SL_max_lambda:
None or float, optional
Maximum wavelength of spectrum locus before it turns back on itelf in the high wavelength range (~700 nm)
Returns:
Ydlep:
ndarray with Y, dominant (complementary) wavelength
and excitation purity
luxpy.color.ctf.colortransforms.Ydlep_to_xyz(Ydlep, cieobs='1931_2', xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), flip_axes=False, SL_max_lambda=None, **kwargs)[source]

Convert Y, dominant (complementary) wavelength and excitation purity to XYZ tristimulus values.

Args:
Ydlep:
ndarray with Y, dominant (complementary) wavelength and excitation purity
xyzw:
None or narray with tristimulus values of a single (!) native white point, optional
None defaults to xyz of CIE D65 using the :cieobs: observer.
cieobs:
luxpy._CIEOBS, optional
CMF set to use when calculating spectrum locus coordinates.
flip_axes:
False, optional
If True: flip axis 0 and axis 1 in Ydelep to increase speed of loop in function.
(single xyzw with is not flipped!)
SL_max_lambda:
None or float, optional
Maximum wavelength of spectrum locus before it turns back on itelf in the high wavelength range (~700 nm)
Returns:
xyz:
ndarray with tristimulus values
luxpy.color.ctf.colortransforms.xyz_to_srgb(xyz, gamma=2.4, offset=-0.055, use_linear_part=True, M=None, **kwargs)[source]

Calculates IEC:61966 sRGB values from xyz.

Args:
xyz:
ndarray with relative tristimulus values.
gamma:
2.4, optional
Gamma compression in gamma-function gf(x): see notes
offset:
-0.055, optional
Offset in gamma-function gf(x): see notes
use_linear_part:
True, optional
If False: omit linear part at low RGB values and use gamma function throughout
M:
None, optional
xyz to linear srgb conversion matrix.
If None: use predefined matrix
Returns:
rgb:
ndarray with R,G,B values (uint8).
Notes:
  1. Gamma-function: gf(x) = ((1-offset)*x**gamma + offset)*255

  2. dark values use linear function: lf(x) = x[dark] * 12.92 * 255

  3. To use a pure gamma function, set offset to zero and use_linear_part to False.

luxpy.color.ctf.colortransforms.srgb_to_xyz(rgb, gamma=2.4, offset=-0.055, use_linear_part=True, M=None, **kwargs)[source]

Calculates xyz from IEC:61966 sRGB values.

Args:
rgb:
ndarray with srgb values (uint8).
gamma:
2.4, optional
Gamma compression in gamma-function gf(x): see notes
offset:
-0.055, optional
Offset in gamma-function gf(x): see notes
use_linear_part:
True, optional
If False: omit linear part at low RGB values and use gamma function throughout
M:
None, optional
xyz to linear srgb conversion matrix
(!!! Don’t give inverse matrix as input, function will take inverse of input to M!!!).
If None: use predefined inverse matrix
Returns:
xyz:
ndarray with xyz tristimulus values.
Notes:
  1. Gamma-function: gf(x) = ((1-offset)*x**gamma + offset)*255

  2. dark values use linear function: lf(x) = x[dark] * 12.92 * 255

  3. To use a pure gamma function, set offset to zero and use_linear_part to False.

Extension of basic colorimetry module

Global internal variables:

_COLORTF_DEFAULT_WHITE_POINT:

ndarray with XYZ values of default white point (equi-energy white) for color transformation if none is supplied.

Functions:

colortf():

Calculates conversion between any two color spaces (‘cspace’) for which functions xyz_to_cspace() and cspace_to_xyz() are defined.


luxpy.color.ctf.colortf.colortf(data, tf='Yuv', fwtf={}, bwtf={}, **kwargs)[source]

Wrapper function to perform various color transformations.

Args:
data:
ndarray
tf:
_CSPACE or str specifying transform type, optional
E.g. tf = ‘spd>xyz’ or ‘spd>Yuv’ or ‘Yuv>cct’
or ‘Yuv’ or ‘Yxy’ or …
If tf is for example ‘Yuv’, it is assumed to be a transformation
of type: ‘xyz>Yuv’
fwtf:
dict with parameters (keys) and values required
by some color transformations for the forward transform:
i.e. ‘xyz>…’
bwtf:
dict with parameters (keys) and values required
by some color transformations for the backward transform:
i.e. ‘…>xyz’
Returns:
returns:
ndarray with data transformed to new color space
Note:

For the forward transform (‘xyz>…’), one can input the keyword arguments specifying the transform parameters directly without having to use the dict :fwtf: (should be empty!) [i.e. kwargs overwrites empty fwtf dict]

cct/

py:
  • __init__.py

  • cct.py

  • cct_legacy.py

  • cctduv_ohno_CORM2011.py

namespace:

luxpy


luxpy.color.cct.cct_to_mired(data)[source]

Convert cct to Mired scale (or back).

Args:
data:
ndarray with cct or Mired values.
Returns:
returns:
ndarray ((10**6) / data)
luxpy.color.cct.xyz_to_cct_mcamy1992(xyzw, cieobs='1931_2', wl=None, out='cct', cspace='Yuv60', cspace_kwargs={'bwtf': {}, 'fwtf': {}})[source]

Convert XYZ tristimulus values to correlated color temperature (CCT) using the mccamy approximation (!!! only valid for CIE 1931 2° input !!!).

Only valid for approx. 3000 < T < 9000, if < 6500, error < 2 K
Args:
xyzw:
ndarray of tristimulus values
cieobs:
‘1931_2’, optional
CMF set used to calculated xyzw.
Note: since the parameter values in Mcamy’s equation were optimized,
using the 1931 2° CMFs, this is only valid for that CMF set.
It can be changed, but will only impact the calculation of Duv and
thereby causing a potential mismatch/error. Change at own discretion.
out:
‘cct’ (or 1), optional
Determines what to return.
Other options: ‘duv’ (or -1), ‘cct,duv’(or 2), “[cct,duv]” (or -2)
wl:
None, optional
Wavelengths used when calculating Planckian radiators when determining Duv.
(!!CCT is determined using a fixed set of equations optimized for the 1931 2° CMFS!!)
cspace:
_CCT_SPACE, optional
Color space to do calculations in.
Options:
- cspace string:
e.g. ‘Yuv60’ for use with luxpy.colortf()
- tuple with forward (i.e. xyz_to..) [and backward (i.e. ..to_xyz)] functions
(and an optional string describing the cspace):
e.g. (forward, backward) or (forward, backward, cspace string) or (forward, cspace string)
- dict with keys: ‘fwtf’ (foward), ‘bwtf’ (backward) [, optional: ‘str’ (cspace string)]
Note: if the backward tf is not supplied, optimization in cct_to_xyz() is done in the CIE 1976 u’v’ diagram
cspace_kwargs:
_CCT_CSPACE_KWARGS, optional
Parameter nested dictionary for the forward and backward transforms.
Returns:
cct:
ndarray of correlated color temperatures estimates
References:

1. McCamy, Calvin S. (April 1992). “Correlated color temperature as an explicit function of chromaticity coordinates”. Color Research & Application. 17 (2): 142–144.

luxpy.color.cct.xyz_to_cct_hernandez1999(xyzw, cieobs='1931_2', wl=None, out='cct', cspace='Yuv60', cspace_kwargs={'bwtf': {}, 'fwtf': {}})[source]

Convert XYZ tristimulus values to correlated color temperature (CCT) using the mccamy approximation (!!! only valid for CIE 1931 2° input !!!).

According to paper small error from 3000 - 800 000 K
Args:
xyzw:
ndarray of tristimulus values
cieobs:
‘1931_2’, optional
CMF set used to calculated xyzw.
Note: since the parameter values in the HA equations were optimized,
using the 1931 2° CMFs, this is only valid for that CMF set.
It can be changed, but will only impact the calculation of Duv and
thereby causing a potential mismatch/error. Change at own discretion.
out:
‘cct’ (or 1), optional
Determines what to return.
Other options: ‘duv’ (or -1), ‘cct,duv’(or 2), “[cct,duv]” (or -2)
wl:
None, optional
Wavelengths used when calculating Planckian radiators when determining Duv.
(!!CCT is determined using a fixed set of equations optimized for the 1931 2° CMFS!!)
cspace:
_CCT_SPACE, optional
Color space to do calculations in.
Options:
- cspace string:
e.g. ‘Yuv60’ for use with luxpy.colortf()
- tuple with forward (i.e. xyz_to..) [and backward (i.e. ..to_xyz)] functions
(and an optional string describing the cspace):
e.g. (forward, backward) or (forward, backward, cspace string) or (forward, cspace string)
- dict with keys: ‘fwtf’ (foward), ‘bwtf’ (backward) [, optional: ‘str’ (cspace string)]
Note: if the backward tf is not supplied, optimization in cct_to_xyz() is done in the CIE 1976 u’v’ diagram
cspace_kwargs:
_CCT_CSPACE_KWARGS, optional
Parameter nested dictionary for the forward and backward transforms.
Returns:
cct:
ndarray of correlated color temperatures estimates
References:

1. Hernández-Andrés, Javier; Lee, RL; Romero, J (September 20, 1999). Calculating Correlated Color Temperatures Across the Entire Gamut of Daylight and Skylight Chromaticities. Applied Optics. 38 (27), 5703–5709. P

luxpy.color.cct.xyz_to_cct_robertson1968(xyzw, cieobs='1931_2', out='cct', is_uv_input=False, wl=None, atol=0.1, rtol=1e-05, force_tolerance=True, tol_method='newton-raphson', lut_resolution_reduction_factor=4, split_calculation_at_N=25, max_iter=10, cspace='Yuv60', cspace_kwargs={'bwtf': {}, 'fwtf': {}}, lut=None, luts_dict=None, ignore_wl_diff=False, use_fast_duv=True, **kwargs)[source]

Convert XYZ tristimulus values to correlated color temperature (CCT) and Duv(distance above (> 0) or below ( < 0) the Planckian locus) using Robertson’s 1968 search method (with a 2023 modification to allow for CCTs < 1667 K).

Args:
xyzw:
ndarray of tristimulus values
cieobs:
luxpy._CIEOBS, optional
CMF set used to calculated xyzw.
out:
‘cct’ (or 1), optional
Determines what to return.
Other options: ‘duv’ (or -1), ‘cct,duv’(or 2), “[cct,duv]” (or -2)
is_uv_input:
False, optional
If True: xyzw contain uv input data, not xyz data!
wl:
None, optional
Wavelengths used when calculating Planckian radiators.
If None: use same wavelengths as CMFs in :cieobs:.
rtol:
1e-5, float, optional
Stop search when cct a relative tolerance is reached.
The relative tolerance is calculated as dCCT/CCT_est,
with CCT_est the current intermediate estimate in the
search and with dCCT the difference between
the present and former estimates.
atol:
0.1, optional
Stop search when cct a absolute tolerance (K) is reached.
force_tolerance:
True, optional
If False: search only using the list of CCTs in the used lut.
Only one loop of the full algorithm is performed.
Accuracy depends on CCT of test source and the location
and spacing of the CCTs in the list.
If True: search will use adjacent CCTs to test source to create a new LUT,
(repeat the algoritm at higher resolution, progessively zooming in
toward the ground-truth) for tol_method == ‘cl’; when
tol_method == ‘nr’ a newton-raphson method is used.
Because the CCT for multiple source is calculated in one go,
the atol and rtol values have to be met for all!
tol_method:
‘newton-raphson’, optional
(Additional) method to try and achieve set tolerances.
Options:
- ‘cl’, ‘cascading-lut’: use increasingly higher CCT-resolution
to ‘zoom-in’ on the ground-truth.
- ‘nr’, ‘newton-raphson’: use the method as described in Li, 2016.
lut_resolution_reduction_factor:
_CCT_LUT_RESOLUTION_REDUCTION_FACTOR, optional
Number of times the interval spanned by the adjacent Tc in a search or lut
method is downsampled (the search process will then start again)
max_iter:
_CCT_MAX_ITER, optional
Maximum number of iterations used by the cascading-lut or newton-raphson methods.
split_calculation_at_N:
_CCT_SPLIT_CALC_AT_N, optional
Split calculation when xyzw.shape[0] > split_calculation_at_N.
Splitting speeds up the calculation. If None: no splitting is done.
lut:
None, optional
Look-Up-Table with Ti, u,v,u’,v’,u”,v”,slope values of Planckians.
Options:
- None: defaults to the lut specified in _CCT_LUT[‘robertson1968’][‘lut_type_def’].
- list (lut,lut_kwargs): use this pre-calculated lut
(add additional kwargs for the lut_generator_fcn(), defaults to None if omitted)
- tuple: must be key (label) in :luts_dict: (pre-calculated dict of luts),
if not: then a new lut will be generated from scratch using the info in the tuple.
- str: must be key (label) in :luts_dict: (pre-calculated dict of luts)
- ndarray [Nx1]: list of luts for which to generate a lut
- ndarray [Nxn] with n>3: pre-calculated lut (last col must contain slope of the isotemperature lines).
luts_dict:
None, optional
Dictionary of pre-calculated luts for various cspaces and cmf sets.
Must have structure luts_dict[cspace][cieobs][lut_label] with the
lut part of a two-element list [lut, lut_kwargs]. It must contain
at the top-level a key ‘wl’ containing the wavelengths of the
Planckians used to generate the luts in this dictionary.
If None: luts_dict defaults to _CCT_LUT[‘robertson1968’][‘luts’].
cspace:
_CCT_SPACE, optional
Color space to do calculations in.
Options:
- cspace string:
e.g. ‘Yuv60’ for use with luxpy.colortf()
- tuple with forward (i.e. xyz_to..) [and backward (i.e. ..to_xyz)] functions
(and an optional string describing the cspace):
e.g. (forward, backward) or (forward, backward, cspace string) or (forward, cspace string)
- dict with keys: ‘fwtf’ (foward), ‘bwtf’ (backward) [, optional: ‘str’ (cspace string)]
Note: if the backward tf is not supplied, optimization in cct_to_xyz() is done in the CIE 1976 u’v’ diagram
cspace_kwargs:
_CCT_CSPACE_KWARGS, optional
Parameter nested dictionary for the forward and backward transforms.
ignore_wl_diff:
False, optional
When getting a lut from the dictionary, if differences are
detected in the wavelengts of the lut and the ones used to calculate any
plankcians then a new lut should be generated. Seting this to True ignores
these differences and proceeds anyway.
use_fast_duv:
_CCT_FAST_DUV, optional
If True: use a fast estimator of the Duv
(one that avoids calculation of Planckians and uses the former
best estimate’s u,v coordinates. This method is accurate enough
when the atol is small enough -> as long as abs(T-T_former)<=1K
the Duv estimate should be ok.)
Returns:
returns:
ndarray with:
cct: out == ‘cct’ (or 1)
duv: out == ‘duv’ (or -1)
cct, duv: out == ‘cct,duv’ (or 2)
[cct,duv]: out == “[cct,duv]” (or -2)
Note:

1. Out-of-lut CCTs are encoded as negative CCTs (with as absolute value the value of the closest CCT from the lut.)

References:

1. Robertson, A. R. (1968). Computation of Correlated Color Temperature and Distribution Temperature. Journal of the Optical Society of America, 58(11), 1528–1535. <https://doi.org/10.1364/JOSA.58.001528>

2. Baxter, D., Royer, M., & Smet, K. (2023). Modifications of the Robertson Method for Calculating Correlated Color Temperature to Improve Accuracy and Speed. LEUKOS, 20(1), 55–66.

3. Smet, K., Royer, M., Baxter, D., Bretschneider, E., Esposito, T., Houser, K., … Ohno, Y. (2023). Recommended Method for Determining the Correlated Color Temperature and Distance from the Planckian Locus of a Light Source. LEUKOS, 20(2), 223–237.

4. Li, C., Cui, G., Melgosa, M., Ruan, X., Zhang, Y., Ma, L., Xiao, K., & Luo, M. R. (2016). Accurate method for computing correlated color temperature. Optics Express, 24(13), 14066–14078.

luxpy.color.cct.xyz_to_cct_ohno2014(xyzw, cieobs='1931_2', out='cct', is_uv_input=False, wl=None, atol=0.1, rtol=1e-05, force_tolerance=True, tol_method='newton-raphson', lut_resolution_reduction_factor=4, duv_triangular_threshold=0.002, split_calculation_at_N=25, max_iter=10, cspace='Yuv60', cspace_kwargs={'bwtf': {}, 'fwtf': {}}, lut=None, luts_dict=None, ignore_wl_diff=False, use_fast_duv=True, **kwargs)[source]

Convert XYZ tristimulus values to correlated color temperature (CCT) and Duv (distance above (>0) or below (<0) the Planckian locus) using Ohno’s 2014 method.

Args:
xyzw:
ndarray of tristimulus values
cieobs:
luxpy._CIEOBS, optional
CMF set used to calculated xyzw.
out:
‘cct’ (or 1), optional
Determines what to return.
Other options: ‘duv’ (or -1), ‘cct,duv’(or 2), “[cct,duv]” (or -2)
is_uv_input:
False, optional
If True: xyzw contain uv input data, not xyz data!
wl:
None, optional
Wavelengths used when calculating Planckian radiators.
If None: use same wavelengths as CMFs in :cieobs:.
rtol:
1e-5, float, optional
Stop search when cct a relative tolerance is reached.
The relative tolerance is calculated as dCCT/CCT_est,
with CCT_est the current intermediate estimate in the
search and with dCCT the difference between
the present and former estimates.
atol:
0.1, optional
Stop search when cct a absolute tolerance (K) is reached.
force_tolerance:
True, optional
If False: search only using the list of CCTs in the used lut.
Only one loop of the full algorithm is performed.
Accuracy depends on CCT of test source and the location
and spacing of the CCTs in the list.
If True: search will use adjacent CCTs to test source to create a new LUT,
(repeat the algoritm at higher resolution, progessively zooming in
toward the ground-truth) for tol_method == ‘cl’; when
tol_method == ‘nr’ a newton-raphson method is used.
Because the CCT for multiple source is calculated in one go,
the atol and rtol values have to be met for all!
tol_method:
‘newton-raphson’, optional
(Additional) method to try and achieve set tolerances.
Options:
- ‘cl’, ‘cascading-lut’: use increasingly higher CCT-resolution
to ‘zoom-in’ on the ground-truth.
- ‘nr’, ‘newton-raphson’: use the method as described in Li, 2016.
lut_resolution_reduction_factor:
_CCT_LUT_RESOLUTION_REDUCTION_FACTOR, optional
Number of times the interval spanned by the adjacent Tc in a search or lut
method is downsampled (the search process will then start again)
duv_triangular_threshold:
0.002, optional
Threshold for use of the triangular solution.
(if smaller use triangular solution, else use the non-triangular one -> 3e-order poly)
max_iter:
_CCT_MAX_ITER, optional
Maximum number of iterations used by the cascading-lut or newton-raphson methods.
split_calculation_at_N:
_CCT_SPLIT_CALC_AT_N, optional
Split calculation when xyzw.shape[0] > split_calculation_at_N.
Splitting speeds up the calculation. If None: no splitting is done.
lut:
None, optional
Look-Up-Table with Ti, u,v,u’,v’,u”,v”,slope values of Planckians.
Options:
- None: defaults to the lut specified in _CCT_LUT[‘ohno2014’][‘lut_type_def’].
- list (lut,lut_kwargs): use this pre-calculated lut
(add additional kwargs for the lut_generator_fcn(), defaults to None if omitted)
- tuple: must be key (label) in :luts_dict: (pre-calculated dict of luts),
if not: then a new lut will be generated from scratch using the info in the tuple.
- str: must be key (label) in :luts_dict: (pre-calculated dict of luts)
- ndarray [Nx1]: list of luts for which to generate a lut
- ndarray [Nxn] with n>3: pre-calculated lut (last col must contain slope of the isotemperature lines).
luts_dict:
None, optional
Dictionary of pre-calculated luts for various cspaces and cmf sets.
Must have structure luts_dict[cspace][cieobs][lut_label] with the
lut part of a two-element list [lut, lut_kwargs]. It must contain
at the top-level a key ‘wl’ containing the wavelengths of the
Planckians used to generate the luts in this dictionary.
If None: luts_dict defaults to _CCT_LUT[‘ohno2014’][‘luts’]
cspace:
_CCT_SPACE, optional
Color space to do calculations in.
Options:
- cspace string:
e.g. ‘Yuv60’ for use with luxpy.colortf()
- tuple with forward (i.e. xyz_to..) [and backward (i.e. ..to_xyz)] functions
(and an optional string describing the cspace):
e.g. (forward, backward) or (forward, backward, cspace string) or (forward, cspace string)
- dict with keys: ‘fwtf’ (foward), ‘bwtf’ (backward) [, optional: ‘str’ (cspace string)]
Note: if the backward tf is not supplied, optimization in cct_to_xyz() is done in the CIE 1976 u’v’ diagram
cspace_kwargs:
_CCT_CSPACE_KWARGS, optional
Parameter nested dictionary for the forward and backward transforms.
ignore_wl_diff:
False, optional
When getting a lut from the dictionary, if differences are
detected in the wavelengts of the lut and the ones used to calculate any
plankcians then a new lut should be generated. Seting this to True ignores
these differences and proceeds anyway.
use_fast_duv:
_CCT_FAST_DUV, optional
If True: use a fast estimator of the Duv
(one that avoids calculation of Planckians and uses the former
best estimate’s u,v coordinates. This method is accurate enough
when the atol is small enough -> as long as abs(T-T_former)<=1K
the Duv estimate should be ok.)
Returns:
returns:
ndarray with:
cct: out == ‘cct’ (or 1)
duv: out == ‘duv’ (or -1)
cct, duv: out == ‘cct,duv’ (or 2)
[cct,duv]: out == “[cct,duv]” (or -2)
Note:

1. Out-of-lut CCTs are encoded as negative CCTs (with as absolute value the value of the closest CCT from the lut.)

References:

1. Ohno Y. Practical use and calculation of CCT and Duv. Leukos. 2014 Jan 2;10(1):47-55.

2. Li, C., Cui, G., Melgosa, M., Ruan, X., Zhang, Y., Ma, L., Xiao, K., & Luo, M. R. (2016). Accurate method for computing correlated color temperature. Optics Express, 24(13), 14066–14078.

luxpy.color.cct.xyz_to_cct_li2016(xyzw, cieobs='1931_2', out='cct', is_uv_input=False, wl=None, atol=0.1, rtol=1e-05, max_iter=10, split_calculation_at_N=25, lut=None, luts_dict=None, ignore_wl_diff=False, lut_resolution_reduction_factor=4, cspace='Yuv60', cspace_kwargs={'bwtf': {}, 'fwtf': {}}, first_guess_mode='robertson2023', fgm_kwargs={}, use_fast_duv=True, **kwargs)[source]

Convert XYZ tristimulus values to correlated color temperature (CCT) and Duv(distance above (> 0) or below ( < 0) the Planckian locus) using the Newton-Raphson method described in Li et al. (2016).

Args:
xyzw:
ndarray of tristimulus values
cieobs:
luxpy._CIEOBS, optional
CMF set used to calculated xyzw.
out:
‘cct’ (or 1), optional
Determines what to return.
Other options: ‘duv’ (or -1), ‘cct,duv’(or 2), “[cct,duv]” (or -2)
is_uv_input:
False, optional
If True: xyzw contain uv input data, not xyz data!
wl:
None, optional
Wavelengths used when calculating Planckian radiators.
If None: use same wavelengths as CMFs in :cieobs:.
rtol:
1e-5, float, optional
Stop method when cct a relative tolerance is reached.
The relative tolerance is calculated as dCCT/CCT_est,
with CCT_est the current intermediate estimate in the
search and with dCCT the difference between
the present and former estimates.
atol:
0.1, optional
Stop method when cct a absolute tolerance (K) is reached.
max_iter:
_CCT_MAX_ITER, optional
Maximum number of iterations used newton-raphson methods.
lut_resolution_reduction_factor:
_CCT_LUT_RESOLUTION_REDUCTION_FACTOR, optional
Number of times the interval spanned by the adjacent Tc in a search or lut
method is downsampled (the search process will then start again)
split_calculation_at_N:
_CCT_SPLIT_CALC_AT_N, optional
Split calculation when xyzw.shape[0] > split_calculation_at_N.
Splitting speeds up the calculation. If None: no splitting is done.
lut:
None, optional
Look-Up-Table with Ti, u,v,u’,v’,u”,v”,slope values of Planckians.
Options:
- None: defaults to the lut specified in _CCT_LUT[first_guess_mode][‘lut_type_def’].
- list (lut,lut_kwargs): use this pre-calculated lut
(add additional kwargs for the lut_generator_fcn(), defaults to None if omitted)
- tuple: must be key (label) in :luts_dict: (pre-calculated dict of luts),
if not: then a new lut will be generated from scratch using the info in the tuple.
- str: must be key (label) in :luts_dict: (pre-calculated dict of luts)
- ndarray [Nx1]: list of luts for which to generate a lut
- ndarray [Nxn] with n>3: pre-calculated lut (last col must contain slope of the isotemperature lines).
luts_dict:
None, optional
Dictionary of pre-calculated luts for various cspaces and cmf sets.
Must have structure luts_dict[cspace][cieobs][lut_label] with the
lut part of a two-element list [lut, lut_kwargs]. It must contain
at the top-level a key ‘wl’ containing the wavelengths of the
Planckians used to generate the luts in this dictionary.
If None: luts_dict defaults to _CCT_LUT[first_guess_mode][‘luts’]
cspace:
_CCT_SPACE, optional
Color space to do calculations in.
Options:
- cspace string:
e.g. ‘Yuv60’ for use with luxpy.colortf()
- tuple with forward (i.e. xyz_to..) [and backward (i.e. ..to_xyz)] functions
(and an optional string describing the cspace):
e.g. (forward, backward) or (forward, backward, cspace string) or (forward, cspace string)
- dict with keys: ‘fwtf’ (foward), ‘bwtf’ (backward) [, optional: ‘str’ (cspace string)]
Note: if the backward tf is not supplied, optimization in cct_to_xyz() is done in the CIE 1976 u’v’ diagram
cspace_kwargs:
_CCT_CSPACE_KWARGS, optional
Parameter nested dictionary for the forward and backward transforms.
ignore_wl_diff:
False, optional
When getting a lut from the dictionary, if differences are
detected in the wavelengts of the lut and the ones used to calculate any
plankcians then a new lut should be generated. Seting this to True ignores
these differences and proceeds anyway.
first_guess_mode:
‘robertson2023’, optional
Method used to get an approximate (first guess) estimate of the cct,
after which the newton-raphson method is started.
Options: ‘robertson2023’, ‘ohno2014’, ‘zhang2019’
fgm_kwargs:
Dict with keyword arguments for the selected first_guess_mode.
use_fast_duv:
_CCT_FAST_DUV, optional
If True: use a fast estimator of the Duv
(one that avoids calculation of Planckians and uses the former
best estimate’s u,v coordinates. This method is accurate enough
when the atol is small enough -> as long as abs(T-T_former)<=1K
the Duv estimate should be ok.)
Returns:
returns:
ndarray with:
cct: out == ‘cct’ (or 1)
duv: out == ‘duv’ (or -1)
cct, duv: out == ‘cct,duv’ (or 2)
[cct,duv]: out == “[cct,duv]” (or -2)
Note:

1. Out-of-lut (of first_guess_mode) CCTs are encoded as negative CCTs (with as absolute value the value of the closest CCT from the lut.)

References:

1. Li, C., Cui, G., Melgosa, M., Ruan, X., Zhang, Y., Ma, L., Xiao, K., & Luo, M. R. (2016). Accurate method for computing correlated color temperature. Optics Express, 24(13), 14066–14078.

2. Robertson, A. R. (1968). Computation of Correlated Color Temperature and Distribution Temperature. Journal of the Optical Society of America, 58(11), 1528–1535.

luxpy.color.cct.xyz_to_cct_li2022(xyzw, cieobs='1931_2', out='cct', is_uv_input=False, wl=None, atol=0.1, rtol=1e-05, force_tolerance=True, tol_method='newton-raphson', lut_resolution_reduction_factor=4, duv_triangular_threshold=0.002, split_calculation_at_N=25, max_iter=10, cspace='Yuv60', cspace_kwargs={'bwtf': {}, 'fwtf': {}}, lut=None, luts_dict=None, ignore_wl_diff=False, use_fast_duv=True, **kwargs)[source]

Convert XYZ tristimulus values to correlated color temperature (CCT) and Duv (distance above (>0) or below (<0) the Planckian locus) using Li’s 2022 update (proposal 2) of Ohno’s 2014 method.

Args:
xyzw:
ndarray of tristimulus values
cieobs:
luxpy._CIEOBS, optional
CMF set used to calculated xyzw.
out:
‘cct’ (or 1), optional
Determines what to return.
Other options: ‘duv’ (or -1), ‘cct,duv’(or 2), “[cct,duv]” (or -2)
is_uv_input:
False, optional
If True: xyzw contain uv input data, not xyz data!
wl:
None, optional
Wavelengths used when calculating Planckian radiators.
If None: use same wavelengths as CMFs in :cieobs:.
rtol:
1e-5, float, optional
Stop search when cct a relative tolerance is reached.
The relative tolerance is calculated as dCCT/CCT_est,
with CCT_est the current intermediate estimate in the
search and with dCCT the difference between
the present and former estimates.
atol:
0.1, optional
Stop search when cct a absolute tolerance (K) is reached.
force_tolerance:
True, optional
If False: search only using the list of CCTs in the used lut.
Only one loop of the full algorithm is performed.
Accuracy depends on CCT of test source and the location
and spacing of the CCTs in the list.
If True: search will use adjacent CCTs to test source to create a new LUT,
(repeat the algoritm at higher resolution, progessively zooming in
toward the ground-truth) for tol_method == ‘cl’; when
tol_method == ‘nr’ a newton-raphson method is used.
Because the CCT for multiple source is calculated in one go,
the atol and rtol values have to be met for all!
tol_method:
‘newton-raphson’, optional
(Additional) method to try and achieve set tolerances.
Options:
- ‘cl’, ‘cascading-lut’: use increasingly higher CCT-resolution
to ‘zoom-in’ on the ground-truth.
- ‘nr’, ‘newton-raphson’: use the method as described in Li, 2016.
lut_resolution_reduction_factor:
_CCT_LUT_RESOLUTION_REDUCTION_FACTOR, optional
Number of times the interval spanned by the adjacent Tc in a search or lut
method is downsampled (the search process will then start again)
duv_triangular_threshold:
0.002, optional
Threshold for use of the triangular solution
(if smaller use triangular solution, else use the non-triangular (third order polynomial))
max_iter:
_CCT_MAX_ITER, optional
Maximum number of iterations used by the cascading-lut or newton-raphson methods.
split_calculation_at_N:
_CCT_SPLIT_CALC_AT_N, optional
Split calculation when xyzw.shape[0] > split_calculation_at_N.
Splitting speeds up the calculation. If None: no splitting is done.
lut:
None, optional
Look-Up-Table with Ti, u,v,u’,v’,u”,v”,slope values of Planckians.
Options:
- None: defaults to the lut specified in _CCT_LUT[‘li2022’][‘lut_type_def’].
- list (lut,lut_kwargs): use this pre-calculated lut
(add additional kwargs for the lut_generator_fcn(), defaults to None if omitted)
- tuple: must be key (label) in :luts_dict: (pre-calculated dict of luts),
if not: then a new lut will be generated from scratch using the info in the tuple.
- str: must be key (label) in :luts_dict: (pre-calculated dict of luts)
- ndarray [Nx1]: list of luts for which to generate a lut
- ndarray [Nxn] with n>3: pre-calculated lut (last col must contain slope of the isotemperature lines).
luts_dict:
None, optional
Dictionary of pre-calculated luts for various cspaces and cmf sets.
Must have structure luts_dict[cspace][cieobs][lut_label] with the
lut part of a two-element list [lut, lut_kwargs]. It must contain
at the top-level a key ‘wl’ containing the wavelengths of the
Planckians used to generate the luts in this dictionary.
If None: luts_dict defaults to _CCT_LUT[‘li2022’][‘luts’]
cspace:
_CCT_SPACE, optional
Color space to do calculations in.
Options:
- cspace string:
e.g. ‘Yuv60’ for use with luxpy.colortf()
- tuple with forward (i.e. xyz_to..) [and backward (i.e. ..to_xyz)] functions
(and an optional string describing the cspace):
e.g. (forward, backward) or (forward, backward, cspace string) or (forward, cspace string)
- dict with keys: ‘fwtf’ (foward), ‘bwtf’ (backward) [, optional: ‘str’ (cspace string)]
Note: if the backward tf is not supplied, optimization in cct_to_xyz() is done in the CIE 1976 u’v’ diagram
cspace_kwargs:
_CCT_CSPACE_KWARGS, optional
Parameter nested dictionary for the forward and backward transforms.
ignore_wl_diff:
False, optional
When getting a lut from the dictionary, if differences are
detected in the wavelengts of the lut and the ones used to calculate any
plankcians then a new lut should be generated. Seting this to True ignores
these differences and proceeds anyway.
use_fast_duv:
_CCT_FAST_DUV, optional
If True: use a fast estimator of the Duv
(one that avoids calculation of Planckians and uses the former
best estimate’s u,v coordinates. This method is accurate enough
when the atol is small enough -> as long as abs(T-T_former)<=1K
the Duv estimate should be ok.)
Returns:
returns:
ndarray with:
cct: out == ‘cct’ (or 1)
duv: out == ‘duv’ (or -1)
cct, duv: out == ‘cct,duv’ (or 2)
[cct,duv]: out == “[cct,duv]” (or -2)
Note:

1. Out-of-lut CCTs are encoded as negative CCTs (with as absolute value the value of the closest CCT from the lut.)

References:

1. Ohno Y. Practical use and calculation of CCT and Duv. Leukos. 2014 Jan 2;10(1):47-55.

2. Li, Y., Gao, C., Melgosa, M. and Li, C. (2022). Improved methods for computing CCT and Duv. LEUKOS, (in press).

luxpy.color.cct.xyz_to_cct_zhang2019(xyzw, cieobs='1931_2', out='cct', is_uv_input=False, wl=None, atol=0.1, rtol=1e-05, force_tolerance=True, tol_method='newton-raphson', lut_resolution_reduction_factor=4, split_calculation_at_N=25, max_iter=10, cspace='Yuv60', cspace_kwargs={'bwtf': {}, 'fwtf': {}}, lut=None, luts_dict=None, ignore_wl_diff=False, use_fast_duv=True, **kwargs)[source]

Convert XYZ tristimulus values to correlated color temperature (CCT) and Duv(distance above (> 0) or below ( < 0) the Planckian locus) using the golden-ratio search method described in Zhang et al. (2019).

Args:
xyzw:
ndarray of tristimulus values
cieobs:
luxpy._CIEOBS, optional
CMF set used to calculated xyzw.
out:
‘cct’ (or 1), optional
Determines what to return.
Other options: ‘duv’ (or -1), ‘cct,duv’(or 2), “[cct,duv]” (or -2)
is_uv_input:
False, optional
If True: xyzw contain uv input data, not xyz data!
wl:
None, optional
Wavelengths used when calculating Planckian radiators.
If None: use same wavelengths as CMFs in :cieobs:.
rtol:
1e-5, float, optional
Stop search when cct a relative tolerance is reached.
The relative tolerance is calculated as dCCT/CCT_est,
with CCT_est the current intermediate estimate in the
search and with dCCT the difference between
the present and former estimates.
atol:
0.1, optional
Stop search when cct a absolute tolerance (K) is reached.
force_tolerance:
True, optional
If False: search only using the list of CCTs in the used lut.
Only one loop of the full algorithm is performed.
Accuracy depends on CCT of test source and the location
and spacing of the CCTs in the list.
If True: search will use adjacent CCTs to test source to create a new LUT,
(repeat the algoritm at higher resolution, progessively zooming in
toward the ground-truth) for tol_method == ‘cl’; when
tol_method == ‘nr’ a newton-raphson method is used.
Because the CCT for multiple source is calculated in one go,
the atol and rtol values have to be met for all!
tol_method:
‘newton-raphson’, optional
(Additional) method to try and achieve set tolerances.
Options:
- ‘cl’, ‘cascading-lut’: use increasingly higher CCT-resolution
to ‘zoom-in’ on the ground-truth.
- ‘nr’, ‘newton-raphson’: use the method as described in Li, 2016.
lut_resolution_reduction_factor:
_CCT_LUT_RESOLUTION_REDUCTION_FACTOR, optional
Number of times the interval spanned by the adjacent Tc in a search or lut
method is downsampled (the search process will then start again)
max_iter:
_CCT_MAX_ITER, optional
Maximum number of iterations used by the cascading-lut or newton-raphson methods.
split_calculation_at_N:
_CCT_SPLIT_CALC_AT_N, optional
Split calculation when xyzw.shape[0] > split_calculation_at_N.
Splitting speeds up the calculation. If None: no splitting is done.
lut:
None, optional
Look-Up-Table with Ti, u,v,u’,v’,u”,v”,slope values of Planckians.
Options:
- None: defaults to the lut specified in _CCT_LUT[‘zhang2019’][‘lut_type_def’].
- list (lut,lut_kwargs): use this pre-calculated lut
(add additional kwargs for the lut_generator_fcn(), defaults to None if omitted)
- tuple: must be key (label) in :luts_dict: (pre-calculated dict of luts),
if not: then a new lut will be generated from scratch using the info in the tuple.
- str: must be key (label) in :luts_dict: (pre-calculated dict of luts)
- ndarray [Nx1]: list of luts for which to generate a lut
- ndarray [Nxn] with n>3: pre-calculated lut (last col must contain slope of the isotemperature lines).
luts_dict:
None, optional
Dictionary of pre-calculated luts for various cspaces and cmf sets.
Must have structure luts_dict[cspace][cieobs][lut_label] with the
lut part of a two-element list [lut, lut_kwargs]. It must contain
at the top-level a key ‘wl’ containing the wavelengths of the
Planckians used to generate the luts in this dictionary.
If None: luts_dict defaults to _CCT_LUT[‘zhang2019’][‘luts’]
cspace:
_CCT_SPACE, optional
Color space to do calculations in.
Options:
- cspace string:
e.g. ‘Yuv60’ for use with luxpy.colortf()
- tuple with forward (i.e. xyz_to..) [and backward (i.e. ..to_xyz)] functions
(and an optional string describing the cspace):
e.g. (forward, backward) or (forward, backward, cspace string) or (forward, cspace string)
- dict with keys: ‘fwtf’ (foward), ‘bwtf’ (backward) [, optional: ‘str’ (cspace string)]
Note: if the backward tf is not supplied, optimization in cct_to_xyz() is done in the CIE 1976 u’v’ diagram
cspace_kwargs:
_CCT_CSPACE_KWARGS, optional
Parameter nested dictionary for the forward and backward transforms.
ignore_wl_diff:
False, optional
When getting a lut from the dictionary, if differences are
detected in the wavelengts of the lut and the ones used to calculate any
plankcians then a new lut should be generated. Seting this to True ignores
these differences and proceeds anyway.
use_fast_duv:
_CCT_FAST_DUV, optional
If True: use a fast estimator of the Duv
(one that avoids calculation of Planckians and uses the former
best estimate’s u,v coordinates. This method is accurate enough
when the atol is small enough -> as long as abs(T-T_former)<=1K
the Duv estimate should be ok.)
Returns:
returns:
ndarray with:
cct: out == ‘cct’ (or 1)
duv: out == ‘duv’ (or -1)
cct, duv: out == ‘cct,duv’ (or 2)
[cct,duv]: out == “[cct,duv]” (or -2)
Note:

1. Out-of-lut CCTs are encoded as negative CCTs (with as absolute value the value of the closest CCT from the lut.)

References:

1. Zhang, F. (2019). High-accuracy method for calculating correlated color temperature with a lookup table based on golden section search. Optik, 193, 163018.

2. Li, C., Cui, G., Melgosa, M., Ruan, X., Zhang, Y., Ma, L., Xiao, K., & Luo, M. R. (2016). Accurate method for computing correlated color temperature. Optics Express, 24(13), 14066–14078.

luxpy.color.cct.xyz_to_cct_fibonacci(xyzw, cieobs='1931_2', out='cct', is_uv_input=False, wl=None, atol=0.1, rtol=1e-05, force_tolerance=True, tol_method='newton-raphson', lut_resolution_reduction_factor=4, split_calculation_at_N=25, max_iter=10, cspace='Yuv60', cspace_kwargs={'bwtf': {}, 'fwtf': {}}, lut=None, luts_dict=None, ignore_wl_diff=False, use_fast_duv=True, **kwargs)[source]

Convert XYZ tristimulus values to correlated color temperature (CCT) and Duv(distance above (> 0) or below ( < 0) the Planckian locus) using a Fibonacci search.

Args:
xyzw:
ndarray of tristimulus values
cieobs:
luxpy._CIEOBS, optional
CMF set used to calculated xyzw.
out:
‘cct’ (or 1), optional
Determines what to return.
Other options: ‘duv’ (or -1), ‘cct,duv’(or 2), “[cct,duv]” (or -2)
is_uv_input:
False, optional
If True: xyzw contain uv input data, not xyz data!
wl:
None, optional
Wavelengths used when calculating Planckian radiators.
If None: use same wavelengths as CMFs in :cieobs:.
rtol:
1e-5, float, optional
Stop search when cct a relative tolerance is reached.
The relative tolerance is calculated as dCCT/CCT_est,
with CCT_est the current intermediate estimate in the
search and with dCCT the difference between
the present and former estimates.
atol:
0.1, optional
Stop search when cct a absolute tolerance (K) is reached.
force_tolerance:
True, optional
If False: search only using the list of CCTs in the used lut.
Only one loop of the full algorithm is performed.
Accuracy depends on CCT of test source and the location
and spacing of the CCTs in the list.
If True: search will use adjacent CCTs to test source to create a new LUT,
(repeat the algoritm at higher resolution, progessively zooming in
toward the ground-truth) for tol_method == ‘cl’; when
tol_method == ‘nr’ a newton-raphson method is used.
Because the CCT for multiple source is calculated in one go,
the atol and rtol values have to be met for all!
tol_method:
‘newton-raphson’, optional
(Additional) method to try and achieve set tolerances.
Options:
- ‘cl’, ‘cascading-lut’: use increasingly higher CCT-resolution
to ‘zoom-in’ on the ground-truth.
- ‘nr’, ‘newton-raphson’: use the method as described in Li, 2016.
lut_resolution_reduction_factor:
_CCT_LUT_RESOLUTION_REDUCTION_FACTOR, optional
Number of times the interval spanned by the adjacent Tc in a search or lut
method is downsampled (the search process will then start again)
max_iter:
_CCT_MAX_ITER, optional
Maximum number of iterations used by the cascading-lut or newton-raphson methods.
split_calculation_at_N:
_CCT_SPLIT_CALC_AT_N, optional
Split calculation when xyzw.shape[0] > split_calculation_at_N.
Splitting speeds up the calculation. If None: no splitting is done.
lut:
None, optional
Look-Up-Table with Ti, u,v,u’,v’,u”,v”,slope values of Planckians.
Options:
- None: defaults to the lut specified in _CCT_LUT[‘fibonacci’][‘lut_type_def’].
- list (lut,lut_kwargs): use this pre-calculated lut
(add additional kwargs for the lut_generator_fcn(), defaults to None if omitted)
- tuple: must be key (label) in :luts_dict: (pre-calculated dict of luts),
if not: then a new lut will be generated from scratch using the info in the tuple.
- str: must be key (label) in :luts_dict: (pre-calculated dict of luts)
- ndarray [Nx1]: list of luts for which to generate a lut
- ndarray [Nxn] with n>3: pre-calculated lut (last col must contain slope of the isotemperature lines).
luts_dict:
None, optional
Dictionary of pre-calculated luts for various cspaces and cmf sets.
Must have structure luts_dict[cspace][cieobs][lut_label] with the
lut part of a two-element list [lut, lut_kwargs]. It must contain
at the top-level a key ‘wl’ containing the wavelengths of the
Planckians used to generate the luts in this dictionary.
If None: luts_dict defaults to _CCT_LUT[‘fibonacci’][‘luts’]
cspace:
_CCT_SPACE, optional
Color space to do calculations in.
Options:
- cspace string:
e.g. ‘Yuv60’ for use with luxpy.colortf()
- tuple with forward (i.e. xyz_to..) [and backward (i.e. ..to_xyz)] functions
(and an optional string describing the cspace):
e.g. (forward, backward) or (forward, backward, cspace string) or (forward, cspace string)
- dict with keys: ‘fwtf’ (foward), ‘bwtf’ (backward) [, optional: ‘str’ (cspace string)]
Note: if the backward tf is not supplied, optimization in cct_to_xyz() is done in the CIE 1976 u’v’ diagram
cspace_kwargs:
_CCT_CSPACE_KWARGS, optional
Parameter nested dictionary for the forward and backward transforms.
ignore_wl_diff:
False, optional
When getting a lut from the dictionary, if differences are
detected in the wavelengts of the lut and the ones used to calculate any
plankcians then a new lut should be generated. Seting this to True ignores
these differences and proceeds anyway.
use_fast_duv:
_CCT_FAST_DUV, optional
If True: use a fast estimator of the Duv
(one that avoids calculation of Planckians and uses the former
best estimate’s u,v coordinates. This method is accurate enough
when the atol is small enough -> as long as abs(T-T_former)<=1K
the Duv estimate should be ok.)
Returns:
returns:
ndarray with:
cct: out == ‘cct’ (or 1)
duv: out == ‘duv’ (or -1)
cct, duv: out == ‘cct,duv’ (or 2)
[cct,duv]: out == “[cct,duv]” (or -2)
Note:

1. Out-of-lut CCTs (or close to) are encoded as negative CCTs (with as absolute value the value of the closest CCT from the lut.)

luxpy.color.cct.xyz_to_cct(xyzw, mode='robertson2023', cieobs='1931_2', out='cct', is_uv_input=False, wl=None, atol=0.1, rtol=1e-05, force_tolerance=True, tol_method='newton-raphson', lut_resolution_reduction_factor=4, split_calculation_at_N=25, max_iter=10, cspace='Yuv60', cspace_kwargs={'bwtf': {}, 'fwtf': {}}, lut=None, luts_dict=None, ignore_wl_diff=False, duv_triangular_threshold=0.002, first_guess_mode='robertson2023', fgm_kwargs={}, use_fast_duv=True, **kwargs)[source]

Convert XYZ tristimulus values to correlated color temperature (CCT) and Duv (distance above (>0) or below (<0) the Planckian locus) using a number of modes (methods).

Args:
xyzw:
ndarray of tristimulus values
mode:
‘robertson2023’, optional
String with name of method to use.
Options: ‘robertson2023’, ‘robertson1968’, ‘ohno2014’, ‘li2016’, ‘li2022’,’zhang2019’, ‘fibonacci’,
(also, but see note below: ‘mcamy1992’, ‘hernandez1999’)
Note: first_guess_mode for li2016 can also be specified using a ‘:’ separator,
e.g. ‘li2016:robertson1968’
cieobs:
luxpy._CIEOBS, optional
CMF set used to calculated xyzw.
out:
‘cct’ (or 1), optional
Determines what to return.
Other options: ‘duv’ (or -1), ‘cct,duv’(or 2), “[cct,duv]” (or -2)
is_uv_input:
False, optional
If True: xyzw contain uv input data, not xyz data!
wl:
None, optional
Wavelengths used when calculating Planckian radiators.
If None: use same wavelengths as CMFs in :cieobs:.
rtol:
1e-5, float, optional
Stop search when cct a relative tolerance is reached.
The relative tolerance is calculated as dCCT/CCT_est,
with CCT_est the current intermediate estimate in the
search and with dCCT the difference between
the present and former estimates.
atol:
0.1, optional
Stop search when cct a absolute tolerance (K) is reached.
force_tolerance:
True, optional
If False: search only using the list of CCTs in the used lut.
Only one loop of the full algorithm is performed.
Accuracy depends on CCT of test source and the location
and spacing of the CCTs in the list.
If True: search will use adjacent CCTs to test source to create a new LUT,
(repeat the algoritm at higher resolution, progessively zooming in
toward the ground-truth) for tol_method == ‘cl’; when
tol_method == ‘nr’ a newton-raphson method is used.
Because the CCT for multiple source is calculated in one go,
the atol and rtol values have to be met for all!
tol_method:
‘newton-raphson’, optional
(Additional) method to try and achieve set tolerances.
Options:
- ‘cl’, ‘cascading-lut’: use increasingly higher CCT-resolution
to ‘zoom-in’ on the ground-truth. (not for mode == ‘li2016’)
- ‘nr’, ‘newton-raphson’: use the method as described in Li, 2016.
lut_resolution_reduction_factor:
_CCT_LUT_RESOLUTION_REDUCTION_FACTOR, optional
Number of times the interval spanned by the adjacent Tc in a search or lut
method is downsampled (the search process will then start again)
max_iter:
_CCT_MAX_ITER, optional
Maximum number of iterations used by the cascading-lut or newton-raphson methods.
split_calculation_at_N:
_CCT_SPLIT_CALC_AT_N, optional
Split calculation when xyzw.shape[0] > split_calculation_at_N.
Splitting speeds up the calculation. If None: no splitting is done.
lut:
None, optional
Look-Up-Table with Ti, u,v,u’,v’,u”,v”,slope values of Planckians.
Options:
- None: defaults to the lut specified in _CCT_LUT[mode][‘lut_type_def’].
- list (lut,lut_kwargs): use this pre-calculated lut
(add additional kwargs for the lut_generator_fcn(), defaults to None if omitted)
- tuple: must be key (label) in :luts_dict: (pre-calculated dict of luts),
if not: then a new lut will be generated from scratch using the info in the tuple.
- str: must be key (label) in :luts_dict: (pre-calculated dict of luts)
- ndarray [Nx1]: list of luts for which to generate a lut
- ndarray [Nxn] with n>3: pre-calculated lut (last col must contain slope of the isotemperature lines).
luts_dict:
None, optional
Dictionary of pre-calculated luts for various cspaces and cmf sets.
Must have structure luts_dict[cspace][cieobs][lut_label] with the
lut part of a two-element list [lut, lut_kwargs]. It must contain
at the top-level a key ‘wl’ containing the wavelengths of the
Planckians used to generate the luts in this dictionary.
If None: the default dict for the mode is used
(e.g. _CCT_LUT[‘ohno2014’][‘lut_type_def’], for mode==’ohno2014’).
cspace:
_CCT_SPACE, optional
Color space to do calculations in.
Options:
- cspace string:
e.g. ‘Yuv60’ for use with luxpy.colortf()
- tuple with forward (i.e. xyz_to..) [and backward (i.e. ..to_xyz)] functions
(and an optional string describing the cspace):
e.g. (forward, backward) or (forward, backward, cspace string) or (forward, cspace string)
- dict with keys: ‘fwtf’ (foward), ‘bwtf’ (backward) [, optional: ‘str’ (cspace string)]
Note: if the backward tf is not supplied, optimization in cct_to_xyz() is done in the CIE 1976 u’v’ diagram
cspace_kwargs:
_CCT_CSPACE_KWARGS, optional
Parameter nested dictionary for the forward and backward transforms.
ignore_wl_diff:
False, optional
When getting a lut from the dictionary, if differences are
detected in the wavelengts of the lut and the ones used to calculate any
plankcians then a new lut should be generated. Seting this to True ignores
these differences and proceeds anyway.
duv_triangular_threshold:
0.002, optional
Threshold for use of the triangular solution.
(if smaller use triangular solution, else use the non-triangular one:
If mode == ‘ohno2014’ -> parabolic, if mode == ‘li2022’ -> 3e-order poly)
first_guess_mode:
‘robertson2023’, optional (cfr. mode == ‘li2016’)
Method used to get an approximate (first guess) estimate of the cct,
after which the newton-raphson method is started.
Options: ‘robertson2023’,’robertson1968’, ‘ohno2014’, ‘zhang2019’,’li2022’
use_fast_duv:
_CCT_FAST_DUV, optional
If True: use a fast estimator of the Duv
(one that avoids calculation of Planckians and uses the former
best estimate’s u,v coordinates. This method is accurate enough
when the atol is small enough -> as long as abs(T-T_former)<=1K
the Duv estimate should be ok.)
Returns:
returns:
ndarray with:
cct: out == ‘cct’ (or 1)
duv: out == ‘duv’ (or -1)
cct, duv: out == ‘cct,duv’ (or 2)
[cct,duv]: out == “[cct,duv]” (or -2)
Note:

1. Using the ‘mcamy1992’ and ‘hernandez1999’ options will result in additional errors when cieobs is different from ‘1931_2’ as for these options the CCT is determined using a fixed set of equations optimized for the 1931 2° CMFs!! The only impact will be on the calculation of the Duv from the CCT. That does depend on the settings of cieobs and cspace! Change at own discretion. 2. Out-of-lut CCTs are encoded as negative CCTs (with as absolute value the value of the closest CCT from the lut.)

References:

1. Robertson, A. R. (1968). Computation of Correlated Color Temperature and Distribution Temperature. Journal of the Optical Society of America, 58(11), 1528–1535.

2. Smet K.A.G., Royer M., Baxter D., Bretschneider E., Esposito E., Houser K., Luedtke W., Man K., Ohno Y. (2022), Recommended method for determining the correlated color temperature and distance from the Planckian Locus of a light source (in preparation, LEUKOS?)

3. Baxter D., Royer M., Smet K.A.G. (2022) Modifications of the Robertson Method for Calculating Correlated Color Temperature to Improve Accuracy and Speed (in preparation, LEUKOS?)

4. Ohno Y. Practical use and calculation of CCT and Duv. Leukos. 2014 Jan 2;10(1):47-55.

5. Zhang, F. (2019). High-accuracy method for calculating correlated color temperature with a lookup table based on golden section search. Optik, 193, 163018.

6. Li, C., Cui, G., Melgosa, M., Ruan, X., Zhang, Y., Ma, L., Xiao, K., & Luo, M. R. (2016). Accurate method for computing correlated color temperature. Optics Express, 24(13), 14066–14078.

7. McCamy, Calvin S. (April 1992). “Correlated color temperature as an explicit function of chromaticity coordinates”. Color Research & Application. 17 (2): 142–144.

8. Hernández-Andrés, Javier; Lee, RL; Romero, J (September 20, 1999). Calculating Correlated Color Temperatures Across the Entire Gamut of Daylight and Skylight Chromaticities. Applied Optics. 38 (27), 5703–5709. P

9. Li, Y., Gao, C., Melgosa, M. and Li, C. (2022). Improved methods for computing CCT and Duv. LEUKOS, (in press).

luxpy.color.cct.cct_to_xyz(ccts, duv=None, cct_offset=None, cieobs='1931_2', wl=None, cspace='Yuv60', cspace_kwargs={'bwtf': {}, 'fwtf': {}})[source]

Convert correlated color temperature (550 K <= CCT <= 1e11 K) and Duv (distance above (>0) or below (<0) the Planckian locus) to XYZ tristimulus values.

Finds xyzw_estimated by determining the iso-temperature line
(= line perpendicular to the Planckian locus):
Option 1 (fastest):
First, the angle between the coordinates corresponding to ccts
and ccts-cct_offset are calculated, then 90° is added, and finally
the new coordinates are determined, while taking sign of duv into account.
Option 2 (slowest, about 55% slower):
Calculate the slope of the iso-T-line directly using the Planckian
spectrum and its derivative.
Args:
ccts:
ndarray [N,1] of cct values
duv:
None or ndarray [N,1] of duv values, optional
Note that duv can be supplied together with cct values in :ccts:
as ndarray with shape [N,2].
cct_offset:
None, optional
If None: use option 2 (direct iso-T slope calculation, more accurate,
but slower: about 1.55 slower)
else: use option 1 (estimate slope from 90° + angle of small cct_offset)
cieobs:
luxpy._CIEOBS, optional
CMF set used to calculated xyzw.
wl:
None, optional
Wavelengths used when calculating Planckian radiators.
If None: use same wavelengths as CMFs in :cieobs:.
cspace:
_CCT_SPACE, optional
Color space to do calculations in.
Options:
- cspace string:
e.g. ‘Yuv60’ for use with luxpy.colortf()
- tuple with forward (i.e. xyz_to..) [and backward (i.e. ..to_xyz)] functions
(and an optional string describing the cspace):
e.g. (forward, backward) or (forward, backward, cspace string) or (forward, cspace string)
- dict with keys: ‘fwtf’ (foward), ‘bwtf’ (backward) [, optional: ‘str’ (cspace string)]
Note: if the backward tf is not supplied, optimization in cct_to_xyz() is done in the CIE 1976 u’v’ diagram
cspace_kwargs:
_CCT_CSPACE_KWARGS, optional
Parameter nested dictionary for the forward and backward transforms.
Returns:
returns:
ndarray with estimated XYZ tristimulus values
Note:

1. If duv is not supplied (:ccts:.shape is (N,1) and :duv: is None), source is assumed to be on the Planckian locus. 2. Minimum CCT is 550 K (lower than 550 K, some negative Duv values will result in coordinates outside of the Spectrum Locus !!!)

luxpy.color.cct.calculate_lut(ccts, cieobs, wl=None, lut_vars=['T', 'uv', 'uvp', 'uvpp', 'iso-T-slope'], cspace='Yuv60', cspace_kwargs={'bwtf': {}, 'fwtf': {}})[source]

Function that calculates a LUT for the specified calculation method for the input ccts. Calculation is performed for CMF set specified in cieobs and in the chromaticity diagram in cspace.

Args:
ccts:
ndarray [Nx1] or str
list of ccts for which to (re-)calculate the LUTs.
If str, ccts contains path/filename.dat to list.
cieobs:
None or str or ndrarray, optional
str specifying cmf set.
wl:
None, optional
Generate luts based on Planckians with wavelengths (range).
If None: use same wavelengths as CMFs in :cieobs:.
lut_vars:
[‘T’,’uv’,’uvp’,’uvpp’,’iso-T-slope’], optional
Data the lut should contain. Must follow this order
and minimum should be [‘T’]
cspace:
_CCT_SPACE, optional
Color space to do calculations in.
Options:
- cspace string:
e.g. ‘Yuv60’ for use with luxpy.colortf()
- tuple with forward (i.e. xyz_to..) [and backward (i.e. ..to_xyz)] functions
(and an optional string describing the cspace):
e.g. (forward, backward) or (forward, backward, cspace string) or (forward, cspace string)
- dict with keys: ‘fwtf’ (foward), ‘bwtf’ (backward) [, optional: ‘str’ (cspace string)]
Note: if the backward tf is not supplied, optimization in cct_to_xyz() is done in the CIE 1976 u’v’ diagram
cspace_kwargs:
_CCT_CSPACE_KWARGS, optional
Parameter nested dictionary for the forward and backward transforms.
Returns:
returns:
lut:
ndarray with T, u, v, u’, v’, u”, v”, slope (note ‘:1st deriv., “:2nd deriv.).
luxpy.color.cct.generate_luts(types=[None], seamless_stitch=True, fallback_unit='K-1', fallback_n=50, cct_min=450, cct_max=100000000000.0, lut_file=None, load=False, lut_path='C:\\Users\\u0032318\\OneDrive - KU Leuven\\Documents\\Github\\luxpy\\luxpy\\data\\cctluts\\', save_luts=True, wl=None, cieobs=['1931_2'], lut_vars=['T', 'uv', 'uvp', 'uvpp', 'iso-T-slope'], cspace=['Yuv60'], cspace_kwargs=[{'bwtf': {}, 'fwtf': {}}], verbosity=0, lut_generator_fcn=<function _generate_lut>, lut_generator_kwargs={})[source]

Generate a number of luts and store them in a nested dictionary. Structure: lut[cspace][cieobs][lut type].

Args:
lut_file:
None, optional
string specifying the filename to save the lut (as .pkl) to.
If None: don’t save anything when generated (i.e. load==False).
load:
True, optional
If True: load previously generated dictionary.
If False: generate from scratch.
lut_path:
_CCT_LUT_PATH, optional
Path to file.
wl:
None, optional
Wavelength for Planckian spectrum generation.
If None: use same wavelengths as CMFs in :cieobs:.
cieobs:
[_CIEOBS] or list, optional
Generate a LUT for each one in the list.
If None: generate for all cmfs in _CMF.
types:
[None], optional
List of lut specifiers of format [(Tmin,Tmax,Tinterval,unit),…]
If units are in MK-1 then the range is also!
Unit options are:
- ‘%’: equal relative Tc spacing (in %, cfr. (Ti+1 - Ti-1)/Ti-1).
- ‘K’ equal absolute Tc spacing (in K, cfr. (Ti+1 - Ti-1).
- ‘%-1’: equal relative reciprocal Tc (MK-1 = mired).
- ‘K-1’: equal absolute reciprocal Tc (MK-1 = mired).
If the last element of the list is a bool, then the way the different
lists of Tcs generated by each list element can be set. If True:
the Tcs will be ‘seamlessly’ stitched together (this does have an
an impact on the min-max range of each Tc set) so that there are no
discontinuities in terms of the intervals.
seamless_stitch:
True, optional
When stitching (creating) LUTs composed of several CCT ranges with different
intervals, these do not always ‘match’ well, in the sense that discontinuities
might be generated. This can be avoided (at the expense of possibly slightly changed ranges)
by setting the :seamless_stitch: argument to True. Is overriden when
the last element in the lut list is a boolean.
cct_max:
_CCT_MAX, optional
Limit Tc’s to a maximum value of cct_max
cct_min:
_CCT_MIN, optional
Limit Tc’s to a minimum value of cct_max
fallback_unit:
_CCT_FALLBACK_UNIT, optional
Unit to fall back on when the input unit in tc4 (of first list) is ‘au’.
As there is no common distancing of the unit types [‘K’,’%’,’%-1’,’K-1’]
the Tc’s are generated by dividing the min-max range into
a number of divisions, specified by the negative 3 element (or when
positive or NaN, the number of divisions is set by :fallback_divisions:)
fallback_n:
_CCT_FALLBACK_N, optional
Number of divisions the min-max range is divided into, in the
fallback case in which unit==’au’ and the 3e 4-vector element
is NaN or positive.
lut_vars:
[‘T’,’uv’,’uvp’,’uvpp’,’iso-T-slope’], optional
Data the lut should contain. Must follow this order
and minimum should be [‘T’]
cspace,cspace_kwargs:
Lists with the cspace and cspace_kwargs for which luts will be generated.
Default is single chromaticity diagram in _CCT_CSPACE.
verbosity:
0, optional
If > 0: give some intermediate feedback while generating luts.
lut_generator_fcn:
_generate_lut, optional
Lets a user specify his own lut generation function (must output a list of 1 lut).
Default is the general function. There is a specific one for
Ohno’s 2014 method as that one requires a different correction factor
for each lut for the parabolic solutions. This optimized value is specified in the
second list index. (see _generate_lut_ohno2014()).
lut_generator_kwargs:
{}, optional
Dict with keyword arguments specific to the (user) lut_generator_fcn.
(e.g. {‘f_corr’:0.9991} for _generate_lut_ohno2014())
Returns:
dict:
Dictionary with luts for the specified mode, cieobs(s) and cspace(s).
Structure: lut[cspace][cieobs][lut type]
At the upper dict level there is also a key ‘wl’ which contains a dict with keys
the cieobs and with values the wavelengths used to calculate the Planckians for
each lut for the specified cieobs; as well as a key with the lut_vars
The luts contains as data the variables as specified in lut_vars:
- T: (in K)
- uv: chromaticity coordinates of planckians
- uvp: chromaticity coordinates of 1st derivative of the planckians.
- uvpp: chromaticity coordinates of 2nd derivative of the planckians.
- iso-T-slope: slope of isotemperature lines (calculated as in Robertson, 1968).
luxpy.color.cct.get_tcs4(tc4, uin=None, seamless_stitch=True, fallback_unit='K-1', fallback_n=50)[source]

Get an ndarray of Tc’s obtained from a list or tuple of tc4 4-vectors.

Args:
tc4:
list or tuple of 4-vectors.
e.g. (tc4_1, tc4_2, tc4_3,…) or (tc4_1, tc4_2, tc4_3,…, bool::seamless_stitch)
When the last element of the list/tuple is a bool, then this specifies
how the Tc arrays generated for each of the 4-vector elements need to be
stitched together. This overrides the seamless_stitch input argument.
Vector elements are:
[Tmin, Tmax inclusive, Tinterval(or number of intervals), unit]
Unit specifies unit of the Tc interval, i.e. it determines the
type of scale in which the spacing of the Tc are done.
Unit options are:
- ‘%’: equal relative Tc spacing (in %, cfr. (Ti+1 - Ti-1)/Ti-1).
- ‘K’ equal absolute Tc spacing (in K, cfr. (Ti+1 - Ti-1).
- ‘%-1’: equal relative reciprocal Tc (MK-1 = mired).
- ‘K-1’: equal absolute reciprocal Tc (MK-1 = mired).
If the ‘interval’ element is negative, it actually represents
the number of intervals between Tmin, Tmax (included).
uin:
None, optional
Unit of input Tmin, Tmax (by default it is assumed to be the same
as the scale ‘unit’).
seamless_stitch:
True, optional
Determines how the Tc arrays generated for each of the 4-vector
elements are stitched together. Is overriden by the presence of a
bool as last list/tuple element in :tc4:.
For a seamless stitch, all units for all 4-vectors should be the same!!
fallback_unit:
_CCT_FALLBACK_UNIT, optional
Unit to fall back on when the input unit in tc4 (of first list) is ‘au’.
As there is no common distancing of the unit types [‘K’,’%’,’%-1’,’K-1’]
the Tc’s are generated by dividing the min-max range into
a number of divisions, specified by the negative 3 element (or when
positive or NaN, the number of divisions is set by :fallback_divisions:)
fallback_n:
_CCT_FALLBACK_N, optional
Number of divisions the min-max range is divided into, in the
fallback case in which unit==’au’ and the 3e 4-vector element
is NaN or positive.
Returns:
tcs:
ndarray with Tcs
luxpy.color.cct._get_lut(lut, uin=None, seamless_stitch=True, fallback_unit='K-1', fallback_n=50, resample_ndarray=False, cct_max=100000000000.0, cct_min=450, luts_dict=None, lut_type_def=None, lut_vars=['T', 'uv', 'uvp', 'uvpp', 'iso-T-slope'], cieobs='1931_2', cspace_str=None, wl=None, ignore_unequal_wl=False, lut_generator_fcn=<function _generate_lut>, lut_generator_kwargs={}, cspace='Yuv60', cspace_kwargs={'bwtf': {}, 'fwtf': {}}, **kwargs)[source]

Get an ndarray LUT from various sources.

Args:
lut:
Look-Up-Table with Ti, u,v,u’,v’,u”,v”,slope values of Planckians, or
whatever quantities are specified in lut_vars (‘T’,’uv’ is always part of the lut).
Options:
- list: must have two elements: [lut,lut_kwargs]
- None: lut from luts_dict with lut_type_def as key
- str: lut from luts_dict at key :lut:
- ndarray [Nxn, with n>1]: precalculated lut (only processing will be to keep it with cct_min-cct_max range)
- ndarray [Nx1]: list of Tc’s from which a new lut will be calculated.
- tuple of 4-vectors: used as key in luts_dict or to generate new lut from scratch
4-vector info:
+ format: e.g. (tc4_1, tc4_2, tc4_3,…) or (tc4_1, tc4_2, tc4_3,…, bool::seamless_stitch)
+ When the last element of the list/tuple is a bool, then this specifies
how the Tc arrays generated for each of the 4-vector elements need to be
stitched together. This overrides the seamless_stitch input argument.
+ Vector elements are:
[Tmin, Tmax inclusive, Tinterval(or number of intervals), unit]
Unit specifies unit of the Tc interval, i.e. it determines the
type of scale in which the spacing of the Tc are done.
Unit options are:
- ‘%’: equal relative Tc spacing (in %, cfr. (Ti+1 - Ti-1)/Ti-1).
- ‘K’ equal absolute Tc spacing (in K, cfr. (Ti+1 - Ti-1).
- ‘%-1’: equal relative reciprocal Tc (MK-1 = mired).
- ‘K-1’: equal absolute reciprocal Tc (MK-1 = mired).
If the ‘interval’ element is negative, it actually represents
the number of intervals between Tmin, Tmax (included).
uin:
None, optional
Unit of input Tmin, Tmax (by default it is assumed to be the same
as the scale ‘unit’) in Tc generation from tuple.
seamless_stitch:
True, optional
Determines how the Tc arrays generated for each of the 4-vector
elements are stitched together. Is overriden by the presence of a
bool as last list/tuple element in :tc4:.
For a seamless stitch, all units for all 4-vectors should be the same!!
cct_max:
_CCT_MAX, optional
Limit Tc’s to a maximum value of cct_max
cct_min:
_CCT_MIN, optional
Limit Tc’s to a minimum value of cct_max
fallback_unit:
_CCT_FALLBACK_UNIT, optional
Unit to fall back on when the input unit in tc4 (of first list) is ‘au’.
As there is no common distancing of the unit types [‘K’,’%’,’%-1’,’K-1’]
the Tc’s are generated by dividing the min-max range into
a number of divisions, specified by the negative 3 element (or when
positive or NaN, the number of divisions is set by :fallback_divisions:)
fallback_n:
_CCT_FALLBACK_N, optional
Number of divisions the min-max range is divided into, in the
fallback case in which unit==’au’ and the 3e 4-vector element
is NaN or positive.
resample_tc4_array:
False, optional
If False: do not resample Tc’s of an ndarray input for tc4
else: divide min-max range in fallback_n intervals. Uses fallback_unit
to determine the scale for the resampling.
wl:
None, optional
Wavelength for Planckian spectrum generation.
If None: use same wavelengths as CMFs in :cieobs:.
cieobs:
_CIEOBS or str or ndarray, optional
CMF set used to convert Planckian spectra to chromaticity coordinates
lut_type_def:
None, placeholder
Default lut (tuple key) to read from luts_dict.
luts_dict:
None, optional
Dictionary of pre-calculated luts for various cspaces and cmf sets.
Must have structure luts_dict[cspace][cieobs][lut_label] with the
lut part of a two-element list [lut, lut_kwargs]. It must contain
at the top-level a key ‘wl’ containing the wavelengths of the
Planckians used to generate the luts in this dictionary.
If None: the default dict for the mode is used
(e.g. _CCT_LUT[‘ohno2014’][‘lut_type_def’], for mode==’ohno2014’).
lut_vars:
[‘T’,’uv’,’uvp’,’uvpp’,’iso-T-slope’], optional
Data the lut should contain. Must follow this order
and minimum should be [‘T’]
cspace,cspace_kwargs:
Lists with the cspace and cspace_kwargs for which luts will be generated.
Default is single chromaticity diagram in _CCT_CSPACE.
ignore_unequal_wl:
False, optional
If True: ignore any differences in the wavelengths used to calculate
the lut (cfr. Planckians) from the luts_dict and the requested
wavelengths in :wl:
lut_generator_fcn:
_generate_lut, optional
Lets a user specify his own lut generation function (must output a list of 1 lut).
Default is the general function. There is a specific one for
Ohno’s 2014 method as that one requires a different correction factor
for each lut for the parabolic solutions. This optimized value is specified in the
second list index. (see _generate_lut_ohno2014()).
lut_generator_kwargs:
{}, optional
Dict with keyword arguments specific to the (user) lut_generator_fcn.
(e.g. {‘f_corr’:0.9991} for _generate_lut_ohno2014())
Returns:
lut:
List with an ndarray with in the columns whatever is specified in
lut_vars (Tc and uv are always present!).
Default lut_vars = [‘T’,’uv’,’uvp’,’uvpp’,’iso-T-slope’]
- Tc: (in K)
- u,v: chromaticity coordinates of planckians
- u’v’: chromaticity coordinates of 1st derivative of the planckians.
- u”,v”: chromaticity coordinates of 2nd derivative of the planckians.
- slope of isotemperature lines (calculated as in Robertson, 1968).
lut_kwargs:
{}
Dictionary with additional parameters related to the generation of the
lut.
luxpy.color.cct._generate_tcs(tc4, uin=None, seamless_stitch=True, cct_max=100000000000.0, cct_min=450, fallback_unit='K-1', fallback_n=50, resample_ndarray=False)[source]

Get an ndarray of Tc’s obtained from a list or tuple of tc4 4-vectors (or ndarray).

Args:
tc4:
list or tuple of 4-vectors or ndarray.
If ndarray: return tc4 limited to a cct_min-cct_max range (do nothing else).
If list/tuple: e.g. (tc4_1, tc4_2, tc4_3,…) or (tc4_1, tc4_2, tc4_3,…, bool::seamless_stitch)
When the last element of the list/tuple is a bool, then this specifies
how the Tc arrays generated for each of the 4-vector elements need to be
stitched together. This overrides the seamless_stitch input argument.
Vector elements are:
[Tmin, Tmax inclusive, Tinterval(or number of intervals), unit]
Unit specifies unit of the Tc interval, i.e. it determines the
type of scale in which the spacing of the Tc are done.
Unit options are:
- ‘%’: equal relative Tc spacing (in %, cfr. (Ti+1 - Ti-1)/Ti-1).
- ‘K’ equal absolute Tc spacing (in K, cfr. (Ti+1 - Ti-1).
- ‘%-1’: equal relative reciprocal Tc (MK-1 = mired).
- ‘K-1’: equal absolute reciprocal Tc (MK-1 = mired).
If the ‘interval’ element is negative, it actually represents
the number of intervals between Tmin, Tmax (included).
uin:
None, optional
Unit of input Tmin, Tmax (by default it is assumed to be the same
as the scale ‘unit’).
seamless_stitch:
True, optional
Determines how the Tc arrays generated for each of the 4-vector
elements are stitched together. Is overriden by the presence of a
bool as last list/tuple element in :tc4:.
For a seamless stitch, all units for all 4-vectors should be the same!!
cct_max:
_CCT_MAX, optional
Limit Tc’s to a maximum value of cct_max
cct_min:
_CCT_MIN, optional
Limit Tc’s to a minimum value of cct_max
fallback_unit:
_CCT_FALLBACK_UNIT, optional
Unit to fall back on when the input unit in tc4 (of first list) is ‘au’.
As there is no common distancing of the unit types [‘K’,’%’,’%-1’,’K-1’]
the Tc’s are generated by dividing the min-max range into
a number of divisions, specified by the negative 3 element (or when
positive or NaN, the number of divisions is set by :fallback_divisions:)
fallback_n:
_CCT_FALLBACK_N, optional
Number of divisions the min-max range is divided into, in the
fallback case in which unit==’au’ and the 3e 4-vector element
is NaN or positive.
resample_ndarray:
False, optional
If False: do not resample Tc’s of an ndarray input for tc4
else: divide min-max range in fallback_n intervals. Uses fallback_unit
to determine the scale for the resampling.
Returns:
tcs:
ndarray with Tcs
luxpy.color.cct._generate_lut(tc4, uin=None, seamless_stitch=True, fallback_unit='K-1', fallback_n='K-1', resample_ndarray=False, cct_max=100000000000.0, cct_min=450, wl=None, cieobs='1931_2', lut_vars=['T', 'uv', 'uvp', 'uvpp', 'iso-T-slope'], cspace='Yuv60', cspace_kwargs={'bwtf': {}, 'fwtf': {}}, **kwargs)[source]

Get an ndarray LUT for Tc’s obtained from a list or tuple of tc4 4-vectors (or ndarray).

Args:
tc4:
list or tuple of 4-vectors or ndarray.
If ndarray: return tc4 limited to a cct_min-cct_max range (do nothing else).
If list/tuple: e.g. (tc4_1, tc4_2, tc4_3,…) or (tc4_1, tc4_2, tc4_3,…, bool::seamless_stitch)
When the last element of the list/tuple is a bool, then this specifies
how the Tc arrays generated for each of the 4-vector elements need to be
stitched together. This overrides the seamless_stitch input argument.
Vector elements are:
[Tmin, Tmax inclusive, Tinterval(or number of intervals), unit]
Unit specifies unit of the Tc interval, i.e. it determines the
type of scale in which the spacing of the Tc are done.
Unit options are:
- ‘%’: equal relative Tc spacing (in %, cfr. (Ti+1 - Ti-1)/Ti-1).
- ‘K’ equal absolute Tc spacing (in K, cfr. (Ti+1 - Ti-1).
- ‘%-1’: equal relative reciprocal Tc (MK-1 = mired).
- ‘K-1’: equal absolute reciprocal Tc (MK-1 = mired).
If the ‘interval’ element is negative, it actually represents
the number of intervals between Tmin, Tmax (included).
uin:
None, optional
Unit of input Tmin, Tmax (by default it is assumed to be the same
as the scale ‘unit’).
seamless_stitch:
True, optional
Determines how the Tc arrays generated for each of the 4-vector
elements are stitched together. Is overriden by the presence of a
bool as last list/tuple element in :tc4:.
For a seamless stitch, all units for all 4-vectors should be the same!!
cct_max:
_CCT_MAX, optional
Limit Tc’s to a maximum value of cct_max
cct_min:
_CCT_MIN, optional
Limit Tc’s to a minimum value of cct_max
fallback_unit:
_CCT_FALLBACK_UNIT, optional
Unit to fall back on when the input unit in tc4 (of first list) is ‘au’.
As there is no common distancing of the unit types [‘K’,’%’,’%-1’,’K-1’]
the Tc’s are generated by dividing the min-max range into
a number of divisions, specified by the negative 3 element (or when
positive or NaN, the number of divisions is set by :fallback_divisions:)
fallback_n:
_CCT_FALLBACK_N, optional
Number of divisions the min-max range is divided into, in the
fallback case in which unit==’au’ and the 3e 4-vector element
is NaN or positive.
resample_tc4_array:
False, optional
If False: do not resample Tc’s of an ndarray input for tc4
else: divide min-max range in fallback_n intervals. Uses fallback_unit
to determine the scale for the resampling.
wl:
None, optional
Wavelength for Planckian spectrum generation.
If None: use same wavelengths as CMFs in :cieobs:.
cieobs:
[_CIEOBS] or list of str or ndarrays, optional
Generate a LUT for each one in the list.
If None: generate for all cmfs in _CMF.
lut_vars:
[‘T’,’uv’,’uvp’,’uvpp’,’iso-T-slope’], optional
Data the lut should contain. Must follow this order
and minimum should be [‘T’]
cspace,cspace_kwargs:
Lists with the cspace and cspace_kwargs for which luts will be generated.
Default is single chromaticity diagram in _CCT_CSPACE.
Returns:
lut:
List with an ndarray with in the columns whatever is specified in
lut_vars (Tc and uv are always present!).
Default lut_vars = [‘T’,’uv’,’uvp’,’uvpp’,’iso-T-slope’]
- Tc: (in K)
- u,v: chromaticity coordinates of planckians
- u’v’: chromaticity coordinates of 1st derivative of the planckians.
- u”,v”: chromaticity coordinates of 2nd derivative of the planckians.
- slope of isotemperature lines (calculated as in Robertson, 1968).
lut_kwargs:
{},
Dictionary with additional parameters related to the generation of the
lut.
luxpy.color.cct._generate_lut_ohno2014(lut, uin=None, seamless_stitch=True, fallback_unit='K-1', fallback_n=50, resample_ndarray=False, cct_max=100000000000.0, cct_min=450, luts_dict=None, lut_type_def=None, lut_vars=['T', 'uv'], cieobs='1931_2', cspace_str=None, wl=None, ignore_unequal_wl=False, cspace='Yuv60', cspace_kwargs={'bwtf': {}, 'fwtf': {}}, f_corr=None, ignore_f_corr_is_None=False, duv_triangular_threshold=0.002, ignore_wl_diff=False, **kwargs)[source]

Lut generator function for ohno2014.

Args:
:
see docstring for _generate_lut
f_corr:
Tc,x correction factor for the parabolic solution in Ohno2014.
If None, it will be recalculated (note that it depends on the lut) for increased accuracy.
ignore_f_corr_is_None:
If True, ignore f_corr is None, i.e. don’t re-calculate f_corr.
Returns:
lut:
an ndarray with the lut
dict:
a dictionary with the (re-optmized) value for f_corr and for ignore_f_cor_is_None.)
luxpy.color.cct._generate_lut_li2022(lut, uin=None, seamless_stitch=True, fallback_unit='K-1', fallback_n=50, resample_ndarray=False, cct_max=100000000000.0, cct_min=450, luts_dict=None, lut_type_def=None, lut_vars=['T', 'uv', 'uvp', 'uvpp'], cieobs='1931_2', cspace_str=None, wl=None, ignore_unequal_wl=False, lut_generator_fcn=<function _generate_lut>, lut_generator_kwargs={}, cspace='Yuv60', cspace_kwargs={'bwtf': {}, 'fwtf': {}}, f_corr=None, ignore_f_corr_is_None=False, duv_triangular_threshold=0.002, ignore_wl_diff=False, **kwargs)[source]

Lut generator function for li2022 (= updated ohno2014).

Args:
:
see docstring for _generate_lut
f_corr:
Tc,x correction factor for the non-triangular solution in Ohno2014.
If None, it will be recalculated (note that it depends on the lut) for increased accuracy.
ignore_f_corr_is_None:
If True, ignore f_corr is None, i.e. don’t re-calculate f_corr.
Returns:
lut:
an ndarray with the lut
dict:
a dictionary with the (re-optmized) value for f_corr and for ignore_f_cor_is_None.)
luxpy.color.cct.calculate_cct_luts(wl, cmf_list=['1931_2', '1964_10', '2015_2', '2015_10'], mode='robertson2023', lut_type=None, lut_generator_kwargs={}, luts=None, load=False, save_luts=False, lut_path='./', cspace=['Yuv60'], cspace_kwargs=[{'bwtf': {}, 'fwtf': {}}], verbosity=1)[source]

Calculate a lut dictionary for a specified wl and list of color matching functions

luxpy.color.cct.xyz_to_cct_ohno2011(xyz)[source]

Calculate cct and Duv from CIE 1931 2° xyz following Ohno (2011).

Args:
xyz:
ndarray with CIE 1931 2° X,Y,Z tristimulus values
Returns:
cct, duv:
ndarrays with correlated color temperatures and distance to blackbody locus in CIE 1960 uv
References:

1. Ohno, Y. (2011). Calculation of CCT and Duv and Practical Conversion Formulae. CORM 2011 Conference, Gaithersburg, MD, May 3-5, 2011

luxpy.color.cct._get_ccts_for_lut_bf(start=1000, end=41000, interval=0.25, unit='%')[source]
luxpy.color.cct.generate_lut_bf(ccts=None, start=1000, end=41000, interval=0.25, unit='%', wl=None, cmfs='1931_2', cspace='Yuv60', cspace_kwargs={})[source]

Calculate a Look-Up-Table for CCT & Duv calculations.

Args:
ccts:
None, optional
If not None: use this specific list or ndarray of CCTs.
start:
1000, optional
Start in CCT (LUT also has one lower CCT)
end:
41000, optional
End at this CCT (LUT also has a higher CCT)
interval:
0.25, optional
Interval to go from one to the next CCT in the LUT
(:unit: determines exactly how much this number increases the CCT)
unit:
‘%’, optional
Options:
- ‘%’: cct[i+1] = cct[i]*(1 + interval/100)
- ‘K’: cct[i+1] = cct[i] + interval
- ‘%-1’: 1e6/cct[i+1] = (1e6/cct[i])*(1 + interval/100)
- ‘K-1’: 1e6/cct[i+1] = 1e6/cct[i] + interval
wl:
None, optional
If None: use same wavelengths as from cmf set to generate blackbody radiators
cmf:
“1931_2”, optional
String specifying or ndarray with CMF set.
cspace:
‘Yuv60’, optional
String specifying the color or chromaticity space to calculate
the distance to the blackbody locus in.
(uses luxpy.colortf)
cspace_kwargs:
{}, optional
A dict with any kwargs for the xyz_to_space function
(cfr. luxpy.colortf(xyz, fwtf = cspace_kwargs)).
Returns:
lut:
ndarray [nx3] with CCT, u, v coordinates
(or whatever equivalent coordinates for the selected cspace)
luxpy.color.cct.xyz_to_cct_bruteforce(xyz, wl=None, cmfs='1931_2', atol=1e-15, rtol=1e-20, n_max=10000.0, down_sampling_factor=10, ccts=None, start=1000, end=41000, interval=0.25, unit='%', cspace='Yuv60', cspace_kwargs={}, lut=array([[9.9751e+02, 4.4860e-01, 3.5457e-01], [1.0000e+03, 4.4801e-01, 3.5462e-01], [1.0025e+03, 4.4743e-01, 3.5468e-01], ..., [4.0869e+04, 1.8165e-01, 2.6966e-01], [4.0971e+04, 1.8165e-01, 2.6964e-01], [4.1073e+04, 1.8164e-01, 2.6962e-01]]), use_newton_raphson=False, fast_duv=True, out='cct')[source]

Calculates the CCT (and Duv) value for a set of tristimulus values using brute-force approach. The method start by generating a large LUT, finds CCT with a minimum distance to the blackbody locus. Then further iterates over smaller and smaller CCT-ranges by generating new LUTs, until the solution converges to a specified tolerance or until a maximum number of iterations is reached.

Args:
xyz:
ndarray of tristimulus values XYZ. [nx3]
wl:
None, optional
If None: use same wavelengths as from cmf set to generate blackbody radiators for LUT.
cmf:
“1931_2”, optional
String specifying or ndarray with CMF set to use for LUT computation.
atol:
0.1, optional
Absolute tolerance in Kelvin. If the difference between the two surrounding CCTs is smaller than tol,
the brute-force search stops.
n_max:
1000, optional
Maximum number of iterations that a more detailed LUT is generated.
If the number of iterations > n_max, the brute-force search stops.
down_sampling_factor:
10, optional
Value by which the original interval is further downsampled at each iteration.
ccts:
None, optional
If not None: use this specific list or ndarray of CCTs.
start:
1000, optional
Start in CCT (LUT also has one lower CCT)
end:
41000, optional
End at this CCT (LUT also has a higher CCT)
interval:
0.25, optional
Interval to go from one to the next CCT in the LUT
(:unit: determines exactly how much this number increases the CCT)
unit:
‘%’, optional
Options:
- ‘%’: cct[i+1] = cct[i]*(1 + interval/100)
- ‘K’: cct[i+1] = cct[i] + interval
- ‘%-1’: 1e6/cct[i+1] = (1e6/cct[i])*(1 + interval/100)
- ‘K-1’: 1e6/cct[i+1] = 1e6/cct[i] + interval
cspace:
‘Yuv60’, optional
String specifying the color or chromaticity space to calculate
the distance to the blackbody locus in.
(uses luxpy.colortf)
cspace_kwargs:
{}, optional
A dict with any kwargs for the xyz_to_space function
(cfr. luxpy.colortf(xyz, fwtf = cspace_kwargs)).
lut:
_CCT_LUT_BRUTEFORCE_1931_2_uv60, optonal
Pre-calculated LUT: Lut for CIE uv 1960 coordinates and CIE 1931 2° CMFs.
If not None, this LUT is used instead of generating a new one (= only starting lut).
use_newton_raphson:
False, optional
If True: use Newton-Raphson method to find the exact CCT.
Much faster than brute-force search.
fast_duv:
True, optional
out:
‘cct’ (or 1), optional
Determines what to return.
Other options: ‘duv’ (or -1), ‘cct,duv’(or 2), “[cct,duv]” (or -2)
Returns:
CCT_Duv:
ndarray(s) with:
cct: out == ‘cct’ (or 1)
duv: out == ‘duv’ (or -1)
cct, duv: out == ‘cct,duv’ (or 2)
[cct,duv]: out == “[cct,duv]” (or -2)

cct/robertson1968

py:
  • __init__.py

  • robertson1968.py

namespace:

luxpy.color.cct.robertson1968

Standalone (no luxpy required) module with (updated, 2022) Robertson1968 CCT functions

(includes correction near slope-sign-change of iso-temperature-lines)

cct_to_xyz():

Calculates xyz from CCT, Duv by estimating the line perpendicular to the planckian locus (=iso-T line).

cct_to_xyz():

Calculates xyz from CCT, Duv [_CCT_MIN < CCT < _CCT_MAX]

References:

1. Robertson, A. R. (1968). Computation of Correlated Color Temperature and Distribution Temperature. Journal of the Optical Society of America, 58(11), 1528–1535.

2. Smet K.A.G., Royer M., Baxter D., Bretschneider E., Esposito E., Houser K., Luedtke W., Man K., Ohno Y. (2022), Recommended method for determining the correlated color temperature and distance from the Planckian Locus of a light source (in preparation, LEUKOS?)

3. Baxter D., Royer M., Smet K.A.G. (2022) Modifications of the Robertson Method for Calculating Correlated Color Temperature to Improve Accuracy and Speed (in preparation, LEUKOS?)


luxpy.color.cct.robertson1968.save_pkl(filename, obj)[source]

Save an object in a pickle file.

Args:
filename:
str with filename of pickle file.
obj:
python object to save
Returns:
None:

luxpy.color.cct.robertson1968.load_pkl(filename)[source]

Load the object in a pickle file.

Args:
filename:
str with filename of pickle file.
Returns:
obj:
loaded python object
luxpy.color.cct.robertson1968.get_tcs4(tc4, cct_min=450, cct_max=100000000000.0)[source]

Generate list of Tc of Planckians from (Tmin, Tmax inclusive, Tincrement, unit)

Args:
tc4:
4-element list or tuple
Elements are: [Tmin, Tmax inclusive, Tincrement, unit]
Unit specifies unit of the Tc interval, i.e. it determines the
type of scale in which the spacing of the Tc are done.
Unit options are:
- ‘%’: equal relative Tc spacing (in %, cfr. (Ti+1 - Ti-1)/Ti-1).
- ‘K’ equal absolute Tc spacing (in K, cfr. (Ti+1 - Ti-1).
- ‘%-1’: equal relative reciprocal Tc (MK-1 = mired).
- ‘K-1’: equal absolute reciprocal Tc (MK-1 = mired).
If the ‘increment’ element is negative, it actually represents
the number of intervals between Tmin, Tmax (included).
cct_min:
_CCT_MIN, optional
Limit Tc’s to a minimum value of cct_min
cct_max:
_CCT_MAX, optional
Limit Tc’s to a maximum value of cct_max
Returns:
Tcs:
ndarray [N,1] of ccts.
luxpy.color.cct.robertson1968.calculate_lut(ccts, cieobs, lut_vars=['T', 'uv', 'uvp', 'uvpp', 'iso-T-slope'], cct_min=450, cct_max=100000000000.0)[source]

Function that calculates a LUT for the specified calculation method for the input ccts. Calculation is performed for CMF set specified in cieobs and in the chromaticity diagram in cspace.

Args:
ccts:
ndarray [Nx1] or str or 4-element tuple
If ndarray: list of ccts for which to (re-)calculate the LUTs.
If str: path to file containing CCTs (no header; sep = ‘,’)
If 4-element tuple: generate ccts from (Tmin, Tmax, increment, unit) specifier
cieobs:
None or str, optional
str specifying cmf set.
lut_vars:
[‘T’,’uv’,’uvp’,’uvpp’,’iso-T-slope’], optional
Data the lut should contain. Must follow this order
and minimum should be [‘T’]
cct_min:
_CCT_MIN, optional
Limit Tc’s to a minimum value of cct_min
cct_max:
_CCT_MAX, optional
Limit Tc’s to a maximum value of cct_max
Returns:
returns:
lut:
ndarray with T, u, v, u’, v’, u”, v”, slope (note ‘:1st deriv., “:2nd deriv.).
luxpy.color.cct.robertson1968.loadtxt(filename, header=None, sep=', ', dtype=<class 'float'>, missing_values=nan)[source]

Load data from text file.

Args:
filename:
String with filename [+path]
header:
None, optional
None: no header present, ‘infer’ get from file.
sep:
‘,’, optional
Delimiter (‘,’ -> csv file)
dtype:
float, optional
Try casting output array to this datatype.
missing_values:
np.nan, optional
Replace missing values with this.
Returns:
ndarray:
loaded data in ndarray of type dtype or object (in case of mixed types)
luxpy.color.cct.robertson1968.xyz_to_cct(xyzw, is_uv_input=False, cieobs='1931_2', out='cct', lut=None, apply_newton_raphson=False, rtol=1e-10, atol=0.1, max_iter=10, split_calculation_at_N=25, use_fast_duv=True)[source]

Convert XYZ tristimulus values to correlated color temperature (CCT) and Duv(distance above (> 0) or below ( < 0) the Planckian locus) using Robertson’s 1968 search method.

Args:
xyzw:
ndarray of tristimulus values
is_uv_input:
False, optional
If True: xyzw contain uv input data, not xyz data!
cieobs:
_CCT_CIEOBS, optional
CMF set used to calculated xyzw.
out:
‘cct’ (or 1), optional
Determines what to return.
Other options: ‘duv’ (or -1), ‘cct,duv’(or 2), “[cct,duv]” (or -2)
rtol:
1e-10, float, optional
Stop search when cct a relative tolerance is reached.
The relative tolerance is calculated as dCCT/CCT_est,
with CCT_est the current intermediate estimate in the
search and with dCCT the difference between
the present and former estimates.
atol:
0.1, optional
Stop search when cct a absolute tolerance (K) is reached.
lut:
None, optional
Look-Up-Table with Ti, u,v,u’,v’,u”,v”,slope values of Planckians.
Options:
- None: defaults to the lut specified in _CCT_LUT[‘lut_type_def’].
- tuple: new lut will be generated from scratch using the info in the tuple.
- ndarray [Nx1]: list of luts for which to generate a lut
- ndarray [Nxn] with n>3: pre-calculated lut (last col must contain slope of the isotemperature lines).
apply_newton_raphson:
False, optional
If False: use only the Robertson1968 base method.
Accuracy depends on CCT of test source and the location
and spacing of the CCTs in the list.
If True: improve estimate of base method using a follow-up
newton-raphson method.
When the CCT for multiple source is calculated in one go,
then the atol and rtol values have to be met for all!
max_iter:
_CCT_MAX_ITER, optional
Maximum number of iterations used by the cascading-lut or newton-raphson methods.
split_calculation_at_N:
_CCT_SPLIT_CALC_AT_N, optional
Split calculation when xyzw.shape[0] > split_calculation_at_N.
Splitting speeds up the calculation. If None: no splitting is done.
use_fast_duv:
_CCT_FAST_DUV, optional
If True: use a fast estimator of the Duv
(one that avoids calculation of Planckians and uses the former
best estimate’s u,v coordinates. This method is accurate enough
when the atol is small enough -> as long as abs(T-T_former)<=1K
the Duv estimate should be ok.)
Returns:
returns:
ndarray with:
cct: out == ‘cct’ (or 1)
duv: out == ‘duv’ (or -1)
cct, duv: out == ‘cct,duv’ (or 2)
[cct,duv]: out == “[cct,duv]” (or -2)
Note:

1. Out-of-lut CCTs are encoded as negative CCTs (with as absolute value the value of the closest CCT from the lut.)

References:

1. Robertson, A. R. (1968). Computation of Correlated Color Temperature and Distribution Temperature. Journal of the Optical Society of America, 58(11), 1528–1535.

2. Baxter D., Royer M., Smet K.A.G. (2022) Modifications of the Robertson Method for Calculating Correlated Color Temperature to Improve Accuracy and Speed (in preparation, LEUKOS?)

3. Li, C., Cui, G., Melgosa, M., Ruan, X., Zhang, Y., Ma, L., Xiao, K., & Luo, M. R. (2016). Accurate method for computing correlated color temperature. Optics Express, 24(13), 14066–14078.

luxpy.color.cct.robertson1968.xyz_to_duv(xyzw, out='duv', **kwargs)[source]

Wraps xyz_to_cct, but with duv output. For kwargs info, see xyz_to_cct.

luxpy.color.cct.robertson1968.cct_to_xyz(ccts, duv=None, cct_offset=None, cieobs='1931_2')[source]

Convert correlated color temperature (550 K <= CCT <= 1e11 K) and Duv (distance above (>0) or below (<0) the Planckian locus) to XYZ tristimulus values.

Finds xyzw_estimated by determining the iso-temperature line
(= line perpendicular to the Planckian locus):
Option 1 (fastest):
First, the angle between the coordinates corresponding to ccts
and ccts-cct_offset are calculated, then 90° is added, and finally
the new coordinates are determined, while taking sign of duv into account.
Option 2 (slowest, about 55% slower):
Calculate the slope of the iso-T-line directly using the Planckian
spectrum and its derivative.
Args:
ccts:
ndarray [N,1] of cct values
duv:
None or ndarray [N,1] of duv values, optional
Note that duv can be supplied together with cct values in :ccts:
as ndarray with shape [N,2].
cct_offset:
None, optional
If None: use option 2 (direct iso-T slope calculation, more accurate,
but slower: about 1.55 slower)
else: use option 1 (estimate slope from 90° + angle of small cct_offset)
cieobs:
_CCT_CIEOBS, optional
CMF set used to calculated xyzw.
wl:
None, optional
Wavelengths used when calculating Planckian radiators.
If None: use same wavelengths as CMFs in :cieobs:.
Returns:
returns:
ndarray with estimated XYZ tristimulus values
Note:

1. If duv is not supplied (:ccts:.shape is (N,1) and :duv: is None), source is assumed to be on the Planckian locus. 2. Minimum CCT is 550 K (lower than 550 K, some negative Duv values will result in coordinates outside of the Spectrum Locus !!!)

cat/

py:
  • __init__.py

  • chromaticadaptation.py

namespace:

luxpy.cat

cat: Module supporting chromatic adaptation transforms (corresponding colors)

_WHITE_POINT:

default adopted white point

_LA:

default luminance of the adaptation field

_MCATS:

default chromatic adaptation sensor spaces

check_dimensions():

Check if dimensions of data and xyzw match.

get_transfer_function():
Calculate the chromatic adaptation diagonal matrix transfer function Dt.
Default = ‘vonkries’ (others: ‘rlab’, see Fairchild 1990)
smet2017_D():
get_degree_of_adaptation():
Calculates the degree of adaptation.
D passes either right through or D is calculated following some D-function (Dtype) published in literature (cat02, cat16, cmccat, smet2017) or set manually.
parse_x1x2_parameters():

local helper function that parses input parameters and makes them the target_shape for easy calculation

apply():

Calculate corresponding colors by applying a von Kries chromatic adaptation transform (CAT), i.e. independent rescaling of ‘sensor sensitivity’ to data to adapt from current adaptation conditions (1) to the new conditions (2).


luxpy.color.cat.check_dimensions(data, xyzw, caller='cat.apply()')[source]

Check if dimensions of data and xyzw match.

Does nothing when they do, but raises error if dimensions don’t match.
Args:
data:
ndarray with color data.
xyzw:
ndarray with white point tristimulus values.
caller:
str with caller function for error handling, optional
Returns:
returns:
ndarray with input color data,
Raises error if dimensions don’t match.
luxpy.color.cat.get_transfer_function(cattype='vonkries', catmode='1>0>2', lmsw1=None, lmsw2=None, lmsw0=array([[100, 100, 100]]), D10=1.0, D20=1.0, La1=100.0, La2=100.0, La0=100.0)[source]

Calculate the chromatic adaptation diagonal matrix transfer function Dt.

Args:
cattype:
‘vonkries’ (others: ‘rlab’, see Farchild 1990), optional
catmode:
‘1>0>2, optional
-‘1>0>2’: Two-step CAT
from illuminant 1 to baseline illuminant 0 to illuminant 2.
-‘1>0’: One-step CAT
from illuminant 1 to baseline illuminant 0.
-‘0>2’: One-step CAT
from baseline illuminant 0 to illuminant 2.
lmsw1:
None, depending on :catmode: optional
lmsw2:
None, depending on :catmode: optional
lmsw0:
_WHITE_POINT, optional
D10:
1.0, optional
Degree of adaptation for ill. 1 to ill. 0
D20:
1.0, optional
Degree of adaptation for ill. 2 to ill. 0
La1:
luxpy._LA, optional
Adapting luminance under ill. 1
La2:
luxpy._LA, optional
Adapting luminance under ill. 2
La0:
luxpy._LA, optional
Adapting luminance under baseline ill. 0
Returns:
Dt:
ndarray (diagonal matrix)
luxpy.color.cat.get_degree_of_adaptation(Dtype=None, **kwargs)[source]

Calculates the degree of adaptation according to some function published in literature.

Args:
Dtype:
None, optional
If None: kwargs should contain ‘D’ with value.
If ‘manual: kwargs should contain ‘D’ with value.
If ‘cat02’ or ‘cat16’: kwargs should contain keys ‘F’ and ‘La’.
Calculate D according to CAT02 or CAT16 model:
D = F*(1-(1/3.6)*numpy.exp((-La-42)/92))
If ‘cmc’: kwargs should contain ‘La’, ‘La0’(or ‘La2’) and ‘order’
for ‘order’ = ‘1>0’: ‘La’ is set La1 and ‘La0’ to La0.
for ‘order’ = ‘0>2’: ‘La’ is set La0 and ‘La0’ to La1.
for ‘order’ = ‘1>2’: ‘La’ is set La1 and ‘La2’ to La0.
D is calculated as follows:
D = 0.08*numpy.log10(La1+La0)+0.76-0.45*(La1-La0)/(La1+La0)
If ‘smet2017’: kwargs should contain ‘xyzw’ and ‘Dmax’
(see Smet2017_D for more details).
If “? user defined”, then D is calculated by:
D = ndarray(eval(:Dtype:))
Returns:
D:
ndarray with degree of adaptation values.
Notes:
  1. D passes either right through or D is calculated following some D-function (Dtype) published in literature.

  2. D is limited to values between zero and one

  3. If kwargs do not contain the required parameters, an exception is raised.

luxpy.color.cat.smet2017_D(xyzw, Dmax=None)[source]

Calculate the degree of adaptation based on chromaticity following Smet et al. (2017)

Args:
xyzw:
ndarray with white point data (CIE 1964 10° XYZs!!)
Dmax:
None or float, optional
Defaults to 0.6539 (max D obtained under experimental conditions,
but probably too low due to dark surround leading to incomplete
chromatic adaptation even for neutral illuminants
resulting in background luminance (fov~50°) of 760 cd/m²))
Returns:
D:
ndarray with degrees of adaptation
References:

1. Smet, K.A.G.*, Zhai, Q., Luo, M.R., Hanselaer, P., (2017), Study of chromatic adaptation using memory color matches, Part II: colored illuminants, Opt. Express, 25(7), pp. 8350-8365.

luxpy.color.cat.parse_x1x2_parameters(x, target_shape, catmode, expand_2d_to_3d=None, default=[1.0, 1.0])[source]

Parse input parameters x and make them the target_shape for easy calculation.

Input in main function can now be a single value valid for all xyzw or an array with a different value for each xyzw.
Args:
x:
list[float, float] or ndarray
target_shape:
tuple with shape information
catmode:
‘1>0>2, optional
-‘1>0>2’: Two-step CAT
from illuminant 1 to baseline illuminant 0 to illuminant 2.
-‘1>0’: One-step CAT
from illuminant 1 to baseline illuminant 0.
-‘0>2’: One-step CAT
from baseline illuminant 0 to illuminant 2.
expand_2d_to_3d:
None, optional
[will be removed in future, serves no purpose]
Expand :x: from 2 to 3 dimensions.
default:
[1.0,1.0], optional
Default values for :x:
Returns:
returns:
(ndarray, ndarray) for x10 and x20
luxpy.color.cat.apply(data, n_step=2, catmode=None, cattype='vonkries', xyzw1=None, xyzw2=None, xyzw0=None, D=None, mcat=['cat02'], normxyz0=None, outtype='xyz', La=None, F=None, Dtype=None)[source]

Calculate corresponding colors by applying a von Kries chromatic adaptation transform (CAT), i.e. independent rescaling of ‘sensor sensitivity’ to data to adapt from current adaptation conditions (1) to the new conditions (2).

Args:
data:
ndarray of tristimulus values (can be NxMx3)
n_step:
2, optional
Number of step in CAT (1: 1-step, 2: 2-step)
catmode:
None, optional
- None: use :n_step: to set mode: 1 = ‘1>2’, 2:’1>0>2’
-‘1>0>2’: Two-step CAT
from illuminant 1 to baseline illuminant 0 to illuminant 2.
-‘1>2’: One-step CAT
from illuminant 1 to illuminant 2.
-‘1>0’: One-step CAT
from illuminant 1 to baseline illuminant 0.
-‘0>2’: One-step CAT
from baseline illuminant 0 to illuminant 2.
cattype:
‘vonkries’ (others: ‘rlab’, see Farchild 1990), optional
xyzw1:
None, depending on :catmode: optional (can be Mx3)
xyzw2:
None, depending on :catmode: optional (can be Mx3)
xyzw0:
None, depending on :catmode: optional (can be Mx3)
D:
None, optional
Degrees of adaptation. Defaults to [1.0, 1.0].
La:
None, optional
Adapting luminances.
If None: xyz values are absolute or relative.
If not None: xyz are relative.
F:
None, optional
Surround parameter(s) for CAT02/CAT16 calculations
(:Dtype: == ‘cat02’ or ‘cat16’)
Defaults to [1.0, 1.0].
Dtype:
None, optional
Type of degree of adaptation function from literature
See luxpy.cat.get_degree_of_adaptation()
mcat:
[_MCAT_DEFAULT], optional
List[str] or List[ndarray] of sensor space matrices for each
condition pair. If len(:mcat:) == 1, the same matrix is used.
normxyz0:
None, optional
Set of xyz tristimulus values to normalize the sensor space matrix to.
outtype:
‘xyz’ or ‘lms’, optional
- ‘xyz’: return corresponding tristimulus values
- ‘lms’: return corresponding sensor space excitation values
(e.g. for further calculations)
Returns:
returns:
ndarray with corresponding colors
Reference:

1. Smet, K. A. G., & Ma, S. (2020). Some concerns regarding the CAT16 chromatic adaptation transform. Color Research & Application, 45(1), 172–177.

luxpy.color.cat.apply_vonkries1(xyz, xyzw1, xyzw2, D=1, mcat=None, invmcat=None, in_type='xyz', out_type='xyz', use_Yw=False)[source]

Apply a 1-step von kries chromatic adaptation transform.

Args:
xyz:
ndarray with sample tristimulus or cat-sensor values
xyzw1:
ndarray with white point tristimulus or cat-sensor values of illuminant 1
xyzw2:
ndarray with white point tristimulus or cat-sensor values of illuminant 2
D:
1, optional
Degree of chromatic adaptation
mcat:
None, optional
Specifies CAT sensor space.
- options:
- None defaults to luxpy.cat._MCAT_DEFAULT
- str: see see luxpy.cat._MCATS.keys() for options
(details on type, ?luxpy.cat)
- ndarray: matrix with sensor primaries
invmcat:
None,optional
Pre-calculated inverse mcat.
If None: calculate inverse of mcat.
in_type:
‘xyz’, optional
Input type (‘xyz’, ‘rgb’) of data in xyz, xyzw1, xyzw2
out_type:
‘xyz’, optional
Output type (‘xyz’, ‘rgb’) of corresponding colors
use_Yw:
False, optional
Use CAT version with Yw factors included (but this results in
potential wrong predictions, see Smet & Ma (2020)).
Returns:
xyzc:
ndarray with corresponding colors.
Reference:

1. Smet, K. A. G., & Ma, S. (2020). Some concerns regarding the CAT16 chromatic adaptation transform. Color Research & Application, 45(1), 172–177.

luxpy.color.cat.apply_vonkries2(xyz, xyzw1, xyzw2, xyzw0=None, D=1, mcat=None, invmcat=None, in_type='xyz', out_type='xyz', use_Yw=False)[source]

Apply a 2-step von kries chromatic adaptation transform.

Args:
xyz:
ndarray with sample tristimulus or cat-sensor values
xyzw1:
ndarray with white point tristimulus or cat-sensor values of illuminant 1
xyzw2:
ndarray with white point tristimulus or cat-sensor values of illuminant 2
xyzw0:
None, optional
ndarray with white point tristimulus or cat-sensor values of baseline illuminant 0
None: defaults to EEW.
D:
[1,1], optional
Degree of chromatic adaptations (Ill.1–>Ill.0, Ill.2.–>Ill.0)
mcat:
None, optional
Specifies CAT sensor space.
- options:
- None defaults to luxpy.cat._MCAT_DEFAULT
- str: see see luxpy.cat._MCATS.keys() for options
(details on type, ?luxpy.cat)
- ndarray: matrix with sensor primaries
invmcat:
None,optional
Pre-calculated inverse mcat.
If None: calculate inverse of mcat.
in_type:
‘xyz’, optional
Input type (‘xyz’, ‘rgb’) of data in xyz, xyzw1, xyzw2
out_type:
‘xyz’, optional
Output type (‘xyz’, ‘rgb’) of corresponding colors
use_Yw:
False, optional
Use CAT version with Yw factors included (but this results in
potential wrong predictions, see Smet & Ma (2020)).
Returns:
xyzc:
ndarray with corresponding colors.
Reference:

1. Smet, K. A. G., & Ma, S. (2020). Some concerns regarding the CAT16 chromatic adaptation transform. Color Research & Application, 45(1), 172–177.

luxpy.color.cat.apply_vonkries(xyz, xyzw1, xyzw2, xyzw0=None, D=1, n_step=2, catmode='1>0>2', mcat=None, invmcat=None, in_type='xyz', out_type='xyz', use_Yw=False)[source]

Apply a 1-step or 2-step von kries chromatic adaptation transform.

Args:
xyz:
ndarray with sample tristimulus or cat-sensor values
xyzw1:
ndarray with white point tristimulus or cat-sensor values of illuminant 1
xyzw2:
ndarray with white point tristimulus or cat-sensor values of illuminant 2
xyzw0:
None, optional
ndarray with white point tristimulus or cat-sensor values of baseline illuminant 0
None: defaults to EEW.
D:
[1,1], optional
Degree of chromatic adaptations (Ill.1–>Ill.0, Ill.2.–>Ill.0)
n_step:
2, optional
Number of step in CAT (1: 1-step, 2: 2-step)
catmode:
None, optional
- None: use :n_step: to set mode: 1 = ‘1>2’, 2:’1>0>2’
-‘1>0>2’: Two-step CAT
from illuminant 1 to baseline illuminant 0 to illuminant 2.
-‘1>2’: One-step CAT
from illuminant 1 to illuminant 2.
-‘1>0’: One-step CAT
from illuminant 1 to baseline illuminant 0.
-‘0>2’: One-step CAT
from baseline illuminant 0 to illuminant 2.
mcat:
None, optional
Specifies CAT sensor space.
- options:
- None defaults to luxpy.cat._MCAT_DEFAULT
- str: see see luxpy.cat._MCATS.keys() for options
(details on type, ?luxpy.cat)
- ndarray: matrix with sensor primaries
invmcat:
None,optional
Pre-calculated inverse mcat.
If None: calculate inverse of mcat.
in_type:
‘xyz’, optional
Input type (‘xyz’, ‘rgb’) of data in xyz, xyzw1, xyzw2
out_type:
‘xyz’, optional
Output type (‘xyz’, ‘rgb’) of corresponding colors
use_Yw:
False, optional
Use CAT version with Yw factors included (but this results in
potential wrong predictions, see Smet & Ma (2020)).
Returns:
xyzc:
ndarray with corresponding colors.
Reference:

1. Smet, K. A. G., & Ma, S. (2020). Some concerns regarding the CAT16 chromatic adaptation transform. Color Research & Application, 45(1), 172–177.

luxpy.color.cat.apply_ciecat94(xyz, xyzw, xyzwr=None, E=1000, Er=1000, Yb=20, D=1, cat94_old=True)[source]

Calculate corresponding color tristimulus values using the CIECAT94 chromatic adaptation transform.

Args:
xyz:
ndarray with sample 1931 2° XYZ tristimulus values under the test illuminant
xyzw:
ndarray with white point tristimulus values of the test illuminant
xyzwr:
None, optional
ndarray with white point tristimulus values of the reference illuminant
None defaults to D65.
E:
100, optional
Illuminance (lx) of test illumination
Er:
63.66, optional
Illuminance (lx) of the reference illumination
Yb:
20, optional
Relative luminance of the adaptation field (background)
D:
1, optional
Degree of chromatic adaptation.
For object colours D = 1,
and for luminous colours (typically displays) D=0
Returns:
xyzc:
ndarray with corresponding tristimlus values.
Reference:
  1. CIE160-2004. (2004). A review of chromatic adaptation transforms (Vols. CIE160-200). CIE.

cam/

py:
  • __init__.py

  • colorappearancemodels.py

  • helpers.py

  • utils.py

  • ciecam02.py

  • cam02ucs.py

  • ciecam16.py

  • cam16ucs.py

  • cam15u

  • sww2016.py

  • cam18sl.py

  • camjabz.py

  • zcam.py

  • cmf_translator_sww2021

namespace:

luxpy.cam

cam: sub-package with color appearance models

_UNIQUE_HUE_DATA:
database of unique hues with corresponding
Hue quadratures and eccentricity factors
for ciecam02, ciecam16, ciecam97s, cam15u, cam18sl)
_SURROUND_PARAMETERS:
database of surround param. c, Nc, F and FLL
for ciecam02, ciecam16, ciecam97s and cam15u.
_NAKA_RUSHTON_PARAMETERS:
database with parameters (n, sig, scaling and noise)
for the Naka-Rushton function:
NK(x) = sign(x) * scaling * ((abs(x)**n) / ((abs(x)**n) + (sig**n))) + noise
_CAM_UCS_PARAMETERS:
database with parameters specifying the conversion
from ciecamX to:
camXucs (uniform color space),
camXlcd (large color diff.),
camXscd (small color diff).
_CAM15U_PARAMETERS:

database with CAM15u model parameters.

_CAM_SWW16_PARAMETERS:

cam_sww16 model parameters.

_CAM18SL_PARAMETERS:

database with CAM18sl model parameters

_CAM_DEFAULT_WHITE_POINT:

Default internal reference white point (xyz)

_CAM_DEFAULT_CONDITIONS:

Default CAM model parameters for model.

_CAM_AXES:

dict with list[str,str,str] containing axis labels of defined cspaces.

deltaH():

Compute a hue difference, dH = 2*C1*C2*sin(dh/2).

naka_rushton():

applies a Naka-Rushton function to the input

hue_angle():

calculates a positive hue angle

hue_quadrature():

calculates the Hue quadrature from the hue.

ciecam02():
cam16():
cam02ucs():
cam16ucs():
cam15u():
cam_sww16():
cam18sl():
camXucs():

Wraps ciecam02(), ciecam16(), cam02ucs(), cam16ucs().

specific wrappers in the ‘xyz_to_cspace()’ and ‘cpsace_to_xyz()’ format:
‘xyz_to_jabM_ciecam02’, ‘jabM_ciecam02_to_xyz’,
‘xyz_to_jabC_ciecam02’, ‘jabC_ciecam02_to_xyz’,
‘xyz_to_jabM_ciecam16’, ‘jabM_ciecam16_to_xyz’,
‘xyz_to_jabC_ciecam16’, ‘jabC_ciecam16_to_xyz’,
‘xyz_to_jabz’, ‘jabz_to_xyz’,
‘xyz_to_jabM_camjabz’, ‘jabM_camjabz_to_xyz’,
‘xyz_to_jabC_camjabz’, ‘jabC_camjabz_to_xyz’,
‘xyz_to_jab_cam02ucs’, ‘jab_cam02ucs_to_xyz’,
‘xyz_to_jab_cam02lcd’, ‘jab_cam02lcd_to_xyz’,
‘xyz_to_jab_cam02scd’, ‘jab_cam02scd_to_xyz’,
‘xyz_to_jab_cam16ucs’, ‘jab_cam16ucs_to_xyz’,
‘xyz_to_jab_cam16lcd’, ‘jab_cam16lcd_to_xyz’,
‘xyz_to_jab_cam16scd’, ‘jab_cam16scd_to_xyz’,
‘xyz_to_qabW_cam15u’, ‘qabW_cam15u_to_xyz’,
‘xyz_to_lab_cam_sww16’,’lab_cam_sww16_to_xyz’,
‘xyz_to_qabM_cam18sl’, ‘qabM_cam18sl_to_xyz’,
‘xyz_to_qabS_cam18sl’, ‘qabS_cam18sl_to_xyz’,
_update_parameter_dict():

Get parameter dict and update with values in args dict

_setup_default_adaptation_field():

Setup a default illuminant adaptation field with Lw = 100 cd/m² for selected CIE observer.

_massage_input_and_init_output():

Redimension input data to ensure most they have the appropriate sizes for easy and efficient looping.

_massage_output_data_to_original_shape():

Massage output data to restore original shape of original CAM input.

_get_absolute_xyz_xyzw():

Calculate absolute xyz tristimulus values of stimulus and white point from spectral input or convert relative xyz values to absolute ones.

_simple_cam():

An example CAM illustration the usage of the functions in luxpy.cam.helpers

Module for CAM “front-end” cmf adaptation

translate_cmfI_to_cmfS():
Using smooth RGB primaries, translate input data (spectral or tristimlus)
for an indivual observer to the expected tristimulus values for a standard observer.
get_conversion_matrix():
Using smooth RGB primaries, get the ‘translator’ matrix to convert
tristimulus values calculated using an individual observer’s
color matching functions (cmfs) to those calculated using the cmfs of
a standard observer.
get_rgb_smooth_prims():

Get smooth R, G, B primaries with specified wavelength range

_R,_G,_B:

precalculated smooth primaries with [360,830,1] wavelength range.

luxpy.color.cam.hue_angle(a, b, htype='deg')[source]

Calculate positive hue angle (0°-360° or 0 - 2*pi rad.) from opponent signals a and b.

Args:
a:
ndarray of a-coordinates
b:
ndarray of b-coordinates
htype:
‘deg’ or ‘rad’, optional
- ‘deg’: hue angle between 0° and 360°
- ‘rad’: hue angle between 0 and 2pi radians
Returns:
returns:
ndarray of positive hue angles.
luxpy.color.cam.naka_rushton(data, sig=2.0, n=0.73, scaling=1.0, noise=0.0, forward=True)[source]

Apply a Naka-Rushton response compression (n) and an adaptive shift (sig).

NK(x) = sign(x) * scaling * ((abs(x)**n) / ((abs(x)**n) + (sig**n))) + noise
Args:
data:
float or ndarray
sig:
2.0, optional
Semi-saturation constant. Value for which NK(:data:) is 1/2
n:
0.73, optional
Compression power.
scaling:
1.0, optional
Maximum value of NK-function.
noise:
0.0, optional
Cone excitation noise.
forward:
True, optional
True: do NK(x)
False: do NK(x)**(-1).
Returns:
returns:
float or ndarray with NK-(de)compressed input :x:
luxpy.color.cam.deltaH(h1, C1, h2=None, C2=None, htype='deg')[source]

Compute a hue difference, dH = 2*C1*C2*sin(dh/2)

Args:
h1:
hue for sample 1 (or hue difference if h2 is None)
C1:
chroma of sample 1 (or prod C1*C2 if C2 is None)
h2:
hue angle of sample 2 (if None, then h1 contains a hue difference)
C2:
chroma of sample 2
htype:
‘deg’ or ‘rad’, optional
- ‘deg’: hue angle between 0° and 360°
- ‘rad’: hue angle between 0 and 2pi radians
Returns:
returns:
ndarray of deltaH values.
luxpy.color.cam.hue_quadrature(h, unique_hue_data=None, forward=True)[source]

Get hue quadrature H from hue h.

Args:
h:
float or ndarray [(N,) or (N,1)] with:
- hue angle data in degrees (!) if forward == True.
- Hue quadrature data if forward = False
unique_hue data:
None or dict, optional
- None: defaults to:
{‘hues’: ‘red yellow green blue red’.split(),
‘i’: np.arange(5.0),
‘hi’:[20.14, 90.0, 164.25,237.53,380.14],
‘ei’:[0.8,0.7,1.0,1.2,0.8],
‘Hi’:[0.0,100.0,200.0,300.0,400.0]}
- dict: user specified unique hue data
(same structure as above)
forward:
True, optional
If true: input h is hue angle, else it is Hue quadrature
Returns:
H:
ndarray of Hue quadrature value(s) (forward == True) or of hue angle values(s) (foward == False).
luxpy.color.cam._update_parameter_dict(args, parameters={}, cieobs='2006_10', match_conversionmatrix_to_cieobs=False, Mxyz2lms_whitepoint=None)[source]
Get parameter dict and update with values in args dict.
Also replace the xyz-to-lms conversion matrix with the one corresponding
to cieobs and normalize it to illuminant E.
Args:
args:
dictionary with updated values.
(get by placing ‘args = locals().copy()’ immediately after the start
of the function from which the update is called,
see _simple_cam() code for an example.)
parameters:
dictionary with all (adjustable) parameter values used by the model
cieobs:
String with the CIE observer CMFs (one of _CMF[‘types’] of the input data
Is used to get the Mxyz2lms matrix when match_conversionmatrix_to_cieobs == True)
match_conversionmatrix_to_cieobs:
False, optional
If False: keep the Mxyz2lms in the parameters dict
Mxyz2lms_whitepoint:
None, optional
If not None: update the Mxyz2lms key in the parameters dict
so that the conversion matrix is the one in _CMF[cieobs][‘M’],
in other such that it matches the cieobs of the input data.
Returns:
parameters:
updated dictionary with model parameters for further use in the CAM.
Notes:

For an example on the use, see code _simple_cam() (type: _simple_cam??)

luxpy.color.cam._setup_default_adaptation_field(dataw=None, Lw=100, cie_illuminant='D65', inputtype='xyz', relative=True, cieobs='2006_10')[source]

Setup a default illuminant adaptation field with Lw = 100 cd/m² for selected CIE observer.

Args:
dataw:
None or ndarray, optional
Input tristimulus values or spectral data of white point.
None defaults to the use of the illuminant specified in :cie_illuminant:.
cie_illuminant:
‘D65’, optional
String corresponding to one of the illuminants (keys)
in luxpy._CIE_ILLUMINANT
If ndarray, then use this one.
This is ONLY USED WHEN dataw is NONE !!!
Lw:
100.0, optional
Luminance (cd/m²) of white point.
inputtype:
‘xyz’ or ‘spd’, optional
Specifies the type of input:
tristimulus values or spectral data for the forward mode.
relative:
True or False, optional
True: xyz tristimulus values are relative (Yw = 100)
cieobs:
_CAM_DEFAULT_CIEOBS, optional
CMF set to use to perform calculations where spectral data
is involved (inputtype == ‘spd’; dataw = None)
Other options: see luxpy._CMF[‘types’]
Returns:
dataw:
Ndarray with default adaptation field data (spectral or xyz)
Notes:

For an example on the use, see code _simple_cam() (type: _simple_cam??)

luxpy.color.cam._massage_input_and_init_output(data, dataw, inputtype='xyz', direction='forward', n_out=3)[source]

Redimension input data to ensure most they have the appropriate sizes for easy and efficient looping. | | 1. Convert data and dataw to atleast_2d ndarrays | 2. Make axis 1 of dataw have ‘same’ dimensions as data | 3. Make dataw have same lights source axis size as data | 4. Flip light source axis to axis=0 for efficient looping | 5. Initialize output array camout to ‘same’ shape as data but with camout.shape[-1] == n_out

Args:
data:
ndarray with input tristimulus values
or spectral data
or input color appearance correlates
Can be of shape: (N [, xM], x 3), whereby:
N refers to samples and M refers to light sources.
Note that for spectral input shape is (N x (M+1) x wl)
dataw:
None or ndarray, optional
Input tristimulus values or spectral data of white point.
None defaults to the use of CIE illuminant C.
inputtype:
‘xyz’ or ‘spd’, optional
Specifies the type of input:
tristimulus values or spectral data for the forward mode.
direction:
‘forward’ or ‘inverse’, optional
-‘forward’: xyz -> cam
-‘inverse’: cam -> xyz
n_out:
3, optional
output size of last dimension of camout
(e.g. n_out=3 for j,a,b output or n_out = 5 for J,M,h,a,b output)
Returns:
data:
ndarray with reshaped data
dataw:
ndarray with reshaped dataw
camout:
NaN filled ndarray for output of CAMv (camout.shape[-1] == Nout)
originalshape:
original shape of data
Notes:

For an example on the use, see code _simple_cam() (type: _simple_cam??)

luxpy.color.cam._massage_output_data_to_original_shape(data, originalshape)[source]

Massage output data to restore original shape of original CAM input.

Notes:

For an example on the use, see code _simple_cam() (type: _simple_cam??)

luxpy.color.cam._get_absolute_xyz_xyzw(data, dataw, i=0, Lw=100, direction='forward', cieobs='2006_10', inputtype='xyz', relative=True)[source]

Calculate absolute xyz tristimulus values of stimulus and white point from spectral input or convert relative xyz values to absolute ones.

Args:
data:
ndarray with input tristimulus values
or spectral data
or input color appearance correlates
Can be of shape: (N [, xM], x 3), whereby:
N refers to samples and M refers to light sources.
Note that for spectral input shape is (N x (M+1) x wl)
dataw:
None or ndarray, optional
Input tristimulus values or spectral data of white point.
None defaults to the use of CIE illuminant C.
i:
0, optional
row number in data and dataw ndarrays
(for loops across illuminant dimension after dimension reshape
with _massage_output_data_to_original_shape).
Lw:
100.0, optional
Luminance (cd/m²) of white point.
inputtype:
‘xyz’ or ‘spd’, optional
Specifies the type of input:
tristimulus values or spectral data for the forward mode.
direction:
‘forward’ or ‘inverse’, optional
-‘forward’: xyz -> cam
-‘inverse’: cam -> xyz
relative:
True or False, optional
True: xyz tristimulus values are relative (Yw = 100)
cieobs:
_CAM_DEFAULT_CIEOBS, optional
CMF set to use to perform calculations where spectral data is involved (inputtype == ‘spd’; dataw = None)
Other options: see luxpy._CMF[‘types’]
Returns:
xyzti:
in forward mode : ndarray with relative or absolute sample xyz for data[i]
in inverse mode: None
xyzwi:
ndarray with relative or absolute white point for dataw[i]
xyzw_abs:
ndarray with absolute xyz for white point for dataw[i]
Notes:

For an example on the use, see code _simple_cam() (type: _simple_cam??)

luxpy.color.cam._simple_cam(data, dataw=None, Lw=100.0, relative=True, inputtype='xyz', direction='forward', cie_illuminant='D65', parameters={'Mxyz2lms': array([[3.8971e-01, 6.8898e-01, -7.8680e-02], [-2.2981e-01, 1.1834e+00, 4.6410e-02], [0.0000e+00, 0.0000e+00, 1.0000e+00]]), 'cA': 1, 'ca': array([1, -1, 0]), 'cb': array([1.6667e-01, 1.6667e-01, -3.3333e-01]), 'n': 0.3333333333333333}, cieobs='2006_10', match_to_conversionmatrix_to_cieobs=True)[source]

An example CAM illustration the usage of the functions in luxpy.cam.helpers

Note that this example uses NO chromatic adaptation
and SIMPLE compression, opponent and correlate processing.
THIS IS ONLY FOR ILLUSTRATION PURPOSES !!!
Args:
data:
ndarray with input:
- tristimulus values
or
- spectral data
or
- input color appearance correlates
Can be of shape: (N [, xM], x 3), whereby:
N refers to samples and M refers to light sources.
Note that for spectral input shape is (N x (M+1) x wl)
dataw:
None or ndarray, optional
Input tristimulus values or spectral data of white point.
None defaults to the use of :cie_illuminant:
cie_illuminant:
‘D65’, optional
String corresponding to one of the illuminants (keys)
in luxpy._CIE_ILLUMINANT
If ndarray, then use this one.
This is ONLY USED WHEN dataw is NONE !!!
Lw:
100.0, optional
Luminance (cd/m²) of white point.
relative:
True or False, optional
True: data and dataw input is relative (i.e. Yw = 100)
parameters:
{‘cA’: 1, ‘ca’:np.array([1,-1,0]), ‘cb’:(1/3)*np.array([0.5,0.5,-1]),
‘n’: 1/3, ‘Mxyz2lms’: _CMF[‘1931_2’][‘M’].copy()}
Dict with model parameters
(For illustration purposes of match_conversionmatrix_to_cieobs,
the conversion matrix luxpy._CMF[‘1931_2’][‘M’] does NOT match
the default observer specification of the input data in :cieobs: !!!)
inputtype:
‘xyz’ or ‘spd’, optional
Specifies the type of input:
tristimulus values or spectral data for the forward mode.
direction:
‘forward’ or ‘inverse’, optional
-‘forward’: xyz -> cam
-‘inverse’: cam -> xyz
cieobs:
‘2006_10’, optional
CMF set to use to perform calculations where spectral data
is involved (inputtype == ‘spd’; dataw = None)
Other options: see luxpy._CMF[‘types’]
match_conversionmatrix_to_cieobs:
True, optional
When changing to a different CIE observer, change the xyz_to_lms
matrix to the one corresponding to that observer.
Set to False to keep the one in the parameter dict!
Returns:
returns:
ndarray with:
- color appearance correlates (:direction: == ‘forward’)
or
- XYZ tristimulus values (:direction: == ‘inverse’)
luxpy.color.cam.ciecam02(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, outin='J,aM,bM', conditions=None, naka_rushton_parameters=None, unique_hue_data=None, forward=True, yellowbluepurplecorrect=False, mcat='cat02')

Run CIECAM02 color appearance model in forward or backward modes.

Args:
data:
ndarray with relative sample xyz values (forward mode) or J’a’b’ coordinates (inverse mode)
xyzw:
ndarray with relative white point tristimulus values
Yw:
None, optional
Luminance factor of white point.
If None: xyz (in data) and xyzw are entered as relative tristimulus values
(normalized to Yw = 100).
If not None: input tristimulus are absolute and Yw is used to
rescale the absolute values to relative ones
(relative to a reference perfect white diffuser
with Ywr = 100).
Yw can be < 100 for e.g. paper as white point. If Yw is None, it
is assumed that the relative Y-tristimulus value in xyzw
represents the luminance factor Yw.
conditions:
None, optional
Dictionary with viewing condition parameters for:
La, Yb, D and surround.
surround can contain:
- str (options: ‘avg’,’dim’,’dark’) or
- dict with keys c, Nc, F.
None results in:
{‘La’:100, ‘Yb’:20, ‘D’:1, ‘surround’:’avg’}
naka_rushton_parameters:
None, optional
If None: use _NAKA_RUSHTON_PARAMETERS
unique_hue_data:
None, optional
If None: use _UNIQUE_HUE_DATA
forward:
True, optional
If True: run in CAM in forward mode, else: inverse mode.
outin:
‘J,aM,bM’, optional
String with requested output (e.g. “J,aM,bM,M,h”) [Forward mode]
- attributes: ‘J’: lightness,’Q’: brightness,
‘M’: colorfulness,’C’: chroma, ‘s’: saturation,
‘h’: hue angle, ‘H’: hue quadrature/composition,
String with inputs in data [inverse mode].
Input must have data.shape[-1]==3 and last dim of data must have
the following structure for inverse mode:
* data[…,0] = J or Q,
* data[…,1:] = (aM,bM) or (aC,bC) or (aS,bS) or (M,h) or (C, h), …
yellowbluepurplecorrect:
False, optional
If False: don’t correct for yellow-blue and purple problems in ciecam02.
If ‘brill-suss’:
for yellow-blue problem, see:
- Brill [Color Res Appl, 2006; 31, 142-145] and
- Brill and Süsstrunk [Color Res Appl, 2008; 33, 424-426]
If ‘jiang-luo’:
for yellow-blue problem + purple line problem, see:
- Jiang, Jun et al. [Color Res Appl 2015: 40(5), 491-503]
mcat:
‘cat02’, optional
Specifies CAT sensor space.
- options:
- None defaults to ‘cat02’
(others e.g. ‘cat02-bs’, ‘cat02-jiang’,
all trying to correct gamut problems of original cat02 matrix)
- str: see see luxpy.cat._MCATS.keys() for options
(details on type, ?luxpy.cat)
- ndarray: matrix with sensor primaries
Returns:
camout:
ndarray with color appearance correlates (forward mode)
or
XYZ tristimulus values (inverse mode)
References:

1. N. Moroney, M. D. Fairchild, R. W. G. Hunt, C. Li, M. R. Luo, and T. Newman, (2002), “The CIECAM02 color appearance model,” IS&T/SID Tenth Color Imaging Conference. p. 23, 2002.

luxpy.color.cam.xyz_to_jabM_ciecam02(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, yellowbluepurplecorrect=False, mcat='cat02', **kwargs)[source]

Wrapper function for ciecam02 forward mode with J,aM,bM output.

For help on parameter details: ?luxpy.cam.ciecam02
luxpy.color.cam.jabM_ciecam02_to_xyz(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, yellowbluepurplecorrect=False, mcat='cat02', **kwargs)[source]

Wrapper function for ciecam02 inverse mode with J,aM,bM input.

For help on parameter details: ?luxpy.cam.ciecam02
luxpy.color.cam.xyz_to_jabC_ciecam02(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, yellowbluepurplecorrect=False, mcat='cat02', **kwargs)[source]

Wrapper function for ciecam02 forward mode with J,aC,bC output.

For help on parameter details: ?luxpy.cam.ciecam02
luxpy.color.cam.jabC_ciecam02_to_xyz(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, yellowbluepurplecorrect=False, mcat='cat02', **kwargs)[source]

Wrapper function for ciecam02 inverse mode with J,aC,bC input.

For help on parameter details: ?luxpy.cam.ciecam02
luxpy.color.cam.cam02ucs(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, ucstype='ucs', forward=True, yellowbluepurplecorrect=False, mcat='cat02')

Run the CAM02-UCS[,-LCD,-SDC] color appearance difference model in forward or backward modes.

Args:
data:
ndarray with sample xyz values (forward mode) or J’a’b’ coordinates (inverse mode)
xyzw:
ndarray with white point tristimulus values
conditions:
None, optional
Dictionary with viewing conditions.
None results in:
{‘La’:100, ‘Yb’:20, ‘D’:1, ‘surround’:’avg’}
For more info see luxpy.cam.ciecam02()?
naka_rushton_parameters:
None, optional
If None: use _NAKA_RUSHTON_PARAMETERS
unique_hue_data:
None, optional
If None: use _UNIQUE_HUE_DATA
ucstype:
‘ucs’, optional
String with type of color difference appearance space
options: ‘ucs’, ‘scd’, ‘lcd’
forward:
True, optional
If True: run in CAM in forward mode, else: inverse mode.
yellowbluepurplecorrect:
False, optional
If False: don’t correct for yellow-blue and purple problems in ciecam02.
If ‘brill-suss’:
for yellow-blue problem, see:
- Brill [Color Res Appl, 2006; 31, 142-145] and
- Brill and Süsstrunk [Color Res Appl, 2008; 33, 424-426]
If ‘jiang-luo’:
for yellow-blue problem + purple line problem, see:
- Jiang, Jun et al. [Color Res Appl 2015: 40(5), 491-503]
mcat:
‘cat02’, optional
Specifies CAT sensor space.
- options:
- None defaults to ‘cat02’
(others e.g. ‘cat02-bs’, ‘cat02-jiang’,
all trying to correct gamut problems of original cat02 matrix)
- str: see see luxpy.cat._MCATS.keys() for options
(details on type, ?luxpy.cat)
- ndarray: matrix with sensor primaries
Returns:
camout:
ndarray with J’a’b’ coordinates (forward mode)
or
XYZ tristimulus values (inverse mode)
References:

1. M.R. Luo, G. Cui, and C. Li, ‘Uniform colour spaces based on CIECAM02 colour appearance model,’ Color Res. Appl., vol. 31, no. 4, pp. 320–330, 2006.

luxpy.color.cam.xyz_to_jab_cam02ucs(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, yellowbluepurplecorrect=None, mcat='cat02', **kwargs)[source]

Wrapper function for cam02ucs forward mode with J,aM,bM output.

For help on parameter details: ?luxpy.cam.cam02ucs
luxpy.color.cam.jab_cam02ucs_to_xyz(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, yellowbluepurplecorrect=None, mcat='cat02', **kwargs)[source]

Wrapper function for cam02ucs inverse mode with J,aM,bM input.

For help on parameter details: ?luxpy.cam.cam02ucs
luxpy.color.cam.xyz_to_jab_cam02lcd(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, yellowbluepurplecorrect=None, mcat='cat02', **kwargs)[source]

Wrapper function for cam02ucs forward mode with J,aMp,bMp output and ucstype = lcd.

For help on parameter details: ?luxpy.cam.cam02ucs
luxpy.color.cam.jab_cam02lcd_to_xyz(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, yellowbluepurplecorrect=None, mcat='cat02', **kwargs)[source]

Wrapper function for cam02ucs inverse mode with J,aMp,bMp input and ucstype = lcd.

For help on parameter details: ?luxpy.cam.cam02ucs
luxpy.color.cam.xyz_to_jab_cam02scd(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, yellowbluepurplecorrect=None, mcat='cat02', **kwargs)[source]

Wrapper function for cam02ucs forward mode with J,aMp,bMp output and ucstype = scd.

For help on parameter details: ?luxpy.cam.cam02ucs
luxpy.color.cam.jab_cam02scd_to_xyz(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, yellowbluepurplecorrect=None, mcat='cat02', **kwargs)[source]

Wrapper function for cam02ucs inverse mode with J,aMp,bMp input and ucstype = scd.

For help on parameter details: ?luxpy.cam.cam02ucs
luxpy.color.cam.ciecam16(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, outin='J,aM,bM', conditions=None, naka_rushton_parameters=None, unique_hue_data=None, forward=True, mcat='cat16')

Run CIECAM16 color appearance model in forward or backward modes.

Args:
data:
ndarray with relative sample xyz values (forward mode) or J’a’b’ coordinates (inverse mode)
xyzw:
ndarray with relative white point tristimulus values
Yw:
None, optional
Luminance factor of white point.
If None: xyz (in data) and xyzw are entered as relative tristimulus values
(normalized to Yw = 100).
If not None: input tristimulus are absolute and Yw is used to
rescale the absolute values to relative ones
(relative to a reference perfect white diffuser
with Ywr = 100).
Yw can be < 100 for e.g. paper as white point. If Yw is None, it
is assumed that the relative Y-tristimulus value in xyzw
represents the luminance factor Yw.
conditions:
None, optional
Dictionary with viewing condition parameters for:
La, Yb, D and surround.
surround can contain:
- str (options: ‘avg’,’dim’,’dark’) or
- dict with keys c, Nc, F.
None results in:
{‘La’:100, ‘Yb’:20, ‘D’:1, ‘surround’:’avg’}
naka_rushton_parameters:
None, optional
If None: use _NAKA_RUSHTON_PARAMETERS
unique_hue_data:
None, optional
If None: use _UNIQUE_HUE_DATA
forward:
True, optional
If True: run in CAM in forward mode, else: inverse mode.
outin:
‘J,aM,bM’, optional
String with requested output (e.g. “J,aM,bM,M,h”) [Forward mode]
- attributes: ‘J’: lightness,’Q’: brightness,
‘M’: colorfulness,’C’: chroma, ‘s’: saturation,
‘h’: hue angle, ‘H’: hue quadrature/composition,
String with inputs in data [inverse mode].
Input must have data.shape[-1]==3 and last dim of data must have
the following structure for inverse mode:
* data[…,0] = J or Q,
* data[…,1:] = (aM,bM) or (aC,bC) or (aS,bS) or (M,h) or (C, h), …
mcat:
‘cat16’, optional
Specifies CAT sensor space.
- options:
- None defaults to ‘cat16’
- str: see see luxpy.cat._MCATS.keys() for options
(details on type, ?luxpy.cat)
- ndarray: matrix with sensor primaries
Returns:
camout:
ndarray with color appearance correlates (forward mode)
or
XYZ tristimulus values (inverse mode)
References:

1. C. Li, Z. Li, Z. Wang, Y. Xu, M. R. Luo, G. Cui, M. Melgosa, M. H. Brill, and M. Pointer, (2017), “Comprehensive color solutions: CAM16, CAT16, and CAM16-UCS,” Color Res. Appl., p. n/a–n/a.

luxpy.color.cam.xyz_to_jabM_ciecam16(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, mcat='cat16', **kwargs)[source]

Wrapper function for ciecam16 forward mode with J,aM,bM output.

For help on parameter details: ?luxpy.cam.ciecam16
luxpy.color.cam.jabM_ciecam16_to_xyz(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, mcat='cat16', **kwargs)[source]

Wrapper function for ciecam16 inverse mode with J,aM,bM input.

For help on parameter details: ?luxpy.cam.ciecam16
luxpy.color.cam.xyz_to_jabC_ciecam16(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, mcat='cat16', **kwargs)[source]

Wrapper function for ciecam16 forward mode with J,aC,bC output.

For help on parameter details: ?luxpy.cam.ciecam16
luxpy.color.cam.jabC_ciecam16_to_xyz(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, mcat='cat16', **kwargs)[source]

Wrapper function for ciecam16 inverse mode with J,aC,bC input.

For help on parameter details: ?luxpy.cam.ciecam16
luxpy.color.cam.cam16ucs(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, ucstype='ucs', forward=True, mcat='cat16')

Run the CAM16-UCS[,-LCD,-SDC] color appearance difference model in forward or backward modes.

Args:
data:
ndarray with sample xyz values (forward mode) or J’a’b’ coordinates (inverse mode)
xyzw:
ndarray with white point tristimulus values
conditions:
None, optional
Dictionary with viewing conditions.
None results in:
{‘La’:100, ‘Yb’:20, ‘D’:1, ‘surround’:’avg’}
For more info see luxpy.cam.ciecam16()?
naka_rushton_parameters:
None, optional
If None: use _NAKA_RUSHTON_PARAMETERS
unique_hue_data:
None, optional
If None: use _UNIQUE_HUE_DATA
ucstype:
‘ucs’, optional
String with type of color difference appearance space
options: ‘ucs’, ‘scd’, ‘lcd’
forward:
True, optional
If True: run in CAM in forward mode, else: inverse mode.
mcat:
‘cat16’, optional
Specifies CAT sensor space.
- options:
- None defaults to ‘cat16’
- str: see see luxpy.cat._MCATS.keys() for options
(details on type, ?luxpy.cat)
- ndarray: matrix with sensor primaries
Returns:
camout:
ndarray with J’a’b’ coordinates (forward mode)
or
XYZ tristimulus values (inverse mode)
References:

1. M.R. Luo, G. Cui, and C. Li, ‘Uniform colour spaces based on CIECAM02 colour appearance model,’ Color Res. Appl., vol. 31, no. 4, pp. 320–330, 2006.

luxpy.color.cam.xyz_to_jab_cam16ucs(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, mcat='cat16', **kwargs)[source]

Wrapper function for cam16ucs forward mode with J,aM,bM output.

For help on parameter details: ?luxpy.cam.cam16ucs
luxpy.color.cam.jab_cam16ucs_to_xyz(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, mcat='cat16', **kwargs)[source]

Wrapper function for cam16ucs inverse mode with J,aM,bM input.

For help on parameter details: ?luxpy.cam.cam16ucs
luxpy.color.cam.xyz_to_jab_cam16lcd(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, mcat='cat16', **kwargs)[source]

Wrapper function for cam16ucs forward mode with J,aMp,bMp output and ucstype = lcd.

For help on parameter details: ?luxpy.cam.cam16ucs
luxpy.color.cam.jab_cam16lcd_to_xyz(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, mcat='cat16', **kwargs)[source]

Wrapper function for cam16ucs inverse mode with J,aMp,bMp input and ucstype = lcd.

For help on parameter details: ?luxpy.cam.cam16ucs
luxpy.color.cam.xyz_to_jab_cam16scd(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, mcat='cat16', **kwargs)[source]

Wrapper function for cam16ucs forward mode with J,aMp,bMp output and ucstype = scd.

For help on parameter details: ?luxpy.cam.cam16ucs
luxpy.color.cam.jab_cam16scd_to_xyz(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, mcat='cat16', **kwargs)[source]

Wrapper function for cam16ucs inverse mode with J,aMp,bMp input and ucstype = scd.

For help on parameter details: ?luxpy.cam.cam16ucs
luxpy.color.cam.zcam(data, xyzw=None, outin='J,aM,bM', cieobs='1931_2', conditions=None, forward=True, mcat='cat02', apply_cat_to_whitepoint=False, **kwargs)

Run the Jz,az,bz based color appearance model in forward or backward modes.

Args:
data:
ndarray with relative sample xyz values (forward mode) or J’a’b’ coordinates (inverse mode)
xyzw:
ndarray with relative white point tristimulus values
None defaults to D65
cieobs:
_CIEOBS, optional
CMF set to use when calculating :xyzw: if this is None.
conditions:
None, optional
Dictionary with viewing condition parameters for:
La, Yb, D and surround.
surround can contain:
- str (options: ‘avg’,’dim’,’dark’) or
- dict with keys c, Nc, F.
None results in:
{‘La’:100, ‘Yb’:20, ‘D’:1, ‘surround’:’avg’}
forward:
True, optional
If True: run in CAM in forward mode, else: inverse mode.
outin:
‘J,aM,bM’, optional
String with requested output (e.g. “J,aM,bM,M,h”) [Forward mode]
- attributes: ‘J’: lightness,’Q’: brightness,
‘M’: colorfulness,’C’: chroma, ‘s’: saturation,
‘h’: hue angle, ‘H’: hue quadrature/composition,
‘Wz’: whiteness, ‘Kz’:blackness, ‘Sz’: saturation, ‘V’: vividness
String with inputs in data [inverse mode].
Input must have data.shape[-1]==3 and last dim of data must have
the following structure for inverse mode:
* data[…,0] = J or Q,
* data[…,1:] = (aM,bM) or (aC,bC) or (aS,bS) or (M,h) or (C, h), …
mcat:
‘cat02’, optional
Specifies CAT sensor space.
- options:
- None defaults to ‘cat02’
- str: see see luxpy.cat._MCATS.keys() for options
(details on type, ?luxpy.cat)
- ndarray: matrix with sensor primaries
apply_cat_to_whitepoint:
False, optional
Apply a CAT to the white point.
However, ZCAM as published doesn’t do this for some reason.
Returns:
camout:
ndarray with color appearance correlates (forward mode)
or
XYZ tristimulus values (inverse mode)
References:

1. Safdar, M., Cui, G., Kim,Y. J., and Luo, M. R.(2017). Perceptually uniform color space for image signals including high dynamic range and wide gamut. Opt. Express, vol. 25, no. 13, pp. 15131–15151, Jun. 2017.

2. Safdar, M., Hardeberg, J., Cui, G., Kim, Y. J., and Luo, M. R.(2018). A Colour Appearance Model based on Jzazbz Colour Space, 26th Color and Imaging Conference (2018), Vancouver, Canada, November 12-16, 2018, pp96-101.

3. Safdar, M., Hardeberg, J.Y., Luo, M.R. (2021) ZCAM, a psychophysical model for colour appearance prediction, Optics Express. 29(4), 6036-6052, <https://doi.org/10.1364/OE.413659>`_

luxpy.color.cam.xyz_to_jabz(xyz, ztype='jabz', use_zcam_parameters=False, **kwargs)[source]

Convert XYZ tristimulus values to Jz,az,bz color coordinates.

Args:
xyz:
ndarray with absolute tristimulus values (Y in cd/m²!)
ztype:
‘jabz’, optional
String with requested return:
Options: ‘jabz’, ‘iabz’
use_zcam_parameters:
False, optional
ZCAM uses a slightly different values (see notes)
Returns:
jabz:
ndarray with Jz (or Iz), az, bz color coordinates
Notes:
1. :xyz: is assumed to be under D65 viewing conditions! If necessary perform chromatic adaptation!

2a. Jz represents the ‘lightness’ relative to a D65 white with luminance = 10000 cd/m²
(note that Jz that not exactly equal 1 for this high value, but rather for 102900 cd/m2)
2b. az, bz represent respectively a red-green and a yellow-blue opponent axis
(but note that a D65 shows a small offset from (0,0))
3. ZCAM: calculates Iz as M’ - epsilon (instead L’/2 + M’/2 as in Iz,az,bz color space!).
Reference:

1. Safdar, M., Cui, G., Kim,Y. J., and Luo, M. R. (2017). Perceptually uniform color space for image signals including high dynamic range and wide gamut. Opt. Express, vol. 25, no. 13, pp. 15131–15151, June 2017.

2. Safdar, M., Hardeberg, J.Y., Luo, M.R. (2021) ZCAM, a psychophysical model for colour appearance prediction, Optics Express. 29(4), 6036-6052, <https://doi.org/10.1364/OE.413659>`_

luxpy.color.cam.jabz_to_xyz(jabz, ztype='jabz', use_zcam_parameters=False, **kwargs)[source]

Convert Jz,az,bz color coordinates to XYZ tristimulus values.

Args:
jabz:
ndarray with Jz,az,bz color coordinates
ztype:
‘jabz’, optional
String with requested return:
Options: ‘jabz’, ‘iabz’
use_zcam_parameters:
False, optional
ZCAM uses a slightly different values (see notes)
Returns:
xyz:
ndarray with tristimulus values
Note:
1. :xyz: is assumed to be under D65 viewing conditions! If necessary perform chromatic adaptation!

2a. Jz represents the ‘lightness’ relative to a D65 white with luminance = 10000 cd/m²
(note that Jz that not exactly equal 1 for this high value, but rather for 102900 cd/m2)
2b. az, bz represent respectively a red-green and a yellow-blue opponent axis
(but note that a D65 shows a small offset from (0,0))
3. ZCAM: calculates Iz as M’ - epsilon (instead L’/2 + M’/2 as in Iz,az,bz color space!).
Reference:

1. Safdar, M., Cui, G., Kim,Y. J., and Luo, M. R. (2017). Perceptually uniform color space for image signals including high dynamic range and wide gamut. Opt. Express, vol. 25, no. 13, pp. 15131–15151, June, 2017.

2. Safdar, M., Hardeberg, J.Y., Luo, M.R. (2021) ZCAM, a psychophysical model for colour appearance prediction, Optics Express. 29(4), 6036-6052, <https://doi.org/10.1364/OE.413659>`_

luxpy.color.cam.xyz_to_jabM_zcam(data, xyzw='_CIE_D65', cieobs='1931_2', conditions=None, mcat='cat02', apply_cat_to_whitepoint=False, **kwargs)[source]

Wrapper function for zcam forward mode with J,aM,bM output.

For help on parameter details: ?luxpy.cam.zcam
luxpy.color.cam.jabM_zcam_to_xyz(data, xyzw='_CIE_D65', cieobs='1931_2', conditions=None, mcat='cat02', apply_cat_to_whitepoint=False, **kwargs)[source]

Wrapper function for zcam inverse mode with J,aM,bM input.

For help on parameter details: ?luxpy.cam.zcam
luxpy.color.cam.xyz_to_jabC_zcam(data, xyzw='_CIE_D65', cieobs='1931_2', conditions=None, mcat='cat02', apply_cat_to_whitepoint=False, **kwargs)[source]

Wrapper function for zcam forward mode with J,aC,bC output.

For help on parameter details: ?luxpy.cam.zcam
luxpy.color.cam.jabC_zcam_to_xyz(data, xyzw='_CIE_D65', cieobs='1931_2', conditions=None, mcat='cat02', apply_cat_to_whitepoint=False, **kwargs)[source]

Wrapper function for zcam inverse mode with J,aC,bC input.

For help on parameter details: ?luxpy.cam.zcam
luxpy.color.cam.cam15u(data, fov=10.0, inputtype='xyz', direction='forward', outin='Q,aW,bW', parameters=None)[source]

Convert between CIE 2006 10° XYZ tristimulus values (or spectral data) and CAM15u color appearance correlates.

Args:
data:
ndarray of CIE 2006 10° XYZ tristimulus values or spectral data
or color appearance attributes
fov:
10.0, optional
Field-of-view of stimulus (for size effect on brightness)
inputtpe:
‘xyz’ or ‘spd’, optional
Specifies the type of input:
tristimulus values or spectral data for the forward mode.
direction:
‘forward’ or ‘inverse’, optional
-‘forward’: xyz -> cam15u
-‘inverse’: cam15u -> xyz
outin:
‘Q,aW,bW’ or str, optional
‘Q,aW,bW’ (brightness and opponent signals for amount-of-neutral)
other options: ‘Q,aM,bM’ (colorfulness) and ‘Q,aS,bS’ (saturation)
Str specifying the type of
input (:direction: == ‘inverse’) and
output (:direction: == ‘forward’)
parameters:
None or dict, optional
Set of model parameters.
- None: defaults to luxpy.cam._CAM15U_PARAMETERS
(see references below)
Returns:
returns:
ndarray with color appearance correlates (:direction: == ‘forward’)
or
XYZ tristimulus values (:direction: == ‘inverse’)
References:

1. M. Withouck, K. A. G. Smet, W. R. Ryckaert, and P. Hanselaer, “Experimental driven modelling of the color appearance of unrelated self-luminous stimuli: CAM15u,” Opt. Express, vol. 23, no. 9, pp. 12045–12064, 2015. 2. M. Withouck, K. A. G. Smet, and P. Hanselaer, (2015), “Brightness prediction of different sized unrelated self-luminous stimuli,” Opt. Express, vol. 23, no. 10, pp. 13455–13466.

luxpy.color.cam.xyz_to_qabW_cam15u(xyz, fov=10.0, parameters=None, **kwargs)[source]

Wrapper function for cam15u forward mode with ‘Q,aW,bW’ output.

For help on parameter details: ?luxpy.cam.cam15u
luxpy.color.cam.qabW_cam15u_to_xyz(qab, fov=10.0, parameters=None, **kwargs)[source]

Wrapper function for cam15u inverse mode with ‘Q,aW,bW’ input.

For help on parameter details: ?luxpy.cam.cam15u
luxpy.color.cam.cam_sww16(data, dataw=None, Yb=20.0, Lw=400.0, Ccwb=None, relative=True, inputtype='xyz', direction='forward', parameters='JOSA', cieobs='2006_10', match_conversionmatrix_to_cieobs=True)[source]

A simple principled color appearance model based on a mapping of the Munsell color system.

This function implements the JOSA A (parameters = ‘JOSA’) published model.
Args:
data:
ndarray with input tristimulus values
or spectral data
or input color appearance correlates
Can be of shape: (N [, xM], x 3), whereby:
N refers to samples and M refers to light sources.
Note that for spectral input shape is (N x (M+1) x wl)
dataw:
None or ndarray, optional
Input tristimulus values or spectral data of white point.
None defaults to the use of CIE illuminant C.
Yb:
20.0, optional
Luminance factor of background (perfect white diffuser, Yw = 100)
Lw:
400.0, optional
Luminance (cd/m²) of white point.
Ccwb:
None, optional
Degree of cognitive adaptation (white point balancing)
If None: use [..,..] from parameters dict.
relative:
True or False, optional
True: xyz tristimulus values are relative (Yw = 100)
parameters:
‘JOSA’ or str or dict, optional
Dict with model parameters.
- str: ‘JOSA’,’best-fit-JOSA’ or ‘best-fit-all-Munsell’
- dict: user defined model parameters
(dict should have same structure)
inputtype:
‘xyz’ or ‘spd’, optional
Specifies the type of input:
tristimulus values or spectral data for the forward mode.
direction:
‘forward’ or ‘inverse’, optional
-‘forward’: xyz -> cam_sww_2016
-‘inverse’: cam_sww_2016 -> xyz
cieobs:
‘2006_10’, optional
CMF set to use to perform calculations where spectral data
is involved (inputtype == ‘spd’; dataw = None)
Other options: see luxpy._CMF[‘types’]
match_conversionmatrix_to_cieobs:
When changing to a different CIE observer, change the xyz_to_lms
matrix to the one corresponding to that observer. If False: use
the one set in parameters or _CAM_SWW16_PARAMETERS
Returns:
returns:
ndarray with color appearance correlates (:direction: == ‘forward’)
or
XYZ tristimulus values (:direction: == ‘inverse’)
Notes:
This function implements the JOSA A (parameters = ‘JOSA’)
published model.
With:
1. A correction for the parameter
in Eq.4 of Fig. 11: 0.952 –> -0.952

2. The delta_ac and delta_bc white-balance shifts in Eq. 5e & 5f
should be: -0.028 & 0.821

(cfr. Ccwb = 0.66 in:
ab_test_out = ab_test_int - Ccwb*ab_gray_adaptation_field_int))
References:

1. Smet, K. A. G., Webster, M. A., & Whitehead, L. A. (2016). A simple principled approach for modeling and understanding uniform color metrics. Journal of the Optical Society of America A, 33(3), A319–A331.

luxpy.color.cam.xyz_to_lab_cam_sww16(xyz, xyzw=None, Yb=20.0, Lw=400.0, Ccwb=None, relative=True, parameters='JOSA', inputtype='xyz', cieobs='2006_10', **kwargs)[source]

Wrapper function for cam_sww16 forward mode with ‘xyz’ input.

For help on parameter details: ?luxpy.cam.cam_sww16
luxpy.color.cam.lab_cam_sww16_to_xyz(lab, xyzw=None, Yb=20.0, Lw=400.0, Ccwb=None, relative=True, parameters='JOSA', inputtype='xyz', cieobs='2006_10', **kwargs)[source]

Wrapper function for cam_sww16 inverse mode with ‘xyz’ input.

For help on parameter details: ?luxpy.cam.cam_sww16
luxpy.color.cam.cam18sl(data, datab=None, Lb=[100], fov=10.0, inputtype='xyz', direction='forward', outin='Q,aS,bS', parameters=None)[source]

Convert between CIE 2006 10° XYZ tristimulus values (or spectral data) and CAM18sl color appearance correlates.

Args:
data:
ndarray of CIE 2006 10° absolute XYZ tristimulus values or spectral data
or color appearance attributes of stimulus
datab:
ndarray of CIE 2006 10° absolute XYZ tristimulus values or spectral data
of stimulus background
Lb:
[100], optional
Luminance (cd/m²) value(s) of background(s) calculated using the CIE 2006 10° CMFs
(only used in case datab == None and the background is assumed to be an Equal-Energy-White)
fov:
10.0, optional
Field-of-view of stimulus (for size effect on brightness)
inputtpe:
‘xyz’ or ‘spd’, optional
Specifies the type of input:
tristimulus values or spectral data for the forward mode.
direction:
‘forward’ or ‘inverse’, optional
-‘forward’: xyz -> cam18sl
-‘inverse’: cam18sl -> xyz
outin:
‘Q,aS,bS’ or str, optional
‘Q,aS,bS’ (brightness and opponent signals for saturation)
other options: ‘Q,aM,bM’ (colorfulness)
(Note that ‘Q,aW,bW’ would lead to a Cartesian
a,b-coordinate system centered at (1,0))
Str specifying the type of
input (:direction: == ‘inverse’) and
output (:direction: == ‘forward’)
parameters:
None or dict, optional
Set of model parameters.
- None: defaults to luxpy.cam._CAM18SL_PARAMETERS
(see references below)
Returns:
returns:
ndarray with color appearance correlates (:direction: == ‘forward’)
or
XYZ tristimulus values (:direction: == ‘inverse’)
Notes:
* Instead of using the CIE 1964 10° CMFs in some places of the model,
the CIE 2006 10° CMFs are used througout, making it more self_consistent.
This has an effect on the k scaling factors (now different those in CAM15u)
and the illuminant E normalization for use in the chromatic adaptation transform.
(see future erratum to Hermans et al., 2018)
* The paper also used an equation for the amount of white W, which is
based on a Q value not expressed in ‘bright’ (‘cA’ = 0.937 instead of 123).
This has been corrected for in the luxpy version of the model, i.e.
_CAM18SL_PARAMETERS[‘cW’][0] has been changed from 2.29 to 1/11672.
(see future erratum to Hermans et al., 2018)
* Default output was ‘Q,aW,bW’ prior to March 2020, but since this
is an a,b Cartesian system centered on (1,0), the default output
has been changed to ‘Q,aS,bS’.
References:

1. Hermans, S., Smet, K. A. G., & Hanselaer, P. (2018). “Color appearance model for self-luminous stimuli.” Journal of the Optical Society of America A, 35(12), 2000–2009.

luxpy.color.cam.xyz_to_qabM_cam18sl(xyz, xyzb=None, Lb=[100], fov=10.0, parameters=None, **kwargs)[source]

Wrapper function for cam18sl forward mode with ‘Q,aM,bM’ output.

For help on parameter details: ?luxpy.cam.cam18sl
luxpy.color.cam.qabM_cam18sl_to_xyz(qab, xyzb=None, Lb=[100], fov=10.0, parameters=None, **kwargs)[source]

Wrapper function for cam18sl inverse mode with ‘Q,aM,bM’ input.

For help on parameter details: ?luxpy.cam.cam18sl
luxpy.color.cam.xyz_to_qabS_cam18sl(xyz, xyzb=None, Lb=[100], fov=10.0, parameters=None, **kwargs)[source]

Wrapper function for cam18sl forward mode with ‘Q,aS,bS’ output.

For help on parameter details: ?luxpy.cam.cam18sl
luxpy.color.cam.qabS_cam18sl_to_xyz(qab, xyzb=None, Lb=[100], fov=10.0, parameters=None, **kwargs)[source]

Wrapper function for cam18sl inverse mode with ‘Q,aS,bS’ input.

For help on parameter details: ?luxpy.cam.cam18sl
luxpy.color.cam.camXucs(data, xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=None, outin='J,aM,bM', conditions=None, forward=True, ucstype='ucs', yellowbluepurplecorrect=False, mcat=None, camtype='ciecam02')[source]

Wraps ciecam02(), ciecam16(), cam02ucs(), cam16ucs().

Args:
camtype:
_DEFAULT_TYPE, optional
String specifying the cam-model.
Notes:
  1. To call ciecam02() or ciecam16(): set ucstype to None !!!

  2. For more info on other input arguments, see doc-strings of those functions.

deltaE/

py:
  • __init__.py

  • colordifferences.py

  • discriminationellipses.py

  • frieleellipses.py

  • macadamellipses.py

namespace:

luxpy.deltaE

Module for color difference calculations

process_DEi():

Process color difference input DEi for output (helper fnc).

DE_camucs():

Calculate color appearance difference DE using camucs type model.

DE_2000():

Calculate DE2000 color difference.

DE_cspace():

Calculate color difference DE in specific color space.

get_macadam_ellipse():

Estimate n-step MacAdam ellipse at CIE x,y coordinates

get_brown1957_ellipse():

Estimate n-step Brown (1957) ellipse at CIE x,y coordinates.

get_gij_fmc():

Get gij matrices describing the discrimination ellipses for Yxy using FMC-1 or FMC-2.

get_fmc_discrimination_ellipse():

Get n-step discrimination ellipse(s) in v-format (R,r, xc, yc, theta) for Yxy using FMC-1 or FMC-2.

luxpy.color.deltaE.deltaH(h1, C1, h2=None, C2=None, htype='deg')[source]

Compute a hue difference, dH = 2*C1*C2*sin(dh/2)

Args:
h1:
hue for sample 1 (or hue difference if h2 is None)
C1:
chroma of sample 1 (or prod C1*C2 if C2 is None)
h2:
hue angle of sample 2 (if None, then h1 contains a hue difference)
C2:
chroma of sample 2
htype:
‘deg’ or ‘rad’, optional
- ‘deg’: hue angle between 0° and 360°
- ‘rad’: hue angle between 0 and 2pi radians
Returns:
returns:
ndarray of deltaH values.
luxpy.color.deltaE.DE_camucs(xyzt, xyzr, DEtype='jab', avg=None, avg_axis=0, out='DEi', xyzwt=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), xyzwr=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Ywt=None, conditionst={'D': 1.0, 'Dtype': None, 'La': 100.0, 'Yb': 20.0, 'surround': 'avg'}, Ywr=None, conditionsr={'D': 1.0, 'Dtype': None, 'La': 100.0, 'Yb': 20.0, 'surround': 'avg'}, camtype='ciecam02', ucstype='ucs', mcat=None, outin='J,aM,bM', yellowbluepurplecorrect=False, **kwargs)[source]

Calculate color appearance difference DE using camucs type model.

Args:
xyzt:
ndarray with tristimulus values of test data.
xyzr:
ndarray with tristimulus values of reference data.
DEtype:
‘jab’ or str, optional
Options:
- ‘jab’ : calculates full color difference over all 3 dimensions.
- ‘ab’ : calculates chromaticity difference.
- ‘j’ : calculates lightness or brightness difference
(depending on :outin:).
- ‘j,ab’: calculates both ‘j’ and ‘ab’ options
and returns them as a tuple.
avg:
None, optional
None: don’t calculate average DE,
otherwise use function handle in :avg:.
avg_axis:
axis to calculate average over, optional
out:
‘DEi’ or str, optional
Requested output.
camtype:
luxpy.cam._CAM_DEFAULT_TYPE, optional
Str specifier for CAM type to use, options: ‘ciecam02’ or ‘ciecam16’.
ucstype:
‘ucs’ or ‘lcd’ or ‘scd’, optional
Str specifier for which type of color attribute compression
parameters to use:
-‘ucs’: uniform color space,
-‘lcd’: large color differences,
-‘scd’: small color differences
Note:

For the other input arguments, see ?luxpy.cam.camucs_structure.

Returns:
returns:
ndarray with DEi [, DEa] or other as specified by :out:
luxpy.color.deltaE.DE2000(xyzt, xyzr, dtype='xyz', DEtype='jab', avg=None, avg_axis=0, out='DEi', xyzwt=None, xyzwr=None, KLCH=None)[source]

Calculate DE2000 color difference.

Args:
xyzt:
ndarray with tristimulus values of test data.
xyzr:
ndarray with tristimulus values of reference data.
dtype:
‘xyz’ or ‘lab’, optional
Specifies data type in :xyzt: and :xyzr:.
xyzwt:
None or ndarray, optional
White point tristimulus values of test data
None defaults to the one set in lx.xyz_to_lab()
xyzwr:
None or ndarray, optional
Whitepoint tristimulus values of reference data
None defaults to the one set in lx.xyz_to_lab()
DEtype:
‘jab’ or str, optional
Options:
- ‘jab’ : calculates full color difference over all 3 dimensions.
- ‘ab’ : calculates chromaticity difference.
- ‘j’ : calculates lightness or brightness difference
(depending on :outin:).
- ‘j,ab’: calculates both ‘j’ and ‘ab’ options
and returns them as a tuple.
KLCH:
None, optional
Weigths for L, C, H
None: default to [1,1,1]
avg:
None, optional
None: don’t calculate average DE,
otherwise use function handle in :avg:.
avg_axis:
axis to calculate average over, optional
out:
‘DEi’ or str, optional
Requested output.
Note:

For the other input arguments, see specific color space used.

Returns:
returns:
ndarray with DEi [, DEa] or other as specified by :out:
References:

1. Sharma, G., Wu, W., & Dalal, E. N. (2005). The CIEDE2000 color‐difference formula: Implementation notes, supplementary test data, and mathematical observations. Color Research & Application, 30(1), 21–30.

luxpy.color.deltaE.DE_cspace(xyzt, xyzr, dtype='xyz', tf='Yuv', DEtype='jab', avg=None, avg_axis=0, out='DEi', xyzwt=None, xyzwr=None, fwtft={}, fwtfr={}, KLCH=None, camtype='ciecam02', ucstype='ucs')[source]

Calculate color difference DE in specific color space.

Args:
xyzt:
ndarray with tristimulus values of test data.
xyzr:
ndarray with tristimulus values of reference data.
dtype:
‘xyz’ or ‘jab’, optional
Specifies data type in :xyzt: and :xyzr:.
xyzwt:
None or ndarray, optional
White point tristimulus values of test data
None defaults to the one set in :fwtft:
or else to the default of cspace.
xyzwr:
None or ndarray, optional
Whitepoint tristimulus values of reference data
None defaults to the one set in non-empty :fwtfr:
or else to default of cspace.
tf:
_CSPACE, optional
Color space to use for color difference calculation.
fwtft:
{}, optional
Dict with parameters for forward transform from xyz to cspace for test data.
fwtfr:
{}, optional
Dict with parameters for forward transform
from xyz to cspace for reference data.
KLCH:
None, optional
Weigths for L, C, H
None: default to [1,1,1]
KLCH is not used when tf == ‘camucs’.
DEtype:
‘jab’ or str, optional
Options:
- ‘jab’ : calculates full color difference over all 3 dimensions.
- ‘ab’ : calculates chromaticity difference.
- ‘j’ : calculates lightness or brightness difference
(depending on :outin:).
- ‘j,ab’: calculates both ‘j’ and ‘ab’ options
and returns them as a tuple.
avg:
None, optional
None: don’t calculate average DE,
otherwise use function handle in :avg:.
avg_axis:
axis to calculate average over, optional
out:
‘DEi’ or str, optional
Requested output.
camtype:
luxpy.cam._CAM_DEFAULT_TYPE, optional
Str specifier for CAM type to use, options: ‘ciecam02’ or ‘ciecam16’.
Only when DEtype == ‘camucs’.
ucstype:
‘ucs’ or ‘lcd’ or ‘scd’, optional
Str specifier for which type of color attribute compression
parameters to use:
-‘ucs’: uniform color space,
-‘lcd’, large color differences,
-‘scd’: small color differences
Only when DEtype == ‘camucs’.
Note:

For the other input arguments, see specific color space used.

Returns:
returns:
ndarray with DEi [, DEa] or other as specified by :out:
luxpy.color.deltaE.get_discrimination_ellipse(Yxy=array([[1.0000e+02, 3.3333e-01, 3.3333e-01]]), etype='fmc2', nsteps=10, k_neighbours=3, average_cik=True, Y=None, brown1957_weighted=True)[source]

Get discrimination ellipse(s) in v-format (R,r, xc, yc, theta) for Yxy using an interpolation of the MacAdam ellipses or using FMC-1 or FMC-2.

Args:
Yxy:
2D ndarray with [Y,]x,y coordinate centers.
If Yxy.shape[-1]==2: Y is added using the value from the Y-input argument.
etype:
‘fmc2’, optional
Type color discrimination ellipse estimation to use.
options: ‘macadam’, ‘fmc1’, ‘fmc2’
- ‘macadam’: interpolate covariance matrices of closest MacAdam ellipses (see: get_macadam_ellipse?).
- ‘fmc1’: use FMC-1 from ref 2 (see get_fmc_discrimination_ellipse?).
- ‘fmc2’: use FMC-1 from ref 3 (see get_fmc_discrimination_ellipse?).
- ‘brown1957’: interpolate covariance matrices of closest Brown1957 ellipses (see: get_brown1957_ellipse?).
nsteps:
10, optional
Set multiplication factor for ellipses
(nsteps=1 corresponds to approximately 1 MacAdam step,
for FMC-2, Y also has to be 10.69, see note below).
brown1957_weighted:
True, optional
If True: use weighted averages from Table III in Brown 1957 paper, else use the straight averages.
k_neighbours:
3, optional
Only for option ‘macadam’.
Number of nearest ellipses to use to calculate ellipse at xy
average_cik:
True, optional
Only for option ‘macadam’.
If True: take distance weighted average of inverse
‘covariance ellipse’ elements cik.
If False: average major & minor axis lengths and
ellipse orientation angles directly.
Y:
None, optional
Only for option ‘fmc2’(see note below).
If not None: Y = 10.69 and overrides values in Yxy.
Note:
  1. FMC-2 is almost identical to FMC-1 is Y = 10.69!; see [3]

References:
  1. MacAdam DL. Visual Sensitivities to Color Differences in Daylight*. J Opt Soc Am. 1942;32(5):247-274.

  2. Chickering, K.D. (1967), Optimization of the MacAdam-Modified 1965 Friele Color-Difference Formula, 57(4):537-541

  3. Chickering, K.D. (1971), FMC Color-Difference Formulas: Clarification Concerning Usage, 61(1):118-122

  4. Brown, WRJ. (1957). Color Discrimination of Twelve Observers*. Journal of the Optical Society of America, 47(2), 137–143.

luxpy.color.deltaE.get_macadam_ellipse(xy=None, k_neighbours=3, nsteps=10, average_cik=True)[source]

Estimate n-step MacAdam ellipse at CIE x,y coordinates xy by calculating average inverse covariance ellipse of the k_neighbours closest ellipses.

Args:
xy:
None or ndarray, optional
If None: output Macadam ellipses, if not None: xy are the
CIE xy coordinates for which ellipses will be estimated.
k_neighbours:
3, optional
Number of nearest ellipses to use to calculate ellipse at xy
nsteps:
10, optional
Set number of MacAdam steps of ellipse.
average_cik:
True, optional
If True: take distance weighted average of inverse
‘covariance ellipse’ elements cik.
If False: average major & minor axis lengths and
ellipse orientation angles directly.
Returns:
v_mac_est:
estimated MacAdam ellipse(s) in v-format [Rmax,Rmin,xc,yc,theta]
References:
  1. MacAdam DL. Visual Sensitivities to Color Differences in Daylight*. J Opt Soc Am. 1942;32(5):247-274.

luxpy.color.deltaE.get_brown1957_ellipse(xy=None, weighted=True, k_neighbours=3, nsteps=10, average_cik=True)[source]

Estimate n-step Brown1957 ellipse at CIE x,y coordinates xy by calculating average inverse covariance ellipse of the k_neighbours closest ellipses.

Args:
xy:
None or ndarray, optional
If None: output Brown1957 ellipses, if not None: xy are the
CIE xy coordinates for which ellipses will be estimated.
weighted:
True, optional
If True: use weighted averages from Table III in Brown 1957 paper, else use the straight averages.
k_neighbours:
3, optional
Number of nearest ellipses to use to calculate ellipse at xy
nsteps:
10, optional
Set number of steps of ellipse.
average_cik:
True, optional
If True: take distance weighted average of inverse
‘covariance ellipse’ elements cik.
If False: average major & minor axis lengths and
ellipse orientation angles directly.
Returns:
v_brown_est:
estimated Brown1957 ellipse(s) in v-format [Rmax,Rmin,xc,yc,theta]
References:
  1. Brown, W.R.J. (1957). Color Discrimination of Twelve Observers*. Journal of the Optical Society of America, 47(2), 137–143. https://doi.org/10.1364/JOSA.47.000137

luxpy.color.deltaE.get_gij_fmc(Yxy, etype='fmc2', ellipsoid=True, Y=None, cspace='Yxy')[source]

Get gij matrices describing the discrimination ellipses/ellipsoids for Yxy or xyz using FMC-1 or FMC-2.

Args:
Yxy:
2D ndarray with [Y,]x,y coordinate centers.
If Yxy.shape[-1]==2: Y is added using the value from the Y-input argument.
etype:
‘fmc2’, optional
Type of FMC color discrimination equations to use (see references below).
options: ‘fmc1’, fmc2’
Y:
None, optional
Only affects FMC-2 (see note below).
If not None: Y = 10.69 and overrides values in Yxy.
ellipsoid:
True, optional
If True: return ellipsoids, else return ellipses (only if cspace == ‘Yxy’)!
cspace:
‘Yxy’, optional
Return coefficients for Yxy-ellipses/ellipsoids (‘Yxy’) or XYZ ellipsoids (‘xyz’)
Note:
  1. FMC-2 is almost identical to FMC-1 is Y = 10.69!; see [2]

References:
  1. Chickering, K.D. (1967), Optimization of the MacAdam-Modified 1965 Friele Color-Difference Formula, 57(4), p.537-541

  2. Chickering, K.D. (1971), FMC Color-Difference Formulas: Clarification Concerning Usage, 61(1), p.118-122

luxpy.color.deltaE.get_fmc_discrimination_ellipse(Yxy=array([[1.0000e+02, 3.3333e-01, 3.3333e-01]]), etype='fmc2', Y=None, nsteps=10)[source]

Get discrimination ellipse(s) in v-format (R,r, xc, yc, theta) for Yxy using FMC-1 or FMC-2.

Args:
Yxy:
2D ndarray with [Y,]x,y coordinate centers.
If Yxy.shape[-1]==2: Y is added using the value from the Y-input argument.
etype:
‘fmc2’, optional
Type of FMC color discrimination equations to use (see references below).
options: ‘fmc1’, fmc2’
Y:
None, optional
Only affects FMC-2 (see note below).
If not None: Y = 10.69 and overrides values in Yxy.
nsteps:
10, optional
Set multiplication factor for ellipses
(nsteps=1 corresponds to approximately 1 MacAdam step,
for FMC-2, Y also has to be 10.69, see note below).
Note:
  1. FMC-2 is almost identical to FMC-1 is Y = 10.69!; see [2]

References:
  1. Chickering, K.D. (1967), Optimization of the MacAdam-Modified 1965 Friele Color-Difference Formula, 57(4), p.537-541

  2. Chickering, K.D. (1971), FMC Color-Difference Formulas: Clarification Concerning Usage, 61(1), p.118-122

luxpy.color.deltaE.discrimination_hotelling_t2(Yxy1, Yxy2, etype='fmc2', ellipsoid=True, Y1=None, Y2=None, cspace='Yxy')[source]

Check ‘significance’ of difference using Hotelling’s T2 test on the centers Yxy1 and Yxy2 and their associate FMC-1/2 discrimination ellipses.

Args:
Yxy1, Yxy2:
2D ndarrays with [Y,]x,y coordinate centers.
If Yxy.shape[-1]==2: Y is added using the value from the Y-input argument.
etype:
‘fmc2’, optional
Type of FMC color discrimination equations to use (see references below).
options: ‘fmc1’, fmc2’
Y1, Y2:
None, optional
Only affects FMC-2 (see note below).
If not None: Yi = 10.69 and overrides values in Yxyi.
ellipsoid:
True, optional
If True: return ellipsoids, else return ellipses (only if cspace == ‘Yxy’)!
cspace:
‘Yxy’, optional
Return coefficients for Yxy-ellipses/ellipsoids (‘Yxy’) or XYZ ellipsoids (‘xyz’)
Returns:
p:
Chi-square based p-value
T2:
T2 test statistic (= mahalanobis distance on summed standard error cov. matrices)
Steps:

1. For each center coordinate, the standard error covariance matrix gij^-1 = Si/ni is determined using the FMC-1 or FMC-2 equations (see refs. 1 & 2). 2. Calculate sum of covariance matrices: SIG = S1/n1 + S2/n2 = gij1^-1 + gij2^-1 3. These are then used in Hotelling’s T2 test: T2 = (xy1 - xy2).T*(SIG^-1)*(xy1_xy2) 4. The T2 statistic is then tested against a Chi-square distribution with 2 or 3 degrees of freedom.

References:
  1. Chickering, K.D. (1967), Optimization of the MacAdam-Modified 1965 Friele Color-Difference Formula, 57(4):537-541

  2. Chickering, K.D. (1971), FMC Color-Difference Formulas: Clarification Concerning Usage, 61(1):118-122

whiteness/

py:
  • __init__.py

  • smet_white_loci.py

namespace:

luxpy

Module with Smet et al. (2018) neutral white loci

_UW_NEUTRALITY_PARAMETERS_SMET2014:

dict with parameters of the unique white models in Smet et al. (2014)

xyz_to_neutrality_smet2018():

Calculate degree of neutrality using the unique white model in Smet et al. (2014) or the normalized (max = 1) degree of chromatic adaptation model from Smet et al. (2017).

cct_to_neutral_loci_smet2018():

Calculate the most neutral appearing Duv10 in and the degree of neutrality for a specified CCT using the models in Smet et al. (2018).

References

Added August 02, 2019.

luxpy.color.whiteness.xyz_to_neutrality_smet2018(xyz10, nlocitype='uw', uw_model='Linvar')[source]

Calculate degree of neutrality using the unique white model in Smet et al. (2014) or the normalized (max = 1) degree of chromatic adaptation model from Smet et al. (2017).

Args:
xyz10:
ndarray with CIE 1964 10° xyz tristimulus values.
nlocitype:
‘uw’, optional
‘uw’: use unique white models published in Smet et al. (2014).
‘ca’: use degree of chromatic adaptation model from Smet et al. (2017).
uw_model:
‘Linvar’, optional
Use Luminance invariant unique white model from Smet et al. (2014).
Other options: ‘L200’ (200 cd/m²), ‘L1000’ (1000 cd/m²) and ‘L2000’ (2000 cd/m²).
Returns:
N:
ndarray with calculated neutrality
References:

1. Smet, K., Deconinck, G., & Hanselaer, P., (2014), Chromaticity of unique white in object mode. Optics Express, 22(21), 25830–25841.

2. Smet, K.A.G., Zhai, Q., Luo, M.R., Hanselaer, P., (2017), Study of chromatic adaptation using memory color matches, Part II: colored illuminants, Opt. Express, 25(7), pp. 8350-8365.

luxpy.color.whiteness.cct_to_neutral_loci_smet2018(cct, nlocitype='uw', out='duv,D')[source]

Calculate the most neutral appearing Duv10 in and the degree of neutrality for a specified CCT using the models in Smet et al. (2018).

Args:
cct10:
ndarray CCT
nlocitype:
‘uw’, optional
‘uw’: use unique white models published in Smet et al. (2014).
‘ca’: use degree of chromatic adaptation model from Smet et al. (2017).
out:
‘duv,D’, optional
Specifies requested output (other options: ‘duv’, ‘D’).
Returns:
duv:
ndarray with most neutral Duv10 value corresponding to the cct input.
D:
ndarray with the degree of neutrality at (cct, duv).
References:

1. Smet, K.A.G., (2018), Two Neutral White Illumination Loci Based on Unique White Rating and Degree of Chromatic Adaptation. LEUKOS, 14(2), 55–67.

Notes:
  1. Duv is specified in the CIE 1960 u10v10 chromatity diagram as the models were developed using CIE 1964 10° tristimulus, chromaticity and CCT values.

  2. The parameter +0.0172 in Eq. 4b should be -0.0172.

cri/

py:
  • __init__.py

  • colorrendition.py

  • /utils/
    • __init__.py

    • init_cri_defaults_database.py

    • DE_scalers.py

    • helpers.py

    • graphics.py

  • /indices/
    • __init__.py

    • indices.py

    • cie_wrappers.py

    • iestm30_wrappers.py

    • cri2012.py

    • mcri.py

    • cqs.py

    • fci.py

    • thorntoncpi.py

  • /iestm30/
    • __init__.py

    • metrics.py

    • graphics.py

    • metrics_fast.py

  • /VFPX/
    • __inint__.py

    • vectorshiftmodel.py

    • pixelshiftmodel.py

    • VF_PX_models.py

namespace:

luxpy.cri

cri: sub-package suppporting color rendition calculations (colorrendition.py)

utils/init_cri_defaults_database.py

_CRI_TYPE_DEFAULT:

Default cri_type.

_CRI_DEFAULTS:
default parameters for color fidelity and gamut area metrics
(major dict has 13 keys (04 Mar, 2025):
- sampleset [str/dict],
- ref_type [str],
- calculation_wavelength_range [list],
- cieobs [Dict],
- cct_mode [str],
- avg [fcn handle],
- rf_from_avg_rounded_rfi [bool],
- round_daylightphase_Mi_to_cie_recommended [bool],
- scale [dict],
- cspace [dict],
- catf [dict],
- rg_pars [dict],
- cri_specific_pars [dict])

Supported cri-types:
* ‘ciera’,’ciera-8’,’ciera-14’,’cierf’,
* ‘iesrf’,’iesrf-tm30-15’,’iesrf-tm30-18’,’iesrf-tm30-20’,’iesrf-tm30-24’
* ‘cri2012’,’cri2012-hl17’,’cri2012-hl1000’,’cri2012-real210’,
* ‘mcri’,
* ‘cqs-v7.5’,’cqs-v9.0’
* ‘fci’
* ‘thornton_cpi’
process_cri_type_input():

load a cri_type dict but overwrites any keys that have a non-None input in calling function.

utils/DE_scalers.py

linear_scale():
Linear color rendering index scale from CIE13.3-1974/1995:
Rfi,a = 100 - c1*DEi,a. (c1 = 4.6)
log_scale():
Log-based color rendering index scale from Davis & Ohno (2009):
Rfi,a = 10 * ln(exp((100 - c1*DEi,a)/10) + 1)
psy_scale():
Psychometric based color rendering index scale from Smet et al. (2013):
Rfi,a = 100 * (2 / (exp(c1*abs(DEi,a)**(c2) + 1))) ** c3

utils/helpers.py

_get_hue_bin_data():

Slice gamut spanned by the sample jabt, jabr and calculate hue-bin data.

_hue_bin_data_to_rxhj():

Calculate hue bin measures: Rcshj, Rhshj, Rfhj, DEhj

_hue_bin_data_to_rfi():

Get sample color differences DEi and calculate color fidelity values Rfi.

_hue_bin_data_to_rg():

Calculates gamut area index, Rg.

spd_to_jab_t_r():

Calculates jab color values for a sample set illuminated with test source and its reference illuminant.

spd_to_rg():

Calculates the color gamut index of spectral data for a sample set illuminated with test source (data) with respect to some reference illuminant.

spd_to_DEi():

Calculates color difference (~fidelity) of spectral data between sample set illuminated with test source (data) and some reference illuminant.

optimize_scale_factor():

Optimize scale_factor of cri-model in cri_type such that average Rf for a set of light sources is the same as that of a target-cri (default: ‘ciera’)

spd_to_cri():

Calculates the color rendering fidelity index (CIE Ra, CIE Rf, IES Rf, CRI2012 Rf) of spectral data. Can also output Rg, Rfhi, Rcshi, Rhshi, cct, duv, …

utils/graphics.py

plot_hue_bins():

Makes basis plot for Color Vector Graphic (CVG).

plot_ColorVectorGraphic():

Plots Color Vector Graphic (see IES TM30).

indices/indices.py

wrapper_functions_for_fidelity_type_metrics:
spd_to_ciera(): CIE 13.3 1995 version
spd_to_ciera_133_1995(): CIE 13.3 1995 version
spd_to_cierf(): latest version
spd_to_cierf_224_2017(): CIE224-2017 version
spd_to_iesrf(): latest version
spd_to_iesrf_tm30(): latest version
spd_to_iesrf_tm30_15(): TM30-15 version
spd_to_iesrf_tm30_18(): TM30-18 version
spd_to_iesrf_tm30_20(): TM30-20 version (= TM30-18)
spd_to_cri2012()
spd_to_cri2012_hl17()
spd_to_cri2012_hl1000()
spd_to_cri2012_real210()
wrapper_functions_for_gamut_area_metrics:
spd_to_iesrg(): latest version
spd_to_iesrg_tm30(): latest version
spd_to_iesrg_tm30_15(): TM30-15 version
spd_to_iesrg_tm30_18(): TM30-18 version
spd_to_iesrg_tm30_20(): TM30-20 version (= TM30-18)

indices/mcri.py

spd_to_mcri():
Calculates the memory color rendition index, Rm:
K. A. G. Smet, W. R. Ryckaert, M. R. Pointer, G. Deconinck, and P. Hanselaer, (2012)
“A memory colour quality metric for white light sources,”
Energy Build., vol. 49, no. C, pp. 216–225.

indices/cqs.py

spd_to_cqs():
versions 7.5 and 9.0 are supported.
W. Davis and Y. Ohno,
“Color quality scale,” (2010),
Opt. Eng., vol. 49, no. 3, pp. 33602–33616.

iestm30/graphics.py

spd_to_ies_tm30_metrics():

Calculates IES TM30 metrics from spectral data

plot_cri_graphics():
Plots graphical information on color rendition
properties based on spectral data input or dict with
pre-calculated measures.
_tm30_process_spd():

Calculate all required parameters for plotting from spd using cri.spd_to_cri()

plot_tm30_cvg():

Plot TM30 Color Vector Graphic (CVG).

plot_tm30_Rfi():

Plot Sample Color Fidelity values (Rfi).

plot_tm30_Rxhj():

Plot Local Chroma Shifts (Rcshj), Local Hue Shifts (Rhshj) and Local Color Fidelity values (Rfhj).

plot_tm30_Rcshj():

Plot Local Chroma Shifts (Rcshj).

plot_tm30_Rhshj():

Plot Local Hue Shifts (Rhshj).

plot_tm30_Rfhj():

Plot Local Color Fidelity values (Rfhj).

plot_tm30_spd():

Plot test SPD and reference illuminant, both normalized to the same luminous power.

plot_tm30_report():

Plot a figure with an ANSI/IES-TM30 color rendition report.

plot_cri_graphics():
Plots graphical information on color rendition
properties based on spectral data input or dict with
pre-calculated measures (cusom design).
Includes Metameric uncertainty index Rt and vector-fields
of color rendition shifts.

iestm30/metrics.py

spd_to_ies_tm30_metrics():

Calculates IES TM30 metrics from spectral data + Metameric Uncertainty + Vector Fields

iestm30/metrics_fast.py

_cri_ref():

Calculate multiple reference illuminant spectra based on ccts for color rendering index calculations.

_xyz_to_jab_cam02ucs():

Calculate CAM02-UCS J’a’b’ coordinates from xyz tristimulus values of sample and white point.

spd_to_tm30():

Calculate tm30 measures from spd.

  • Created for faster spectral optimization based on ANSI/IES-TM30 measures

VFPX

:Module_for_VectorField_and_Pixelation_CRI models.

  • see ?luxpy.cri.VFPX

luxpy.color.cri.linear_scale(data, scale_factor=[4.6], scale_max=100.0)[source]

Linear color rendering index scale from CIE13.3-1974/1995:

Rfi,a = 100 - c1*DEi,a. (c1 = 4.6)
Args:
data:
float or list[floats] or ndarray
scale_factor:
[4.6] or list[float] or ndarray, optional
Rescales color differences before subtracting them from :scale_max:
scale_max:
100.0, optional
Maximum value of linear scale
Returns:
returns:
float or list[floats] or ndarray
References:

1. CIE13.3-1995, “Method of Measuring and Specifying Colour Rendering Properties of Light Sources,” CIE, Vienna, Austria, 1995.,ISBN 978 3 900734 57 2

luxpy.color.cri.log_scale(data, scale_factor=[6.73], scale_max=100.0)[source]

Log-based color rendering index scale from Davis & Ohno (2009):

Rfi,a = 10 * ln(exp((100 - c1*DEi,a)/10) + 1).
Args:
data:
float or list[floats] or ndarray
scale_factor:
[6.73] or list[float] or ndarray, optional
Rescales color differences before subtracting them from :scale_max:
Note that the default value is the one from cie-224-2017.
scale_max:
100.0, optional
Maximum value of linear scale
Returns:
returns:
float or list[floats] or ndarray
References:

1. W. Davis and Y. Ohno, “Color quality scale,” (2010), Opt. Eng., vol. 49, no. 3, pp. 33602–33616. 2. CIE224:2017. CIE 2017 Colour Fidelity Index for accurate scientific use. Vienna, Austria: CIE. (2017).

luxpy.color.cri.psy_scale(data, scale_factor=[0.01818181818181818, 1.5, 2.0], scale_max=100.0)[source]

Psychometric based color rendering index scale from CRI2012:

Rfi,a = 100 * (2 / (exp(c1*abs(DEi,a)**(c2) + 1))) ** c3.
Args:
data:
float or list[floats] or ndarray
scale_factor:
[1/55, 3/2, 2.0] or list[float] or ndarray, optional
Rescales color differences before subtracting them from :scale_max:
Note that the default value is the one from (Smet et al. 2013, LRT).
scale_max:
100.0, optional
Maximum value of linear scale
Returns:
returns:
float or list[floats] or ndarray
References:

1. Smet, K., Schanda, J., Whitehead, L., & Luo, R. (2013). CRI2012: A proposal for updating the CIE colour rendering index. Lighting Research and Technology, 45, 689–709.

luxpy.color.cri._get_hue_bin_data(jabt, jabr, start_hue=0, nhbins=16, normalized_chroma_ref=100)[source]

Slice gamut spanned by the sample jabt, jabr and calculate hue-bin data.

Args:
jabt:
ndarray with jab sample data under test illuminant
jabr:
ndarray with jab sample data under reference illuminant
start_hue:
0.0 or float, optional
Hue angle to start bin slicing
nhbins:
None or int, optional
- None: defaults to using the sample hues themselves as ‘bins’.
In other words, the number of bins will be equal to the
number of samples.
- float: number of bins to slice the sample gamut in.
normalized_chroma_ref:
100.0 or float, optional
Controls the size (chroma/radius) of the normalization circle/gamut.
Returns:
dict:
Dictionary with keys:

- ‘jabt’, ‘jabr’: ndarrays with jab sample data under test & ref. illuminants
- ‘DEi’: ndarray with sample jab color difference between test and ref.
- ‘Ct’, ‘Cr’: chroma for each sample under test and ref.
- ‘ht’, ‘hr’: hue angles (rad.) for each sample under test and ref.
- ‘ht_idx’, ‘hr_idx’: hue bin indices for each sample under test and ref.
- ‘jabt_hj’, ‘jabr_hj’: ndarrays with hue-bin averaged jab’s under test & ref. illuminants
- ‘DE_hj’ : ndarray with average sample DE in each hue bin
- ‘jabt_hj_closed’, ‘jabr_hj_closed’: ndarrays with hue-bin averaged jab’s under test & ref. illuminants (closed gamut: 1st == last)
- ‘jabtn_hj’, ‘jabrn_hj’: ndarrays with hue-bin averaged and normalized jab’s under test & ref. illuminants
- ‘jabtn_hj_closed’, ‘jabrn_hj_closed’: ndarrays with hue-bin and normalized averaged jab’s under test & ref. illuminants (closed gamut: 1st == last)
- ‘ht_hj’, ‘hr_hj’: hues (rad.) for each hue bin for test and ref.
- ‘Ct_hj’, ‘Cr_hj’: chroma for each hue bin for test and ref.
- ‘Ctn_hj’ : normalized chroma for each hue bin for test (ref = normalized_chroma_ref)
- ‘nhbins’: number of hue bins
- ‘start_hue’ : start hue for bin slicing
- ‘normalized_chroma_ref’: normalized chroma value for ref.
- ‘dh’: hue-angle arcs (°)
- ‘hue_bin_edges’: hue bin edge (rad)
- ‘hbinnrs’: hue bin indices for each sample under ref. (= hr_idx)
luxpy.color.cri.spd_to_jab_t_r(St, cri_type='ies-tm30', out='jabt,jabr', wl=None, sampleset=None, ref_type=None, calculation_wavelength_range=None, cieobs=None, cct_mode=None, cspace=None, catf=None, cri_specific_pars=None, round_daylightphase_Mi_to_cie_recommended=False, interp_settings=None)[source]

Calculates jab color values for a sample set illuminated with test source SPD and its reference illuminant.

Args:
St:
ndarray with spectral data
(can be multiple SPDs, first axis are the wavelengths)
out:
‘jabt,jabr’ or str, optional
Specifies requested output (e.g.’jabt,jabr’ or ‘jabt,jabr,cct,duv’)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the spds in St to.
None: default to no interpolation
cri_type:
_CRI_TYPE_DEFAULT or str or dict, optional
-‘str: specifies dict with default cri model parameters
(for supported types, see luxpy.cri._CRI_DEFAULTS[‘cri_types’])
- dict: user defined model parameters
(see e.g. luxpy.cri._CRI_DEFAULTS[‘cierf’]
for required structure)
Note that any non-None input arguments to the function will
override default values in cri_type dict.
sampleset:
None or ndarray or str, optional
Specifies set of spectral reflectance samples for cri calculations.
- None defaults to standard set for metric in cri_type.
- ndarray: user defined set of spectral reflectance functions
(.shape = (N+1, number of wavelengths);
first axis are wavelengths)
ref_type:
None or str or ndarray, optional
Specifies type of reference illuminant type.
- None: defaults to metric_specific reference illuminant in
accordance with cri_type.
- str: ‘BB’ : Blackbody radiatiors,
‘DL’: daylightphase,
‘ciera’: used in CIE CRI-13.3-1995,
‘cierf’: used in CIE 224-2017,
‘iesrf’: used in TM30-15, …
- ndarray: user defined reference SPD
calculation_wavelength_range:
None or list, optional
Specifies the range outside of which all values of the SPD will be dropped in the calculations.
cieobs:
None or dict, optional
Specifies which CMF sets to use for the calculation of the sample
XYZs and the CCT (for reference illuminant calculation).
None defaults to the one specified in :cri_type: dict.
- key: ‘xyz’: str specifying CMF set for calculating xyz
of samples and white
- key: ‘cct’: str specifying CMF set for calculating cct
cct_mode:
None or str or (str, dict), optional
Specifies which mode to use when calculating xyz_to_cct().
If tuple: second element is dict with additional kwargs for xyz_to_cct
cspace:
None or dict, optional
Specifies which color space to use.
None defaults to the one specified in :cri_type: dict.
- key: ‘type’: str specifying color space used to calculate
color differences in.
- key: ‘xyzw’: None or ndarray with white point of color space
If None: use xyzw of test / reference (after chromatic
adaptation, if specified)
- other keys specify other possible parameters needed for color
space calculation,
see lx.cri._CRI_DEFAULTS[‘iesrf’][‘cspace’] for details.
catf:
None or dict, optional
Perform explicit CAT before converting to color space coordinates.
- None: don’t apply a cat (other than perhaps the one built
into the colorspace)
- dict: with CAT parameters:
- key: ‘D’: ndarray with degree of adaptation
- key: ‘mcat’: ndarray with sensor matrix specification
- key: ‘xyzw’: None or ndarray with white point
None: use xyzw of reference otherwise transform both
test and ref to xyzw
cri_specific_pars:
None or dict, optional
Specifies other parameters specific to type of cri
(e.g. maxC for CQS calculations)
- None: default to the one specified in :cri_type: dict.
- dict: user specified parameters.
For its use, see for example:
luxpy.cri._CRI_DEFAULTS[‘mcri’][‘cri_specific_pars’]
round_daylightphase_Mi_to_cie_recommended:
False, optional
Round M1, M2 values to 3 decimals as recommended by CIE (not that TM30 does not do this, which gives slight errors when calculating a daylight phase (equivalent of around 0.75 K for 6500 K illuminant))
Returns:
returns:
(ndarray, ndarray)
with jabt and jabr data for :out: ‘jabt,jabr’

Other output is also possible by changing the :out: str value.
luxpy.color.cri.spd_to_rg(St, cri_type='ies-tm30', out='Rg', wl=None, sampleset=None, ref_type=None, calculation_wavelength_range=None, round_daylightphase_Mi_to_cie_recommended=None, cct_mode=None, cieobs=None, avg=None, cspace=None, catf=None, cri_specific_pars=None, rg_pars=None, fit_gamut_ellipse=False, interp_settings=None)[source]

Calculates the color gamut index, Rg, of spectral data.

Args:
St:
ndarray with spectral data
(can be multiple SPDs, first axis are the wavelengths)
out:
‘Rg’ or str, optional
Specifies requested output (e.g. ‘Rg,cct,duv’)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the SPDs to.
None: default to no interpolation
cri_type:
_CRI_TYPE_DEFAULT or str or dict, optional
-‘str: specifies dict with default cri model parameters
(for supported types, see luxpy.cri._CRI_DEFAULTS[‘cri_types’])
- dict: user defined model parameters
(see e.g. luxpy.cri._CRI_DEFAULTS[‘cierf’]
for required structure)
Note that any non-None input arguments to the function will
override default values in cri_type dict.
sampleset:
None or ndarray or str, optional
Specifies set of spectral reflectance samples for cri calculations.
- None defaults to standard set for metric in cri_type.
- ndarray: user defined set of spectral reflectance functions
(.shape = (N+1, number of wavelengths);
first axis are wavelengths)
ref_type:
None or str or ndarray, optional
Specifies type of reference illuminant type.
- None: defaults to metric_specific reference illuminant in
accordance with cri_type.
- str: ‘BB’ : Blackbody radiatiors,
‘DL’: daylightphase,
‘ciera’: used in CIE CRI-13.3-1995,
‘cierf’: used in CIE 224-2017,
‘iesrf’: used in TM30-15, …
- ndarray: user defined reference SPD
calculation_wavelength_range:
None or list, optional
Specifies the range outside of which all values of the SPD will be dropped in the calculations.
cieobs:
None or dict, optional
Specifies which CMF sets to use for the calculation of the sample
XYZs and the CCT (for reference illuminant calculation).
None defaults to the one specified in :cri_type: dict.
- key: ‘xyz’: str specifying CMF set for calculating xyz
of samples and white
- key: ‘cct’: str specifying CMF set for calculating cct
cct_mode:
None or str or (str, dict), optional
Specifies which mode to use when calculating xyz_to_cct().
If tuple: second element is dict with additional kwargs for xyz_to_cct
cspace:
None or dict, optional
Specifies which color space to use.
None defaults to the one specified in :cri_type: dict.
- key: ‘type’: str specifying color space used to calculate
color differences in.
- key: ‘xyzw’: None or ndarray with white point of color space
If None: use xyzw of test / reference (after chromatic
adaptation, if specified)
- other keys specify other possible parameters needed for color
space calculation,
see lx.cri._CRI_DEFAULTS[‘iesrf’][‘cspace’] for details.
catf:
None or dict, optional
Perform explicit CAT before converting to color space coordinates.
- None: don’t apply a cat (other than perhaps the one built
into the colorspace)
- dict: with CAT parameters:
- key: ‘D’: ndarray with degree of adaptation
- key: ‘mcat’: ndarray with sensor matrix specification
- key: ‘xyzw’: None or ndarray with white point
None: use xyzw of reference otherwise transform both
test and ref to xyzw
cri_specific_pars:
None or dict, optional
Specifies other parameters specific to type of cri
(e.g. maxC for CQS calculations)
- None: default to the one specified in :cri_type: dict.
- dict: user specified parameters.
For its use, see for example:
luxpy.cri._CRI_DEFAULTS[‘mcri’][‘cri_specific_pars’]
round_daylightphase_Mi_to_cie_recommended:
None or bool, optional
Round M1, M2 values to 3 decimals as recommended by CIE (not that TM30 does not do this, which gives slight errors when calculating a daylight phase (equivalent of around 0.75 K for 6500 K illuminant))
rg_pars:
None or dict, optional
Dict containing specifying parameters for slicing the gamut.
Dict structure:
{‘nhbins’ : None, ‘start_hue’ : 0,
‘normalize_gamut’ : False, ‘normalized_chroma_ref’: 100.0}
- key: ‘nhbins’: int, number of hue bins to slice gamut
(None use the one specified in :cri_type: dict).
- key: ‘start_hue’: float (°), hue at which to start slicing
- key: ‘normalize_gamut’: True or False:
normalize gamut or not before calculating a gamut
area index Rg.
- key: ‘normalized_chroma_ref’: 100.0 or float, optional
Controls the size (chroma/radius)
of the normalization circle/gamut.
- key ‘use_bin_avg_DEi’: True or False
Note that following IES-TM30 DEhj from gamut_slicer()
is obtained by averaging the DEi per hue bin (True),
and NOT by averaging the jabt and jabr per hue bin
and then calculating the DEhj (False).
avg:
None or fcn handle, optional
Averaging function (handle) for color differences, DEi
(e.g. numpy.mean, .math.rms, .math.geomean)
None use the one specified in :cri_type: dict.
scale:
None or dict, optional
Specifies scaling of color differences to obtain CRI.
- None use the one specified in :cri_type: dict.
- dict: user specified dict with scaling parameters.
- key: ‘fcn’: function handle to type of cri scale,
e.g.
* linear()_scale –> (100 - scale_factor*DEi),
* log_scale –> (cfr. Ohno’s CQS),
* psy_scale (Smet et al.’s cri2012,See: LRT 2013)
- key: ‘cfactor’: factors used in scaling function,
If None:
Scaling factor value(s) will be optimized to
minimize the rms between the Rf’s of the
requested metric and the target metric specified
in:

- key: ‘opt_cri_type’: str
* str: one of the preset _CRI_DEFAULTS
* dict: user speciied
(dict must contain all keys as normal)
Note that if key not in :scale: dict,
then ‘opt_cri_type’ is added with default
setting = ‘ciera’.
- key: ‘opt_spd_set’: ndarray with set of light
source spds used to optimize cfactor.
Note that if key not in :scale: dict,
then default = ‘F1-F12’.
fit_gamut_ellipse:
fit ellipse to normalized color gamut
(extract from function using out; also stored in hue_bin_data[‘gamut_ellipse_fit’])
Returns:
returns:
float or ndarray with Rg for :out: ‘Rg’
Other output is also possible by changing the :out: str value.
E.g. out == ‘Rg,data’ would output an ndarray with Rg values
and a dictionary :data: with keys:
‘St’, ‘Sr’, ‘cct’, ‘duv’, ‘hue_bin_data’
‘xyzti’, xyzti, ‘xyztw’, ‘xyzri’, ‘xyzrw’
References:

1. IES TM30, Method for Evaluating Light Source Color Rendition. New York, NY: The Illuminating Engineering Society of North America.

2. A. David, P. T. Fini, K. W. Houser, Y. Ohno, M. P. Royer, K. A. G. Smet, M. Wei, and L. Whitehead, “Development of the IES method for evaluating the color rendition of light sources,” Opt. Express, vol. 23, no. 12, pp. 15888–15906, 2015.

luxpy.color.cri.spd_to_DEi(St, cri_type='ies-tm30', out='DEi', wl=None, sampleset=None, ref_type=None, calculation_wavelength_range=None, round_daylightphase_Mi_to_cie_recommended=None, cieobs=None, cct_mode=None, avg=None, cspace=None, catf=None, cri_specific_pars=None, interp_settings=None)[source]

Calculates color differences (~fidelity), DEi, of spectral data.

Args:
St:
ndarray with spectral data
(can be multiple SPDs, first axis are the wavelengths)
out:
‘DEi’ or str, optional
Specifies requested output (e.g. ‘DEi,DEa,cct,duv’)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the spds in St to.
None: default to no interpolation
cri_type:
_CRI_TYPE_DEFAULT or str or dict, optional
-‘str: specifies dict with default cri model parameters
(for supported types, see luxpy.cri._CRI_DEFAULTS[‘cri_types’])
- dict: user defined model parameters
(see e.g. luxpy.cri._CRI_DEFAULTS[‘cierf’]
for required structure)
Note that any non-None input arguments to the function will override default values in cri_type dict.
sampleset:
None or ndarray or str, optional
Specifies set of spectral reflectance samples for cri calculations.
- None defaults to standard set for metric in cri_type.
- ndarray: user defined set of spectral reflectance functions
(.shape = (N+1, number of wavelengths);
first axis are wavelengths)
ref_type:
None or str or ndarray, optional
Specifies type of reference illuminant type.
- None: defaults to metric_specific reference illuminant in
accordance with cri_type.
- str: ‘BB’ : Blackbody radiatiors,
‘DL’: daylightphase,
‘ciera’: used in CIE CRI-13.3-1995,
‘cierf’: used in CIE 224-2017,
‘iesrf’: used in TM30-15, …
- ndarray: user defined reference SPD
cieobs:
None or dict, optional
Specifies which CMF sets to use for the calculation of the sample
XYZs and the CCT (for reference illuminant calculation).
None defaults to the one specified in :cri_type: dict.
- key: ‘xyz’: str specifying CMF set for calculating xyz
of samples and white
- key: ‘cct’: str specifying CMF set for calculating cct
cspace:
None or dict, optional
Specifies which color space to use.
None defaults to the one specified in :cri_type: dict.
- key: ‘type’: str specifying color space used to calculate
color differences in.
- key: ‘xyzw’: None or ndarray with white point of color space
If None: use xyzw of test / reference (after chromatic
adaptation, if specified)
- other keys specify other possible parameters needed for color
space calculation,
see lx.cri._CRI_DEFAULTS[‘iesrf’][‘cspace’] for details.
catf:
None or dict, optional
Perform explicit CAT before converting to color space coordinates.
- None: don’t apply a cat (other than perhaps the one built
into the colorspace)
- dict: with CAT parameters:
- key: ‘D’: ndarray with degree of adaptation
- key: ‘mcat’: ndarray with sensor matrix specification
- key: ‘xyzw’: None or ndarray with white point
None: use xyzw of reference otherwise transform both
test and ref to xyzw
cri_specific_pars:
None or dict, optional
Specifies other parameters specific to type of cri
(e.g. maxC for CQS calculations)
- None: default to the one specified in :cri_type: dict.
- dict: user specified parameters.
For its use, see for example:
luxpy.cri._CRI_DEFAULTS[‘mcri’][‘cri_specific_pars’]
round_daylightphase_Mi_to_cie_recommended:
None or bool, optional
Round M1, M2 values to 3 decimals as recommended by CIE (not that TM30 does not do this, which gives slight errors when calculating a daylight phase (equivalent of around 0.75 K for 6500 K illuminant))
Returns:
returns:
float or ndarray with DEi for :out: ‘DEi’

Other output is also possible by changing the :out: str value.
luxpy.color.cri.optimize_scale_factor(cri_type, opt_scale_factor, scale_fcn, avg, rf_from_avg_rounded_rfi, interp_settings=None)[source]

Optimize scale_factor of cri-model in cri_type such that average Rf for a set of light sources is the same as that of a target-cri (default: ‘ciera’).

Args:
cri_type:
str or dict
-‘str: specifies dict with default cri model parameters
(for supported types, see luxpy.cri._CRI_DEFAULTS[‘cri_types’])
- dict: user defined model parameters
(see e.g. luxpy.cri._CRI_DEFAULTS[‘cierf’]
for required structure)
opt_scale:
True or False
True: optimize scaling-factor, else do nothing and use value of
scaling-factor in :scale: dict.
scale_fcn:
function handle to type of cri scale,
e.g.
* linear()_scale –> (100 - scale_factor*DEi),
* log_scale –> (cfr. Ohno’s CQS),
* psy_scale (Smet et al.’s cri2012,See: LRT 2013)
avg:
None or fcn handle
Averaging function (handle) for color differences, DEi
(e.g. numpy.mean, .math.rms, .math.geomean)
None use the one specified in :cri_type: dict.
Returns:
scaling_factor:
ndarray
luxpy.color.cri.spd_to_cri(St, cri_type='ies-tm30', out='Rf', wl=None, sampleset=None, ref_type=None, calculation_wavelength_range=None, round_daylightphase_Mi_to_cie_recommended=None, cieobs=None, cct_mode=None, avg=None, rf_from_avg_rounded_rfi=None, scale=None, opt_scale_factor=False, cspace=None, catf=None, cri_specific_pars=None, rg_pars=None, fit_gamut_ellipse=False, interp_settings=None)[source]

Calculates the color rendering fidelity index, Rf, of spectral data.

Args:
St:
ndarray with spectral data
(can be multiple SPDs, first axis are the wavelengths)
out:
‘Rf’ or str, optional
Specifies requested output (e.g. ‘Rf,cct,duv’)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the SPDs to.
None: default to no interpolation
cri_type:
_CRI_TYPE_DEFAULT or str or dict, optional
-‘str: specifies dict with default cri model parameters
(for supported types, see luxpy.cri._CRI_DEFAULTS[‘cri_types’])
- dict: user defined model parameters
(see e.g. luxpy.cri._CRI_DEFAULTS[‘cierf’]
for required structure)
Note that any non-None input arguments to the function will
override default values in cri_type dict.
sampleset:
None or ndarray or str, optional
Specifies set of spectral reflectance samples for cri calculations.
- None defaults to standard set for metric in cri_type.
- ndarray: user defined set of spectral reflectance functions
(.shape = (N+1, number of wavelengths);
first axis are wavelengths)
ref_type:
None or str or ndarray, optional
Specifies type of reference illuminant type.
- None: defaults to metric_specific reference illuminant in
accordance with cri_type.
- str: ‘BB’ : Blackbody radiatiors,
‘DL’: daylightphase,
‘ciera’: used in CIE CRI-13.3-1995,
‘cierf’: used in CIE 224-2017,
‘iesrf’: used in TM30-15, …
- ndarray: user defined reference SPD
calculation_wavelength_range:
None or list, optional
Specifies the range outside of which all values of the SPD will be dropped in the calculations.
round_daylightphase_Mi_to_cie_recommended:
None or bool, optional
Round M1, M2 values to 3 decimals as recommended by CIE (not that TM30 does not do this, which gives slight errors when calculating a daylight phase (equivalent of around 0.75 K for 6500 K illuminant))
cieobs:
None or dict, optional
Specifies which CMF sets to use for the calculation of the sample
XYZs and the CCT (for reference illuminant calculation).
None defaults to the one specified in :cri_type: dict.
- key: ‘xyz’: str specifying CMF set for calculating xyz
of samples and white
- key: ‘cct’: str specifying CMF set for calculating cct
cct_mode:
None or str or (str, dict), optional
Specifies which mode to use when calculating xyz_to_cct().
If tuple: second element is dict with additional kwargs for xyz_to_cct
cspace:
None or dict, optional
Specifies which color space to use.
None defaults to the one specified in :cri_type: dict.
- key: ‘type’: str specifying color space used to calculate
color differences in.
- key: ‘xyzw’: None or ndarray with white point of color space
If None: use xyzw of test / reference (after chromatic
adaptation, if specified)
- other keys specify other possible parameters needed for color
space calculation,
see lx.cri._CRI_DEFAULTS[‘iesrf’][‘cspace’] for details.
catf:
None or dict, optional
Perform explicit CAT before converting to color space coordinates.
- None: don’t apply a cat (other than perhaps the one built
into the colorspace)
- dict: with CAT parameters:
- key: ‘D’: ndarray with degree of adaptation
- key: ‘mcat’: ndarray with sensor matrix specification
- key: ‘xyzw’: None or ndarray with white point
None: use xyzw of reference otherwise transform both
test and ref to xyzw
cri_specific_pars:
None or dict, optional
Specifies other parameters specific to type of cri
(e.g. maxC for CQS calculations)
- None: default to the one specified in :cri_type: dict.
- dict: user specified parameters.
For its use, see for example:
luxpy.cri._CRI_DEFAULTS[‘mcri’][‘cri_specific_pars’]
rg_pars:
None or dict, optional
Dict containing specifying parameters for slicing the gamut
and calculating hue bin specific indices.
Dict structure:
{‘nhbins’ : None, ‘start_hue’ : 0,
‘normalize_gamut’ : False, ‘normalized_chroma_ref’: 100.0}
- key: ‘nhbins’: int, number of hue bins to slice gamut
(None use the one specified in :cri_type: dict).
- key: ‘start_hue’: float (°), hue at which to start slicing
- key: ‘normalize_gamut’: True or False:
normalize gamut or not before calculating a gamut
area index Rg.
- key: ‘normalized_chroma_ref’: 100.0 or float, optional
Controls the size (chroma/radius)
of the normalization circle/gamut.
- key ‘use_bin_avg_DEi’: True or False
Note that following IES-TM30 DEhj from gamut_slicer()
is obtained by averaging the DEi per hue bin (True),
and NOT by averaging the jabt and jabr per hue bin
and then calculating the DEhj (False).
avg:
None or fcn handle, optional
Averaging function (handle) for color differences, DEi
(e.g. numpy.mean, .math.rms, .math.geomean)
None use the one specified in :cri_type: dict.
rf_from_avg_rounded_rfi:
None, optional
If None: use as specified in the :cri_type: dict
If False: calculate Rf directly from DEa.
If True: round Rfi to integer numbers and average them to Rf
(method used in CIE-13.3-1995 Ra calculation)
scale:
None or dict, optional
Specifies scaling of color differences to obtain CRI.
- None use the one specified in :cri_type: dict.
- dict: user specified dict with scaling parameters.
- key: ‘fcn’: function handle to type of cri scale,
e.g.
* linear_scale –> (100 - scale_factor*DEi),
* log_scale –> (cfr. Ohno’s CQS),
* psy_scale (Smet et al.’s cri2012,See: LRT 2013)
- key: ‘cfactor’: factors used in scaling function,
If None:
Scaling factor value(s) will be optimized to
minimize the rms between the Rf’s of the
requested metric and the target metric specified
in:

- key: ‘opt_cri_type’: str
* str: one of the preset _CRI_DEFAULTS
* dict: user speciied
(dict must contain all keys as normal)
Note that if key not in :scale: dict,
then ‘opt_cri_type’ is added with default
setting = ‘ciera’.
- key: ‘opt_spd_set’: ndarray with set of light
source spds used to optimize cfactor.
Note that if key not in :scale: dict,
then default = ‘F1-F12’.
opt_scale_factor:
True or False, optional
True: optimize scaling-factor, else do nothing and use value of
scaling-factor in :scale: dict.
fit_gamut_ellipse:
fit ellipse to normalized color gamut
(extract from function using out; also stored in hue_bin_data[‘gamut_ellipse_fit’])
Returns:
returns:
float or ndarray with Rf for :out: ‘Rf’
Other output is also possible by changing the :out: str value.
E.g. out == ‘Rg,data’ would output an ndarray with Rf values

and a dictionary :data: with keys:

- ‘St, Sr’ : ndarray of test SPDs and corresponding ref. illuminants.
- ‘xyz_cct’: xyz of white point calculate with cieobs defined for cct calculations in cri_type[‘cieobs’]
- ‘cct, duv’: CCT and Duv obtained with cieobs in cri_type[‘cieobs’][‘cct’]
- ‘xyzti, xyzri’: ndarray tristimulus values of test and ref. samples (obtained with with cieobs in cri_type[‘cieobs’][‘xyz’])
- ‘xyztw, xyzrw’: ndarray tristimulus values of test and ref. white points (obtained with with cieobs in cri_type[‘cieobs’][‘xyz’])
- ‘DEi, DEa’: ndarray with individual sample color differences DEi and average DEa between test and ref.
- ‘Rf’ : ndarray with general color fidelity index values
- ‘Rg’ : ndarray with color gamut area index values
- ‘Rfi’ : ndarray with specific (sample) color fidelity indices
- ‘Rfhj’ : ndarray with local (hue binned) fidelity indices
- ‘DEhj’ : ndarray with local (hue binned) color differences
- ‘Rcshj’: ndarray with local chroma shifts indices
- ‘Rhshj’: ndarray with local hue shifts indices
- ‘hue_bin_data’: dict with output from _get_hue_bin_data() [see its help for more info]
- ‘cri_type’: same as input (for reference purposes)
References:

1. IES TM30, Method for Evaluating Light Source Color Rendition. New York, NY: The Illuminating Engineering Society of North America.

2. A. David, P. T. Fini, K. W. Houser, Y. Ohno, M. P. Royer, K. A. G. Smet, M. Wei, and L. Whitehead, “Development of the IES method for evaluating the color rendition of light sources,” Opt. Express, vol. 23, no. 12, pp. 15888–15906, 2015.

3. CIE224:2017. CIE 2017 Colour Fidelity Index for accurate scientific use. Vienna, Austria: CIE. (2017).

4. Smet, K., Schanda, J., Whitehead, L., & Luo, R. (2013). CRI2012: A proposal for updating the CIE colour rendering index. Lighting Research and Technology, 45, 689–709.

5. CIE13.3-1995. Method of Measuring and Specifying Colour Rendering Properties of Light Sources (Vol. CIE13.3-19). Vienna, Austria: CIE. (1995).

luxpy.color.cri._hue_bin_data_to_rxhj(hue_bin_data, cri_type='ies-tm30', scale_factor=None, scale_fcn=None, use_bin_avg_DEi=True)[source]

Calculate hue bin measures: Rcshj, Rhshj, Rfhj, DEhj.

Rcshj: local chroma shift
Rhshj: local hue shift
Rfhj: local (hue bin) color fidelity
DEhj: local (hue bin) color differences

(See IES TM30)
Args:
hue_bin_data:
Dict with hue bin data obtained with _get_hue_bin_data().
use_bin_avg_DEi:
True, optional
Note that following IES-TM30 DEhj from gamut_slicer() is obtained by
averaging the DEi per hue bin (True), and NOT by averaging the
jabt and jabr per hue bin and then calculating the DEhj (False).
If None: use value in rg_pars dict in cri_type dict!
scale_fcn:
function handle to type of cri scale,
e.g.
* linear()_scale –> (100 - scale_factor*DEi),
* log_scale –> (cfr. Ohno’s CQS),
* psy_scale (Smet et al.’s cri2012,See: LRT 2013)
scale_factor:
factors used in scaling function
Returns:
returns:
ndarrays of Rcshj, Rhshj, Rfhj, DEhj
References:

1. IES TM30, Method for Evaluating Light Source Color Rendition. New York, NY: The Illuminating Engineering Society of North America.

luxpy.color.cri._hue_bin_data_to_rfi(hue_bin_data=None, cri_type='ies-tm30', scale_factor=None, scale_fcn=None)[source]

Get sample color differences DEi and calculate color fidelity values Rfi.

Rfi: Sample color fidelity
DEi: Sample color differences

(See IES TM30)
Args:
hue_bin_data:
Dict with hue bin data obtained with _get_hue_bin_data().
scale_fcn:
function handle to type of cri scale,
e.g.
* linear()_scale –> (100 - scale_factor*DEi),
* log_scale –> (cfr. Ohno’s CQS),
* psy_scale (Smet et al.’s cri2012,See: LRT 2013)
scale_factor:
factors used in scaling function
Returns:
returns:
ndarrays of Rfi, DEi
References:

1. IES TM30, Method for Evaluating Light Source Color Rendition. New York, NY: The Illuminating Engineering Society of North America.

luxpy.color.cri._hue_bin_data_to_rg(hue_bin_data, max_scale=100, normalize_gamut=False)[source]

Calculates gamut area index, Rg.

Args:
hue_bin_data:
Dict with hue bin data obtained with _get_hue_bin_data().
max_scale:
100.0, optional
Value of Rg when Rf = max_scale (i.e. DEavg = 0)
normalize_gamut:
False, optional
True normalizes the gamut of test to that of ref.
(perfect agreement results in circle).
out:
‘Rg’, optional
Specifies which variables to output as ndarray
Returns:
Rg:
float or ndarray with gamut area indices Rg.
luxpy.color.cri.spd_to_ciera(SPD, out='Rf', wl=None, interp_settings=None)[source]

Wrapper function the ‘ciera’ color rendition (fidelity) metric (CIE 13.3-1995).

Args:
SPD:
ndarray with spectral data
(can be multiple SPDs, first axis are the wavelengths)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate :SPD: to.
None: default to no interpolation
out:
‘Rf’ or str, optional
Specifies requested output (e.g. ‘Rf,Rfi,cct,duv’)
Returns:
returns:
float or ndarray with CIE13.3 Ra for :out: ‘Rf’
Other output is also possible by changing the :out: str value.
References:

1. CIE13.3-1995. Method of Measuring and Specifying Colour Rendering Properties of Light Sources (Vol. CIE13.3-19). Vienna, Austria: CIE. (1995).

luxpy.color.cri.spd_to_cierf(SPD, out='Rf', wl=None, interp_settings=None)[source]

Wrapper function the ‘cierf’ color rendition (fidelity) metric (CIE224-2017).

Args:
SPD:
ndarray with spectral data (can be multiple SPDs,
first axis are the wavelengths)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate :SPD: to.
None: default to no interpolation
out:
‘Rf’ or str, optional
Specifies requested output (e.g. ‘Rf,Rfi,cct,duv’)
Returns:
returns:
float or ndarray with CIE224-2017 Rf for :out: ‘Rf’
Other output is also possible by changing the :out: str value.
References:

1. CIE224:2017. CIE 2017 Colour Fidelity Index for accurate scientific use. Vienna, Austria: CIE. (2017).

luxpy.color.cri.spd_to_ciera_133_1995(SPD, out='Rf', wl=None, interp_settings=None)

Wrapper function the ‘ciera’ color rendition (fidelity) metric (CIE 13.3-1995).

Args:
SPD:
ndarray with spectral data
(can be multiple SPDs, first axis are the wavelengths)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate :SPD: to.
None: default to no interpolation
out:
‘Rf’ or str, optional
Specifies requested output (e.g. ‘Rf,Rfi,cct,duv’)
Returns:
returns:
float or ndarray with CIE13.3 Ra for :out: ‘Rf’
Other output is also possible by changing the :out: str value.
References:

1. CIE13.3-1995. Method of Measuring and Specifying Colour Rendering Properties of Light Sources (Vol. CIE13.3-19). Vienna, Austria: CIE. (1995).

luxpy.color.cri.spd_to_cierf_224_2017(SPD, out='Rf', wl=None, interp_settings=None)

Wrapper function the ‘cierf’ color rendition (fidelity) metric (CIE224-2017).

Args:
SPD:
ndarray with spectral data (can be multiple SPDs,
first axis are the wavelengths)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate :SPD: to.
None: default to no interpolation
out:
‘Rf’ or str, optional
Specifies requested output (e.g. ‘Rf,Rfi,cct,duv’)
Returns:
returns:
float or ndarray with CIE224-2017 Rf for :out: ‘Rf’
Other output is also possible by changing the :out: str value.
References:

1. CIE224:2017. CIE 2017 Colour Fidelity Index for accurate scientific use. Vienna, Austria: CIE. (2017).

luxpy.color.cri.spd_to_iesrf(SPD, out='Rf', wl=None, cri_type='iesrf-tm30-20', interp_settings=None)

Wrapper function for the ‘iesrf’ color fidelity index (IES TM30-20 = TM30-18).

Args:
SPD:
ndarray with spectral data (can be multiple SPDs,
first axis are the wavelengths)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the SPDs to.
None: default to no interpolation
out:
‘Rf’ or str, optional
Specifies requested output (e.g. ‘Rf,Rfi,cct,duv’)
Returns:
returns:
float or ndarray with IES TM30-20 Rf for :out: ‘Rf’
Other output is also possible by changing the :out: str value.
References:

1. IES TM30 (99, 4880 spectrally uniform samples)

2. A. David, P. T. Fini, K. W. Houser, Y. Ohno, M. P. Royer, K. A. G. Smet, M. Wei, and L. Whitehead, “Development of the IES method for evaluating the color rendition of light sources,” Opt. Express, vol. 23, no. 12, pp. 15888–15906, 2015.

3. K. A. G. Smet, A. David, and L. Whitehead, “Why color space uniformity and sample set spectral uniformity are essential for color rendering measures,” LEUKOS, vol. 12, no. 1–2, pp. 39–50, 2016

luxpy.color.cri.spd_to_iesrg(SPD, out='Rg', wl=None, cri_type='iesrf-tm30-20', interp_settings=None)

Wrapper function for the ‘spd_to_rg’ color gamut area index (IES TM30-18 = TM30-20).

Args:
SPD:
ndarray with spectral data (can be multiple SPDs,
first axis are the wavelengths)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the SPDs to.
None: default to no interpolation
out:
‘Rg’ or str, optional
Specifies requested output (e.g. ‘Rg,Rf,Rfi,cct,duv’)
Returns:
returns:
float or ndarray with IES TM30-20 Rg for :out: ‘Rg’
Other output is also possible by changing the :out: str value.
References:

1. IES TM30 (99, 4880 spectrally uniform samples)

2. A. David, P. T. Fini, K. W. Houser, Y. Ohno, M. P. Royer, K. A. G. Smet, M. Wei, and L. Whitehead, “Development of the IES method for evaluating the color rendition of light sources,” Opt. Express, vol. 23, no. 12, pp. 15888–15906, 2015.

3. K. A. G. Smet, A. David, and L. Whitehead, “Why color space uniformity and sample set spectral uniformity are essential for color rendering measures,” LEUKOS, vol. 12, no. 1–2, pp. 39–50, 2016

luxpy.color.cri.spd_to_iesrf_tm30(SPD, out='Rf', wl=None, cri_type='iesrf-tm30-20', interp_settings=None)

Wrapper function for the ‘iesrf’ color fidelity index (IES TM30-20 = TM30-18).

Args:
SPD:
ndarray with spectral data (can be multiple SPDs,
first axis are the wavelengths)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the SPDs to.
None: default to no interpolation
out:
‘Rf’ or str, optional
Specifies requested output (e.g. ‘Rf,Rfi,cct,duv’)
Returns:
returns:
float or ndarray with IES TM30-20 Rf for :out: ‘Rf’
Other output is also possible by changing the :out: str value.
References:

1. IES TM30 (99, 4880 spectrally uniform samples)

2. A. David, P. T. Fini, K. W. Houser, Y. Ohno, M. P. Royer, K. A. G. Smet, M. Wei, and L. Whitehead, “Development of the IES method for evaluating the color rendition of light sources,” Opt. Express, vol. 23, no. 12, pp. 15888–15906, 2015.

3. K. A. G. Smet, A. David, and L. Whitehead, “Why color space uniformity and sample set spectral uniformity are essential for color rendering measures,” LEUKOS, vol. 12, no. 1–2, pp. 39–50, 2016

luxpy.color.cri.spd_to_iesrg_tm30(SPD, out='Rg', wl=None, cri_type='iesrf-tm30-20', interp_settings=None)

Wrapper function for the ‘spd_to_rg’ color gamut area index (IES TM30-18 = TM30-20).

Args:
SPD:
ndarray with spectral data (can be multiple SPDs,
first axis are the wavelengths)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the SPDs to.
None: default to no interpolation
out:
‘Rg’ or str, optional
Specifies requested output (e.g. ‘Rg,Rf,Rfi,cct,duv’)
Returns:
returns:
float or ndarray with IES TM30-20 Rg for :out: ‘Rg’
Other output is also possible by changing the :out: str value.
References:

1. IES TM30 (99, 4880 spectrally uniform samples)

2. A. David, P. T. Fini, K. W. Houser, Y. Ohno, M. P. Royer, K. A. G. Smet, M. Wei, and L. Whitehead, “Development of the IES method for evaluating the color rendition of light sources,” Opt. Express, vol. 23, no. 12, pp. 15888–15906, 2015.

3. K. A. G. Smet, A. David, and L. Whitehead, “Why color space uniformity and sample set spectral uniformity are essential for color rendering measures,” LEUKOS, vol. 12, no. 1–2, pp. 39–50, 2016

luxpy.color.cri.spd_to_iesrf_tm30_15(SPD, out='Rf', wl=None, cri_type='iesrf-tm30-15', interp_settings=None)[source]

Wrapper function for the ‘iesrf’ color fidelity index (IES TM30-15).

Args:
SPD:
ndarray with spectral data (can be multiple SPDs,
first axis are the wavelengths)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the SPDs to.
None: default to no interpolation
out:
‘Rf’ or str, optional
Specifies requested output (e.g. ‘Rf,Rfi,cct,duv’)
Returns:
returns:
float or ndarray with IES TM30-15 Rf for :out: ‘Rf’
Other output is also possible by changing the :out: str value.
References:

1. IES TM30 (99, 4880 spectrally uniform samples)

2. A. David, P. T. Fini, K. W. Houser, Y. Ohno, M. P. Royer, K. A. G. Smet, M. Wei, and L. Whitehead, “Development of the IES method for evaluating the color rendition of light sources,” Opt. Express, vol. 23, no. 12, pp. 15888–15906, 2015.

3. K. A. G. Smet, A. David, and L. Whitehead, “Why color space uniformity and sample set spectral uniformity are essential for color rendering measures,” LEUKOS, vol. 12, no. 1–2, pp. 39–50, 2016

luxpy.color.cri.spd_to_iesrg_tm30_15(SPD, out='Rg', wl=None, cri_type='iesrf-tm30-15', interp_settings=None)[source]

Wrapper function for the ‘spd_to_rg’ color gamut area index (IES TM30-15).

Args:
SPD:
ndarray with spectral data (can be multiple SPDs,
first axis are the wavelengths)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the SPDs to.
None: default to no interpolation
out:
‘Rg’ or str, optional
Specifies requested output (e.g. ‘RgRf,Rfi,cct,duv’)
Returns:
returns:
float or ndarray with IES TM30-15 Rg for :out: ‘Rg’
Other output is also possible by changing the :out: str value.
References:

1. IES TM30 (99, 4880 spectrally uniform samples)

2. A. David, P. T. Fini, K. W. Houser, Y. Ohno, M. P. Royer, K. A. G. Smet, M. Wei, and L. Whitehead, “Development of the IES method for evaluating the color rendition of light sources,” Opt. Express, vol. 23, no. 12, pp. 15888–15906, 2015.

3. K. A. G. Smet, A. David, and L. Whitehead, “Why color space uniformity and sample set spectral uniformity are essential for color rendering measures,” LEUKOS, vol. 12, no. 1–2, pp. 39–50, 2016

luxpy.color.cri.spd_to_iesrf_tm30_18(SPD, out='Rf', wl=None, cri_type='iesrf-tm30-18', interp_settings=None)[source]

Wrapper function for the ‘iesrf’ color fidelity index (IES TM30-18).

Args:
SPD:
ndarray with spectral data (can be multiple SPDs,
first axis are the wavelengths)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the SPDs to.
None: default to no interpolation
out:
‘Rf’ or str, optional
Specifies requested output (e.g. ‘Rf,Rfi,cct,duv’)
Returns:
returns:
float or ndarray with IES TM30-18 Rf for :out: ‘Rf’
Other output is also possible by changing the :out: str value.
References:

1. IES TM30 (99, 4880 spectrally uniform samples)

2. A. David, P. T. Fini, K. W. Houser, Y. Ohno, M. P. Royer, K. A. G. Smet, M. Wei, and L. Whitehead, “Development of the IES method for evaluating the color rendition of light sources,” Opt. Express, vol. 23, no. 12, pp. 15888–15906, 2015.

3. K. A. G. Smet, A. David, and L. Whitehead, “Why color space uniformity and sample set spectral uniformity are essential for color rendering measures,” LEUKOS, vol. 12, no. 1–2, pp. 39–50, 2016

luxpy.color.cri.spd_to_iesrg_tm30_18(SPD, out='Rg', wl=None, cri_type='iesrf-tm30-18', interp_settings=None)[source]

Wrapper function for the ‘spd_to_rg’ color gamut area index (IES TM30-18).

Args:
SPD:
ndarray with spectral data (can be multiple SPDs,
first axis are the wavelengths)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the SPDs to.
None: default to no interpolation
out:
‘Rg’ or str, optional
Specifies requested output (e.g. ‘Rg,Rf,Rfi,cct,duv’)
Returns:
returns:
float or ndarray with IES TM30-18 Rg for :out: ‘Rg’
Other output is also possible by changing the :out: str value.
References:

1. IES TM30 (99, 4880 spectrally uniform samples)

2. A. David, P. T. Fini, K. W. Houser, Y. Ohno, M. P. Royer, K. A. G. Smet, M. Wei, and L. Whitehead, “Development of the IES method for evaluating the color rendition of light sources,” Opt. Express, vol. 23, no. 12, pp. 15888–15906, 2015.

3. K. A. G. Smet, A. David, and L. Whitehead, “Why color space uniformity and sample set spectral uniformity are essential for color rendering measures,” LEUKOS, vol. 12, no. 1–2, pp. 39–50, 2016

luxpy.color.cri.spd_to_iesrf_tm30_20(SPD, out='Rf', wl=None, cri_type='iesrf-tm30-20', interp_settings=None)[source]

Wrapper function for the ‘iesrf’ color fidelity index (IES TM30-20 = TM30-18).

Args:
SPD:
ndarray with spectral data (can be multiple SPDs,
first axis are the wavelengths)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the SPDs to.
None: default to no interpolation
out:
‘Rf’ or str, optional
Specifies requested output (e.g. ‘Rf,Rfi,cct,duv’)
Returns:
returns:
float or ndarray with IES TM30-20 Rf for :out: ‘Rf’
Other output is also possible by changing the :out: str value.
References:

1. IES TM30 (99, 4880 spectrally uniform samples)

2. A. David, P. T. Fini, K. W. Houser, Y. Ohno, M. P. Royer, K. A. G. Smet, M. Wei, and L. Whitehead, “Development of the IES method for evaluating the color rendition of light sources,” Opt. Express, vol. 23, no. 12, pp. 15888–15906, 2015.

3. K. A. G. Smet, A. David, and L. Whitehead, “Why color space uniformity and sample set spectral uniformity are essential for color rendering measures,” LEUKOS, vol. 12, no. 1–2, pp. 39–50, 2016

luxpy.color.cri.spd_to_iesrg_tm30_20(SPD, out='Rg', wl=None, cri_type='iesrf-tm30-20', interp_settings=None)[source]

Wrapper function for the ‘spd_to_rg’ color gamut area index (IES TM30-18 = TM30-20).

Args:
SPD:
ndarray with spectral data (can be multiple SPDs,
first axis are the wavelengths)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the SPDs to.
None: default to no interpolation
out:
‘Rg’ or str, optional
Specifies requested output (e.g. ‘Rg,Rf,Rfi,cct,duv’)
Returns:
returns:
float or ndarray with IES TM30-20 Rg for :out: ‘Rg’
Other output is also possible by changing the :out: str value.
References:

1. IES TM30 (99, 4880 spectrally uniform samples)

2. A. David, P. T. Fini, K. W. Houser, Y. Ohno, M. P. Royer, K. A. G. Smet, M. Wei, and L. Whitehead, “Development of the IES method for evaluating the color rendition of light sources,” Opt. Express, vol. 23, no. 12, pp. 15888–15906, 2015.

3. K. A. G. Smet, A. David, and L. Whitehead, “Why color space uniformity and sample set spectral uniformity are essential for color rendering measures,” LEUKOS, vol. 12, no. 1–2, pp. 39–50, 2016

luxpy.color.cri.spd_to_cri2012(SPD, out='Rf', wl=None, interp_settings=None)[source]

Wrapper function for the ‘cri2012’ color rendition (fidelity) metric with the spectally uniform HL17 mathematical sampleset.

Args:
SPD:
ndarray with spectral data (can be multiple SPDs,
first axis are the wavelengths)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the SPDs to.
None: default to no interpolation
out:
‘Rf’ or str, optional
Specifies requested output (e.g. ‘Rf,Rfi,cct,duv’)
Returns:
returns:
float or ndarray with CRI2012 Rf for :out: ‘Rf’
Other output is also possible by changing the :out: str value.
References:
..[1] Smet, K., Schanda, J., Whitehead, L., & Luo, R. (2013).

CRI2012: A proposal for updating the CIE colour rendering index. Lighting Research and Technology, 45, 689–709. Retrieved from http://lrt.sagepub.com/content/45/6/689

luxpy.color.cri.spd_to_cri2012_hl17(SPD, out='Rf', wl=None, interp_settings=None)[source]

Wrapper function for the ‘cri2012’ color rendition (fidelity) metric with the spectally uniform HL17 mathematical sampleset.

Args:
SPD:
ndarray with spectral data (can be multiple SPDs,
first axis are the wavelengths)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the SPDs to.
None: default to no interpolation
out:
‘Rf’ or str, optional
Specifies requested output (e.g. ‘Rf,Rfi,cct,duv’)
Returns:
returns:
float or ndarray with CRI2012 Rf for :out: ‘Rf’
Other output is also possible by changing the :out: str value.
Reference:

1. Smet, K., Schanda, J., Whitehead, L., & Luo, R. (2013). CRI2012: A proposal for updating the CIE colour rendering index. Lighting Research and Technology, 45, 689–709.

luxpy.color.cri.spd_to_cri2012_hl1000(SPD, out='Rf', wl=None, interp_settings=None)[source]

Wrapper function for the ‘cri2012’ color rendition (fidelity) metric with the spectally uniform Hybrid HL1000 sampleset.

Args:
SPD:
ndarray with spectral data (can be multiple SPDs,
first axis are the wavelengths)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the SPDs to.
None: default to no interpolation
out:
‘Rf’ or str, optional
Specifies requested output (e.g. ‘Rf,Rfi,cct,duv’)
Returns:
returns:
float or ndarray with CRI2012 Rf for :out: ‘Rf’
Other output is also possible by changing the :out: str value.
Reference:

1. Smet, K., Schanda, J., Whitehead, L., & Luo, R. (2013). CRI2012: A proposal for updating the CIE colour rendering index. Lighting Research and Technology, 45, 689–709.

luxpy.color.cri.spd_to_cri2012_real210(SPD, out='Rf', wl=None, interp_settings=None)[source]

Wrapper function the ‘cri2012’ color rendition (fidelity) metric with the Real-210 sampleset (normally for special color rendering indices).

Args:
SPD:
ndarray with spectral data (can be multiple SPDs,
first axis are the wavelengths)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the SPDs to.
None: default to no interpolation
out:
‘Rf’ or str, optional
Specifies requested output (e.g. ‘Rf,Rfi,cct,duv’)
Returns:
returns:
float or ndarray with CRI2012 Rf for :out: ‘Rf’
Other output is also possible by changing the :out: str value.
Reference:

1. Smet, K., Schanda, J., Whitehead, L., & Luo, R. (2013). CRI2012: A proposal for updating the CIE colour rendering index. Lighting Research and Technology, 45, 689–709.

luxpy.color.cri.spd_to_mcri(SPD, D=0.9, E=None, Yb=20.0, out='Rm', wl=None, mcri_defaults=None, interp_settings=None)[source]

Calculates the MCRI or Memory Color Rendition Index, Rm

Args:
SPD:
ndarray with spectral data (can be multiple SPDs,
first axis are the wavelengths)
D:
0.9, optional
Degree of adaptation.
E:
None, optional
Illuminance in lux
(used to calculate La = (Yb/100)*(E/pi) to then calculate D
following the ‘cat02’ model).
If None: the degree is determined by :D:
If (:E: is not None) & (:Yb: is None): :E: is assumed to contain
the adapting field luminance La (cd/m²).
Yb:
20.0, optional
Luminance factor of background. (used when calculating La from E)
If None, E contains La (cd/m²).
out:
‘Rm’ or str, optional
Specifies requested output (e.g. ‘Rm,Rmi,cct,duv’)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the SPDs to.
None: default to no interpolation
mcri_defaults:
None, optional
Dictionary with structure of _MCRI_DEFAULTS containing everything
needed to calculate MCRI.
If None: _MCRI_DEFAULTS is used.
Returns:
returns:
float or ndarray with MCRI Rm for :out: ‘Rm’
Other output is also possible by changing the :out: str value.
References:

1. K.A.G. Smet, W.R. Ryckaert, M.R. Pointer, G. Deconinck, P. Hanselaer,(2012) “A memory colour quality metric for white light sources,” Energy Build., vol. 49, no. C, pp. 216–225.

luxpy.color.cri.spd_to_cqs(SPD, version='v9.0', out='Qa', wl=None, interp_settings=None)[source]

Calculates CQS Qa (Qai) or Qf (Qfi) or Qp (Qpi) for versions v9.0 or v7.5.

Args:
SPD:
ndarray with spectral data (can be multiple SPDs,
first axis are the wavelengths)
version:
‘v9.0’ or ‘v7.5’, optional
out:
‘Qa’ or str, optional
Specifies requested output (e.g. ‘Qa,Qai,Qf,cct,duv’)
wl:
None, optional
Wavelengths (or [start, end, spacing]) to interpolate the SPDs to.
None: default to no interpolation
Returns:
returns:
float or ndarray with CQS Qa for :out: ‘Qa’
Other output is also possible by changing the :out: str value.
References:

1. W. Davis and Y. Ohno, “Color quality scale,” (2010), Opt. Eng., vol. 49, no. 3, pp. 33602–33616.

luxpy.color.cri.spd_to_fci(spd, use_cielab=True)[source]

Calculate Feeling of Contrast Index (FCI).

Args:
spd:
ndarray with spectral power distribution(s) of the test light source(s).
use_cielab:
True, optional
True: use original formulation of FCI, which adopts a CIECAT94
chromatic adaptation transform followed by a conversion to
CIELAB coordinates before calculating the gamuts.
False: use CIECAM02 coordinates and embedded CAT02 transform.
Returns:
fci:
ndarray with FCI values.
References:

1. Hashimoto, K., Yano, T., Shimizu, M., & Nayatani, Y. (2007). New method for specifying color-rendering properties of light sources based on feeling of contrast. Color Research and Application, 32(5), 361–371.

luxpy.color.cri.spd_to_thornton_cpi(spd, interp_settings=None)[source]

Calculate Thornton’s Color Preference Index (CPI).

Args:
spd:
nd array with spectral power distribution(s) of the test light source(s).
Returns:
cpi:
ndarray with CPI values.
Reference:

1. Thornton, W. A. (1974). A Validation of the Color-Preference Index. Journal of the Illuminating Engineering Society, 4(1), 48–52.

luxpy.color.cri.plot_hue_bins(hbins=16, start_hue=0.0, scalef=100, plot_axis_labels=False, bin_labels='#', plot_edge_lines=True, plot_center_lines=False, plot_bin_colors=True, plot_10_20_circles=False, axtype='polar', ax=None, force_CVG_layout=False, hbin_color_map=None)[source]

Makes basis plot for Color Vector Graphic (CVG).

Args:
hbins:
16 or ndarray with sorted hue bin centers (°), optional
start_hue:
0.0, optional
scalef:
100, optional
Scale factor for graphic.
plot_axis_labels:
False, optional
Turns axis ticks on/off (True/False).
bin_labels:
None or list[str] or ‘#’, optional
Plots labels at the bin center hues.
- None: don’t plot.
- list[str]: list with str for each bin.
(len(:bin_labels:) = :nhbins:)
- ‘#’: plots number.
plot_edge_lines:
True or False, optional
Plot grey bin edge lines with ‘–‘.
plot_center_lines:
False or True, optional
Plot colored lines at ‘center’ of hue bin.
plot_bin_colors:
True, optional
Colorize hue bins.
plot_10_20_circles:
False, optional
If True and :axtype: == ‘cart’: Plot white circles at
80%, 90%, 100%, 110% and 120% of :scalef:
axtype:
‘polar’ or ‘cart’, optional
Make polar or Cartesian plot.
ax:
None or ‘new’ or ‘same’, optional
- None or ‘new’ creates new plot
- ‘same’: continue plot on same axes.
- axes handle: plot on specified axes.
force_CVG_layout:
False or True, optional
True: Force plot of basis of CVG on first encounter.
hbin_color_map:
ndarray with predefined RGB color map
If None or hbin_color_map.shape[0]<nhbins: cmap will be created, else use values in ndarray.
Returns:
returns:
gcf(), gca(), list with rgb colors for hue bins (for use in other plotting fcns)
luxpy.color.cri.plot_ColorVectorGraphic(jabt, jabr, hbins=16, start_hue=0.0, scalef=100, plot_axis_labels=False, bin_labels=None, plot_edge_lines=True, plot_center_lines=False, plot_bin_colors=True, plot_10_20_circles=True, plot_vectors=True, gamut_line_color=None, gamut_line_style='-', gamut_line_marker='o', gamut_line_label=None, axtype='polar', ax=None, force_CVG_layout=False, hbin_color_map=None, hvector_color_map=None, jabti=None, jabri=None, hbinnr=None)[source]

Plot Color Vector Graphic (CVG).

Args:
jabt:
ndarray with jab data under test SPD
jabr:
ndarray with jab data under reference SPD
hbins:
16 or ndarray with sorted hue bin centers (°), optional
start_hue:
0.0, optional
scalef:
100, optional
Scale factor for graphic.
plot_axis_labels:
False, optional
Turns axis ticks on/off (True/False).
bin_labels:
None or list[str] or ‘#’, optional
Plots labels at the bin center hues.
- None: don’t plot.
- list[str]: list with str for each bin.
(len(:bin_labels:) = :nhbins:)
- ‘#’: plots number.
plot_edge_lines:
True or False, optional
Plot grey bin edge lines with ‘–‘.
plot_center_lines:
False or True, optional
Plot colored lines at ‘center’ of hue bin.
plot_bin_colors:
True, optional
Colorize hue-bins.
plot_10_20_circles:
True, optional
If True and :axtype: == ‘cart’: Plot white circles at
80%, 90%, 100%, 110% and 120% of :scalef:
plot_vectors:
True, optional
True: plot vectors from reference to test colors.
gamut_line_color:
‘grey’, optional
Color to plot the test color gamut in.
gamut_line_style:
‘-’, optional
Line style to plot the test color gamut in.
gamut_line_marker:
‘o’, optional
Markers to plot the test color gamut points for each hue bin in
(only used when plot_vectors = False).
gamut_line_label:
None, optional
Label for gamut line. (only used when plot_vectors = False).
axtype:
‘polar’ or ‘cart’, optional
Make polar or Cartesian plot.
ax:
None or ‘new’ or ‘same’, optional
- None or ‘new’ creates new plot
- ‘same’: continue plot on same axes.
- axes handle: plot on specified axes.
force_CVG_layout:
False or True, optional
True: Force plot of basis of CVG.
hbin_color_map:
ndarray with predefined RGB color map for the hue bins
If None or hbin_color_map.shape[0]<nhbins: cmap will be created, else use values in ndarray.
hvector_color_map:
ndarray with predefined RGB color map for the color shift vectors in each hue bin.
If None or hvector_color_map.shape[0]<hbins: cmap will be created, else use values in ndarray.
jabti:
None, optional
ndarray with jab data of all samples under test SPD (scaled to ‘unit’ circle)
If not None: plot chromaticity coordinates of test samples relative to
the mean chromaticity of the samples under the reference illuminant.
jabri:
None, optional
ndarray with jab data of all samples under reference SPD (scaled to ‘unit’ circle)
Must be supplied when jabti is not None!
hbinnr:
None, optional
ndarray with hue bin number of each sample.
Must be supplied when jabti is not None!
Returns:
returns:
gcf(), gca(), list with rgb colors for hue bins (for use in
other plotting fcns)
luxpy.color.cri.spd_to_ies_tm30_metrics(St, cri_type=None, hbins=16, start_hue=0.0, scalef=100, no_VF_metrics=False, vf_model_type='M6', vf_pcolorshift={'Cref': 40, 'href': array([3.7835e+00, 3.3161e+00, 2.8272e+00, 1.9093e+00, 5.2787e+00, 4.3081e+00, 3.7762e-01, 6.2055e+00, 1.4564e+00, 8.8926e-01]), 'labels': array(['5B', '5BG', '5G', '5GY', '5P', '5PB', '5R', '5RP', '5Y', '5YR'], dtype=object), 'sig': 0.3}, scale_vf_chroma_to_sample_chroma=False, interp_settings=None)[source]

Calculates IES TM30 metrics from spectral data.

Args:
St:
numpy.ndarray with spectral data
cri_type:
None, optional
If None: defaults to cri_type = ‘iesrf’.
Not none values of :hbins:, :start_hue: and :scalef: overwrite
input in cri_type[‘rg_pars’]
hbins:
None or numpy.ndarray with sorted hue bin centers (°), optional
start_hue:
None, optional
scalef:
None, optional
Scale factor for reference circle.
no_VF_metrics:
False, optional
If True: don’t calculate vector-field based metrics.
vf_pcolorshift:
_VF_PCOLORSHIFT or user defined dict, optional
The polynomial models of degree 5 and 6 can be fully specified or
summarized by the model parameters themselved OR by calculating the
dCoverC and dH at resp. 5 and 6 hues. :VF_pcolorshift: specifies
these hues and chroma level.
scale_vf_chroma_to_sample_chroma:
False, optional
Scale chroma of reference and test vf fields such that average of
binned reference chroma equals that of the binned sample chroma
before calculating hue bin metrics.
Returns:
data:
Dictionary with color rendering data:

- ‘St, Sr’ : ndarray of test SPDs and corresponding ref. illuminants.
- ‘xyz_cct’: xyz of white point calculate with cieobs defined for cct calculations in cri_type[‘cieobs’] and cri_type[‘cct_mode’]
- ‘cct, duv’: CCT and Duv obtained with cieobs in cri_type[‘cieobs’][‘cct’] and using mode in cri_type[‘cct_mode’]
- ‘xyzti, xyzri’: ndarray tristimulus values of test and ref. samples (obtained with with cieobs in cri_type[‘cieobs’][‘xyz’])
- ‘xyztw, xyzrw’: ndarray tristimulus values of test and ref. white points (obtained with with cieobs in cri_type[‘cieobs’][‘xyz’])
- ‘DEi, DEa’: ndarray with individual sample color differences DEi and average DEa between test and ref.
- ‘Rf’ : ndarray with general color fidelity index values
- ‘Rg’ : ndarray with color gamut area index values
- ‘Rfi’ : ndarray with specific (sample) color fidelity indices
- ‘Rfhj’ : ndarray with local (hue binned) fidelity indices
- ‘DEhj’ : ndarray with local (hue binned) color differences
- ‘Rcshj’: ndarray with local chroma shifts indices
- ‘Rhshj’: ndarray with local hue shifts indices
- ‘hue_bin_data’: dict with output from _get_hue_bin_data() [see its help for more info]
- ‘cri_type’: same as input (for reference purposes)
- ‘vf’ : dictionary with vector field measures and data. (if no_VF_metrics == False)
Keys:
- ‘Rt’ : ndarray with general metameric uncertainty index Rt
- ‘Rti’ : ndarray with specific metameric uncertainty indices Rti
- ‘Rfhj’ : ndarray with local (hue binned) fidelity indices
obtained from VF model predictions at color space
pixel coordinates
- ‘DEhj’ : ndarray with local (hue binned) color differences
(same as above)
- ‘Rcshj’: ndarray with local chroma shifts indices for vectorfield coordinates
(same as above)
- ‘Rhshj’: ndarray with local hue shifts indicesfor vectorfield coordinates
(same as above)
- ‘Rfi’: ndarray with sample fidelity indices for vectorfield coordinates
(same as above)
- ‘DEi’: ndarray with sample color differences for vectorfield coordinates
(same as above)
- ‘hue_bin_data’: dict with output from _get_hue_bin_data() for vectorfield coordinates
- ‘dataVF’: dictionary with output of cri.VFPX.VF_colorshift_model()
luxpy.color.cri._tm30_process_spd(spd, cri_type='ies-tm30', **kwargs)[source]

Calculate all required parameters for plotting from spd using cri.spd_to_cri()

Args:
spd:
ndarray or dict
If ndarray: single spectral power distribution.
If dict: dictionary with pre-computed parameters.
required keys:
dict_keys([‘St’, ‘Sr’, ‘xyztw_cct’, ‘cct’, ‘duv’,
‘xyzti’, ‘xyztw’, ‘xyzri’, ‘xyzrw’,
‘DEi’, ‘DEa’, ‘Rf’, ‘Rg’,
‘Rcshj’, ‘Rhshj’, ‘Rfhj’, ‘hue_bin_data’])
see cri.spd_to_cri() for more info on parameters.
cri_type:
_CRI_TYPE_DEFAULT or str or dict, optional
-‘str: specifies dict with default cri model parameters
(for supported types, see luxpy.cri._CRI_DEFAULTS[‘cri_types’])
- dict: user defined model parameters
(see e.g. luxpy.cri._CRI_DEFAULTS[‘cierf’]
for required structure)
Note that any non-None input arguments (in kwargs)
to the function will override default values in cri_type dict.
kwargs:
Additional optional keyword arguments,
the same as in cri.spd_to_cri()
Returns:
data:
dictionary with required parameters for plotting functions.
luxpy.color.cri.plot_tm30_cvg(spd, cri_type='ies-tm30', gamut_line_color=None, gamut_line_style='-', gamut_line_marker='o', gamut_line_label=None, plot_vectors=True, plot_index_values=True, axh=None, axtype='cart', show_annexE_priority=True, show_Rcsh1_Rfh1=True, **kwargs)[source]

Plot TM30 Color Vector Graphic (CVG).

Args:
spd:
ndarray or dict
If ndarray: single spectral power distribution.
If dict: dictionary with pre-computed parameters (using _tm30_process_spd()).
required keys:
dict_keys([‘St’, ‘Sr’, ‘xyztw_cct’, ‘cct’, ‘duv’,
‘xyzti’, ‘xyztw’, ‘xyzri’, ‘xyzrw’,
‘DEi’, ‘DEa’, ‘Rf’, ‘Rg’,
‘Rcshj’, ‘Rhshj’, ‘Rfhj’, ‘hue_bin_data’])
see cri.spd_to_cri() for more info on parameters.
cri_type:
_CRI_TYPE_DEFAULT or str or dict, optional
-‘str: specifies dict with default cri model parameters
(for supported types, see luxpy.cri._CRI_DEFAULTS[‘cri_types’])
- dict: user defined model parameters
(see e.g. luxpy.cri._CRI_DEFAULTS[‘cierf’]
for required structure)
Note that any non-None input arguments (in kwargs)
to the function will override default values in cri_type dict.
gamut_line_color:
‘r’, optional
Plotting line style for the line connecting the
average test chromaticity in the hue bins.
None defaults to red (240,80,70)/255 (IES-TM30-20 recommended).
gamut_line_style:
‘-’, optional
Plotting color for the line connecting the
average test chromaticity in the hue bins.
gamut_line_marker:
‘-’, optional
Markers to plot the test color gamut points for each hue bin in
(only used when plot_vectors = False).
gamut_line_label:
None, optional
Label for gamut line. (only used when plot_vectors = False).
plot_vectors:
True, optional
Plot color shift vectors in CVG (True) or not (False).
plot_index_values:
True, optional
Print Rf, Rg, CCT and Duv in corners of CVG (True) or not (False).
If False: turns of potential prints of Rcsh1, Rfh1
and annexE_priority levelels as well. This way this argument can be
easily used to turn off all plotting and printing when graphs are
to be generated with gamuts of multiple sources.
axh:
None, optional
If None: create new figure with single axes, else plot on specified axes.
axtype:
‘cart’ (or ‘polar’), optional
Make Cartesian (default) or polar plot.
show_annexE_priority:
True, optional
Add Annex E priority levels for source.
show_Rcsh1_Rfh1:
True, optional
Add the local chroma shift (%) and the local color fidelity index
for hue bin 1 at the bottom of the graph.
kwargs:
Additional optional keyword arguments,
the same as in cri.spd_to_cri()
Returns:
axh:
handle to figure axes.
data:
dictionary with required parameters for plotting functions.
luxpy.color.cri.plot_tm30_Rfi(spd, cri_type='ies-tm30', axh=None, font_size=11, **kwargs)[source]

Plot Sample Color Fidelity values (Rfi).

Args:
spd:
ndarray or dict
If ndarray: single spectral power distribution.
If dict: dictionary with pre-computed parameters (using _tm30_process_spd()).
required keys:
dict_keys([‘St’, ‘Sr’, ‘xyztw_cct’, ‘cct’, ‘duv’,
‘xyzti’, ‘xyztw’, ‘xyzri’, ‘xyzrw’,
‘DEi’, ‘DEa’, ‘Rf’, ‘Rg’,
‘Rcshj’, ‘Rhshj’, ‘Rfhj’, ‘hue_bin_data’])
see cri.spd_to_cri() for more info on parameters.
cri_type:
_CRI_TYPE_DEFAULT or str or dict, optional
-‘str: specifies dict with default cri model parameters
(for supported types, see luxpy.cri._CRI_DEFAULTS[‘cri_types’])
- dict: user defined model parameters
(see e.g. luxpy.cri._CRI_DEFAULTS[‘cierf’]
for required structure)
Note that any non-None input arguments (in kwargs)
to the function will override default values in cri_type dict.
axh:
None, optional
If None: create new figure with single axes, else plot on specified axes.
font_size:
_TM30_FONT_SIZE, optional
Font size of text, axis labels and axis values.
kwargs:
Additional optional keyword arguments,
the same as in cri.spd_to_cri()
Returns:
axh:
handle to figure axes.
data:
dictionary with required parameters for plotting functions.
luxpy.color.cri.plot_tm30_Rxhj(spd, cri_type='ies-tm30', axh=None, figsize=(6, 15), font_size=11, **kwargs)[source]

Plot Local Chroma Shifts (Rcshj), Local Hue Shifts (Rhshj) and Local Color Fidelity values (Rfhj) (one for each hue-bin).

Args:
spd:
ndarray or dict
If ndarray: single spectral power distribution.
If dict: dictionary with pre-computed parameters (using _tm30_process_spd()).
required keys:
dict_keys([‘St’, ‘Sr’, ‘xyztw_cct’, ‘cct’, ‘duv’,
‘xyzti’, ‘xyztw’, ‘xyzri’, ‘xyzrw’,
‘DEi’, ‘DEa’, ‘Rf’, ‘Rg’,
‘Rcshj’, ‘Rhshj’, ‘Rfhj’, ‘hue_bin_data’])
see cri.spd_to_cri() for more info on parameters.
cri_type:
_CRI_TYPE_DEFAULT or str or dict, optional
-‘str: specifies dict with default cri model parameters
(for supported types, see luxpy.cri._CRI_DEFAULTS[‘cri_types’])
- dict: user defined model parameters
(see e.g. luxpy.cri._CRI_DEFAULTS[‘cierf’]
for required structure)
Note that any non-None input arguments (in kwargs)
to the function will override default values in cri_type dict.
axh:
None, optional
If None: create new figure with single axes, else plot on specified axes.
figsize:
(6,15), optional
Figure size of pyplot figure.
font_size:
_TM30_FONT_SIZE, optional
Font size of text, axis labels and axis values.
kwargs:
Additional optional keyword arguments,
the same as in cri.spd_to_cri()
Returns:
axh:
handle to figure axes.
data:
dictionary with required parameters for plotting functions.
luxpy.color.cri.plot_tm30_Rcshj(spd, cri_type='ies-tm30', axh=None, xlabel=True, y_offset=0, font_size=11, **kwargs)[source]

Plot Local Chroma Shift values (Rcshj) (one for each hue-bin).

Args:
spd:
ndarray or dict
If ndarray: single spectral power distribution.
If dict: dictionary with pre-computed parameters (using _tm30_process_spd()).
required keys:
dict_keys([‘St’, ‘Sr’, ‘xyztw_cct’, ‘cct’, ‘duv’,
‘xyzti’, ‘xyztw’, ‘xyzri’, ‘xyzrw’,
‘DEi’, ‘DEa’, ‘Rf’, ‘Rg’,
‘Rcshj’, ‘Rhshj’, ‘Rfhj’, ‘hue_bin_data’])
see cri.spd_to_cri() for more info on parameters.
cri_type:
_CRI_TYPE_DEFAULT or str or dict, optional
-‘str: specifies dict with default cri model parameters
(for supported types, see luxpy.cri._CRI_DEFAULTS[‘cri_types’])
- dict: user defined model parameters
(see e.g. luxpy.cri._CRI_DEFAULTS[‘cierf’]
for required structure)
Note that any non-None input arguments (in kwargs)
to the function will override default values in cri_type dict.
axh:
None, optional
If None: create new figure with single axes, else plot on specified axes.
xlabel:
True, optional
If False: don’t add label and numbers to x-axis
(useful when plotting plotting all ‘Local Rfhi, Rcshi, Rshhi’
values in 3x1 subplots with ‘shared x-axis’: saves vertical space)
y_offset:
0, optional
text-offset from top of bars in barplot.
font_size:
_TM30_FONT_SIZE, optional
Font size of text, axis labels and axis values.
kwargs:
Additional optional keyword arguments,
the same as in cri.spd_to_cri()
Returns:
axh:
handle to figure axes.
data:
dictionary with required parameters for plotting functions.
luxpy.color.cri.plot_tm30_Rhshj(spd, cri_type='ies-tm30', axh=None, xlabel=True, y_offset=0, font_size=11, **kwargs)[source]

Plot Local Hue Shift values (Rhshj) (one for each hue-bin).

Args:
spd:
ndarray or dict
If ndarray: single spectral power distribution.
If dict: dictionary with pre-computed parameters (using _tm30_process_spd()).
required keys:
dict_keys([‘St’, ‘Sr’, ‘xyztw_cct’, ‘cct’, ‘duv’,
‘xyzti’, ‘xyztw’, ‘xyzri’, ‘xyzrw’,
‘DEi’, ‘DEa’, ‘Rf’, ‘Rg’,
‘Rcshj’, ‘Rhshj’, ‘Rfhj’, ‘hue_bin_data’])
see cri.spd_to_cri() for more info on parameters.
cri_type:
_CRI_TYPE_DEFAULT or str or dict, optional
-‘str: specifies dict with default cri model parameters
(for supported types, see luxpy.cri._CRI_DEFAULTS[‘cri_types’])
- dict: user defined model parameters
(see e.g. luxpy.cri._CRI_DEFAULTS[‘cierf’]
for required structure)
Note that any non-None input arguments (in kwargs)
to the function will override default values in cri_type dict.
axh:
None, optional
If None: create new figure with single axes, else plot on specified axes.
xlabel:
True, optional
If False: don’t add label and numbers to x-axis
(useful when plotting plotting all ‘Local Rfhi, Rcshi, Rshhi’
values in 3x1 subplots with ‘shared x-axis’: saves vertical space)
y_offset:
0, optional
text-offset from top of bars in barplot.
font_size:
_TM30_FONT_SIZE, optional
Font size of text, axis labels and axis values.
kwargs:
Additional optional keyword arguments,
the same as in cri.spd_to_cri()
Returns:
axh:
handle to figure axes.
data:
dictionary with required parameters for plotting functions.
luxpy.color.cri.plot_tm30_Rfhj(spd, cri_type='ies-tm30', axh=None, xlabel=True, y_offset=0, font_size=11, **kwargs)[source]

Plot Local Color Fidelity values (Rfhj) (one for each hue-bin).

Args:
spd:
ndarray or dict
If ndarray: single spectral power distribution.
If dict: dictionary with pre-computed parameters (using _tm30_process_spd()).
required keys:
dict_keys([‘St’, ‘Sr’, ‘xyztw_cct’, ‘cct’, ‘duv’,
‘xyzti’, ‘xyztw’, ‘xyzri’, ‘xyzrw’,
‘DEi’, ‘DEa’, ‘Rf’, ‘Rg’,
‘Rcshj’, ‘Rhshj’, ‘Rfhj’, ‘hue_bin_data’])
see cri.spd_to_cri() for more info on parameters.
cri_type:
_CRI_TYPE_DEFAULT or str or dict, optional
-‘str: specifies dict with default cri model parameters
(for supported types, see luxpy.cri._CRI_DEFAULTS[‘cri_types’])
- dict: user defined model parameters
(see e.g. luxpy.cri._CRI_DEFAULTS[‘cierf’]
for required structure)
Note that any non-None input arguments (in kwargs)
to the function will override default values in cri_type dict.
axh:
None, optional
If None: create new figure with single axes, else plot on specified axes.
xlabel:
True, optional
If False: don’t add label and numbers to x-axis
(useful when plotting plotting all ‘Local Rfhi, Rcshi, Rshhi’
values in 3x1 subplots with ‘shared x-axis’: saves vertical space)
y_offset:
0, optional
text-offset from top of bars in barplot.
font_size:
_TM30_FONT_SIZE, optional
Font size of text, axis labels and axis values.
kwargs:
Additional optional keyword arguments,
the same as in cri.spd_to_cri()
Returns:
axh:
handle to figure axes.
data:
dictionary with required parameters for plotting functions.
luxpy.color.cri.plot_tm30_spd(spd, cri_type='ies-tm30', axh=None, font_size=11, **kwargs)[source]

Plot test SPD and reference illuminant, both normalized to the same luminous power.

Args:
spd:
ndarray or dict
If ndarray: single spectral power distribution.
If dict: dictionary with pre-computed parameters (using _tm30_process_spd()).
required keys:
dict_keys([‘St’, ‘Sr’, ‘xyztw_cct’, ‘cct’, ‘duv’,
‘xyzti’, ‘xyztw’, ‘xyzri’, ‘xyzrw’,
‘DEi’, ‘DEa’, ‘Rf’, ‘Rg’,
‘Rcshj’, ‘Rhshj’, ‘Rfhj’, ‘hue_bin_data’])
see cri.spd_to_cri() for more info on parameters.
cri_type:
_CRI_TYPE_DEFAULT or str or dict, optional
-‘str: specifies dict with default cri model parameters
(for supported types, see luxpy.cri._CRI_DEFAULTS[‘cri_types’])
- dict: user defined model parameters
(see e.g. luxpy.cri._CRI_DEFAULTS[‘cierf’]
for required structure)
Note that any non-None input arguments (in kwargs)
to the function will override default values in cri_type dict.
axh:
None, optional
If None: create new figure with single axes, else plot on specified axes.
font_size:
_TM30_FONT_SIZE, optional
Font size of text, axis labels and axis values.
kwargs:
Additional optional keyword arguments,
the same as in cri.spd_to_cri()
Returns:
axh:
handle to figure axes.
data:
dictionary with required parameters for plotting functions.
luxpy.color.cri.plot_tm30_report(spd, cri_type='ies-tm30', report_type='full', source='', manufacturer='', date='', model='', notes='', max_len_notes_line=40, figsize=None, save_fig_name=None, dpi=300, plot_report_top=True, plot_report_bottom=True, show_annexE_priority=True, show_Rcsh1_Rfh1=True, suptitle='ANSI/IES TM-30-18 Color Rendition Report', font_size=None, **kwargs)[source]

Create TM30 Color Rendition Report.

Args:
spd:
ndarray or dict
If ndarray: single spectral power distribution.
If dict: dictionary with pre-computed parameters (using _tm30_process_spd()).
required keys:
dict_keys([‘St’, ‘Sr’, ‘xyztw_cct’, ‘cct’, ‘duv’,
‘xyzti’, ‘xyztw’, ‘xyzri’, ‘xyzrw’,
‘DEi’, ‘DEa’, ‘Rf’, ‘Rg’,
‘Rcshj’, ‘Rhshj’, ‘Rfhj’, ‘hue_bin_data’])
see cri.spd_to_cri() for more info on parameters.
cri_type:
_CRI_TYPE_DEFAULT or str or dict, optional
-‘str: specifies dict with default cri model parameters
(for supported types, see luxpy.cri._CRI_DEFAULTS[‘cri_types’])
- dict: user defined model parameters
(see e.g. luxpy.cri._CRI_DEFAULTS[‘cierf’]
for required structure)
Note that any non-None input arguments (in kwargs)
to the function will override default values in cri_type dict.
report_type:
‘full’, optional
Generate a full report as in ANSI/IES-TM30-2020
Options :
- ‘full’: full report with spectrum plot, color vector graphic, local indices, sample indices’simple’, …
- ‘intermediate’: color vector graphic + local chroma and hue shifts
- ‘simple’: color vector graphic only
- ‘spd_cvg’: spectrum plot + color vector graphic
source:
string with source name.
manufacturer:
string with source manufacturer.
model:
string with source model.
date:
string with source measurement date.
notes:
string to be split
max_len_notes_line:
40, optional
Maximum length of a single line when splitting the string.
figsize:
None, optional
Figure size of pyplot figure.
If None a default depending on the report_type is used:
- ‘full’: (7,12)
- ‘intermediate’ : (14,6)
- ‘simple’ : (6,6)
-‘spd_cvg’: (14,6)
save_fig_name:
None, optional
Filename (+path) to which the report will be saved as an image (png).
If None: don’t save, just display.
dpi:
300, optional
Dots-Per-Inch of image file (PNG).
plot_report_top:
execute _plot_tm30_report_top()
plot_report_bottom:
execute _plot_tm30_report_bottom()
show_annexE_priority:
True, optional
Add Annex E priority levels for source.
show_Rcsh1_Rfh1:
True, optional
Add the local chroma shift (%) and the local color fidelity index
for hue bin 1 at the bottom of the graph.
suptitle:
‘ANSI/IES TM-30-18 Color Rendition Report’ or str, optional
report title (input for plt.suptitle).
font_size:
None, optional
Font size of text, axis labels and axis values (adjust when changing figsizes).
Defaults : (‘full’: _TM30_FONT_SIZE_FULLREPORT, other options: _TM30_FONT_SIZE)
kwargs:
Additional optional keyword arguments,
the same as in cri.spd_to_cri()
Returns:
axs:
dictionary with handles to each axes.
data:
dictionary with required parameters for plotting functions.
luxpy.color.cri.spd_to_tm30_report(spd, cri_type='ies-tm30', report_type='full', source='', manufacturer='', date='', model='', notes='', max_len_notes_line=40, figsize=None, save_fig_name=None, dpi=300, plot_report_top=True, plot_report_bottom=True, show_annexE_priority=True, show_Rcsh1_Rfh1=True, suptitle='ANSI/IES TM-30-18 Color Rendition Report', font_size=None, **kwargs)

Create TM30 Color Rendition Report.

Args:
spd:
ndarray or dict
If ndarray: single spectral power distribution.
If dict: dictionary with pre-computed parameters (using _tm30_process_spd()).
required keys:
dict_keys([‘St’, ‘Sr’, ‘xyztw_cct’, ‘cct’, ‘duv’,
‘xyzti’, ‘xyztw’, ‘xyzri’, ‘xyzrw’,
‘DEi’, ‘DEa’, ‘Rf’, ‘Rg’,
‘Rcshj’, ‘Rhshj’, ‘Rfhj’, ‘hue_bin_data’])
see cri.spd_to_cri() for more info on parameters.
cri_type:
_CRI_TYPE_DEFAULT or str or dict, optional
-‘str: specifies dict with default cri model parameters
(for supported types, see luxpy.cri._CRI_DEFAULTS[‘cri_types’])
- dict: user defined model parameters
(see e.g. luxpy.cri._CRI_DEFAULTS[‘cierf’]
for required structure)
Note that any non-None input arguments (in kwargs)
to the function will override default values in cri_type dict.
report_type:
‘full’, optional
Generate a full report as in ANSI/IES-TM30-2020
Options :
- ‘full’: full report with spectrum plot, color vector graphic, local indices, sample indices’simple’, …
- ‘intermediate’: color vector graphic + local chroma and hue shifts
- ‘simple’: color vector graphic only
- ‘spd_cvg’: spectrum plot + color vector graphic
source:
string with source name.
manufacturer:
string with source manufacturer.
model:
string with source model.
date:
string with source measurement date.
notes:
string to be split
max_len_notes_line:
40, optional
Maximum length of a single line when splitting the string.
figsize:
None, optional
Figure size of pyplot figure.
If None a default depending on the report_type is used:
- ‘full’: (7,12)
- ‘intermediate’ : (14,6)
- ‘simple’ : (6,6)
-‘spd_cvg’: (14,6)
save_fig_name:
None, optional
Filename (+path) to which the report will be saved as an image (png).
If None: don’t save, just display.
dpi:
300, optional
Dots-Per-Inch of image file (PNG).
plot_report_top:
execute _plot_tm30_report_top()
plot_report_bottom:
execute _plot_tm30_report_bottom()
show_annexE_priority:
True, optional
Add Annex E priority levels for source.
show_Rcsh1_Rfh1:
True, optional
Add the local chroma shift (%) and the local color fidelity index
for hue bin 1 at the bottom of the graph.
suptitle:
‘ANSI/IES TM-30-18 Color Rendition Report’ or str, optional
report title (input for plt.suptitle).
font_size:
None, optional
Font size of text, axis labels and axis values (adjust when changing figsizes).
Defaults : (‘full’: _TM30_FONT_SIZE_FULLREPORT, other options: _TM30_FONT_SIZE)
kwargs:
Additional optional keyword arguments,
the same as in cri.spd_to_cri()
Returns:
axs:
dictionary with handles to each axes.
data:
dictionary with required parameters for plotting functions.
luxpy.color.cri.plot_cri_graphics(data, cri_type=None, hbins=16, start_hue=0.0, scalef=100, plot_axis_labels=False, bin_labels=None, plot_edge_lines=True, plot_center_lines=False, plot_bin_colors=True, axtype='polar', ax=None, force_CVG_layout=True, vf_model_type='M6', vf_pcolorshift={'Cref': 40, 'href': array([3.7835e+00, 3.3161e+00, 2.8272e+00, 1.9093e+00, 5.2787e+00, 4.3081e+00, 3.7762e-01, 6.2055e+00, 1.4564e+00, 8.8926e-01]), 'labels': array(['5B', '5BG', '5G', '5GY', '5P', '5PB', '5R', '5RP', '5Y', '5YR'], dtype=object), 'sig': 0.3}, vf_color='k', vf_bin_labels=array(['5B', '5BG', '5G', '5GY', '5P', '5PB', '5R', '5RP', '5Y', '5YR'], dtype=object), vf_plot_bin_colors=True, scale_vf_chroma_to_sample_chroma=False, plot_VF=True, plot_CF=False, plot_SF=False, plot_test_sample_coord=False)[source]

Plot graphical information on color rendition properties (custom design).

Args:
data:
ndarray with spectral data or dict with pre-computed metrics.
cri_type:
None, optional
If None: defaults to cri_type = ‘iesrf’.
:hbins:, :start_hue: and :scalef: are ignored if cri_type not None
and values are replaced by those in cri_type[‘rg_pars’]
hbins:
16 or ndarray with sorted hue bin centers (°), optional
start_hue:
0.0, optional
scalef:
100, optional
Scale factor for graphic.
plot_axis_labels:
False, optional
Turns axis ticks on/off (True/False).
bin_labels:
None or list[str] or ‘#’, optional
Plots labels at the bin center hues.
- None: don’t plot.
- list[str]: list with str for each bin.
(len(:bin_labels:) = :nhbins:)
- ‘#’: plots number.
plot_edge_lines:
True or False, optional
Plot grey bin edge lines with ‘–‘.
plot_center_lines:
False or True, optional
Plot colored lines at ‘center’ of hue bin.
plot_bin_colors:
True, optional
Colorize hue bins.
axtype:
‘polar’ or ‘cart’, optional
Make polar or Cartesian plot.
ax:
None or ‘new’ or ‘same’, optional
- None or ‘new’ creates new plot
- ‘same’: continue plot on same axes.
- axes handle: plot on specified axes.
force_CVG_layout:
True, optional
True: Force plot of basis of CVG.
vf_model_type:
_VF_MODEL_TYPE or ‘M6’ or ‘M5’, optional
Type of polynomial vector field model to use for the calculation of base color shift and metameric uncertainty.
vf_pcolorshift:
_VF_PCOLORSHIFT or user defined dict, optional
The polynomial models of degree 5 and 6 can be fully specified or
summarized by the model parameters themselved OR by calculating the
dCoverC and dH at resp. 5 and 6 hues. :VF_pcolorshift: specifies
these hues and chroma level.
vf_color:
‘k’, optional
For plotting the vector fields.
vf_plot_bin_colors:
True, optional
Colorize hue bins of VF graph.
scale_vf_chroma_to_sample_chroma:
False, optional
Scale chroma of reference and test vf fields such that average of
binned reference chroma equals that of the binned sample chroma
before calculating hue bin metrics.
vf_bin_labels:
see :bin_labels:
Set VF model hue-bin labels.
plot_CF:
False, optional
Plot circle fields.
plot_VF:
True, optional
Plot vector fields.
plot_SF:
True, optional
Plot sample shifts.
plot_test_sample_coord:
Plot the coordinates of the samples under the test illuminant
relative to the mean chromaticity under the reference illuminant (in the CVG plot).
Returns:
returns:
(data,
[plt.gcf(),ax_spd, ax_CVG, ax_locC, ax_locH, ax_VF],
cmap )

:data: is a dictionary with color rendering data
with keys:
- ‘St, Sr’ : ndarray of test SPDs and corresponding ref. illuminants.
- ‘xyz_cct’: xyz of white point calculate with cieobs defined for cct calculations in cri_type[‘cieobs’]
- ‘cct, duv’: CCT and Duv obtained with cieobs in cri_type[‘cieobs’][‘cct’]
- ‘xyzti, xyzri’: ndarray tristimulus values of test and ref. samples (obtained with with cieobs in cri_type[‘cieobs’][‘xyz’])
- ‘xyztw, xyzrw’: ndarray tristimulus values of test and ref. white points (obtained with with cieobs in cri_type[‘cieobs’][‘xyz’])
- ‘DEi, DEa’: ndarray with individual sample color differences DEi and average DEa between test and ref.
- ‘Rf’ : ndarray with general color fidelity index values
- ‘Rg’ : ndarray with color gamut area index values
- ‘Rfi’ : ndarray with specific (sample) color fidelity indices
- ‘Rfhj’ : ndarray with local (hue binned) fidelity indices
- ‘DEhj’ : ndarray with local (hue binned) color differences
- ‘Rcshj’: ndarray with local chroma shifts indices
- ‘Rhshj’: ndarray with local hue shifts indices
- ‘hue_bin_data’: dict with output from _get_hue_bin_data() [see its help for more info]
- ‘cri_type’: same as input (for reference purposes)
- ‘vf’ : dictionary with vector field measures and data.
Keys:
- ‘Rt’ : ndarray with general metameric uncertainty index Rt
- ‘Rti’ : ndarray with specific metameric uncertainty indices Rti
- ‘Rfhj’ : ndarray with local (hue binned) fidelity indices
obtained from VF model predictions at color space
pixel coordinates
- ‘DEhj’ : ndarray with local (hue binned) color differences
(same as above)
- ‘Rcshj’: ndarray with local chroma shifts indices for vectorfield coordinates
(same as above)
- ‘Rhshj’: ndarray with local hue shifts indicesfor vectorfield coordinates
(same as above)
- ‘Rfi’: ndarray with sample fidelity indices for vectorfield coordinates
(same as above)
- ‘DEi’: ndarray with sample color differences for vectorfield coordinates
(same as above)
- ‘hue_bin_data’: dict with output from _get_hue_bin_data() for vectorfield coordinates
- ‘dataVF’: dictionary with output of cri.VFPX.VF_colorshift_model()

:[…]: list with handles to current figure and 5 axes.

:cmap: list with rgb colors for hue bins (for use in other plotting fcns)
luxpy.color.cri.spd_to_tm30_fast(St, interp_settings=None)

Calculate tm30 measures from spd.

luxpy.color.cri.cri_ref_fast(ccts, wl3=array([360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830]), ref_type='iestm30', mix_range=[4000, 5000], cieobs=None, cieobs_Y_normalization=None, force_daylight_below4000K=False, n=None, daylight_locus=None, round_daylightphase_Mi_to_cie_recommended=None, interp_settings=None)

Calculates multiple reference illuminant spectra based on ccts for color rendering index calculations.

luxpy.color.cri.xyz_to_jab_cam02ucs_fast(xyz, xyzw, ucs=True, conditions=None)

Calculate CAM02-UCS J’a’b’ coordinates from xyz tristimulus values of sample and white point.

Args:
xyz:
ndarray with sample tristimulus values
xyzw:
ndarray with white point tristimulus values
conditions:
None, optional
Dictionary with viewing conditions.
None results in:
{‘La’:100, ‘Yb’:20, ‘D’:1, ‘surround’:’avg’}
For more info see luxpy.cam.ciecam02()?
Returns:
jab:
ndarray with J’a’b’ coordinates.

cri/VFPX/

py:
  • __init__.py

  • VF_PX_models.py

  • vectorshiftmodel.py

  • pixelshiftmodel.py

namespace:

luxpy.cri.VFPX

luxpy.color.cri.VFPX.get_poly_model(jabt, jabr, modeltype='M6')[source]

Setup base color shift model (delta_a, delta_b), determine model parameters and accuracy.

Calculates a base color shift (delta) from the ref. chromaticity ar, br.
Args:
jabt:
ndarray with jab color coordinates under the test SPD.
jabr:
ndarray with jab color coordinates under the reference SPD.
modeltype:
_VF_MODEL_TYPE or ‘M6’ or ‘M5’, optional
Specifies degree 5 or degree 6 polynomial model in ab-coordinates.
(see notes below)
Returns:
returns:
(poly_model,
pmodel,
dab_model,
dab_res,
dCHoverC_res,
dab_std,
dCHoverC_std)

:poly_model: function handle to model
:pmodel: ndarray with model parameters
:dab_model: ndarray with ab model predictions from ar, br.
:dab_res: ndarray with residuals between ‘da,db’ of samples and
‘da,db’ predicted by the model.
:dCHoverC_res: ndarray with residuals between ‘dCoverC,dH’
of samples and ‘dCoverC,dH’ predicted by the model.
Note: dCoverC = (Ct - Cr)/Cr and dH = ht - hr
(predicted from model, see notes below)
:dab_std: ndarray with std of :dab_res:
:dCHoverC_std: ndarray with std of :dCHoverC_res:
Notes:
  1. Model types:
    poly5_model = lambda a,b,p: p[0]*a + p[1]*b + p[2]*(a**2) + p[3]*a*b + p[4]*(b**2)
    poly6_model = lambda a,b,p: p[0] + p[1]*a + p[2]*b + p[3]*(a**2) + p[4]*a*b + p[5]*(b**2)
  2. Calculation of dCoverC and dH:
    dCoverC = (np.cos(hr)*da + np.sin(hr)*db)/Cr
    dHoverC = (np.cos(hr)*db - np.sin(hr)*da)/Cr
luxpy.color.cri.VFPX.apply_poly_model_at_x(poly_model, pmodel, axr, bxr)[source]

Applies base color shift model at cartesian coordinates axr, bxr.

Args:
poly_model:
function handle to model
pmodel:
ndarray with model parameters.
axr:
ndarray with a-coordinates under the reference conditions
bxr:
ndarray with b-coordinates under the reference conditions
Returns:
returns:
(axt,bxt,Cxt,hxt,
axr,bxr,Cxr,hxr)

ndarrays with ab-coordinates, chroma and hue
predicted by the model (xt), under the reference (xr).
luxpy.color.cri.VFPX.generate_vector_field(poly_model, pmodel, axr=array([-40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40]), bxr=array([-40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40]), make_grid=True, limit_grid_radius=0, color='k')[source]

Generates a field of vectors using the base color shift model.

Has the option to plot vector field.
Args:
poly_model:
function handle to model
pmodel:
ndarray with model parameters.
axr:
np.arange(-_VF_MAXR,_VF_MAXR+_VF_DELTAR,_VF_DELTAR), optional
Ndarray specifying the a-coordinates at which to apply the model.
bxr:
np.arange(-_VF_MAXR,_VF_MAXR+_VF_DELTAR,_VF_DELTAR), optional
Ndarray specifying the b-coordinates at which to apply the model.
make_grid:
True, optional
True: generate a 2d-grid from :axr:, :bxr:.
limit_grid_radius:
0, optional
A value of zeros keeps grid as specified by axr,bxr.
A value > 0 only keeps (a,b) coordinates within :limit_grid_radius:
color:
‘k’, optional
For plotting the vector field.
If :color: == 0, no plot will be generated.
Returns:
returns:
If :color: == 0: ndarray of axt,bxt,axr,bxr
Else: handle to axes used for plotting.
luxpy.color.cri.VFPX.VF_colorshift_model(S, cri_type='iesrf', model_type='M6', cspace={'Yw': None, 'conditions': {'D': 1.0, 'Dtype': None, 'La': 100.0, 'Yb': 20.0, 'surround': 'avg'}, 'mcat': 'cat02', 'type': 'jab_cam02ucs', 'xyzw': None, 'yellowbluepurplecorrect': None}, sampleset=None, pool=False, pcolorshift={'Cref': 40, 'href': array([3.1416e-01, 9.4248e-01, 1.5708e+00, 2.1991e+00, 2.8274e+00, 3.4558e+00, 4.0841e+00, 4.7124e+00, 5.3407e+00, 5.9690e+00]), 'sig': 0.3}, vfcolor='k', verbosity=0, interp_settings=None)[source]

Applies full vector field model calculations to spectral data.

Args:
S:
nump.ndarray with spectral data.
cri_type:
_VF_CRI_DEFAULT or str or dict, optional
Specifies type of color fidelity model to use.
Controls choice of ref. ill., sample set, averaging, scaling, etc.
See luxpy.cri.spd_to_cri for more info.
modeltype:
_VF_MODEL_TYPE or ‘M6’ or ‘M5’, optional
Specifies degree 5 or degree 6 polynomial model in ab-coordinates.
cspace:
_VF_CSPACE or dict, optional
Specifies color space. See _VF_CSPACE_EXAMPLE for example structure.
sampleset:
None or str or ndarray, optional
Sampleset to be used when calculating vector field model.
pool:
False, optional
If :S: contains multiple spectra, True pools all jab data before
modeling the vector field, while False models a different field
for each spectrum.
pcolorshift:
default dict (see below) or user defined dict, optional
Dict containing the specification input
for apply_poly_model_at_hue_x().
Default dict = {‘href’: np.arange(np.pi/10,2*np.pi,2*np.pi/10),
‘Cref’ : _VF_MAXR,
‘sig’ : _VF_SIG,
‘labels’ : ‘#’}
The polynomial models of degree 5 and 6 can be fully specified or
summarized by the model parameters themselved OR by calculating the
dCoverC and dH at resp. 5 and 6 hues.
vfcolor:
‘k’, optional
For plotting the vector fields.
verbosity:
0, optional
Report warnings or not.
Returns:
returns:
list[dict] (each list element refers to a different test SPD)
with the following keys:
- ‘Source’: dict with ndarrays of the S, cct and duv of source spd.
- ‘metrics’: dict with ndarrays for:
* Rf (color fidelity: base + metameric shift)
* Rt (metameric uncertainty index)
* Rfi (specific color fidelity indices)
* Rti (specific metameric uncertainty indices)
* cri_type (str with cri_type)
- ‘Jab’: dict with with ndarrays for Jabt, Jabr, DEi
- ‘dC/C_dH_x_sig’ :
np.vstack((dCoverC_x,dCoverC_x_sig,dH_x,dH_x_sig)).T
See get_poly_model() for more info.
- ‘fielddata’: dict with dicts containing data on the calculated
vector-field and circle-fields:
* ‘vectorfield’ : {‘axt’: vfaxt, ‘bxt’ : vfbxt,
‘axr’ : vfaxr, ‘bxr’ : vfbxr},
* ‘circlefield’ : {‘axt’: cfaxt, ‘bxt’ : cfbxt,
‘axr’ : cfaxr, ‘bxr’ : cfbxr}},
- ‘modeldata’ : dict with model info:
{‘pmodel’: pmodel,
‘pcolorshift’ : pcolorshift,
‘dab_model’ : dab_model,
‘dab_res’ : dab_res,
‘dab_std’ : dab_std,
‘modeltype’ : modeltype,
‘fmodel’ : poly_model,
‘Jabtm’ : Jabtm,
‘Jabrm’ : Jabrm,
‘DEim’ : DEim},
- ‘vshifts’ :dict with various vector shifts:
* ‘Jabshiftvector_r_to_t’ : ndarray with difference vectors
between jabt and jabr.
* ‘vshift_ab_s’ : vshift_ab_s: ab-shift vectors of samples
* ‘vshift_ab_s_vf’ : vshift_ab_s_vf: ab-shift vectors of
VF model predictions of samples.
* ‘vshift_ab_vf’ : vshift_ab_vf: ab-shift vectors of VF
model predictions of vector field grid.
luxpy.color.cri.VFPX.initialize_VF_hue_angles(hx=None, Cxr=40, cri_type='iesrf', modeltype='M6', determine_hue_angles=True, interp_settings=None)[source]

Initialize the hue angles that will be used to ‘summarize’ the VF model fitting parameters.

Args:
hx:
None or ndarray, optional
None defaults to Munsell H5 hues.
Cxr:
_VF_MAXR, optional
cri_type:
_VF_CRI_DEFAULT or str or dict, optional,
Cri_type parameters for cri and VF model.
modeltype:
_VF_MODEL_TYPE or ‘M5’ or ‘M6’, optional
Determines the type of polynomial model.
determine_hue_angles:
_DETERMINE_HUE_ANGLES or True or False, optional
True: determines the 10 primary / secondary Munsell hues (‘5..’).
Note that for ‘M6’, an additional
Returns:
pcolorshift:
{‘href’: href,
‘Cref’ : _VF_MAXR,
‘sig’ : _VF_SIG,
‘labels’ : list[str]}
luxpy.color.cri.VFPX.generate_grid(jab_ranges=None, out='grid', ax=array([-40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40]), bx=array([-40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40]), jx=None, limit_grid_radius=0)[source]

Generate a grid of color coordinates.

Args:
out:
‘grid’ or ‘vectors’, optional
- ‘grid’: outputs a single 2d numpy.nd-vector with the grid coordinates
- ‘vector’: outputs each dimension seperately.
jab_ranges:
None or ndarray, optional
Specifies the pixelization of color space.
(ndarray.shape = (3,3), with first axis: J,a,b, and second
axis: min, max, delta)
ax:
default ndarray or user defined ndarray, optional
default = np.arange(-_VF_MAXR,_VF_MAXR+_VF_DELTAR,_VF_DELTAR)
bx:
default ndarray or user defined ndarray, optional
default = np.arange(-_VF_MAXR,_VF_MAXR+_VF_DELTAR,_VF_DELTAR)
jx:
None, optional
Note that not-None :jab_ranges: override :ax:, :bx: and :jx input.
limit_grid_radius:
0, optional
A value of zeros keeps grid as specified by axr,bxr.
A value > 0 only keeps (a,b) coordinates within :limit_grid_radius:
Returns:
returns:
single ndarray with ax,bx [,jx]
or
seperate ndarrays for each dimension specified.
luxpy.color.cri.VFPX.calculate_shiftvectors(jabt, jabr, average=True, vtype='ab')[source]

Calculate color shift vectors.

Args:
jabt:
ndarray with jab coordinates under the test SPD
jabr:
ndarray with jab coordinates under the reference SPD
average:
True, optional
If True, take mean of difference vectors along axis = 0.
vtype:
‘ab’ or ‘jab’, optional
Reduce output ndarray to only a,b coordinates of shift vector(s).
Returns:
returns:
ndarray of (mean) shift vector(s).
luxpy.color.cri.VFPX.plot_shift_data(data, fieldtype='vectorfield', scalef=40, color='k', axtype='polar', ax=None, hbins=10, start_hue=0.0, bin_labels='#', plot_center_lines=True, plot_axis_labels=False, plot_edge_lines=False, plot_bin_colors=True, force_CVG_layout=True)[source]

Plots vector or circle fields generated by VFcolorshiftmodel() or PXcolorshiftmodel().

Args:
data:
dict generated by VFcolorshiftmodel() or PXcolorshiftmodel()
Must contain ‘fielddata’- key, which is a dict with possible keys:
- key: ‘vectorfield’: ndarray with vector field data
- key: ‘circlefield’: ndarray with circle field data
color:
‘k’, optional
Color for plotting the vector-fields.
axtype:
‘polar’ or ‘cart’, optional
Make polar or Cartesian plot.
ax:
None or ‘new’ or ‘same’, optional
- None or ‘new’ creates new plot
- ‘same’: continue plot on same axes.
- axes handle: plot on specified axes.
hbins:
16 or ndarray with sorted hue bin centers (°), optional
start_hue:
_VF_MAXR, optional
Scale factor for graphic.
plot_axis_labels:
False, optional
Turns axis ticks on/off (True/False).
bin_labels:
None or list[str] or ‘#’, optional
Plots labels at the bin center hues.
- None: don’t plot.
- list[str]: list with str for each bin.
(len(:bin_labels:) = :nhbins:)
- ‘#’: plots number.
plot_edge_lines:
True or False, optional
Plot grey bin edge lines with ‘–‘.
plot_center_lines:
False or True, optional
Plot colored lines at ‘center’ of hue bin.
plot_bin_colors:
True, optional
Colorize hue-bins.
force_CVG_layout:
False or True, optional
True: Force plot of basis of CVG.
Returns:
returns:
figCVG, hax, cmap
:figCVG: handle to CVG figure
:hax: handle to CVG axes
:cmap: list with rgb colors for hue bins
(for use in other plotting fcns)
luxpy.color.cri.VFPX.plotcircle(radii=array([0, 10, 20, 30, 40, 50]), angles=array([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340]), color='k', linestyle='--', out=None)[source]

Plot one or more concentric circles around (0,0).

Args:
radii:
np.arange(0,60,10) or ndarray with radii of circle(s), optional
angles:
np.arange(0,350,10) or ndarray with angles (°), optional
color:
‘k’, optional
Color for plotting.
linestyle:
‘–’, optional
Linestyle of circles.
out:
None, optional
If None: plot circles, return (x,y) otherwise.
Returns:
x,y:
ndarrays with circle coordinates (only returned if out is ‘x,y’)
luxpy.color.cri.VFPX.get_pixel_coordinates(jab, jab_ranges=None, jab_deltas=None, limit_grid_radius=0)[source]

Get pixel coordinates corresponding to array of jab color coordinates.

Args:
jab:
ndarray of color coordinates
jab_ranges:
None or ndarray, optional
Specifies the pixelization of color space.
(ndarray.shape = (3,3), with first axis: J,a,b, and second axis: min, max, delta)
jab_deltas:
float or ndarray, optional
Specifies the sampling range.
A float uses jab_deltas as the maximum Euclidean distance to select
samples around each pixel center. A ndarray of 3 deltas, uses
a city block sampling around each pixel center.
limit_grid_radius:
0, optional
A value of zeros keeps grid as specified by axr,bxr.
A value > 0 only keeps (a,b) coordinates within :limit_grid_radius:
Returns:
returns:
gridp, idxp, jabp, samplenrs, samplesIDs
- :gridp: ndarray with coordinates of all pixel centers.
- :idxp: list[int] with pixel index for each non-empty pixel
- :jabp: ndarray with center color coordinates of non-empty pixels
- :samplenrs: list[list[int]] with sample numbers belong to each
non-empty pixel
- :sampleIDs: summarizing list,
with column order: ‘idxp, jabp, samplenrs’
luxpy.color.cri.VFPX.PX_colorshift_model(Jabt, Jabr, jab_ranges=None, jab_deltas=None, limit_grid_radius=0)[source]

Pixelates the color space and calculates the color shifts in each pixel.

Args:
Jabt:
ndarray with color coordinates under the (single) test SPD.
Jabr:
ndarray with color coordinates under the (single) reference SPD.
jab_ranges:
None or ndarray, optional
Specifies the pixelization of color space.
(ndarray.shape = (3,3), with first axis: J,a,b, and second
axis: min, max, delta)
jab_deltas:
float or ndarray, optional
Specifies the sampling range.
A float uses jab_deltas as the maximum Euclidean distance to select
samples around each pixel center. A ndarray of 3 deltas, uses
a city block sampling around each pixel center.
limit_grid_radius:
0, optional
A value of zeros keeps grid as specified by axr,bxr.
A value > 0 only keeps (a,b) coordinates within :limit_grid_radius:
Returns:
returns:
dict with the following keys:
- ‘Jab’: dict with with ndarrays for:
Jabt, Jabr, DEi, DEi_ab (only ab-coordinates), DEa (mean)
and DEa_ab
- ‘vshifts’: dict with:
* ‘vectorshift’: ndarray with vector shifts between average
Jabt and Jabr for each pixel
* ‘vectorshift_ab’: ndarray with vector shifts averaged
over J for each pixel
* ‘vectorshift_ab_J0’: ndarray with vector shifts averaged
over J for each pixel of J=0 plane.
* ‘vectorshift_len’: length of ‘vectorshift’
* ‘vectorshift_ab_len’: length of ‘vectorshift_ab’
* ‘vectorshift_ab_J0_len’: length of ‘vectorshift_ab_J0’
* ‘vectorshift_len_DEnormed’: length of ‘vectorshift’
normalized to ‘DEa’
* ‘vectorshift_ab_len_DEnormed’: length of ‘vectorshift_ab’
normalized to ‘DEa_ab’
* ‘vectorshift_ab_J0_len_DEnormed’: length of ‘vectorshift_ab_J0’
normalized to ‘DEa_ab’
- ‘pixeldata’: dict with pixel info:
* ‘grid’ ndarray with coordinates of all pixel centers.
* ‘idx’: list[int] with pixel index for each non-empty pixel
* ‘Jab’: ndarray with center coordinates of non-empty pixels
* ‘samplenrs’: list[list[int]] with sample numbers belong to
each non-empty pixel
* ‘IDs: summarizing list,
with column order: ‘idxp, jabp, samplenrs’
- ‘fielddata’ : dict with dicts containing data on the calculated
vector-field and circle-fields
* ‘vectorfield’: dict with ndarrays for the ab-coordinates
under the ref. (axr, bxr) and test (axt, bxt) illuminants,
centered at the pixel centers corresponding to the ab-coordinates of the reference illuminant.
luxpy.color.cri.VFPX.calculate_VF_PX_models(S, cri_type='iesrf', sampleset=None, pool=False, pcolorshift={'Cref': 40, 'href': array([3.1416e-01, 9.4248e-01, 1.5708e+00, 2.1991e+00, 2.8274e+00, 3.4558e+00, 4.0841e+00, 4.7124e+00, 5.3407e+00, 5.9690e+00]), 'labels': '#', 'sig': 0.3}, vfcolor='k', verbosity=0, interp_settings=None)[source]

Calculate Vector Field and Pixel color shift models.

Args:
cri_type:
_VF_CRI_DEFAULT or str or dict, optional
Specifies type of color fidelity model to use.
Controls choice of ref. ill., sample set, averaging, scaling, etc.
See luxpy.cri.spd_to_cri for more info.
sampleset:
None or str or ndarray, optional
Sampleset to be used when calculating vector field model.
pool:
False, optional
If :S: contains multiple spectra, True pools all jab data before
modeling the vector field, while False models a different field
for each spectrum.
pcolorshift:
default dict (see below) or user defined dict, optional
Dict containing the specification input
for apply_poly_model_at_hue_x().
Default dict = {‘href’: np.arange(np.pi/10,2*np.pi,2*np.pi/10),
‘Cref’ : _VF_MAXR,
‘sig’ : _VF_SIG,
‘labels’ : ‘#’}
The polynomial models of degree 5 and 6 can be fully specified or
summarized by the model parameters themselved OR by calculating the
dCoverC and dH at resp. 5 and 6 hues.
vfcolor:
‘k’, optional
For plotting the vector fields.
verbosity:
0, optional
Report warnings or not.
Returns:
returns:
:dataVF:, :dataPX:
Dicts, for more info, see output description of resp.:
luxpy.cri.VF_colorshift_model() and luxpy.cri.PX_colorshift_model()
luxpy.color.cri.VFPX.subsample_RFL_set(rfl, rflpath='', samplefcn='rand', S=array([[3.6000e+02, 3.6100e+02, 3.6200e+02, 3.6300e+02, 3.6400e+02, 3.6500e+02, 3.6600e+02, 3.6700e+02, 3.6800e+02, 3.6900e+02, 3.7000e+02, 3.7100e+02, 3.7200e+02, 3.7300e+02, 3.7400e+02, 3.7500e+02, 3.7600e+02, 3.7700e+02, 3.7800e+02, 3.7900e+02, 3.8000e+02, 3.8100e+02, 3.8200e+02, 3.8300e+02, 3.8400e+02, 3.8500e+02, 3.8600e+02, 3.8700e+02, 3.8800e+02, 3.8900e+02, 3.9000e+02, 3.9100e+02, 3.9200e+02, 3.9300e+02, 3.9400e+02, 3.9500e+02, 3.9600e+02, 3.9700e+02, 3.9800e+02, 3.9900e+02, 4.0000e+02, 4.0100e+02, 4.0200e+02, 4.0300e+02, 4.0400e+02, 4.0500e+02, 4.0600e+02, 4.0700e+02, 4.0800e+02, 4.0900e+02, 4.1000e+02, 4.1100e+02, 4.1200e+02, 4.1300e+02, 4.1400e+02, 4.1500e+02, 4.1600e+02, 4.1700e+02, 4.1800e+02, 4.1900e+02, 4.2000e+02, 4.2100e+02, 4.2200e+02, 4.2300e+02, 4.2400e+02, 4.2500e+02, 4.2600e+02, 4.2700e+02, 4.2800e+02, 4.2900e+02, 4.3000e+02, 4.3100e+02, 4.3200e+02, 4.3300e+02, 4.3400e+02, 4.3500e+02, 4.3600e+02, 4.3700e+02, 4.3800e+02, 4.3900e+02, 4.4000e+02, 4.4100e+02, 4.4200e+02, 4.4300e+02, 4.4400e+02, 4.4500e+02, 4.4600e+02, 4.4700e+02, 4.4800e+02, 4.4900e+02, 4.5000e+02, 4.5100e+02, 4.5200e+02, 4.5300e+02, 4.5400e+02, 4.5500e+02, 4.5600e+02, 4.5700e+02, 4.5800e+02, 4.5900e+02, 4.6000e+02, 4.6100e+02, 4.6200e+02, 4.6300e+02, 4.6400e+02, 4.6500e+02, 4.6600e+02, 4.6700e+02, 4.6800e+02, 4.6900e+02, 4.7000e+02, 4.7100e+02, 4.7200e+02, 4.7300e+02, 4.7400e+02, 4.7500e+02, 4.7600e+02, 4.7700e+02, 4.7800e+02, 4.7900e+02, 4.8000e+02, 4.8100e+02, 4.8200e+02, 4.8300e+02, 4.8400e+02, 4.8500e+02, 4.8600e+02, 4.8700e+02, 4.8800e+02, 4.8900e+02, 4.9000e+02, 4.9100e+02, 4.9200e+02, 4.9300e+02, 4.9400e+02, 4.9500e+02, 4.9600e+02, 4.9700e+02, 4.9800e+02, 4.9900e+02, 5.0000e+02, 5.0100e+02, 5.0200e+02, 5.0300e+02, 5.0400e+02, 5.0500e+02, 5.0600e+02, 5.0700e+02, 5.0800e+02, 5.0900e+02, 5.1000e+02, 5.1100e+02, 5.1200e+02, 5.1300e+02, 5.1400e+02, 5.1500e+02, 5.1600e+02, 5.1700e+02, 5.1800e+02, 5.1900e+02, 5.2000e+02, 5.2100e+02, 5.2200e+02, 5.2300e+02, 5.2400e+02, 5.2500e+02, 5.2600e+02, 5.2700e+02, 5.2800e+02, 5.2900e+02, 5.3000e+02, 5.3100e+02, 5.3200e+02, 5.3300e+02, 5.3400e+02, 5.3500e+02, 5.3600e+02, 5.3700e+02, 5.3800e+02, 5.3900e+02, 5.4000e+02, 5.4100e+02, 5.4200e+02, 5.4300e+02, 5.4400e+02, 5.4500e+02, 5.4600e+02, 5.4700e+02, 5.4800e+02, 5.4900e+02, 5.5000e+02, 5.5100e+02, 5.5200e+02, 5.5300e+02, 5.5400e+02, 5.5500e+02, 5.5600e+02, 5.5700e+02, 5.5800e+02, 5.5900e+02, 5.6000e+02, 5.6100e+02, 5.6200e+02, 5.6300e+02, 5.6400e+02, 5.6500e+02, 5.6600e+02, 5.6700e+02, 5.6800e+02, 5.6900e+02, 5.7000e+02, 5.7100e+02, 5.7200e+02, 5.7300e+02, 5.7400e+02, 5.7500e+02, 5.7600e+02, 5.7700e+02, 5.7800e+02, 5.7900e+02, 5.8000e+02, 5.8100e+02, 5.8200e+02, 5.8300e+02, 5.8400e+02, 5.8500e+02, 5.8600e+02, 5.8700e+02, 5.8800e+02, 5.8900e+02, 5.9000e+02, 5.9100e+02, 5.9200e+02, 5.9300e+02, 5.9400e+02, 5.9500e+02, 5.9600e+02, 5.9700e+02, 5.9800e+02, 5.9900e+02, 6.0000e+02, 6.0100e+02, 6.0200e+02, 6.0300e+02, 6.0400e+02, 6.0500e+02, 6.0600e+02, 6.0700e+02, 6.0800e+02, 6.0900e+02, 6.1000e+02, 6.1100e+02, 6.1200e+02, 6.1300e+02, 6.1400e+02, 6.1500e+02, 6.1600e+02, 6.1700e+02, 6.1800e+02, 6.1900e+02, 6.2000e+02, 6.2100e+02, 6.2200e+02, 6.2300e+02, 6.2400e+02, 6.2500e+02, 6.2600e+02, 6.2700e+02, 6.2800e+02, 6.2900e+02, 6.3000e+02, 6.3100e+02, 6.3200e+02, 6.3300e+02, 6.3400e+02, 6.3500e+02, 6.3600e+02, 6.3700e+02, 6.3800e+02, 6.3900e+02, 6.4000e+02, 6.4100e+02, 6.4200e+02, 6.4300e+02, 6.4400e+02, 6.4500e+02, 6.4600e+02, 6.4700e+02, 6.4800e+02, 6.4900e+02, 6.5000e+02, 6.5100e+02, 6.5200e+02, 6.5300e+02, 6.5400e+02, 6.5500e+02, 6.5600e+02, 6.5700e+02, 6.5800e+02, 6.5900e+02, 6.6000e+02, 6.6100e+02, 6.6200e+02, 6.6300e+02, 6.6400e+02, 6.6500e+02, 6.6600e+02, 6.6700e+02, 6.6800e+02, 6.6900e+02, 6.7000e+02, 6.7100e+02, 6.7200e+02, 6.7300e+02, 6.7400e+02, 6.7500e+02, 6.7600e+02, 6.7700e+02, 6.7800e+02, 6.7900e+02, 6.8000e+02, 6.8100e+02, 6.8200e+02, 6.8300e+02, 6.8400e+02, 6.8500e+02, 6.8600e+02, 6.8700e+02, 6.8800e+02, 6.8900e+02, 6.9000e+02, 6.9100e+02, 6.9200e+02, 6.9300e+02, 6.9400e+02, 6.9500e+02, 6.9600e+02, 6.9700e+02, 6.9800e+02, 6.9900e+02, 7.0000e+02, 7.0100e+02, 7.0200e+02, 7.0300e+02, 7.0400e+02, 7.0500e+02, 7.0600e+02, 7.0700e+02, 7.0800e+02, 7.0900e+02, 7.1000e+02, 7.1100e+02, 7.1200e+02, 7.1300e+02, 7.1400e+02, 7.1500e+02, 7.1600e+02, 7.1700e+02, 7.1800e+02, 7.1900e+02, 7.2000e+02, 7.2100e+02, 7.2200e+02, 7.2300e+02, 7.2400e+02, 7.2500e+02, 7.2600e+02, 7.2700e+02, 7.2800e+02, 7.2900e+02, 7.3000e+02, 7.3100e+02, 7.3200e+02, 7.3300e+02, 7.3400e+02, 7.3500e+02, 7.3600e+02, 7.3700e+02, 7.3800e+02, 7.3900e+02, 7.4000e+02, 7.4100e+02, 7.4200e+02, 7.4300e+02, 7.4400e+02, 7.4500e+02, 7.4600e+02, 7.4700e+02, 7.4800e+02, 7.4900e+02, 7.5000e+02, 7.5100e+02, 7.5200e+02, 7.5300e+02, 7.5400e+02, 7.5500e+02, 7.5600e+02, 7.5700e+02, 7.5800e+02, 7.5900e+02, 7.6000e+02, 7.6100e+02, 7.6200e+02, 7.6300e+02, 7.6400e+02, 7.6500e+02, 7.6600e+02, 7.6700e+02, 7.6800e+02, 7.6900e+02, 7.7000e+02, 7.7100e+02, 7.7200e+02, 7.7300e+02, 7.7400e+02, 7.7500e+02, 7.7600e+02, 7.7700e+02, 7.7800e+02, 7.7900e+02, 7.8000e+02, 7.8100e+02, 7.8200e+02, 7.8300e+02, 7.8400e+02, 7.8500e+02, 7.8600e+02, 7.8700e+02, 7.8800e+02, 7.8900e+02, 7.9000e+02, 7.9100e+02, 7.9200e+02, 7.9300e+02, 7.9400e+02, 7.9500e+02, 7.9600e+02, 7.9700e+02, 7.9800e+02, 7.9900e+02, 8.0000e+02, 8.0100e+02, 8.0200e+02, 8.0300e+02, 8.0400e+02, 8.0500e+02, 8.0600e+02, 8.0700e+02, 8.0800e+02, 8.0900e+02, 8.1000e+02, 8.1100e+02, 8.1200e+02, 8.1300e+02, 8.1400e+02, 8.1500e+02, 8.1600e+02, 8.1700e+02, 8.1800e+02, 8.1900e+02, 8.2000e+02, 8.2100e+02, 8.2200e+02, 8.2300e+02, 8.2400e+02, 8.2500e+02, 8.2600e+02, 8.2700e+02, 8.2800e+02, 8.2900e+02, 8.3000e+02], [1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00]]), jab_ranges=None, jab_deltas=None, cieobs='1964_10', cspace={'Yw': None, 'conditions': {'D': 1.0, 'Dtype': None, 'La': 100.0, 'Yb': 20.0, 'surround': 'avg'}, 'mcat': 'cat02', 'type': 'jab_cam02ucs', 'xyzw': None, 'yellowbluepurplecorrect': None}, ax=array([-40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40]), bx=array([-40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40]), jx=None, limit_grid_radius=0)[source]

Sub-samples a spectral reflectance set by pixelization of color space.

Args:
rfl:
ndarray or str
Array with of str referring to a set of spectral reflectance
functions to be subsampled.
If str to file: file must contain data as columns, with first
column the wavelengths.
rflpath:
‘’ or str, optional
Path to folder with rfl-set specified in a str :rfl: filename.
samplefcn:
‘rand’ or ‘mean’, optional
-‘rand’: selects a random sample from the samples within each pixel
-‘mean’: returns the mean spectral reflectance in each pixel.
S:
_CIE_ILLUMINANTS[‘E’], optional
Illuminant used to calculate the color coordinates of the spectral
reflectance samples.
jab_ranges:
None or ndarray, optional
Specifies the pixelization of color space.
(ndarray.shape = (3,3), with first axis: J,a,b, and second
axis: min, max, delta)
jab_deltas:
float or ndarray, optional
Specifies the sampling range.
A float uses jab_deltas as the maximum Euclidean distance to select
samples around each pixel center. A ndarray of 3 deltas, uses
a city block sampling around each pixel center.
cspace:
_VF_CSPACE or dict, optional
Specifies color space. See _VF_CSPACE_EXAMPLE for example structure.
cieobs:
_VF_CIEOBS or str, optional
Specifies CMF set used to calculate color coordinates.
ax:
default ndarray or user defined ndarray, optional
default = np.arange(-_VF_MAXR,_VF_MAXR+_VF_DELTAR,_VF_DELTAR)
bx:
default ndarray or user defined ndarray, optional
default = np.arange(-_VF_MAXR,_VF_MAXR+_VF_DELTAR,_VF_DELTAR)
jx:
None, optional
Note that not-None :jab_ranges: override :ax:, :bx: and :jx input.
limit_grid_radius:
0, optional
A value of zeros keeps grid as specified by axr,bxr.
A value > 0 only keeps (a,b) coordinates within :limit_grid_radius:
Returns:
returns:
rflsampled, jabp
ndarrays with resp. the subsampled set of spectral reflectance
functions and the pixel coordinate centers.
luxpy.color.cri.VFPX.plot_VF_PX_models(dataVF=None, dataPX=None, plot_VF=True, plot_PX=True, axtype='polar', ax='new', plot_circle_field=True, plot_sample_shifts=False, plot_samples_shifts_at_pixel_center=False, jabp_sampled=None, plot_VF_colors=['g'], plot_PX_colors=['r'], hbin_cmap=None, bin_labels=None, plot_bin_colors=True, force_CVG_layout=False)[source]

Plot the VF and PX model color shift vectors.

Args:
dataVF:
None or list[dict] with VF_colorshift_model() output, optional
None plots nothing related to VF model.
Each list element refers to a different test SPD.
dataPX:
None or list[dict] with PX_colorshift_model() output, optional
None plots nothing related to PX model.
Each list element refers to a different test SPD.
plot_VF:
True, optional
Plot VF model (if :dataVF: is not None).
plot_PX:
True, optional
Plot PX model (if :dataPX: is not None).
axtype:
‘polar’ or ‘cart’, optional
Make polar or Cartesian plot.
ax:
None or ‘new’ or ‘same’, optional
- None or ‘new’ creates new plot
- ‘same’: continue plot on same axes.
- axes handle: plot on specified axes.
plot_circle_field:
True or False, optional
Plot lines showing how a series of circles of color coordinates is
distorted by the test SPD.
The width (wider means more) and color (red means more) of the
lines specify the intensity of the hue part of the color shift.
plot_sample_shifts:
False or True, optional
Plots the shifts of the individual samples of the rfl-set used to
calculated the VF model.
plot_samples_shifts_at_pixel_center:
False, optional
Offers the possibility of shifting the vector shifts of subsampled
sets from the reference illuminant positions to the pixel centers.
Note that the pixel centers must be supplied in :jabp_sampled:.
jabp_sampled:
None, ndarray, optional
Corresponding pixel center for each sample in a subsampled set.
plot_VF_colors:
[‘g’] or list[str], optional
Specifies the plot color the color shift vectors of the VF model.
If len(:plot_VF_colors:) == 1: same color for each list element
of :dataVF:.
plot_VF_colors:
[‘g’] or list[str], optional
Specifies the plot color the color shift vectors of the VF model.
If len(:plot_VF_colors:) == 1: same color for each list element
of :dataVF:.
hbin_cmap:
None or colormap, optional
Color map with RGB entries for each of the hue bins specified by
the hues in _VF_PCOLORSHIFT.
If None: cmap will be obtained on first run by
luxpy.cri.plot_shift_data() and returned for use in other functions
plot_bin_colors:
True, optional
Colorize hue-bins.
bin_labels:
None or list[str] or ‘#’, optional
Plots labels at the bin center hues.
- None: don’t plot.
- list[str]: list with str for each bin.
(len(:bin_labels:) = :nhbins:)
- ‘#’: plots number.
- ‘_VF_PCOLORSHIFT’: uses the labels in _VF_PCOLORSHIFT[‘labels’]
- ‘pcolorshift’: uses the labels in dataVF[‘modeldata’][‘pcolorshift’][‘labels’]
force_CVG_layout:
False or True, optional
True: Force plot of basis of CVG.
Returns:
returns:
ax (handle to current axes), cmap (hbin_cmap)

XYZ,LAB classes

py:
  • CDATA.py

namespace:

luxpy

class luxpy.color.CDATA.XYZ(value=None, relative=True, cieobs='1931_2', dtype='xyz')[source]
ctf(dtype='Yuv', **kwargs)[source]

Convert XYZ tristimulus values to color space coordinates.

Args:
dtype:
_CSPACE or str, optional
Convert to this color space.
kwargs:
additional input arguments required for
color space transformation.
See specific luxpy function for more info
(e.g. ?luxpy.xyz_to_lab)
Returns:
returns:
luxpy.LAB with .value field that is a ndarray
with color space coordinates
plot(ax=None, title=None, **kwargs)[source]

Plot tristimulus or cone fundamental values.

Args:
ax:
None or axes handles, optional
None: create new figure axes, else use :ax: for plotting.
title:
None or str, optional
Give plot a title.
kwargs:
additional arguments for use with
matplotlib.pyplot.scatter
Returns:
gca:
handle to current axes.
to_Yxy()[source]

Convert XYZ tristimulus values CIE Yxy chromaticity values.

Returns:
Yxy:
luxpy.LAB with .value field that is a ndarray
with Yxy chromaticity values.
(Y value refers to luminance or luminance factor)
to_Yuv(**kwargs)[source]

Convert XYZ tristimulus values CIE 1976 Yu’v’ chromaticity values.

Returns:
Yuv:
luxpy.LAB with .value field that is a ndarray
with CIE 1976 Yu’v’ chromaticity values.
(Y value refers to luminance or luminance factor)
to_Yuv76(**kwargs)[source]

Convert XYZ tristimulus values CIE 1976 Yu’v’ chromaticity values.

Returns:
Yuv:
luxpy.LAB with .value field that is a ndarray
with CIE 1976 Yu’v’ chromaticity values.
(Y value refers to luminance or luminance factor)
to_Yuv60(**kwargs)[source]

Convert XYZ tristimulus values CIE 1960 Yuv chromaticity values.

Returns:
Yuv:
luxpy.LAB with .value field that is a ndarray
with CIE 1960 Yuv chromaticity values.
(Y value refers to luminance or luminance factor)
to_wuv(xyzw=array([1.0000e+02, 1.0000e+02, 1.0000e+02]))[source]

Convert XYZ tristimulus values CIE 1964 U*V*W* color space.

Args:
xyzw:
ndarray with tristimulus values of white point, optional
Defaults to luxpy._COLORTF_DEFAULT_WHITE_POINT
Returns:
wuv:
luxpy.LAB with .value field that is a ndarray
with W*U*V* values.
to_lms()[source]

Convert XYZ tristimulus values or LMS cone fundamental responses to LMS cone fundamental responses.

Returns:
lms:
luxpy.XYZ with .value field that is a ndarray
with LMS cone fundamental responses.
to_xyz()[source]

Convert XYZ tristimulus values or LMS cone fundamental responses to XYZ tristimulus values.

Returns:
xyz:
luxpy.XYZ with .value field that is a ndarray
with XYZ tristimulus values.
to_lab(xyzw=None, cieobs='1931_2')[source]

Convert XYZ tristimulus values to CIE 1976 L*a*b* (CIELAB) coordinates.

Args:
xyzw:
None or ndarray with xyz values of white point, optional
None defaults to xyz of CIE D65 using the :cieobs: observer.
cieobs:
luxpy._CIEOBS, optional
CMF set to use when calculating xyzw.
Returns:
lab:
luxpy.LAB with .value field that is a ndarray
with CIE 1976 L*a*b* (CIELAB) color coordinates
to_luv(xyzw=None, cieobs='1931_2')[source]

Convert XYZ tristimulus values to CIE 1976 L*u*v* (CIELUV) coordinates.

Args:
xyzw:
None or ndarray with xyz values of white point, optional
None defaults to xyz of CIE D65 using the :cieobs: observer.
cieobs:
luxpy._CIEOBS, optional
CMF set to use when calculating xyzw.
Returns:
luv:
luxpy.LAB with .value field that is a ndarray
with CIE 1976 L*u*v* (CIELUV) color coordinates
to_Vrb_mb(cieobs='1931_2', scaling=[1, 1], M=None)[source]

Convert XYZ tristimulus values to V,r,b (Macleod-Boynton) coordinates.

Macleod Boynton: V = R+G, r = R/V, b = B/V
Note that R,G,B ~ L,M,S
Args:
cieobs:
luxpy._CIEOBS, optional
CMF set to use when calculating xyzw.
scaling:
list of scaling factors for r and b dimensions.
M:
None, optional
Conversion matrix for going from XYZ to RGB (LMS)
If None, :cieobs: determines the M (function does inversion)
Returns:
Vrb:
luxpy.LAB with .value field that is a ndarray
ndarray with V,r,b (Macleod-Boynton) color coordinates
to_ipt(cieobs='1931_2', xyzw=None, M=None)[source]

Convert XYZ tristimulus values to IPT color coordinates.

I: Lightness axis, P, red-green axis, T: yellow-blue axis.
Args:
xyzw:
None or ndarray with xyz values of white point, optional
None defaults to xyz of CIE D65 using the :cieobs: observer.
cieobs:
luxpy._CIEOBS, optional
CMF set to use when calculating xyzw for rescaling Mxyz2lms
(only when not None).
M:
None, optional
None defaults to conversion matrix determined by :cieobs:
Returns:
ipt:
luxpy.LAB with .value field that is a ndarray
with IPT color coordinates
Note:
xyz:

is assumed to be under D65 viewing conditions!! | If necessary perform chromatic adaptation !!

to_Ydlep(cieobs='1931_2', xyzw=array([1.0000e+02, 1.0000e+02, 1.0000e+02]))[source]

Convert XYZ values to Y, dominant (complementary) wavelength and excitation purity.

Args:
xyzw:
None or ndarray with xyz values of white point, optional
None defaults to xyz of CIE D65 using the :cieobs: observer.
cieobs:
luxpy._CIEOBS, optional
CMF set to use when calculating spectrum locus coordinates.
Returns:
Ydlep:
ndarray with Y, dominant (complementary) wavelength
and excitation purity
to_srgb(gamma=2.4)[source]

Calculates IEC:61966 sRGB values from xyz.

Args:
xyz:
ndarray with relative tristimulus values.
gamma:
2.4, optional
compression in sRGB
Returns:
rgb:
ndarray with R,G,B values (uint8).
to_jabz(ztype='jabz')[source]

Convert XYZ tristimulus values to Jz,az,bz color coordinates.

Args:
xyz:
ndarray with absolute tristimulus values (Y in cd/m²!)
ztype:
‘jabz’, optional
String with requested return:
Options: ‘jabz’, ‘iabz’
Returns:
jabz:
ndarray with Jz,az,bz color coordinates
Notes:
1. :xyz: is assumed to be under D65 viewing conditions! If necessary perform chromatic adaptation!

2a. Jz represents the ‘lightness’ relative to a D65 white with luminance = 10000 cd/m²
(note that Jz that not exactly equal 1 for this high value, but rather for 102900 cd/m2)
2b. az, bz represent respectively a red-green and a yellow-blue opponent axis
(but note that a D65 shows a small offset from (0,0))
Reference:

1. Safdar, M., Cui, G., Kim,Y. J., and Luo,M. R. (2017). Perceptually uniform color space for image signals including high dynamic range and wide gamut. Opt. Express, vol. 25, no. 13, pp. 15131–15151, Jun. 2017.

to_jabM_ciecam02(xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=100.0, conditions={'D': 1.0, 'Dtype': None, 'La': 100.0, 'Yb': 20.0, 'surround': 'avg'}, naka_rushton_parameters=None, unique_hue_data=None, yellowbluepurplecorrect=None, mcat='cat02')[source]

See ?luxpy.xyz_to_jabM_ciecam02

to_jabC_ciecam02(xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=100.0, conditions={'D': 1.0, 'Dtype': None, 'La': 100.0, 'Yb': 20.0, 'surround': 'avg'}, naka_rushton_parameters=None, unique_hue_data=None, yellowbluepurplecorrect=None, mcat='cat02')[source]

See ?luxpy.xyz_to_jabC_ciecam02

to_jab_cam02ucs(xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=100.0, conditions={'D': 1.0, 'Dtype': None, 'La': 100.0, 'Yb': 20.0, 'surround': 'avg'}, naka_rushton_parameters=None, unique_hue_data=None, yellowbluepurplecorrect=None, mcat='cat02')[source]

See ?luxpy.xyz_to_jab_cam02ucs

to_jab_cam02lcd(xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=100.0, conditions={'D': 1.0, 'Dtype': None, 'La': 100.0, 'Yb': 20.0, 'surround': 'avg'}, naka_rushton_parameters=None, unique_hue_data=None, yellowbluepurplecorrect=None, mcat='cat02')[source]

See ?luxpy.xyz_to_jab_cam02lcd

to_jab_cam02scd(xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=100.0, conditions={'D': 1.0, 'Dtype': None, 'La': 100.0, 'Yb': 20.0, 'surround': 'avg'}, naka_rushton_parameters=None, unique_hue_data=None, yellowbluepurplecorrect=None, mcat='cat02')[source]

See ?luxpy.xyz_to_jab_cam02scd

to_jabM_ciecam16(xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=100.0, conditions={'D': 1.0, 'Dtype': None, 'La': 100.0, 'Yb': 20.0, 'surround': 'avg'}, naka_rushton_parameters=None, unique_hue_data=None, mcat='cat16')[source]

See ?luxpy.xyz_to_jabM_ciecam16

to_jabC_ciecam16(xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=100.0, conditions={'D': 1.0, 'Dtype': None, 'La': 100.0, 'Yb': 20.0, 'surround': 'avg'}, naka_rushton_parameters=None, unique_hue_data=None, mcat='cat16')[source]

See ?luxpy.xyz_to_jabC_ciecam16

to_jab_cam16ucs(xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=100.0, conditions={'D': 1.0, 'Dtype': None, 'La': 100.0, 'Yb': 20.0, 'surround': 'avg'}, naka_rushton_parameters=None, unique_hue_data=None, mcat='cat16')[source]

See ?luxpy.xyz_to_jab_cam02ucs

to_jab_cam16lcd(xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=100.0, conditions={'D': 1.0, 'Dtype': None, 'La': 100.0, 'Yb': 20.0, 'surround': 'avg'}, naka_rushton_parameters=None, unique_hue_data=None, mcat='cat16')[source]

See ?luxpy.xyz_to_jab_cam16lcd

to_jab_cam16scd(xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), Yw=100.0, conditions={'D': 1.0, 'Dtype': None, 'La': 100.0, 'Yb': 20.0, 'surround': 'avg'}, naka_rushton_parameters=None, unique_hue_data=None, mcat='cat16')[source]

See ?luxpy.xyz_to_jab_cam16scd

to_jabM_zcam(xyzw=None, conditions={'D': 1.0, 'Dtype': None, 'La': 100.0, 'Yb': 20.0, 'surround': 'avg'}, mcat='cat16')[source]

See ?luxpy.xyz_to_jabM_zcam

to_jabC_zcam(xyzw=array([[1.0000e+02, 1.0000e+02, 1.0000e+02]]), conditions={'D': 1.0, 'Dtype': None, 'La': 100.0, 'Yb': 20.0, 'surround': 'avg'}, mcat='cat16')[source]

See ?luxpy.xyz_to_jabC_zcam

to_qabW_cam15u(fov=10.0, parameters=None)[source]

See ?luxpy.xyz_to_qabW_cam15u

to_lab_cam_sww_2016(xyzw=None, Yb=20.0, Lw=400.0, relative=True, parameters=None, inputtype='xyz', cieobs='2006_10')[source]

See ?luxpy.xyz_to_lab_cam_sww_2016

to_qabS_cam18sl(xyz, xyzb=None, Lb=[100], fov=10.0, parameters=None)[source]

See ?luxpy.xyz_to_qabS_cam18sl

to_qabM_cam18sl(xyz, xyzb=None, Lb=[100], fov=10.0, parameters=None)[source]

See ?luxpy.xyz_to_qabM_cam18sl

class luxpy.color.CDATA.LAB(value=None, relative=True, cieobs='1931_2', dtype='lab', xyzw=None, M=None, scaling=None, Lw=None, Yw=None, Yb=None, conditions=None, naka_rushton_parameters=None, unique_hue_data=None, yellowbluepurplecorrect=None, mcat=None, ucstype=None, fov=None, parameters=None)[source]
ctf(**kwargs)[source]

Convert color space coordinates to XYZ tristimulus values.

Args:
dtype:
‘xyz’
Convert to this color space.
kwargs:
additional input arguments required for
color space transformation.
See specific luxpy function for more info
(e.g. ?luxpy.xyz_to_lab)
Returns:
returns:
luxpy.XYZ with .value field that is a ndarray
with tristimulus values
plot(plt_type='3d', ax=None, title=None, **kwargs)[source]

Plot color coordinates.

Args:
plt_type:
‘3d’ or 3 or ‘2d or 2, optional
-‘3d’ or 3: plot all 3 dimensions (lightness and chromaticity)
-‘2d’ or 2: plot only chromaticity dimensions.
ax:
None or axes handles, optional
None: create new figure axes, else use :ax: for plotting.
title:
None or str, optional
Give plot a title.
kwargs:
additional arguments for use with
matplotlib.pyplot.scatter
Returns:
gca:
handle to current axes.
to_xyz(**kwargs)[source]

Convert color space coordinates to XYZ tristimulus values.