<s> import numpy as np <EOL> from collections import defaultdict <EOL> from . util import stacklast <EOL> from . testing import check_conversion <EOL> from . basics import ( sRGB1_to_sRGB1_linear , sRGB1_linear_to_sRGB1 , <EOL> sRGB1_linear_to_XYZ100 , XYZ100_to_sRGB1_linear , <EOL> XYZ_to_xyY , xyY_to_XYZ , <EOL> XYZ100_to_CIELab , CIELab_to_XYZ100 , <EOL> CIELab_to_CIELCh , CIELCh_to_CIELab ) <EOL> from . ciecam02 import CIECAM02Space <EOL> from . luoetal2006 import ( LuoEtAl2006UniformSpace , <EOL> CAM02UCS , CAM02LCD , CAM02SCD ) <EOL> from . cvd import machado_et_al_2009_matrix <EOL> from . transform_graph import Edge , MATCH , ANY , TransformGraph <EOL> __all__ = [ "<STR_LIT>" , "<STR_LIT>" ] <EOL> EDGES = [ ] <EOL> def pair ( a , b , a2b , b2a ) : <EOL> if isinstance ( a , str ) : <EOL> a = { "<STR_LIT:name>" : a } <EOL> if isinstance ( b , str ) : <EOL> b = { "<STR_LIT:name>" : b } <EOL> return [ Edge ( a , b , a2b ) , Edge ( b , a , b2a ) ] <EOL> EDGES += pair ( "<STR_LIT>" , "<STR_LIT>" , <EOL> lambda sRGB1 : np . asarray ( sRGB1 ) * <NUM_LIT> , <EOL> lambda sRGB255 : np . asarray ( sRGB255 ) / <NUM_LIT> ) <EOL> def _apply_rgb_mat ( mat , rgb ) : <EOL> return np . einsum ( "<STR_LIT>" , mat , rgb ) <EOL> def _CVD_forward ( sRGB , cvd_type , severity ) : <EOL> mat = machado_et_al_2009_matrix ( cvd_type , severity ) <EOL> return _apply_rgb_mat ( mat , sRGB ) <EOL> def _CVD_inverse ( sRGB , cvd_type , severity ) : <EOL> forward = machado_et_al_2009_matrix ( cvd_type , severity ) <EOL> return _apply_rgb_mat ( np . linalg . inv ( forward ) , sRGB ) <EOL> EDGES += pair ( { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : MATCH , "<STR_LIT>" : MATCH } , <EOL> { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : MATCH , "<STR_LIT>" : MATCH } , <EOL> lambda x , ** kwargs : sRGB1_to_sRGB1_linear ( x ) , <EOL> lambda x , ** kwargs : sRGB1_linear_to_sRGB1 ( x ) , <EOL> ) <EOL> EDGES += pair ( { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : ANY , "<STR_LIT>" : ANY } , <EOL> "<STR_LIT>" , <EOL> _CVD_forward , _CVD_inverse ) <EOL> EDGES += pair ( "<STR_LIT>" , "<STR_LIT>" , sRGB1_to_sRGB1_linear , sRGB1_linear_to_sRGB1 ) <EOL> EDGES += pair ( "<STR_LIT>" , "<STR_LIT>" , sRGB1_linear_to_XYZ100 , XYZ100_to_sRGB1_linear ) <EOL> EDGES += pair ( "<STR_LIT>" , "<STR_LIT>" , <EOL> lambda XYZ100 : np . asarray ( XYZ100 ) / <NUM_LIT> , <EOL> lambda XYZ1 : np . asarray ( XYZ1 ) * <NUM_LIT> ) <EOL> EDGES += pair ( "<STR_LIT>" , "<STR_LIT>" , XYZ_to_xyY , xyY_to_XYZ ) <EOL> EDGES += pair ( "<STR_LIT>" , "<STR_LIT>" , XYZ_to_xyY , xyY_to_XYZ ) <EOL> EDGES += pair ( "<STR_LIT>" , { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : ANY } , <EOL> XYZ100_to_CIELab , CIELab_to_XYZ100 ) <EOL> def _CIELab_to_CIELCh ( CIELab , XYZ100_w ) : <EOL> return CIELab_to_CIELCh ( CIELab ) <EOL> def _CIELCh_to_CIELab ( CIELCh , XYZ100_w ) : <EOL> return CIELCh_to_CIELab ( CIELCh ) <EOL> EDGES += pair ( { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : MATCH } , <EOL> { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : MATCH } , <EOL> _CIELab_to_CIELCh , _CIELCh_to_CIELab ) <EOL> def _XYZ100_to_CIECAM02 ( XYZ100 , ciecam02_space ) : <EOL> return ciecam02_space . XYZ100_to_CIECAM02 ( XYZ100 ) <EOL> def _CIECAM02_to_XYZ100 ( CIECAM02 , ciecam02_space ) : <EOL> return ciecam02_space . CIECAM02_to_XYZ100 ( J = CIECAM02 . J , <EOL> C = CIECAM02 . C , <EOL> h = CIECAM02 . h ) <EOL> EDGES += pair ( "<STR_LIT>" , { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : ANY } , <EOL> _XYZ100_to_CIECAM02 , _CIECAM02_to_XYZ100 ) <EOL> _CIECAM02_axes = set ( "<STR_LIT>" ) <EOL> def _CIECAM02_to_CIECAM02_subset ( CIECAM02 , ciecam02_space , axes ) : <EOL> pieces = [ ] <EOL> for axis in axes : <EOL> pieces . append ( getattr ( CIECAM02 , axis ) ) <EOL> return stacklast ( * pieces ) <EOL> def _CIECAM02_subset_to_XYZ100 ( subset , ciecam02_space , axes ) : <EOL> subset = np . asarray ( subset , dtype = float ) <EOL> kwargs = { } <EOL> if subset . shape [ - <NUM_LIT:1> ] != len ( axes ) : <EOL> raise ValueError ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> % ( subset . shape [ - <NUM_LIT:1> ] , len ( axes ) , axes ) ) <EOL> for i , coord in enumerate ( axes ) : <EOL> kwargs [ coord ] = subset [ ... , i ] <EOL> return ciecam02_space . CIECAM02_to_XYZ100 ( ** kwargs ) <EOL> EDGES += [ <EOL> Edge ( { "<STR_LIT:name>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : MATCH } , <EOL> { "<STR_LIT:name>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : MATCH , "<STR_LIT>" : ANY } , <EOL> _CIECAM02_to_CIECAM02_subset ) , <EOL> Edge ( { "<STR_LIT:name>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : ANY , "<STR_LIT>" : ANY } , <EOL> { "<STR_LIT:name>" : "<STR_LIT>" } , <EOL> _CIECAM02_subset_to_XYZ100 ) , <EOL> ] <EOL> def _JMh_to_LuoEtAl2006 ( JMh , ciecam02_space , luoetal2006_space , axes ) : <EOL> return luoetal2006_space . JMh_to_Jpapbp ( JMh ) <EOL> def _LuoEtAl2006_to_JMh ( Jpapbp , ciecam02_space , luoetal2006_space , axes ) : <EOL> return luoetal2006_space . Jpapbp_to_JMh ( Jpapbp ) <EOL> EDGES += pair ( { "<STR_LIT:name>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : MATCH , <EOL> "<STR_LIT>" : "<STR_LIT>" } , <EOL> { "<STR_LIT:name>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : MATCH , <EOL> "<STR_LIT>" : ANY } , <EOL> _JMh_to_LuoEtAl2006 , _LuoEtAl2006_to_JMh ) <EOL> GRAPH = TransformGraph ( EDGES , <EOL> [ [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ] , <EOL> [ "<STR_LIT>" , "<STR_LIT>" ] , <EOL> ] ) <EOL> ALIASES = { <EOL> "<STR_LIT>" : CAM02UCS , <EOL> "<STR_LIT>" : CAM02LCD , <EOL> "<STR_LIT>" : CAM02SCD , <EOL> "<STR_LIT>" : CIECAM02Space . sRGB , <EOL> "<STR_LIT>" : { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : CIECAM02Space . sRGB . XYZ100_w } , <EOL> "<STR_LIT>" : { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : CIECAM02Space . sRGB . XYZ100_w } , <EOL> } <EOL> def norm_cspace_id ( cspace ) : <EOL> try : <EOL> cspace = ALIASES [ cspace ] <EOL> except ( KeyError , TypeError ) : <EOL> pass <EOL> if isinstance ( cspace , str ) : <EOL> if _CIECAM02_axes . issuperset ( cspace ) : <EOL> return { "<STR_LIT:name>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : CIECAM02Space . sRGB , <EOL> "<STR_LIT>" : cspace } <EOL> else : <EOL> return { "<STR_LIT:name>" : cspace } <EOL> elif isinstance ( cspace , CIECAM02Space ) : <EOL> return { "<STR_LIT:name>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : cspace } <EOL> elif isinstance ( cspace , LuoEtAl2006UniformSpace ) : <EOL> return { "<STR_LIT:name>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : CIECAM02Space . sRGB , <EOL> "<STR_LIT>" : cspace } <EOL> elif isinstance ( cspace , dict ) : <EOL> if cspace [ "<STR_LIT:name>" ] in ALIASES : <EOL> base = ALIASES [ cspace [ "<STR_LIT:name>" ] ] <EOL> if isinstance ( base , dict ) and base [ "<STR_LIT:name>" ] == cspace [ "<STR_LIT:name>" ] : <EOL> return cspace <EOL> else : <EOL> base = norm_cspace_id ( base ) <EOL> cspace = dict ( cspace ) <EOL> del cspace [ "<STR_LIT:name>" ] <EOL> base = dict ( base ) <EOL> base . update ( cspace ) <EOL> return base <EOL> return cspace <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" % ( cspace , ) ) <EOL> def cspace_converter ( start , end ) : <EOL> """<STR_LIT>""" <EOL> start = norm_cspace_id ( start ) <EOL> end = norm_cspace_id ( end ) <EOL> return GRAPH . get_transform ( start , end ) <EOL> def cspace_convert ( arr , start , end ) : <EOL> """<STR_LIT>""" <EOL> converter = cspace_converter ( start , end ) <EOL> return converter ( arr ) <EOL> def check_cspace_convert ( source_cspace , target_cspace , gold , ** kwargs ) : <EOL> def forward ( source_values ) : <EOL> return cspace_convert ( source_values , source_cspace , target_cspace ) <EOL> def reverse ( target_values ) : <EOL> return cspace_convert ( target_values , target_cspace , source_cspace ) <EOL> check_conversion ( forward , reverse , gold , ** kwargs ) <EOL> def test_cspace_convert_trivial ( ) : <EOL> check_cspace_convert ( "<STR_LIT>" , "<STR_LIT>" , <EOL> [ ( [ <NUM_LIT:0.1> , <NUM_LIT> , <NUM_LIT> ] , [ <NUM_LIT:0.1> , <NUM_LIT> , <NUM_LIT> ] ) , <EOL> ( [ <NUM_LIT> , <NUM_LIT> , <NUM_LIT:0.1> ] , [ <NUM_LIT> , <NUM_LIT> , <NUM_LIT:0.1> ] ) , <EOL> ] ) <EOL> def test_cspace_convert_long_paths ( ) : <EOL> from . gold_values import sRGB1_xyY100_gold <EOL> check_cspace_convert ( "<STR_LIT>" , "<STR_LIT>" , sRGB1_xyY100_gold , <EOL> a_min = <NUM_LIT:0> , a_max = <NUM_LIT:1> , <EOL> b_min = <NUM_LIT:0> , b_max = [ <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:100> ] ) <EOL> from . gold_values import sRGB1_xyY1_gold <EOL> check_cspace_convert ( "<STR_LIT>" , "<STR_LIT>" , sRGB1_xyY1_gold , <EOL> a_min = <NUM_LIT:0> , a_max = <NUM_LIT:1> , <EOL> b_min = <NUM_LIT:0> , b_max = <NUM_LIT:1> ) <EOL> from . gold_values import XYZ1_sRGB255_gold <EOL> check_cspace_convert ( "<STR_LIT>" , "<STR_LIT>" , XYZ1_sRGB255_gold , <EOL> a_min = <NUM_LIT:0> , a_max = <NUM_LIT:1> , <EOL> b_min = <NUM_LIT:0> , b_max = <NUM_LIT:255> ) <EOL> from . gold_values import sRGB1_CIELab_gold_D65 <EOL> check_cspace_convert ( "<STR_LIT>" , "<STR_LIT>" , sRGB1_CIELab_gold_D65 , <EOL> a_min = <NUM_LIT:0> , a_max = <NUM_LIT:1> , <EOL> b_min = [ <NUM_LIT:10> , - <NUM_LIT:30> , <NUM_LIT:30> ] , b_max = [ <NUM_LIT> , <NUM_LIT:30> , <NUM_LIT:30> ] , <EOL> gold_rtol = <NUM_LIT> ) <EOL> from . gold_values import XYZ100_CIELab_gold_D50 <EOL> check_cspace_convert ( "<STR_LIT>" , { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : "<STR_LIT>" } , <EOL> XYZ100_CIELab_gold_D50 , <EOL> b_min = [ <NUM_LIT:10> , - <NUM_LIT:30> , <NUM_LIT:30> ] , b_max = [ <NUM_LIT> , <NUM_LIT:30> , <NUM_LIT:30> ] ) <EOL> from . gold_values import XYZ100_CIELCh_gold_D65 <EOL> check_cspace_convert ( "<STR_LIT>" , "<STR_LIT>" , <EOL> XYZ100_CIELCh_gold_D65 , <EOL> a_min = [ <NUM_LIT:10> , - <NUM_LIT:30> , <NUM_LIT:30> ] , a_max = [ <NUM_LIT> , <NUM_LIT:30> , <NUM_LIT:30> ] , <EOL> b_min = <NUM_LIT:0> , b_max = [ <NUM_LIT:100> , <NUM_LIT:50> , <NUM_LIT> ] ) <EOL> from . gold_values import XYZ100_CIELCh_gold_D50 <EOL> check_cspace_convert ( "<STR_LIT>" , <EOL> { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : "<STR_LIT>" } , <EOL> XYZ100_CIELCh_gold_D50 , <EOL> a_min = [ <NUM_LIT:10> , - <NUM_LIT:30> , <NUM_LIT:30> ] , a_max = [ <NUM_LIT> , <NUM_LIT:30> , <NUM_LIT:30> ] , <EOL> b_min = <NUM_LIT:0> , b_max = [ <NUM_LIT:100> , <NUM_LIT:50> , <NUM_LIT> ] ) <EOL> from . gold_values import XYZ100_CIECAM02_gold <EOL> for t in XYZ100_CIECAM02_gold : <EOL> xyY100 = cspace_convert ( t . XYZ100 , "<STR_LIT>" , "<STR_LIT>" ) <EOL> CIECAM02_got = cspace_convert ( xyY100 , "<STR_LIT>" , t . vc ) <EOL> for i in range ( len ( CIECAM02_got ) ) : <EOL> assert np . allclose ( CIECAM02_got [ i ] , t . expected [ i ] , atol = <NUM_LIT> ) <EOL> xyY100_got = cspace_convert ( CIECAM02_got , t . vc , "<STR_LIT>" ) <EOL> assert np . allclose ( xyY100_got , xyY100 ) <EOL> def subset ( axes ) : <EOL> return { "<STR_LIT:name>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : axes , "<STR_LIT>" : t . vc } <EOL> JCh = stacklast ( t . expected . J , t . expected . C , t . expected . h ) <EOL> xyY100_got2 = cspace_convert ( JCh , subset ( "<STR_LIT>" ) , "<STR_LIT>" ) <EOL> assert np . allclose ( xyY100_got2 , xyY100 ) <EOL> JCh_got = cspace_convert ( xyY100 , "<STR_LIT>" , subset ( "<STR_LIT>" ) ) <EOL> assert np . allclose ( JCh_got , JCh , rtol = <NUM_LIT> ) <EOL> QMH = stacklast ( t . expected . Q , t . expected . M , t . expected . H ) <EOL> check_cspace_convert ( subset ( "<STR_LIT>" ) , subset ( "<STR_LIT>" ) , <EOL> [ ( JCh , QMH ) ] , <EOL> a_max = [ <NUM_LIT:100> , <NUM_LIT:100> , <NUM_LIT> ] , <EOL> b_max = [ <NUM_LIT:100> , <NUM_LIT:100> , <NUM_LIT> ] ) <EOL> t1 = XYZ100_CIECAM02_gold [ <NUM_LIT:0> ] <EOL> t2 = XYZ100_CIECAM02_gold [ <NUM_LIT:1> ] <EOL> got2 = cspace_convert ( t1 . expected , t1 . vc , t2 . vc ) <EOL> for i in range ( len ( got2 ) ) : <EOL> assert np . allclose ( got2 [ i ] , t2 . expected [ i ] , atol = <NUM_LIT> ) <EOL> JCh1 = stacklast ( t1 . expected . J , t1 . expected . C , t1 . expected . h ) <EOL> JCh2 = stacklast ( t2 . expected . J , t2 . expected . C , t2 . expected . h ) <EOL> JCh_space1 = { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : t1 . vc } <EOL> JCh_space2 = { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : t2 . vc } <EOL> check_cspace_convert ( JCh_space1 , JCh_space2 , <EOL> [ ( JCh1 , JCh2 ) ] , <EOL> a_max = [ <NUM_LIT:100> , <NUM_LIT:100> , <NUM_LIT> ] , <EOL> b_max = [ <NUM_LIT:100> , <NUM_LIT:100> , <NUM_LIT> ] ) <EOL> from . gold_values import JMh_to_CAM02UCS_silver <EOL> check_cspace_convert ( "<STR_LIT>" , "<STR_LIT>" , JMh_to_CAM02UCS_silver , <EOL> a_max = [ <NUM_LIT:100> , <NUM_LIT:100> , <NUM_LIT> ] , <EOL> b_min = [ <NUM_LIT:0> , - <NUM_LIT:30> , - <NUM_LIT:30> ] , b_max = [ <NUM_LIT:100> , <NUM_LIT:30> , <NUM_LIT:30> ] ) <EOL> from . gold_values import JMh_to_CAM02LCD_silver <EOL> check_cspace_convert ( "<STR_LIT>" , "<STR_LIT>" , JMh_to_CAM02LCD_silver , <EOL> a_max = [ <NUM_LIT:100> , <NUM_LIT:100> , <NUM_LIT> ] , <EOL> b_min = [ <NUM_LIT:0> , - <NUM_LIT:30> , - <NUM_LIT:30> ] , b_max = [ <NUM_LIT:100> , <NUM_LIT:30> , <NUM_LIT:30> ] ) <EOL> from . gold_values import JMh_to_CAM02SCD_silver <EOL> check_cspace_convert ( "<STR_LIT>" , "<STR_LIT>" , JMh_to_CAM02SCD_silver , <EOL> a_max = [ <NUM_LIT:100> , <NUM_LIT:100> , <NUM_LIT> ] , <EOL> b_min = [ <NUM_LIT:0> , - <NUM_LIT:30> , - <NUM_LIT:30> ] , b_max = [ <NUM_LIT:100> , <NUM_LIT:30> , <NUM_LIT:30> ] ) <EOL> from . gold_values import CVD_deut50_to_sRGB1_silver <EOL> check_cspace_convert ( <EOL> { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : "<STR_LIT>" , "<STR_LIT>" : <NUM_LIT:50> } , <EOL> "<STR_LIT>" , <EOL> CVD_deut50_to_sRGB1_silver , <EOL> ) <EOL> from . gold_values import CVD_prot95_to_sRGB1_silver <EOL> check_cspace_convert ( <EOL> { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : "<STR_LIT>" , "<STR_LIT>" : <NUM_LIT> } , <EOL> "<STR_LIT>" , <EOL> CVD_prot95_to_sRGB1_silver , <EOL> ) <EOL> def test_CIECAM02_subset_error_checking ( ) : <EOL> from nose . tools import assert_raises <EOL> assert_raises ( ValueError , <EOL> cspace_convert , np . ones ( ( <NUM_LIT:5> , <NUM_LIT:4> ) ) , "<STR_LIT>" , "<STR_LIT>" ) <EOL> def test_name_aliases ( ) : <EOL> from . gold_values import JMh_to_CAM02UCS_silver <EOL> check_cspace_convert ( "<STR_LIT>" , "<STR_LIT>" , JMh_to_CAM02UCS_silver , <EOL> a_max = [ <NUM_LIT:100> , <NUM_LIT:100> , <NUM_LIT> ] , <EOL> b_min = [ <NUM_LIT:0> , - <NUM_LIT:30> , - <NUM_LIT:30> ] , b_max = [ <NUM_LIT:100> , <NUM_LIT:30> , <NUM_LIT:30> ] ) <EOL> check_cspace_convert ( "<STR_LIT>" , { "<STR_LIT:name>" : "<STR_LIT>" } , <EOL> JMh_to_CAM02UCS_silver , <EOL> a_max = [ <NUM_LIT:100> , <NUM_LIT:100> , <NUM_LIT> ] , <EOL> b_min = [ <NUM_LIT:0> , - <NUM_LIT:30> , - <NUM_LIT:30> ] , b_max = [ <NUM_LIT:100> , <NUM_LIT:30> , <NUM_LIT:30> ] ) <EOL> weird_space = CIECAM02Space ( "<STR_LIT>" , <NUM_LIT> , <NUM_LIT:30> ) <EOL> assert np . allclose ( <EOL> cspace_convert ( [ <NUM_LIT:0.1> , <NUM_LIT> , <NUM_LIT> ] , <EOL> "<STR_LIT>" , <EOL> { "<STR_LIT:name>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : weird_space } ) , <EOL> cspace_convert ( [ <NUM_LIT:0.1> , <NUM_LIT> , <NUM_LIT> ] , <EOL> "<STR_LIT>" , <EOL> { "<STR_LIT:name>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : weird_space , <EOL> "<STR_LIT>" : CAM02UCS } ) ) <EOL> from nose . tools import assert_raises <EOL> assert_raises ( ValueError , <EOL> cspace_convert , [ <NUM_LIT:1> , <NUM_LIT:2> , <NUM_LIT:3> ] , "<STR_LIT>" , object ( ) ) <EOL> assert_raises ( ValueError , <EOL> cspace_convert , [ <NUM_LIT:1> , <NUM_LIT:2> , <NUM_LIT:3> ] , "<STR_LIT>" , "<STR_LIT>" ) </s>
