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)
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))
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()
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()
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()
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)
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()
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()
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()
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]
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)
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)
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))