# 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)
# 
# def run_in_loop_thread_blocking(coroutine):
#     """Run *coroutine* in a new loop in a separate thread. Useful for third party functions, which
#     are unaware of asyncio and we want to feed them with our asyncio code (like in the optimization
#     module).
#     """
#     global _TLOOP
# 
#     if _TLOOP:
#         raise RuntimeError('Another coroutine is already running in a separate thread. '
#                            'Currently only one coroutine can run in a separate thread at a time.')
# 
#     def run():
#         _TLOOP.run_forever()
# 
#     _TLOOP = asyncio.new_event_loop()
#     thread = Thread(target=run, daemon=False)
#     thread.start()
# 
#     try:
#         future = asyncio.run_coroutine_threadsafe(coroutine, _TLOOP)
#         return future.result()
#     except concurrent.futures.CancelledError as e:
#         LOG.log(AIODEBUG, 'run_in_loop_thread_blocking: %s cancelled', coroutine.__qualname__)
#     finally:
#         _TLOOP.call_soon_threadsafe(_TLOOP.stop)
#         thread.join()
#         _TLOOP.close()
#         _TLOOP = None
# 
# Path: concert/quantities.py



import logging
from functools import wraps
from concert.coroutines.base import background, run_in_executor, run_in_loop_thread_blocking
from concert.quantities import q
    from scipy import optimize as scipy_optimize
    from scipy import optimize as scipy_optimize
    from scipy import optimize as scipy_optimize
    from scipy import optimize as scipy_optimize
    from scipy import optimize as scipy_optimize
    Optimize *parameter* and use the *feedback* (a coroutine function)
    as a result. Other arguments are the same as by :func:`optimize`.
    The function to be optimized is determined as follows::

        await parameter.set(x)
        y = await feedback()

    *callback* is the same as by :func:`optimize`.
    """
    async def function(x_val):
        """
        Create a function from setting a parameter and getting a feedback.
        """
        # Do not go out of the limits
        lower = await parameter.get_lower()
        upper = await parameter.get_upper()
        if lower is not None:
            if lower is not None and x_val < lower:
                x_val = lower
        if upper is not None:
            if upper is not None and x_val > upper:
                x_val = upper
        await parameter.set(x_val)

        return await feedback()

    return await optimize(function, x_0, algorithm, alg_args=alg_args,
                          alg_kwargs=alg_kwargs, callback=callback)



# 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)
# 
# def run_in_loop_thread_blocking(coroutine):
#     """Run *coroutine* in a new loop in a separate thread. Useful for third party functions, which
#     are unaware of asyncio and we want to feed them with our asyncio code (like in the optimization
#     module).
#     """
#     global _TLOOP
# 
#     if _TLOOP:
#         raise RuntimeError('Another coroutine is already running in a separate thread. '
#                            'Currently only one coroutine can run in a separate thread at a time.')
# 
#     def run():
#         _TLOOP.run_forever()
# 
#     _TLOOP = asyncio.new_event_loop()
#     thread = Thread(target=run, daemon=False)
#     thread.start()
# 
#     try:
#         future = asyncio.run_coroutine_threadsafe(coroutine, _TLOOP)
#         return future.result()
#     except concurrent.futures.CancelledError as e:
#         LOG.log(AIODEBUG, 'run_in_loop_thread_blocking: %s cancelled', coroutine.__qualname__)
#     finally:
#         _TLOOP.call_soon_threadsafe(_TLOOP.stop)
#         thread.join()
#         _TLOOP.close()
#         _TLOOP = None
# 
# Path: concert/quantities.py



# Path: concert/optimization.py
import logging
from functools import wraps
from concert.coroutines.base import background, run_in_executor, run_in_loop_thread_blocking
from concert.quantities import q
    from scipy import optimize as scipy_optimize
    from scipy import optimize as scipy_optimize
    from scipy import optimize as scipy_optimize
    from scipy import optimize as scipy_optimize
    from scipy import optimize as scipy_optimize

    Optimize *parameter* and use the *feedback* (a coroutine function)
    as a result. Other arguments are the same as by :func:`optimize`.
    The function to be optimized is determined as follows::

        await parameter.set(x)
        y = await feedback()

    *callback* is the same as by :func:`optimize`.
    """
    async def function(x_val):
        """
        Create a function from setting a parameter and getting a feedback.
        """
        # Do not go out of the limits
        lower = await parameter.get_lower()
        upper = await parameter.get_upper()
        if lower is not None:
            if lower is not None and x_val < lower:
                x_val = lower
        if upper is not None:
            if upper is not None and x_val > upper:
                x_val = upper
        await parameter.set(x_val)

        return await feedback()

    return await optimize(function, x_0, algorithm, alg_args=alg_args,
                          alg_kwargs=alg_kwargs, callback=callback)



@background