bci_essentials.io.sources

  1from abc import ABC, abstractmethod
  2
  3from ..utils.logger import Logger  # Logger wrapper
  4
  5# Instantiate a logger for the module at the default level of logging.INFO
  6# Logs to bci_essentials.__module__) where __module__ is the name of the module
  7logger = Logger(name=__name__)
  8
  9
 10class MarkerSource(ABC):
 11    """MarkerSource objects send time synchronized markers/commands to bci_controller."""
 12
 13    @property
 14    @abstractmethod
 15    def name(self) -> str:
 16        """Name of the marker source"""
 17        pass
 18
 19    @abstractmethod
 20    def get_markers(self) -> tuple[list[list], list]:
 21        """Get marker/command data and timestamps since last call
 22
 23        Returns
 24        -------
 25        marker_data : tuple(marker, timestemps)
 26            A tuple of (markers, timestamps):
 27            - markers : list[list]
 28                - A list of samples, where each sample corresponds to a timestamp.
 29                - Each sample is a list with a single string element that represents a command or a marker.
 30                - The string is formatted as follows:
 31                    - command = an arbitrary string, ex: "Trial Started"
 32                    - marker = "paradigm, num options, label number, trial length"
 33            - timestamps : list[float]
 34                - A list timestamps (float in seconds) corresponding to the markers
 35        """
 36        pass
 37
 38    @abstractmethod
 39    def time_correction(self) -> float:
 40        """Get the current time correction for timestamps.
 41
 42        Returns
 43        -------
 44        time_correction : float
 45            The current time correction estimate (seconds).
 46            - This is the number that needs to be added to a time tamp that was remotely generated via local_clock() to map it into the local clock domain of the machine.
 47
 48        """
 49        pass
 50
 51
 52class EegSource(ABC):
 53    """EegSource objects produce samples of EEG for use in bci_controller.
 54
 55    It can be used to represent an BCI headset providing EEG data, or it could be a source
 56    of Markers to control bci_controller behaviour, etc.
 57    """
 58
 59    @property
 60    @abstractmethod
 61    def name(self) -> str:
 62        """Name of the EEG source"""
 63        pass
 64
 65    @property
 66    @abstractmethod
 67    def fsample(self) -> float:
 68        """Sample rate of EEG source"""
 69        pass
 70
 71    @property
 72    @abstractmethod
 73    def n_channels(self) -> int:
 74        """Number of EEG channels per sample"""
 75        pass
 76
 77    @property
 78    @abstractmethod
 79    def channel_types(self) -> list[str]:
 80        """The type of each channel, ex: eeg, or stim"""
 81        pass
 82
 83    @property
 84    @abstractmethod
 85    def channel_units(self) -> list[str]:
 86        """The unit of each channel, ex: microvolts"""
 87        pass
 88
 89    @property
 90    @abstractmethod
 91    def channel_labels(self) -> list[str]:
 92        """The label for each channel, ex: FC3, C5"""
 93        pass
 94
 95    @abstractmethod
 96    def get_samples(self) -> tuple[list[list], list]:
 97        """Get EEG samples and timestamps since last call
 98
 99        Returns
100        -------
101        samples_data: tuple(samples, timestamps)
102            - A tuple of (samples, timestamps) where:
103                - samples : list[float]
104                    - A list of samples, where each sample corresponds to a timestamp. Each sample is a list of floats representing the value for each channel of EEG.
105                - timestamps : list[float]
106                    - A list timestamps (float in seconds) corresponding to the samples
107
108        """
109        pass
110
111    @abstractmethod
112    def time_correction(self) -> float:
113        """Get the current time correction for timestamps.
114
115        Returns
116        -------
117        time_correction : float
118            The current time correction estimate (seconds).
119            - This is the number that needs to be added to a time tamp that was remotely generated via local_clock() to map it into the local clock domain of the machine.
120
121        """
122        pass
class MarkerSource(abc.ABC):
11class MarkerSource(ABC):
12    """MarkerSource objects send time synchronized markers/commands to bci_controller."""
13
14    @property
15    @abstractmethod
16    def name(self) -> str:
17        """Name of the marker source"""
18        pass
19
20    @abstractmethod
21    def get_markers(self) -> tuple[list[list], list]:
22        """Get marker/command data and timestamps since last call
23
24        Returns
25        -------
26        marker_data : tuple(marker, timestemps)
27            A tuple of (markers, timestamps):
28            - markers : list[list]
29                - A list of samples, where each sample corresponds to a timestamp.
30                - Each sample is a list with a single string element that represents a command or a marker.
31                - The string is formatted as follows:
32                    - command = an arbitrary string, ex: "Trial Started"
33                    - marker = "paradigm, num options, label number, trial length"
34            - timestamps : list[float]
35                - A list timestamps (float in seconds) corresponding to the markers
36        """
37        pass
38
39    @abstractmethod
40    def time_correction(self) -> float:
41        """Get the current time correction for timestamps.
42
43        Returns
44        -------
45        time_correction : float
46            The current time correction estimate (seconds).
47            - This is the number that needs to be added to a time tamp that was remotely generated via local_clock() to map it into the local clock domain of the machine.
48
49        """
50        pass

