def get_illuminant_xyz(self, observer=None, illuminant=None): """ :param str observer: Get the XYZ values for another observer angle. Must be either '2' or '10'. :param str illuminant: Get the XYZ values for another illuminant. :returns: the color's illuminant's XYZ values. """ try: if observer is None: observer = self.observer illums_observer = color_constants.ILLUMINANTS[observer] except KeyError: raise InvalidObserverError(self) try: if illuminant is None: illuminant = self.illuminant illum_xyz = illums_observer[illuminant] except (KeyError, AttributeError): raise InvalidIlluminantError(illuminant) return {'X': illum_xyz[0], 'Y': illum_xyz[1], 'Z': illum_xyz[2]}
def Spectral_to_XYZ(cobj, illuminant_override=None, *args, **kwargs): """ Converts spectral readings to XYZ. """ # If the user provides an illuminant_override numpy array, use it. if illuminant_override: reference_illum = illuminant_override else: # Otherwise, look up the illuminant from known standards based # on the value of 'illuminant' pulled from the SpectralColor object. try: reference_illum = spectral_constants.REF_ILLUM_TABLE[ cobj.illuminant] except KeyError: raise InvalidIlluminantError(cobj.illuminant) # Get the spectral distribution of the selected standard observer. if cobj.observer == '10': std_obs_x = spectral_constants.STDOBSERV_X10 std_obs_y = spectral_constants.STDOBSERV_Y10 std_obs_z = spectral_constants.STDOBSERV_Z10 else: # Assume 2 degree, since it is theoretically the only other possibility. std_obs_x = spectral_constants.STDOBSERV_X2 std_obs_y = spectral_constants.STDOBSERV_Y2 std_obs_z = spectral_constants.STDOBSERV_Z2 # This is a NumPy array containing the spectral distribution of the color. sample = cobj.get_numpy_array() # The denominator is constant throughout the entire calculation for X, # Y, and Z coordinates. Calculate it once and re-use. denom = std_obs_y * reference_illum # This is also a common element in the calculation whereby the sample # NumPy array is multiplied by the reference illuminant's power distribution # (which is also a NumPy array). sample_by_ref_illum = sample * reference_illum # Calculate the numerator of the equation to find X. x_numerator = sample_by_ref_illum * std_obs_x y_numerator = sample_by_ref_illum * std_obs_y z_numerator = sample_by_ref_illum * std_obs_z xyz_x = x_numerator.sum() / denom.sum() xyz_y = y_numerator.sum() / denom.sum() xyz_z = z_numerator.sum() / denom.sum() return XYZColor(xyz_x, xyz_y, xyz_z, observer=cobj.observer, illuminant=cobj.illuminant)
def set_illuminant(self, illuminant): """ Validates and sets the color's illuminant. .. note:: This only changes the illuminant. It does no conversion of the color's coordinates. For this, you'll want to refer to :py:meth:`XYZColor.apply_adaptation <colormath.color_objects.XYZColor.apply_adaptation>`. .. tip:: Call this after setting your observer. :param str illuminant: One of the various illuminants. """ illuminant = illuminant.lower() if illuminant not in color_constants.ILLUMINANTS[self.observer]: raise InvalidIlluminantError(illuminant) self.illuminant = illuminant