Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
kevincar committed Nov 20, 2023
2 parents 95af876 + 6f02d1a commit 62f4f6f
Show file tree
Hide file tree
Showing 15 changed files with 101 additions and 26 deletions.
7 changes: 7 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[flake8]
# Recommend matching the black line length (default 88),
# rather than using the flake8 default of 79:
max-line-length = 88
extend-ignore =
# See https://github.com/PyCQA/pycodestyle/issues/373
E203,
7 changes: 6 additions & 1 deletion libbids/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
from .dataset import Dataset
from .clibbids import Subject
from .clibbids import Subject # type: ignore
from .utils import qprompt


Dataset
Subject
qprompt
12 changes: 5 additions & 7 deletions libbids/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
Supplemental pybids object for manipulating the dataset
"""
import os
import sys
import json
import pandas as pd # type: ignore
from bids.layout import BIDSLayout # type: ignore
from pathlib import Path
from typing import Dict, List, Optional, cast
from .clibbids import Subject
from .clibbids import Subject # type: ignore

try:
from PyQt6.QtWidgets import QMessageBox, QWidget # type: ignore
Expand Down Expand Up @@ -105,11 +104,10 @@ def get_subjects(self) -> List[int]:
-------
List[int]
"""
participant_ids: List[str] = self.participant_table["participant_id"].values.tolist()
return [
int(ids[4:])
for ids in participant_ids
]
participant_ids: List[str] = self.participant_table[
"participant_id"
].values.tolist()
return [int(ids[4:]) for ids in participant_ids]

def is_subject(self, idx: int) -> bool:
"""determins if the subject with the provided id exists
Expand Down
4 changes: 4 additions & 0 deletions libbids/instruments/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from .instrument import Instrument
from .eeg_instrument import EEGInstrument
from .physio_instrument import PhysioInstrument
from .read_instrument import ReadInstrument
from .stim_instrument import StimInstrument
from .write_instrument import WriteInstrument

EEGInstrument
Instrument
PhysioInstrument
ReadInstrument
StimInstrument
WriteInstrument
10 changes: 7 additions & 3 deletions libbids/instruments/eeg_instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
cast,
)

from .instrument import Instrument
from .read_instrument import ReadInstrument
from ..enums import Modality

if TYPE_CHECKING:
from ..session import Session
from ..session import Session # type: ignore


class EEGInstrument(Instrument):
class EEGInstrument(ReadInstrument):
"""An instrumentation device capable of recording electroecephalograms"""

def __init__(
Expand Down Expand Up @@ -105,6 +105,10 @@ def device_read(self) -> np.ndarray:
fn, args, kwargs = cast(Tuple, self.read_fn)
return self.device.__getattribute__(fn)(*args, **kwargs)

def flush(self) -> None:
"""Read data from the device simply to discard"""
self.device_read()

def read(self, remainder: bool = False) -> np.ndarray:
"""Read data from the headset and return the data
Expand Down
2 changes: 1 addition & 1 deletion libbids/instruments/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from ..enums import Modality

if TYPE_CHECKING:
from ..session import Session
from ..session import Session # type: ignore


class Instrument(ABC):
Expand Down
3 changes: 1 addition & 2 deletions libbids/instruments/physio_instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from ..enums import Modality

if TYPE_CHECKING:
from ..session import Session
from ..session import Session # type: ignore


class PhysioInstrument(Instrument):
Expand Down Expand Up @@ -144,4 +144,3 @@ def _fixup_edf_metadata(self, metadata: Dict):
value = datetime.now()
result.update({required_key: value})
return result

1 change: 1 addition & 0 deletions libbids/instruments/read_instrument
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class ReadInstrument
31 changes: 31 additions & 0 deletions libbids/instruments/read_instrument.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import numpy as np
from abc import abstractmethod

from .instrument import Instrument


class ReadInstrument(Instrument):
"""An instrument device capabale of recording data"""

@abstractmethod
def flush(self) -> None:
"""Read from the device but throw away the data as a way to
clear any data buffers from the device"""
raise Exception("Method not implemented")

