Robust Averaging Face Stimuli

Mixed Valence 200 Trial Stimuli Generation

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

"""

Created on Mon Jun 10 11:07:36 2024

 

@author: xdong23

"""

 

import numpy as np

from scipy import stats

import math

import random

import csv

 

#generate 100 random mean values

def generate_100_mean(mean = 25, variance = 5):

    values = []

    while len(values) < 100:

        value = np.random.normal(mean, variance)

        value = np.clip(value, 1, 50) #must be within range (1, 50)

        values.append(value)

    return values

 

#generate two random mean value lists

def generate_mean(mean = 25, variance = 5):

    values1 = []

    values2 = []

    values1 = generate_100_mean()

    values2 = generate_100_mean()

    tValue, pValue = stats.ttest_ind(values1, values2)

    if pValue < 0.05:

        return generate_mean()

    else:

        return values1, values2

 

#use the generate_mean() function

meanList, meanList2 = generate_mean()

 

#generate a list of 8 values from a Gaussian distribution

def generate_stimuli(mean, variance, depth = 0):

    values = []

    while len(values) < 8:

        value = np.random.normal(mean, variance)

        value = np.clip(value, 1, 50)

        value = int(round(value))

        if value not in values: #no repeats

            values.append(value)

    actMean = sum(values) / 8

    actVar = math.sqrt(sum([(x - actMean) ** 2 for x in values]) / 8)

    diffMean = abs(actMean - mean)

    diffVar= abs(actVar - variance)

    tolMean = mean * 0.05

    tolVar = variance * 0.05

    if diffMean <= tolMean and diffVar <= tolVar:

        depthCheck = 'checked'

        return values, depthCheck

    elif depth >= 300:

        depthCheck = 'ALERT'

        return values, depthCheck

    else:

        return generate_stimuli(mean, variance, depth + 1)

    return values, depthCheck

 

#input previously generated means into the generate_stimuli() function

X1 = [] #create emotion value lists X1 to X8

X2 = []

X3 = []

X4 = []

X5 = []

X6 = []

X7 = []

X8 = []

emotionList = []

conditionList = []

depthCheckList = []

 

for i in range(100): #small variance conditoin

    emotion_new = []

    emotion_new, depth_new = generate_stimuli(meanList[i], 5) #generate emotion list

    X1.append(emotion_new[0]) #assign each emotion value to X1 to X8

    X2.append(emotion_new[1])

    X3.append(emotion_new[2])

    X4.append(emotion_new[3])

    X5.append(emotion_new[4])

    X6.append(emotion_new[5])

    X7.append(emotion_new[6])

    X8.append(emotion_new[7])

    emotionList.append(emotion_new)

    conditionList.append('small')

    depthCheckList.append(depth_new)

 

for i in range(100): #large variance condition

    emotion_new = []

    emotion_new, depth_new = generate_stimuli(meanList2[i], 15)

    X1.append(emotion_new[0])

    X2.append(emotion_new[1])

    X3.append(emotion_new[2])

    X4.append(emotion_new[3])

    X5.append(emotion_new[4])

    X6.append(emotion_new[5])

    X7.append(emotion_new[6])

    X8.append(emotion_new[7])

    emotionList.append(emotion_new)

    conditionList.append('large')

    depthCheckList.append(depth_new)

 

meanList.extend(meanList2) #combine mean lists

 

#create identity list

identity = []

for i in range(200):

    identity_new = [] #empty list to temporarily store each eight-identity list

    male_numbers = ["M" + str(num) for num in random.sample(range(1, 9), 4)]

    female_numbers = ["F" + str(num) for num in random.sample(range(1, 9), 4)]

    identity_new.extend(male_numbers + female_numbers)

    random.shuffle(identity_new)

    identity.append(identity_new)

 

#randomize the stimuli rows

rows = list(zip(meanList, emotionList, conditionList, X1, X2, X3, X4,

                X5, X6, X7, X8, depthCheckList, identity)) #make sure same row stays together

random.shuffle(rows)

meanList, emotionList, conditionList, X1, X2, X3, X4, X5, X6, X7, X8, depthCheckList, identity = zip(*rows)

meanList = list(meanList) #turn tuples to lists

emotionList = list(emotionList)

conditionList = list(conditionList)

X1 = list(X1)

X2 = list(X2)

X3 = list(X3)

X4 = list(X4)

X5 = list(X5)

X6 = list(X6)

X7 = list(X7)

X8 = list(X8)

depthCheckList = list(depthCheckList)

identity = list(identity)

 

#write csv file

with open('new_stimuli_randomized.csv', 'w', newline='') as csvfile:

    writer = csv.writer(csvfile)

    writer.writerow(['mean', 'emotion', 'variance', 'X1', 'X2', 'X3',

                     'X4', 'X5', 'X6', 'X7', 'X8', 'depth', 'identity']) #create column names

    for i in range(200):

        writer.writerow([meanList[i], emotionList[i], conditionList[i],

                        X1[i], X2[i], X3[i], X4[i],

                        X5[i], X6[i], X7[i], X8[i], depthCheckList[i],

                        identity[i]])