MarkerSource objects send time synchronized markers/commands to bci_controller.

name: str
14    @property
15    @abstractmethod
16    def name(self) -> str:
17        """Name of the marker source"""
18        pass

Name of the marker source

@abstractmethod
def get_markers(self) -> tuple[list[list], list]:
20    @abstractmethod
21    def get_markers(self) -> tuple[list[list], list]:
22        """Get marker/command data and timestamps since last call
23
24        Returns
25        -------
26        marker_data : tuple(marker, timestemps)
27            A tuple of (markers, timestamps):
28            - markers : list[list]
29                - A list of samples, where each sample corresponds to a timestamp.
30                - Each sample is a list with a single string element that represents a command or a marker.
31                - The string is formatted as follows:
32                    - command = an arbitrary string, ex: "Trial Started"
33                    - marker = "paradigm, num options, label number, trial length"
34            - timestamps : list[float]
35                - A list timestamps (float in seconds) corresponding to the markers
36        """
37        pass

Get marker/command data and timestamps since last call

Returns
  • marker_data (tuple(marker, timestemps)): A tuple of (markers, timestamps):
    • markers : list[list]
      • A list of samples, where each sample corresponds to a timestamp.
      • Each sample is a list with a single string element that represents a command or a marker.
      • The string is formatted as follows:
        • command = an arbitrary string, ex: "Trial Started"
        • marker = "paradigm, num options, label number, trial length"
    • timestamps : list[float]
      • A list timestamps (float in seconds) corresponding to the markers
@abstractmethod
def time_correction(self) -> float:
39    @abstractmethod
40    def time_correction(self) -> float:
41        """Get the current time correction for timestamps.
42
43        Returns
44        -------
45        time_correction : float
46            The current time correction estimate (seconds).
47            - This is the number that needs to be added to a time tamp that was remotely generated via local_clock() to map it into the local clock domain of the machine.
48
49        """
50        pass

Get the current time correction for timestamps.

Returns
  • time_correction (float): The current time correction estimate (seconds).
    • This is the number that needs to be added to a time tamp that was remotely generated via local_clock() to map it into the local clock domain of the machine.
