Esempio n. 1
0
def check(eeg: EEG, n_samples=256) -> pd.Series:
    """
    Usage:
    ------

    from eegnb.devices.eeg import EEG
    from eegnb.analysis.utils import check
    eeg = EEG(device='museS')
    check(eeg, n_samples=256)

    """

    df = eeg.get_recent(n_samples=n_samples)

    # seems to be necessary to give brainflow cnxn time to settle
    if len(df) != n_samples:
        sleep(10)
        df = eeg.get_recent(n_samples=n_samples)

    assert len(df) == n_samples

    n_channels = eeg.n_channels
    sfreq = eeg.sfreq
    device_backend = eeg.backend
    device_name = eeg.device_name

    vals = df.values[:, :n_channels]
    df.values[:, :n_channels] = channel_filter(vals, n_channels, sfreq,
                                               device_backend, device_name)

    std_series = df.std(axis=0)

    return std_series
Esempio n. 2
0
def runexp(
    experiment: str,
    eegdevice: str = None,
    macaddr: str = None,
    recdur: float = None,
    outfname: str = None,
    prompt: bool = False,
    dosigqualcheck=True,
):
    """
    Run experiment.

    Examples:

    Run experiment explicitly defining all necessary parameters
    (eeg device, experiment, duration, output file)
    This is the quickest way to run eeg-notebooks experiments,
    but requires knowledge of formatting for available options

    $ eegnb runexp -ex visual-N170 -ed museS -rd 10 -of test.csv


    Launch the interactive command line experiment setup+run tool
    This takes you through every experiment parameter in order
    and figures out + runs the complete function calls for you

    $ eegnb runexp -ip
    """

    if prompt:
        eeg, experiment, recdur, outfname = intro_prompt()
    else:
        if eegdevice == "ganglion":
            # if the ganglion is chosen a MAC address should also be provided
            eeg = EEG(device=eegdevice, mac_addr=macaddr)
        else:
            eeg = EEG(device=eegdevice)

    def askforsigqualcheck():
        do_sigqual = input(
            "\n\nRun signal quality check? (y/n). Recommend y \n")
        if do_sigqual == 'y':
            check_report(eeg)
        elif do_sigqual != 'n':
            "Sorry, didn't recognize answer. "
            askforsigqualcheck()

    if dosigqualcheck:
        askforsigqualcheck()

    run_experiment(experiment, eeg, recdur, outfname)

    print(f"\n\n\nExperiment complete! Recorded data is saved @ {outfname}")
Esempio n. 3
0
def runexp(
    experiment: str,
    eegdevice: str = None,
    macaddr: str = None,
    recdur: float = None,
    outfname: str = None,
    prompt: bool = False,
):
    """
    Run experiment.

    Examples:

    Run experiment explicitly defining all necessary parameters
    (eeg device, experiment, duration, output file)
    This is the quickest way to run eeg-notebooks experiments,
    but requires knowledge of formatting for available options

    $ eegnb runexp -ed museS -ex visual-N170 -rd 10 -of test.csv


    Launch the interactive command line experiment setup+run tool
    This takes you through every experiment parameter in order
    and figures out + runs the complete function calls for you

    $ eegnb runexp -ip
    """
    if prompt:
        print("run command line prompt script")
        from .introprompt import main as run_introprompt

        run_introprompt()
    else:
        from .utils import run_experiment
        from eegnb.devices.eeg import EEG

        if eegdevice == "ganglion":
            # if the ganglion is chosen a MAC address should also be proviced
            eeg = EEG(device=eegdevice, mac_addr=macaddr)
        else:
            eeg = EEG(device=eegdevice)

        run_experiment(experiment, eeg, recdur, outfname)
Esempio n. 4
0
def checksigqual(eegdevice: str):
    """
    Run signal quality check.

    Usage:
        eegnb checksigqual --eegdevice museS
    """

    from eegnb.devices.eeg import EEG
    from eegnb.analysis.utils import check_report

    eeg = EEG(device=eegdevice)

    check_report(eeg)
