# Path: concert/helpers.py
# def memoize(func):
#     """
#     Memoize the result of *func*.
# 
#     Remember the result of *func* depending on its arguments. Note, that this
#     requires that the function is free from any side effects, e.g. returns the
#     same value given the same arguments.
#     """
#     memo = {}
# 
#     if inspect.iscoroutinefunction(func):
#         async def wrapper(*args):
#             if args in memo:
#                 return memo[args]
# 
#             result = await func(*args)
#             memo[args] = result
#             return result
#     else:
#         def wrapper(*args):
#             if args in memo:
#                 return memo[args]
# 
#             result = func(*args)
#             memo[args] = result
#             return result
# 
#     return wrapper
# 
# 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_loop(coroutine):
#     """Wrap *coroutine* into a `asyncio.Task`, run it in the current loop, block until it finishes
#     and return the result.  On KeyboardInterrupt, the task is cancelled.
#     """
#     loop = asyncio.get_event_loop()
#     task = asyncio.ensure_future(coroutine, loop=loop)
# 
#     try:
#         result = loop.run_until_complete(task)
#         return result
#     except KeyboardInterrupt:
#         # _coro instead of get_coro() for Python 3.7 compatibilityget_coro()
#         LOG.log(AIODEBUG, "KeyboardInterrupt in `%s', cancelling", task._coro.__qualname__)
#         task.cancel()
# 
# async def wait_until(condition, sleep_time=1e-1 * q.s, timeout=None):
#     """Wait until a callable *condition* returns True. *sleep_time* is the time to sleep
#     between consecutive checks of *condition*. If *timeout* is given and the *condition* doesn't
#     return True within the time specified by it a :class:`.WaitingError` is raised.
#     """
#     sleep_time = sleep_time.to(q.s).magnitude
#     if timeout:
#         start = time.time()
#         timeout = timeout.to(q.s).magnitude
# 
#     while not await condition():
#         if timeout and time.time() - start > timeout:
#             raise WaitError('Waiting timed out')
#         await asyncio.sleep(sleep_time)
# 
# Path: concert/quantities.py



import asyncio
import numpy as np
import logging
import functools
import inspect
import types
from concert.helpers import memoize
from concert.coroutines.base import background, run_in_loop, wait_until
from concert.quantities import q
        from concert.session.utils import get_default_table
        from concert.session.utils import get_default_table
                msg.format(self._parameter.name, type(self._instance), self.unit, value))

        def leq(a, b):
            """check a <= b"""
            if not hasattr(a, 'shape') or len(a.shape) == 0:
                return a <= b
            else:
                # Vector data type
                valid_a = np.invert(np.isnan(a.magnitude))
                valid_b = np.invert(np.isnan(b.magnitude))
                valid = valid_a & valid_b
                test_a = a[valid]
                test_b = b[valid]
                return np.all(test_a.to_base_units().magnitude <= test_b.to_base_units().magnitude)

        lower = await self.get_lower()
        upper = await self.get_upper()
        if lower is not None:
            if not leq(lower, value):
                msg = "{} is out of range [{}, {}]"
                raise SoftLimitError(msg.format(value, lower, upper))
        if upper is not None:
            if not leq(value, upper):
                msg = "{} is out of range [{}, {}]"
                raise SoftLimitError(msg.format(value, lower, upper))

        converted = self._parameter.convert(value)
        await super(QuantityValue, self).set(converted, wait_on=wait_on)

    @background

# Path: concert/helpers.py
# def memoize(func):
#     """
#     Memoize the result of *func*.
# 
#     Remember the result of *func* depending on its arguments. Note, that this
#     requires that the function is free from any side effects, e.g. returns the
#     same value given the same arguments.
#     """
#     memo = {}
# 
#     if inspect.iscoroutinefunction(func):
#         async def wrapper(*args):
#             if args in memo:
#                 return memo[args]
# 
#             result = await func(*args)
#             memo[args] = result
#             return result
#     else:
#         def wrapper(*args):
#             if args in memo:
#                 return memo[args]
# 
#             result = func(*args)
#             memo[args] = result
#             return result
# 
#     return wrapper
# 
# 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_loop(coroutine):
#     """Wrap *coroutine* into a `asyncio.Task`, run it in the current loop, block until it finishes
#     and return the result.  On KeyboardInterrupt, the task is cancelled.
#     """
#     loop = asyncio.get_event_loop()
#     task = asyncio.ensure_future(coroutine, loop=loop)
# 
#     try:
#         result = loop.run_until_complete(task)
#         return result
#     except KeyboardInterrupt:
#         # _coro instead of get_coro() for Python 3.7 compatibilityget_coro()
#         LOG.log(AIODEBUG, "KeyboardInterrupt in `%s', cancelling", task._coro.__qualname__)
#         task.cancel()
# 
# async def wait_until(condition, sleep_time=1e-1 * q.s, timeout=None):
#     """Wait until a callable *condition* returns True. *sleep_time* is the time to sleep
#     between consecutive checks of *condition*. If *timeout* is given and the *condition* doesn't
#     return True within the time specified by it a :class:`.WaitingError` is raised.
#     """
#     sleep_time = sleep_time.to(q.s).magnitude
#     if timeout:
#         start = time.time()
#         timeout = timeout.to(q.s).magnitude
# 
#     while not await condition():
#         if timeout and time.time() - start > timeout:
#             raise WaitError('Waiting timed out')
#         await asyncio.sleep(sleep_time)
# 
# Path: concert/quantities.py



# Path: concert/base.py
import asyncio
import numpy as np
import logging
import functools
import inspect
import types
from concert.helpers import memoize
from concert.coroutines.base import background, run_in_loop, wait_until
from concert.quantities import q
        from concert.session.utils import get_default_table
        from concert.session.utils import get_default_table

                msg.format(self._parameter.name, type(self._instance), self.unit, value))

        def leq(a, b):
            """check a <= b"""
            if not hasattr(a, 'shape') or len(a.shape) == 0:
                return a <= b
            else:
                # Vector data type
                valid_a = np.invert(np.isnan(a.magnitude))
                valid_b = np.invert(np.isnan(b.magnitude))
                valid = valid_a & valid_b
                test_a = a[valid]
                test_b = b[valid]
                return np.all(test_a.to_base_units().magnitude <= test_b.to_base_units().magnitude)

        lower = await self.get_lower()
        upper = await self.get_upper()
        if lower is not None:
            if not leq(lower, value):
                msg = "{} is out of range [{}, {}]"
                raise SoftLimitError(msg.format(value, lower, upper))
        if upper is not None:
            if not leq(value, upper):
                msg = "{} is out of range [{}, {}]"
                raise SoftLimitError(msg.format(value, lower, upper))

        converted = self._parameter.convert(value)
        await super(QuantityValue, self).set(converted, wait_on=wait_on)

    @background

    async def wait(self, value, eps=None, sleep_time=1e-1 * q.s, timeout=None):