Beispiel #1
0
def run(
    question_list,  # <-- list of strings
    randomize_presentation=False,
    experiment_id='experiment',
    phase_id='scale_questionnaire',
    subject_info=None,
    save_data=False,
    window=None,
    text_ypos=150,  # <-- y position of the row of stimuli
    text_padding=10,
    click_instructions_txt='Use the slider below to provide your answer.',
    click_instructions_txt_color=[-1, -1, -1],
    click_instructions_position=[0, -120],
    continue_txt_position=[0, -130],
    continue_txt_color=[-1, -1, -1],
    rating_scale_font='Arial',
    rating_scale_font_size=1,
    rating_scale_choices=['low', 'high'],
    rating_scale_min=0,
    rating_scale_max=100,
    rating_scale_message='',
    rating_scale_marker='circle',  # <-- options: {'circle', 'triangle', 'glow', 'slider', 'hover'}
    rating_scaler_marker_color='grey',
    rating_scale_position=[0, -250],
    rating_scale_length=1.2,
    rating_scale_size=1,
    rating_scale_show_value=False,
    rating_scale_density=100,
    quit_keys=['escape'],
    debug_mode=False,
):

    # Initialize Main Psychopy win if one isn't included
    if window == None:
        window = event_utils.build_window()

    cursor = event.Mouse()  # set initial cursor
    timer = core.Clock()

    if subject_info == None:
        subject_info = {
            'id': '0000',
            'condition': 0,
            'datafile_path': './subject_data.csv'
        }

    ## Prepare Stimuli and Text Objects
    object_bin = {}

    object_bin['question'] = visual.TextStim(
        window, pos=[0, 0], color=text_color)  # create Text Stim Object

    object_bin['response_scale'] = visual.RatingScale(
        window,
        labels=rating_scale_choices,
        low=rating_scale_min,
        high=rating_scale_max,
        precision=rating_scale_density,
        marker=rating_scale_marker,
        markerColor=rating_scaler_marker_color,
        pos=rating_scale_position,
        size=rating_scale_size,
        stretch=rating_scale_length,
        textFont=rating_scale_font,
        textSize=rating_scale_font_size,
        showValue=rating_scale_show_value,
        acceptSize=2,
        textColor=[-1, -1, -1],
        lineColor=[-1, -1, -1],
        mouseOnly=True,
        scale=None,
    )

    object_bin['click_msg'] = visual.TextStim(
        window,
        text=click_instructions_txt,
        pos=click_instructions_position,
        color=click_instructions_txt_color)

    object_bin['click_anywhere_msg'] = visual.TextStim(
        window,
        text='Click anywhere to continue...',
        pos=continue_txt_position,
        color=continue_txt_color,
    )

    if randomize_presentation == True:
        random.shuffle(question_list)

    for question in question_list:

        object_bin['question'].setText(question)

        # initially draw stimulus and response buttons
        event_utils.draw_objects_in_bin(
            window,
            object_bin,
            object_list=['question', 'response_scale'],
        )

        # wait some time
        if debug_mode == False: core.wait(.77)

        # draw click message
        object_bin['click_msg'].setText(click_instructions_txt)
        event_utils.draw_objects_in_bin(
            window,
            object_bin,
            object_list=['question', 'response_scale', 'click_msg'],
        )

        # wait some time
        if debug_mode == False: core.wait(.35)

        # wait for user to click a response button
        cursor.clickReset()
        event.clearEvents()
        timer.reset()
        while object_bin['response_scale'].noResponse:
            if event.getKeys(keyList=quit_keys):
                print('user terminated')
                core.quit()
            event_utils.draw_objects_in_bin(
                window,
                object_bin,
                object_list=['question', 'response_scale', 'click_msg'])

        response = object_bin['response_scale'].getRating()
        rt = object_bin['response_scale'].getRT()
        object_bin['response_scale'].reset()

        event_utils.draw_objects_in_bin(
            window,
            object_bin,
            object_list=['question', 'response_scale'],
        )

        if debug_mode == False: core.wait(1)

        # draw continue message
        event_utils.draw_objects_in_bin(
            window,
            object_bin,
            object_list=['question', 'response_scale', 'click_anywhere_msg'],
        )

        if debug_mode == False: core.wait(.35)

        event_utils.wait_for_click_response(cursor, timer, quit_keys=quit_keys)

        event_utils.draw_objects_in_bin(
            window,
            object_bin,
            object_list=['response_scale'],
        )

        if save_data == True:
            subject_data = [
                subject_info['id'],
                phase_id,
                subject_info['condition'],
                trial_num,
                question,
                response,
                rt,
            ]

            with open(subject_info['datafile_path'], 'a') as file:
                csv_object = csv.writer(file)
                csv_object.writerow(subject_data)

        trial_num = trial_num + 1
