def spinDownTest(self): # OK, we have collected the number of requested getEvents, that have returned >0 events # so _close psychopy window self.psychoWindow.close() # disable high priority in both processes Computer.disableHighPriority()
def disableHighPriority(self): Computer.disableHighPriority()
def runBlockSet(self, blockSet): # using getDevice() returns None if the device is not found, tracker = self.hub.getDevice("tracker") daq = self.hub.getDevice("daq") # using self.devices.xxxxx raises an exception if the # device is not present kb = self.devices.kb display = self.devices.display # for each block in the group of blocks..... for trialSet in blockSet.getNextConditionSet(): # if an eye tracker is connected, if tracker: self.instructionScreen.setTimeout(30 * 60.0) # 30 minute timeout, long enough for a break if needed. dtrigger = DeviceEventTrigger(kb, EventConstants.KEYBOARD_PRESS, {"key": ["RETURN", "ESCAPE"]}) self.instructionScreen.setEventTriggers(dtrigger) self.instructionScreen.setText( "Press 'Enter' to go to eye tracker Calibration mode.\n\nTo skip calibration and start Data Recording press 'Escape'" ) flip_time, time_since_flip, event = self.instructionScreen.switchTo(msg="CALIBRATION_SELECT") if event and event.key == "RETURN": runEyeTrackerSetupAndCalibration(tracker, self.window) elif event and event.key == "ESCAPE": print "** Calibration stage skipped for block ", blockSet.getCurrentConditionSetIteration() else: print "** Time out occurred. Entering calibration mode to play it safe. ;)" runEyeTrackerSetupAndCalibration(tracker, self.window) dres = display.getPixelResolution() # right now, target positions are automatically generated based on point grid size, screen size, and a scaling factor (a gain). TARGET_POSITIONS = generatedPointGrid( dres[0], dres[1], self.HORZ_SCALING, self.VERT_SCALING, self.HORZ_POS_COUNT, self.VERT_POS_COUNT ) # indexes to display the condition variable order in start out 'non' randomized. RAND_INDEXES = np.arange(TARGET_POSITIONS.shape[0]) # if conditionVariablesProvider was told to randomize trials, then randomize trial index access list. if self.conditionVariablesProvider.randomizeTrials is True: self.hub.sendMessageEvent( "RAND SEED = {0}".format(ExperimentVariableProvider._randomGeneratorSeed), sec_time=ExperimentVariableProvider._randomGeneratorSeed / 1000.0, ) np.random.shuffle(RAND_INDEXES) dtrigger = DeviceEventTrigger(kb, EventConstants.KEYBOARD_PRESS, {"key": "SPACE"}) self.instructionScreen.setEventTriggers(dtrigger) self.instructionScreen.setText( "Press 'Space' key when Ready to Start Block %d" % (blockSet.getCurrentConditionSetIteration()) ) flip_time, time_since_flip, event = self.instructionScreen.switchTo(msg="BLOCK_START") # enable high priority for the experiment process only. Not sure this is necessary, or a good idea, # based on tests so far frankly. Running at std priority seems to usually be just fine. Computer.enableRealTimePriority(True) # if we have a tracker, start recording....... if tracker: tracker.setRecordingState(True) # delay a short time to let " the data start flow'in " self.hub.wait(0.050) # In this paradigm, each 'trial' is the movement from one target location to another. # Recording of eye data is on for the whole block of XxY target positions within the block. # A rough outline of the runtime / data collection portion of a block is as follows: # a) Start each block with the target at screen center. # b) Wait sec.msec duration after showing the target [ column PRE_POS_CHANGE_INTERVAL ] in excel file # c) Then schedule move of target to next target position at the time of the next retrace. # d) Once the Target has moved to the 2nd position for the trial, wait PRE_COLOR_CHANGE_INTERVAL # sec.msec before 'possibly changing the color of the center of the target. The new color is # determined by the FP_INNER_COLOR2 column. If no color change is wanted, simply make this color # equal to the color of the target center in column FP_INNER_COLOR for that row of the spreadsheet. # e) Once the target has been redrawn (either with or without a color change, it stays in position for # another POST_COLOR_CHANGE_INTERVAL sec.msec. Since ioHub is being used, all keyboard activity # is being recorded to the ioDataStore file, so there is no need really to 'monitor' for # the participants key presses, since we do not use it for feedback. It can be retrieved from the # data file for analysis post hoc. # f) After the POST_COLOR_CHANGE_INTERVAL, the current 'trial' officially ends, and the next trial # starts, with the target remaining in the position it was at in the end of the last trial, but # with the target center color switching to FP_INNER_COLOR. # g) Then the sequence from b) starts again for the number of target positions in the block # (49 currently). # self.hub.clearEvents("all") self._TRIAL_STATE = None self.targetScreen.nextAreaOfInterest = None for trial in trialSet.getNextConditionSet(): currentTrialIndex = trialSet.getCurrentConditionSetIndex() nextTargetPosition = TARGET_POSITIONS[currentTrialIndex] trial["FP_X"] = nextTargetPosition[0] trial["FP_Y"] = nextTargetPosition[1] ppd_x, ppd_y = self.devices.display.getPixelsPerDegree() fp_outer_radius = int(trial["FP_OUTER_RADIUS"] * ppd_x), int(trial["FP_OUTER_RADIUS"] * ppd_y) fp_inner_radius = int(trial["FP_INNER_RADIUS"] * ppd_x), int(trial["FP_INNER_RADIUS"] * ppd_y) self.targetScreen.setScreenColor(tuple(trial["SCREEN_COLOR"])) self.targetScreen.setTargetOuterColor(tuple(trial["FP_OUTER_COLOR"])) self.targetScreen.setTargetInnerColor(tuple(trial["FP_INNER_COLOR"])) self.targetScreen.setTargetOuterSize(fp_outer_radius) self.targetScreen.setTargetInnerSize(fp_inner_radius) self.hub.clearEvents("kb") self.targetScreen.setTimeout(trial["PRE_POS_CHANGE_INTERVAL"]) self._TRIAL_STATE = trial, "FIRST_PRE_POS_CHANGE_KEY" target_pos1_color1_time, time_since_flip, event = self.targetScreen.switchTo( msg="TRIAL_TARGET_INITIAL_COLOR" ) self.targetScreen.setTargetPosition(nextTargetPosition) self.targetScreen.setTimeout(trial["PRE_COLOR_CHANGE_INTERVAL"]) self._TRIAL_STATE = trial, "FIRST_POST_POS_CHANGE_KEY" # create a 3 degree circular region (1.5 degree radius) around the next target position # for use as out invisible boundary self.targetScreen.nextAreaOfInterest = Point(*nextTargetPosition).buffer(((ppd_x + ppd_y) / 2.0) * 1.5) target_pos2_color1_time, time_since_flip, event = self.targetScreen.switchTo(msg="TRIAL_TARGET_MOVE") self.targetScreen.setTargetInnerColor(tuple(trial["FP_INNER_COLOR2"])) self.targetScreen.setTimeout(trial["POST_COLOR_CHANGE_INTERVAL"]) self._TRIAL_STATE = trial, "FIRST_POST_COLOR_CHANGE_KEY" target_pos2_color2_time, time_since_flip, event = self.targetScreen.switchTo( msg="TRIAL_TARGET_COLOR_TWO" ) # end of 'trial sequence' # send condition variables used / populated to ioDataStore toSend = [self.hub.experimentSessionID, trialSet.getCurrentConditionSetIteration()] trial["TSTART_TIME"] = target_pos1_color1_time trial["APPROX_TEND_TIME"] = target_pos2_color2_time + time_since_flip trial["target_pos1_color1_time"] = target_pos1_color1_time trial["target_pos2_color1_time"] = target_pos2_color1_time trial["target_pos2_color2_time"] = target_pos2_color2_time if self.targetScreen.aoiTriggeredID: trial["VOG_SAMPLE_ID_AOI_TRIGGER"] = self.targetScreen.aoiTriggeredID trial["VOG_SAMPLE_TIME_AOI_TRIGGER"] = self.targetScreen.aoiTriggeredTime if self.targetScreen.aoiBestGaze: trial["BEST_GAZE_X"] = self.targetScreen.aoiBestGaze[0] trial["BEST_GAZE_Y"] = self.targetScreen.aoiBestGaze[1] self._TRIAL_STATE = None if self.targetScreen.nextAreaOfInterest: del self.targetScreen.nextAreaOfInterest self.targetScreen.nextAreaOfInterest = None toSend.extend(trial.tolist()) self.hub.addRowToConditionVariableTable(toSend) # end of block of trials, clear screen self.clearScreen.flip(text="BLOCK_END") self._TRIAL_STATE = None # if tracking eye position, turn off eye tracking. if tracker: tracker.setRecordingState(False) if daq: daq.enableEventReporting(False) # turn off high priority so python GC can clean up if it needs to. Computer.disableHighPriority() # give a 100 msec delay before starting next block self.hub.wait(0.100) # end of block set, return from method. self.clearScreen.flip(text="BLOCK_SET_END") return True
print "You played around with the mouse cursor for {0} seconds.".format( k.time-first_flip_time) print '' # wait 250 msec before ending the experiment # (makes it feel less abrupt after you press the key) actualDelay=io.wait(0.250) print "Delay requested %.6f, actual delay %.6f, Diff: %.6f"%( 0.250,actualDelay,actualDelay-0.250) print '' # for fun, test getting a bunch of events at once, # likely causing a mutlipacket getEvents() since we have not cleared the # event buffer or retrieved events from anything but the keyboard since # the start. stime = Computer.currentSec() events=io.getEvents() etime=Computer.currentSec() print 'event count: ', len(events),' delay (msec): ',(etime-stime)*1000.0 # close neccessary files / objects, 'disable high priority. Computer.disableHighPriority() psychoWindow.close() # be sure to shutdown your ioHub server! io.quit() core.quit() ### End of experiment logic