class_docstr: Mixin class to make a texture aware of color limits.
  
  This class contains the shared functionality for the CPU and GPU mixin
  classes below. In some cases this class provides a "generic"
  implementation of a specific method and is then overridden by one of the
  subclasses.
  
  Parameters
  ----------
  data : ndarray | tuple | None
      Texture data in the form of a numpy array. A tuple of the shape of the
      texture can also be given. However, some subclasses may benefit from
      or even require a numpy array to make decisions based on shape **and**
      dtype.
  **texture_kwargs
      Any other keyword arguments to pass to the parent TextureXD class.
class_docstr_tok: ["Mixin","class","to","make","a","texture","aware","of","color","limits",".","This","class","contains","the","shared","functionality","for","the","CPU","and","GPU","mixin","classes","below",".","In","some","cases","this","class","provides","a","``","generic","''","implementation","of","a","specific","method","and","is","then","overridden","by","one","of","the","subclasses",".","Parameters","--","--","--","--","--","data",":","ndarray","|","tuple","|","None","Texture","data","in","the","form","of","a","numpy","array",".","A","tuple","of","the","shape","of","the","texture","can","also","be","given",".","However",",","some","subclasses","may","benefit","from","or","even","require","a","numpy","array","to","make","decisions","based","on","shape","*","*","and","*","*","dtype",".","*","*","texture_kwargs","Any","other","keyword","arguments","to","pass","to","the","parent","TextureXD","class","."]
docstr: Normalize current clims to match texture data inside the shader.
  
  If data is scaled on the CPU then the texture data will be in the range
  0-1 in the _build_texture() method. Inside the fragment shader the
  final contrast adjustment will be applied based on this normalized
  ``clim``.
docstr_tok: ["Normalize","current","clims","to","match","texture","data","inside","the","shader",".","If","data","is","scaled","on","the","CPU","then","the","texture","data","will","be","in","the","range","0-1","in","the","_build_texture","(",")","method",".","Inside","the","fragment","shader","the","final","contrast","adjustment","will","be","applied","based","on","this","normalized","``","clim","``","."]
code: def clim_normalized(self):
      """Normalize current clims to match texture data inside the shader.
  
      If data is scaled on the CPU then the texture data will be in the range
      0-1 in the _build_texture() method. Inside the fragment shader the
      final contrast adjustment will be applied based on this normalized
      ``clim``.
  
      """
      if isinstance(self.clim, str) and self.clim == "auto":
          raise RuntimeError(
              "Can't return 'auto' normalized color limits "
              "until data has been set. Call "
              "'scale_and_set_data' first."
          )
      if self._data_dtype is None:
          raise RuntimeError(
              "Can't return normalized color limits until "
              "data has been set. Call "
              "'scale_and_set_data' first."
          )
      if self.clim[0] == self.clim[1]:
          return self.clim[0], np.inf
      # if the internalformat of the texture is normalized we need to
      # also normalize the clims so they match in-shader
      clim_min = self.normalize_value(self.clim[0], self._data_dtype)
      clim_max = self.normalize_value(self.clim[1], self._data_dtype)
      return clim_min, clim_max
  
imports: import warnings
  import numpy
  from vispy.gloo.texture import Texture2D, Texture3D, convert_dtype_and_clip
label_desc: Use image node_id 6 for calling the _ScaledTextureMixin obj's underlying member method code with example usage: obj.clim_normalized() and returns: clim_min,  clim_max, self,  np