Esempio n. 5
0
def intro_prompt():
    """ This function handles the user prompts for inputting information about the session they wish to record.

    """
    # define the names of the available boards
    boards = [
        'None', 'Muse2016', 'Muse2', 'MuseS', 'OpenBCI Ganglion',
        'OpenBCI Cyton', 'OpenBCI Cyton + Daisy', 'G.Tec Unicorn', 'BrainBit',
        'Notion 1', 'Notion 2', 'Synthetic'
    ]

    # also define the board codes for passing to functions
    board_codes = [
        'none', 'muse2016', 'muse2', 'museS', 'ganglion', 'cyton',
        'cyton_daisy', 'unicorn', 'brainbit', 'notion1', 'notion2', 'synthetic'
    ]

    experiments = ['visual-N170', 'visual-P300', 'visual-SSVEP']

    # have the user input which device they intend to record with
    print(
        "Welcome to NeurotechX EEG Notebooks. \n"
        "Please enter the integer value corresponding to your EEG device: \n"
        f"[0] {boards[0]} \n"
        f"[1] {boards[1]} \n"
        f"[2] {boards[2]} \n"
        f"[3] {boards[3]} \n"
        f"[4] {boards[4]} \n"
        f"[5] {boards[5]} \n"
        f"[6] {boards[6]} \n"
        f"[7] {boards[7]} \n"
        f"[8] {boards[8]} \n"
        f"[9] {boards[9]} \n"
        f"[10] {boards[10]} \n", f"[11] {boards[11]} \n")

    board_idx = int(input('Enter Board Selection:'))
    board_selection = board_codes[
        board_idx]  # Board_codes are the actual names to be passed to the EEG class
    print(f"Selected board {boards[board_idx]} \n")

    # Handles wifi shield connectivity selection if an OpenBCI board is being used
    if board_selection in ['cyton', 'cyton_daisy', 'ganglion']:
        # if the ganglion is being used, will also need the MAC address
        if board_selection == 'ganglion':
            print("Please enter the Ganglions MAC address:\n")
            mac_address = input("MAC address:")

        # determine whether board is connected via Wifi or BLE
        print("Please select your connection method:\n"
              "[0] usb dongle \n"
              "[1] wifi shield \n")
        connect_idx = input("Enter connection method:")

        # add "_wifi" suffix to the end of the board name for brainflow
        if connect_idx == 1:
            board_selection = board_selection + "_wifi"

    # Experiment selection
    print("Please select which experiment you would like to run: \n"
          "[0] visual n170 \n"
          "[1] visual p300 \n"
          "[2] ssvep \n")

    exp_idx = int(input('Enter Experiment Selection:'))
    exp_selection = experiments[exp_idx]
    print(f"Selected experiment {exp_selection} \n")

    # record duration
    print("Now, enter the duration of the recording (in seconds). \n")
    duration = int(input("Enter duration:"))

    # Subject ID specification
    print("Next, enter the ID# of the subject you are recording data from. \n")
    subj_id = int(input("Enter subject ID#:"))

    # Session ID specification
    print("Next, enter the session number you are recording for. \n")
    session_nb = int(input("Enter session #:"))

    # start the EEG device
    if board_selection == 'ganglion':
        # if the ganglion is chosen a MAC address should also be proviced
        eeg_device = EEG(device=board_selection, mac_addr=mac_address)
    else:
        eeg_device = EEG(device=board_selection)

    # ask if they are ready to begin
    input("Press [ENTER] when ready to begin...")

    # generate the save file name
    save_fn = generate_save_fn(board_selection, exp_selection, subj_id,
                               session_nb)

    return eeg_device, exp_selection, duration, save_fn
Esempio n. 6
0
#
# Imports
import os
from eegnb import generate_save_fn
from eegnb.devices.eeg import EEG
from eegnb.experiments.visual_n170 import n170

# Define some variables
board_name = "muse"
experiment = "visual_n170"
subject_id = 0
session_nb = 0
record_duration = 120

###################################################################################################
# Initiate EEG device
# ---------------------
#
# Start EEG device
eeg_device = EEG(device=board_name)

# Create save file name
save_fn = generate_save_fn(board_name, experiment, subject_id, session_nb)
print(save_fn)

