'Base method which calculates the result of the arithmetic operation.
This method determines the result of the arithmetic operation on the
``data`` including their units and then forwards to other methods
to calculate the other properties for the result (like uncertainty).
Parameters
operation : callable
The operation that is performed on the `NDData`. Supported are
`numpy.add`, `numpy.subtract`, `numpy.multiply` and
`numpy.true_divide`.
operand : same type (class) as self
see :meth:`NDArithmeticMixin.add`
propagate_uncertainties : `bool` or ``None``, optional
see :meth:`NDArithmeticMixin.add`
handle_mask : callable, ``\'first_found\'`` or ``None``, optional
see :meth:`NDArithmeticMixin.add`
handle_meta : callable, ``\'first_found\'`` or ``None``, optional
see :meth:`NDArithmeticMixin.add`
compare_wcs : callable, ``\'first_found\'`` or ``None``, optional
see :meth:`NDArithmeticMixin.add`
uncertainty_correlation : ``Number`` or `~numpy.ndarray`, optional
see :meth:`NDArithmeticMixin.add`
kwargs :
Any other parameter that should be passed to the
different :meth:`NDArithmeticMixin._arithmetic_mask` (or wcs, ...)
methods.
Returns
result : `~numpy.ndarray` or `~astropy.units.Quantity`
The resulting data as array (in case both operands were without
unit) or as quantity if at least one had a unit.
kwargs : `dict`
The kwargs should contain all the other attributes (besides data
and unit) needed to create a new instance for the result. Creating
the new instance is up to the calling method, for example
:meth:`NDArithmeticMixin.add`.'

def _arithmetic(self, operation, operand, propagate_uncertainties=True, handle_mask=np.logical_or, handle_meta=None, uncertainty_correlation=0, compare_wcs=u'first_found', **kwds):

    kwds2 = {u'mask': {}, u'meta': {}, u'wcs': {}, u'data': {}, u'uncertainty': {}}
    for i in kwds:
        splitted = i.split(u'_', 1)
        try:
            kwds2[splitted[0]][splitted[1]] = kwds[i]
        except KeyError:
            raise KeyError(u'Unknown    prefix    {0}    for    parameter    {1}'.format(splitted[0], i))
    kwargs = {}
    if (compare_wcs is None):
        kwargs[u'wcs'] = None
    elif (compare_wcs in [u'ff', u'first_found']):
        if (self.wcs is None):
            kwargs[u'wcs'] = deepcopy(operand.wcs)
        else:
            kwargs[u'wcs'] = deepcopy(self.wcs)
    else:
        kwargs[u'wcs'] = self._arithmetic_wcs(operation, operand, compare_wcs, **kwds2[u'wcs'])
    result = self._arithmetic_data(operation, operand, **kwds2[u'data'])
    if (propagate_uncertainties is None):
        kwargs[u'uncertainty'] = None
    elif (not propagate_uncertainties):
        if (self.uncertainty is None):
            kwargs[u'uncertainty'] = deepcopy(operand.uncertainty)
        else:
            kwargs[u'uncertainty'] = deepcopy(self.uncertainty)
    else:
        kwargs[u'uncertainty'] = self._arithmetic_uncertainty(operation, operand, result, uncertainty_correlation, **kwds2[u'uncertainty'])
    if (handle_mask is None):
        kwargs[u'mask'] = None
    elif (handle_mask in [u'ff', u'first_found']):
        if (self.mask is None):
            kwargs[u'mask'] = deepcopy(operand.mask)
        else:
            kwargs[u'mask'] = deepcopy(self.mask)
    else:
        kwargs[u'mask'] = self._arithmetic_mask(operation, operand, handle_mask, **kwds2[u'mask'])
    if (handle_meta is None):
        kwargs[u'meta'] = None
    elif (handle_meta in [u'ff', u'first_found']):
        if (not self.meta):
            kwargs[u'meta'] = deepcopy(operand.meta)
        else:
            kwargs[u'meta'] = deepcopy(self.meta)
    else:
        kwargs[u'meta'] = self._arithmetic_meta(operation, operand, handle_meta, **kwds2[u'meta'])
    return (result, kwargs)
