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
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}")
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)
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)
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
# # 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)
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
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
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 )
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
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()
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)