class TestPhotos(DirectObject): def __init__(self): DirectObject.__init__(self) # start Panda3d self.base = ShowBase() # get configurations from config file config_file = 'config.py' self.config = {} execfile(config_file, self.config) self.accept("cleanup", self.cleanup) self.accept("escape", self.close) self.photos = Photos(self.base, self.config) self.photos.load_all_photos() self.start_loop() def start_loop(self): self.photos.flag_timer = True self.photos.show_photo() def cleanup(self): print 'cleanup' if self.photos.cal_pts_per_photo: self.start_loop() else: print 'done?' def close(self): print 'time to close' self.photos.cal_pts_per_photo = None self.photos.imageObject.destroy() self.base.taskMgr.remove('timer_task') sys.exit()
def savePhotosShown(self): for item in self.allPhotosInfo: summary = {} summary['ownerId'] = item['owner'] summary['albumId'] = self.albumID summary['photoId'] = str(item['id']) photos = Photos(self.spider, self.userID, self.albumName, summary, self.path, True) photos.work()
def getAllPhotosInfo(self): '''photoList里面并没有存储该相册全部的照片信息,只暂时显示了部分照片,当进度条拖到下面的时候才会动态加\ 载剩余图片,而任意一张照片中都有该相册中所有照片的信息,因此需要先从任意一张照片中获得该相册中所有\ 照片的信息''' for item in self.photoList: photos = Photos(self.spider, self.userID, self.albumName, item, self.path, False) self.allPhotosInfo = photos.getAllPhotosInfoInAlbum() break #通过一张照片的信息就可以在element页面下的html代码中得到该相册所有照片
def __init__(self): DirectObject.__init__(self) # start Panda3d self.base = ShowBase() # get configurations from config file config_file = 'config.py' self.config = {} execfile(config_file, self.config) self.accept("cleanup", self.cleanup) self.accept("escape", self.close) self.photos = Photos(self.base, self.config) self.photos.load_all_photos() self.start_loop()
def setup_game(self): # this only happens once, at beginning # set up keys self.setup_keys() self.logging = Logging(self.config) self.sequences = CalSequences(self.config, self.base, self.logging, self.key_dict) if self.config.setdefault('PHOTO_PATH', False): self.photos = Photos(self.config, self.base, self.logging, self.deg_per_pixel) self.photos.load_all_photos() self.call_subroutine.append(self.photos) # print 'call_subroutine', self.call_subroutine # start generating/receiving data self.eye_data = EyeData(self.base, self.config['FAKE_DATA']) self.start_eye_data() # start reward capabilities, if using daq if self.use_daq_reward: # print 'setup reward' self.start_reward_task() if not self.testing: self.start_gig()
def savePhotos(self): for item in self.photoList: photos = Photos(self.userID, self.spider, self.albumName, item, self.path) photos.work() break
def onModuleLoad(self): self.photos = Photos() RootPanel().add(self.photos)
def savePhotos(self): for item in self.photoList: photos = Photos(self.userID,self.spider,self.albumName,item,self.path) photos.work() break
def savePhotos(self): for item in self.photoList: photos = Photos(self.spider, self.userID, self.albumName, item, self.path, False) photos.work() break #通过一张照片的信息就可以在element页面下的html代码中得到该相册所有照片,所以不用遍历每一个照片信息了
class World(DirectObject): def __init__(self, mode=None, config_file=None): DirectObject.__init__(self) # Python assumes all input from sys are string, but not # input variables # mode sets whether starts at manual or auto, default is manual, auto is 0 # Start in auto, if, and only if the input number was a zero, if mode == '0' or mode == 0: self.manual = False else: self.manual = True # print('manual', self.manual) if not config_file: config_file = 'config.py' self.pydaq = pydaq # get configurations from config file self.config = {} execfile(config_file, self.config) print 'Subject is', self.config['SUBJECT'] self.config.setdefault('file_name', config_file) print 'Calibration file is', config_file # if subject is test, doing unit tests if self.config['SUBJECT'] == 'test': # doing tests so use fake eye data and testing configuration. # for testing, always leave gain at one, so eye_data and eye_data_to_plot are the same gain = [1, 1] # print 'test' self.testing = True self.use_daq_reward = False else: gain = self.config['GAIN'] self.testing = False self.use_daq_reward = self.config.setdefault('REWARD', True) # default is not fake data, and don't send signal data_type = 'IScan' if self.config.setdefault('FAKE_DATA', False) or not self.pydaq: print('using fake data') data_type = 'Fake Data' self.config.setdefault('SEND_DATA', False) # assume 0.2 seconds for pump delay, if not set self.config.setdefault('PUMP_DELAY', 0.2) # start Panda3d self.base = ShowBase() # default is no subroutines, will fill in later, if using self.sub_index = None self.call_subroutine = [] # This will be the photo object, if we are showing photos self.photos = None # initialize text before setting up second window. # text will be overridden there. # text only happens on second window self.text_nodes = [None] * 5 self.text_dict = dict(Gain=0, Offset=1, Tolerance=3, Manual=4) self.text_dict[data_type] = 2 eye_position = '[0, 0]' data_type = '' # always start with Manual and eye in the center # stuff that changes with plotting offset = [0, 0] # tolerance in degrees, will need to be changed to pixels to be useful, # but since tolerance can change (in degrees), makes sense to do this on the fly self.plot_variables = [ gain, offset, eye_position, self.config['TOLERANCE'], data_type ] # print base.pipe.getDisplayWidth() # print base.pipe.getDisplayHeight() # if window is offscreen (for testing), does not have WindowProperties, # so can't open second window. # if an actual resolution in config file, change to that resolution, # otherwise keep going... if self.config['WIN_RES'] != 'Test': # only set up windows if not testing self.setup_windows() eye_res = self.config['EYE_RES'] position = [ (0 - eye_res[0] / 4, 0, eye_res[1] / 2 - eye_res[1] / 16), (0, 0, eye_res[1] / 2 - eye_res[1] / 16), (0 + eye_res[0] / 4, 0, eye_res[1] / 2 - eye_res[1] / 16), (0, 0, eye_res[1] / 2 - eye_res[1] * 2 / 16), (-eye_res[0] / 2 + eye_res[0] * 1 / 16, 0, eye_res[1] / 2 - eye_res[1] * 1 / 16) ] for k, v in self.text_dict.items(): self.text_nodes[v] = (self.setup_text(k, self.plot_variables[v], position[v])) self.text_dict['Auto'] = 4 else: # resolution in file equal to test, so use the projector screen # value for determining pixels size. In this case, accuracy is not # important, because never actually calibrating with this setup. resolution = [1280, 800] self.deg_per_pixel = visual_angle(self.config['SCREEN'], resolution, self.config['VIEW_DIST'])[0] # print('gain', self.gain) # print 'window loaded' # empty list for plotting eye nodes self.eye_nodes = [] self.current_eye_data = None # initialize file variables self.eye_file_name = '' self.time_file_name = '' self.eye_data_file = None self.time_data_file = None # starts out not fixated, and not checking for fixation (will # check for fixation when stimulus comes on, if we are doing an auto task) self.fixated = False self.base.setBackgroundColor(115 / 255, 115 / 255, 115 / 255) self.base.disableMouse() # create dummy variable for helper objects self.logging = None self.eye_data = None self.sequences = None # initialize list for eye window self.eye_window = [] # set up daq for reward, if on windows and not testing # testing auto mode depends on being able to control eye position self.reward_task = None self.num_beeps = self.config[ 'NUM_BEEPS'] # number of rewards each time self.num_reward = 0 # count number of rewards # Keyboard stuff: # initiate self.key_dict = {"switch": 0, "task_flag": False} def start_gig(self): # used when beginning in either auto or manual mode, # either at start or after switching # print 'start new gig' if not self.testing: # text4 and text5 change if self.manual: text_label = 'Manual' else: text_label = 'Auto' self.update_text('Tolerance', self.plot_variables[self.text_dict['Tolerance']]) self.update_text(text_label) # open files, start data stream, prepare tasks self.logging.open_files( self.manual, self.plot_variables[self.text_dict['Tolerance']]) self.logging.log_config('Gain', self.plot_variables[self.text_dict['Gain']]) self.logging.log_config('Offset', self.plot_variables[self.text_dict['Offset']]) self.eye_data.start_logging(self.logging) self.sequences.prepare_task(self.manual) def end_gig(self): # used when end in either auto or manual mode, # either at start or after switching # print 'end gig' # clear screen # self.clear_eyes() # close stuff self.eye_data.stop_logging() self.logging.close_files() def change_tasks(self): # change from manual to auto-calibrate or vise-versa # print 'change task' self.manual = not self.manual # print('switched manual?', self.manual) # reset stuff self.key_dict['task_flag'] = False self.end_gig() self.start_gig() # if going from manual to auto, start automatically, otherwise # wait for keypress to start. if not self.manual: self.start_main_loop() def start_main_loop(self, good_trial=None): # check to see if manual, no subroutines for manual if self.manual: self.sequences.setup_manual_sequence() self.sequences.manual_sequence.start() else: # check to see if we are doing a subroutine # print 'new loop, not manual' do_subroutine = False if self.call_subroutine: # print 'check subroutines' for index, tasks in enumerate(self.call_subroutine): do_subroutine = tasks.check_trial(good_trial, self.start_plot_eye_task) if do_subroutine: # print 'show photo' self.sub_index = index break else: self.sub_index = None # print 'after call_subroutine, do_subroutine now', do_subroutine if not do_subroutine: # print 'show square' self.sequences.setup_auto_sequences(good_trial) self.sequences.auto_sequence_one.start() def cleanup_main_loop(self): # print 'cleanup main loop' # print('time', time()) # end of loop, check to see if we are switching tasks, start again good_trial = self.num_reward > 0 self.num_reward = 0 self.fixated = False # if we change tasks, wait for keypress to start again if self.key_dict['task_flag']: # print 'change tasks' self.change_tasks() else: # unit tests we step through, rather than # run main loop if not self.testing: # print 'start next loop' self.start_main_loop(good_trial) # print('done cleanup_main_loop') def give_reward(self): # if got reward, square can move # print 'reward, 3' # print(self.base.taskMgr) # give reward for each num_beeps # give one reward right away, have # to wait delay before giving next reward if self.reward_task: # print 'first reward' self.num_reward = 1 self.reward_task.pumpOut() # if using actual reward have to wait to give next reward self.base.taskMgr.doMethodLater(self.config['PUMP_DELAY'], self.reward_after_pause, 'reward') else: for i in range(self.num_beeps): # print 'beep' self.num_reward += 1 # print 'give reward returns' # print('time', time()) def reward_after_pause(self, task): # print 'give another reward' self.reward_task.pumpOut() self.num_reward += 1 if self.num_reward < self.num_beeps: return task.again # print 'reward done' return task.done def clear_fix_window(self): # remove threshold window around square for win in self.eye_window: win.detachNode() def clear_screen(self): # print 'clear screen' # We can now stop plotting eye positions, # and get rid of old eye positions. self.stop_plot_eye_task() self.clear_fix_window() if self.eye_nodes: # print self.eye_nodes # can do this in a loop, since does not # delete object from list for eye in self.eye_nodes: if not eye.isEmpty(): eye.removeNode() self.current_eye_data = None # print 'should be no nodes now', self.eye_nodes self.eye_nodes = [] # Eye plotting def start_plot_eye_task(self, check_eye=False, timer=False): # print 'start plot eye task' # print 'check_eye', check_eye # print 'timer', timer target = None if check_eye: target, on_interval = self.check_fixation_target() if timer: self.start_fixation_timer(target, on_interval) self.stop_plot_eye_task() self.base.taskMgr.add(self.process_eye_data, 'plot_eye', extraArgs=[check_eye, target], appendTask=True) def stop_plot_eye_task(self): self.base.taskMgr.remove('plot_eye') def check_fixation_target(self): if self.sub_index is not None: # would be great if this were more generic, but works for now target, on_interval = self.call_subroutine[ self.sub_index].get_fixation_target() # print target, on_interval else: # else is going to be regular auto calibrate target, on_interval = self.sequences.get_fixation_target() return target, on_interval # Eye Methods def start_fixation_timer(self, target, on_interval): # print 'show fixation window, start timer' # print on_interval # print target self.show_window(target) # start timing for on task, this runs for target on time and waits for fixation, # if no fixation, method runs to abort trial # print time() if self.sub_index is not None: no_fix_task = self.call_subroutine[self.sub_index].no_fixation else: no_fix_task = self.sequences.no_fixation self.base.taskMgr.doMethodLater(on_interval, no_fix_task, 'wait_for_fix') # print('should still not be fixated', self.fixated) def process_eye_data(self, check_eye=None, target=None, task=None): # get data from producer eye_data = self.eye_data.consume_queue() if not eye_data: return task.cont # print 'plot eye data', eye_data # convert to pixels for plotting and testing distance, # need the eye position from the last run for the starting # position for move to position for plotting, and the # current eye position for ending position if not self.current_eye_data: # print 'use first data point in this chunk' # if no previous eye, just use first data point start_eye = self.eye_data_to_pixel(eye_data[0]) else: # print 'use previous data' start_eye = self.current_eye_data[-1] # print 'eye data in calibration', start_eye # print start_eye # save data self.current_eye_data = [ self.eye_data_to_pixel(data_point) for data_point in eye_data ] self.plot_eye_trace(start_eye) # and set text to last data point if not self.testing: node = self.text_dict[self.eye_data.data_type] # print self.text_dict # print self.eye_data.data_type # print node self.text_nodes[node].setText(self.eye_data.data_type + ' [' + str(round(eye_data[-1][0], 3)) + ', ' + str(round(eye_data[-1][1], 3)) + ']') # print 'check_eye', check_eye if check_eye: # print 'check eye', check_eye # print 'check fixation' self.evaluate_fixation(target) return task.cont def plot_eye_trace(self, first_eye): # print 'plot trace' # if plotting too many eye positions, things slow down and # python goes into lala land. Never need more than 500, and # last 300 is definitely plenty, so every time it hits 500, # get rid of first 200. if len(self.eye_nodes) > 500: # print('get rid of eye nodes', len(self.eye_nodes)) # Since this just removes the node, but doesn't delete # the object in the list, can do this in a for loop, for index in range(200): self.eye_nodes[index].removeNode() # now get rid of the empty nodes in eye_nodes # print('new length', len(self.eye_nodes)) self.eye_nodes = self.eye_nodes[200:] # print('new length', len(self.eye_nodes)) eye = LineSegs() # eye.setThickness(2.0) eye.setThickness(2.0) # print 'last', last_eye # print 'now', self.current_eye_data eye.moveTo(first_eye[0], 55, first_eye[1]) for data_point in self.current_eye_data: eye.drawTo(data_point[0], 55, data_point[1]) # print('plotted eye', eye_data_to_plot) node = self.base.render.attachNewNode(eye.create(True)) node.show(BitMask32.bit(0)) node.hide(BitMask32.bit(1)) self.eye_nodes.append(node) # print 'end plot trace' def evaluate_fixation(self, target): # print 'evaluate' previous_fixation = self.fixated # convert tolerance to pixels tolerance = self.plot_variables[ self.text_dict['Tolerance']] / self.deg_per_pixel # send in eye data converted to pixels, self.current_eye_data fixated = [] # print 'target', target if target is None: # target is none if we are using a subroutine's check_fixation # (usually means fixation area is square instead of round) for data_point in self.current_eye_data: # print 'use sub routine check_fixation' fixated.append(self.call_subroutine[ self.sub_index].check_fixation(data_point)) else: for data_point in self.current_eye_data: # print 'actual data', data_point fixated.append(check_fixation(data_point, tolerance, target)) # print 'fixation array', fixated self.fixated = all(fixated) # print('fixated?', self.fixated) # need to check if time to start fixation period or time to end # fixation period, otherwise business as usual if self.fixated and not previous_fixation: # print 'fixated, start fixation period' # end waiting period self.base.taskMgr.remove('wait_for_fix') # start fixation period if self.sub_index is not None: # print 'subroutine' self.call_subroutine[self.sub_index].start_fixation_period() else: # print 'auto_fix' self.sequences.start_fixation_period() elif not self.fixated and previous_fixation: # print 'broke fixation' if self.sub_index is not None: self.call_subroutine[self.sub_index].broke_fixation() else: self.sequences.broke_fixation() def eye_data_to_pixel(self, eye_data): # change the offset and gain as necessary, so eye data looks # right on screen. Actually, most of this is changed in IScan # before it ever makes it to this machine, but found we have to # at least change the gain by a couple of order of magnitudes return [ (eye_data[0] + self.plot_variables[self.text_dict['Offset']][0]) * self.plot_variables[self.text_dict['Gain']][0], (eye_data[1] + self.plot_variables[self.text_dict['Offset']][1]) * self.plot_variables[self.text_dict['Gain']][1] ] def start_eye_data(self, start_pos=None, variance=None): # if we are sending in variance, then coming from testing and we need to close first # (just stops task producing fake data, so we can restart in different place) if variance is not None: self.eye_data.close() self.eye_data.start_producer_thread('producer', origin=start_pos, variance=variance) self.eye_data.start_consumer_thread('consumer') def show_window(self, target_pos): # draw line around target representing how close the subject has to be looking to get reward # print('show window around square', square_pos) tolerance = self.plot_variables[ self.text_dict['Tolerance']] / self.deg_per_pixel # print 'tolerance in pixels', tolerance # print 'square', square[0], square[2] eye_window = LineSegs() eye_window.setThickness(2.0) eye_window.setColor(1, 0, 0, 1) angle_radians = radians(360) for i in range(50): a = angle_radians * i / 49 y = tolerance * sin(a) x = tolerance * cos(a) eye_window.drawTo((x + target_pos[0], 55, y + target_pos[1])) # draw a radius line # eye_window.moveTo(square[0], 55, square[2]) # eye_window.drawTo(square[0], 55, square[2] + self.plot_variables[self.text_dict['Tolerance']]) # print 'distance drawn', self.distance((square[0], square[2]), (square[0], square[2] + self.plot_variables[self.text_dict['Tolerance']])) # True optimizes the line segments, which sounds useful node = self.base.render.attachNewNode(eye_window.create(True)) node.show(BitMask32.bit(0)) node.hide(BitMask32.bit(1)) self.eye_window.append(node) def setup_text(self, name, text_frag, position): text_node = TextNode(name) if not text_frag: text_node.setText(name) elif name == 'Tolerance': # always start in manual, so tolerance meaningless text_node.setText('') else: text_node.setText(name + ': ' + str(text_frag)) text_node_path = self.base.render.attach_new_node(text_node) text_node_path.setScale(25) text_node_path.setPos(position) text_node_path.show(BitMask32.bit(0)) text_node_path.hide(BitMask32.bit(1)) return text_node def update_text(self, ch_type, change=''): # print 'update', ch_type if not change: update_string = ch_type else: update_string = change if ch_type == 'Tolerance': if self.manual: update_string = '' else: degree = unichr(176).encode('utf-8') update_string = ch_type + ': ' + str( change) + degree + ' V.A., \n alt-arrow to adjust' node = self.text_dict[ch_type] self.text_nodes[node].setText(update_string) def start_reward_task(self): self.reward_task = pydaq.GiveReward() # Key Functions # key press or messenger methods def change_gain_or_offset(self, ch_type, x_or_y, ch_amount): self.plot_variables[self.text_dict[ch_type]][x_or_y] += ch_amount node = self.text_dict[ch_type] self.text_nodes[node].setText( ch_type + ': ' + str(self.plot_variables[self.text_dict[ch_type]])) self.logging.log_change(ch_type, self.plot_variables[self.text_dict[ch_type]]) def change_tolerance(self, direction): # print 'change tolerance' tolerance = self.plot_variables[self.text_dict['Tolerance']] tolerance += direction self.logging.log_change('Tolerance', tolerance) self.update_text('Tolerance', tolerance) self.plot_variables[self.text_dict['Tolerance']] = tolerance # erase any window up currently for win in self.eye_window: win.detachNode() # self.eye_window.detachNode() # and redraw new window target = self.sequences.get_fixation_target() self.show_window(target[0]) # this simply sets a key in the self.key_dict dictionary to the given value def set_key(self, key, val): self.key_dict[key] = val # print 'set key', self.key_dict[key] # this actually assigns keys to methods def setup_keys(self): self.accept("escape", self.close) # escape # starts turning square on self.accept("space", self.start_main_loop) # switches from manual to auto-calibrate or vise-versa, # but only at end of current loop (after reward) # True signifies that we want to change self.accept("s", self.set_key, ["task_flag", True]) # For adjusting calibration # inputs, gain or offset, x or y, how much change # gain - up and down are y self.accept("shift-arrow_up", self.change_gain_or_offset, ['Gain', 1, 1]) self.accept("shift-arrow_up-repeat", self.change_gain_or_offset, ['Gain', 1, 1]) self.accept("shift-arrow_down", self.change_gain_or_offset, ['Gain', 1, -1]) self.accept("shift-arrow_down-repeat", self.change_gain_or_offset, ['Gain', 1, -1]) # gain - right and left are x self.accept("shift-arrow_right", self.change_gain_or_offset, ['Gain', 0, 1]) self.accept("shift-arrow_right-repeat", self.change_gain_or_offset, ['Gain', 0, 1]) self.accept("shift-arrow_left", self.change_gain_or_offset, ['Gain', 0, -1]) self.accept("shift-arrow_left-repeat", self.change_gain_or_offset, ['Gain', 0, -1]) # offset - up and down are y self.accept("control-arrow_up", self.change_gain_or_offset, ['Offset', 1, 0.5]) self.accept("control-arrow_up-repeat", self.change_gain_or_offset, ['Offset', 1, 0.5]) self.accept("control-arrow_down", self.change_gain_or_offset, ['Offset', 1, -0.5]) self.accept("control-arrow_down-repeat", self.change_gain_or_offset, ['Offset', 1, -0.5]) # offset - right and left are x self.accept("control-arrow_right", self.change_gain_or_offset, ['Offset', 0, 0.5]) self.accept("control-arrow_right-repeat", self.change_gain_or_offset, ['Offset', 0, 0.5]) self.accept("control-arrow_left", self.change_gain_or_offset, ['Offset', 0, -0.5]) self.accept("control-arrow_left-repeat", self.change_gain_or_offset, ['Offset', 0, -0.5]) # For adjusting tolerance (allowable distance from target that still gets reward) self.accept("alt-arrow_up", self.change_tolerance, [0.5]) self.accept("alt-arrow_up-repeat", self.change_tolerance, [0.5]) self.accept("alt-arrow_down", self.change_tolerance, [-0.5]) self.accept("alt-arrow_down-repeat", self.change_tolerance, [-0.5]) # send messages from other classes # done with an outside process, time to cleanup self.accept("cleanup", self.cleanup_main_loop) self.accept("reward", self.give_reward) self.accept("clear", self.clear_screen) self.accept("clear_fix", self.clear_fix_window) self.accept("plot", self.start_plot_eye_task) # keys will update the list, and loop will query it # to get new position # why is this a dictionary? It only has one entry?!?! # needs to be a dictionary for other classes to see changes # someday should figure out how to do this better # keyboard self.accept("1", self.set_key, ["switch", 1]) self.accept("2", self.set_key, ["switch", 2]) self.accept("3", self.set_key, ["switch", 3]) self.accept("4", self.set_key, ["switch", 4]) self.accept("5", self.set_key, ["switch", 5]) self.accept("6", self.set_key, ["switch", 6]) self.accept("7", self.set_key, ["switch", 7]) self.accept("8", self.set_key, ["switch", 8]) self.accept("9", self.set_key, ["switch", 9]) # setup methods def setup_windows(self): # get properties for setting up researchers window props = WindowProperties() # props.setForeground(True) props.setCursorHidden(True) try: self.base.win.requestProperties(props) # print props except AttributeError: print 'Cannot open second window. To open just one window, ' \ 'change the resolution in the config file to Test ' \ 'or change the resolution to None for default Panda window' # go ahead and give the traceback and exit raise # Need to get this better. keypress only works with one window. # plus looks ugly. window2 = self.base.openWindow() window2.setClearColor((115 / 255, 115 / 255, 115 / 255, 1)) # resolution of window for actual calibration resolution = self.config['WIN_RES'] eye_res = self.config['EYE_RES'] # if resolution given, set the appropriate resolution # otherwise assume want small windows if resolution is not None: # properties for second window props.setOrigin(-int(eye_res[0]), 0) # props.setOrigin(0, 0) # resolution for second window, one for plotting eye data # props.setSize(1024, 768) props.setSize(int(eye_res[0]), int(eye_res[1])) else: resolution = [ 800, 600 ] # if no resolution given, assume normal panda window props.setOrigin( 600, 200) # make it so windows aren't on top of each other # x and y are pretty damn close, so just use x # degree per pixel is important only for determining where to plot squares and # determining tolerance, but no effect on actual eye position plotting, uses projector # resolution, screen size, etc self.deg_per_pixel = visual_angle(self.config['SCREEN'], resolution, self.config['VIEW_DIST'])[0] # print 'deg_per_pixel', self.deg_per_pixel # set the properties for eye data window props.set_foreground(False) window2.requestProperties(props) # print 'main', window1.getReqeustedProperties() # print 'researcher', window2.getRequestedProperties() # resolution for main window, subjects monitor self.set_resolution(resolution) # orthographic lens means 2d, then we can set size to resolution # so coordinate system is in pixels lens = OrthographicLens() lens.setFilmSize(int(resolution[0]), int(resolution[1])) # lens.setFilmSize(800, 600) # this allows us to layer, as long as we use between -100 # and 100 for z. (eye position on top of squares) lens.setNearFar(-100, 100) camera = self.base.camList[0] camera.node().setLens(lens) camera.reparentTo(self.base.render) camera2 = self.base.camList[1] camera2.node().setLens(lens) camera2.reparentTo(self.base.render) # set bit mask for eye positions camera.node().setCameraMask(BitMask32.bit(1)) camera2.node().setCameraMask(BitMask32.bit(0)) def set_resolution(self, res): # sets the resolution for the main window (projector) wp = WindowProperties() # print 'calibration window', res wp.setSize(int(res[0]), int(res[1])) # wp.setSize(1600, 900) # wp.setOrigin(-1600, 0) wp.setOrigin(0, 0) # wp.setOrigin(-int(res[0]), 0) # wp.setUndecorated(True) wp.set_foreground(True) self.base.win.requestProperties(wp) # print 'main', self.base.win.getRequestedProperties() def setup_game(self): # this only happens once, at beginning # set up keys self.setup_keys() self.logging = Logging(self.config) self.sequences = CalSequences(self.config, self.base, self.logging, self.key_dict) if self.config.setdefault('PHOTO_PATH', False): self.photos = Photos(self.config, self.base, self.logging, self.deg_per_pixel) self.photos.load_all_photos() self.call_subroutine.append(self.photos) # print 'call_subroutine', self.call_subroutine # start generating/receiving data self.eye_data = EyeData(self.base, self.config['FAKE_DATA']) self.start_eye_data() # start reward capabilities, if using daq if self.use_daq_reward: # print 'setup reward' self.start_reward_task() if not self.testing: self.start_gig() def close(self): # print 'close' # if we close during a photo showing or photo break, will interrupt task # also want to keep track of where we ended. Move this to Photos. # make sure eye data is # close any subroutines if self.call_subroutine: for tasks in self.call_subroutine: tasks.close() self.eye_data.close() self.logging.close_files() if self.testing: self.ignoreAll( ) # ignore everything, so nothing weird happens after deleting it. else: sys.exit()