Beispiel #1
0
 def test_find_connector(self):
     """Registry should find the correct connector given the DeviceSpec and ConnectionMethod"""
     self.assertEqual(
         find_connector(supported_device('DSI'), ConnectionMethod.TCP),
         DsiConnector)
     self.assertEqual(
         find_connector(supported_device('DSI'), ConnectionMethod.LSL),
         LslConnector)
     self.assertEqual(
         find_connector(supported_device('LSL'), ConnectionMethod.LSL),
         LslConnector)
Beispiel #2
0
    def test_connector(self):
        """Registry should construct the correct connector given the DeviceSpec and ConnectionMethod."""
        connector = make_connector(supported_device('DSI'),
                                   ConnectionMethod.TCP, {
                                       'host': '127.0.0.1',
                                       'port': 9000
                                   })
        self.assertTrue(isinstance(connector, DsiConnector))
        self.assertEqual(9000, connector.connection_params['port'])

        connector = make_connector(supported_device('LSL'),
                                   ConnectionMethod.LSL, {})
        self.assertTrue(isinstance(connector, LslConnector))
Beispiel #3
0
def main():
    """Initialize and run the server."""
    import argparse

    from bcipy.acquisition.datastream.generator import file_data_generator, random_data_generator, generator_with_args
    from bcipy.acquisition.protocols.registry import find_protocol
    from bcipy.acquisition.connection_method import ConnectionMethod
    from bcipy.acquisition.devices import supported_device

    parser = argparse.ArgumentParser()
    parser.add_argument('-H', '--host', default='127.0.0.1')
    parser.add_argument('-p', '--port', type=int, default=8844)
    parser.add_argument('-f',
                        '--filename',
                        default=None,
                        help="file containing data to be streamed; "
                        "if missing, random data will be served.")
    parser.add_argument('-n',
                        '--name',
                        default='DSI',
                        help='Name of the device spec to mock.')
    args = parser.parse_args()

    if args.filename:
        daq_type, sample_rate, channels = _settings(args.filename)
        device_spec = supported_device(daq_type)
        device_spec.sample_rate = sample_rate
        device_spec.channels = channels

        generator = generator_with_args(file_data_generator,
                                        filename=args.filename)
    else:
        device_spec = supported_device(args.name)
        generator = random_data_generator

    protocol = find_protocol(device_spec, ConnectionMethod.TCP)
    try:
        server = TcpDataServer(protocol=protocol,
                               generator=generator,
                               host=args.host,
                               port=args.port)
        log.debug("New server created")
        server.start()
        log.debug("Server started")
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("Keyboard Interrupt")
        server.stop()
Beispiel #4
0
def main():
    """Creates a new TCP server that serves up random EEG-like data in the
    DSI format. The server can be stopped with a Keyboard Interrupt (Ctl-C)"""

    import time
    import sys

    # Allow the script to be run from the bci root, acquisition dir, or
    # demo dir.
    sys.path.append('.')
    sys.path.append('..')
    sys.path.append('../..')

    from bcipy.acquisition.protocols import registry
    from bcipy.acquisition.devices import supported_device
    from bcipy.acquisition.connection_method import ConnectionMethod
    from bcipy.acquisition.datastream.tcp_server import TcpDataServer

    # Find the DSI protocol by name.
    protocol = registry.find_protocol(supported_device('DSI'), ConnectionMethod.TCP)

    try:
        server = TcpDataServer(protocol=protocol, host='127.0.0.1', port=9000)
        server.start()
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("Keyboard Interrupt")
        server.stop()
Beispiel #5
0
def main():
    """Creates a sample client that reads data from a sample TCP server
    (see demo/server.py). Data is written to a buffer.db sqlite3 database
    and streamed through a GUI. These files are written in whichever directory
    the script was run.

    The client/server can be stopped with a Keyboard Interrupt (Ctl-C)."""

    from bcipy.acquisition.datastream.lsl_server import LslDataServer
    from bcipy.acquisition.devices import supported_device
    from bcipy.gui.viewer import data_viewer

    device_spec = supported_device('LSL')
    server = LslDataServer(device_spec=device_spec)

    try:
        server.start()
        data_viewer.main(data_file=None,
                         seconds=5,
                         downsample_factor=2,
                         refresh=500,
                         yscale=150,
                         display_screen=0)
        # Stop the server after the data_viewer GUI is closed
        server.stop()
    except KeyboardInterrupt:
        print("Keyboard Interrupt; stopping.")
        server.stop()
