def __array_wrap__(self, out_arr, context=None): ret = super(YTArray, self).__array_wrap__(out_arr, context) if isinstance(ret, YTQuantity) and ret.shape != (): ret = ret.view(YTArray) if context is None: if ret.shape == (): return ret[()] else: return ret elif context[0] in unary_operators: u = getattr(context[1][0], "units", None) if u is None: u = NULL_UNIT unit = self._ufunc_registry[context[0]](u) ret_class = type(self) elif context[0] in binary_operators: oper1 = coerce_iterable_units(context[1][0]) oper2 = coerce_iterable_units(context[1][1]) cls1 = type(oper1) cls2 = type(oper2) unit1 = getattr(oper1, "units", None) unit2 = getattr(oper2, "units", None) ret_class = get_binary_op_return_class(cls1, cls2) if unit1 is None: unit1 = Unit(registry=getattr(unit2, "registry", None)) if unit2 is None and context[0] is not power: unit2 = Unit(registry=getattr(unit1, "registry", None)) elif context[0] is power: unit2 = oper2 if isinstance(unit2, np.ndarray): if isinstance(unit2, YTArray): if unit2.units.is_dimensionless: pass else: raise YTUnitOperationError(context[0], unit1, unit2) unit2 = 1.0 unit_operator = self._ufunc_registry[context[0]] if unit_operator in (preserve_units, comparison_unit, arctan2_unit): if unit1 != unit2: if not unit1.same_dimensions_as(unit2): raise YTUnitOperationError(context[0], unit1, unit2) else: raise YTUfuncUnitError(context[0], unit1, unit2) unit = self._ufunc_registry[context[0]](unit1, unit2) if unit_operator in (multiply_units, divide_units): if unit.is_dimensionless and unit.base_value != 1.0: if not unit1.is_dimensionless: if unit1.dimensions == unit2.dimensions: np.multiply(out_arr.view(np.ndarray), unit.base_value, out=out_arr) unit = Unit(registry=unit.registry) else: raise RuntimeError("Support for the %s ufunc has not been added " "to YTArray." % str(context[0])) if unit is None: out_arr = np.array(out_arr, copy=False) return out_arr out_arr.units = unit if out_arr.size == 1: return YTQuantity(np.array(out_arr), unit) else: if ret_class is YTQuantity: # This happens if you do ndarray * YTQuantity. Explicitly # casting to YTArray avoids creating a YTQuantity with size > 1 return YTArray(np.array(out_arr), unit) return ret_class(np.array(out_arr, copy=False), unit)
def __array_wrap__(self, out_arr, context=None): ret = super(YTArray, self).__array_wrap__(out_arr, context) if isinstance(ret, YTQuantity) and ret.shape != (): ret = ret.view(YTArray) if context is None: if ret.shape == (): return ret[()] else: return ret elif context[0] in unary_operators: u = getattr(context[1][0], 'units', None) if u is None: u = NULL_UNIT unit = self._ufunc_registry[context[0]](u) ret_class = type(self) elif context[0] in binary_operators: oper1 = coerce_iterable_units(context[1][0]) oper2 = coerce_iterable_units(context[1][1]) cls1 = type(oper1) cls2 = type(oper2) unit1 = getattr(oper1, 'units', None) unit2 = getattr(oper2, 'units', None) ret_class = get_binary_op_return_class(cls1, cls2) if unit1 is None: unit1 = Unit(registry=getattr(unit2, 'registry', None)) if unit2 is None and context[0] is not power: unit2 = Unit(registry=getattr(unit1, 'registry', None)) elif context[0] is power: unit2 = oper2 if isinstance(unit2, np.ndarray): if isinstance(unit2, YTArray): if unit2.units.is_dimensionless: pass else: raise YTUnitOperationError(context[0], unit1, unit2) unit2 = 1.0 unit_operator = self._ufunc_registry[context[0]] if unit_operator in (preserve_units, comparison_unit, arctan2_unit): if unit1 != unit2: if not unit1.same_dimensions_as(unit2): raise YTUnitOperationError(context[0], unit1, unit2) else: raise YTUfuncUnitError(context[0], unit1, unit2) unit = self._ufunc_registry[context[0]](unit1, unit2) if unit_operator in (multiply_units, divide_units): if unit.is_dimensionless and unit.base_value != 1.0: if not unit1.is_dimensionless: if unit1.dimensions == unit2.dimensions: np.multiply(out_arr.view(np.ndarray), unit.base_value, out=out_arr) unit = Unit(registry=unit.registry) else: raise RuntimeError("Support for the %s ufunc has not been added " "to YTArray." % str(context[0])) if unit is None: out_arr = np.array(out_arr, copy=False) return out_arr out_arr.units = unit if out_arr.size == 1: return YTQuantity(np.array(out_arr), unit) else: if ret_class is YTQuantity: # This happens if you do ndarray * YTQuantity. Explicitly # casting to YTArray avoids creating a YTQuantity with size > 1 return YTArray(np.array(out_arr), unit) return ret_class(np.array(out_arr, copy=False), unit)
def __array_wrap__(self, out_arr, context=None): ret = super(YTArray, self).__array_wrap__(out_arr, context) if isinstance(ret, YTQuantity) and ret.shape != (): ret = ret.view(YTArray) if context is None: if ret.shape == (): return ret[()] else: return ret elif context[0] in unary_operators: u = getattr(context[1][0], 'units', None) if u is None: u = Unit() try: unit = self._ufunc_registry[context[0]](u) # Catch the RuntimeError raised inside of ensure_same_dimensions # Raise YTUnitOperationError up here since we know the context now except RuntimeError: raise YTUnitOperationError(context[0], u) ret_class = type(self) elif context[0] in binary_operators: oper1 = coerce_iterable_units(context[1][0]) oper2 = coerce_iterable_units(context[1][1]) cls1 = type(oper1) cls2 = type(oper2) unit1 = getattr(oper1, 'units', None) unit2 = getattr(oper2, 'units', None) ret_class = get_binary_op_return_class(cls1, cls2) if unit1 is None: unit1 = Unit(registry=getattr(unit2, 'registry', None)) if unit2 is None and context[0] is not power: unit2 = Unit(registry=getattr(unit1, 'registry', None)) elif context[0] is power: unit2 = oper2 if isinstance(unit2, np.ndarray): if isinstance(unit2, YTArray): if unit2.units.is_dimensionless: pass else: raise YTUnitOperationError(context[0], unit1, unit2) unit2 = 1.0 if self._ufunc_registry[context[0]] in \ (preserve_units, comparison_unit, arctan2_unit): if unit1 != unit2: if not unit1.same_dimensions_as(unit2): raise YTUnitOperationError(context[0], unit1, unit2) else: raise YTUfuncUnitError(context[0], unit1, unit2) try: unit = self._ufunc_registry[context[0]](unit1, unit2) # Catch the RuntimeError raised inside of ensure_same_dimensions # Raise YTUnitOperationError up here since we know the context now except RuntimeError: raise YTUnitOperationError(context[0], unit1, unit2) else: raise RuntimeError("Operation is not defined.") if unit is None: out_arr = np.array(out_arr, copy=False) return out_arr out_arr.units = unit if out_arr.size == 1: return YTQuantity(np.array(out_arr), unit) else: if ret_class is YTQuantity: # This happens if you do ndarray * YTQuantity. Explicitly # casting to YTArray avoids creating a YTQuantity with size > 1 return YTArray(np.array(out_arr, unit)) return ret_class(np.array(out_arr, copy=False), unit)