###################################################################################################
# Run experiment
# ---------------------
#
n170.present(duration=record_duration, eeg=eeg_device, save_fn=save_fn)
Esempio n. 7
0
def intro_prompt():
    """This function handles the user prompts for inputting information about the session they wish to record."""
    # define the names of the available boards
    boards = [
        "None",
        "Muse2016",
        "Muse2",
        "MuseS",
        "OpenBCI Ganglion",
        "OpenBCI Cyton",
        "OpenBCI Cyton + Daisy",
        "G.Tec Unicorn",
        "BrainBit",
        "Notion 1",
        "Notion 2",
        "Synthetic",
    ]

    # also define the board codes for passing to functions
    board_codes = [
        "none",
        "muse2016",
        "muse2",
        "museS",
        "ganglion",
        "cyton",
        "cyton_daisy",
        "unicorn",
        "brainbit",
        "notion1",
        "notion2",
        "synthetic",
    ]

    experiments = {
        '0': "visual-N170",
        '1': "visual-P300",
        '2': "visual-SSVEP",
        '3a': "auditory-oddball orig",
        '3b': "auditory-oddball diaconescu",
        '4a': "auditory-SSAEP orig",
        "4b": "auditory-SSAEP onefreq"
    }

    # have the user input which device they intend to record with
    print(
        "Welcome to NeurotechX EEG Notebooks. \n"
        "Please enter the integer value corresponding to your EEG device: \n"
        f"[0] {boards[0]} \n"
        f"[1] {boards[1]} \n"
        f"[2] {boards[2]} \n"
        f"[3] {boards[3]} \n"
        f"[4] {boards[4]} \n"
        f"[5] {boards[5]} \n"
        f"[6] {boards[6]} \n"
        f"[7] {boards[7]} \n"
        f"[8] {boards[8]} \n"
        f"[9] {boards[9]} \n"
        f"[10] {boards[10]} \n",
        f"[11] {boards[11]} \n",
    )

    board_idx = int(input("Enter Board Selection: "))
    board_selection = board_codes[
        board_idx]  # Board_codes are the actual names to be passed to the EEG class
    print(f"Selected board {boards[board_idx]} \n")

    # Handles connectivity selection if an OpenBCI board is being used
    if board_selection in ["cyton", "cyton_daisy", "ganglion"]:

        # determine whether board is connected via Wifi or BLE
        print("Please select your connection method:\n"
              "[0] usb dongle \n"
              "[1] wifi shield \n")
        connect_idx = int(input("Enter connection method: "))

        # add "_wifi" suffix to the end of the board name for brainflow
        if connect_idx == 1:
            board_selection = board_selection + "_wifi"

        if board_selection == "ganglion":
            # If the Ganglion is being used, you can enter optional Ganglion mac address
            ganglion_mac_address = input(
                "\nGanglion MAC Address (Press Enter to Autoscan): ")
        elif board_selection == "ganglion_wifi":
            # IP address is required for this board configuration
            ip_address = input("\nEnter Ganglion+WiFi IP Address: ")
        elif board_selection == "cyton_wifi" or board_selection == "cyton_daisy_wifi":
            print(
                f"\n{boards[board_idx]} + WiFi is not supported. Please use the dongle that was shipped with the device.\n"
            )
            exit()

    # Experiment selection
    print("\nPlease select which experiment you would like to run: \n"
          "[0] visual n170 \n"
          "[1] visual p300 \n"
          "[2] ssvep \n"
          "[3a] auditory oddball, orig version\n"
          "[3b] auditory oddball, diaconescu version\n"
          "[4a] auditory ssaep, orig version \n"
          "[4b] auditory ssaep, single freq version\n")

    exp_idx = str(input("Enter Experiment Selection: "))
    exp_selection = experiments[exp_idx]
    print(f"Selected experiment {exp_selection} \n")

    # record duration
    print("Now, enter the duration of the recording (in seconds). \n")
    duration = int(input("Enter duration: "))

    # Subject ID specification
    print(
        "\nNext, enter the ID# of the subject you are recording data from. \n")
    subj_id = int(input("Enter subject ID#: "))

    # Session ID specification
    print("\nNext, enter the session number you are recording for. \n")
    session_nb = int(input("Enter session #: "))

    # start the EEG device
    if board_selection.startswith("ganglion"):
        if board_selection == "ganglion_wifi":
            eeg_device = EEG(device=board_selection, ip_addr=ip_address)
        else:
            eeg_device = EEG(device=board_selection,
                             mac_addr=ganglion_mac_address)
    else:
        eeg_device = EEG(device=board_selection)

    # ask if they are ready to begin
    print("\nEEG device successfully connected!")
    input("Press [ENTER] when ready to begin...")

    # generate the save file name
    save_fn = generate_save_fn(board_selection, exp_selection, subj_id,
                               session_nb)

    return eeg_device, exp_selection, duration, save_fn