Beispiel #6
0
    def test_load_from_config(self):
        """Should be able to load a list of supported devices from a
        configuration file."""

        # create a config file in a temp location.
        temp_dir = tempfile.mkdtemp()
        channels = ["P4", "Fz", "Pz", "F7", "PO8", "PO7", "Oz", "TRG"]
        my_devices = [
            dict(name="DSI-VR300",
                 content_type="EEG",
                 channels=channels,
                 sample_rate=300.0,
                 connection_methods=["TCP", "LSL"],
                 description="Wearable Sensing DSI-VR300")
        ]
        config_path = Path(temp_dir, 'my_devices.json')
        with open(config_path, 'w') as config_file:
            json.dump(my_devices, config_file)

        devices.load(config_path)
        supported = devices.supported_devices()
        self.assertEqual(1, len(supported.keys()))
        self.assertTrue('DSI-VR300' in supported.keys())

        spec = supported['DSI-VR300']
        self.assertEqual('EEG', spec.content_type)
        self.assertEqual(300.0, spec.sample_rate)
        self.assertEqual(channels, spec.channels)

        self.assertEqual(spec, devices.supported_device('DSI-VR300'))
        shutil.rmtree(temp_dir)
Beispiel #7
0
def main():
    """Creates a sample client that reads data from an LSL server
    (see demo/server.py). Data is written to a rawdata.csv file, as well as a
    buffer.db sqlite3 database. These files are written in whichever directory
    the script was run.

    The client can be stopped with a Keyboard Interrupt (Ctl-C).

    Note: This demo assumes that you already have a running lsl_server.
    """

    import sys
    import time

    # Allow the script to be run from the bci root, acquisition dir, or
    # demo dir.
    sys.path.append('.')
    sys.path.append('..')
    sys.path.append('../..')

    from bcipy.acquisition.client import DataAcquisitionClient
    from bcipy.acquisition.protocols import registry
    from bcipy.acquisition.devices import supported_device
    from bcipy.acquisition.connection_method import ConnectionMethod

    # pylint: disable=invalid-name
    device_spec = supported_device('LSL')
    print(f"\nAcquiring data from device {device_spec}")

    Connector = registry.find_connector(device_spec, ConnectionMethod.LSL)
    lsl_connector = Connector(connection_params={}, device_spec=device_spec)
    lsl_connector.include_marker_streams = True
    if Connector:
        print(f"Found device connector: {lsl_connector}")

    # Use default processor (FileWriter), buffer, and clock.
    raw_data_name = 'lsl_client_raw_data.csv'
    client = DataAcquisitionClient(connector=lsl_connector,
                                   raw_data_file_name=raw_data_name)

    try:
        client.start_acquisition()
        print("\nCollecting data for 3s... (Interrupt [Ctl-C] to stop)\n")

        while True:
            time.sleep(3)
            print(f"Number of samples: {client.get_data_len()}")
            client.stop_acquisition()
            client.cleanup()
            print(f"The collected data has been written to {raw_data_name}")
            break
    except IOError as e:
        print(f'{e.strerror}; make sure you started the server.')
    except KeyboardInterrupt:
        print("Keyboard Interrupt")
        client.stop_acquisition()
        client.cleanup()
Beispiel #8
0
def main():
    """Initialize and start the server."""
    import time
    import argparse

    from bcipy.acquisition.datastream.generator import file_data_generator
    from bcipy.acquisition.devices import supported_device

    parser = argparse.ArgumentParser()
    parser.add_argument('-f', '--filename', default=None,
                        help="file containing data to be streamed; "
                        "if missing, random data will be served.")
    parser.add_argument('-m', '--markers', action="store_true", default=False)
    parser.add_argument('-n', '--name', default='LSL', help='Name of the device spec to mock.')
    args = parser.parse_args()

    if args.filename:
        daq_type, sample_rate, channels = _settings(args.filename)
        device_spec = supported_device(daq_type)
        device_spec.sample_rate = sample_rate
        device_spec.channels = channels
        generator = file_data_generator(filename=args.filename)
    else:
        device_spec = supported_device(args.name)
        generator = None

    markers = True if args.markers else False
    try:
        server = LslDataServer(device_spec=device_spec, generator=generator, add_markers=markers)

        log.debug("New server created")
        server.start()
        log.debug("Server started")
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("Keyboard Interrupt")
        server.stop()
