def _cri_ref_i(cct, wl3=_WL, ref_type='iestm30', mix_range=[4000, 5000], cieobs='1931_2', force_daylight_below4000K=False, n=None, daylight_locus=None): """ Calculates a reference illuminant spectrum based on cct for color rendering index calculations. """ if mix_range is None: mix_range = _CRI_REF_TYPES[ref_type] if (cct < mix_range[0]) | (ref_type == 'BB'): return blackbody(cct, wl3, n=n) elif (cct > mix_range[0]) | (ref_type == 'DL'): return daylightphase( cct, wl3, force_daylight_below4000K=force_daylight_below4000K, cieobs=cieobs, daylight_locus=daylight_locus) else: SrBB = blackbody(cct, wl3, n=n) SrDL = daylightphase( cct, wl3, verbosity=None, force_daylight_below4000K=force_daylight_below4000K, cieobs=cieobs, daylight_locus=daylight_locus) cmf = _CMF[cieobs]['bar'] if isinstance(cieobs, str) else cieobs wl = SrBB[0] ld = getwld(wl) SrBB = 100.0 * SrBB[1] / np.array(np.sum(SrBB[1] * cmf[2] * ld)) SrDL = 100.0 * SrDL[1] / np.array(np.sum(SrDL[1] * cmf[2] * ld)) Tb, Te = float(mix_range[0]), float(mix_range[1]) cBB, cDL = (Te - cct) / (Te - Tb), (cct - Tb) / (Te - Tb) if cBB < 0.0: cBB = 0.0 elif cBB > 1: cBB = 1.0 if cDL < 0.0: cDL = 0.0 elif cDL > 1: cDL = 1.0 Sr = SrBB * cBB + SrDL * cDL Sr[Sr == float('NaN')] = 0.0 Sr = np.vstack((wl, (Sr / Sr[_POS_WL560]))) return Sr
def calculate_lut(ccts=None, cieobs=None, add_to_lut=True): """ Function that calculates LUT for the ccts stored in ./data/cctluts/cct_lut_cctlist.dat or given as input argument. Calculation is performed for CMF set specified in cieobs. Adds a new (temprorary) field to the _CCT_LUT dict. Args: :ccts: | ndarray or str, optional | list of ccts for which to (re-)calculate the LUTs. | If str, ccts contains path/filename.dat to list. :cieobs: | None or str, optional | str specifying cmf set. Returns: :returns: | ndarray with cct and duv. Note: Function changes the global variable: _CCT_LUT! """ if ccts is None: ccts = getdata('{}cct_lut_cctlist.dat'.format(_CCT_LUT_PATH)) elif isinstance(ccts, str): ccts = getdata(ccts) Yuv = np.ones((ccts.shape[0], 2)) * np.nan for i, cct in enumerate(ccts): Yuv[i, :] = xyz_to_Yuv( spd_to_xyz(blackbody(cct, wl3=[360, 830, 1]), cieobs=cieobs))[:, 1:3] u = Yuv[:, 0, None] # get CIE 1960 u v = (2.0 / 3.0) * Yuv[:, 1, None] # get CIE 1960 v cctuv = np.hstack((ccts, u, v)) if add_to_lut == True: _CCT_LUT[cieobs] = cctuv return cctuv
def spd_to_COI_ASNZS1680(S=None, tf=_COI_CSPACE, cieobs=_COI_CIEOBS, out='COI,cct', extrapolate_rfl=False): """ Calculate the Cyanosis Observation Index (COI) [ASNZS 1680.2.5-1995]. Args: :S: | ndarray with light source spectrum (first column are wavelengths). :tf: | _COI_CSPACE, optional | Color space in which to calculate the COI. | Default is CIELAB. :cieobs: | _COI_CIEOBS, optional | CMF set to use. | Default is '1931_2'. :out: | 'COI,cct' or str, optional | Determines output. :extrapolate_rfl: | False, optional | If False: | limit the wavelength range of the source to that of the standard | reflectance spectra for the 50% and 100% oxygenated blood. Returns: :COI: | ndarray with cyanosis indices for input sources. :cct: | ndarray with correlated color temperatures. Note: Clause 7.2 of the ASNZS 1680.2.5-1995. standard mentions the properties demanded of the light source used in region where visual conditions suitable to the detection of cyanosis should be provided: 1. The correlated color temperature (CCT) of the source should be from 3300 to 5300 K. 2. The cyanosis observation index should not exceed 3.3 """ if S is None: #use default S = _CIE_ILLUMINANTS['F4'] if extrapolate_rfl == False: # _COI_RFL do not cover the full 360-830nm range. wl_min = _COI_RFL_BLOOD[0].min() wl_max = _COI_RFL_BLOOD[0].max() S = S[:, np.where((S[0] >= wl_min) & (S[0] <= wl_max))[0]] # Calculate reference spd: Sr = blackbody(4000, wl3=S[0]) # same wavelength range # Calculate xyz of blood under test source and ref. source: xyzt, xyzwt = spd_to_xyz(S, rfl=_COI_RFL_BLOOD, relative=True, cieobs=cieobs, out=2) xyzr, xyzwr = spd_to_xyz(Sr, rfl=_COI_RFL_BLOOD, relative=True, cieobs=cieobs, out=2) # Calculate color difference between blood under test and ref. DEi = deltaE.DE_cspace(xyzt, xyzr, xyzwt=xyzwt, xyzwr=xyzwr, tf=tf) # Calculate Cyanosis Observation Index: COI = np.nanmean(DEi, axis=0)[:, None] # Calculate cct, if requested: if 'cct' in out.split(','): cct, duv = xyz_to_cct(xyzwt, cieobs=cieobs, out=2) # manage output: if out == 'COI': return COI elif out == 'COI,cct': return COI, cct else: return eval(out)
'_COI_RFL_BLOOD', '_COI_CIEOBS', '_COI_CSPACE', 'spd_to_COI_ASNZS1680' ] # Reflectance spectra of 100% and 50% oxygenated blood _COI_RFL_BLOOD = getdata(_PKG_PATH + _SEP + 'toolboxes' + _SEP + 'photbiochem' + _SEP + 'data' + _SEP + 'ASNZS_1680.2.5_1997_cyanosisindex_100_50.dat', header=None, kind='np', verbosity=0).T _COI_CIEOBS = '1931_2' # default CMF set _COI_CSPACE = 'lab' _COI_REF = blackbody(4000, ) def spd_to_COI_ASNZS1680(S=None, tf=_COI_CSPACE, cieobs=_COI_CIEOBS, out='COI,cct', extrapolate_rfl=False): """ Calculate the Cyanosis Observation Index (COI) [ASNZS 1680.2.5-1995]. Args: :S: | ndarray with light source spectrum (first column are wavelengths). :tf: | _COI_CSPACE, optional