Esempio n. 8
0
def device_prompt() -> EEG:
    # define the names of the available boards
    # boards is a mapping from board code to board description
    boards = {
        "none": "None",
        "muse2016": "Muse (2016)",
        "muse2": "Muse 2",
        "museS": "Muse S",
        "ganglion": "OpenBCI Ganglion",
        "cyton": "OpenBCI Cyton",
        "cyton_daisy": "OpenBCI Cyton + Daisy",
        "unicord": "G.Tec Unicorn",
        "brainbit": "BrainBit",
        "notion1": "Notion 1",
        "notion2": "Notion 2",
        "synthetic": "Synthetic",
        "freeeeg32": "FreeEEG32",
    }

    print("Please enter the integer value corresponding to your EEG device: \n")
    print("\n".join(f"[{i:2}] {board}" for i, board in enumerate(boards.values())))

    board_idx = int(input("\nEnter Board Selection: "))

    # Board_codes are the actual names to be passed to the EEG class
    board_code = list(boards.keys())[board_idx]
    board_desc = list(boards.values())[board_idx]

    print(f"Selected board: {board_desc} \n")

    # Handles connectivity selection if an OpenBCI board is being used
    if board_code in ["cyton", "cyton_daisy", "ganglion"]:

        # determine whether board is connected via Wifi or BLE
        print(
            "Please select your connection method:\n"
            "[0] usb dongle \n"
            "[1] wifi shield \n"
        )
        connect_idx = int(input("Enter connection method: "))

        # add "_wifi" suffix to the end of the board name for brainflow
        if connect_idx == 1:
            board_code = board_code + "_wifi"
        if board_code == "ganglion":
            # If the Ganglion is being used, you can enter optional Ganglion mac address
            ganglion_mac_address = input(
                "\nGanglion MAC Address (Press Enter to Autoscan): "
            )
        elif board_code == "ganglion_wifi":
            # IP address is required for this board configuration
            ip_address = input("\nEnter Ganglion+WiFi IP Address: ")
        elif board_code == "cyton_wifi" or board_code == "cyton_daisy_wifi":
            print(
                f"\n{board_desc} + WiFi is not supported. Please use the dongle that was shipped with the device.\n"
            )
            exit()

    # initialize the EEG device
    if board_code.startswith("ganglion"):
        if board_code == "ganglion_wifi":
            eeg_device = EEG(device=board_code, ip_addr=ip_address)
        else:
            eeg_device = EEG(device=board_code, mac_addr=ganglion_mac_address)
    else:
        eeg_device = EEG(device=board_code)

    return eeg_device
Esempio n. 9
0
    def runexp(self):

        parser = argparse.ArgumentParser(description="Run EEG experiment.")

        parser.add_argument(
            "-ed",
            "--eegdevice",
            dest="eeg_device",
            type=str,
            default=None,
            help="add help here",
        )

        parser.add_argument(
            "-ma",
            "--macaddr",
            dest="mac_address",
            type=str,
            default=False,
            help="add help here",
        )

        parser.add_argument(
            "-ex",
            "--expt",
            dest="experiment",
            type=str,
            default=None,
            help="add help str",
        )

        parser.add_argument(
            "-rd",
            "--recdur",
            dest="record_duration",
            type=str,
            default=None,
            help="add help str",
        )

        parser.add_argument(
            "-of",
            "--outfname",
            dest="save_fn",
            type=str,
            default=None,
            help="add help str",
        )

        parser.add_argument(
            "-ip", "--inprom", dest="inprompt", action="store_true", help="add help str"
        )

        args = parser.parse_args(sys.argv[2:])

        if args.inprompt:
            print("run command line prompt script")
            from .introprompt import main as run_introprompt

            run_introprompt()
        else:
            from .utils import run_experiment
            from eegnb.devices.eeg import EEG

            if args.eeg_device == "ganglion":
                # if the ganglion is chosen a MAC address should also be proviced
                eeg_device = EEG(device=args.eeg_device, mac_addr=args.mac_address)
            else:
                eeg_device = EEG(device=args.eeg_device)

            run_experiment(
                args.experiment, args.record_duration, eeg_device, args.save_fn
            )
