Пример #1
0
    def test_get_data_for_clock(self):
        """Test queries to the data store by experiment clock units."""

        channels = ['ch1', 'ch2', 'TRG']
        sample_hz = 100
        trigger_at = 10
        num_records = 1000
        n_channels = len(channels) - 1
        data = [
            mock_record(n_channels) + [0 if (i + 1) < trigger_at else 1]
            for i in range(num_records)
        ]

        device = _MockConnector(data=data,
                                device_spec=DeviceSpec(name="Mock_device",
                                                       channels=channels,
                                                       sample_rate=sample_hz))
        daq = DataAcquisitionClient(
            connector=device,
            buffer_name='buffer_client_test_get_data_for_clock.db',
            raw_data_file_name=None,
            delete_archive=True,
            clock=CountClock())

        daq.start_acquisition()
        time.sleep(0.2)
        daq.stop_acquisition()

        self.assertTrue(daq.is_calibrated)

        # rownum at calibration should be trigger_at
        self.assertEqual(trigger_at, daq.record_at_calib.rownum)
        self.assertEqual(trigger_at, daq.record_at_calib.timestamp)
        self.assertEqual(data[trigger_at - 1], daq.record_at_calib.data)

        # Test with clocks exactly synchronized.
        self.assertEqual(0.1, daq.offset)
        data_slice = daq.get_data_for_clock(calib_time=0.1,
                                            start_time=0.2,
                                            end_time=0.3)
        self.assertEqual(10, len(data_slice))

        start_offset = 20
        for i, record in enumerate(data_slice):
            # mock-data is 0-based, so we have to subtract 1 from the start.
            mock_data_index = i + start_offset - 1
            self.assertEqual(record.data, data[mock_data_index])

        # Test with clocks offset
        data_slice = daq.get_data_for_clock(calib_time=0.2,
                                            start_time=0.4,
                                            end_time=0.6)
        self.assertEqual(20, len(data_slice))
        start_offset = 30
        for i, record in enumerate(data_slice):
            # mock-data is 0-based, so we have to subtract 1 from the start.
            mock_data_index = i + start_offset - 1
            self.assertEqual(record.data, data[mock_data_index])

        daq.cleanup()
Пример #2
0
    def test_missing_offset(self):
        """Test missing offset when no triggers are present in the data."""
        channels = ['ch1', 'ch2', 'TRG']
        sample_hz = 100
        num_records = 500

        # mock_data only has empty trigger values.
        n_channels = len(channels) - 1
        data = [mock_record(n_channels) + [0] for i in range(num_records)]

        device = _MockConnector(data=data,
                                device_spec=DeviceSpec(name="Mock_device",
                                                       channels=channels,
                                                       sample_rate=sample_hz))
        daq = DataAcquisitionClient(
            connector=device,
            clock=CountClock(),
            buffer_name='buffer_client_test_missing_offset.db',
            raw_data_file_name=None,
            delete_archive=True)

        with daq:
            time.sleep(0.1)

        self.assertFalse(daq.is_calibrated)
        self.assertEqual(daq.offset, None)
        daq.cleanup()
Пример #3
0
    def test_clock(self):
        """Test clock integration."""

        clock = CountClock()
        clock.counter = 10  # ensures that clock gets reset.

        device = _MockConnector(data=self.mock_data,
                                device_spec=self.device_spec)
        daq = DataAcquisitionClient(connector=device,
                                    buffer_name='buffer_client_test_clock.db',
                                    raw_data_file_name=None,
                                    delete_archive=True,
                                    clock=clock)
        with daq:
            time.sleep(0.1)

        # Get all records from buffer
        data = daq.get_data()

        # NOTE: we can't make any assertions about the Clock, since it is
        # copied when it's passed to the acquisition thread.
        self.assertTrue(len(data) > 0)
        for i, record in enumerate(data):
            self.assertEqual(record.timestamp, float(i + 1))

        daq.cleanup()
