Source code for ethoscope.stimulators.stimulators

__author__ = 'quentin'

from ethoscope.utils.description import DescribedObject
from ethoscope.core.variables import BaseIntVariable
from ethoscope.hardware.interfaces.interfaces import DefaultInterface
from ethoscope.utils.scheduler import Scheduler



[docs]class HasInteractedVariable(BaseIntVariable): """ Custom variable to save whether the stimulator has sent instruction to its hardware interface. 0 means no interaction. Any positive integer describes a different interaction. """ functional_type = "interaction" header_name = "has_interacted"
[docs]class BaseStimulator(DescribedObject): _tracker = None _HardwareInterfaceClass = None def __init__(self, hardware_connection, date_range=""): """ Template class to interact with the tracked animal in a real-time feedback loop. Derived classes must have an attribute ``_hardwareInterfaceClass`` defining the class of the :class:`~ethoscope.hardware.interfaces.interfaces.BaseInterface` object (not on object) that instances will share with one another. In addition, they must implement a ``_decide()`` method. :param hardware_connection: The hardware interface to use. :type hardware_connection: :class:`~ethoscope.hardware.interfaces.interfaces.BaseInterface` :param date_range: the start and stop date/time for the stimulator. Format described `here <https://github.com/gilestrolab/ethoscope/blob/master/user_manual/schedulers.md>`_ :type date_range: str """ self._scheduler = Scheduler(date_range) self._hardware_connection = hardware_connection
[docs] def apply(self): """ Apply this stimulator. This method will: 1. check ``_tracker`` exists 2. decide (``_decide``) whether to interact 3. if 2. pass the interaction arguments to the hardware interface :return: whether a stimulator has worked, and a result dictionary """ if self._tracker is None: raise ValueError("No tracker bound to this stimulator. Use `bind_tracker()` methods") if self._scheduler.check_time_range() is False: return HasInteractedVariable(False) , {} interact, result = self._decide() if interact > 0: self._deliver(**result) return interact, result
[docs] def bind_tracker(self, tracker): """ Link a tracker to this interactor :param tracker: a tracker object. :type tracker: :class:`~ethoscope.trackers.trackers.BaseTracker` """ self._tracker = tracker
def _decide(self): raise NotImplementedError def _deliver(self, **kwargs): if self._hardware_connection is not None: self._hardware_connection.send_instruction(kwargs)
[docs]class DefaultStimulator(BaseStimulator): """ Default interactor. Simply never interacts """ _description = {"overview": "The default 'interactor'. To use when no hardware interface is to be used.", "arguments": []} _HardwareInterfaceClass = DefaultInterface def _decide(self): out = HasInteractedVariable(False) return out, {}