Skip to content
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

Report artifact enhancements, README, Python 3.10.6 support #357

Merged
merged 17 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
[run]
omit =
*__init__*
*__main__*
*/usr/local/lib*
*tests*
*test*
*demo*
*exceptions.py
*/gui/*
*/gui/experiments/*
*/gui/viewer/*
*/gui/BCInterface.py

[report]
exclude_lines =
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.8, 3.9]
python-version: [3.8, 3.9, 3.10.6]

steps:
- uses: actions/checkout@v2
Expand Down Expand Up @@ -68,7 +68,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.8, 3.9]
python-version: [3.8, 3.9, 3.10.6]

steps:
- uses: actions/checkout@v2
Expand Down Expand Up @@ -103,7 +103,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.8, 3.9]
python-version: [3.8, 3.9, 3.10.6]

steps:
- uses: actions/checkout@v4
Expand Down
105 changes: 78 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ If using zsh, instead of bash, you may encounter a segementation fault when runn
## Installation
---------------

#### BciPy Setup
### BciPy Setup
----------------

In order to run BciPy on your computer, after following the dependencies above, you will need to install the BciPy package.

Expand All @@ -62,26 +63,86 @@ Alternately, if [Make](http://www.mingw.org/) is installed, you may run the foll
make dev-install
```

#### Client Usage
Invoke an experiment protocol or task directly using command line utility `bcipy`.
- You can pass it attributes with flags, if desired.
Running with a User ID and Task: `bcipy --user "bci_user" --task "RSVP Calibration"`
Running with a User ID and Tasks with a registered Protocol: `bcipy --user "bci_user" --experiment "default"`
Running with fake data: `bcipy --fake`
Running without visualizations: `bcipy --noviz`
Running with alerts after each Task execution: `bcipy --alert`
Running with custom parameters: `bcipy --parameters "path/to/valid/parameters.json"`
### Client Usage
----------------

##### Run an experiment protocol or task

Invoke an experiment protocol or task directly using command line utility `bcipy`.

- Use the help flag to see other available input options: `bcipy --help`
- You can pass it attributes with flags, if desired.
- Running with a User ID and Task:
- `bcipy --user "bci_user" --task "RSVP Calibration"`
- Running with a User ID and Tasks with a registered Protocol:
- `bcipy --user "bci_user" --experiment "default"`
- Running with fake data:
- `bcipy --fake`
- Running without visualizations:
- `bcipy --noviz`
- Running with alerts after each Task execution:
- `bcipy --alert`
- Running with custom parameters:
- `bcipy --parameters "path/to/valid/parameters.json"`

##### Train a signal model with registered BciPy models

To train a signal model (currently `PCARDAKDE`), run the following command after installing BciPy:

`bcipy-train`

- Use the help flag to see other available input options: `bcipy-train --help`
- You can pass it attributes with flags, if desired.
- Running without a window prompting for data session folder:
- `bcipy-train -d path/to/data`
- Running with data visualizations (ERPs, etc.):
- `bcipy-train -v`
- Running with data visualizations that do not show, but save to file:
- `bcipy-train -s`
- Running with balanced accuracy:
- `bcipy-train --balanced-acc`
- Running with alerts after each Task execution:
- `bcipy-train --alert`
- Running with custom parameters:
- `bcipy-train -p "path/to/valid/parameters.json"`

##### Visualize ERP data from a session with Target / Non-Target labels

To generate plots that can be shown or saved after collection of data, run the following command after installing BciPy:

`bcipy-erp-viz`

- Use the help flag to see other available input options: `bcipy-erp-viz --help`
- You can pass it attributes with flags, if desired.
- Running without a window prompting for data session folder:
- `bcipy-erp-viz -s path/to/data`
- Running with data visualizations (ERPs, etc.):
- `bcipy-erp-viz --show`
- Running with data visualizations that do not show, but save to file:
- `bcipy-erp-viz --save`
- Running with custom parameters (default is in bcipy/parameters/parameters.json):
- `bcipy-erp-viz -p "path/to/valid/parameters.json"`

##### BciPy Simulator Usage

The simulator can be run using the command line utility `bcipy-sim`.

Ex.
`bcipy-sim -d my_data_folder/ -p my_parameters.json -m my_models/ -n 5`

Run `bcipy-sim --help` for documentation or see the README in the simulator module.

- Use the help flag to see other available input options: `bcipy --help`

##### Example Usage as a Package
### Package Usage
-------------------

```python
from bcipy.helpers import system_utils
system_utils.get_system_info()
```

#### Example Usage through the GUI
### GUI Usage
-------------

Run the following command in your terminal to start the BciPy GUI:
```sh
Expand All @@ -95,16 +156,6 @@ make bci-gui
```


#### Simulator Usage

The simulator can be run using the command line utility `bcipy-sim`.

Ex.
`bcipy-sim -d my_data_folder/ -p my_parameters.json -m my_models/ -n 5`

Run `bcipy-sim --help` for documentation or see the README in the simulator module.


## Glossary
-----------

Expand Down Expand Up @@ -150,7 +201,7 @@ This a list of the major modules and their functionality. Each module will conta
## Paradigms
------------

See `bcipy/task/README.md` for more information on all supported paradigms and modes. The following are the supported and validated paradigms:
See `bcipy/task/README.md` for more information on all supported paradigms, tasks, actions and modes. The following are the supported and validated paradigms:


> RSVPKeyboard
Expand Down Expand Up @@ -213,7 +264,6 @@ After running the above command, the recommended offset correction value will be
```bash
# Let's say the recommneded offset value is 0.1
python bcipy/helpers/offset.py --offset "0.1" -p

```

Alternately, if Make is installed, you may run the follow command to run offset determination and display the results:
Expand Down Expand Up @@ -306,10 +356,11 @@ make type


### Contributions Welcome!
--------------------------

If you want to be added to the development team slack or have additional questions, please reach out to us at [email protected]!

### Contribution Guidelines
#### Contribution Guidelines

We follow and will enforce the contributor's covenant to foster a safe and inclusive environment for this open source software, please reference this link for more information: https://www.contributor-covenant.org/

Expand All @@ -325,7 +376,7 @@ Other guidelines:

See this resource for examples: http://docs.python-guide.org/en/latest/writing/style/

## Contributors
### Contributors
---------------

All contributions are greatly appreciated!
Expand Down
16 changes: 10 additions & 6 deletions bcipy/gui/file_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class FileDialog(QWidget):

def __init__(self):
super().__init__()
self.title = 'PyQt6 file dialogs - pythonspot.com'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Looks like that was left over from a copy-paste.

self.title = 'File Dialog'
self.width = 640
self.height = 480

Expand Down Expand Up @@ -45,20 +45,23 @@ def ask_file(self,
options=self.options)
return filename

def ask_directory(self, directory: str = "") -> str:
def ask_directory(self, directory: str = "", prompt: str = "Select Directory") -> str:
"""Opens a dialog window to select a directory.

Returns
-------
path or None
"""
return QFileDialog.getExistingDirectory(self,
"Select Directory",
prompt,
directory=directory,
options=self.options)


def ask_filename(file_types: str = DEFAULT_FILE_TYPES, directory: str = "", prompt="Select File") -> str:
def ask_filename(
file_types: str = DEFAULT_FILE_TYPES,
directory: str = "",
prompt: str = "Select File") -> str:
"""Prompt for a file.

Parameters
Expand Down Expand Up @@ -87,7 +90,7 @@ def ask_filename(file_types: str = DEFAULT_FILE_TYPES, directory: str = "", prom
return filename


def ask_directory() -> str:
def ask_directory(prompt: str = "Select Directory") -> str:
"""Prompt for a directory.

Returns
Expand All @@ -100,9 +103,10 @@ def ask_directory() -> str:
directory = ''
if preferences.last_directory:
directory = str(Path(preferences.last_directory).parent)
name = dialog.ask_directory(directory)
name = dialog.ask_directory(directory, prompt=prompt)
if name and Path(name).is_dir():
preferences.last_directory = name

# Alternatively, we could use `app.closeAllWindows()`
app.quit()

Expand Down
2 changes: 1 addition & 1 deletion bcipy/helpers/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ def convert_to_mne(
channel_types: Optional[List[str]] = None,
transform: Optional[Composition] = None,
montage: str = 'standard_1020',
volts: bool = True) -> RawArray:
volts: bool = False) -> RawArray:
"""Convert to MNE.

Returns BciPy RawData as an MNE RawArray. This assumes all channel names
Expand Down
9 changes: 8 additions & 1 deletion bcipy/helpers/stimuli.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,12 +433,19 @@ def mne_epochs(mne_data: RawArray,
tmp_data.set_annotations(all_annotations)

events_from_annot, _ = mne.events_from_annotations(tmp_data)

if baseline is None:
baseline = (0, 0)
tmin = -0.1
else:
tmin = baseline[0]

return Epochs(
mne_data,
events_from_annot,
baseline=baseline,
tmax=trial_length,
tmin=-0.05,
tmin=tmin,
proj=False, # apply SSP projection to data. Defaults to True in Epochs.
reject_by_annotation=reject_by_annotation,
preload=preload)
Expand Down
2 changes: 1 addition & 1 deletion bcipy/helpers/tests/test_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ def test_convert_to_mne_with_transform(self):
def transform(x, fs):
return x * multiplier, fs

data = convert_to_mne(self.raw_data, transform=transform)
data = convert_to_mne(self.raw_data, transform=transform, volts=True)

self.assertTrue(len(data) > 0)
self.assertEqual(data.ch_names, self.channels[1:])
Expand Down
2 changes: 1 addition & 1 deletion bcipy/helpers/visualization.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def visualize_erp(
trial_length = trial_window[1] - 0.0

# check for a baseline interval or set to None
if trial_window[0] < 0:
if trial_window[0] <= 0:
baseline = (trial_window[0], 0.0)
else:
baseline = None
Expand Down
Loading
Loading