Esempio n. 10
0
def present(eeg: EEG = None,
            save_fn=None,
            stim_types=None,
            itis=None,
            additional_labels={},
            secs=0.07,
            volume=0.8,
            tone1_hz=440,
            tone2_hz=528,
            do_fixation=True):

    soa = 0  # ?

    # additional_labels is dict with column names as keys and column vecs as values,
    # that will be added to the dataframe

    # def present(duration=120, n_trials=10, iti=0.3, soa=0.2, jitter=0.2,
    #            secs=0.2, volume=0.8, random_state=None):

    # Create markers stream outlet
    # info = StreamInfo('Markers', 'Markers', 1, 0, 'int32', 'myuidw43536')
    # info = StreamInfo('Markers', 'Markers', 1 + len(additional_labels), 0, 'int32', 'myuidw43536')
    info = StreamInfo("Markers", "Markers", 1 + len(additional_labels), 0,
                      "float32", "myuidw43536")

    outlet = StreamOutlet(info)

    # np.random.seed(random_state)
    markernames = [1, 2]
    start = time.time()

    # Initialize stimuli
    # aud1 = sound.Sound('C', octave=5, sampleRate=44100, secs=secs)
    aud1 = sound.Sound(tone1_hz,
                       secs=secs)  # , octave=5, sampleRate=44100, secs=secs)
    aud1.setVolume(volume)

    # aud2 = sound.Sound('D', octave=6, sampleRate=44100, secs=secs)
    aud2 = sound.Sound(tone2_hz, secs=secs)
    aud2.setVolume(volume)
    auds = [aud1, aud2]

    # Setup trial list
    trials = DataFrame(dict(sound_ind=stim_types, iti=itis))

    record_duration_int = int(round(trials.iti.values.sum(), -1))
    record_duration_float = np.float32(record_duration_int)

    for col_name, col_vec in additional_labels.items():
        trials[col_name] = col_vec

    if do_fixation:
        # Setup graphics
        mywin = visual.Window([1920, 1080],
                              monitor="testMonitor",
                              units="deg",
                              fullscr=True)
        fixation = visual.GratingStim(win=mywin,
                                      size=0.2,
                                      pos=[0, 0],
                                      sf=0,
                                      rgb=[1, 0, 0])
        fixation.setAutoDraw(True)
        mywin.flip()

        # Show the instructions screen
        show_instructions(record_duration_int)

    # Start the EEG stream
    if eeg:
        if save_fn is None:  # If no save_fn passed, generate a new unnamed save file
            # random_id = random.randint(1000,10000)
            random_id = 9999
            save_fn = generate_save_fn(eeg.device_name, "auditory_erp_arrayin",
                                       random_id, random_id, "unnamed")
            print(
                f"No path for a save file was passed to the experiment. Saving data to {save_fn}"
            )
        eeg.start(save_fn, duration=record_duration_float + 5)

    # Start EEG Stream, wait for signal to settle, and then pull timestamp for start point
    start = time.time()

    for ii, trial in trials.iterrows():

        # Intertrial interval
        time.sleep(trial["iti"])

        # Select and play sound
        ind = int(trial["sound_ind"])
        auds[ind].stop()
        auds[ind].play()

        additional_stamps = []
        for k in additional_labels.keys():
            additional_stamps += [trial[k]]

        # Send marker
        #timestamp = time.time()
        # outlet.push_sample([markernames[ind]], timestamp)

        #outlet.push_sample(additional_stamps + [markernames[ind]], timestamp)

        # Offset
        # time.sleep(soa)
        # if (time.time() - start) > record_duration:
        #    break

        # Send marker
        # outlet.push_sample([markernames[ind]], timestamp)
        #outlet.push_sample(additional_stamps + [markernames[ind]], timestamp)

        # Push sample
        if eeg:
            timestamp = time.time()

            marker = additional_stamps + [markernames[ind]]
            """
            if eeg.backend == "muselsl":
                #marker = [markernames[ind]]
                marker = additional_stamps + [markernames[ind]]
            else:
                marker = markernames[ind]  # type: ignore
                mark
            """

            #eeg.push_sample(marker=additional_stamps + marker, timestamp=timestamp)
            eeg.push_sample(marker=marker, timestamp=timestamp)

        if do_fixation:
            mywin.flip()

            # offset
            core.wait(soa)
            mywin.flip()

        if len(event.getKeys()) > 0 or (time.time() -
                                        start) > (record_duration_float + 5):
            break

        event.clearEvents()

    # Cleanup
    if eeg: eeg.stop()

    if do_fixation:
        mywin.close()

    return trials
