code: def apply_chromatic_adaptation(val_x, val_y, val_z, orig_illum, targ_illum,
                                 observer='2', adaptation='bradford'):
      
      # It's silly to have to do this, but some people may want to call this
      # function directly, so we'll protect them from messing up upper/lower case.
      adaptation = adaptation.lower()
  
      # Get white-points for illuminant
      if isinstance(orig_illum, str):
          orig_illum = orig_illum.lower()
          wp_src = color_constants.ILLUMINANTS[observer][orig_illum]
      elif hasattr(orig_illum, '__iter__'):
          wp_src = orig_illum
  
      if isinstance(targ_illum, str):
          targ_illum = targ_illum.lower()
          wp_dst = color_constants.ILLUMINANTS[observer][targ_illum]
      elif hasattr(targ_illum, '__iter__'):
          wp_dst = targ_illum
  
      logger.debug("  \* Applying adaptation matrix: %s", adaptation)
      # Retrieve the appropriate transformation matrix from the constants.
      transform_matrix = _get_adaptation_matrix(wp_src, wp_dst,
                                                observer, adaptation)
  
      # Stuff the XYZ values into a NumPy matrix for conversion.
      XYZ_matrix = numpy.array((val_x, val_y, val_z))
      # Perform the adaptation via matrix multiplication.
      result_matrix = numpy.dot(transform_matrix, XYZ_matrix)
  
      # Return individual X, Y, and Z coordinates.
      return result_matrix[0], result_matrix[1], result_matrix[2]
docs: Applies a chromatic adaptation matrix to convert XYZ values between
      illuminants. It is important to recognize that color transformation results
      in color errors, determined by how far the original illuminant is from the
      target illuminant. For example, D65 to A could result in very high maximum
      deviance.
  
      An informative article with estimate average Delta E values for each
      illuminant conversion may be found at:
  
      http://brucelindbloom.com/ChromAdaptEval.html