Skip to content

Commit

Permalink
changes for 2.0 release (#22)
Browse files Browse the repository at this point in the history
* minor changes

* update python and mkdocs build versions

* updates

- renamed all instances of "variables dialog" with "controls dialog"
- added information about accessing GUI settings
- note about experiment subfolder
- updated pulse duty cycle information
- added information about special variables: hidden, custom_controls_dialog, hw_, and api_class
- added note about viewing the error log
  • Loading branch information
alustig3 committed Nov 16, 2023
1 parent 5077e71 commit c004a05
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 26 deletions.
2 changes: 1 addition & 1 deletion docs/about/release-notes.md
@@ -1,4 +1,4 @@
# Release Notes
# Release notes
[Releases on GitHub](https://github.com/pyControl/code/releases)

## Version 1.8.1 (2023-02-21)
Expand Down
4 changes: 2 additions & 2 deletions docs/contributing.md
Expand Up @@ -9,7 +9,7 @@ Contributions can be made in a number of ways, including:
- reporting bugs and reviewing code patches
- submitting code patches via pull requests

## Reporting an Issue
## Reporting an issue

Please include as much detail as you can.
Let us know your platform and pyControl version, and ideally include a screenshot of the error message.
Expand All @@ -24,7 +24,7 @@ Spreading the word about pyControl helps maximize the number of people that bene
Additionally, increasing users should lead to more feedback, suggestions, and code contributions that will ultimately improve the software for everyone.
If you have found pyControl useful, consider starring the [code repository on GitHub](https://github.com/pyControl/code) and/or sharing your experience with others.

## Submitting Pull Requests
## Submitting pull requests

To get started developing for pyControl, fork the relevant pyControl repository on [GitHub](https://github.com/pyControl).

Expand Down
34 changes: 19 additions & 15 deletions docs/user-guide/graphical-user-interface.md
@@ -1,14 +1,14 @@
# pyControl GUI

The pyControl GUI is a graphical interface for running experiments, configuring setups and visualising behaviour. The GUI is a tabbed window with *Run task*, *Experiments* and *Setups* tabs. The *Run task* tab controls one hardware setup at a time i.e. one pyboard and its connected hardware. It is designed for quickly prototyping tasks and testing hardware setups, but can also be used to acquire data from one setup. The *Experiments* tab is used to configure and run experiments on many setups in parallel. The *Setups* tab is used to name and configure the hardware setups connected to the computer.
The pyControl GUI is a graphical interface for running experiments, configuring setups and visualising behaviour. The GUI is a tabbed window with *Run task*, *Experiments* and *Setups* tabs. The [Run task tab](#run-task-tab) controls one hardware setup at a time i.e. one pyboard and its connected hardware. It is designed for quickly prototyping tasks and testing hardware setups, but can also be used to acquire data from a single setup. The [Experiments tab](#experiments-tab) is used to configure and run experiments on multiple setups in parallel. The [Setups tab](#setups-tab) is used to name and configure the hardware setups connected to the computer.

To run the GUI, run the file *pyControl_GUI.pyw* in the pyControl root directory.

## Run task tab

![run_task_GUI.jpg](../media/GUI/run_task_tab.png)

The run task tab consists of controls, a log text box and plot panels. See the [Running a task](../index.md#running-a-task) section of the home page for a step-by-step guide to running a task. When a task is run the output is printed to the log and the behaviour is plotted. If a valid data directory and a subject ID are provided, the *Start* button changes to *Record* and the GUI will save the data generated when the task is run.
The run task tab consists of controls, a log text box and plot panels. See the [Running a task](../index.md#running-a-task) section of the home page for a step-by-step guide to running a task. When a task is run, the output is printed to the log and the behaviour is plotted. If a valid data directory and a subject ID are provided, the *Start* button changes to *Record* and the GUI will save the data generated when the task is run.

The **Setup** control box is used to select a pyboard, connect and disconnect from the board, and configure the board. Pressing the *config* button brings up a menu with options detailed below in the [Board configuration](#board-configuration) section.

Expand All @@ -18,19 +18,20 @@ The **Task** control box is used to select and upload a task and configure task
!!! tip "Task subfolders"
Tasks can be organised into subfolders within the *tasks* folder, creating a nested list in the GUI drop down menu. This can be useful if you have a lot of tasks, e.g. to organise them by user.

The *Variables* button opens a dialog for setting or getting the value of task variables. It can be used either before a run starts or while a task is running. Variables must be defined in the task definition file using the `v.my_variable` syntax (see [programming tasks](programming-tasks.md#variables)). Variables can be set to numbers, or to Python objects including strings, lists and dictionaries. The constants `ms`, `second`, `minute` and `hour` can be used, e.g. a variable can be set to `30*minute`. You can make task variables invisible to the GUI by ending their name in three underscores (e.g. `v.my_private_variable___`). Such 'private' variables work as normal in the task file but do not show up in the GUI. This can be useful if you have a lot of task variables, making it hard to find the ones you need to change in the GUI.
The *Controls* button opens a dialog for setting/getting the value of task variables, adding notes, and manually triggering task events. It can be used either before a run starts or while a task is running. Variables must be defined in the task definition file using the `v.my_variable` syntax (see [programming tasks](programming-tasks.md#variables)). Variables can be set to numbers, or to Python objects including strings, lists and dictionaries. The constants `ms`, `second`, `minute` and `hour` can be used, e.g. a variable can be set to `30*minute`. You can make task variables invisible to the GUI by ending their name in three underscores (e.g. `v.my_private_variable___`). Such 'private' variables work as normal in the task file but do not show up in the GUI. This can be useful if you have a lot of task variables, making it hard to find the ones you need to change in the GUI.

!!! tip "Variables dialog customization"
The variables dialog can be customized by adding a `v.custom_variables_dialog` variable to your task file.
<a name="controls-dialog"></a>
!!! tip "Controls dialog customization"
The controls dialog can be customized by adding a `v.custom_controls_dialog` variable to your task file.
When a task with this variable is first uploaded, a prompt will ask if you want to create a new custom variable dialog.
An editor will appear that allows you to add and customize interactive controls (checkboxes, sliders, spinboxes etc.) for your task's variables.
The controls can be rearranged and organized into separate tabs, can have custom labels added, and can include hints that will appear when hovering over the control.
Any remaining variables that don't get assigned a custom control will automatically be placed in an extra "..." tab.
Future edits can be made by opening the variables dialog in the Run task tab when the task is not running and pressing the *edit* button.
Future edits can be made by opening the controls dialog in the Run task tab when the task is not running and pressing the *edit* button.

This feature can be useful for tasks that have many variables that you would otherwise have to scroll/search through and type in edits for. The included [*example/custom_variables_dialog.py*](https://github.com/pyControl/code/blob/master/tasks/example/custom_variables_dialog.py) task is a good reference for this feature that can be viewed and run on any setup.
This feature can be useful for tasks that have many variables that you would otherwise have to scroll/search through and type in edits for. The included [*example/custom_controls_dialog.py*](https://github.com/pyControl/code/blob/master/tasks/example/custom_controls_dialog.py) task is a good reference for this feature that can be viewed and run on any setup.

![custom variable dialog](../media/GUI/custom_variable_dialog.png)
![custom controls dialog](../media/GUI/custom_variable_dialog.png)

## Experiments tab

Expand All @@ -40,9 +41,12 @@ The experiments tab is used to configure, save, load and run experiments on one

![run_task_GUI.jpg](../media/GUI/configure_experiment_tab.png)

When the experiments tab is opened it shows the configure experiment dialog. To create an experiment, specify the experiment name and select the task. By default, data generated by the experiment will be saved in a folder *pyControl/data/experiment_name*, but the data folder can be changed using the data dir control.
When the experiments tab is opened it shows the configure experiment dialog. To create an experiment, click the *new* button and name a new experiment file within your the experiments folder. Next select a task that will be run for all of the subjects. By default, data generated by the experiment will be saved in a folder *pyControl/data/experiment_name*, but the data folder can be changed using the data directory control.

Optionally a hardware test can be specified for the experiment. The hardware test is a task that is run before the main task, allowing the user to check whether the hardware is working as intended. The hardware test can be the same task as that used for the experiment, or another task designed specifically to test the hardware. No data is saved during the hardware test.
!!! tip "Experiment subfolders"
Experiments can be organised into subfolders within the *experiments* folder, creating a nested list in the GUI drop down menu. This can be useful if you have a lot of experiments, e.g. to organise them by user.

An optional hardware test can be specified for the experiment. The hardware test is a task that is run before the main task, allowing the user to check whether the hardware is working as intended. The hardware test can be the same task as that used for the experiment, or another task designed specifically to test the hardware. No data is saved during the hardware test.

The *Subjects* table is used to specify which subjects will run in which hardware setups. To add a subject to the experiment, press the *add* button, select the setup and enter a name for the subject. The *Run* checkbox determines whether on not a particular subject will be run when the experiment is run. You can assign multiple subjects to the same setup in the variables table but can only run a single subject on a given setup at a time.

Expand Down Expand Up @@ -85,10 +89,10 @@ The configure button next to each setup bring up a menu of configuration options
The board configuration menu has the following options to configure pyboards.

- *Load framework:* Reload the pyControl framework onto the board. If you are using a hardware definition you will need to reload it after loading the framework.
- *Load hardware definition:* Load a [hardware definition](hardware.md#hardware-definition) file onto the pyboard. The selected file is renamed *hardware_definition.py* on the pyboard filesystem irrespective of its name on the computer, so the hardware definition is always imported into the task file with:

```python
import hardware_definition as hw
```
- *Load hardware definition:* Load a [hardware definition](hardware.md#hardware-definitions) file onto the pyboard.
- *Device Firmware Update (DFU) mode:* Put the pyboard into DFU mode used for upgrading the version of MicroPython running on the board. For more information on upgrading MicroPython see [here](http://micropython.org/download).
- *Enable/disable USB flash drive:* Disabling the USB flash drive prevents the pyboard from showing up on the computer's filesystem as a USB storage device. This can be useful if you are connecting a large number of pyboards to a computer and run out of space on the USB bus. With the flashdrive enabled each pyboard shows up as two USB devices - a flash drive and a USB serial port.

## GUI settings

Settings can be adjusted by going to Settings->Edit settings or pressing <kbd> Ctrl</kbd> + <kbd> , </kbd>
4 changes: 2 additions & 2 deletions docs/user-guide/hardware.md
Expand Up @@ -117,7 +117,7 @@ class Digital_output(pin, inverted=False)

`Digital_output.toggle()` Toggle output.

`Digital_output.pulse(freq, duty_cycle=50, n_pulses=False)` Turn on a pulse train with specified frequency (Hz). The duty cycle (percentage of the period for which the signal is high) can be specified as 10, 25, 50 or 75. If the n_pulses argument is set to an integer the pulse train will stop after this number of pulses has been delivered.
`Digital_output.pulse(freq, duty_cycle=50, n_pulses=False)` Turn on a pulse train with specified frequency (Hz). The duty cycle (percentage of the period for which the signal is high) can be specified as any multiple of 5 betweeen 5 and 95. If the n_pulses argument is set to an integer the pulse train will stop after this number of pulses has been delivered.

---

Expand Down Expand Up @@ -291,7 +291,7 @@ sync_input = Digital_input(pin=board.port_5.DIO_B, rising_event='sync_pulse')
```
The easiest way to make an electrical connection to pins on a behavioural port is to plug in a *port adapter* board. This breaks out all the pins of the port to a screw terminal, and the power driver lines along with +5 and +12V to a set of female headers that can be used to connect loads such as solenoids or LEDs.

**Port adapter:** [GitHub](https://github.com/pyControl/hardware/tree/master/Port_adapter), [Open Ephys](https://open-ephys.org/pycontrol/pycontrol-peripherals), [LabMaker]([link](https://www.labmaker.org/products/pycontrol-port-adapter))
**Port adapter:** [GitHub](https://github.com/pyControl/hardware/tree/master/Port_adapter), [Open Ephys](https://open-ephys.org/pycontrol/pycontrol-peripherals), [LabMaker](https://www.labmaker.org/products/pycontrol-port-adapter)

![Port adapter](../media/hardware/port_adapter.png)

Expand Down
22 changes: 20 additions & 2 deletions docs/user-guide/programming-tasks.md
Expand Up @@ -170,7 +170,7 @@ Code can be executed when the framework starts or stops running by defining the


```python
def run_start():
def run_start():
# Code here is executed when the framework starts running.

def run_end():
Expand Down Expand Up @@ -229,7 +229,25 @@ def state_A(event):

Starting all variable names with `v.` makes all variables attributes of a single object called `v` (imported from `pyControl.utility`). This avoids problems that could otherwise occur when variables are accessed or set in state behaviour functions due to these functions having their own [namespaces](https://docs.python.org/3/tutorial/classes.html). It also allows the GUI to access the variables to set or get their values.

You can make task variables invisible to the GUI by ending their name in three underscores (e.g. `v.my_private_variable___`). Such 'private' variables work as normal in the task file but do not show up in the GUI. This can be useful if you have a lot of task variables, making it hard to find the ones you need to change in the GUI.
### Special variables

You can make task variables invisible to the GUI by ending their name in three underscores, for example `v.my_private_variable___`. Such 'private' variables work as normal in the task file but do not show up in the GUI. This can be useful if you have a lot of task variables, making it hard to find the ones you need to change in the GUI.

A custom controls dialog can be specified by adding a `v.custom_controls_dialog` variable. See [controls dialog customization](graphical-user-interface.md#controls-dialog) for more details.

Variables associated with hardware setups (e.g. calibration data for solenoid valves) can be used within a task by including a variable that begins with "hw_" for example `v.hw_my_hardware_variable`.
Once a hardware variable (any variable beginning with "v.hw_") has been established in a task file, the hardware specific value can be assigned to a hardware setup by going to the [Setups tab](graphical-user-interface.md#setups-tab), checking the named hardware setups that you want to assign values to, and then clicking the *Variables* button.
An "Edit Hardware Variables" dialog will appear.
From the hardware variable dropdown, select a variable and fill in the setup-value table below and finish by clicking the *save* button in the bottom right corner.
The included [*example/hardware_setup_level_variable.py*](https://github.com/pyControl/code/blob/master/tasks/example/hardware_setup_level_variable.py) task is a good reference for this feature that can be viewed and run on any setup.

Adding `v.api_class` will provide a two-way application programming interface (API) between the task running on the microntroller and a custom Python script running on the PC. See [API](#api) for more details

## API
An interface between the microcontroller task logic and the desktop computer during a running task can extend the capabilities of pyControl.
For instance, it can be useful to offload intensive computations onto the more capable PC and then send the results back down to the microcontroller.
Or you may want pyControl to connect to and communicate with external programs such as [Bonsai](https://www.bonsai-rx.org) or [PsychoPy](https://www.psychopy.org).
The included [*example/api.py*](https://github.com/pyControl/code/blob/master/tasks/example/api.py) task is a good reference for this feature that can be viewed and run on any setup.

## Data output

Expand Down
2 changes: 1 addition & 1 deletion docs/user-guide/synchronisation.md
Expand Up @@ -62,7 +62,7 @@ frame_trigger = Frame_trigger(pin=board.BNC_2, pulse_rate=60) # Instantiate Fram

## Synchronising data

The [rsync](https://github.com/pyControl/code/blob/master/tools/rsync.py) module in the tools folder can be used in Python to convert event times from one hardware system's reference frame that of another system by using sync pulse times generated by the `Rsync` object recorded on both systems. To illustrate this, assume we have an array of sync pulse times recorded by pyControl called `pulse_times_pycontrol` and an array of sync pulse times recorded by an ephys system called `pulse_times_ephys`. We also have an array of spike times recorded by the ephys system called `spike_times_ephys` which we want to convert into the reference frame of the pyControl data. We first instantiate an *Rsync_aligner* object using the pulse times recorded by both systems:
The [rsync](https://github.com/pyControl/code/blob/master/tools/rsync.py) module in the tools folder can be used in Python to convert event times from one hardware system's reference frame to that of another system by using sync pulse times generated by the `Rsync` object recorded on both systems. To illustrate this, assume we have an array of sync pulse times recorded by pyControl called `pulse_times_pycontrol` and an array of sync pulse times recorded by an ephys system called `pulse_times_ephys`. We also have an array of spike times recorded by the ephys system called `spike_times_ephys` which we want to convert into the reference frame of the pyControl data. We first instantiate an *Rsync_aligner* object using the pulse times recorded by both systems:

```python
from rsync import Rsync_aligner
Expand Down

0 comments on commit c004a05

Please sign in to comment.