Beispiel #9
0
def main():
    """Creates a sample client that reads data from a TCP server
    (see demo/server.py). Data is written to a rawdata.csv file, as well as a
    buffer.db sqlite3 database. These files are written in whichever directory
    the script was run.

    The client can be stopped with a Keyboard Interrupt (Ctl-C)."""

    import time
    import sys
    from psychopy import clock

    # Allow the script to be run from the bci root, acquisition dir, or
    # demo dir.
    sys.path.append('.')
    sys.path.append('..')
    sys.path.append('../..')

    from bcipy.acquisition.client import DataAcquisitionClient
    from bcipy.acquisition.devices import supported_device
    from bcipy.acquisition.protocols.dsi.dsi_connector import DsiConnector

    # Start the server with the command:
    # python bcipy/acquisition/datastream/tcp_server.py --name DSI --port 9000
    device_spec = supported_device('DSI')
    connection_params = {'host': '127.0.0.1', 'port': 9000}
    connector = DsiConnector(connection_params=connection_params,
                             device_spec=device_spec)

    # Use default processor (FileWriter), buffer, and clock.
    client = DataAcquisitionClient(connector=connector, clock=clock.Clock())

    try:
        client.start_acquisition()
        print("\nCollecting data for 3s... (Interrupt [Ctl-C] to stop)\n")
        while True:
            time.sleep(3)
            print(f"Number of samples: {client.get_data_len()}")
            client.stop_acquisition()
            client.cleanup()
            break
    except IOError as e:
        print(f'{e.strerror}; make sure you started the server.')
    except KeyboardInterrupt:
        print("Keyboard Interrupt")
        client.stop_acquisition()
        client.cleanup()
Beispiel #10
0
def analysis_channels(channels: List[str], device_name: str) -> list:
    """Analysis Channels.

    Defines the channels within a device that should be used for analysis.

    Parameters:
    ----------
        channels(list(str)): list of channel names from the raw_data
            (excluding the timestamp)
        device_name(str): daq_type from the raw_data file.
    Returns:
    --------
        A binary list indicating which channels should be used for analysis.
        If i'th element is 0, i'th channel in filtered_eeg is removed.
    """
    device = supported_device(device_name)
    relevant_channels = device.analysis_channels()
    if not relevant_channels:
        raise Exception("Analysis channels for the given device not found: "
                        f"{device_name}.")
    if channels is None:
        return relevant_channels
    return [int(ch in relevant_channels) for ch in channels]
Beispiel #11
0
def init_eeg_acquisition(parameters: dict,
                         save_folder: str,
                         clock=CountClock(),
                         server: bool = False):
    """Initialize EEG Acquisition.

    Initializes a client that connects with the EEG data source and begins
    data collection.

    Parameters
    ----------
        parameters : dict
            configuration details regarding the device type and other relevant
            connection information.
             {
               "acq_device": str,
               "acq_connection_method": str,
               "acq_host": str,
               "acq_port": int,
               "buffer_name": str,
               "raw_data_name": str
             }
        clock : Clock, optional
            optional clock used in the client; see client for details.
        server : bool, optional
            optionally start a mock data server that streams random data.
    Returns
    -------
        (client, server) tuple
    """

    # Set configuration parameters with default values if not provided.
    host = parameters['acq_host']
    port = parameters['acq_port']
    buffer_name = str(
        Path(save_folder, parameters.get('buffer_name', 'raw_data.db')))
    raw_data_file = Path(save_folder,
                         parameters.get('raw_data_name', 'raw_data.csv'))

    connection_method = ConnectionMethod.by_name(
        parameters['acq_connection_method'])
    # TODO: parameter for loading devices; path to devices.json?
    # devices.load(devices_path)
    device_spec = supported_device(parameters['acq_device'])

    dataserver = False
    if server:
        dataserver = start_server(connection_method, device_spec, host, port)

    # TODO: only use these connection_params if this is ConnectionMethod.TCP
    # Refactor to extract only the needed connection params from parameters.
    connection_params = {'host': host, 'port': port}
    connector = registry.make_connector(device_spec, connection_method,
                                        connection_params)

    client = DataAcquisitionClient(connector=connector,
                                   buffer_name=buffer_name,
                                   delete_archive=False,
                                   raw_data_file_name=raw_data_file,
                                   clock=clock)

    client.start_acquisition()

    if parameters['acq_show_viewer']:
        viewer_screen = 1 if int(parameters['stim_screen']) == 0 else 0
        start_viewer(display_screen=viewer_screen)

    # If we're using a server or data generator, there is no reason to
    # calibrate data.
    if server and connection_method != ConnectionMethod.LSL:
        client.is_calibrated = True

    return (client, dataserver)
Beispiel #12
0
 def test_search_by_name(self):
     """Should be able to find a supported device by name."""
     dsi_device = devices.supported_device('DSI')
     self.assertEqual('DSI', dsi_device.name)
Beispiel #13
0
 def test_find_protocol(self):
     """Registry should find the correct protocol given the DeviceSpec and ConnectionMethod"""
     device_spec = supported_device('DSI')
     protocol = find_protocol(device_spec, ConnectionMethod.TCP)
     self.assertTrue(isinstance(protocol, DsiProtocol))