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