class EegSource(abc.ABC):
 53class EegSource(ABC):
 54    """EegSource objects produce samples of EEG for use in bci_controller.
 55
 56    It can be used to represent an BCI headset providing EEG data, or it could be a source
 57    of Markers to control bci_controller behaviour, etc.
 58    """
 59
 60    @property
 61    @abstractmethod
 62    def name(self) -> str:
 63        """Name of the EEG source"""
 64        pass
 65
 66    @property
 67    @abstractmethod
 68    def fsample(self) -> float:
 69        """Sample rate of EEG source"""
 70        pass
 71
 72    @property
 73    @abstractmethod
 74    def n_channels(self) -> int:
 75        """Number of EEG channels per sample"""
 76        pass
 77
 78    @property
 79    @abstractmethod
 80    def channel_types(self) -> list[str]:
 81        """The type of each channel, ex: eeg, or stim"""
 82        pass
 83
 84    @property
 85    @abstractmethod
 86    def channel_units(self) -> list[str]:
 87        """The unit of each channel, ex: microvolts"""
 88        pass
 89
 90    @property
 91    @abstractmethod
 92    def channel_labels(self) -> list[str]:
 93        """The label for each channel, ex: FC3, C5"""
 94        pass
 95
 96    @abstractmethod
 97    def get_samples(self) -> tuple[list[list], list]:
 98        """Get EEG samples and timestamps since last call
 99
100        Returns
101        -------
102        samples_data: tuple(samples, timestamps)
103            - A tuple of (samples, timestamps) where:
104                - samples : list[float]
105                    - A list of samples, where each sample corresponds to a timestamp. Each sample is a list of floats representing the value for each channel of EEG.
106                - timestamps : list[float]
107                    - A list timestamps (float in seconds) corresponding to the samples
108
109        """
110        pass
111
112    @abstractmethod
113    def time_correction(self) -> float:
114        """Get the current time correction for timestamps.
115
116        Returns
117        -------
118        time_correction : float
119            The current time correction estimate (seconds).
120            - This is the number that needs to be added to a time tamp that was remotely generated via local_clock() to map it into the local clock domain of the machine.
121
122        """
123        pass

EegSource objects produce samples of EEG for use in bci_controller.

It can be used to represent an BCI headset providing EEG data, or it could be a source of Markers to control bci_controller behaviour, etc.

name: str
60    @property
61    @abstractmethod
62    def name(self) -> str:
63        """Name of the EEG source"""
64        pass

Name of the EEG source

fsample: float
66    @property
67    @abstractmethod
68    def fsample(self) -> float:
69        """Sample rate of EEG source"""
70        pass

Sample rate of EEG source

n_channels: int
72    @property
73    @abstractmethod
74    def n_channels(self) -> int:
75        """Number of EEG channels per sample"""
76        pass

Number of EEG channels per sample

channel_types: list[str]
78    @property
79    @abstractmethod
80    def channel_types(self) -> list[str]:
81        """The type of each channel, ex: eeg, or stim"""
82        pass

The type of each channel, ex: eeg, or stim

channel_units: list[str]
84    @property
85    @abstractmethod
86    def channel_units(self) -> list[str]:
87        """The unit of each channel, ex: microvolts"""
88        pass

The unit of each channel, ex: microvolts

channel_labels: list[str]
90    @property
91    @abstractmethod
92    def channel_labels(self) -> list[str]:
93        """The label for each channel, ex: FC3, C5"""
94        pass

The label for each channel, ex: FC3, C5

@abstractmethod
def get_samples(self) -> tuple[list[list], list]:
 96    @abstractmethod
 97    def get_samples(self) -> tuple[list[list], list]:
 98        """Get EEG samples and timestamps since last call
 99
100        Returns
101        -------
102        samples_data: tuple(samples, timestamps)
103            - A tuple of (samples, timestamps) where:
104                - samples : list[float]
105                    - A list of samples, where each sample corresponds to a timestamp. Each sample is a list of floats representing the value for each channel of EEG.
106                - timestamps : list[float]
107                    - A list timestamps (float in seconds) corresponding to the samples
108
109        """
110        pass

Get EEG samples and timestamps since last call

Returns
  • samples_data (tuple(samples, timestamps)):
    • A tuple of (samples, timestamps) where:
      • samples : list[float]
        • A list of samples, where each sample corresponds to a timestamp. Each sample is a list of floats representing the value for each channel of EEG.
      • timestamps : list[float]
        • A list timestamps (float in seconds) corresponding to the samples
@abstractmethod
def time_correction(self) -> float:
112    @abstractmethod
113    def time_correction(self) -> float:
114        """Get the current time correction for timestamps.
115
116        Returns
117        -------
118        time_correction : float
119            The current time correction estimate (seconds).
120            - This is the number that needs to be added to a time tamp that was remotely generated via local_clock() to map it into the local clock domain of the machine.
121
122        """
123        pass

Get the current time correction for timestamps.

Returns
  • time_correction (float): The current time correction estimate (seconds).
    • This is the number that needs to be added to a time tamp that was remotely generated via local_clock() to map it into the local clock domain of the machine.