Пример #4
0
    def test_zero_offset(self):
        """Test offset value override"""

        channels = ['ch1', 'ch2', 'TRG']
        sample_hz = 100
        trigger_at = 10
        num_records = 500
        n_channels = len(channels) - 1

        data = [mock_record(n_channels) + [0 if (i + 1) < trigger_at else 1]
                for i in range(num_records)]

        device = _MockDevice(data=data, channels=channels, fs=sample_hz)
        daq = DataAcquisitionClient(device=device,
                                    processor=NullProcessor(),
                                    buffer_name='buffer_client_test_offset.db',
                                    clock=CountClock())

        daq.is_calibrated = True  # force the override.
        daq.start_acquisition()
        time.sleep(0.1)
        daq.stop_acquisition()

        self.assertTrue(daq.is_calibrated)
        self.assertEqual(daq.offset, 0.0, "Setting the is_calibrated to True\
            should override the offset calcution.")

        daq.cleanup()
Пример #5
0
    def test_zero_offset(self):
        """Test offset value override"""

        channels = ['ch1', 'ch2', 'TRG']
        sample_hz = 100
        trigger_at = 10
        num_records = 500
        n_channels = len(channels) - 1

        data = [
            mock_record(n_channels) + [0 if (i + 1) < trigger_at else 1]
            for i in range(num_records)
        ]

        device = _MockConnector(data=data,
                                device_spec=DeviceSpec(name="Mock_device",
                                                       channels=channels,
                                                       sample_rate=sample_hz))
        daq = DataAcquisitionClient(connector=device,
                                    buffer_name='buffer_client_test_offset.db',
                                    raw_data_file_name=None,
                                    delete_archive=True,
                                    clock=CountClock())

        daq.is_calibrated = True  # force the override.
        daq.start_acquisition()
        time.sleep(0.1)
        daq.stop_acquisition()

        self.assertTrue(daq.is_calibrated)
        self.assertEqual(
            daq.offset, 0.0, "Setting the is_calibrated to True\
            should override the offset calcution.")

        daq.cleanup()
Пример #6
0
    def test_offset(self):
        """Test offset calculation"""

        channels = ['ch1', 'ch2', 'TRG']
        sample_hz = 100
        trigger_at = 10
        num_records = 500
        n_channels = len(channels) - 1

        data = [mock_record(n_channels) + [0 if (i + 1) < trigger_at else 1]
                for i in range(num_records)]

        device = _MockDevice(data=data, channels=channels, fs=sample_hz)
        daq = DataAcquisitionClient(device=device,
                                    processor=NullProcessor(),
                                    buffer_name='buffer_client_test_offset.db',
                                    clock=CountClock())

        daq.start_acquisition()
        time.sleep(0.1)
        daq.stop_acquisition()

        # The assertions should work before the stop_acquisition, but on some
        # Windows environments the tests were taking too long to setup and the
        # time would complete before any data had been processed.
        self.assertTrue(daq.is_calibrated)
        self.assertEqual(daq.offset, float(trigger_at) / sample_hz)

        daq.cleanup()
Пример #7
0
    def test_acquisition_null_device_exception(self):
        """Exception should be thrown if unable to connect to device or message not understood """
        daq = DataAcquisitionClient(connector=None)
        daq._is_streaming = False
        with self.assertRaises(Exception):
            daq.start_acquisition()

        daq.cleanup()
Пример #8
0
    def test_get_data(self):
        """Data should be queryable."""

        device = _MockDevice(data=self.mock_data, channels=self.mock_channels)
        daq = DataAcquisitionClient(device=device,
                                    processor=NullProcessor())
        daq.start_acquisition()
        time.sleep(0.1)
        daq.stop_acquisition()

        # Get all records
        data = daq.get_data()
        self.assertTrue(
            len(data) > 0, "DataAcquisitionClient should have data.")
        for i, record in enumerate(data):
            self.assertEqual(record.data, self.mock_data[i])

        daq.cleanup()
Пример #9
0
    def test_missing_offset(self):
        """Test missing offset when no triggers are present in the data."""
        channels = ['ch1', 'ch2', 'TRG']
        sample_hz = 100
        num_records = 500

        # mock_data only has empty trigger values.
        n_channels = len(channels) - 1
        data = [mock_record(n_channels) + [0] for i in range(num_records)]

        device = _MockDevice(data=data, channels=channels, fs=sample_hz)
        daq = DataAcquisitionClient(
            device=device,
            processor=NullProcessor(),
            clock=CountClock(),
            buffer_name='buffer_client_test_missing_offset.db')

        with daq:
            time.sleep(0.1)

        self.assertFalse(daq.is_calibrated)
        self.assertEqual(daq.offset, None)
        daq.cleanup()
Пример #10
0
    def test_get_data(self):
        """Data should be queryable."""

        device = _MockConnector(data=self.mock_data,
                                device_spec=self.device_spec)
        daq = DataAcquisitionClient(connector=device,
                                    delete_archive=True,
                                    raw_data_file_name=None)
        daq.start_acquisition()
        time.sleep(0.1)
        daq.stop_acquisition()

        # Get all records
        data = daq.get_data()
        self.assertTrue(
            len(data) > 0, "DataAcquisitionClient should have data.")
        for i, record in enumerate(data):
            self.assertEqual(record.data, self.mock_data[i])

        daq.cleanup()
Пример #11
0
    def test_clock(self):
        """Test clock integration."""

        clock = CountClock()
        clock.counter = 10  # ensures that clock gets reset.
        daq = DataAcquisitionClient(
            device=_MockDevice(data=self.mock_data,
                               channels=self.mock_channels),
            processor=NullProcessor(),
            buffer_name='buffer_client_test_clock.db',
            clock=clock)
        with daq:
            time.sleep(0.1)

        # Get all records from buffer
        data = daq.get_data()

        # NOTE: we can't make any assertions about the Clock, since it is
        # copied when it's passed to the acquisition thread.
        self.assertTrue(len(data) > 0)
        for i, record in enumerate(data):
            self.assertEqual(record.timestamp, float(i + 1))

        daq.cleanup()
Пример #12
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 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.protocols import registry

    # pylint: disable=invalid-name
    Device = registry.find_device('LSL')
    dsi_device = Device(connection_params={'host': '127.0.0.1', 'port': 9000})

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

    try:
        client.start_acquisition()
        print("\nCollecting data... (Interrupt [Ctl-C] to stop)\n")
        while True:
            pass
    except IOError as e:
        print(f'{e.strerror}; make sure you started the server.')
    except KeyboardInterrupt:
        print("Keyboard Interrupt")
        print("Number of samples: {0}".format(client.get_data_len()))
        client.stop_acquisition()
        client.cleanup()
Пример #13
0
    def test_offset_column(self):
        """Test offset calculation when a custom offset column is specified."""

        col_name = 'PHOTODIODE'
        channels = ['ch1', 'ch2', col_name]
        sample_hz = 100
        trigger_at = 10
        num_records = 500
        n_channels = len(channels) - 1

        data = [
            mock_record(n_channels) + [0 if (i + 1) < trigger_at else 1]
            for i in range(num_records)
        ]

        device = _MockConnector(data=data,
                                device_spec=DeviceSpec(name="Mock_device",
                                                       channels=channels,
                                                       sample_rate=sample_hz))
        daq = DataAcquisitionClient(connector=device,
                                    buffer_name='buffer_client_test_offset.db',
                                    raw_data_file_name=None,
                                    delete_archive=True,
                                    clock=CountClock())
        daq.trigger_column = col_name
        daq.start_acquisition()
        time.sleep(0.1)
        daq.stop_acquisition()

        # The assertions should work before the stop_acquisition, but on some
        # Windows environments the tests were taking too long to setup and the
        # time would complete before any data had been processed.
        self.assertTrue(daq.is_calibrated)
        self.assertEqual(daq.offset, float(trigger_at) / sample_hz)

        daq.cleanup()
Пример #14
0
def main(debug: bool = False):
    # pylint: disable=too-many-locals
    """Creates a sample lsl client that reads data from a sample 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/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.devices import DeviceSpec
    from bcipy.acquisition.protocols.lsl.lsl_connector import LslConnector
    from bcipy.acquisition.client import DataAcquisitionClient
    from bcipy.acquisition.datastream.lsl_server import LslDataServer
    from bcipy.acquisition.datastream.tcp_server import await_start

    from bcipy.helpers.system_utils import log_to_stdout

    if debug:
        log_to_stdout()

    # Generic LSL device with 16 channels.
    device_spec = DeviceSpec(name="LSL_demo",
                             channels=[
                                 "Ch1", "Ch2", "Ch3", "Ch4", "Ch5", "Ch6",
                                 "Ch7", "Ch8", "Ch9", "Ch10", "Ch11", "Ch12",
                                 "Ch13", "Ch14", "Ch15", "Ch16"
                             ],
                             sample_rate=256.0)
    server = LslDataServer(device_spec=device_spec)
    await_start(server)

    # Device is for reading data.
    connector = LslConnector(connection_params={}, device_spec=device_spec)

    raw_data_name = 'demo_raw_data.csv'
    client = DataAcquisitionClient(connector=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(1)
            client.marker_writer.push_marker('calibration_trigger')
            time.sleep(2)
            # since calibration trigger was pushed after 1 second of sleep
            print(f"Offset: {client.offset}; this value should be close to 1.")
            client.stop_acquisition()
            client.cleanup()
            server.stop()
            print(f"\nThe collected data has been written to {raw_data_name}")
            break

    except KeyboardInterrupt:
        print("Keyboard Interrupt; stopping.")
        client.stop_acquisition()
        client.cleanup()
        server.stop()
        print(f"\nThe collected data has been written to {raw_data_name}")
Пример #15
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)
Пример #16
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)."""

    import time

    from bcipy.acquisition.datastream import generator
    from bcipy.acquisition.protocols import registry
    from bcipy.acquisition.client import DataAcquisitionClient
    from bcipy.acquisition.datastream.server import DataServer
    from bcipy.gui.viewer.processor.viewer_processor import ViewerProcessor

    host = '127.0.0.1'
    port = 9000
    # The Protocol is for mocking data.
    protocol = registry.default_protocol('DSI')
    server = DataServer(protocol=protocol,
                        generator=generator.random_data,
                        gen_params={'channel_count': len(protocol.channels)},
                        host=host,
                        port=port)

    # Device is for reading data.
    # pylint: disable=invalid-name
    Device = registry.find_device('DSI')
    dsi_device = Device(connection_params={'host': host, 'port': port})
    client = DataAcquisitionClient(device=dsi_device,
                                   processor=ViewerProcessor())

    try:
        server.start()
        client.start_acquisition()
        seconds = 10
        print(
            f"\nCollecting data for {seconds}s... (Interrupt [Ctl-C] to stop)\n"
        )

        t0 = time.time()
        elapsed = 0
        while elapsed < seconds:
            time.sleep(0.1)
            elapsed = (time.time()) - t0
        client.stop_acquisition()
        client.cleanup()
        print("Number of samples: {0}".format(client.get_data_len()))
        server.stop()

    except KeyboardInterrupt:
        print("Keyboard Interrupt; stopping.")
        client.stop_acquisition()
        client.cleanup()
        print("Number of samples: {0}".format(client.get_data_len()))
        server.stop()
Пример #17
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()
Пример #18
0
    def test_daq_with_no_buffer(self):
        """get_data should return an empty list if daq._buf is None
        data length should return 0
        """

        device = _MockConnector(data=self.mock_data,
                                device_spec=self.device_spec)
        daq = DataAcquisitionClient(connector=device,
                                    delete_archive=True,
                                    raw_data_file_name=None)
        daq.start_acquisition()
        time.sleep(0.1)
        daq.stop_acquisition()

        # Make sure we are able to stop the buffer process
        buf_temp = daq._buf

        daq._buf = None

        # test get_data
        data = daq.get_data()
        self.assertEqual(data, [])

        # test get_data_len
        data_length = daq.get_data_len()
        self.assertEqual(data_length, 0)

        # test offset
        offset = daq.offset
        self.assertEqual(offset, None)

        daq._buf = buf_temp
        daq.cleanup()