Esempio n. 11
0
def present(duration=120,
            eeg: EEG = None,
            save_fn=None,
            n_trials=2010,
            iti=0.4,
            soa=0.3,
            jitter=0.2):

    record_duration = np.float32(duration)
    markernames = [1, 2]

    # Setup trial list
    image_type = np.random.binomial(1, 0.5, n_trials)
    trials = DataFrame(
        dict(image_type=image_type, timestamp=np.zeros(n_trials)))

    def load_image(fn):
        return visual.ImageStim(win=mywin, image=fn)

    # start the EEG stream, will delay 5 seconds to let signal settle

    # Setup graphics
    mywin = visual.Window([1600, 900],
                          monitor="testMonitor",
                          units="deg",
                          fullscr=True)

    faces = list(
        map(load_image, glob(os.path.join(FACE_HOUSE, "faces", "*_3.jpg"))))
    houses = list(
        map(load_image, glob(os.path.join(FACE_HOUSE, "houses", "*.3.jpg"))))
    stim = [houses, faces]

    # Show the instructions screen
    show_instructions(duration)

    if eeg:
        if save_fn is None:  # If no save_fn passed, generate a new unnamed save file
            random_id = random.randint(1000, 10000)
            save_fn = generate_save_fn(eeg.device_name, "visual_n170",
                                       random_id, random_id, "unnamed")
            print(
                f"No path for a save file was passed to the experiment. Saving data to {save_fn}"
            )
        eeg.start(save_fn, duration=record_duration + 5)

    # Start EEG Stream, wait for signal to settle, and then pull timestamp for start point
    start = time()

    # Iterate through the events
    for ii, trial in trials.iterrows():
        # Inter trial interval
        core.wait(iti + np.random.rand() * jitter)

        # Select and display image
        label = trials["image_type"].iloc[ii]
        image = choice(faces if label == 1 else houses)
        image.draw()

        # Push sample
        if eeg:
            timestamp = time()
            if eeg.backend == "muselsl":
                marker = [markernames[label]]
            else:
                marker = markernames[label]
            eeg.push_sample(marker=marker, timestamp=timestamp)

        mywin.flip()

        # offset
        core.wait(soa)
        mywin.flip()
        if len(event.getKeys()) > 0 or (time() - start) > record_duration:
            break

        event.clearEvents()

    # Cleanup
    if eeg:
        eeg.stop()

    mywin.close()
Esempio n. 12
0
    def runexp(self):

        parser = argparse.ArgumentParser(description='Run EEG experiment.')

        parser.add_argument('-ed',
                            '--eegdevice',
                            dest='eeg_device',
                            type=str,
                            default=None,
                            help='add help here')

        parser.add_argument('-ma',
                            '--macaddr',
                            dest='mac_address',
                            type=str,
                            default=False,
                            help='add help here')

        parser.add_argument('-ex',
                            '--expt',
                            dest='experiment',
                            type=str,
                            default=None,
                            help='add help str')

        parser.add_argument('-rd',
                            '--recdur',
                            dest='record_duration',
                            type=str,
                            default=None,
                            help='add help str')

        parser.add_argument('-of',
                            '--outfname',
                            dest='save_fn',
                            type=str,
                            default=None,
                            help='add help str')

        parser.add_argument('-ip',
                            '--inprom',
                            dest='inprompt',
                            action='store_true',
                            help='add help str')

        args = parser.parse_args(sys.argv[2:])

        if args.inprompt:
            print('run command line prompt script')
            from .introprompt import main as run_introprompt
            run_introprompt()
        else:
            from .utils import run_experiment
            from eegnb.devices.eeg import EEG

            if args.eeg_device == 'ganglion':
                # if the ganglion is chosen a MAC address should also be proviced
                eeg_device = EEG(device=args.eeg_device,
                                 mac_addr=args.mac_address)
            else:
                eeg_device = EEG(device=args.eeg_device)

            run_experiment(args.experiment, args.record_duration, eeg_device,
                           args.save_fn)