#Homework 4
#Ethan Witkowski
import numpy as np
import random as rnd
from statistics import mean
from psychopy import visual, core, event
#Randomizes sequence of conditions across blocks of an experiement
#No consecutive repeats of conditions
def exp_randomization(nblocks,nconds):
block_list = []
#Initialize condition
init_condition = np.random.choice(range(1,nconds+1), size=(1,nconds), replace=False, p=None)
block_list.append(init_condition)
for block in range(nblocks-1):
while True:
#Random condition sequence for current block
condition_list = np.random.choice(range(1,nconds+1), size=(1,nconds), replace=False, p=None)
prior_block = block_list[-1]
#If consective conditions, choose new random condition
if condition_list[0][0] == prior_block[-1][-1]:
continue
#Append random condition to list of blocks
else:
block_list.append(condition_list)
break
print(block_list)
nblocks = input("Please input the number of blocks: ")
nconds = input("Please input the number of conditions: ")
nblocks = int(nblocks)
nconds = int(nconds)
exp_conditions = exp_randomization(nblocks,nconds)
#Read-in file
f = open('midterm_catfr_data.txt', 'r')
full_data = f.readlines()
f.close()
#Remove spacing elements, transfer to list
for i, observation in enumerate(full_data):
full_data[i] = observation.strip().split(',')
print(full_data[i])
#list to hold variable values
data = []
for i in range(len(full_data[0])):
data.append([]) #Create new list for each variable
for sub_list in full_data:
data[i].append(sub_list[i]) #Append ith element in sub_list to correct variable
#Declare variable names
subjects, experiment, sess, list_number, serial_position, word_pres, category, recall = data
#List of unique categories
unique_category = list(set(category))
#List of unique subjects
unique_subjects = list(set(subjects))
#Trial level data np arrays
np_categories = np.array(category)
np_subjects = np.array(subjects)
np_recall = np.array(recall)
#Unique categories/subjects
np_u_categories = np.unique(np_categories)
np_u_subjects = np.unique(np_subjects)
#Pre-allocate 2d array to store means of each subjects/category
np_subjects_mean_recall_by_cat = np.empty([186,26])
#Obtain each subject's performance recall for each category
for i,u_subjects in enumerate(np_u_subjects):
for j,u_categories in enumerate(np_u_categories):
#Inner np.logical_and: 70,000 long, True if subj/cat match loops
subj_and_cat_match = np.logical_and(np_subjects==u_subjects,np_categories==u_categories)
#indexing np_recall with True, gives us 0/1s for each subject for each category
recall_index = np_recall[subj_and_cat_match]
#Convert to float
recall_index = recall_index.astype(np.float)
#Given recall values, taking the mean gives us their performance recall
#Place in numpy array corresponding to subject/category
if len(recall_index) > 0:
np_subjects_mean_recall_by_cat[i,j] = np.mean(recall_index)
else:
continue
#Transpose for arrays to represent categories, elements in arrays the mean recall for each subject
np_t_subjects_mean_recall_by_cat = np.transpose(np_subjects_mean_recall_by_cat)
np.shape(np_t_subjects_mean_recall_by_cat)
#Pre-allocate matrix of correlation coefficients for each subject for each category
corr_cat_matrix = np.empty([26,26])
corr_cat_matrix[:] = np.nan
#Place category recall correlation coefficients in matrix
for m,cat in enumerate(np_t_subjects_mean_recall_by_cat):
for n,cat_2 in enumerate(np_t_subjects_mean_recall_by_cat):
corr_cat_matrix[m][n] = np.corrcoef(cat,cat_2)[1,0]
print(len(corr_cat_matrix))
print(len(corr_cat_matrix[0]))
print(corr_cat_matrix)
#Find maximum correlation coefficient, pair of categories
corr_max = 0
for i,corr_array in enumerate(corr_cat_matrix):
for j,corr_value in enumerate(corr_array):
if (corr_value > corr_max) & (corr_value < 0.99999):
corr_max = corr_value
max_i_index = (i)
max_j_index = (j)
else:
continue
print("The maximum correlation coefficient is " + str(corr_max))
print("The pair of categories with the highest correlation in recall performance is: ")
print(str(np_u_categories[max_i_index]) + " and " + str(np_u_categories[max_j_index]))
#Find minimum correlation coefficient, pair of categories
corr_min = 2
for i,corr_array in enumerate(corr_cat_matrix):
for j,corr_value in enumerate(corr_array):
if (abs(corr_value) < abs(corr_min)):
corr_min = corr_value
min_i_index = (i)
min_j_index = (j)
else:
continue
print("The minimum correlation coefficient is " + str(corr_min))
print("The pair of categories with the lowest correlation in recall performance is: ")
print(str(np_u_categories[min_i_index]) + " and " + str(np_u_categories[min_j_index]))
#Read-in word list
f = open('wordpool.txt')
words = f.read().splitlines()
f.close()
#Set number of targets
ntargets = input("Please input the number of targets: ")
ntargets = int(ntargets)
#Set number of lures
nlures = input("Please input the number of lures: ")
nlures = int(nlures)
#Randomly select targets and lures
#Randomly shuffle words, choose targets, delete chosen targets
rnd.shuffle(words)
targets = words[:ntargets]
del words[:ntargets]
print(targets)
#Randomly shuffle remaining words, choose lures
rnd.shuffle(words)
lures = words[:nlures]
del words[:nlures]
print(lures)
#Reset list of words
f = open('wordpool.txt')
words = f.read().splitlines()
f.close()
#List of randomly selected targets/lures presented during test phase
#Concatenate lists of targets and lures
test_words = targets + lures
print(test_words)
#Randomly shuffle words
rnd.shuffle(test_words)
print(test_words)
#Pre-allocate numpy array for responses
responses = np.empty([1,len(test_words)], dtype = "object")
#Pre-allocate list of results
results = np.empty([1,len(test_words)], dtype = "object")
#Experiment
#Encoding phase
#Create window
win = visual.Window([400,400])
#Show target words to participant with 1-second delay
for target in targets:
stim = visual.TextStim(win,text=target.rstrip('\n'))
stim.draw()
win.flip()
core.wait(1)
#Intermediate phase
#Present window asking participant to input 'i' to move to test phase
stim = visual.TextStim(win,text='In the test phase, pressing "j" indicates a word shown in the encoding phase. Pressing "k" indicates a word not shown in the encoding phase. Please press "i" to show your understanding.')
stim.draw()
win.flip()
pressedkey = event.waitKeys(keyList = ["i"])
if pressedkey[0] == 'i':
win.flip()
core.wait(1)
#Test Phase
for i,test_word in enumerate(test_words):
stim = visual.TextStim(win,text=test_word.rstrip('\n'))
stim.draw()
win.flip()
pressedkey = event.waitKeys(keyList = ["j", "k"])
pressedkey = "".join(pressedkey)
responses[0][i] = pressedkey
if (responses[0][i] == "j") & (test_words[i] in targets):
results[0][i] = str("hit")
elif (responses[0][i] == "j") & (test_words[i] in lures):
results[0][i] = str("false alarm")
elif (responses[0][i] == "k") & (test_words[i] in targets):
results[0][i] = str("miss")
elif (responses[0][i] == "k") & (test_words[i] in lures):
results[0][i] = str("correct rejection")
win.close()
print(responses)
print(results)
hit_counter = 0
for result in results[0]:
if result == "hit":
hit_counter += 1
hit_rate = hit_counter/ntargets
print("The hit rate is " + str(hit_rate))
false_alarm_counter = 0
for result_2 in results[0]:
if result_2 == "false alarm":
false_alarm_counter += 1
false_alarm_rate = false_alarm_counter/nlures
print("The false alarm rate is " + str(false_alarm_rate))