Пример #19
0
def main():
    """Creates a sample client that reads data from a sample 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/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.datastream import generator
    from bcipy.acquisition.protocols import registry
    from bcipy.acquisition.client import DataAcquisitionClient
    from bcipy.acquisition.datastream.server import DataServer

    host = '127.0.0.1'
    port = 9000
    # The Protocol is for mocking data.
    protocol = registry.default_protocol('DSI')
    server = DataServer(protocol=protocol,
                        generator=generator.random_data,
                        gen_params={'channel_count': len(protocol.channels)},
                        host=host, port=port)

    # Device is for reading data.
    # pylint: disable=invalid-name
    Device = registry.find_device('DSI')
    dsi_device = Device(connection_params={'host': host, 'port': port})
    client = DataAcquisitionClient(device=dsi_device)

    try:
        server.start()
        client.start_acquisition()

        print("\nCollecting data for 10s... (Interrupt [Ctl-C] to stop)\n")

        while True:
            time.sleep(10)
            client.stop_acquisition()
            client.cleanup()
            print("Number of samples: {0}".format(client.get_data_len()))
            server.stop()
            print("The collected data has been written to rawdata.csv")
            break

    except KeyboardInterrupt:
        print("Keyboard Interrupt; stopping.")
        client.stop_acquisition()
        client.cleanup()
        print("Number of samples: {0}".format(client.get_data_len()))
        server.stop()
        print("The collected data has been written to rawdata.csv")
Пример #20
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()
Пример #21
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_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 server that streams random DSI data; defaults
            to true; if this is True, the client will also be a DSI client.
    Returns
    -------
        (client, server) tuple
    """

    # Initialize the needed DAQ Parameters
    host = parameters['acq_host']
    port = parameters['acq_port']

    parameters = {
        'acq_show_viewer': parameters['acq_show_viewer'],
        'viewer_screen': 1 if int(parameters['stim_screen']) == 0 else 0,
        'buffer_name': save_folder + '/' + parameters['buffer_name'],
        'device': parameters['acq_device'],
        'filename': save_folder + '/' + parameters['raw_data_name'],
        'connection_params': {
            'host': host,
            'port': port
        }
    }

    # Set configuration parameters (with default values if not provided).
    buffer_name = parameters.get('buffer_name', 'buffer.db')
    connection_params = parameters.get('connection_params', {})
    device_name = parameters.get('device', 'DSI')
    filename = parameters.get('filename', 'rawdata.csv')

    dataserver = False
    if server:
        if device_name == 'DSI':
            protocol = registry.default_protocol(device_name)
            dataserver, port = start_socket_server(protocol, host, port)
            connection_params['port'] = port
        elif device_name == 'LSL':
            channel_count = 16
            sample_rate = 256
            channels = ['ch{}'.format(c + 1) for c in range(channel_count)]
            dataserver = LslDataServer(
                params={
                    'name': 'LSL',
                    'channels': channels,
                    'hz': sample_rate
                },
                generator=generator.random_data(channel_count=channel_count))
            await_start(dataserver)
        else:
            raise ValueError(
                'Server (fake data mode) for this device type not supported')

    Device = registry.find_device(device_name)

    filewriter = FileWriter(filename=filename)
    proc = filewriter
    if parameters['acq_show_viewer']:
        proc = DispatchProcessor(
            filewriter,
            ViewerProcessor(display_screen=parameters['viewer_screen']))

    # Start a client. We assume that the channels and fs will be set on the
    # device; add a channel parameter to Device to override!
    client = DataAcquisitionClient(
        device=Device(connection_params=connection_params),
        processor=proc,
        buffer_name=buffer_name,
        clock=clock)

    client.start_acquisition()

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

    return (client, dataserver)
Пример #22
0
def main():
    # pylint: disable=too-many-locals
    """Creates a sample lsl client that reads data from a sample 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/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.datastream import generator
    from bcipy.acquisition.protocols import registry
    from bcipy.acquisition.client import DataAcquisitionClient
    from bcipy.acquisition.datastream.lsl_server import LslDataServer
    from bcipy.acquisition.datastream.server import await_start

    host = '127.0.0.1'
    port = 9000

    channel_count = 16
    sample_rate = 256
    channels = ['ch{}'.format(c + 1) for c in range(channel_count)]
    # The Protocol is for mocking data.
    server = LslDataServer(params={'name': 'LSL',
                                   'channels': channels,
                                   'hz': sample_rate},
                           generator=generator.random_data(
                               channel_count=channel_count))
    await_start(server)

    # Device is for reading data.
    # pylint: disable=invalid-name
    Device = registry.find_device('LSL')
    device = Device(connection_params={'host': host, 'port': port})
    client = DataAcquisitionClient(device=device)

    try:
        client.start_acquisition()

        print("\nCollecting data for 10s... (Interrupt [Ctl-C] to stop)\n")

        while True:
            time.sleep(10)
            client.stop_acquisition()
            client.cleanup()
            print("Number of samples: {0}".format(client.get_data_len()))
            server.stop()
            print("The collected data has been written to rawdata.csv")
            break

    except KeyboardInterrupt:
        print("Keyboard Interrupt; stopping.")
        client.stop_acquisition()
        client.cleanup()
        print("Number of samples: {0}".format(client.get_data_len()))
        server.stop()
        print("The collected data has been written to rawdata.csv")