# Path: concert/coroutines/base.py
# def background(coroutine):
#     """Same as :func:`.start`, just meant to be used as a decorator."""
#     @functools.wraps(coroutine)
#     def inner(*args, **kwargs):
#         return start(coroutine(*args, **kwargs))
# 
#     return inner
# 
# def run_in_executor(func, *args):
#     """Run a blocking function *func* with signature func(\*args) in an executor."""
#     # Leave this here for now, if there are problems with the normal run_in_executor returning a
#     # future then let's re-visit
#     # """Run a blocking function *func* with signature func(*args) in an executor, wrap the future
#     # into a real coroutine and return it.
#     # """
#     # async def make_coro():
#     #     loop = asyncio.get_running_loop()
#     #     future = loop.run_in_executor(None, func, *args)
#     #
#     #     try:
#     #         return await future
#     #     except asyncio.CancelledError:
#     #         # Wait for the future to finish even if we are cancelled.
#     #         LOG.log(AIODEBUG, f'{func.__name__} waiting for concurrent.Future')
#     #         return await future
#     # return make_coro()
#     loop = asyncio.get_event_loop()
# 
#     return loop.run_in_executor(None, func, *args)
# 
# Path: concert/quantities.py



import asyncio
import numpy as np
import logging
from scipy.signal import fftconvolve
from concert.coroutines.base import background, run_in_executor
from concert.quantities import q
        from skimage.filters import threshold_otsu
        from skimage.morphology import dilation, disk, convex_hull_image, label
    from scipy.ndimage import gaussian_filter1d
    from numpy.fft import fft2, ifft2, fftshift
        from skimage.filters import sobel
        from skimage.transform import resize
    y = (np.argmax(g) + middle - supersampling) / supersampling + y_start

    return (y, peak[1])


def _get_boundary_coordinates(coordinates, max_val):
    """Return coordinates which reside on image edges."""
    return [coor for coor in coordinates if coor % max_val == 0]


def _is_corner_point(point, shape):
    """Test if the *point* lies in one of the image corners."""
    return (point[1] == 0 or point[1] == shape[1] - 1) and\
        (point[0] == 0 or point[0] == shape[0] - 1)


def _get_intersection_points(image):
    """Get *image* edges and sample intersection points. The *image* is
    a segmented binary image."""
    y_ind, x_ind = np.where(image != 0)
    x_low = x_ind[np.where(y_ind == 0)]
    x_high = x_ind[np.where(y_ind == image.shape[0] - 1)]
    y_low = y_ind[np.where(x_ind == 0)]
    y_high = y_ind[np.where(x_ind == image.shape[1] - 1)]

    points = []
    if len(x_low) != 0:
        points.append((0, x_low[0]))
        if x_low[-1] != x_low[0]:
            points.append((0, x_low[-1]))

# Path: concert/coroutines/base.py
# def background(coroutine):
#     """Same as :func:`.start`, just meant to be used as a decorator."""
#     @functools.wraps(coroutine)
#     def inner(*args, **kwargs):
#         return start(coroutine(*args, **kwargs))
# 
#     return inner
# 
# def run_in_executor(func, *args):
#     """Run a blocking function *func* with signature func(\*args) in an executor."""
#     # Leave this here for now, if there are problems with the normal run_in_executor returning a
#     # future then let's re-visit
#     # """Run a blocking function *func* with signature func(*args) in an executor, wrap the future
#     # into a real coroutine and return it.
#     # """
#     # async def make_coro():
#     #     loop = asyncio.get_running_loop()
#     #     future = loop.run_in_executor(None, func, *args)
#     #
#     #     try:
#     #         return await future
#     #     except asyncio.CancelledError:
#     #         # Wait for the future to finish even if we are cancelled.
#     #         LOG.log(AIODEBUG, f'{func.__name__} waiting for concurrent.Future')
#     #         return await future
#     # return make_coro()
#     loop = asyncio.get_event_loop()
# 
#     return loop.run_in_executor(None, func, *args)
# 
# Path: concert/quantities.py



# Path: concert/imageprocessing.py
import asyncio
import numpy as np
import logging
from scipy.signal import fftconvolve
from concert.coroutines.base import background, run_in_executor
from concert.quantities import q
        from skimage.filters import threshold_otsu
        from skimage.morphology import dilation, disk, convex_hull_image, label
    from scipy.ndimage import gaussian_filter1d
    from numpy.fft import fft2, ifft2, fftshift
        from skimage.filters import sobel
        from skimage.transform import resize

    y = (np.argmax(g) + middle - supersampling) / supersampling + y_start

    return (y, peak[1])


def _get_boundary_coordinates(coordinates, max_val):
    """Return coordinates which reside on image edges."""
    return [coor for coor in coordinates if coor % max_val == 0]


def _is_corner_point(point, shape):
    """Test if the *point* lies in one of the image corners."""
    return (point[1] == 0 or point[1] == shape[1] - 1) and\
        (point[0] == 0 or point[0] == shape[0] - 1)


def _get_intersection_points(image):
    """Get *image* edges and sample intersection points. The *image* is
    a segmented binary image."""
    y_ind, x_ind = np.where(image != 0)
    x_low = x_ind[np.where(y_ind == 0)]
    x_high = x_ind[np.where(y_ind == image.shape[0] - 1)]
    y_low = y_ind[np.where(x_ind == 0)]
    y_high = y_ind[np.where(x_ind == image.shape[1] - 1)]

    points = []
    if len(x_low) != 0:
        points.append((0, x_low[0]))
        if x_low[-1] != x_low[0]:
            points.append((0, x_low[-1]))

    if len(x_high) != 0: