#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division
from psychopy import locale_setup, sound, gui, visual, core, data, event, logging, clock
from psychopy.constants import (NOT_STARTED, STARTED, PLAYING, PAUSED,
STOPPED, FINISHED, PRESSED, RELEASED, FOREVER)
import numpy as np # whole numpy lib is available, prepend 'np.'
from numpy import (sin, cos, tan, log, log10, pi, average,
sqrt, std, deg2rad, rad2deg, linspace, asarray)
from numpy.random import random, randint, normal, shuffle
import os # handy system and path functions
import sys # to get file system encoding
# Ensure that relative paths start from the same directory as this script
_thisDir = os.path.dirname(os.path.abspath(__file__)).decode(sys.getfilesystemencoding())
os.chdir(_thisDir)
# Store info about the experiment session
expName = 'blockedVideoTrialsWithBreaksWorking_videoLoop_PreFinal' # from the Builder filename that created this script
expInfo = {'participant': ''}
dlg = gui.DlgFromDict(dictionary=expInfo, title=expName)
if dlg.OK == False:
core.quit() # user pressed cancel
expInfo['date'] = data.getDateStr() # add a simple timestamp
expInfo['expName'] = expName
# Data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc
filename = _thisDir + os.sep + u'data/%s_%s_%s' % (expInfo['participant'], expName, expInfo['date'])
# An ExperimentHandler isn't essential but helps with data saving
thisExp = data.ExperimentHandler(name=expName, version='',
extraInfo=expInfo, runtimeInfo=None,
originPath=None,
savePickle=True, saveWideText=True,
dataFileName=filename)
# save a log file for detail verbose info
logFile = logging.LogFile(filename+'.log', level=logging.EXP)
logging.console.setLevel(logging.WARNING) # this outputs to the screen, not a file
endExpNow = False # flag for 'escape' or other condition => quit the exp
# Start Code - component code to be run before the window creation
# Setup the Window
win = visual.Window(
size=[1920, 1080], fullscr=False, screen=0,
allowGUI=True, allowStencil=False,
monitor='testMonitor', color=[0,0,0], colorSpace='rgb',
blendMode='avg', useFBO=True,
units='norm')
# store frame rate of monitor if we can measure it
expInfo['frameRate'] = win.getActualFrameRate()
if expInfo['frameRate'] != None:
frameDur = 1.0 / round(expInfo['frameRate'])
else:
frameDur = 1.0 / 60.0 # could not measure, so guess
# Initialize components for Routine "beginInstruct"
beginInstructClock = core.Clock()
overviewInstructions = visual.TextStim(win=win, name='overviewInstructions',
text='INSTRUCTIONS PLACEMENT\n\nClick Next to contine.\n',
font='Arial',
pos=(0, 0), height=0.1, wrapWidth=None, ori=0,
color='white', colorSpace='rgb', opacity=1,
depth=0.0);
mousenext = event.Mouse(win=win)
x, y = [None, None]
nextInstrucButton = visual.Rect(
win=win, name='nextInstrucButton',
width=(0.25, 0.15)[0], height=(0.25, 0.15)[1],
ori=0, pos=(0, -.5),
lineWidth=1, lineColor=[1,1,1], lineColorSpace='rgb',
fillColor=[-1,-1,-1], fillColorSpace='rgb',
opacity=.5, depth=-2.0, interpolate=True)
text = visual.TextStim(win=win, name='text',
text='Next >>',
font='Arial',
units='norm', pos=(0, -.5), height=0.1, wrapWidth=None, ori=0,
color='white', colorSpace='rgb', opacity=1,
depth=-3.0);
# Initialize components for Routine "pause"
pauseClock = core.Clock()
text_2 = visual.TextStim(win=win, name='text_2',
text='Loading ...',
font='Arial',
pos=(0, 0), height=0.1, wrapWidth=None, ori=0,
color='white', colorSpace='rgb', opacity=1,
depth=0.0);
# Initialize components for Routine "registersNext"
registersNextClock = core.Clock()
mouseYN_2 = event.Mouse(win=win)
x, y = [None, None]
yesButton_2 = visual.Rect(
win=win, name='yesButton_2',
width=(0.1, 0.1)[0], height=(0.1, 0.1)[1],
ori=0, pos=(-0.15, -0.78),
lineWidth=1, lineColor=[1,1,1], lineColorSpace='rgb',
fillColor=[-.9,-.9,-.9], fillColorSpace='rgb',
opacity=0.3, depth=-3.0, interpolate=True)
noButton_2 = visual.Rect(
win=win, name='noButton_2',
width=(0.1, 0.1)[0], height=(0.1, 0.1)[1],
ori=0, pos=(0, -0.78),
lineWidth=1, lineColor=[1,1,1], lineColorSpace='rgb',
fillColor=[-.9,-.9,-.9], fillColorSpace='rgb',
opacity=.3, depth=-4.0, interpolate=True)
nextImageButton_2 = visual.Rect(
win=win, name='nextImageButton_2',
width=(0.5, 0.1)[0], height=(0.5, 0.1)[1],
ori=0, pos=(0.5, -0.8),
lineWidth=1, lineColor=[.2,.2,.2], lineColorSpace='rgb',
fillColor=[.1,.1,.1], fillColorSpace='rgb',
opacity=.4, depth=-5.0, interpolate=True)
yesText_2 = visual.TextStim(win=win, name='yesText_2',
text='Yes',
font='Arial',
pos=(-0.15, -0.78), height=0.05, wrapWidth=None, ori=0,
color='white', colorSpace='rgb', opacity=1,
depth=-6.0);
noText_2 = visual.TextStim(win=win, name='noText_2',
text='No',
font='Arial',
pos=(0, -0.78), height=0.05, wrapWidth=None, ori=0,
color='white', colorSpace='rgb', opacity=1,
depth=-7.0);
nextIma_2 = visual.TextStim(win=win, name='nextIma_2',
text='Next Image >>',
font='Arial',
pos=(0.5, -0.8), height=0.05, wrapWidth=None, ori=0,
color='white', colorSpace='rgb', opacity=1,
depth=-8.0);
# Initialize components for Routine "interBreak"
interBreakClock = core.Clock()
breakMouse = event.Mouse(win=win)
x, y = [None, None]
breakInBetween = visual.TextStim(win=win, name='breakInBetween',
text='Please use this time to take a brief break.\nFeel free to use the bathroom or rest your eyes for a minute.\n\nWhen you are ready to go to the next block of trials, click next.',
font='Arial',
pos=(0, 0), height=0.1, wrapWidth=None, ori=0,
color='white', colorSpace='rgb', opacity=1,
depth=-2.0);
finishBreak = visual.Rect(
win=win, name='finishBreak',
width=(0.2, 0.1)[0], height=(0.2, 0.1)[1],
ori=0, pos=(0, -.7),
lineWidth=1, lineColor=[-1,-1,-1], lineColorSpace='rgb',
fillColor=[-1,-1,-1], fillColorSpace='rgb',
opacity=.5, depth=-3.0, interpolate=True)
nextPastBreak = visual.TextStim(win=win, name='nextPastBreak',
text='Next >>',
font='Arial',
pos=(0, -.7), height=0.1, wrapWidth=None, ori=0,
color='white', colorSpace='rgb', opacity=1,
depth=-4.0);
numblocks = visual.TextStim(win=win, name='numblocks',
text='default text',
font='Arial',
pos=(0, -.8), height=0.1, wrapWidth=None, ori=0,
color='white', colorSpace='rgb', opacity=1,
depth=-5.0);
# Initialize components for Routine "thanks"
thanksClock = core.Clock()
text_3 = visual.TextStim(win=win, name='text_3',
text='Thanks!\n\nYou are finished.\n\nClick anywhere to close out the program.\n\nNote to self:\n-Two of the images are at different wxh based on pixels \n-set width and height to be a square at norm of 1 to 1\n-displayed image with w and h same as saved format\n',
font='Arial',
pos=(0, 0), height=0.1, wrapWidth=None, ori=0,
color='white', colorSpace='rgb', opacity=1,
depth=0.0);
mouse = event.Mouse(win=win)
x, y = [None, None]
# Create some handy timers
globalClock = core.Clock() # to track the time since experiment started
routineTimer = core.CountdownTimer() # to track time remaining of each (non-slip) routine
# ------Prepare to start Routine "beginInstruct"-------
t = 0
beginInstructClock.reset() # clock
frameN = -1
continueRoutine = True
# update component parameters for each repeat
# setup some python lists for storing info about the mousenext
mousenext.clicked_name = []
gotValidClick = False # until a click is received
# keep track of which components have finished
beginInstructComponents = [overviewInstructions, mousenext, nextInstrucButton, text]
for thisComponent in beginInstructComponents:
if hasattr(thisComponent, 'status'):
thisComponent.status = NOT_STARTED
# -------Start Routine "beginInstruct"-------
while continueRoutine:
# get current time
t = beginInstructClock.getTime()
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
# *overviewInstructions* updates
if t >= 0.0 and overviewInstructions.status == NOT_STARTED:
# keep track of start time/frame for later
overviewInstructions.tStart = t
overviewInstructions.frameNStart = frameN # exact frame index
overviewInstructions.setAutoDraw(True)
# *mousenext* updates
if t >= 0.0 and mousenext.status == NOT_STARTED:
# keep track of start time/frame for later
mousenext.tStart = t
mousenext.frameNStart = frameN # exact frame index
mousenext.status = STARTED
prevButtonState = mousenext.getPressed() # if button is down already this ISN'T a new click
if mousenext.status == STARTED: # only update if started and not stopped!
buttons = mousenext.getPressed()
if buttons != prevButtonState: # button state changed?
prevButtonState = buttons
if sum(buttons) > 0: # state changed to a new click
# check if the mouse was inside our 'clickable' objects
for obj in [nextInstrucButton]:
if obj.contains(mousenext):
gotValidClick = True
mousenext.clicked_name.append(obj.name)
if gotValidClick: # abort routine on response
continueRoutine = False
# *nextInstrucButton* updates
if t >= 0.0 and nextInstrucButton.status == NOT_STARTED:
# keep track of start time/frame for later
nextInstrucButton.tStart = t
nextInstrucButton.frameNStart = frameN # exact frame index
nextInstrucButton.setAutoDraw(True)
# *text* updates
if t >= 0.0 and text.status == NOT_STARTED:
# keep track of start time/frame for later
text.tStart = t
text.frameNStart = frameN # exact frame index
text.setAutoDraw(True)
# check if all components have finished
if not continueRoutine: # a component has requested a forced-end of Routine
break
continueRoutine = False # will revert to True if at least one component still running
for thisComponent in beginInstructComponents:
if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
continueRoutine = True
break # at least one component has not yet finished
# check for quit (the Esc key)
if endExpNow or event.getKeys(keyList=["escape"]):
core.quit()
# refresh the screen
if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
win.flip()
# -------Ending Routine "beginInstruct"-------
for thisComponent in beginInstructComponents:
if hasattr(thisComponent, "setAutoDraw"):
thisComponent.setAutoDraw(False)
# store data for thisExp (ExperimentHandler)
thisExp.nextEntry()
# the Routine "beginInstruct" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()
# set up handler to look after randomisation of conditions etc
blocks = data.TrialHandler(nReps=1, method='random',
extraInfo=expInfo, originPath=-1,
trialList=data.importConditions('blockOrder.xlsx'),
seed=None, name='blocks')
thisExp.addLoop(blocks) # add the loop to the experiment
thisBlock = blocks.trialList[0] # so we can initialise stimuli with some values
# abbreviate parameter names if possible (e.g. rgb = thisBlock.rgb)
if thisBlock != None:
for paramName in thisBlock:
exec('{} = thisBlock[paramName]'.format(paramName))
for thisBlock in blocks:
currentLoop = blocks
# abbreviate parameter names if possible (e.g. rgb = thisBlock.rgb)
if thisBlock != None:
for paramName in thisBlock:
exec('{} = thisBlock[paramName]'.format(paramName))
# set up handler to look after randomisation of conditions etc
trials = data.TrialHandler(nReps=1, method='random',
extraInfo=expInfo, originPath=-1,
trialList=data.importConditions(orderBlocks),
seed=None, name='trials')
thisExp.addLoop(trials) # add the loop to the experiment
thisTrial = trials.trialList[0] # so we can initialise stimuli with some values
# abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
if thisTrial != None:
for paramName in thisTrial:
exec('{} = thisTrial[paramName]'.format(paramName))
for thisTrial in trials:
currentLoop = trials
# abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
if thisTrial != None:
for paramName in thisTrial:
exec('{} = thisTrial[paramName]'.format(paramName))
# ------Prepare to start Routine "pause"-------
t = 0
pauseClock.reset() # clock
frameN = -1
continueRoutine = True
routineTimer.add(1.200000)
# update component parameters for each repeat
#gives a 0.2 second pause before the next trial appears
#there is a noticeable different in user test taking satisfaction
#pierce (creator of psychopy) mentions that users feel that the exp is
#running too fast if the stimuli appears exactly one right after another
# keep track of which components have finished
pauseComponents = [text_2]
for thisComponent in pauseComponents:
if hasattr(thisComponent, 'status'):
thisComponent.status = NOT_STARTED
# -------Start Routine "pause"-------
while continueRoutine and routineTimer.getTime() > 0:
# get current time
t = pauseClock.getTime()
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
# *text_2* updates
if t >= 0.2 and text_2.status == NOT_STARTED:
# keep track of start time/frame for later
text_2.tStart = t
text_2.frameNStart = frameN # exact frame index
text_2.setAutoDraw(True)
frameRemains = 0.2 + 1- win.monitorFramePeriod * 0.75 # most of one frame period left
if text_2.status == STARTED and t >= frameRemains:
text_2.setAutoDraw(False)
# check if all components have finished
if not continueRoutine: # a component has requested a forced-end of Routine
break
continueRoutine = False # will revert to True if at least one component still running
for thisComponent in pauseComponents:
if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
continueRoutine = True
break # at least one component has not yet finished
# check for quit (the Esc key)
if endExpNow or event.getKeys(keyList=["escape"]):
core.quit()
# refresh the screen
if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
win.flip()
# -------Ending Routine "pause"-------
for thisComponent in pauseComponents:
if hasattr(thisComponent, "setAutoDraw"):
thisComponent.setAutoDraw(False)
# ------Prepare to start Routine "registersNext"-------
t = 0
registersNextClock.reset() # clock
frameN = -1
continueRoutine = True
# update component parameters for each repeat
#WOOOOOOOOOOOOOWEEEEEEEEEEEEEEEEEE
# setup some python lists for storing info about the mouseYN_2
mouseYN_2.clicked_name = []
mouseYN_2.clicked_pos = []
mouseYN_2.clicked_time = []
gotValidClick = False # until a click is received
movie_2 = visual.MovieStim3(
win=win, name='movie_2',
noAudio = True,
filename=videoClips,
ori=0, pos=(0, 0), opacity=1,
depth=-2.0,
)
# keep track of which components have finished
registersNextComponents = [mouseYN_2, movie_2, yesButton_2, noButton_2, nextImageButton_2, yesText_2, noText_2, nextIma_2]
for thisComponent in registersNextComponents:
if hasattr(thisComponent, 'status'):
thisComponent.status = NOT_STARTED
# -------Start Routine "registersNext"-------
while continueRoutine:
# get current time
t = registersNextClock.getTime()
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
#checks each frame to see if the mouse overs over butt obj
#provide user feedback when they hover mouse over y/n button
#color of button looks darker (changed opacity since couldn't get setColor to come out correctly
if yesButton_2.contains(mouseYN_2):
#YesButton.color = ([-1,-1,-1], colorSpace='rgb')
yesButton_2.opacity=(.5)
else:
#YesButton.color = ([1,1,1], colorSpace='rgb')
yesButton_2.opacity= (.3)
if noButton_2.contains(mouseYN_2):
#NoButton.color = ([-1,-1,-1], colorSpace='rgb')
noButton_2.opacity=(.5)
else:
#NoButton.color= ([1,1,1], colorSpace='rgb')
noButton_2.opacity= (.3)
#gives user visible feedback when Yes or No buttons are pressed
# these lines does not mean that these lines save the answer
#gives buttons a bounce effect
if mouseYN_2.isPressedIn(yesButton_2, buttons=[0]): #left-click only on yesbutt
yesButton_2.opacity=(.9)
# yesButton_2.setColor=((-1,-1,-1),'rgb255')
noButton_2.opacity=(.3)
elif mouseYN_2.isPressedIn(noButton_2, buttons=[0]):
# noButton_2.color=((-1,-1,-1),'rgb255')
yesButton_2.opacity=(.3)
noButton_2.opacity=(.9)
else:
pass #do nothing. also read that can leave this out
#if people end up changing their answer, then allow prog to save the answer before moving on
#saves the button name, time clicked, and position to a list
if mouseYN_2.isPressedIn(yesButton_2, buttons=[0]):
stimX,stimY = mouseYN_2.getPos() #in case you want to later save the x and y coordinates in end routine
mouseYN_2.clicked_name.append(yesButton_2.name)
mouseYN_2.clicked_pos.append(yesButton_2.pos)
mouseYN_2.clicked_time.append(registersNextClock.getTime())
elif mouseYN_2.isPressedIn(noButton_2, buttons=[0]):
stimX,stimY = mouseYN_2.getPos()#in case you want to later save the x and y coordinates in end routine
mouseYN_2.clicked_name.append(noButton_2.name)
mouseYN_2.clicked_pos.append(noButton_2.pos)
mouseYN_2.clicked_time.append(registersNextClock.getTime())
#check to make sure Y/N clicked before moving on
if mouseYN_2.isPressedIn(nextImageButton_2, buttons=[0]):
if yesButton_2.name in mouseYN_2.clicked_name: #if name of object in mouse object list
# movieClipLooping.finished=True #looping ends (can actually take out movieClipLooping but kept it there in case need to loop stuff in future
continueRoutine = False #stops current routine and starts new one or the next trial
elif noButton_2.name in mouseYN_2.clicked_name:
# movieClipLooping.finished=True (added in case in future, need to loop this routine)
continueRoutine = False
else:
# print("Please click yes or no before clicking Next Image") #need to format this
continueRoutine = True
else:
movie_2.loop=True #if don't click on Next, keep looping the movie
# *movie_2* updates
if t >= 0.0 and movie_2.status == NOT_STARTED:
# keep track of start time/frame for later
movie_2.tStart = t
movie_2.frameNStart = frameN # exact frame index
movie_2.setAutoDraw(True)
# *yesButton_2* updates
if t >= 0 and yesButton_2.status == NOT_STARTED:
# keep track of start time/frame for later
yesButton_2.tStart = t
yesButton_2.frameNStart = frameN # exact frame index
yesButton_2.setAutoDraw(True)
# *noButton_2* updates
if t >= 0.0 and noButton_2.status == NOT_STARTED:
# keep track of start time/frame for later
noButton_2.tStart = t
noButton_2.frameNStart = frameN # exact frame index
noButton_2.setAutoDraw(True)
# *nextImageButton_2* updates
if t >= 0.0 and nextImageButton_2.status == NOT_STARTED:
# keep track of start time/frame for later
nextImageButton_2.tStart = t
nextImageButton_2.frameNStart = frameN # exact frame index
nextImageButton_2.setAutoDraw(True)
# *yesText_2* updates
if t >= 0.0 and yesText_2.status == NOT_STARTED:
# keep track of start time/frame for later
yesText_2.tStart = t
yesText_2.frameNStart = frameN # exact frame index
yesText_2.setAutoDraw(True)
# *noText_2* updates
if t >= 0.0 and noText_2.status == NOT_STARTED:
# keep track of start time/frame for later
noText_2.tStart = t
noText_2.frameNStart = frameN # exact frame index
noText_2.setAutoDraw(True)
# *nextIma_2* updates
if t >= 0.0 and nextIma_2.status == NOT_STARTED:
# keep track of start time/frame for later
nextIma_2.tStart = t
nextIma_2.frameNStart = frameN # exact frame index
nextIma_2.setAutoDraw(True)
# check if all components have finished
if not continueRoutine: # a component has requested a forced-end of Routine
break
continueRoutine = False # will revert to True if at least one component still running
for thisComponent in registersNextComponents:
if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
continueRoutine = True
break # at least one component has not yet finished
# check for quit (the Esc key)
if endExpNow or event.getKeys(keyList=["escape"]):
core.quit()
# refresh the screen
if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
win.flip()
# -------Ending Routine "registersNext"-------
for thisComponent in registersNextComponents:
if hasattr(thisComponent, "setAutoDraw"):
thisComponent.setAutoDraw(False)
if len(mouseYN_2.clicked_name): #if there is a something in length of list (versus nothing in list)
trials.addData('Answer',mouseYN_2.clicked_name[-1]) #saves last answer in list of clicked Y and N
trials.addData('Button position', mouseYN_2.clicked_pos[-1]) #saves the last ans's x, y mouse position @ valid obj's center coordinates
trials.addData('Reaction Time', mouseYN_2.clicked_time[-1]) #reaction time of last clicked answer
# store data for trials (TrialHandler)
# the Routine "registersNext" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()
thisExp.nextEntry()
# completed 1 repeats of 'trials'
# ------Prepare to start Routine "interBreak"-------
t = 0
interBreakClock.reset() # clock
frameN = -1
continueRoutine = True
# update component parameters for each repeat
if blocks.thisN == 1: #if at 2nd block (final block)
continueRoutine = False #don't continue the routine, showing recommendation for break
#tried to say if blocks.thisN == -1: but this doesn't stop running in last block listed in array