Scales the control and IP data to million mapped reads, then subtracts
        scaled control from scaled IP, applies `func(diffed)` to the diffed
        array, and finally sets `self.diffed_array` to be the result.

        Arrays `self.ip` and `self.control` are set as well, and if
        `force=False`, then previously-created arrays will be used instead of
        re-calculating new ones.  This is useful if you want to easily try
        multiple `func` functions without having to re-calculate the data.

        Another side-effect is that `self.features` is set so that it can be
        accesed by other methods.

        :param features: a list of pybedtools.Interval objects
        :param array_kwargs: extra keyword args passed to genomic_signal.array;
            typically this will include `bins`, `processes`, and `chunksize`
            arguments.
        :param func: a function to apply to the diffed arrays. By default
            this is :func:`metaseq.plotutils.nice_log`; another option might be
            `lambda x: x`, or `lambda x: 1e6*x`
        :param force: Force a re-calculation of the arrays; otherwise uses
            cached values

def diff_array(self, features, force=True, func=None,
                   array_kwargs=dict(), cache=None):
        """
        Scales the control and IP data to million mapped reads, then subtracts
        scaled control from scaled IP, applies `func(diffed)` to the diffed
        array, and finally sets `self.diffed_array` to be the result.

        Arrays `self.ip` and `self.control` are set as well, and if
        `force=False`, then previously-created arrays will be used instead of
        re-calculating new ones.  This is useful if you want to easily try
        multiple `func` functions without having to re-calculate the data.

        Another side-effect is that `self.features` is set so that it can be
        accesed by other methods.

        :param features: a list of pybedtools.Interval objects
        :param array_kwargs: extra keyword args passed to genomic_signal.array;
            typically this will include `bins`, `processes`, and `chunksize`
            arguments.
        :param func: a function to apply to the diffed arrays. By default
            this is :func:`metaseq.plotutils.nice_log`; another option might be
            `lambda x: x`, or `lambda x: 1e6*x`
        :param force: Force a re-calculation of the arrays; otherwise uses
            cached values
        """
        self.features = list(features)
        self.browser_local_coverage_kwargs = array_kwargs.copy()
        self.browser_local_coverage_kwargs.pop('processes', None)
        self.browser_local_coverage_kwargs.pop('chunksize', 1)

        self.array_kwargs = array_kwargs.copy()

        if (self.ip_array is None) or force:
            self.ip_array = self.ip.array(features, **array_kwargs)
            self.ip_array /= self.ip.mapped_read_count() / 1e6

        if (self.control_array is None) or force:
            self.control_array = self.control.array(features, **array_kwargs)
            self.control_array /= self.control.mapped_read_count() / 1e6

        if func is None:
            #func = metaseq.plotutils.nice_log
            self.diffed_array = self.ip_array - self.control_array
        else:
            self.diffed_array = func(self.ip_array - self.control_array)