def run(
	stimuli,
	labels = None,
	randomize_presentation = True,

	supervised = True, # this determines whether participants recieve feedback
	num_blocks = 1,

	experiment_id = 'experiment',
	phase_id = 'forced_choice',
	subject_info = None,
	save_data = False,

	window = None,

	stim_position = [0,0],

	fixation_symbol = '',

	click_instructions_txt = 'Click a button to select the correct category.',
	click_instructions_txt_color = [-1,-1,-1], 
	click_instructions_position = [0, -120],

	feedback_txt_position = [0, -90],
	feedback_txt_color = [-1,-1,-1],
	
	continue_txt_position = [0, -145],
	continue_txt_color = [-1,-1,-1],

	response_btn_labels = None,
	response_btn_ypos = -280,
	response_btn_padding = 150,
	response_btn_box_size = [160, 80],
	response_btn_box_color = [.5, .8, .5],
	response_btn_txt_size = 22,
	response_btn_txt_font = 'Consolas',
	response_btn_txt_color = [-1,-1,-1],

	quit_keys = ['escape'],
	debug_mode = False,
):

	feedback_correct = [
		'msg 1',
		'msg 2',
		'msg 3',
		'msg 4',
		'msg 5',
		'msg 6',
	]

	feedback_incorrect = [
		'msg 1',
		'msg 2',
		'msg 3',
		'msg 4',
		'msg 5',
		'msg 6',
	]



	# Initialize Main Psychopy win if one isn't included
	if window == None:
		window = event_utils.build_window()

	cursor = event.Mouse() # set initial cursor
	timer = core.Clock()

	if subject_info == None:
		subject_info = {
			'id': '0000',
			'condition': 0,
			'datafile_path': './subject_data.csv'
		}

	if (labels == None) & (supervised == True):
		print(phase_id + ' is set to "supeprvised", but no labels were provided. quitting experiment.')
		sys.exit()

	if response_btn_labels == None:
		if labels != None:
			response_btn_labels = list(set(labels))
		else:
			response_btn_labels = ['no', 'labels', 'provided']


	## Prepare Stimuli and Text Objects
	object_bin = {} 
	
	object_bin['stim'] = visual.ImageStim(
		window,
		pos = stim_position,
		name = 'image_stim',
		interpolate = True,
	)
	
	object_bin['response_btns'] = event_utils.make_button_row(
		window,    # psychopy win object (required argument)
		labels = response_btn_labels, 
		ypos = response_btn_ypos, 
		padding = 100,  # this determines how far apart butons will be evenly placed
		btn_box_size = response_btn_box_size, 
		btn_box_color = response_btn_box_color, 
		btn_txt_size = response_btn_txt_size,
		btn_txt_color = response_btn_txt_color,
		btn_txt_font = response_btn_txt_font,
	)
	
	object_bin['click_msg'] = visual.TextStim(
		window,
		text = click_instructions_txt,
		pos = click_instructions_position,
		color = click_instructions_txt_color
	)

	object_bin['feedback_msg'] = visual.TextStim(
		window,
		pos = feedback_txt_position,
		color = feedback_txt_color,
	)

	object_bin['click_anywhere_msg'] = visual.TextStim(
		window,
		text = 'Click anywhere to continue...',
		pos = continue_txt_position, 
		color = continue_txt_color,
	)


	##__ Start Phase
	trial_num = 0
	accuracy = []
	presentation_order = list(range(len(stimuli)))

	for block in range(num_blocks):
		if randomize_presentation == True:
			random.shuffle(presentation_order)

		for i in presentation_order:
			
			# set stimulus image
			object_bin['stim'].setImage(stimuli[i])

			# initially draw stimulus and response buttons
			event_utils.draw_objects_in_bin(
				window,
				object_bin, 
				object_list = ['stim', 'response_btns'],
			)           

			# wait some time
			if debug_mode == False: core.wait(.77)

			# draw click message
			event_utils.draw_objects_in_bin(
				window,
				object_bin, 
				object_list = ['stim', 'response_btns', 'click_msg'],
			)

			# wait some time
			if debug_mode == False: core.wait(.35)

			# wait for user to click a response button
			response, rt = event_utils.wait_for_btn_response(cursor, timer, object_bin['response_btns'], quit_keys=quit_keys)

			# check accuracy of subject's response
			correct_category = labels[i]
			if (supervised == True) & (correct_category != 'gen'):
				hit = response == correct_category
			else:
				hit = 'gen'
			accuracy.append(hit)

			if supervised == True:
				if response == correct_category:
					object_bin['feedback_msg'].setText(random.choice(feedback_correct))
				else:
					object_bin['feedback_msg'].setText(random.choice(feedback_incorrect))

				# draw feedback message
				event_utils.draw_objects_in_bin(
					window,
					object_bin, 
					object_list = ['stim', 'response_btns', 'feedback_msg'],
				)
			else:
				event_utils.draw_objects_in_bin(
					window,
					object_bin, 
					object_list = ['stim', 'response_btns'],
				)


			if debug_mode == False: core.wait(1)
			
			# draw continue message
			if supervised == True:
				event_utils.draw_objects_in_bin(
					window,
					object_bin, 
					object_list = ['stim', 'response_btns', 'feedback_msg', 'click_anywhere_msg'],
				)

			else:
				event_utils.draw_objects_in_bin(
					window,
					object_bin, 
					object_list = ['stim', 'response_btns', 'click_anywhere_msg'],
				)

			if debug_mode == False: core.wait(.35)

			event_utils.wait_for_click_response(cursor, timer, quit_keys=quit_keys)

			event_utils.draw_objects_in_bin(
				window,
				object_bin,
				object_list = ['response_btns'],
			)

			if save_data == True:
				subject_data = [
					subject_info['id'],
					phase_id,
					subject_info['condition'],
					block,
					trial_num,
					stimuli[i],
					correct_category,
					response,
					hit,
					rt,
				]
				with open(subject_info['datafile_path'], 'a') as file:
					csv_object = csv.writer(file)
					csv_object.writerow(subject_data)



			# if early_finish_accuracy_criterion != None:
			# 	if trial_num > minimum_trials:
			# 		if sum(accuracy[-early_finish_lookback:]) / len(accuracy[-early_finish_lookback:]) >= early_finish_accuracy_criterion:
			# 			return

			trial_num = trial_num + 1
