Skip to content

Commit 9f7e9d6

Browse files
authored
Merge pull request #89 from tne-lab/dev
Merging Changes from JOSS Review
2 parents ff7d116 + 2d25b6c commit 9f7e9d6

38 files changed

+1179
-186
lines changed

docs/events.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,33 @@ Event associated with the request to close the hardware/software connection with
435435

436436
`comp_id` the ID of the component
437437

438+
### Subject Configuration Events
439+
440+
### ConstantsUpdateEvent
441+
442+
class ConstantsUpdateEvent(TaskEvent):
443+
constants: Dict
444+
445+
Event associated with sending information from the [SubjectConfigWidget](workstation.md#configuration-with-subjectconfigwidget) to the Task. This event may send multiple updates
446+
at once which will be split into constant-specific ConstantUpdateEvents for constants that actually had their values changed.
447+
448+
### ConstantUpdateEvent
449+
450+
class ConstantUpdateEvent(Loggable):
451+
name: str
452+
value: Any
453+
454+
Event associated with changes to constants from the SubjectConfigWidget that occur while the Task is running. One of these
455+
events will be logged for each constant that had a change in value after receiving a ConstantsUpdateEvent.
456+
457+
### ConstantRemoveEvent
458+
459+
class ConstantRemoveEvent(TaskEvent):
460+
constant: str
461+
462+
Event associated with removing a constant from the SubjectConfigWidget. Will reset the value of the constant to what is listed
463+
in the task's `get_constants` method. If this occurs while a task is running, a ConstantUpdateEvent will be logged.
464+
438465
### EventLoggers
439466

440467
The classes detailed below are contained in the `Events` package and associated with event logging.

docs/img/addressfile_gui.png

28.2 KB
Loading

docs/img/protocol_gui.png

12 KB
Loading

docs/img/subject_config.png

226 Bytes
Loading

docs/protocols_addressfiles.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@ by the task's `get_constants` method with a new value to replace the pre-existin
2525

2626
Protocols can be loaded from any directory, but we recommend saving them at *Desktop/py-behav-v2/TASK_NAME/Protocols*.
2727

28+
### Protocol Creation GUI
29+
30+
Instead of manually creating Protocols, Protocols can also be created using a GUI tool by going to File->Protocols->New/Edit.
31+
From here, you can select which Task you want to create a Protocol for. In the creation GUI, constants can be added or removed
32+
from the Protocol with the corresponding buttons in the bottom-left of the interface. When a constant is added, the GUI
33+
will default to selecting one of the available entries and autopopulate it with the default value from the `get_constants`
34+
method. The chosen constant can be changed in the corresponding Constant dropdown. If the constant's default value is an expression,
35+
the expression will be evaluated and set as the default value.
36+
37+
![img/protocol_gui.png](img/protocol_gui.png)
38+
2839
## AddressFiles
2940

3041
AddressFiles are executed at runtime to associate *Components* with particular *Sources*. Tasks can have any number of AddressFiles
@@ -50,4 +61,20 @@ is the identifier that was given to the [Source](sources.md) this component shou
5061
is the hardware address the source should associate this component with. The first of the two optional arguments, `list_index`
5162
indicates the component's list position if the ID is associated with a list of components. The second optional argument, `metadata`
5263
is a dictionary that can be used to override Component attributes (analogous to a Protocol for components). AddressFiles can be
53-
loaded from any directory, but we recommend saving them at *Desktop/py-behav-v2/TASK_NAME/AddressFiles*.
64+
loaded from any directory, but we recommend saving them at *Desktop/py-behav-v2/TASK_NAME/AddressFiles*.
65+
66+
### AddressFile Creation GUI
67+
68+
Instead of manually creating AddressFiles, AddressFiles can also be created using a GUI tool by going to File->AddressFiless->New/Edit.
69+
From here, you can select which Task you want to create an AddressFile for. In the creation GUI, components can be added or removed
70+
from the AddressFile with the corresponding buttons in the bottom-left of the interface. When a component is added, the GUI
71+
will default to selecting one of the available entries and autopopulate it according to the `get_components`
72+
method. The chosen component can be changed in the corresponding Component dropdown. The type of the component can be changed
73+
in the Type dropdown and will automatically be restricted to valid options. The Source linked to the component can be changed
74+
in the Source dropdown and will include possible entries for all Sources configured in the system. The component address can
75+
be changed in the Address field; valid addresses must be strings, integers, floats, or list of the aforementioned options.
76+
If the component is part of a list, the component index in the list can be selected from the Index dropdown. Lastly, any metadata
77+
required for this component by the linked Source or the Component class itself will automatically be indicated in the Metdata
78+
field. Default values for metadata are indicated in the corresponding Source or Component class.
79+
80+
![addressfile_gui.png](img/addressfile_gui.png)

docs/sources.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ Communicates with digital input and output lines represented via a connection to
126126

127127
*Required Extras:* `whisker`
128128

129+
Run `pip install pybehave[whisker]` if the extra is missing.
130+
129131
*Attributes:*
130132

131133
`address` IP address for the computer running the Whisker Server. Use "localhost" if pybehave and Whisker are on the same machine.
@@ -146,6 +148,8 @@ Communicates with touchscreen objects represented via a connection to Whisker.
146148

147149
*Required Extras:* `whisker`
148150

151+
Run `pip install pybehave[whisker]` if the extra is missing.
152+
149153
*Attributes:*
150154

151155
`address` IP address for the computer running the Whisker Server. Use "localhost" if pybehave and Whisker are on the same machine.
@@ -166,6 +170,8 @@ in JSON mode.
166170

167171
*Required Extras:* `oe`
168172

173+
Run `pip install pybehave[oe]` if the extra is missing.
174+
169175
*Attributes:*
170176

171177
`address` IP address for the computer running OpenEphys. Use "localhost" if pybehave and OpenEphys are on the same machine.
@@ -183,6 +189,8 @@ Source for coordinating connections to the Open Source Controller for Animal Res
183189

184190
*Required Extras:* `serial`
185191

192+
Run `pip install pybehave[serial]` if the extra is missing.
193+
186194
*Attributes:*
187195

188196
`coms` list of serial port IDs corresponding to OSCAR interfaces.
@@ -195,6 +203,8 @@ Source for coordinating connections to serial devices.
195203

196204
*Required Extras:* `serial`
197205

206+
Run `pip install pybehave[serial]` if the extra is missing.
207+
198208
*Required Metadata:*
199209

200210
`baudrate: int` the baudrate for the Serial connection corresponding to a registered Component
@@ -214,7 +224,9 @@ Source for coordinating connections to serial devices.
214224
Source for coordinating video recording with Webcams. Generally intended for sole use with Video components. Currently supports
215225
standard USB webcams.
216226

217-
*Required Extras:* `opencv-python`
227+
*Required Extras:* `video`
228+
229+
Run `pip install pybehave[video]` if the extra is missing.
218230

219231
*Attributes:*
220232

@@ -251,6 +263,8 @@ By default, the source will draw a small black rectangle in the bottom left of t
251263

252264
*Required Extras:* `hikvision`
253265

266+
Run `pip install pybehave[hikvision]` if the extra is missing.
267+
254268
*Attributes:*
255269

256270
`ip` the IP of the DVR
@@ -269,6 +283,8 @@ Input functionality is currently not implemented.
269283

270284
*Required Extras:* `ni`
271285

286+
Run `pip install pybehave[ni]` if the extra is missing.
287+
272288
*Attributes:*
273289

274290
`dev` the device ID of the DAQ
@@ -284,4 +300,6 @@ Input functionality is currently not implemented.
284300
Source for coordinating selection of arbitrary parameters (like stimulation or task variables) according to an outcome of interest
285301
using Bayesian optimization with gaussian process regression. Typically used with the general purpose `Both` component class.
286302

287-
*Required Extras:* `bo`
303+
*Required Extras:* `bo`
304+
305+
Run `pip install pybehave[bo]` if the extra is missing.

docs/tutorials/task_no_hardware.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,12 @@ task's `get_constants` method).
6464

6565
![img.png](../img/constant_added.png)
6666

67+
Values for a particular subject can be saved to load every time this subject runs the task by pressing the down-arrow button.
6768
Subject specific configuration can also be made to differ per Protocol or AddressFile but this feature is less useful for
68-
task testing and more for streamlining experiments.
69+
task testing and more for streamlining experiments. Constants can also be updated while a task is running and will log
70+
ConstantUpdateEvents which can be analyzed offline or handled in Task code. Generally, this real-time feature is more intended
71+
for development than as an actual part of the task workflow since constants are meant to have fixed values. Instead, elements
72+
can be added to the GUI to update task variables if user input is required while the task is running.
6973

7074
## Simulating sources
7175

docs/workstation.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,19 @@ default but can be associated with any number of additional Widgets. Widgets are
6262
to the associated Task or its EventLoggers or controlling external hardware/software manually from the pybehave GUI.
6363
While similar functionality can be implemented in Task GUIs, Widgets will have identical behavior regardless of the Task they are associated with.
6464

65-
#### EventWidget
65+
#### Accessing events with EventWidget
6666

6767
EventWidget is an abstract subclass of Widget that provides access to the Task event stream. This functionality should only be necessary if
6868
the Widget is intended for visualizing/displaying Task information or requires feedback from the Task
6969

70-
#### SubjectConfigWidget
70+
#### Configuration with SubjectConfigWidget
7171

7272
SubjectConfigWidget is a special purpose Widget that is integrated into the pybehave core. This Widget allows for overriding the
7373
value of any Task constant for a particular subject. This is useful if constants need to be set on a per-subject basis.
74-
Values can also be made specific to the address file or protocol the subject is running on.
74+
Values can also be made specific to the address file or protocol the subject is running on. Constants can also be updated while a task is running and will log
75+
ConstantUpdateEvents which can be analyzed offline or handled in Task code.
76+
77+
![subject_config.png](img/subject_config.png)
7578

7679
## Workstation Settings
7780

pybehave/Components/Component.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,8 @@ def close(self) -> None:
8686
if self.task is not None:
8787
self.task.close_component(self.id)
8888

89+
@staticmethod
90+
def metadata_defaults() -> Dict:
91+
"""Call to get the metadata names and default values required by this component."""
92+
return {}
93+

pybehave/Components/OEBinaryInput.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
2-
from typing import TYPE_CHECKING
2+
from typing import TYPE_CHECKING, Dict
3+
34
if TYPE_CHECKING:
45
from pybehave.Tasks.Task import Task
56

@@ -29,3 +30,7 @@ def update(self, value: dict) -> bool:
2930
self.state = False
3031
return True
3132
return False
33+
34+
@staticmethod
35+
def metadata_defaults() -> Dict:
36+
return {"rising": True, "falling": False}

0 commit comments

Comments
 (0)