Robust Averaging Stimuli Generation

import csv

import random

 

#create 150 identity lists

identity = [] #create empty list

for i in range(150): #repeat 150 times

    identity_new = [] #create new empty list

    male_numbers = ["M" + str(num) for num in random.sample(range(1, 9), 4)] #select 4 M faces

    female_numbers = ["F" + str(num) for num in random.sample(range(1, 9), 4)] #select 4 F faces

    identity_new.extend(male_numbers + female_numbers) #add selected faces to the new list

    random.shuffle(identity_new) #randomly shuffle the new list

    identity.append(identity_new) #append the randomly shuffled list to the identity list

 

#create mean emotion values

mean = [22]*50 + [25]*50 + [28]*50

 

#cretea emotion variance values

variance = ["small"]*25 + ["large"]*25 #25 repeats of each variance value ("small", "large")

variance = variance * 3 #repeat 3 times (one for each mean value)

 

#function to create full emotion values

def generate_emotion(mean, variance):

    emotions = { #create a dictionary where mean and variance correspond with respective emotion values

        (22, "small"): [13, 19, 25, 31]*2,

        (22, "large"): [4, 16, 28, 40]*2,

        (25, "small"): [16, 22, 28, 34]*2,

        (25, "large"): [7, 19, 31, 43]*2,

        (28, "small"): [19, 25, 31, 37]*2,

        (28, "large"): [10, 22, 34, 46]*2

    }

    emotion_list = emotions[(mean, variance)] #create list with emotion values

    random.shuffle(emotion_list)  #randomly shuffle the list

    return emotion_list

 

#create emotion based on mean and variance values for 150 trials

X1 = [] #create emotion value lists X1 to X8

X2 = []

X3 = []

X4 = []

X5 = []

X6 = []

X7 = []

X8 = []

for i in range(150): #repeat 150 times

    emotion_new = []

    emotion_new = generate_emotion(mean[i], variance[i]) #generate emotion list

    X1.append(emotion_new[0]) #assign each emotion value to X1 to X8

    X2.append(emotion_new[1])

    X3.append(emotion_new[2])

    X4.append(emotion_new[3])

    X5.append(emotion_new[4])

    X6.append(emotion_new[5])

    X7.append(emotion_new[6])

    X8.append(emotion_new[7])

 

#write csv file

with open('demo_stimuli.csv', 'w', newline='') as csvfile:

    writer = csv.writer(csvfile)

    writer.writerow(['identity', 'mean', 'variance', 'X1', 'X2', 'X3', 'X4',

                     'X5', 'X6', 'X7', 'X8']) #create column names

    for i in range(150): #create 150 stimuli

        writer.writerow([identity[i], mean[i], variance[i], X1[i], X2[i], X3[i], X4[i],

                         X5[i], X6[i], X7[i], X8[i]])

Robust Averaging Stimuli Generation (X1:X8 not separated)

import csv

import random

 

#create 150 identity lists

identity = [] #create empty list

for _ in range(150): #repeat 150 times

    identity_new = [] #create new empty list

    male_numbers = ["M" + str(num) for num in random.sample(range(1, 9), 4)] #select 4 M faces

    female_numbers = ["F" + str(num) for num in random.sample(range(1, 9), 4)] #select 4 F faces

    identity_new.extend(male_numbers + female_numbers) #add selected faces to the new list

    random.shuffle(identity_new) #randomly shuffle the new list

    identity.append(identity_new) #append the randomly shuffled list to the identity list

 

#create mean emotion values

mean = [22]*50 + [25]*50 + [28]*50

 

#cretea emotion variance values

variance = ["small"]*25 + ["large"]*25 #25 repeats of each variance value ("small", "large")

variance = variance * 3 #repeat 3 times (one for each mean value)

 

#function to create full emotion values

def generate_emotion(mean, variance):

    emotions = { #create a dictionary where mean and variance correspond with respective emotion values

        (22, "small"): [13, 19, 25, 31]*2,

        (22, "large"): [4, 16, 28, 40]*2,

        (25, "small"): [16, 22, 28, 34]*2,

        (25, "large"): [7, 19, 31, 43]*2,

        (28, "small"): [19, 25, 31, 37]*2,

        (28, "large"): [10, 22, 34, 46]*2

    }

    emotion_list = emotions[(mean, variance)] #create list with emotion values

    random.shuffle(emotion_list)  #randomly shuffle the list

    return emotion_list

 

#create emotion based on mean and variance values for 150 trials

emotion = [generate_emotion(mean[i], variance[i]) for i in range(150)]

 

#write csv file

with open('demo_stimuli.csv', 'w', newline='') as csvfile:

    writer = csv.writer(csvfile)

    writer.writerow(['identity', 'mean', 'variance', 'emotion']) #create column names

    for i in range(150): #create 150 stimuli

        writer.writerow([identity[i], mean[i], variance[i], emotion[i]])

Robust Averaging Stimuli Sample 5.1.24