Beispiel #3
0
def run(
	stimuli,
	labels,
	randomize_presentation = True,

	supervised = True, # this determines whether participants recieve feedback
	num_blocks = 1,

	experiment_id = 'experiment',
	phase_id = 'forced_choice_endorsement',
	subject_info = None,
	save_data = False,

	window = None,

	stim_position = [0,0],

	fixation_symbol = '',

	click_instructions_txt = 'Do you think this is a member of this category?',
	click_instructions_txt_color = [-1,-1,-1],
	click_instructions_position = [0, -120],

	feedback_txt_position = [0, -90],
	feedback_txt_color = [-1,-1,-1],

	continue_txt_position = [0, -145],
	continue_txt_color = [-1,-1,-1],

	response_btn_ypos = -280,
	response_btn_padding = 150,
	response_btn_box_size = [160, 80],
	response_btn_box_color = [.5, .8, .5],
	response_btn_txt_size = 22,
	response_btn_txt_font = 'Consolas',
	response_btn_txt_color = [-1,-1,-1],

	quit_keys = ['escape'],
	debug_mode = False,
):

	# Initialize Main Psychopy win if one isn't included
	if window == None:
		window = event_utils.build_window()

	cursor = event.Mouse() # set initial cursor
	timer = core.Clock()

	if subject_info == None:
		subject_info = {
			'id': '0000',
			'condition': 0,
			'datafile_path': './subject_data.csv'
		}

	if (labels == None) & (supervised == True):
		print(phase_id + ' is set to "supeprvised", but no labels were provided. quitting experiment.')
		sys.exit()


	## Prepare Stimuli and Text Objects
	object_bin = {}

	object_bin['stim'] = visual.ImageStim(
		window,
		pos = stim_position,
		name = 'image_stim',
		interpolate = True,
	)

	btn_map = {
		'no': 'no',
		'yes': 'yes',
	}
	object_bin['response_btns'] = event_utils.make_button_row(
		window,    # psychopy win object (required argument)
		labels = list(btn_map.values()),
		ypos = response_btn_ypos,
		padding = 100,  # this determines how far apart butons will be evenly placed
		btn_box_size = response_btn_box_size,
		btn_box_color = response_btn_box_color,
		btn_txt_size = response_btn_txt_size,
		btn_txt_color = response_btn_txt_color,
		btn_txt_font = response_btn_txt_font,
	)

	object_bin['click_msg'] = visual.TextStim(
		window,
		text = click_instructions_txt,
		pos = click_instructions_position,
		color = click_instructions_txt_color
	)

	object_bin['feedback_msg'] = visual.TextStim(
		window,
		pos = feedback_txt_position,
		color = feedback_txt_color,
	)

	object_bin['click_anywhere_msg'] = visual.TextStim(
		window,
		text = 'Click anywhere to continue...',
		pos = continue_txt_position,
		color = continue_txt_color,
	)


	##__ Start Phase
	trial_num = 0
	accuracy = []
	unique_labels = []
	for label in list(set(labels)):
		if label != 'gen':
			unique_labels.append(label)

	for block in range(num_blocks):

		trial_data = [
			{
				'stimulus': stim,
				'correct_label': label,
				'presented_label': random.choice(unique_labels),
			}
		for stim, label in zip(stimuli, labels)
		]

		if randomize_presentation == True:
			random.shuffle(trial_data)

		for trial in trial_data:

			# set stimulus image
			object_bin['stim'].setImage(trial['stimulus'])

			# initially draw stimulus and response buttons
			event_utils.draw_objects_in_bin(
				window,
				object_bin,
				object_list = ['stim', 'response_btns'],
			)

			# wait some time
			if debug_mode == False: core.wait(.77)

			# draw click message
			object_bin['click_msg'].setText('Is this a member of category ' + trial['presented_label'] + ' ??')
			event_utils.draw_objects_in_bin(
				window,
				object_bin,
				object_list = ['stim', 'response_btns', 'click_msg'],
			)

			# wait some time
			if debug_mode == False: core.wait(.35)

			# wait for user to click a response button
			response, rt = event_utils.wait_for_btn_response(cursor, timer, object_bin['response_btns'], quit_keys=quit_keys)

			# check accuracy of subject's response
			if (supervised == True) & (trial['correct_label'] != 'gen'):
				if trial['presented_label'] == trial['correct_label']:
					if response == btn_map['no']:
						correct = False
					elif response == btn_map['yes']:
						correct = True
				elif trial['presented_label'] != trial['correct_label']:
					if response == btn_map['no']:
						correct = True
					elif response == btn_map['yes']:
						correct = False
				accuracy.append(correct)
			else:
				correct = 'gen'


			if supervised == True:
				if correct == True:
					if response == btn_map['no']:
						object_bin['feedback_msg'].setText('Correct! ' + trial['presented_label'] + ' was  *not* the correct category.')
					elif response == btn_map['yes']:
						object_bin['feedback_msg'].setText('Correct! ' + trial['presented_label'] + ' was the correct category.')
				else:
					if response == btn_map['no']:
						object_bin['feedback_msg'].setText('Incorrect... ' + trial['presented_label'] + ' was the correct category.')
					elif response == btn_map['yes']:
						object_bin['feedback_msg'].setText('Incorrect... ' + trial['presented_label'] + ' was *not* the correct category.')

				# draw feedback message
				event_utils.draw_objects_in_bin(
					window,
					object_bin,
					object_list = ['stim', 'response_btns', 'feedback_msg'],
				)
			else:
				event_utils.draw_objects_in_bin(
					window,
					object_bin,
					object_list = ['stim', 'response_btns'],
				)


			if debug_mode == False: core.wait(1)

			# draw continue message
			if supervised == True:
				event_utils.draw_objects_in_bin(
					window,
					object_bin, 
					object_list = ['stim', 'response_btns', 'feedback_msg', 'click_anywhere_msg'],
				)

			else:
				event_utils.draw_objects_in_bin(
					window,
					object_bin, 
					object_list = ['stim', 'response_btns', 'click_anywhere_msg'],
				)

			if debug_mode == False: core.wait(.35)

			event_utils.wait_for_click_response(cursor, timer, quit_keys=quit_keys)

			event_utils.draw_objects_in_bin(
				window,
				object_bin,
				object_list = ['response_btns'],
			)

			if save_data == True:
				subject_data = [
					subject_info['id'],
					phase_id,
					subject_info['condition'],
					block,
					trial_num,
					trial['stimulus'],
					trial['correct_label'],
					trial['presented_label'],
					response,
					correct,
					rt,
				]
				with open(subject_info['datafile_path'], 'a') as file:
					csv_object = csv.writer(file)
					csv_object.writerow(subject_data)



			# if early_finish_accuracy_criterion != None:
			# 	if trial_num > minimum_trials:
			# 		if sum(accuracy[-early_finish_lookback:]) / len(accuracy[-early_finish_lookback:]) >= early_finish_accuracy_criterion:
			# 			return

			trial_num = trial_num + 1