colour-science / colour

Colour Science for Python
https://www.colour-science.org
BSD 3-Clause "New" or "Revised" License
2.1k stars 260 forks source link

[BUG]: `ValueError` exception raised when using `colour.xy_to_CCT` definition. #1150

Closed vsohler closed 1 year ago

vsohler commented 1 year ago

Description

There is a numpy array exception when calling colour.xy_to_CCT(np.array([ 0.34540765, 0.35500682]))

Code for Reproduction

import colour
import numpy as np

colour.xy_to_CCT(np.array([ 0.34540765, 0.35500682]))

Exception Message

File C:\Python310\lib\site-packages\colour\temperature\__init__.py:364, in xy_to_CCT(xy, method)
    324 """
    325 Return the correlated colour temperature :math:`T_{cp}` from given
    326 *CIE xy* chromaticity coordinates using given method.
   (...)
    359 6500.7420431...
    360 """
    362 method = validate_method(method, XY_TO_CCT_METHODS)
--> 364 return XY_TO_CCT_METHODS[method](xy)

 

File C:\Python310\lib\site-packages\colour\temperature\cie_d.py:113, in xy_to_CCT_CIE_D(xy, optimisation_kwargs)
    109 if optimisation_kwargs is not None:
    110     optimisation_settings.update(optimisation_kwargs)
    112 CCT = as_float_array(
--> 113     [
    114         minimize(
    115             objective_function,
    116             x0=6500,
    117             args=(xy_i,),
    118             **optimisation_settings,
    119         ).x
    120         for xy_i in as_float_array(xy)
    121     ]
    122 )
    124 return as_float(np.reshape(CCT, shape[:-1]))

 

File C:\Python310\lib\site-packages\colour\temperature\cie_d.py:114, in <listcomp>(.0)
    109 if optimisation_kwargs is not None:
    110     optimisation_settings.update(optimisation_kwargs)
    112 CCT = as_float_array(
    113     [
--> 114         minimize(
    115             objective_function,
    116             x0=6500,
    117             args=(xy_i,),
    118             **optimisation_settings,
    119         ).x
    120         for xy_i in as_float_array(xy)
    121     ]
    122 )
    124 return as_float(np.reshape(CCT, shape[:-1]))

 

File C:\Python310\lib\site-packages\scipy\optimize\_minimize.py:684, in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
    681     bounds = standardize_bounds(bounds, x0, meth)
    683 if meth == 'nelder-mead':
--> 684     res = _minimize_neldermead(fun, x0, args, callback, bounds=bounds,
    685                                **options)
    686 elif meth == 'powell':
    687     res = _minimize_powell(fun, x0, args, callback, bounds, **options)

 

File C:\Python310\lib\site-packages\scipy\optimize\_optimize.py:845, in _minimize_neldermead(func, x0, args, callback, maxiter, maxfev, disp, return_all, initial_simplex, xatol, fatol, adaptive, bounds, **unknown_options)
    843 try:
    844     for k in range(N + 1):
--> 845         fsim[k] = func(sim[k])
    846 except _MaxFuncCallError:
    847     pass

 

File C:\Python310\lib\site-packages\scipy\optimize\_optimize.py:569, in _wrap_scalar_function_maxfun_validation.<locals>.function_wrapper(x, *wrapper_args)
    567 ncalls[0] += 1
    568 # A copy of x is sent to the user function (gh13740)
--> 569 fx = function(np.copy(x), *(wrapper_args + args))
    570 # Ideally, we'd like to a have a true scalar returned from f(x). For
    571 # backwards-compatibility, also allow np.array([1.3]),
    572 # np.array([[1.3]]) etc.
    573 if not np.isscalar(fx):

 

File C:\Python310\lib\site-packages\colour\temperature\cie_d.py:99, in xy_to_CCT_CIE_D.<locals>.objective_function(CCT, xy)
     94 def objective_function(
     95     CCT: FloatingOrArrayLike, xy: ArrayLike
     96 ) -> FloatingOrNDArray:
     97     """Objective function."""
---> 99     objective = np.linalg.norm(CCT_to_xy_CIE_D(CCT) - xy)
    101     return as_float(objective)

 

File C:\Python310\lib\site-packages\colour\temperature\cie_d.py:183, in CCT_to_xy_CIE_D(CCT)
    181 y = daylight_locus_function(x)
    182 print([x, y])
--> 183 return tstack([x, y])

 

File C:\Python310\lib\site-packages\colour\utilities\array.py:2032, in tstack(a, dtype)
   1978 """
   1979 Stack given array of arrays :math:`a` along the last axis (tail) to
   1980 produce a stacked array.
   (...)
   2027          [ 5.,  5.,  5.]]]])
   2028 """
   2030 dtype = cast(Type[DTypeFloating], optional(dtype, DEFAULT_FLOAT_DTYPE))
-> 2032 a = as_array(a, dtype)
   2034 if a.ndim <= 2:
   2035     return np.transpose(a)

 

File C:\Python310\lib\site-packages\colour\utilities\array.py:563, in as_array(a, dtype)
    561 if isinstance(a, (KeysView, ValuesView)):
    562     a = list(a)
--> 563 return np.asarray(a, dtype)

 

ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.

Environment Information

OS:
Microsoft Windows 10 Professional
Version 10.0.19045 Build 19045

Python:
Python 3.10.9 (tags/v3.10.9:1dd9be6, Dec  6 2022, 20:01:21) [MSC v.1934 64 bit (AMD64)]
Package           Version
----------------- -------
colour-science    0.4.2
imageio           2.28.1
numpy             1.24.3
Pillow            9.5.0
pip               22.3.1
scipy             1.10.1
setuptools        65.5.0
typing_extensions 4.5.0
KelSolaar commented 1 year ago

Hi @vsohler,

This was fixed in develop a while ago, but it is a really good reminder that we should really work toward releasing 0.4.3!

Cheers,

Thomas

tjdcs commented 1 year ago

@KelSolaar we should move 0.4.3 forward without my performance improvements. Is there anything I can help with that you want done before release?

KelSolaar commented 1 year ago

@tjdcs : We will get the PR in!

An easy option in your case @vsohler would be to downgrade Numpy to 1.23 or alike.

vsohler commented 1 year ago

Many thanks for your suggestion! I managed to get what I wanted by using another computation method. It turns out that those based on scipy.optimize are the only one that were not working.