docstr: Checks if scaling is needed for input array
  
  Raises WriterError if no scaling possible.
  
  The rules are in the code, but:
  
  * If numpy will cast, return False (no scaling needed)
  * If input or output is an object or structured type, raise
  * If input is complex, raise
  * If the output is float, return False
  * If the input array is all zero, return False
  * By now we are casting to (u)int. If the input type is a float, return
    True (we do need scaling)
  * Now input and output types are (u)ints. If the min and max in the
    data are within range of the output type, return False
  * Otherwise return True
docstr_tok: ["Checks","if","scaling","is","needed","for","input","array","Raises","WriterError","if","no","scaling","possible",".","The","rules","are","in","the","code",",","but",":","*","If","numpy","will","cast",",","return","False","(","no","scaling","needed",")","*","If","input","or","output","is","an","object","or","structured","type",",","raise","*","If","input","is","complex",",","raise","*","If","the","output","is","float",",","return","False","*","If","the","input","array","is","all","zero",",","return","False","*","By","now","we","are","casting","to","(","u",")","int",".","If","the","input","type","is","a","float",",","return","True","(","we","do","need","scaling",")","*","Now","input","and","output","types","are","(","u",")","ints",".","If","the","min","and","max","in","the","data","are","within","range","of","the","output","type",",","return","False","*","Otherwise","return","True"]
code: def scaling_needed(self):
      """Checks if scaling is needed for input array
  
      Raises WriterError if no scaling possible.
  
      The rules are in the code, but:
  
      * If numpy will cast, return False (no scaling needed)
      * If input or output is an object or structured type, raise
      * If input is complex, raise
      * If the output is float, return False
      * If the input array is all zero, return False
      * By now we are casting to (u)int. If the input type is a float, return
        True (we do need scaling)
      * Now input and output types are (u)ints. If the min and max in the
        data are within range of the output type, return False
      * Otherwise return True
      """
      data = self._array
      arr_dtype = data.dtype
      out_dtype = self._out_dtype
      # There's a bug in np.can_cast (at least up to and including 1.6.1)
      # such that any structured output type passes.  Check for this first.
      if "V" in (arr_dtype.kind, out_dtype.kind):
          if arr_dtype == out_dtype:
              return False
          raise WriterError("Cannot cast to or from non-numeric types")
      if np.can_cast(arr_dtype, out_dtype):
          return False
      # Direct casting for complex output from any numeric type
      if out_dtype.kind == "c":
          return False
      if arr_dtype.kind == "c":
          raise WriterError("Cannot cast complex types to non-complex")
      # Direct casting for float output from any non-complex numeric type
      if out_dtype.kind == "f":
          return False
      # Now we need to look at the data for special cases
      if data.size == 0:
          return False
      mn, mx = self.finite_range()  # this is cached
      if (mn, mx) == (0, 0):
          # Data all zero
          return False
      # Floats -> (u)ints always need scaling
      if arr_dtype.kind == "f":
          return True
      # (u)int input, (u)int output
      assert arr_dtype.kind in "iu" and out_dtype.kind in "iu"
      info = np.iinfo(out_dtype)
      # No scaling needed if data already fits in output type
      # But note - we need to convert to ints, to avoid conversion to float
      # during comparisons, and therefore int -> float conversions which are
      # not exact.  Only a problem for uint64 though.
      if int(mn) >= int(info.min) and int(mx) <= int(info.max):
          return False
      return True
  
imports: import numpy
  from .casting import best_float, floor_exact, int_abs, shared_range, type_info
  from .volumeutils import array_to_file, finite_range
label_desc: Use image node_id 2 for calling the ArrayWriter obj's underlying member method code with example usage: obj.scaling_needed() and returns: True, False, False, False, False, False, True, False, False