Extension of the MORESANE algorithm. This takes a scale-by-scale approach, attempting to remove all sources
        at the lower scales before moving onto the higher ones. At each step the algorithm may return to previous
        scales to remove the sources uncovered by the deconvolution.

        INPUTS:
        start_scale         (default=1)         The first scale which is to be considered.
        stop_scale          (default=20)        The maximum scale which is to be considered. Optional.
        subregion           (default=None):     Size, in pixels, of the central region to be analyzed and deconvolved.
        sigma_level         (default=4)         Number of sigma at which thresholding is to be performed.
        loop_gain           (default=0.1):      Loop gain for the deconvolution.
        tolerance           (default=0.75):     Tolerance level for object extraction. Significant objects contain
                                                wavelet coefficients greater than the tolerance multiplied by the
                                                maximum wavelet coefficient in the scale under consideration.
        accuracy            (default=1e-6):     Threshold on the standard deviation of the residual noise. Exit main
                                                loop when this threshold is reached.
        major_loop_miter    (default=100):      Maximum number of iterations allowed in the major loop. Exit
                                                condition.
        minor_loop_miter    (default=30):       Maximum number of iterations allowed in the minor loop. Serves as an
                                                exit condition when the SNR does not reach a maximum.
        all_on_gpu          (default=False):    Boolean specifier to toggle all gpu modes on.
        decom_mode          (default='ser'):    Specifier for decomposition mode - serial, multiprocessing, or gpu.
        core_count          (default=1):        In the event that multiprocessing, specifies the number of cores.
        conv_device         (default='cpu'):    Specifier for device to be used - cpu or gpu.
        conv_mode           (default='linear'): Specifier for convolution mode - linear or circular.
        extraction_mode     (default='cpu'):    Specifier for mode to be used - cpu or gpu.
        enforce_positivity  (default=False):    Boolean specifier for whether or not a model must be strictly positive.
        edge_suppression    (default=False):    Boolean specifier for whether or not the edges are to be suprressed.
        edge_offset         (default=0):        Numeric value for an additional user-specified number of edge pixels
                                                to be ignored. This is added to the minimum suppression.

        OUTPUTS:
        self.model          (no default):       Model extracted by the algorithm.
        self.residual       (no default):       Residual signal after deconvolution.

def moresane_by_scale(self, start_scale=1, stop_scale=20, subregion=None, sigma_level=4, loop_gain=0.1,
                          tolerance=0.75, accuracy=1e-6, major_loop_miter=100, minor_loop_miter=30, all_on_gpu=False,
                          decom_mode="ser", core_count=1, conv_device='cpu', conv_mode='linear', extraction_mode='cpu',
                          enforce_positivity=False, edge_suppression=False,
                          edge_offset=0, flux_threshold=0, neg_comp=False, edge_excl=0, int_excl=0):
        """
        Extension of the MORESANE algorithm. This takes a scale-by-scale approach, attempting to remove all sources
        at the lower scales before moving onto the higher ones. At each step the algorithm may return to previous
        scales to remove the sources uncovered by the deconvolution.

        INPUTS:
        start_scale         (default=1)         The first scale which is to be considered.
        stop_scale          (default=20)        The maximum scale which is to be considered. Optional.
        subregion           (default=None):     Size, in pixels, of the central region to be analyzed and deconvolved.
        sigma_level         (default=4)         Number of sigma at which thresholding is to be performed.
        loop_gain           (default=0.1):      Loop gain for the deconvolution.
        tolerance           (default=0.75):     Tolerance level for object extraction. Significant objects contain
                                                wavelet coefficients greater than the tolerance multiplied by the
                                                maximum wavelet coefficient in the scale under consideration.
        accuracy            (default=1e-6):     Threshold on the standard deviation of the residual noise. Exit main
                                                loop when this threshold is reached.
        major_loop_miter    (default=100):      Maximum number of iterations allowed in the major loop. Exit
                                                condition.
        minor_loop_miter    (default=30):       Maximum number of iterations allowed in the minor loop. Serves as an
                                                exit condition when the SNR does not reach a maximum.
        all_on_gpu          (default=False):    Boolean specifier to toggle all gpu modes on.
        decom_mode          (default='ser'):    Specifier for decomposition mode - serial, multiprocessing, or gpu.
        core_count          (default=1):        In the event that multiprocessing, specifies the number of cores.
        conv_device         (default='cpu'):    Specifier for device to be used - cpu or gpu.
        conv_mode           (default='linear'): Specifier for convolution mode - linear or circular.
        extraction_mode     (default='cpu'):    Specifier for mode to be used - cpu or gpu.
        enforce_positivity  (default=False):    Boolean specifier for whether or not a model must be strictly positive.
        edge_suppression    (default=False):    Boolean specifier for whether or not the edges are to be suprressed.
        edge_offset         (default=0):        Numeric value for an additional user-specified number of edge pixels
                                                to be ignored. This is added to the minimum suppression.

        OUTPUTS:
        self.model          (no default):       Model extracted by the algorithm.
        self.residual       (no default):       Residual signal after deconvolution.
        """

        # The following preserves the dirty image as it will be changed on every iteration.

        dirty_data = self.dirty_data

        scale_count = start_scale


        while not (self.complete):

            logger.info("MORESANE at scale {}".format(scale_count))

            self.moresane(subregion=subregion, scale_count=scale_count, sigma_level=sigma_level, loop_gain=loop_gain,
                          tolerance=tolerance, accuracy=accuracy, major_loop_miter=major_loop_miter,
                          minor_loop_miter=minor_loop_miter, all_on_gpu=all_on_gpu, decom_mode=decom_mode,
                          core_count=core_count, conv_device=conv_device, conv_mode=conv_mode,
                          extraction_mode=extraction_mode, enforce_positivity=enforce_positivity,
                          edge_suppression=edge_suppression, edge_offset=edge_offset,
                          flux_threshold=flux_threshold, neg_comp=neg_comp,
                          edge_excl=edge_excl, int_excl=int_excl)

            self.dirty_data = self.residual

            scale_count += 1

            if (scale_count>(np.log2(self.dirty_data.shape[0]))-1):
                logger.info("Maximum scale reached - finished.")
                break

            if (scale_count>stop_scale):
                logger.info("Maximum scale reached - finished.")
                break

        # Restores the original dirty image.

        self.dirty_data = dirty_data
        self.complete = False