def test_staircase(): # this seems to block stairs1 = slab.Staircase(start_val=10, n_reversals=4) stairs2 = slab.Staircase(start_val=8, n_reversals=6) stairs = zip_longest(stairs1, stairs2) count = 0 for stim1, stim2 in stairs: count += 1 if count > 100: break print(count) if stim1 is not None: r1 = stairs1.simulate_response(4) stairs1.add_response(r1) # stairs1.print_trial_info() if stim2 is not None: r2 = stairs2.simulate_response(2) stairs2.add_response(r2) # stairs2.print_trial_info() fig, ax = plt.subplots(2) stairs1.plot(axis=ax[0], show=False) stairs2.plot(axis=ax[1], show=False) # adaptive staircase stairs = slab.Staircase(start_val=10, n_reversals=18, step_sizes=[4, 1]) for stimulus_value in stairs: response = stairs.simulate_response(threshold=3) stairs.add_response(response) stairs.save_csv(PATH / "staircase.csv")
def practice_stairs(): ''' Presents an easy large-step staircase to practice. ''' print('This is a practise run. Explain the procedure to the participant.') print('Show the running staircase to the participant.') print('') print('One sound is presented in each trial.') print('Is this sound moving left or right?') print('Press 1 for left, 2 for right.') print('The direction will get more and more difficult to hear.') input('Press enter to start practice...') stairs = slab.Staircase(start_val=24, n_reversals=6, step_sizes=[10, 6, 4], min_val=1, max_val=30, n_up=1, n_down=1, n_pretrials=1) for trial in stairs: direction = numpy.random.choice(('left', 'right')) stim = moving_gaussian(speed=_adapter_speed, SNR=trial, direction=direction) stairs.present_tone_trial( stimulus=stim, correct_key_idx=1 if direction == 'left' else 2, print_info=True) stairs.plot() input('Done. Press enter to continue...') stairs.close_plot()
def jnd(speed=None, adapter_list=None): ''' Presents a staricase of moving_gaussian stimuli with varying SNR and returns the threshold. This threshold is used in the main experiment as the listener-specific SNR parameter. ''' if adapter_list: print( f'{_n_adapters_per_trial} sounds moving {_adapter_dir}, followed by' ) print('one sound moving left or right is presented.') print('Is this last sound moving left or right?') else: print('One sound is presented in each trial.') print('Is this sound moving left or right?') print('Press 1 for left, 2 for right.') print('The direction will get more and more difficult to hear.') input('Press enter to start JND estimation...') repeat = 'r' while repeat == 'r': # define the staircase stairs = slab.Staircase(start_val=24, n_reversals=14, step_sizes=[8, 6, 4, 3, 2, 1], min_val=0, max_val=30, n_up=1, n_down=1, n_pretrials=2) # loop through it _results_file.write('jnd:', tag='time') for trial in stairs: direction = numpy.random.choice(('left', 'right')) stim = moving_gaussian(speed=speed, SNR=trial, direction=direction) if adapter_list: adapters = adapter_list.random_choice( n=_n_adapters_per_trial) # some variety in the adapters adapters.append(stim) # add stim to list of adapters stim = slab.Sound.sequence( *adapters) # concatenate sounds in the list stairs.present_tone_trial( stimulus=stim, correct_key_idx=1 if direction == 'left' else 2) thresh = stairs.threshold(n=10) tag = f"{speed} {'with_adapter' if adapter_list else 'no_adapter'}" print(f'jnd for {tag}: {round(thresh, ndigits=1)}') repeat = input( 'Press enter to continue, "r" to repeat this threshold measurement.\n\n' ) _results_file.write(thresh, tag=tag) return thresh
def practice_stairs(): """ Presents an easy large-step staircase to practice. """ print( ' \n This is a practise run. Explain the procedure to the participant. \n ' 'Show the running staircase to the participant. \n \n' 'One sound is presented in each trial. \n' 'Is this sound moving left or right? \n' 'Press 1 for left, 2 for right. \n' 'The direction will get more and more difficult to hear. \n') input('Press enter to start practice...') _results_file.write('familiarization:', tag='time') stairs = slab.Staircase(start_val=24, n_reversals=6, step_sizes=[10, 6, 4], min_val=1, max_val=30, n_up=1, n_down=1, n_pretrials=1) for trial in stairs: direction = numpy.random.choice(('left', 'right')) stim = moving_gaussian(speed=_adaptor_speed, snr=trial, direction=direction) stairs.present_tone_trial( stimulus=stim, correct_key_idx=1 if direction == 'left' else 2, print_info=True) stairs.plot() thresh = stairs.threshold() print(f'threshold: {thresh}') _results_file.write(thresh, tag='threshold') input('Done. Press enter to continue...') stairs.close_plot()
def jnd(adaptor): """ Presents a staricase of moving_gaussian stimuli with varying SNR and returns the threshold. This threshold is used in the main experiment as the listener-specific SNR parameter. """ print() if adaptor: print(f'{_n_adaptors_per_trial} sounds moving {_adaptor_dir},' f' followed by one sound moving left or right is presented. \n' f'Is this last sound moving left or right? \n \n') else: print('One sound is presented in each trial. \n' 'Is this sound moving left or right? \n \n') print('Press 1 for left, 2 for right. \n' 'The direction will get more and more difficult to hear.\n') input('Press enter to start JND estimation...') repeat = 'r' while repeat == 'r': stairs = slab.Staircase(start_val=24, n_reversals=5, step_sizes=[8, 6, 4, 3, 2, 1], min_val=0, max_val=30, n_up=1, n_down=1, n_pretrials=2) _results_file.write('jnd:', tag='time') for trial in stairs: direction = numpy.random.choice(('left', 'right')) #Stimulus erzeugen: probe = moving_gaussian(speed=150, snr=trial, direction=direction) if adaptor == None: stim = probe else: adaptation = adaptor.random_choice( n=_n_adaptors_per_trial) # some variety in the adaptors adaptation.append( slab.Binaural.silence( duration=0.3, samplerate=44100)) #wie kurze Pause einbauen adaptation.append(probe) # add probe to list of adaptors stim = slab.Sound.sequence( *adaptation ) # concatenate sounds (6 Adaptoren + Probe) in the list stairs.present_tone_trial( stimulus=stim, correct_key_idx=0 if direction == 'left' else 1) #funtioniert manchmal nicht. Alternativ slab.psychoacoustics.input_method = 'figure'oben festlegen,kann mit dem stairsplot verbunden werden thresh = stairs.threshold( ) #n=x berechnet threshold der letzten x Umkehrungen #print(f'jnd for {adaptor}: {round(thresh, ndigits=1)}') #??? wie beziehen auf Adaptor-Namen? #_results_file.write(thresh, tag=adaptor) ??? geht nicht, weil Adaptor sich auf den Datensatz bezieht und nicht den Variablennamen repeat = input( 'Press r to repeat this threshold measurement. Press enter to continue.' ) return thresh
def jnd(condition, practise=False): ''' Presents a staricase for a 2AFC task and returns the threshold. This threshold is used in the main experiment as jnd. condition ... 'room', voice', or 'itd' ''' print('Three sounds are presented in each trial.') print('They are always different, but sometimes') if condition == 'room': print('one sound is played in a larger room,') print('and sometimes all three are played in the same room.') print('Was the larger room presented first, second, or third?') elif condition == 'voice': print('one is spoken by a different (larger) person,') print('and sometimes all three are spoken by the same person.') print('Was the larger person presented first, second, or third?') elif condition == 'itd': print('one is played from a different direction (slightly to the left),') print('and sometimes all three are played from straight ahead.') print('Was the sound slightly from the left played first, second, or third?') else: raise ValueError(f'Invalid condition {condition}.') print('Press 1 for first, 2 for second, 3 for third.') print('The difference will get more and more difficult to hear.') input('Press enter to start JND estimation...') repeat = 'r' condition_values = globals()[condition+'s'] # get the parameter list (vars rooms, voices, or itds) from condition string while repeat == 'r': # make a random, non-repeating list of words to present during the staircase word_seq = slab.Trialsequence(conditions=word_list, kind='infinite', label='word_seq') # define the staircase if practise: stairs = slab.Staircase(start_val=len(condition_values)-1, n_reversals=3, step_sizes=[4, 3, 2], min_val=0, max_val=len(condition_values)-1, n_up=1, n_down=1, n_pretrials=0) else: stairs = slab.Staircase(start_val=len(condition_values)-4, n_reversals=15, step_sizes=[4, 2], min_val=0, max_val=len(condition_values)-1, n_up=1, n_down=2, step_up_factor=1.5, n_pretrials=1) # should give approx. 70% hitrate _results_file.write(f'{condition} jnd:', tag='time') for trial in stairs: current = condition_values[int(trial)] # load stimuli word = next(word_seq) word2 = next(word_seq) word3 = next(word_seq) if condition == 'room': jnd_stim = slab.Sound(stim_folder / word / f'{word}_SER{default_voice:.4g}_GPR168_{current}_{default_itd}.wav') elif condition == 'voice': jnd_stim = slab.Sound(stim_folder / word / f'{word}_SER{current:.4g}_GPR168_{default_room}_{default_itd}.wav') elif condition == 'itd': jnd_stim = slab.Sound(stim_folder / word / f'{word}_SER{default_voice:.4g}_GPR168_{default_room}_{current}.wav') default_stim1 = slab.Sound(stim_folder / word2 / f'{word2}_SER{default_voice:.4g}_GPR168_{default_room}_{default_itd}.wav') default_stim2 = slab.Sound(stim_folder / word3 / f'{word3}_SER{default_voice:.4g}_GPR168_{default_room}_{default_itd}.wav') stairs.present_afc_trial(jnd_stim, [default_stim1, default_stim2], isi=ISI_stairs, print_info=practise) if practise: stairs.plot() thresh = stairs.threshold() thresh_condition_value = condition_values[numpy.ceil(thresh).astype('int')] if practise: stairs.close_plot() else: print(f'room jnd: {round(thresh, ndigits=1)}') _results_file.write(repr(stairs), tag=f'stairs {condition}') _results_file.write(thresh, tag=f'jnd {condition}') _results_file.write(thresh_condition_value, tag=f'jnd condition value {condition}') repeat = input('Press enter to continue, "r" to repeat this threshold measurement.\n\n') return thresh_condition_value