def setup(self): ''' process custom settings that might have been set after initializing the object. ''' # check if these parameters / properties / attributes were actually set! self.USE_MMAP = getattr(self, 'receive_data_from_matlab', self.USE_MMAP) self.SETTINGS.COLOR_TO_USE = getattr(self, 'COLOR_TO_USE', self.SETTINGS.COLOR_TO_USE) # add 'abs_plugin_ID' to plugin name. self.PLUGIN_NAME = self.PLUGIN_NAME + '-' + str(self.abs_plugin_ID) ''' set variables based on init() values. ''' self.Y_LIMS = [0, self.SETTINGS.WINDOW_HEIGHT_DEFAULT] self.SETTINGS.WINDOW_WIDTH_CURRENT = self.SETTINGS.WINDOW_WIDTH_DEFAULT self.SETTINGS.WINDOW_HEIGHT_CURRENT = self.SETTINGS.WINDOW_HEIGHT_DEFAULT ''' setup mmap or random data interface ''' status, self.MMAP, self.RANDOM_DATA = setup_incoming_data_interface(self.USE_MMAP, self.PLUGIN_NAME, self.NBR_CHANNELS, self.nPointsToUpdate, self.nPoints, self.SETTINGS.WINDOW_WIDTH_CURRENT, self.SETTINGS.WINDOW_HEIGHT_CURRENT) if not status: sys.exit(1) ''' setup plot queue ''' self.plot_queue = setup_plotting_queue() ''' generate initial positions & colors, and setup VOBs ''' self.vbo_data, self.vbo_colors, self.x_coords, self.SETTINGS.COLOR_USED = \ gl_setup_initial_data_and_color_and_vbos(self.nPoints, n_COORDINATES_PER_COLOR, self.NBR_CHANNELS, self.SETTINGS) ''' horizontal and vertical lines - setup even if user doesn't want to see them, because we setup key press functions to en-/disable them. ''' # horizontal line showing the threshold self.line_hor = line_default_horizontal(self) # vertical line showing which data point is going to be update next self.line_ver = line_default_vertical(self) ''' axes - setup even it user doesn't want to see it, because of kpf. ''' self.coord_axes, self.y_axis_tics = axes_default_with_y_ticks(self) ''' other stuff ''' # is Tkinter installed and running? self.SETTINGS = tkinter_register_with_settings(self.SETTINGS) # set the window caption. Can't do it in 'setup_window' because some parameters # are not processed there yet. self.setup_window_caption()
def purge_plot_queue_if_necessary(self): if self.plot_queue_purge_if_size_limit_reached and len(self.plot_queue) > self.plot_queue_size_limit: self.plot_queue = setup_plotting_queue()
def on_key_press(self, symbol, modifiers): ''' basic kpf ''' if symbol == key.A: # show / hide axes if modifiers == key.MOD_CTRL + self.mod_offset: if self.SHOW_AXES: self.coord_axes, self.y_axis_tics, self.SHOW_AXES = False, False, False else: self.SHOW_AXES = True self.coord_axes, self.y_axis_tics = axes_default_with_y_ticks(self) elif symbol == key.C: self.plot_queue = setup_plotting_queue() print "Cleared Plot-Queue" elif symbol == key.F: # show / hide FPS display self.SHOW_FPS = not self.SHOW_FPS elif symbol == key.H: # show help menu from pyglet_app_strings import main_help_menu # the tkinterface is currently buggy - show console output by default. if self.SETTINGS.TKINTER_AVAILABLE and (modifiers == key.MOD_CTRL + self.mod_offset): from pyglet_app_tkinter_dialogs import text_info help_win = text_info() help_win.run('help', main_help_menu) else: print main_help_menu elif symbol == key.P: # switch between plotting modes from pyglet_app_screen_update_elements_static_line import StaticLineUpdateScreen from pyglet_app_screen_update_elements_moving_line import MovingLineUpdateScreen # we have three different modes currently that we can choose from. self._screen_update_mode = (self._screen_update_mode + 1) % 3 if self._screen_update_mode == 0: current_screen = StaticLineUpdateScreen mode = 0 elif self._screen_update_mode == 1: current_screen = StaticLineUpdateScreen mode = 1 elif self._screen_update_mode == 2: current_screen = MovingLineUpdateScreen mode = None self.clearCurrentScreen() self.set_current_screen(current_screen) self.current_screen.mode = mode self.startCurrentScreen() elif symbol == key.Q: # show number of elements in plot queue print "Plot-Queue size: %d" % (len(self.plot_queue)) elif symbol == key.S: # take screenshot of current screen content if (modifiers == key.MOD_SHIFT + self.mod_offset): # set screenshot path label_strg = 'Screenshot path ' if self.SETTINGS.SCREENSHOT_PATH is not None: label_strg = label_strg + '(currently %s) '%self.SETTINGS.SCREENSHOT_PATH got_value, new_value = one_input(self.SETTINGS, label_strg, 'Please provide new Screenshot path and press ENTER: ', 'Screenshot path') # nothing given - return. if not got_value: return # replace '\' with '/' because path.join() transforms everything to '/' notation. self.SETTINGS.SCREENSHOT_PATH = new_value.replace('\\', '/') elif not (modifiers == key.MOD_CTRL + self.mod_offset): try: now = datetime.now().strftime("%Y-%m-%d--%H-%M-%S") filename = 'Screenshot-from-%s---%s.png' %(now, self.PLUGIN_NAME) if self.SETTINGS.SCREENSHOT_PATH is not None: filename = os.path.join(self.SETTINGS.SCREENSHOT_PATH, filename) pyglet.image.get_buffer_manager().get_color_buffer().save(filename) print 'File "%s" saved.' % filename except Exception, e: print "An error occurred while saving the screenshot: " print e pass
def on_key_press(self, symbol, modifiers): # offset that needs to be added to 'key.MOD_*' in order to match the # 'modifiers' value mod_offset = 16 ''' key press function for y limits ''' key_matched = self.kpf_change_y_lims(symbol, modifiers, mod_offset) # skip remainder of key press function in case 'kpf_change_y_lims' had a hit. if key_matched: return ''' key press function for horizontal line ''' key_matched = self.kpf_change_horizontal_line(symbol, modifiers, mod_offset) # skip remainder of key press function in case 'kpf_change_horizontal_line' had a hit. if key_matched: return ''' remaining keys ''' if symbol == key.A: if modifiers == key.MOD_CTRL + mod_offset: if self.SHOW_AXES: self.coord_axes, self.y_axis_tics, self.SHOW_AXES = False, False, False else: self.SHOW_AXES = True self.coord_axes, self.y_axis_tics = axes_default_with_y_ticks( self.SETTINGS, self.Y_LIMS) elif symbol == key.C: self.plot_queue = setup_plotting_queue() print "Cleared Plot-Queue" elif symbol == key.F: # show / hide FPS display self.SHOW_FPS = not self.SHOW_FPS elif symbol == key.H: # show help menu print " " print " *** HELP ***" print " " print "\t 0: \t\t\trestore original y-lims" print "\t 1: \t\t\tdecrease upper y-lim" print "\t 2: \t\t\tincrease upper y-lim" print "\t 3: \t\t\tdecrease lower y-lim" print "\t 4: \t\t\tincrease lower y-lim" print "\t a + ctrl: \t\tshow / hide axes" print "\t f: \t\t\tshow / hide FPS display" print "\t q: \t\t\tshow number of elements in plot queue" print "\t t: \t\t\tset position of horizontal line" print "\t t + shift: \t\tprint out current position of horizontal line" print "\t t + ctrl: \t\tshow / hide horizontal line" print "\t v + ctrl: \t\tshow / hide vertical line" print "\t y: \t\t\tset upper y-lim to value from command line" print "\t y + shift: \t\tset lower y-lim to value from command line" print "\t y + ctrl: \t\tset upper and lower y limits through GUI" print "\t arrow up: \t\tmove horizontal line up by one" print "\t arrow down: \t\tmove horizontal line down by one" print "\t arrow up + shift: \tmove horizontal line up by five" print "\t arrow down + shift: \tmove horizontal line down by five" print "\t space bar: \t\tpause / resume screen update" print " " elif symbol == key.Q: # show number of elements in plot queue print "Plot-Queue size: %d" % (len(self.plot_queue)) elif symbol == key.V: # show / hide vertical line (toggle display of vertical line) if modifiers == key.MOD_CTRL + mod_offset: if not self.SHOW_VERTICAL_LINE: self.line_ver = line_default_vertical( self.SETTINGS.WINDOW_HEIGHT_CURRENT, self.x_coords) self.SHOW_VERTICAL_LINE = not self.SHOW_VERTICAL_LINE elif symbol == key.ESCAPE: # quit program sys.exit() elif symbol == key.SPACE: # freeze / resume plotting self.DO_DRAW = not self.DO_DRAW
def update(self, dt): # update nPointsToUpdate points per `update()` call # TODO: handle cases where 'nPoints' is not a multiple of 'nPointsToUpdate' # (need to wrap around at the end of the list) ''' START 'DATA MANAGEMENT' ''' # pick up new data from mmap or other system (i.e. generated) new_data, new_data_is_empty, nbr_buffers_per_mmap_file = request_new_data( self.USE_MMAP, self.DATA, self.MMAP) # don't add empty data to the queue # don't use 'NBR_INDEPENDENT_CHANNELS' here, because we might be skipping this channel if sum(new_data_is_empty) != len(new_data): #print len(new_data[0][0]) #print new_data[1][0] append_data_to_plot_queue(self.plot_queue, new_data, nbr_buffers_per_mmap_file) ''' END 'DATA MANAGEMENT' ''' ''' debugging if new_data_is_empty[0] == 1: print 'new data is empty!' else: print ' NOT EMPTY!' ''' # Quit here if we are not supposed to draw anything new. This way the queue # keeps growing and we don't miss anything. if not self.DO_DRAW: return # don't purge entire queue - keep at least 'MIN_NBR_BUFFERS_NECESSARY_FOR_UPDATE' elements in queue. # this will give us a smoother plotting experience. queue_length = len(self.plot_queue) if queue_length < MIN_NBR_BUFFERS_NECESSARY_FOR_UPDATE: return ''' START 'dequeue buffers and prepare them for plotting' ''' # plot ALL buffers currently in queue. for j in xrange(queue_length): # dequeue buffers and update VBOs # raw_data is an array of channels containing the data per channel. raw_data = get_data_from_plot_queue(self.plot_queue) #print raw_data # update y values in main VBO - do this for each channel! current_pos_in_memory = gl_update_two_coordinates_in_VBO_static_view( raw_data, self.vbo_data, self.c, self.nPoints, self.nPointsToUpdate, BYTES_PER_POINT, BYTES_PER_COORDINATE, self.NBR_CHANNELS, self.x_coords) # Update position of vertical line - move it one 'nPointsToUpdate' # buffer ahead of currently updated position. calc modulo 'nPoints', # so that the position is in the range from 0 to nPoints. self.line_ver.curr_pos = (current_pos_in_memory + self.nPointsToUpdate) % self.nPoints # increase counter and modulo 'nPoints', so that 'c' doesn't grow out of bounds. self.c = (self.c + 1) % self.nPoints ''' END 'dequeue buffers and prepare them for plotting' ''' # set the resulting vertical line position. if self.SHOW_VERTICAL_LINE: self.line_ver.gl_update_line_x_value(self.line_ver.curr_pos) # auto-purge plot queue if feature is activated and limit is reached. if self.plot_queue_purge_if_size_limit_reached and len( self.plot_queue) > self.plot_queue_size_limit: self.plot_queue = setup_plotting_queue()
def setup(self): ''' set variables based on init() values. ''' self.Y_LIMS = [0, self.SETTINGS.WINDOW_HEIGHT_DEFAULT] self.SETTINGS.WINDOW_WIDTH_CURRENT = self.SETTINGS.WINDOW_WIDTH_DEFAULT self.SETTINGS.WINDOW_HEIGHT_CURRENT = self.SETTINGS.WINDOW_HEIGHT_DEFAULT # add 'abs_plugin_ID' to plugin name. self.PLUGIN_NAME = self.PLUGIN_NAME + '-' + str(self.abs_plugin_ID) ''' setup mmap or random data interface ''' status, self.MMAP, self.DATA = setup_incoming_data_interface( self.USE_MMAP, self.PLUGIN_NAME, self.NBR_CHANNELS, self.nPointsToUpdate, self.nPoints, self.SETTINGS.WINDOW_WIDTH_CURRENT, self.SETTINGS.WINDOW_HEIGHT_CURRENT) if not status: sys.exit(1) ''' setup plot queue ''' self.plot_queue = setup_plotting_queue() ''' generate initial positions & colors, and setup VOBs ''' self.vbo_data, self.vbo_colors, self.x_coords = \ gl_setup_initial_data_and_color_and_vbos(self.nPoints, n_COORDINATES_PER_COLOR, self.NBR_CHANNELS, self.SETTINGS.WINDOW_WIDTH_DEFAULT, self.SETTINGS.WINDOW_HEIGHT_DEFAULT) ''' horizontal and vertical lines ''' # horizontal line showing the threshold if self.SHOW_HORIZONTAL_LINE: self.line_hor = line_default_horizontal(self) # vertical line showing which data point is going to be update next if self.SHOW_VERTICAL_LINE: self.line_ver = line_default_vertical(self) ''' axes ''' if self.SHOW_AXES: self.coord_axes, self.y_axis_tics = axes_default_with_y_ticks(self) ''' other stuff ''' # is Tkinter installed and running? self.SETTINGS = tkinter_register_with_settings(self.SETTINGS) # set default gl modes set_gl_defaults(self.POINT_SIZE) # try to render a smooth line (if supported by driver) gl_enable_line_smoothing() # set window title win_title = 'generating random data' if self.USE_MMAP: win_title = 'receiving data from matlab' nbr_points_shown = ' -- showing %s points per panel.' % self.nPoints self.set_caption(self.PLUGIN_NAME + ' -- ' + win_title + nbr_points_shown) # hide mouse - disabled. # self.set_mouse_visible(False) # schedule the 'update()' method to be called each 'update_interval' pyglet.clock.schedule_interval(self.update, self.update_interval) # Create a font for our FPS clock ft = pyglet.font.load('Arial', 28) self.fps_display = pyglet.clock.ClockDisplay(font=ft, interval=0.125, format='FPS %(fps).2f')
def on_key_press(self, symbol, modifiers): # offset that needs to be added to 'key.MOD_*' in order to match the # 'modifiers' value mod_offset = 16 """ key press function for y limits """ key_matched = self.kpf_change_y_lims(symbol, modifiers, mod_offset) # skip remainder of key press function in case 'kpf_change_y_lims' had a hit. if key_matched: return """ key press function for horizontal line """ key_matched = self.kpf_change_horizontal_line(symbol, modifiers, mod_offset) # skip remainder of key press function in case 'kpf_change_horizontal_line' had a hit. if key_matched: return """ remaining keys """ if symbol == key.A: if modifiers == key.MOD_CTRL + mod_offset: if self.SHOW_AXES: self.coord_axes, self.y_axis_tics, self.SHOW_AXES = False, False, False else: self.SHOW_AXES = True self.coord_axes, self.y_axis_tics = axes_default_with_y_ticks(self.SETTINGS, self.Y_LIMS) elif symbol == key.C: self.plot_queue = setup_plotting_queue() print "Cleared Plot-Queue" elif symbol == key.F: # show / hide FPS display self.SHOW_FPS = not self.SHOW_FPS elif symbol == key.H: # show help menu print " " print " *** HELP ***" print " " print "\t 0: \t\t\trestore original y-lims" print "\t 1: \t\t\tdecrease upper y-lim" print "\t 2: \t\t\tincrease upper y-lim" print "\t 3: \t\t\tdecrease lower y-lim" print "\t 4: \t\t\tincrease lower y-lim" print "\t a + ctrl: \t\tshow / hide axes" print "\t f: \t\t\tshow / hide FPS display" print "\t q: \t\t\tshow number of elements in plot queue" print "\t t: \t\t\tset position of horizontal line" print "\t t + shift: \t\tprint out current position of horizontal line" print "\t t + ctrl: \t\tshow / hide horizontal line" print "\t v + ctrl: \t\tshow / hide vertical line" print "\t y: \t\t\tset upper y-lim to value from command line" print "\t y + shift: \t\tset lower y-lim to value from command line" print "\t y + ctrl: \t\tset upper and lower y limits through GUI" print "\t arrow up: \t\tmove horizontal line up by one" print "\t arrow down: \t\tmove horizontal line down by one" print "\t arrow up + shift: \tmove horizontal line up by five" print "\t arrow down + shift: \tmove horizontal line down by five" print "\t space bar: \t\tpause / resume screen update" print " " elif symbol == key.Q: # show number of elements in plot queue print "Plot-Queue size: %d" % (len(self.plot_queue)) elif symbol == key.V: # show / hide vertical line (toggle display of vertical line) if modifiers == key.MOD_CTRL + mod_offset: if not self.SHOW_VERTICAL_LINE: self.line_ver = line_default_vertical(self.SETTINGS.WINDOW_HEIGHT_CURRENT, self.x_coords) self.SHOW_VERTICAL_LINE = not self.SHOW_VERTICAL_LINE elif symbol == key.ESCAPE: # quit program sys.exit() elif symbol == key.SPACE: # freeze / resume plotting self.DO_DRAW = not self.DO_DRAW
def update(self, dt): # update nPointsToUpdate points per `update()` call # TODO: handle cases where 'nPoints' is not a multiple of 'nPointsToUpdate' # (need to wrap around at the end of the list) """ START 'DATA MANAGEMENT' """ # pick up new data from mmap or other system (i.e. generated) new_data, new_data_is_empty, nbr_buffers_per_mmap_file = request_new_data(self.USE_MMAP, self.DATA, self.MMAP) # don't add empty data to the queue # don't use 'NBR_INDEPENDENT_CHANNELS' here, because we might be skipping this channel if sum(new_data_is_empty) != len(new_data): # print len(new_data[0][0]) # print new_data[1][0] append_data_to_plot_queue(self.plot_queue, new_data, nbr_buffers_per_mmap_file) """ END 'DATA MANAGEMENT' """ """ debugging if new_data_is_empty[0] == 1: print 'new data is empty!' else: print ' NOT EMPTY!' """ # Quit here if we are not supposed to draw anything new. This way the queue # keeps growing and we don't miss anything. if not self.DO_DRAW: return # don't purge entire queue - keep at least 'MIN_NBR_BUFFERS_NECESSARY_FOR_UPDATE' elements in queue. # this will give us a smoother plotting experience. queue_length = len(self.plot_queue) if queue_length < MIN_NBR_BUFFERS_NECESSARY_FOR_UPDATE: return """ START 'dequeue buffers and prepare them for plotting' """ # plot ALL buffers currently in queue. for j in xrange(queue_length): # dequeue buffers and update VBOs # raw_data is an array of channels containing the data per channel. raw_data = get_data_from_plot_queue(self.plot_queue) # print raw_data # update y values in main VBO - do this for each channel! current_pos_in_memory = gl_update_two_coordinates_in_VBO_static_view( raw_data, self.vbo_data, self.c, self.nPoints, self.nPointsToUpdate, BYTES_PER_POINT, BYTES_PER_COORDINATE, self.NBR_CHANNELS, self.x_coords, ) # Update position of vertical line - move it one 'nPointsToUpdate' # buffer ahead of currently updated position. calc modulo 'nPoints', # so that the position is in the range from 0 to nPoints. self.line_ver.curr_pos = (current_pos_in_memory + self.nPointsToUpdate) % self.nPoints # increase counter and modulo 'nPoints', so that 'c' doesn't grow out of bounds. self.c = (self.c + 1) % self.nPoints """ END 'dequeue buffers and prepare them for plotting' """ # set the resulting vertical line position. if self.SHOW_VERTICAL_LINE: self.line_ver.gl_update_line_x_value(self.line_ver.curr_pos) # auto-purge plot queue if feature is activated and limit is reached. if self.plot_queue_purge_if_size_limit_reached and len(self.plot_queue) > self.plot_queue_size_limit: self.plot_queue = setup_plotting_queue()
def setup(self): """ set variables based on init() values. """ self.Y_LIMS = [0, self.SETTINGS.WINDOW_HEIGHT_DEFAULT] self.SETTINGS.WINDOW_WIDTH_CURRENT = self.SETTINGS.WINDOW_WIDTH_DEFAULT self.SETTINGS.WINDOW_HEIGHT_CURRENT = self.SETTINGS.WINDOW_HEIGHT_DEFAULT # add 'abs_plugin_ID' to plugin name. self.PLUGIN_NAME = self.PLUGIN_NAME + "-" + str(self.abs_plugin_ID) """ setup mmap or random data interface """ status, self.MMAP, self.DATA = setup_incoming_data_interface( self.USE_MMAP, self.PLUGIN_NAME, self.NBR_CHANNELS, self.nPointsToUpdate, self.nPoints, self.SETTINGS.WINDOW_WIDTH_CURRENT, self.SETTINGS.WINDOW_HEIGHT_CURRENT, ) if not status: sys.exit(1) """ setup plot queue """ self.plot_queue = setup_plotting_queue() """ generate initial positions & colors, and setup VOBs """ self.vbo_data, self.vbo_colors, self.x_coords = gl_setup_initial_data_and_color_and_vbos( self.nPoints, n_COORDINATES_PER_COLOR, self.NBR_CHANNELS, self.SETTINGS.WINDOW_WIDTH_DEFAULT, self.SETTINGS.WINDOW_HEIGHT_DEFAULT, ) """ horizontal and vertical lines """ # horizontal line showing the threshold if self.SHOW_HORIZONTAL_LINE: self.line_hor = line_default_horizontal(self) # vertical line showing which data point is going to be update next if self.SHOW_VERTICAL_LINE: self.line_ver = line_default_vertical(self) """ axes """ if self.SHOW_AXES: self.coord_axes, self.y_axis_tics = axes_default_with_y_ticks(self) """ other stuff """ # is Tkinter installed and running? self.SETTINGS = tkinter_register_with_settings(self.SETTINGS) # set default gl modes set_gl_defaults(self.POINT_SIZE) # try to render a smooth line (if supported by driver) gl_enable_line_smoothing() # set window title win_title = "generating random data" if self.USE_MMAP: win_title = "receiving data from matlab" nbr_points_shown = " -- showing %s points per panel." % self.nPoints self.set_caption(self.PLUGIN_NAME + " -- " + win_title + nbr_points_shown) # hide mouse - disabled. # self.set_mouse_visible(False) # schedule the 'update()' method to be called each 'update_interval' pyglet.clock.schedule_interval(self.update, self.update_interval) # Create a font for our FPS clock ft = pyglet.font.load("Arial", 28) self.fps_display = pyglet.clock.ClockDisplay(font=ft, interval=0.125, format="FPS %(fps).2f")