Subclassing NDData and NDUncertainty

Subclassing NDUncertainty

New error classes should sub-class from NDUncertainty, and should provide methods with the following API:

class MyUncertainty(NDUncertainty):

    def propagate_add(self, other_nddata, result_data):
        ...
        result_uncertainty = MyUncertainty(...)
        return result_uncertainty

    def propagate_subtract(self, other_nddata, result_data):
        ...
        result_uncertainty = MyUncertainty(...)
        return result_uncertainty

    def propagate_multiply(self, other_nddata, result_data):
        ...
        result_uncertainty = MyUncertainty(...)
        return result_uncertainty

    def propagate_divide(self, other_nddata, result_data):
        ...
        result_uncertainty = MyUncertainty(...)
        return result_uncertainty

All error sub-classes inherit an attribute self.parent_nddata that is automatically set to the parent NDData object that they are attached to. The arguments passed to the error propagation methods are other_nddata, which is the NDData object that is being combined with self.parent_nddata, and result_data, which is a Numpy array that contains the data array after the arithmetic operation. All these methods should return an error instance result_uncertainty, and should not modify parent_nddata directly. For subtraction and division, the order of the operations is parent_nddata - other_nddata and parent_nddata / other_nddata.

To make it easier and clearer to code up the error propagation, you can use variables with more explicit names, e.g:

class MyUncertainty(NDUncertainty):

    def propogate_add(self, other_nddata, result_data):

        left_uncertainty = self.parent.uncertainty.array
        right_uncertainty = other_nddata.uncertainty.array

        ...

Note that the above example assumes that the errors are stored in an array attribute, but this does not have to be the case.

For an example of a complete implementation, see StdDevUncertainty.