def max_ball(restriction): # TODO:this should be saved in each restriction for less calculation # but I don't want to do this '''get max ball in each part''' def get_formulas(array): x, y, z, r = array ball = { 'center': Point_3D({ 'x': x, 'y': y, 'z': z, }), 'radius': r } return list(map(lambda re: re.is_tangent_to(ball), restriction)) if len(restriction) > 4: # for comparing the_max_ball = Ball({'x': 100, 'y': 100, 'z': 100}, 0) all_four_combinations = combination_traversal(restriction, 4) for combination in all_four_combinations: ball = max_ball(combination) all_valid = True for single_restriction in restriction: valid = single_restriction.is_valid(ball) if not valid: if LOG_LEVEL > 0: print(single_restriction.dictify(), valid, ball.dictify()) all_valid = False break if ball.radius >= the_max_ball.radius and all_valid: the_max_ball = ball return the_max_ball # if we have the previous ball, use its center as root point. # if not, use the default point. prev_ball = restriction[0] start_point_3D = [100, 100, 100, 100] if hasattr(prev_ball, 'center'): start_point_3D = [ prev_ball.center.x, prev_ball.center.y, prev_ball.center.z, prev_ball.radius ] x, y, z, r = fsolve(get_formulas, start_point_3D) return Ball({'x': x, 'y': y, 'z': z}, r)
def createBalls(win, nBalls, radius, boundRect, speed): """ Create the balls to be put in the area """ halfX = (boundRect[0] + boundRect[2]) / 2.0 halfY = (boundRect[1] + boundRect[3]) / 2.0 # The four rectangles that build the main rectangle rectanglesList = [] rectanglesList.append([boundRect[0], boundRect[1], halfX, halfY]) rectanglesList.append([halfX, boundRect[1], boundRect[2], halfY]) rectanglesList.append([boundRect[0], halfY, halfX, boundRect[3]]) rectanglesList.append([halfX, halfY, boundRect[2], boundRect[3]]) # Generate the balls in the balls = [] from random import shuffle from numpy.random import uniform from common import Geometry for i in range(0, nBalls): startPos = np.array( [uniform( rectanglesList[ i % 4][0] + radius, rectanglesList[i % 4][2] - radius), uniform(rectanglesList[i % 4][1] + radius, rectanglesList[i % 4][3] - radius)]) direction = Geometry.normalized( np.array([uniform(-1, 1), uniform(-1, 1)])) ball = Ball(win, position=startPos, direction=direction, speed=speed, radius=radius, color='Black') balls.append(ball) shuffle(balls) return balls, rectanglesList
#!/usr/bin/python3.7 from common import Ball, Ghost, Man, Woman, make_humans, Person # Ball class b0 = Ball() print(b0) b1 = Ball('super') print(b1) # Ghost class gh = Ghost() print(gh) # Humans humans = make_humans() print('human name is {} sex is {}'.format(humans[0].name, humans[0].sex)) print('human name is {} sex is {}'.format(humans[1].name, humans[1].sex)) # Person pe = Person('john', 34) print(pe.getPersonInfo()) class A: """Dummy class.""" def func1(self) -> None: """""" print('func1')
def trackingTrial(win, experimentalInfo, ballSpeed, thisCondition, simulation=False): """ Start the tracking trial 1) Generate random balls 2) Generate the central white fixation dot 3) Start blinking 2 balls in the left or right zone, for unilateral, in both zones for bilateral 4) Move the balls in random directions, bouncing on walls and on theirselves """ # Generate a list of 4 balls on left side for unilateral condition trialClock = core.Clock() rectWidth, rectHeight = experimentalInfo['RectWidth'], experimentalInfo[ 'RectHeight'] displacementX = 4 # 1 cm central displacement nBallsPerRectangle = experimentalInfo['NumBalls'] ballRadius = experimentalInfo['BallRadius'] leftRightRectangles = [[ -rectWidth - displacementX / 2.0, -rectHeight / 2.0, -displacementX / 2.0, rectHeight / 2.0 ], [ displacementX / 2.0, -rectHeight / 2.0, rectWidth + displacementX / 2.0, rectHeight / 2.0 ]] ballsLeft, rectanglesLeft = createBalls(win, nBallsPerRectangle, radius=ballRadius, boundRect=leftRightRectangles[0], speed=ballSpeed) ballsRight, rectanglesRight = createBalls(win, nBallsPerRectangle, radius=ballRadius, boundRect=leftRightRectangles[1], speed=ballSpeed) #allBallsList = { 0:ballsLowerLeft, 1:ballsLowerRight, 2:ballsUpperLeft,3:ballsUpperRight } allBallsList = {0: ballsLeft, 1: ballsRight} from numpy import array fixationBall = Ball(win, position=array([0.0, 0.0]), direction=array([0.0, 0.0]), speed=0.0, radius=0.10, color='White') trialClock.reset() blinkingBalls = list() whichSide = None if thisCondition['Side'] == 'Left': whichSide = 0 if thisCondition['Side'] == 'Right': whichSide = 1 runMode = None if thisCondition['label'].split('-')[0] == 'Unilateral': runMode = 0 if thisCondition['label'].split('-')[0] == 'Bilateral': runMode = 1 runModes = {0: 'Unilateral', 1: 'Bilateral'} if runModes[runMode] == 'Unilateral': blinkingBalls = [ allBallsList[whichSide][0], allBallsList[whichSide][1] ] if runModes[runMode] == 'Bilateral': blinkingBalls = [ allBallsList[0][0], allBallsList[0][1], allBallsList[1][0], allBallsList[1][1] ] if runModes[runMode] != 'Unilateral' and runModes[runMode] != 'Bilateral': raise Exception("Run mode must be \"Unilateral\" or \"Bilateral\"") blinkTimer = core.Clock() blinkInteger = 0 rectanglesVisual = [] for r in rectanglesLeft + rectanglesRight: rectanglesVisual.append( visual.Rect(win, width=(r[2] - r[0]), height=(r[3] - r[1]), fillColor=None, lineColor='Red', units='cm', pos=[(r[0] + r[2]) / 2.0, (r[1] + r[3]) / 2.0])) # Start first part of the experiment, 2 balls blink for a certain amount # of time controlled by experimentalInfo['BlinkTime'] while trialClock.getTime() < experimentalInfo['BlinkTime']: fixationBall.draw() # speedText.draw() if experimentalInfo['DrawRectangles']: for r in rectanglesVisual: r.draw() for ballListID, ballList in allBallsList.iteritems(): for ball1 in ballList: ball1.draw() if (blinkTimer.getTime() > 0.125): blinkInteger = blinkInteger + 1 blinkTimer.reset() if (blinkInteger % 2): for blinkBall in blinkingBalls: blinkBall.setColor('White') else: for blinkBall in blinkingBalls: blinkBall.setColor('Black') win.flip() # Reset all colors of the balls to black and move each ball in its right # part of space for ballListID, ballList in allBallsList.iteritems(): for ball1 in ballList: ball1.setColor('Black') ball1.draw() fixationBall.draw() win.flip() trialClock.reset() # This function pregenerates all the trajectories so that in displaying # them we have no slowing allFrames = preGenerateTrajectories(ballSpeed / win.fps(), experimentalInfo, allBallsList, leftRightRectangles, repulsionStrength=2000.0 * ballSpeed, edgerepulsionStrength=10.0 * ballSpeed, centerAttraction=0.0001) trialClock.reset() for balls in allFrames: for ball, pos in balls.iteritems(): ball.setPos(pos) ball.draw() # speedText.draw() if experimentalInfo['DrawRectangles']: for r in rectanglesVisual: r.draw() fixationBall.draw() win.flip() event.clearEvents(eventType='keyboard') trialClock.reset() randomBall = allBallsList[whichSide][randrange(0, nBallsPerRectangle)] randomBall.setColor('Red') event.clearEvents(eventType='keyboard') responseKey = None response = None time_exceeded = False trialClock.reset() has_answered = False answerclock = core.Clock() answerclock.reset() response = -1 # default response if the subject does not answer # Wait 'MaxAnswerTime' seconds if both the answer is given by the subject or not. while answerclock.getTime() < experimentalInfo['MaxAnswerTime']: fixationBall.draw() for ballListID, ballList in allBallsList.iteritems(): for ball1 in ballList: ball1.draw() randomBall.draw() keys = event.getKeys() if not has_answered: if '1' in keys: responseKey = True response = responseKey == (randomBall in blinkingBalls) trialClock.reset() if '2' in keys: responseKey = False response = responseKey == (randomBall in blinkingBalls) trialClock.reset() if 'escape' in keys: win.close() core.quit() if response is True: fixationBall.setColor('Green') if response is False: fixationBall.setColor('Red') fixationBall.draw() win.flip() fixationBall.draw() for ballListID, ballList in allBallsList.iteritems(): for ball1 in ballList: ball1.draw() randomBall.draw() win.flip() # PREVIOUS LOOP # while True: # keys = event.getKeys() # fixationBall.draw() # for ballListID, ballList in allBallsList.iteritems(): # for ball1 in ballList: # ball1.draw() # randomBall.draw() # if '1' in keys: #would you put in next line core.wait() until trialClock.getTime() > experimentalInfo['MaxAnswerTime'] OR wait with blank screen at line 338 until 2 seconds complete # responseKey = True # response = responseKey == (randomBall in blinkingBalls) # trialClock.reset() # if '2' in keys: # responseKey = False # response = responseKey == (randomBall in blinkingBalls) # trialClock.reset() # if trialClock.getTime() > experimentalInfo['MaxAnswerTime']: # response = -1 # trialClock.reset() # # Plot the green/red dot for 0.5 seconds # if response != None: # break # if 'escape' in keys: # win.close() # core.quit() # win.flip() # if response is True: # fixationBall.setColor('Green') # if response is False: # fixationBall.setColor('Red') # trialClock.reset() # while trialClock.getTime() < 0.4: # keys = event.getKeys() # fixationBall.draw() # for ballListID, ballList in allBallsList.iteritems(): # for ball1 in ballList: # ball1.draw() # randomBall.draw() # win.flip() return response
def trackingTrial(win, experimentalInfo, ballSpeed, thisCondition, simulation=False, isCatchTrial=0): if simulation: return perfectObserver(obs_mean=3, obs_std=0.1, intensity=ballSpeed) from psychopy import visual, event """ Start the tracking trial 1) Generate random balls 2) Generate the central white fixation dot 3) Start blinking 2 balls in the left or right zone, for unilateral, in both zones for bilateral 4) Move the balls in random directions, bouncing on walls and on theirselves """ # Generate a list of 4 balls on left side for unilateral condition trialClock = core.Clock() rectWidth, rectHeight = experimentalInfo[ 'RectWidth'], experimentalInfo['RectHeight'] displacementX = 4 # 1 cm central displacement nBallsPerRectangle = experimentalInfo['NumBalls'] ballRadius = experimentalInfo['BallRadius'] leftRightRectangles = [ [-rectWidth - displacementX / 2.0, -rectHeight / 2.0, -displacementX / 2.0, rectHeight / 2.0], [displacementX / 2.0, -rectHeight / 2.0, rectWidth + displacementX / 2.0, rectHeight / 2.0]] ballsLeft, rectanglesLeft = createBalls( win, nBallsPerRectangle, radius=ballRadius, boundRect=leftRightRectangles[0], speed=ballSpeed) ballsRight, rectanglesRight = createBalls( win, nBallsPerRectangle, radius=ballRadius, boundRect=leftRightRectangles[1], speed=ballSpeed) #allBallsList = { 0:ballsLowerLeft, 1:ballsLowerRight, 2:ballsUpperLeft,3:ballsUpperRight } allBallsList = {0: ballsLeft, 1: ballsRight} fixationBall = Ball(win, position=np.array([0.0, 0.0]), direction=np.array( [0.0, 0.0]), speed=0.0, radius=0.10, color='White') trialClock.reset() blinkingBalls = list() whichSide = None if thisCondition['Side'] == 'Left': whichSide = 0 if thisCondition['Side'] == 'Right': whichSide = 1 runMode = None if thisCondition['label'].split('-')[0] == 'Unilateral': runMode = 0 if thisCondition['label'].split('-')[0] == 'Bilateral': runMode = 1 runModes = {0: 'Unilateral', 1: 'Bilateral'} if runModes[runMode] == 'Unilateral': blinkingBalls = [ allBallsList[whichSide][0], allBallsList[whichSide][1] ] if runModes[runMode] == 'Bilateral': blinkingBalls = [allBallsList[0][0], allBallsList[0][1], allBallsList[1][0], allBallsList[1][1] ] if runModes[runMode] != 'Unilateral' and runModes[runMode] != 'Bilateral': raise Exception("Run mode must be \"Unilateral\" or \"Bilateral\"") blinkTimer = core.Clock() blinkInteger = 0 rectanglesVisual = [] for r in rectanglesLeft + rectanglesRight: rectanglesVisual.append(visual.Rect(win, width=( r[2] - r[0]), height=(r[3] - r[1]), fillColor=None, lineColor='Red', units='cm',pos=[(r[0] + r[2]) / 2.0, (r[1] + r[3]) / 2.0])) # Start first part of the experiment, 2 balls blink for a certain amount # of time controlled by experimentalInfo['BlinkTime'] if isCatchTrial==1: catchText = visual.TextStim(win, "Catch 25% trial speed=" + str(ballSpeed), color='Red', pos=[0,0]) elif isCatchTrial==2: catchText = visual.TextStim(win, "Catch 50% trial speed=" + str(ballSpeed), color='Blue', pos=[0,0]) while trialClock.getTime() < experimentalInfo['BlinkTime']: fixationBall.draw() if isCatchTrial: catchText.draw() # speedText.draw() if experimentalInfo['DrawRectangles']: for r in rectanglesVisual: r.draw() for ballListID, ballList in allBallsList.iteritems(): for ball1 in ballList: ball1.draw() if (blinkTimer.getTime() > 0.125): blinkInteger = blinkInteger + 1 blinkTimer.reset() if (blinkInteger % 2): for blinkBall in blinkingBalls: blinkBall.setColor('White') else: for blinkBall in blinkingBalls: blinkBall.setColor('Black') if (experimentalInfo['SaveVideo']): win.getMovieFrame() win.flip() # Reset all colors of the balls to black and move each ball in its right # part of space for ballListID, ballList in allBallsList.iteritems(): for ball1 in ballList: ball1.setColor('Black') ball1.draw() fixationBall.draw() if (experimentalInfo['SaveVideo']): win.getMovieFrame() win.flip() trialClock.reset() # This function pregenerates all the trajectories so that in displaying # them we have no slowing allFrames = preGenerateTrajectories( ballSpeed / win.fps(), experimentalInfo, allBallsList, leftRightRectangles, repulsionStrength=2000.0 * ballSpeed, edgerepulsionStrength=10.0 * ballSpeed, centerAttraction=0.0001) trialClock.reset() for balls in allFrames: for ball, pos in balls.iteritems(): ball.setPos(pos) ball.draw() # speedText.draw() if experimentalInfo['DrawRectangles']: for r in rectanglesVisual: r.draw() fixationBall.draw() if (experimentalInfo['SaveVideo']): win.getMovieFrame() win.flip() event.clearEvents(eventType='keyboard') trialClock.reset() randomBall = allBallsList[whichSide][randrange(0, nBallsPerRectangle)] randomBall.setColor('Red') event.clearEvents(eventType='keyboard') trialClock.reset() responseKey = None response = None while True: keys = event.getKeys() fixationBall.draw() for ballListID, ballList in allBallsList.iteritems(): for ball1 in ballList: ball1.draw() randomBall.draw() if 's' in keys: responseKey = True response = responseKey == (randomBall in blinkingBalls) trialClock.reset() if 'd' in keys: responseKey = False response = responseKey == (randomBall in blinkingBalls) trialClock.reset() # Plot the green/red dot for 0.5 seconds if response is not None: break if 'escape' in keys: win.close() core.quit() if (experimentalInfo['SaveVideo']): win.getMovieFrame() win.flip() if response is True: fixationBall.setColor('Green') if response is False: fixationBall.setColor('Red') trialClock.reset() while trialClock.getTime() < 0.4: keys = event.getKeys() fixationBall.draw() for ballListID, ballList in allBallsList.iteritems(): for ball1 in ballList: ball1.draw() randomBall.draw() if (experimentalInfo['SaveVideo']): win.getMovieFrame() win.flip() if (experimentalInfo['SaveVideo']): import os currentpath = os.getcwd() savedatapath = currentpath + os.path.sep + 'data' outputVideo = savedatapath + os.path.sep + \ "frames" + os.path.sep + 'Tracking.png' print "Saving video to " + outputVideo win.saveMovieFrames(outputVideo) return response
def contrastTrial(win, experimentalInfo, contrastValue, side, useSameStimuli): from psychopy import visual, event """ Start the contrast trial """ saveVideo = experimentalInfo['SaveVideo'] edge = experimentalInfo['SquareEdge'] # First two stimuli are on the left, second two stimuli are on the right positions = [ np.array([-edge / 2, -edge / 2]), np.array([-edge / 2, edge / 2]), np.array([edge / 2, -edge / 2]), np.array([edge / 2, edge / 2]) ] fixationBall = Ball(win, position=np.array([0.0, 0.0]), direction=np.array([0.0, 0.0]), speed=0.0, radius=0.15, color='White') sameStimuliIndex = randrange(0, 4) noiseMaskStimuli = [] for i in range(0, 4): noiseMaskStimuli.append( visual.GratingStim( win, pos=positions[i], tex=np.random.random_integers(0, 1, size=[1024, 1024]) * 2 - 1, mask='circle', size=[ experimentalInfo['BallRadius'] * 2, experimentalInfo['BallRadius'] * 2 ])) # Generate the ball that has different contrast noiseMaskStimuli[sameStimuliIndex] = visual.GratingStim( win, pos=positions[sameStimuliIndex], tex=np.random.random_integers(0, 1, size=[1024, 1024]) * 2 - 1, mask='circle', size=[ experimentalInfo['BallRadius'] * 2, experimentalInfo['BallRadius'] * 2 ]) noiseMaskStimuli[sameStimuliIndex].contrast = contrastValue if useSameStimuli: for i in range(0, 4): noiseMaskStimuli[i].contrast = contrastValue arrows = [ visual.TextStim(win, "<--", pos=[0, 0]), visual.TextStim(win, "-->", pos=[0, 0]) ] # Draw the arrow cue trialClock = core.Clock() trialClock.reset() sideIndex = (side == 'Left') while (trialClock.getTime() < 2.0): arrows[sideIndex].draw() if (saveVideo): win.getMovieFrame() win.flip() # Mostra lo stimolo di contrasti per due secondi totalMaskTime = experimentalInfo.get('ContrastDuration', 2.0) totalMaskTimeInFrames = int(round(totalMaskTime * win.measuredFPS)) for t in range(0, totalMaskTimeInFrames): for i in range(0, 4): noiseMaskStimuli[i].draw() if (saveVideo): win.getMovieFrame() win.flip() # Get the subject response event.getKeys() trialClock = core.Clock() trialClock.reset() response = None while True: keys = event.getKeys() fixationBall.draw() if 's' in keys: response = (sideIndex == (sameStimuliIndex < 2)) if useSameStimuli: response = True trialClock.reset() break if 'd' in keys: response = (sideIndex == (sameStimuliIndex >= 2)) if useSameStimuli: response = False trialClock.reset() break if 'escape' in keys: win.close() core.quit() if (saveVideo): win.getMovieFrame() win.flip() if (saveVideo): import os currentpath = os.getcwd() savedatapath = currentpath + os.path.sep + 'data' outputVideo = savedatapath + os.path.sep + \ "frames" + os.path.sep + 'contrast.png' print "Saving video to " + outputVideo win.saveMovieFrames(outputVideo) return response
def flickerTrial(win, experimentalInfo, flickerFreq, side, useOddBall): from psychopy import visual, event """ Start the tracking trial """ # Generate the 4 balls as list balls = [] edge = experimentalInfo['SquareEdge'] # First two balls are left, second two balls are right positions = [ np.array([-edge / 2, -edge / 2]), np.array([-edge / 2, edge / 2]), np.array([edge / 2, -edge / 2]), np.array([edge / 2, edge / 2]) ] for i in range(0, 4): balls.append( Ball(win, position=positions[i], direction=np.array([0, 0]), speed=0, radius=experimentalInfo['BallRadius'], color='Black')) fixationBall = Ball(win, position=np.array([0.0, 0.0]), direction=np.array([0.0, 0.0]), speed=0.0, radius=0.15, color='White') oddBallIndex = randrange(0, 4) oddBalls = [balls[oddBallIndex]] noiseMaskStimuli = [] for i in range(0, 4): noiseMaskStimuli.append( visual.GratingStim(win, pos=positions[i], units='cm', tex=np.random.rand(256, 256) * 2.0 - 1.0, mask='circle', size=[ experimentalInfo['BallRadius'] * 2, experimentalInfo['BallRadius'] * 2 ])) arrows = [ visual.TextStim(win, "-->", pos=[0, 0]), visual.TextStim(win, "<--", pos=[0, 0]) ] # Initialize a color for the balls for ball in balls: ball.setColor('Black') if useOddBall: for oddBall in oddBalls: oddBall.setColor('White') # Draw the arrow cue trialClock = core.Clock() trialClock.reset() sideIndex = (side == 'Left') while (trialClock.getTime() < 2.0): arrows[sideIndex].draw() if (experimentalInfo['SaveVideo']): win.getMovieFrame() win.flip() totalMaskTime = 0.350 # seconds totalMaskTimeInFrames = int(round(totalMaskTime * win.measuredFPS)) for t in range(0, totalMaskTimeInFrames): for i in range(0, 4): noiseMaskStimuli[i].draw() if (experimentalInfo['SaveVideo']): win.getMovieFrame() win.flip() # Here instead of using timers we precompute the number of frames to display for the stimuli, so # that the calls to timers are avoided and the program is faster between # two flips totStimFrames = int(round(experimentalInfo['BlinkTime'] * win.measuredFPS)) totBlinkFrames = int(round(1.0 / flickerFreq * win.measuredFPS)) blinkFrame, totBlinks = 0, 0 times = [None] * totStimFrames switchIndices = [] for t in range(0, totStimFrames): fixationBall.draw() blinkFrame = blinkFrame + 1 oldTotBlinks = totBlinks if (blinkFrame >= totBlinkFrames): blinkFrame = 0 totBlinks = totBlinks + 1 if (oldTotBlinks < totBlinks): switchIndices.append(t) if (totBlinks % 2): for ball in balls: ball.setColor('White') if useOddBall: for oddBall in oddBalls: oddBall.setColor('Black') else: for ball in balls: ball.setColor('Black') if useOddBall: for oddBall in oddBalls: oddBall.setColor('White') for ball in balls: ball.draw() if (experimentalInfo['SaveVideo']): win.getMovieFrame() times[t] = win.flip() totalMaskTimeInFrames = int(round(totalMaskTime * win.measuredFPS)) for t in range(0, totalMaskTimeInFrames): for i in range(0, 4): noiseMaskStimuli[i].draw() if (experimentalInfo['SaveVideo']): win.getMovieFrame() win.flip() times = np.array(times) # switchIndices=np.array(switchIndices) # switchTimes=np.diff(times[switchIndices]) # print "Average switch times",np.average(switchTimes),"corresponding to ",1.0/np.average(switchTimes)," [Hz]" # print "Average inversion times # error=",np.average(switchTimes-1.0/flickerFreq)*1000,"[ms]" # Get the subject response event.getKeys() trialClock = core.Clock() trialClock.reset() response = None while True: keys = event.getKeys() fixationBall.draw() if 's' in keys: response = (sideIndex == (oddBallIndex >= 2)) trialClock.reset() break if 'd' in keys: response = (sideIndex == (oddBallIndex < 2)) trialClock.reset() break if 'escape' in keys: win.close() core.quit() if (experimentalInfo['SaveVideo']): win.getMovieFrame() win.flip() print sideIndex, side, oddBallIndex, response if (experimentalInfo['SaveVideo']): import os currentpath = os.getcwd() savedatapath = currentpath + os.path.sep + 'data' outputVideo = savedatapath + os.path.sep + \ "frames" + os.path.sep + 'Flicker.png' print "Saving video to " + outputVideo win.saveMovieFrames(outputVideo) return response