-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clean-up Experiment dependencies inside Stimulus #72
base: master
Are you sure you want to change the base?
Changes from all commits
6fc6347
4e96d16
8e79c62
516d893
884016a
e4ffdf0
03a99bc
bad8037
6db29ec
7d9cf14
f1b545b
1f3c8cb
27e377a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,16 @@ | ||
from dataclasses import dataclass | ||
import datetime | ||
from copy import deepcopy | ||
import warnings | ||
|
||
from PyQt5.QtCore import pyqtSignal, QTimer, QObject | ||
from stytra.stimulation.stimuli import Pause, DynamicStimulus | ||
from stytra.stimulation.stimuli import Pause, DynamicStimulus, EnvironmentState | ||
from stytra.collectors.accumulators import DynamicLog, FramerateAccumulator | ||
from stytra.utilities import FramerateRecorder | ||
from lightparam.param_qt import ParametrizedQt, Param | ||
|
||
import logging | ||
|
||
|
||
class ProtocolRunner(QObject): | ||
"""Class for managing and running stimulation Protocols. | ||
|
@@ -91,7 +93,9 @@ def __init__(self, experiment=None, target_dt=0, log_print=True): | |
self.current_stimulus = None # current stimulus object | ||
self.past_stimuli_elapsed = None # time elapsed in previous stimuli | ||
self.dynamic_log = None # dynamic log for stimuli | ||
|
||
|
||
self.environment_state = EnvironmentState(calibrator = self.experiment.calibrator,) | ||
|
||
self.update_protocol() | ||
self.protocol.sig_param_changed.connect(self.update_protocol) | ||
|
||
|
@@ -109,11 +113,31 @@ def update_protocol(self): | |
self.stimuli = self.protocol._get_stimulus_list() | ||
|
||
self.current_stimulus = self.stimuli[0] | ||
|
||
|
||
#populate environment_state class | ||
if hasattr(self.experiment, 'estimator'): | ||
self.environment_state.estimator = self.experiment.estimator | ||
Comment on lines
+118
to
+119
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the experiment class has initialized the estimator pass it to the env_state variable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The more "pythonic" way is try/catch an |
||
if hasattr(self.experiment, 'arduino_board'): | ||
self.environment_state.arduino_board = self.experiment.arduino_board | ||
if hasattr(self.experiment, 'asset_dir'): | ||
self.environment_state.asset_dir = self.experiment.asset_dir | ||
if hasattr(self.experiment, 'logger'): | ||
self.environment_state.logger = self.experiment.logger | ||
if hasattr(self.experiment, 'trigger'): | ||
self.environment_state.trigger = self.experiment.trigger | ||
|
||
# pass experiment to stimuli for calibrator and asset folders: | ||
for stimulus in self.stimuli: | ||
stimulus.initialise_external(self.experiment) | ||
|
||
try: | ||
stimulus.initialise_external(self.experiment, self.environment_state,) | ||
except TypeError as e: | ||
print("Error: {}".format(e)) | ||
stimulus.initialise_external(self.experiment) | ||
msg = "Warning: self._experiment is deprecated use self._environment_state instead, self._experiment will be unavailable from version 1.0!" | ||
warnings.warn(msg, FutureWarning) | ||
warnings.warn(msg, DeprecationWarning) | ||
|
||
|
||
if self.dynamic_log is None: | ||
self.dynamic_log = DynamicLog(self.stimuli, experiment=self.experiment) | ||
else: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,29 @@ | ||
import numpy as np | ||
import datetime | ||
|
||
import warnings | ||
from dataclasses import dataclass | ||
|
||
@dataclass | ||
class EnvironmentState: | ||
def __init__(self, calibrator = None, | ||
estimator = None, | ||
arduino_board = None, | ||
asset_dir = None, | ||
logger = None, | ||
trigger = None, | ||
height:int = 600, | ||
width:int = 800): | ||
""" | ||
Holds Environment variables to pass from the protocol runner to the stimulus | ||
""" | ||
self.calibrator = calibrator | ||
self.estimator = estimator | ||
self.arduino_board = arduino_board | ||
self.trigger = trigger | ||
self.asset_dir = asset_dir | ||
self.logger = logger | ||
self.height = height | ||
self.width = width | ||
|
||
class Stimulus: | ||
""" Abstract class for a Stimulus. | ||
|
@@ -66,6 +89,7 @@ def __init__(self, duration=0.0): | |
self._elapsed = 0.0 # time from the beginning of the stimulus | ||
self.name = "undefined" | ||
self._experiment = None | ||
self._environment_state = None | ||
self.real_time_start = None | ||
self.real_time_stop = None | ||
|
||
|
@@ -111,7 +135,7 @@ def stop(self): | |
""" | ||
pass | ||
|
||
def initialise_external(self, experiment): | ||
def initialise_external(self, experiment, environment_state: EnvironmentState = None): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think keeping both arguments is a good idea, at some point we anyway need to pass only the environment_state. We can consider having a |
||
""" Make a reference to the Experiment class inside the Stimulus. | ||
This is required to access from inside the Stimulus class to the | ||
Calibrator, the Pyboard, the asset directories with movies or the motor | ||
|
@@ -130,7 +154,19 @@ def initialise_external(self, experiment): | |
None | ||
|
||
""" | ||
|
||
if isinstance(environment_state, EnvironmentState): | ||
self._environment_state = environment_state | ||
else: | ||
self._environment_state = experiment | ||
msg = "Warning: self._experiment is deprecated use self._environment_state instead, self._experiment will be unavailable from version 1.0!" | ||
warnings.warn(msg, FutureWarning) | ||
warnings.warn(msg, DeprecationWarning) | ||
|
||
|
||
self._experiment = experiment | ||
|
||
|
||
|
||
|
||
class DynamicStimulus(Stimulus): | ||
|
@@ -251,7 +287,7 @@ def start(self): | |
|
||
def update(self): | ||
# If trigger is set, make it end: | ||
if self._experiment.trigger.start_event.is_set(): | ||
if self._environment_state.trigger.start_event.is_set(): | ||
self.duration = self._elapsed | ||
|
||
|
||
|
@@ -289,10 +325,10 @@ def update(self): | |
s.update() | ||
s._elapsed = self._elapsed | ||
|
||
def initialise_external(self, experiment): | ||
super().initialise_external(experiment) | ||
def initialise_external(self, experiment, environment_state): | ||
super().initialise_external(experiment, environment_state) | ||
for s in self._stim_list: | ||
s.initialise_external(experiment) | ||
s.initialise_external(experiment, environment_state) | ||
|
||
@property | ||
def dynamic_parameter_names(self): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
initialize the env state variable with only the calibrator