@abstractmethod
def read(self, remainder: bool = False) -> np.ndarray:
"""Read data from the headset and return the data
Parameters
----------
remainder : bool
Because EDFWriter only allows full seconds to be written, the last
time this function should be called is with remainder set to true
Returns
-------
np.ndarray
A 2D array of data in the shape of (channels, time)
"""
raise Exception("Method not implemented")
8 changes: 4 additions & 4 deletions libbids/instruments/stim_instrument.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from typing import Any, TYPE_CHECKING

from .instrument import Instrument
from .write_instrument import WriteInstrument
from ..enums import Modality

if TYPE_CHECKING:
from ..session import Session
from ..session import Session # type: ignore


class StimInstrument(Instrument):
class StimInstrument(WriteInstrument):
"""Ann instrument device capable of sending a stimulus"""

def __init__(
Expand Down Expand Up @@ -38,6 +38,6 @@ def start(self, task: str, run_id: str):
def stop(self):
self.device.stop()

def write(self, command: str):
def write(self, command: str) -> None:
"""a string command to send to the device"""
self.device.write(command)
17 changes: 17 additions & 0 deletions libbids/instruments/write_instrument.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from abc import abstractmethod

from .instrument import Instrument


class WriteInstrument(Instrument):

@abstractmethod
def write(self, command: str) -> None:
"""A string command to send to the device
Parameters
----------
command : str
The command to send to the device
"""
raise Exception("Method not implemented")
11 changes: 9 additions & 2 deletions libbids/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
from pathlib import Path
from typing import Any, List, Optional, TYPE_CHECKING, cast

from .clibbids import Entity
from .clibbids import Entity # type: ignore
from .event import Event
from .instruments import ReadInstrument

if TYPE_CHECKING:
from .task import Task
Expand Down Expand Up @@ -55,6 +56,12 @@ def end_current_event(self) -> None:
self.previous_event = self.current_event
self.current_event = None

def flush_instruments(self) -> None:
"""Flushes Read instruments"""
for ins in self.task.instruments:
if isinstance(ins, ReadInstrument):
ins.flush()

def initialize_event_file(self) -> None:
"""Initializes the event file for writing"""
if self.event_filepath.exists():
Expand Down Expand Up @@ -106,7 +113,7 @@ def start(self) -> None:
self.task.on_event_start(self.current_event)

# Throw away any samples collected during setup
self.task.process()
self.flush_instruments()
while not self.done:
# Handle events
if self.is_current_event_finished():
Expand Down
2 changes: 1 addition & 1 deletion libbids/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from datetime import timedelta
from pathlib import Path
from typing import Dict, List, Optional, TYPE_CHECKING
from .clibbids import Entity
from .clibbids import Entity # type: ignore
from .event import Event
from .instruments import Instrument
from .notes import Notes
Expand Down
10 changes: 6 additions & 4 deletions libbids/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
try:
from PyQt6.QtWidgets import QMessageBox, QPushButton # type: ignore
except ModuleNotFoundError:
from PyQt5.QtWidgets import QMessageBox, QPushButton # type: ignore
from PyQt5.QtWidgets import QMessageBox, QPushButton # type: ignore


def qprompt(msg: str, yes_button_text: str = "Yes", no_button_text: str = "No"):
Expand Down Expand Up @@ -29,7 +29,9 @@ def qprompt(msg: str, yes_button_text: str = "Yes", no_button_text: str = "No"):

msgbox: QMessageBox = QMessageBox()
msgbox.setText(msg)
yes_button: QPushButton = msgbox.addButton(yes_button_text, QMessageBox.YesRole)
msgbox.addButton(no_button_text, QMessageBox.NoRole)
QMessageBox.exec_(msgbox)
yes_button: QPushButton = msgbox.addButton(
yes_button_text, QMessageBox.YesRole # type: ignore
)
msgbox.addButton(no_button_text, QMessageBox.NoRole) # type: ignore
QMessageBox.exec_(msgbox) # type: ignore
return msgbox.clickedButton() == yes_button
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "libbids"
version = "0.1.3"
version = "0.1.4"
description = "Library for generating data using the Brain Imaging Data Structure"
authors = [ { name = "Kevin Davis", email = "[email protected]" } ]
dependencies = [
Expand Down

0 comments on commit 62f4f6f

Please sign in to comment.