class ShellTest(HasPrivateTraits): # ------------------------------------------------------------------------- # Trait definitions: # ------------------------------------------------------------------------- name = Str() age = Int() weight = Float() shell_1 = Str() shell_2 = Dict() # ------------------------------------------------------------------------- # Traits view definitions: # ------------------------------------------------------------------------- view = View( 'name', 'age', 'weight', '_', Item('shell_1', editor=ShellEditor()), Item('shell_2', editor=ShellEditor()), id='traitsui.tests.shell_editor_test', resizable=True, width=0.3, height=0.3, )
class WithShell(HasTraits): df = Instance(DataFrame) shell = Any() pandasplot = Instance(PandasPlot) def __init__(self): # self.df=DataFrame([1,2,3]) self.pandasplot = PandasPlot() # self.pandasplot.df=self.df def _df_changed(self): if self.pandasplot: self.pandasplot.df = self.df main_group = Group( Item('pandasplot', show_label=False, style='custom'), # Item('df_new'), Item('df_change'), Item('shell', editor=ShellEditor(), style='simple'), #Include('sample_group'), #Include('axis_traits_group') ) traits_view = View(Include('main_group'), resizable=True, height=600, width=800)
class DebugModelView(ModelView): """ Base class for Model/View's to provide a python shell for debugging. """ #### Private protocol ##################################################### # A dummy python value to allow us to display a Python shell. _python_value = PythonValue #### Traits UI ############################################################ python_shell_group = Group( Item( '_python_value', editor = ShellEditor(share=True), show_label = False, ), label = 'Python Shell' ) debug_group = python_shell_group debug_view = View( VGroup( Include('body'), Include('debug_group'), layout = 'split' ), resizable = True, width = 800, height = 600 )
def shell_editor(): """ Factory function that returns a Python shell for editing Python values. """ global PythonShellEditor if PythonShellEditor is None: from traitsui.api import ShellEditor PythonShellEditor = ShellEditor() return PythonShellEditor
def trait_view(self, parent=None): self.shell = self.__dict__ traits_view = View(VGroup( Item('shell', editor=ShellEditor(), id="Shell"), Item('datafiles@', id='notebook', show_label=False, editor=ListEditor(use_notebook=True, deletable=False, selected='selected', export='DockWindowShell', page_name='.filename'))), width=1024, height=768, resizable=True, title="Stoner Plotter") return traits_view
def get_dict_view(share=False): return View(Item( "locals_dict", editor=ShellEditor(share=share), ))
def get_str_view(share=False): return View(Item( "locals_str", editor=ShellEditor(share=share), ))
class Application(HasStrictTraits): """ Main GUI application which allows user to set global, Openfoam and Liggghts parameters of the computation and visualize it with Mayavi """ #: The global settings for the calculation global_settings = Instance(GlobalParametersModel) #: The Liggghts settings for the calculation liggghts_settings = Instance(LiggghtsModel) #: The Openfoam settings for the calculation openfoam_settings = Instance(OpenfoamModel) # The mayavi sources, associated to the following datasets: # first element is the openfoam mesh, second and third are # the flow and walls particles, respectively. # It is an invariant. The cuds gets changed as we select different # frames. sources = Tuple(Instance(CUDSSource), Instance(CUDSSource), Instance(CUDSSource)) # All the frames resulting from the execution of our computation. frames = List(Tuple(VTKMesh, VTKParticles, VTKParticles)) # The frame to visualize current_frame_index = Int() # The physical current frame, for practicality _current_frame = Either( None, Tuple(VTKMesh, VTKParticles, VTKParticles) ) #: The button on which the user will click to run the # calculation run_button = Button("Run") first_button = Button("First") previous_button = Button("Previous") play_stop_button = Button() play_stop_label = Str("Play") next_button = Button("Next") last_button = Button("Last") save_button = Button("Save...") play_timer = Instance(Timer) #: The pop up dialog which will show the status of the # calculation progress_dialog = Instance(ProgressDialog) #: Boolean representing if the application should allow # operations or not interactive = Bool(True) #: The Mayavi traits model which contains the scene and engine mlab_model = Instance(MlabSceneModel, ()) #: Event object which will be useful for error dialog calculation_error_event = Event(Str) #: True if the calculation can be safely run, False otherwise valid = Bool(False) #: Dictionary of the namespace associated to the shell editor shell = Dict() # Private traits. #: Executor for the threaded action. _executor = Instance(futures.ThreadPoolExecutor) # Lock to synchronize the execution loop and the storage of the Datasets # from application specific cuds to VTK Datasets. We need to do so because # the computational engine can change the datasets, so we need to hold # the computational engine until we are done "copying and storing" each # frame _event_lock = Instance(threading.Event, ()) traits_view = View( HSplit( VSplit( VGroup( Tabbed( UItem('global_settings', style='custom'), UItem('liggghts_settings', style='custom'), UItem('openfoam_settings', label='OpenFOAM settings', style="custom"), ), UItem( name='run_button', enabled_when='valid' ), enabled_when='interactive', ), UItem('shell', editor=ShellEditor()) ), VGroup( UItem( name='mlab_model', editor=SceneEditor(scene_class=MayaviScene) ), HGroup( UItem( name="first_button", enabled_when=( "current_frame_index > 0 and play_timer is None"), ), UItem( name="previous_button", enabled_when=( "current_frame_index > 0 and play_timer is None"), ), UItem( name="play_stop_button", editor=ButtonEditor(label_value="play_stop_label") ), UItem( name="next_button", enabled_when=( "current_frame_index < len(frames) " "and play_timer is None"), ), UItem( name="last_button", enabled_when=( "current_frame_index < len(frames) " "and play_timer is None"), ), Item(name="current_frame_index", style="readonly"), UItem(name="save_button"), enabled_when=( 'interactive and len(frames) > 0') ) ), ), title='Simphony UI', resizable=True, width=1.0, height=1.0 ) @on_trait_change('calculation_error_event', dispatch='ui') def show_error(self, error_message): error( None, 'Oups ! Something went bad...\n\n{}'.format(error_message), 'Error' ) @on_trait_change('openfoam_settings:valid,' 'liggghts_settings:valid') def update_valid(self): self.valid = (self.openfoam_settings.valid and self.liggghts_settings.valid) @on_trait_change('run_button') def run_calc(self): """ Function which will start the calculation on a secondary thread on run button click Raises ------ RuntimeError If the calculation is already running """ if not self.interactive: raise RuntimeError('Unable to start calculation. Another ' 'operation is already in progress') self.frames = [] self.interactive = False self.progress_dialog.title = 'Calculation running...' self.progress_dialog.open() future = self._executor.submit(self._run_calc_threaded) future.add_done_callback(self._calculation_done) def _add_sources_to_scene(self): """Add the sources to the main scene.""" mayavi_engine = self.mlab_model.engine mayavi_engine.add_source(self.sources[0]) mayavi_engine.add_module(Surface()) self._add_liggghts_source_to_scene(self.sources[1]) self._add_liggghts_source_to_scene(self.sources[2]) def _add_liggghts_source_to_scene(self, source): """ Function which add to liggghts source to the Mayavi scene Parameters ---------- source : The mayavi source linked to the dataset """ mayavi_engine = self.mlab_model.engine # Create Sphere glyph sphere_glyph_module = Glyph() # Add Liggghts sources mayavi_engine.add_source(source) try: source.point_vectors_name = 'VELOCITY' except TraitError: # The data is not available in the dataset for some reason. # Add the modules anyway, but don't select it. pass # Add sphere glyph module mayavi_engine.add_module(sphere_glyph_module) sphere_glyph_module.glyph.glyph_source.glyph_source = SphereSource() sphere_glyph_module.glyph.scale_mode = 'scale_by_scalar' sphere_glyph_module.glyph.glyph.range = [0.0, 1.0] sphere_glyph_module.glyph.glyph_source.glyph_source.radius = 1.0 # Velocities are in meter/second, this scale factor makes # 1 graphical unit = 1 millimeter/sec arrow_scale_factor = 1.0 arrow_glyph_module = Glyph() mayavi_engine.add_module(arrow_glyph_module) arrow_glyph_module.glyph.scale_mode = 'scale_by_vector' arrow_glyph_module.glyph.color_mode = 'color_by_vector' arrow_glyph_module.glyph.glyph.range = [0.0, 1.0] arrow_glyph_module.glyph.glyph.scale_factor = arrow_scale_factor def _remove_sources_from_scene(self): for source in self.sources: try: self.mlab_model.mayavi_scene.remove_child(source) except ValueError: pass def _run_calc_threaded(self): """ Function which will run the calculation. This function is only run by the secondary thread """ try: return run_calc( self.global_settings, self.openfoam_settings, self.liggghts_settings, self.progress_callback, self._event_lock ) except Exception: self.calculation_error_event = traceback.format_exc() log.exception('Error during the calculation') return None def _calculation_done(self, future): """ Function which will return the result of the computation to the main thread Parameters ---------- future Object containing the result of the calculation """ GUI.invoke_later(self._computation_done, future.result()) def _computation_done(self, datasets): self.progress_dialog.update(100) if datasets is not None: self._append_frame(datasets) self._to_last_frame() self.interactive = True def _append_frame(self, datasets): self.frames.append( ( VTKMesh.from_mesh(datasets[0]), VTKParticles.from_particles(datasets[1]), VTKParticles.from_particles(datasets[2]) ) ) @on_trait_change("current_frame_index,frames[]") def _sync_current_frame(self): """Synchronizes the current frame with the index and the available frames.""" try: self._current_frame = self.frames[self.current_frame_index] except IndexError: self._current_frame = None @on_trait_change("_current_frame") def _update_sources_with_current_frame(self, object, name, old, new): """Called when the current frame is changed, updates the sources with the new data. Parameters are from traits interface.""" scene = self.mlab_model.mayavi_scene scene.scene.disable_render = True if new is None: self._remove_sources_from_scene() else: self._remove_sources_from_scene() for i in xrange(len(self._current_frame)): self.sources[i].cuds = self._current_frame[i] self._add_sources_to_scene() scene.scene.disable_render = False def progress_callback(self, datasets, current_iteration, total_iterations): """ Function called in the secondary thread. It will transfer the progress status of the calculation to the main thread Parameters ---------- progress The progress of the calculation (Integer in the range [0, 100]) """ progress = current_iteration/total_iterations*100 GUI.invoke_later(self._append_frame_and_continue, datasets) GUI.invoke_later(self.progress_dialog.update, progress) def _append_frame_and_continue(self, datasets): self._append_frame(datasets) self._event_lock.set() self.current_frame_index = len(self.frames) - 1 def reset(self): """ Function which reset the Mayavi scene. """ # Clear scene self._remove_sources_from_scene() @on_trait_change('first_button') def _to_first_frame(self): """Goes to the first frame""" self.current_frame_index = 0 @on_trait_change('last_button') def _to_last_frame(self): """Goes to the last frame""" self.current_frame_index = len(self.frames) - 1 @on_trait_change('previous_button') def _to_prev_frame(self): """Goes to the previous frame""" frame = self.current_frame_index - 1 if frame < 0: frame = 0 self.current_frame_index = frame @on_trait_change('next_button') def _to_next_frame(self): """Goes to the next frame""" frame = self.current_frame_index + 1 if frame >= len(self.frames): frame = len(self.frames) - 1 self.current_frame_index = frame @on_trait_change('play_stop_button') def _start_stop_video(self): """Starts the video playing""" if self.play_timer is None: self.play_timer = Timer(500, self._next_frame_looped) else: self.play_timer.Stop() self.play_timer = None @on_trait_change("save_button") def _save_images(self): """Saves the current frames in individual images.""" dialog = DirectoryDialog() if dialog.open() != OK: return self.progress_dialog.title = 'Saving images...' self.progress_dialog.open() dirpath = dialog.path self.interactive = False try: for frame_index in xrange(len(self.frames)): self.current_frame_index = frame_index mlab.savefig(os.path.join( dirpath, "frame-{}.png".format(frame_index) )) progress = 100*frame_index/len(self.frames) self.progress_dialog.update(progress) self.progress_dialog.update(100) except Exception: self.calculation_error_event = traceback.format_exc() log.exception('Error while saving') finally: self.interactive = True @on_trait_change('play_timer') def _change_play_button_label(self): """Changes the label from play to stop and vice-versa""" self.play_stop_label = "Stop" if self.play_timer else "Start" def _next_frame_looped(self): """Goes to the next frame, but loop back to the first when over.""" if len(self.frames) == 0: self.current_frame_index = 0 self.current_frame_index = ( self.current_frame_index + 1 ) % len(self.frames) def __executor_default(self): return futures.ThreadPoolExecutor(max_workers=1) def _progress_dialog_default(self): return ProgressDialog( min=0, max=100, ) def _sources_default(self): return CUDSSource(), CUDSSource(), CUDSSource() def _global_settings_default(self): return GlobalParametersModel() def _liggghts_settings_default(self): return LiggghtsModel() def _openfoam_settings_default(self): return OpenfoamModel()
class SwiftConsole(HasTraits): link = Instance(serial_link.SerialLink) console_output = Instance(OutputStream) python_console_env = Dict a = Int b = Int tracking_view = Instance(TrackingView) solution_view = Instance(SolutionView) baseline_view = Instance(BaselineView) observation_view = Instance(ObservationView) observation_view_base = Instance(ObservationView) system_monitor_view = Instance(SystemMonitorView) settings_view = Instance(SettingsView) update_view = Instance(UpdateView) view = View( VSplit( Tabbed( Item('tracking_view', style='custom', label='Tracking'), Item('solution_view', style='custom', label='Solution'), Item('baseline_view', style='custom', label='Baseline'), VSplit( Item('observation_view', style='custom', show_label=False), Item('observation_view_base', style='custom', show_label=False), label='Observations', ), Item('settings_view', style='custom', label='Settings'), Item('update_view', style='custom', label='Firmware Update'), Item('system_monitor_view', style='custom', label='System Monitor'), Item( 'python_console_env', style='custom', label='Python Console', editor=ShellEditor() ), show_labels=False ), Item( 'console_output', style='custom', editor=InstanceEditor(), height=0.3, show_label=False, ), ), icon = icon, resizable = True, width = 1000, height = 600, title = 'Piksi Console, Version: ' + CONSOLE_VERSION ) def print_message_callback(self, data): try: self.console_output.write(data.encode('ascii', 'ignore')) except UnicodeDecodeError: print "Oh crap!" def debug_var_callback(self, data): x = struct.unpack('<d', data[:8])[0] name = data[8:] print "VAR: %s = %d" % (name, x) def __init__(self, *args, **kwargs): try: update = kwargs.pop('update') except KeyError: update = True self.console_output = OutputStream() sys.stdout = self.console_output sys.stderr = self.console_output self.log_file = None log = kwargs.pop('log') reset = kwargs.pop('reset') try: self.link = serial_link.SerialLink(*args, **kwargs) self.link.add_callback(ids.PRINT, self.print_message_callback) self.link.add_callback(ids.DEBUG_VAR, self.debug_var_callback) # Setup logging if log: log_name = serial_link.generate_log_filename() self.log_file = open(log_name, 'w+') print "Logging at %s." % log_name self.link.add_global_callback(serial_link.default_log_callback(self.log_file)) if reset: self.link.send_message(ids.RESET, '') settings_read_finished_functions = [] self.tracking_view = TrackingView(self.link) self.solution_view = SolutionView(self.link) self.baseline_view = BaselineView(self.link) self.observation_view = ObservationView(self.link, name='Rover', relay=False) self.observation_view_base = ObservationView(self.link, name='Base', relay=True) self.system_monitor_view = SystemMonitorView(self.link) self.update_view = UpdateView(self.link, prompt=update) settings_read_finished_functions.append(self.update_view.compare_versions) self.settings_view = \ SettingsView(self.link, settings_read_finished_functions) self.update_view.settings = self.settings_view.settings self.python_console_env = { 'send_message': self.link.send_message, 'link': self.link, } self.python_console_env.update(self.tracking_view.python_console_cmds) self.python_console_env.update(self.solution_view.python_console_cmds) self.python_console_env.update(self.baseline_view.python_console_cmds) self.python_console_env.update(self.observation_view.python_console_cmds) self.python_console_env.update(self.system_monitor_view.python_console_cmds) self.python_console_env.update(self.update_view.python_console_cmds) self.python_console_env.update(self.settings_view.python_console_cmds) except: import traceback traceback.print_exc() def stop(self): self.link.close() if self.log_file: self.log_file.close()
UItem("source", style="custom"), HGroup( spring, UItem("handler.run_button", ), visible_when="source is not None", ), ), Tabbed( Item("log", style="readonly", editor=CodeEditor(show_line_numbers=False, selected_color=0xFFFFFF), label="Output", show_label=False), Item("locals", editor=ShellEditor(share=True), label="Shell", show_label=False), UItem( "demo", style="custom", resizable=True, ), ), dock="horizontal", ), ), id="demo_file_view", handler=demo_file_handler, kind='subpanel', )
class PythonShellView(HasTraits): ns = Dict() view = View(Item('ns', editor=ShellEditor(), show_label=False))
class PythonShellView(HasTraits): ns = Dict() view = View(Item('ns', editor=ShellEditor(), show_label=False), id='pysph.mayavi_viewer.python_shell_view')
class SwiftConsole(HasTraits): link = Instance(serial_link.SerialLink) console_output = Instance(OutputStream) python_console_env = Dict a = Int b = Int tracking_view = Instance(TrackingView) almanac_view = Instance(AlmanacView) solution_view = Instance(SolutionView) baseline_view = Instance(BaselineView) observation_view = Instance(ObservationView) observation_view_base = Instance(ObservationView) system_monitor_view = Instance(SystemMonitorView) simulator_view = Instance(SimulatorView) settings_view = Instance(SettingsView) view = View(VSplit( Tabbed(Item('tracking_view', style='custom', label='Tracking'), Item('almanac_view', style='custom', label='Almanac'), Item('solution_view', style='custom', label='Solution'), Item('baseline_view', style='custom', label='Baseline'), VSplit( Item('observation_view', style='custom', show_label=False), Item('observation_view_base', style='custom', show_label=False), label='Observations', ), Item('simulator_view', style='custom', label='Simulator'), Item('settings_view', style='custom', label='Settings'), Item('system_monitor_view', style='custom', label='System Monitor'), Item('python_console_env', style='custom', label='Python Console', editor=ShellEditor()), show_labels=False), Item( 'console_output', style='custom', editor=InstanceEditor(), height=0.3, show_label=False, ), ), icon=icon, resizable=True, width=900, height=600, title='Piksi Console, Version: ' + CONSOLE_VERSION) def print_message_callback(self, data): try: self.console_output.write(data.encode('ascii', 'ignore')) except UnicodeDecodeError: print "Oh crap!" def debug_var_callback(self, data): x = struct.unpack('<d', data[:8])[0] name = data[8:] print "VAR: %s = %d" % (name, x) def __init__(self, *args, **kwargs): try: update = kwargs.pop('update') except KeyError: update = True self.console_output = OutputStream() sys.stdout = self.console_output sys.stderr = self.console_output try: self.link = serial_link.SerialLink(*args, **kwargs) self.link.add_callback(ids.PRINT, self.print_message_callback) self.link.add_callback(ids.DEBUG_VAR, self.debug_var_callback) settings_read_finished_functions = [] self.tracking_view = TrackingView(self.link) self.almanac_view = AlmanacView(self.link) self.solution_view = SolutionView(self.link) self.baseline_view = BaselineView(self.link) self.observation_view = ObservationView(self.link, name='Rover', relay=False) self.observation_view_base = ObservationView(self.link, name='Base', relay=True) self.system_monitor_view = SystemMonitorView(self.link) self.simulator_view = SimulatorView(self.link) self.settings_view = SettingsView(self.link) if update: self.ocu = OneClickUpdate(self.link, self.console_output) settings_read_finished_functions.append(self.ocu.start) self.settings_view = \ SettingsView(self.link, settings_read_finished_functions) if update: self.ocu.point_to_settings(self.settings_view.settings) self.python_console_env = { 'send_message': self.link.send_message, 'link': self.link, } self.python_console_env.update( self.tracking_view.python_console_cmds) self.python_console_env.update( self.almanac_view.python_console_cmds) self.python_console_env.update( self.solution_view.python_console_cmds) self.python_console_env.update( self.baseline_view.python_console_cmds) self.python_console_env.update( self.observation_view.python_console_cmds) self.python_console_env.update( self.system_monitor_view.python_console_cmds) except: import traceback traceback.print_exc() def stop(self): self.link.close()
class CvuGUI(ErrorHandler, DatasetViewportInterface): controller = Instance(Controller) def _mayavi_port_default(self): return Viewport(self.controller.ds_orig, view_type='3D Brain') def _matrix_port_default(self): return Viewport(self.controller.ds_orig, view_type='Connection Matrix') def _circle_port_default(self): return Viewport(self.controller.ds_orig, view_type='Circular plot') options_window = Instance(dialogs.InteractiveSubwindow) adjmat_chooser_window = Instance(dialogs.InteractiveSubwindow) parcellation_chooser_window = Instance(dialogs.InteractiveSubwindow) tractography_chooser_window = Instance(dialogs.InteractiveSubwindow) node_chooser_window = Instance(dialogs.InteractiveSubwindow) module_chooser_window = Instance(dialogs.InteractiveSubwindow) module_customizer_window = Instance(dialogs.InteractiveSubwindow) graph_theory_window = Instance(dialogs.InteractiveSubwindow) configure_scalars_window = Instance(dialogs.InteractiveSubwindow) save_snapshot_window = Instance(dialogs.InteractiveSubwindow) make_movie_window = Instance(dialogs.InteractiveSubwindow) really_overwrite_file_window = Instance(dialogs.InteractiveSubwindow) calculate_window = Instance(dialogs.InteractiveSubwindow) color_legend_window = Instance(dialogs.InteractiveSubwindow) #load_tractography_window load_standalone_matrix_window = Instance(dialogs.InteractiveSubwindow) select_node_button = Button('Choose node') display_all_button = Button('Reset Displays') graph_theory_button = Button('Show statistics') calculate_button = Button('Calculate stats') #load_module_button = Button('Load module') select_module_button = Button('View module') custom_module_button = Button('Custom subset') display_scalars_button = Button('Show scalars') #load_scalars_button = Button('Load scalars') load_standalone_button = Button('Load stats') load_adjmat_button = Button('Load an adjacency matrix') #force_render_button = Button('Force render') color_legend_button = Button('Color legend') load_parcellation_button = Button('Load a parcellation') options_button = Button('Options') controller_button = Button('Manage views') load_tractography_button = Button('Load tractography') save_snapshot_button = Button('Take snapshot') make_movie_button = Button currently_making_movie = Bool(False) mk_movie_lbl = Property(depends_on='currently_making_movie') def _get_mk_movie_lbl(self): return 'Stop movie' if self.currently_making_movie else 'Make movie' about_button = Button('About') manage_views_button = Button('Manage views') python_shell = Dict traits_view = View( VSplit( HSplit( Item( name='mayavi_port', height=500, width=500, editor=InstanceEditor(view='mayavi_view'), show_label=False, style='custom', resizable=True, ), Item( name='matrix_port', height=500, width=500, editor=InstanceEditor(view='matrix_view'), show_label=False, style='custom', resizable=True, ), Group( Spring(), Item(name='select_node_button'), Item(name='display_all_button'), Item(name='color_legend_button'), Spring(), Item(name='calculate_button'), Item(name='load_standalone_button'), Item(name='graph_theory_button'), Item(name='display_scalars_button'), Item(name='select_module_button'), Item(name='custom_module_button'), Spring(), #Item(name='force_render_button'), show_labels=False, )), HSplit( Item( name='circle_port', height=500, width=500, editor=InstanceEditor(view='circle_view'), show_label=False, style='custom', resizable=True, ), Group( HSplit( Item(name='load_parcellation_button', ), Item(name='load_adjmat_button', ), Item(name='load_tractography_button', ), show_labels=False, ), HSplit( Item(name='save_snapshot_button'), Item(name='make_movie_button', editor=ButtonEditor(label_value='mk_movie_lbl')), Item(name='options_button', ), Item(name='controller_button', ), Item(name='about_button'), show_labels=False, ), HSplit( Item(name='python_shell', editor=ShellEditor(), height=450, show_label=False), ), ), ), ), resizable=True, title="Connectome Visualization Utility") def __init__(self, sample_data, sample_metadata, quiet=False, **kwargs): super(HasTraits, self).__init__(quiet=quiet, **kwargs) ctrl = self.controller = Controller(self, sample_data, sample_metadata) ds_orig = self.controller.ds_orig #these dialogs exist strictly in the gui and have no control item #they do not extend interactivesubwindow self.error_dialog_window = dialogs.ErrorDialogWindow() self.warning_dialog_window = dialogs.WarningDialogWindow() self.about_window = dialogs.AboutWindow() self.really_overwrite_file_window = dialogs.ReallyOverwriteFileWindow() self.options_window = dialogs.OptionsWindow(ds_orig.opts, ctrl) self.configure_scalars_window = dialogs.ConfigureScalarsWindow( ds_orig.scalar_display_settings, ctrl) self.calculate_window = dialogs.CalculateWindow( ctrl.options_db.calculate_parameters, ctrl) self.adjmat_chooser_window = dialogs.AdjmatChooserWindow( ctrl.options_db.adjmat_chooser_parameters, ctrl) self.parcellation_chooser_window = dialogs.ParcellationChooserWindow( ctrl.options_db.parcellation_chooser_parameters, ctrl) self.tractography_chooser_window = dialogs.TractographyChooserWindow( ctrl.options_db.tractography_chooser_parameters, ctrl) self.load_standalone_matrix_window = dialogs.LoadGeneralMatrixWindow( ctrl.options_db.general_matrix_chooser_parameters, ctrl) self.node_chooser_window = dialogs.NodeChooserWindow( ctrl.options_db.node_chooser_parameters, ctrl) self.module_chooser_window = dialogs.ModuleChooserWindow( ctrl.options_db.module_chooser_parameters, ctrl) self.module_customizer_window = dialogs.ModuleCustomizerWindow( ctrl.options_db.module_customizer_parameters, ctrl) self.graph_theory_window = dialogs.GraphTheoryWindow( ctrl.options_db.graph_theory_parameters, ctrl) self.color_legend_window = dialogs.ColorLegendWindow( ctrl.options_db.color_legend_parameters, ctrl) self.save_snapshot_window = dialogs.SaveSnapshotWindow( ctrl.options_db.snapshot_parameters, ctrl) self.make_movie_window = dialogs.MakeMovieWindow( ctrl.options_db.make_movie_parameters, ctrl) self.panel_name = 'base_gui' def error_dialog(self, message): self.error_dialog_window.stacktrace = None _, _, tb = sys.exc_info() if tb is not None: self.error_dialog_window.stacktrace = tb self.error_dialog_window.error = message self.error_dialog_window.edit_traits() def warning_dialog(self, message): self.warning_dialog_window.warning = message self.warning_dialog_window.edit_traits() def reset_controls(self, ds_match): for window in ( self.load_standalone_matrix_window, self.adjmat_chooser_window, self.node_chooser_window, self.parcellation_chooser_window, self.module_chooser_window, self.module_customizer_window, self.graph_theory_window, self.save_snapshot_window, self.make_movie_window, self.calculate_window, self.color_legend_window, self.configure_scalars_window, self.options_window, ): if window.ctl.ds_ref is ds_match or window.ctl.ds_ref is None: window._current_dataset_list = [self.controller.ds_orig] ###################################################################### # BUTTONS AND INTERACTIONS ###################################################################### def _display_all_button_fired(self): for ds in self.controller.ds_instances.values(): ds.display_all() def _options_button_fired(self): self.options_window.finished = False self.options_window.edit_traits() def _load_parcellation_button_fired(self): self.parcellation_chooser_window.finished = False self.parcellation_chooser_window.edit_traits() @on_trait_change('parcellation_chooser_window:notify') def _load_parcellation_check(self): pcw = self.parcellation_chooser_window if not pcw.finished: return if pcw.ctl.new_dataset: if pcw.ctl.new_dataset_name == '': self.error_dialog('Must specify a dataset name!') return elif pcw.ctl.new_dataset_name in self.controller.ds_instances: self.error_dialog('Dataset name is not unique') return else: ds_name = pcw.ctl.new_dataset_name import preprocessing parc_struct = preprocessing.process_parc(pcw.ctl, self) if parc_struct is None: return #preprocessing errored out lab_pos, labnam, srf, labv, subject_name, parc_name = parc_struct display_metadata = DisplayMetadata(subject_name=subject_name, parc_name=parc_name, adj_filename='') ds = Dataset(ds_name, lab_pos, labnam, srf, labv, gui=self) self.controller.add_dataset(ds, display_metadata) else: import preprocessing parc_struct = preprocessing.process_parc(pcw.ctl, self) if parc_struct is None: return lab_pos, labnam, srf, labv, subject_name, parc_name = parc_struct pcw.ctl.ds_ref._load_parc(lab_pos, labnam, srf, labv) self.controller.update_display_metadata(pcw.ctl.ds_ref.name, subject_name=subject_name, parc_name=parc_name) #find the viewports that were previously holding this scene #find_dataset_views returns a DatasetViewportInterface object #with references to the viewports (source in viewport.py) ds_interface = self.controller.find_dataset_views(pcw.ctl.ds_ref) ds_interface.mayavi_port = Viewport(pcw.ctl.ds_ref) ds_interface.matrix_port = Viewport(pcw.ctl.ds_ref) ds_interface.circle_port = Viewport(pcw.ctl.ds_ref) def _load_adjmat_button_fired(self): self.adjmat_chooser_window.finished = False self.adjmat_chooser_window.edit_traits() @on_trait_change('adjmat_chooser_window:notify') def _load_adjmat_check(self): acw = self.adjmat_chooser_window if not acw.finished: return import preprocessing as pp adj_struct = pp.process_adj(acw.ctl, self) if adj_struct is None: return #preprocessing returned an error adj, soft_max_edges, adj_filename = adj_struct acw.ctl.ds_ref._load_adj(adj, soft_max_edges, acw.ctl.require_ls, acw.ctl.suppress_extra_rois) self.controller.update_display_metadata(acw.ctl.ds_ref.name, adj_filename=adj_filename) def _load_tractography_button_fired(self): self.tractography_chooser_window.finished = False self.tractography_chooser_window.edit_traits() @on_trait_change('tractography_chooser_window:notify') def _load_tractography_check(self): tcw = self.tractography_chooser_window if not tcw.finished: return tcw.ctl.ds_ref.load_tractography(tcw.ctl) def _load_standalone_button_fired(self): self.load_standalone_matrix_window.finished = False self.load_standalone_matrix_window.edit_traits() @on_trait_change('load_standalone_matrix_window:notify') def _load_standalone_check(self): lsmw = self.load_standalone_matrix_window if not lsmw.finished: return lsmw.ctl.ds_ref.load_modules_or_scalars(lsmw.ctl) def _display_scalars_button_fired(self): #more checking required. should make sure scalars exist first. csw = self.configure_scalars_window csw.finished = False #csw.ctl.reset_configuration() self.configure_scalars_window.edit_traits() @on_trait_change('configure_scalars_window:notify') def _display_scalars_check(self): csw = self.configure_scalars_window if not csw.finished or (not any( (csw.ctl.node_color, csw.ctl.surf_color, csw.ctl.node_size, csw.ctl.circle, csw.ctl.connmat))): return csw.ctl.ds_ref.display_scalars() def _select_node_button_fired(self): self.node_chooser_window.finished = False self.node_chooser_window.edit_traits() @on_trait_change('node_chooser_window:notify') def _select_node_check(self): ncw = self.node_chooser_window if not ncw.finished: return ncw.ctl.ds_ref.display_node(ncw.ctl.cur_node) def _calculate_button_fired(self): cw = self.calculate_window cw.finished = False cw.edit_traits() @on_trait_change('calculate_window:notify') def _calculation_check(self): cw = self.calculate_window if not cw.finished: return if cw.ctl.ds_ref.adj is None: self.error_dialog("There is no adjacency matrix loaded") return if cw.ctl.thresh_type == 'abs': thres = cw.ctl.athresh elif cw.ctl.thresh_type == 'prop': if cw.ctl.pthresh == 0.: thres = -np.inf else: thres = cw.ctl.ds_ref.adjdat[int( round(cw.ctl.pthresh * cw.ctl.ds_ref.nr_edges - 1))] if cw.ctl.calculation_type == 'modules': cw.ctl.ds_ref.calculate_modules(thres) cw.ctl.ds_ref.display_multi_module() elif cw.ctl.calculation_type == 'statistics': (Thread(target=cw.ctl.ds_ref.calculate_graph_stats, args=(thres, ))).start() def _select_module_button_fired(self): self.module_chooser_window.finished = False self.module_chooser_window.edit_traits() @on_trait_change('module_chooser_window:notify') def _select_module_check(self): mcw = self.module_chooser_window if not mcw.finished or mcw.ctl.cur_mod == -1: return else: mcw.ctl.ds_ref.display_module(mcw.ctl.cur_mod) def _custom_module_button_fired(self): self.module_customizer_window.finished = False self.module_customizer_window.edit_traits() @on_trait_change('module_customizer_window:notify') def _module_customizer_check(self): mcw = self.module_customizer_window if not mcw.finished: return try: mcw.ctl._index_convert() except ValueError: self.error_dialog('Internal error: bad index conversion') return mcw.ctl.ds_ref.custom_module = mcw.ctl.return_module mcw.ctl.ds_ref.display_module('custom') def _graph_theory_button_fired(self): #more checking required. should make sure stats exist first self.graph_theory_window.finished = False self.graph_theory_window.edit_traits() def _color_legend_button_fired(self): self.color_legend_window.edit_traits() def _save_snapshot_button_fired(self): self.save_snapshot_window.finished = False self.save_snapshot_window.edit_traits() @on_trait_change('save_snapshot_window:notify') def _save_snapshot_check(self): ssw = self.save_snapshot_window if not ssw.finished: return save_continuation = ssw.ctl.ds_ref.snapshot(ssw.ctl) self.process_save_continuation(ssw.ctl.savefile, save_continuation) #elif not ssw.ctl.savefile: # self.error_dialog('You must specify a filename to save to') # return #else: # save_continuation = ssw.ctl.ds_ref.snapshot(ssw.ctl) # if not os.path.exists(os.path.dirname(ssw.ctl.savefile)): # self.error_dialog('Bad path specified. Check for typo?') # elif not os.path.exists(ssw.ctl.savefile): # save_continuation() # else: # rofw = self.really_overwrite_file_window # rofw.save_continuation = save_continuation # rofw.finished=False # rofw.edit_traits() def _make_movie_button_fired(self): if not self.currently_making_movie: self.make_movie_window.finished = False self.make_movie_window.edit_traits() else: self.currently_making_movie = False mmw = self.make_movie_window mmw.ctl.ds_ref.make_movie_finish(mmw.ctl) @on_trait_change('make_movie_window:notify') def make_movie_check(self): mmw = self.make_movie_window if not mmw.finished: return movie_continuation = mmw.ctl.ds_ref.make_movie(mmw.ctl) def save_continuation(): self.currently_making_movie = True movie_continuation() self.process_save_continuation(mmw.ctl.savefile, save_continuation) @on_trait_change('really_overwrite_file_window:notify') def _really_overwrite_file_check(self): rofw = self.really_overwrite_file_window #if the user clicks ok, call the save continuation if rofw.finished: rofw.save_continuation() #otherwise, dont do anything def process_save_continuation(self, filename, save_continuation): if not filename: self.error_dialog("No save file specified") return elif not os.path.exists(os.path.dirname(filename)): self.error_dialog("Bad save file specified. Check for typos.") return elif not os.path.exists(filename): save_continuation() else: rofw = self.really_overwrite_file_window rofw.save_continuation = save_continuation rofw.finished = False rofw.edit_traits() def _controller_button_fired(self): self.controller.viewport_manager.edit_traits() def _about_button_fired(self): self.about_window.edit_traits()
class SwiftConsole(HasTraits): link = Instance(serial_link.SerialLink) console_output = Instance(OutputStream) python_console_env = Dict a = Int b = Int tracking_view = Instance(TrackingView) almanac_view = Instance(AlmanacView) solution_view = Instance(SolutionView) view = View(VSplit( Tabbed( Item('solution_view', style='custom', show_label=False), Item('tracking_view', style='custom', show_label=False), Item('tracking_view', style='custom', show_label=False, editor=InstanceEditor(view='snr_line_view')), Item('solution_view', style='custom', show_label=False, editor=InstanceEditor(view='prs_view')), Item('almanac_view', style='custom', show_label=False), ), HSplit(Item('python_console_env', editor=ShellEditor()), Item('console_output', style='custom', editor=InstanceEditor()), Item('tracking_view', style='custom', editor=InstanceEditor(view='snr_bar_view')), show_labels=False)), resizable=True, width=1000, height=600) def print_message_callback(self, data): try: self.console_output.write(data.encode('ascii', 'ignore')) except UnicodeDecodeError: print "Oh crap!" def __init__(self, port=serial_link.DEFAULT_PORT): self.console_output = OutputStream() self.link = serial_link.SerialLink(port) self.link.add_callback(serial_link.MSG_PRINT, self.print_message_callback) self.tracking_view = TrackingView(self.link) self.almanac_view = AlmanacView(self.link) self.solution_view = SolutionView(self.link) self.flash = flash.Flash(self.link) self.flash.start() self.python_console_env = { 'send_message': self.link.send_message, 'link': self.link, 'flash': self.flash } self.python_console_env.update(self.tracking_view.python_console_cmds) self.python_console_env.update(self.almanac_view.python_console_cmds) self.python_console_env.update(self.solution_view.python_console_cmds) def stop(self): self.flash.stop() self.link.close()
class SwiftConsole(HasTraits): """Traits-defined Swift Console. link : object Serial driver update : bool Update the firmware log_level_filter : str Syslog string, one of "ERROR", "WARNING", "INFO", "DEBUG". skip_settings : bool Don't read the device settings. Set to False when the console is reading from a network connection only. """ link = Instance(sbpc.Handler) console_output = Instance(OutputList()) python_console_env = Dict device_serial = Str('') a = Int b = Int tracking_view = Instance(TrackingView) solution_view = Instance(SolutionView) baseline_view = Instance(BaselineView) observation_view = Instance(ObservationView) networking_view = Instance(SbpRelayView) observation_view_base = Instance(ObservationView) system_monitor_view = Instance(SystemMonitorView) settings_view = Instance(SettingsView) update_view = Instance(UpdateView) log_level_filter = Enum(list(SYSLOG_LEVELS.itervalues())) """" mode : baseline and solution view - SPP, Fixed or Float num_sat : baseline and solution view - number of satellites port : which port is Piksi connected to directory_name : location of logged files json_logging : enable JSON logging csv_logging : enable CSV logging is_valid_directory : check to see if chosen directory is valid """ mode = Str('') num_sats = Int(0) port = Str('') directory_name = Directory json_logging = Bool(True) csv_logging = Bool(False) is_valid_directory = Bool(True) csv_logging_button = SVGButton( toggle=True, label='CSV log', tooltip='start CSV logging', toggle_tooltip='stop CSV logging', filename=os.path.join(determine_path(), 'images', 'iconic', 'pause.svg'), toggle_filename=os.path.join(determine_path(), 'images', 'iconic', 'play.svg'), orientation='vertical', width=2, height=2, ) json_logging_button = SVGButton( toggle=True, label='JSON log', tooltip='start JSON logging', toggle_tooltip='stop JSON logging', filename=os.path.join(determine_path(), 'images', 'iconic', 'pause.svg'), toggle_filename=os.path.join(determine_path(), 'images', 'iconic', 'play.svg'), orientation='vertical', width=2, height=2, ) paused_button = SVGButton(label='', tooltip='Pause console update', toggle_tooltip='Resume console update', toggle=True, filename=os.path.join(determine_path(), 'images', 'iconic', 'pause.svg'), toggle_filename=os.path.join( determine_path(), 'images', 'iconic', 'play.svg'), width=8, height=8) clear_button = SVGButton(label='', tooltip='Clear console buffer', filename=os.path.join(determine_path(), 'images', 'iconic', 'x.svg'), width=8, height=8) view = View(VSplit( Tabbed(Item('tracking_view', style='custom', label='Tracking'), Item('solution_view', style='custom', label='Solution'), Item('baseline_view', style='custom', label='Baseline'), VSplit( Item('observation_view', style='custom', show_label=False), Item('observation_view_base', style='custom', show_label=False), label='Observations', ), Item('settings_view', style='custom', label='Settings'), Item('update_view', style='custom', label='Firmware Update'), Tabbed(Item('system_monitor_view', style='custom', label='System Monitor'), Item('networking_view', label='Networking', style='custom', show_label=False), Item('python_console_env', style='custom', label='Python Console', editor=ShellEditor()), label='Advanced', show_labels=False), show_labels=False), VGroup( VGroup( HGroup( Spring(width=4, springy=False), Item('paused_button', show_label=False, padding=0, width=8, height=8), Item('clear_button', show_label=False, width=8, height=8), Item('', label='Console Log', emphasized=True), Item('csv_logging_button', emphasized=True, show_label=False, width=12, height=-30, padding=0), Item('json_logging_button', emphasized=True, show_label=False, width=12, height=-30, padding=0), Item( 'directory_name', show_label=False, springy=True, tooltip= 'Choose location for file logs. Default is home/SwiftNav.', height=-25, enabled_when='not(json_logging or csv_logging)'), UItem( 'log_level_filter', style='simple', padding=0, height=8, show_label=True, tooltip= 'Show log levels up to and including the selected level of severity.\nThe CONSOLE log level is always visible.' ), ), Item('console_output', style='custom', editor=InstanceEditor(), height=125, show_label=False, full_size=True), ), HGroup( Spring(width=4, springy=False), Item('', label='PORT:', emphasized=True, tooltip='Serial Port that Piksi is connected to'), Item('port', show_label=False, style='readonly'), Item('', label='FIX TYPE:', emphasized=True, tooltip='Piksi Mode: SPS, Float RTK, Fixed RTK'), Item('mode', show_label=False, style='readonly'), Item('', label='#SATS:', emphasized=True, tooltip='Number of satellites acquired by Piksi'), Item('num_sats', padding=2, show_label=False, style='readonly'), ), Spring(height=1, springy=False), ), ), icon=icon, resizable=True, width=800, height=600, handler=ConsoleHandler(), title=CONSOLE_TITLE) def print_message_callback(self, sbp_msg, **metadata): try: encoded = sbp_msg.payload.encode('ascii', 'ignore') for eachline in reversed(encoded.split('\n')): self.console_output.write_level( eachline, str_to_log_level(eachline.split(':')[0])) except UnicodeDecodeError: print "Critical Error encoding the serial stream as ascii." def log_message_callback(self, sbp_msg, **metadata): try: encoded = sbp_msg.text.encode('ascii', 'ignore') for eachline in reversed(encoded.split('\n')): self.console_output.write_level(eachline, sbp_msg.level) except UnicodeDecodeError: print "Critical Error encoding the serial stream as ascii." def ext_event_callback(self, sbp_msg, **metadata): e = MsgExtEvent(sbp_msg) print 'External event: %s edge on pin %d at wn=%d, tow=%d, time qual=%s' % ( "Rising" if (e.flags & (1 << 0)) else "Falling", e.pin, e.wn, e.tow, "good" if (e.flags & (1 << 1)) else "unknown") def _paused_button_fired(self): self.console_output.paused = not self.console_output.paused def _log_level_filter_changed(self): """ Takes log level enum and translates into the mapped integer. Integer stores the current filter value inside OutputList. """ self.console_output.log_level_filter = str_to_log_level( self.log_level_filter) def _clear_button_fired(self): self.console_output.clear() def _directory_name_changed(self): if os.path.isdir(self.directory_name): self.is_valid_directory = True if self.baseline_view and self.solution_view: self.baseline_view.directory_name_b = self.directory_name self.solution_view.directory_name_p = self.directory_name self.solution_view.directory_name_v = self.directory_name if self.observation_view and self.observation_view_base: self.observation_view.dirname = self.directory_name self.observation_view_base.dirname = self.directory_name else: print "Please enter a valid directory!" self.is_valid_directory = False def update_on_heartbeat(self, sbp_msg, **metadata): # First initialize the state to nothing, if we can't update, it will be none temp_mode = "None" temp_num_sats = 0 view = None # If we have a recent baseline update, we use the baseline info if time.time() - self.baseline_view.last_btime_update < 10: view = self.baseline_view # Otherwise, if we have a recent SPP update, we use the SPP elif time.time() - self.solution_view.last_stime_update < 10: view = self.solution_view if view: if view.last_soln: # if all is well we update state temp_mode = view.mode_string(view.last_soln) temp_num_sats = view.last_soln.n_sats self.mode = temp_mode self.num_sats = temp_num_sats if self.settings_view: # for auto populating surveyed fields self.settings_view.lat = self.solution_view.latitude self.settings_view.lon = self.solution_view.longitude self.settings_view.alt = self.solution_view.altitude def _csv_logging_button_fired(self): if self.is_valid_directory: if self.csv_logging and self.baseline_view.logging_b and self.solution_view.logging_p and self.solution_view.logging_v: print "Stopped CSV logging" self.csv_logging = False self.baseline_view.logging_b = False self.solution_view.logging_p = False self.solution_view.logging_v = False else: print "Started CSV logging at %s" % self.directory_name self.csv_logging = True self.baseline_view.logging_b = True self.solution_view.logging_p = True self.solution_view.logging_v = True else: print "Directory not valid" def _start_json_logging(self, override_filename=None): if override_filename: filename = override_filename else: filename = s.logfilename() filename = os.path.normpath(os.path.join(self.directory_name, filename)) self.logger = s.get_logger(True, filename) self.forwarder = sbpc.Forwarder(self.link, self.logger) self.forwarder.start() def _stop_json_logging(self): fwd = self.forwarder fwd.stop() self.logger.flush() self.logger.close() def _json_logging_button_fired(self): if self.is_valid_directory: if self.first_json_press and self.json_logging: print "JSON Logging initiated via CMD line. Please press button again to stop logging" elif self.json_logging: self._stop_json_logging() self.json_logging = False print "Stopped JSON logging" else: self._start_json_logging() self.json_logging = True self.first_json_press = False else: print "Directory not valid" def __init__(self, link, update, log_level_filter, skip_settings=False, error=False, port=None, json_logging=False, log_dirname=None): self.console_output = OutputList() self.console_output.write("Console: starting...") self.error = error sys.stdout = self.console_output self.port = port self.num_sats = 0 self.mode = '' self.forwarder = None # if we have passed a logfile, we set our directory to it override_filename = None swift_path = None home = expanduser("~") swift_path = os.path.normpath(os.path.join(home, 'SwiftNav')) try: os.makedirs(swift_path) except OSError: if not os.path.isdir(swift_path): raise if log_dirname: self.directory_name = log_dirname else: self.directory_name = swift_path if not error: sys.stderr = self.console_output self.log_level_filter = log_level_filter self.console_output.log_level_filter = str_to_log_level( log_level_filter) try: self.link = link self.link.add_callback(self.print_message_callback, SBP_MSG_PRINT_DEP) self.link.add_callback(self.log_message_callback, SBP_MSG_LOG) self.link.add_callback(self.ext_event_callback, SBP_MSG_EXT_EVENT) self.link.add_callback(self.update_on_heartbeat, SBP_MSG_HEARTBEAT) self.dep_handler = DeprecatedMessageHandler(link) settings_read_finished_functions = [] self.tracking_view = TrackingView(self.link) self.solution_view = SolutionView(self.link, dirname=self.directory_name) self.baseline_view = BaselineView(self.link, dirname=self.directory_name) self.observation_view = ObservationView( self.link, name='Local', relay=False, dirname=self.directory_name) self.observation_view_base = ObservationView( self.link, name='Remote', relay=True, dirname=self.directory_name) self.system_monitor_view = SystemMonitorView(self.link) self.update_view = UpdateView(self.link, prompt=update) settings_read_finished_functions.append( self.update_view.compare_versions) self.networking_view = SbpRelayView(self.link) self.json_logging = json_logging self.csv_logging = False self.first_json_press = True if json_logging: self._start_json_logging(override_filename) self.json_logging = True # Once we have received the settings, update device_serial with # the Piksi serial number which will be displayed in the window # title. This callback will also update the header route as used # by the networking view. def update_serial(): serial_string = self.settings_view.settings['system_info'][ 'serial_number'].value self.device_serial = 'PK%04d' % int(serial_string) if serial_string: self.networking_view.set_route(int(serial_string)) settings_read_finished_functions.append(update_serial) self.settings_view = SettingsView(self.link, settings_read_finished_functions, skip=skip_settings) self.update_view.settings = self.settings_view.settings self.python_console_env = { 'send_message': self.link, 'link': self.link, } self.python_console_env.update( self.tracking_view.python_console_cmds) self.python_console_env.update( self.solution_view.python_console_cmds) self.python_console_env.update( self.baseline_view.python_console_cmds) self.python_console_env.update( self.observation_view.python_console_cmds) self.python_console_env.update( self.networking_view.python_console_cmds) self.python_console_env.update( self.system_monitor_view.python_console_cmds) self.python_console_env.update( self.update_view.python_console_cmds) self.python_console_env.update( self.settings_view.python_console_cmds) except: import traceback traceback.print_exc() if self.error: sys.exit(1)
class SwiftConsole(HasTraits): link = Instance(sbp.client.handler.Handler) console_output = Instance(OutputStream) python_console_env = Dict device_serial = Str('') a = Int b = Int tracking_view = Instance(TrackingView) solution_view = Instance(SolutionView) baseline_view = Instance(BaselineView) observation_view = Instance(ObservationView) observation_view_base = Instance(ObservationView) system_monitor_view = Instance(SystemMonitorView) settings_view = Instance(SettingsView) update_view = Instance(UpdateView) paused_button = SVGButton( label='', tooltip='Pause console update', toggle_tooltip='Resume console update', toggle=True, filename=os.path.join(os.path.dirname(__file__), 'images', 'iconic', 'pause.svg'), toggle_filename=os.path.join(os.path.dirname(__file__), 'images', 'iconic', 'play.svg'), width=8, height=8 ) clear_button = SVGButton( label='', tooltip='Clear console buffer', filename=os.path.join(os.path.dirname(__file__), 'images', 'iconic', 'x.svg'), width=8, height=8 ) view = View( VSplit( Tabbed( Item('tracking_view', style='custom', label='Tracking'), Item('solution_view', style='custom', label='Solution'), Item('baseline_view', style='custom', label='Baseline'), VSplit( Item('observation_view', style='custom', show_label=False), Item('observation_view_base', style='custom', show_label=False), label='Observations', ), Item('settings_view', style='custom', label='Settings'), Item('update_view', style='custom', label='Firmware Update'), Item('system_monitor_view', style='custom', label='System Monitor'), Item( 'python_console_env', style='custom', label='Python Console', editor=ShellEditor() ), show_labels=False ), VGroup( HGroup( Item('', show_label=False), Item('paused_button', show_label=False), Item('clear_button', show_label=False), Item('', label='Console Log', emphasized=True), ), Item( 'console_output', style='custom', editor=InstanceEditor(), height=0.3, show_label=False, ), ) ), icon = icon, resizable = True, width = 1000, height = 600, handler = ConsoleHandler(), title = CONSOLE_TITLE ) def print_message_callback(self, sbp_msg): try: self.console_output.write(sbp_msg.payload.encode('ascii', 'ignore')) except UnicodeDecodeError: print "Critical Error encoding the serial stream as ascii." def ext_event_callback(self, sbp_msg): e = MsgExtEvent(sbp_msg) print 'External event: %s edge on pin %d at wn=%d, tow=%d, time qual=%s' % ( "Rising" if (e.flags & (1<<0)) else "Falling", e.pin, e.wn, e.tow, "good" if (e.flags & (1<<1)) else "unknown") def debug_var_callback(self, sbp_msg): x = struct.unpack('<d', sbp_msg.payload[:8])[0] name = sbp_msg.payload[8:] print "VAR: %s = %d" % (name, x) def _paused_button_fired(self): self.console_output.paused = not self.console_output.paused def _clear_button_fired(self): self.console_output.reset() def __init__(self, link, update): self.console_output = OutputStream() sys.stdout = self.console_output sys.stderr = self.console_output try: self.link = link self.link.add_callback(self.print_message_callback, SBP_MSG_PRINT) self.link.add_callback(self.debug_var_callback, SBP_MSG_DEBUG_VAR) self.link.add_callback(self.ext_event_callback, SBP_MSG_EXT_EVENT) self.link.start() settings_read_finished_functions = [] self.tracking_view = TrackingView(self.link) self.solution_view = SolutionView(self.link) self.baseline_view = BaselineView(self.link) self.observation_view = ObservationView(self.link, name='Rover', relay=False) self.observation_view_base = ObservationView(self.link, name='Base', relay=True) self.system_monitor_view = SystemMonitorView(self.link) self.update_view = UpdateView(self.link, prompt=update) settings_read_finished_functions.append(self.update_view.compare_versions) # Once we have received the settings, update device_serial with the Piksi # serial number which will be displayed in the window title def update_serial(): serial_string = self.settings_view.settings['system_info']['serial_number'].value self.device_serial = 'PK%04d' % int(serial_string) settings_read_finished_functions.append(update_serial) self.settings_view = \ SettingsView(self.link, settings_read_finished_functions) self.update_view.settings = self.settings_view.settings self.python_console_env = { 'send_message': self.link.send, 'link': self.link, } self.python_console_env.update(self.tracking_view.python_console_cmds) self.python_console_env.update(self.solution_view.python_console_cmds) self.python_console_env.update(self.baseline_view.python_console_cmds) self.python_console_env.update(self.observation_view.python_console_cmds) self.python_console_env.update(self.system_monitor_view.python_console_cmds) self.python_console_env.update(self.update_view.python_console_cmds) self.python_console_env.update(self.settings_view.python_console_cmds) except: import traceback traceback.print_exc()
class SwiftConsole(HasTraits): link = Instance(sbp.client.Handler) console_output = Instance(OutputList()) python_console_env = Dict device_serial = Str('') a = Int b = Int tracking_view = Instance(TrackingView) solution_view = Instance(SolutionView) baseline_view = Instance(BaselineView) observation_view = Instance(ObservationView) sbp_relay_view = Instance(SbpRelayView) observation_view_base = Instance(ObservationView) system_monitor_view = Instance(SystemMonitorView) settings_view = Instance(SettingsView) update_view = Instance(UpdateView) log_level_filter = Enum(list(SYSLOG_LEVELS.itervalues())) paused_button = SVGButton( label='', tooltip='Pause console update', toggle_tooltip='Resume console update', toggle=True, filename=os.path.join(os.path.dirname(__file__), 'images', 'iconic', 'pause.svg'), toggle_filename=os.path.join(os.path.dirname(__file__), 'images', 'iconic', 'play.svg'), width=8, height=8) clear_button = SVGButton(label='', tooltip='Clear console buffer', filename=os.path.join(os.path.dirname(__file__), 'images', 'iconic', 'x.svg'), width=8, height=8) view = View(VSplit( Tabbed(Item('tracking_view', style='custom', label='Tracking'), Item('solution_view', style='custom', label='Solution'), Item('baseline_view', style='custom', label='Baseline'), VSplit( Item('observation_view', style='custom', show_label=False), Item('observation_view_base', style='custom', show_label=False), label='Observations', ), Item('settings_view', style='custom', label='Settings'), Item('update_view', style='custom', label='Firmware Update'), Tabbed(Item('system_monitor_view', style='custom', label='System Monitor'), Item('sbp_relay_view', label='SBP Relay', style='custom', show_label=False), Item('python_console_env', style='custom', label='Python Console', editor=ShellEditor()), label='Advanced', show_labels=False), show_labels=False), VGroup( HGroup( Spring(width=4, springy=False), Item('paused_button', show_label=False, width=8, height=8), Item('clear_button', show_label=False, width=8, height=8), Item('', label='Console Log', emphasized=True), Spring(), UItem( 'log_level_filter', style='simple', padding=0, height=8, show_label=True, tooltip= 'Show log levels up to and including the selected level of severity.\nThe CONSOLE log level is always visible.' ), ), Item( 'console_output', style='custom', editor=InstanceEditor(), height=0.3, show_label=False, ), )), icon=icon, resizable=True, width=1000, height=600, handler=ConsoleHandler(), title=CONSOLE_TITLE) def print_message_callback(self, sbp_msg, **metadata): try: encoded = sbp_msg.payload.encode('ascii', 'ignore') for eachline in reversed(encoded.split('\n')): self.console_output.write_level( eachline, str_to_log_level(eachline.split(':')[0])) except UnicodeDecodeError: print "Critical Error encoding the serial stream as ascii." def log_message_callback(self, sbp_msg, **metadata): try: encoded = sbp_msg.text.encode('ascii', 'ignore') for eachline in reversed(encoded.split('\n')): self.console_output.write_level(eachline, sbp_msg.level) except UnicodeDecodeError: print "Critical Error encoding the serial stream as ascii." def ext_event_callback(self, sbp_msg, **metadata): e = MsgExtEvent(sbp_msg) print 'External event: %s edge on pin %d at wn=%d, tow=%d, time qual=%s' % ( "Rising" if (e.flags & (1 << 0)) else "Falling", e.pin, e.wn, e.tow, "good" if (e.flags & (1 << 1)) else "unknown") def _paused_button_fired(self): self.console_output.paused = not self.console_output.paused def _log_level_filter_changed(self): """ Takes log level enum and translates into the mapped integer. Integer stores the current filter value inside OutputList. """ self.console_output.log_level_filter = str_to_log_level( self.log_level_filter) def _clear_button_fired(self): self.console_output.clear() def __init__(self, link, update, log_level_filter): self.console_output = OutputList() self.console_output.write("Console: starting...") sys.stdout = self.console_output sys.stderr = self.console_output self.log_level_filter = log_level_filter self.console_output.log_level_filter = str_to_log_level( log_level_filter) try: self.link = link self.link.add_callback(self.print_message_callback, SBP_MSG_PRINT_DEP) self.link.add_callback(self.log_message_callback, SBP_MSG_LOG) self.link.add_callback(self.ext_event_callback, SBP_MSG_EXT_EVENT) settings_read_finished_functions = [] self.tracking_view = TrackingView(self.link) self.solution_view = SolutionView(self.link) self.baseline_view = BaselineView(self.link) self.observation_view = ObservationView(self.link, name='Rover', relay=False) self.observation_view_base = ObservationView(self.link, name='Base', relay=True) self.sbp_relay_view = SbpRelayView(self.link) self.system_monitor_view = SystemMonitorView(self.link) self.update_view = UpdateView(self.link, prompt=update) settings_read_finished_functions.append( self.update_view.compare_versions) # Once we have received the settings, update device_serial with the Piksi # serial number which will be displayed in the window title def update_serial(): serial_string = self.settings_view.settings['system_info'][ 'serial_number'].value self.device_serial = 'PK%04d' % int(serial_string) settings_read_finished_functions.append(update_serial) self.settings_view = \ SettingsView(self.link, settings_read_finished_functions, hide_expert = not args.expert) self.update_view.settings = self.settings_view.settings self.python_console_env = { 'send_message': self.link, 'link': self.link, } self.python_console_env.update( self.tracking_view.python_console_cmds) self.python_console_env.update( self.solution_view.python_console_cmds) self.python_console_env.update( self.baseline_view.python_console_cmds) self.python_console_env.update( self.observation_view.python_console_cmds) self.python_console_env.update( self.sbp_relay_view.python_console_cmds) self.python_console_env.update( self.system_monitor_view.python_console_cmds) self.python_console_env.update( self.update_view.python_console_cmds) self.python_console_env.update( self.settings_view.python_console_cmds) except: import traceback traceback.print_exc()
def shell_editor(): """ Factory function that returns a Python shell for editing Python values. """ from traitsui.api import ShellEditor return ShellEditor()
class SwiftConsole(HasTraits): """Traits-defined Swift Console. link : object Serial driver update : bool Update the firmware log_level_filter : str Syslog string, one of "ERROR", "WARNING", "INFO", "DEBUG". skip_settings : bool Don't read the device settings. Set to False when the console is reading from a network connection only. """ link = Instance(sbpc.Handler) console_output = Instance(OutputList()) python_console_env = Dict device_serial = Str('') dev_id = Str('') tracking_view = Instance(TrackingView) solution_view = Instance(SolutionView) baseline_view = Instance(BaselineView) observation_view = Instance(ObservationView) networking_view = Instance(SbpRelayView) observation_view_base = Instance(ObservationView) system_monitor_view = Instance(SystemMonitorView) settings_view = Instance(SettingsView) update_view = Instance(UpdateView) imu_view = Instance(IMUView) spectrum_analyzer_view = Instance(SpectrumAnalyzerView) log_level_filter = Enum(list(SYSLOG_LEVELS.itervalues())) """" mode : baseline and solution view - SPP, Fixed or Float num_sat : baseline and solution view - number of satellites port : which port is Swift Device is connected to directory_name : location of logged files json_logging : enable JSON logging csv_logging : enable CSV logging """ mode = Str('') num_sats = Int(0) cnx_desc = Str('') latency = Str('') directory_name = Directory json_logging = Bool(True) csv_logging = Bool(False) cnx_icon = Str('') heartbeat_count = Int() last_timer_heartbeat = Int() solid_connection = Bool(False) csv_logging_button = SVGButton( toggle=True, label='CSV log', tooltip='start CSV logging', toggle_tooltip='stop CSV logging', filename=os.path.join(determine_path(), 'images', 'iconic', 'pause.svg'), toggle_filename=os.path.join(determine_path(), 'images', 'iconic', 'play.svg'), orientation='vertical', width=2, height=2, ) json_logging_button = SVGButton( toggle=True, label='JSON log', tooltip='start JSON logging', toggle_tooltip='stop JSON logging', filename=os.path.join(determine_path(), 'images', 'iconic', 'pause.svg'), toggle_filename=os.path.join(determine_path(), 'images', 'iconic', 'play.svg'), orientation='vertical', width=2, height=2, ) paused_button = SVGButton(label='', tooltip='Pause console update', toggle_tooltip='Resume console update', toggle=True, filename=os.path.join(determine_path(), 'images', 'iconic', 'pause.svg'), toggle_filename=os.path.join( determine_path(), 'images', 'iconic', 'play.svg'), width=8, height=8) clear_button = SVGButton(label='', tooltip='Clear console buffer', filename=os.path.join(determine_path(), 'images', 'iconic', 'x.svg'), width=8, height=8) view = View(VSplit( Tabbed(Item('tracking_view', style='custom', label='Tracking'), Item('solution_view', style='custom', label='Solution'), Item('baseline_view', style='custom', label='Baseline'), VSplit( Item('observation_view', style='custom', show_label=False), Item('observation_view_base', style='custom', show_label=False), label='Observations', ), Item('settings_view', style='custom', label='Settings'), Item('update_view', style='custom', label='Firmware Update'), Tabbed(Item('system_monitor_view', style='custom', label='System Monitor'), Item('imu_view', style='custom', label='IMU'), Item('networking_view', label='Networking', style='custom', show_label=False), Item('spectrum_analyzer_view', label='Spectrum Analyzer', style='custom'), Item('python_console_env', style='custom', label='Python Console', editor=ShellEditor()), label='Advanced', show_labels=False), show_labels=False), VGroup( VGroup( HGroup( Spring(width=4, springy=False), Item('paused_button', show_label=False, padding=0, width=8, height=8), Item('clear_button', show_label=False, width=8, height=8), Item('', label='Console Log', emphasized=True), Item('csv_logging_button', emphasized=True, show_label=False, width=12, height=-30, padding=0), Item('json_logging_button', emphasized=True, show_label=False, width=12, height=-30, padding=0), Item( 'directory_name', show_label=False, springy=True, tooltip= 'Choose location for file logs. Default is home/SwiftNav.', height=-25, enabled_when='not(json_logging or csv_logging)', editor_args={'auto_set': True}), UItem( 'log_level_filter', style='simple', padding=0, height=8, show_label=True, tooltip= 'Show log levels up to and including the selected level of severity.\nThe CONSOLE log level is always visible.' ), ), Item('console_output', style='custom', editor=InstanceEditor(), height=125, show_label=False, full_size=True), ), HGroup( Spring(width=4, springy=False), Item('', label='Interface:', emphasized=True, tooltip='Interface for communicating with Swift device'), Item('cnx_desc', show_label=False, style='readonly'), Item('', label='FIX TYPE:', emphasized=True, tooltip='Device Mode: SPS, Float RTK, Fixed RTK'), Item('mode', show_label=False, style='readonly'), Item('', label='#Sats:', emphasized=True, tooltip='Number of satellites used in solution'), Item('num_sats', padding=2, show_label=False, style='readonly'), Item('', label='Base Latency:', emphasized=True, tooltip='Corrections latency (-1 means no corrections)'), Item('latency', padding=2, show_label=False, style='readonly'), Spring(springy=True), Item('cnx_icon', show_label=False, padding=0, width=8, height=8, visible_when='solid_connection', springy=False, editor=ImageEditor(allow_clipping=False, image=ImageResource( 'arrows_blue.png', search_path=[ os.path.join( determine_path(), 'images', 'iconic') ]))), Item('cnx_icon', show_label=False, padding=0, width=8, height=8, visible_when='not solid_connection', springy=False, editor=ImageEditor(allow_clipping=False, image=ImageResource( 'arrows_grey.png', search_path=[ os.path.join( determine_path(), 'images', 'iconic') ]))), Spring(width=4, height=-2, springy=False), ), Spring(height=1, springy=False), ), ), icon=icon, resizable=True, width=800, height=600, handler=ConsoleHandler(), title=CONSOLE_TITLE) def print_message_callback(self, sbp_msg, **metadata): try: encoded = sbp_msg.payload.encode('ascii', 'ignore') for eachline in reversed(encoded.split('\n')): self.console_output.write_level( eachline, str_to_log_level(eachline.split(':')[0])) except UnicodeDecodeError: print("Critical Error encoding the serial stream as ascii.") def log_message_callback(self, sbp_msg, **metadata): try: encoded = sbp_msg.text.encode('ascii', 'ignore') for eachline in reversed(encoded.split('\n')): self.console_output.write_level(eachline, sbp_msg.level) except UnicodeDecodeError: print("Critical Error encoding the serial stream as ascii.") def ext_event_callback(self, sbp_msg, **metadata): e = MsgExtEvent(sbp_msg) print( 'External event: %s edge on pin %d at wn=%d, tow=%d, time qual=%s' % ("Rising" if (e.flags & (1 << 0)) else "Falling", e.pin, e.wn, e.tow, "good" if (e.flags & (1 << 1)) else "unknown")) def cmd_resp_callback(self, sbp_msg, **metadata): r = MsgCommandResp(sbp_msg) print("Received a command response message with code {0}".format( r.code)) def _paused_button_fired(self): self.console_output.paused = not self.console_output.paused def _log_level_filter_changed(self): """ Takes log level enum and translates into the mapped integer. Integer stores the current filter value inside OutputList. """ self.console_output.log_level_filter = str_to_log_level( self.log_level_filter) def _clear_button_fired(self): self.console_output.clear() def _directory_name_changed(self): if self.baseline_view and self.solution_view: self.baseline_view.directory_name_b = self.directory_name self.solution_view.directory_name_p = self.directory_name self.solution_view.directory_name_v = self.directory_name if self.observation_view and self.observation_view_base: self.observation_view.dirname = self.directory_name self.observation_view_base.dirname = self.directory_name def check_heartbeat(self): # if our heartbeat hasn't changed since the last timer interval the connection must have dropped if self.heartbeat_count == self.last_timer_heartbeat: self.solid_connection = False else: self.solid_connection = True self.last_timer_heartbeat = self.heartbeat_count def update_on_heartbeat(self, sbp_msg, **metadata): self.heartbeat_count += 1 # First initialize the state to nothing, if we can't update, it will be none temp_mode = "None" temp_num_sats = 0 view = None if self.baseline_view and self.solution_view: # If we have a recent baseline update, we use the baseline info if time.time() - self.baseline_view.last_btime_update < 10: view = self.baseline_view # Otherwise, if we have a recent SPP update, we use the SPP elif time.time() - self.solution_view.last_stime_update < 10: view = self.solution_view if view: if view.last_soln: # if all is well we update state temp_mode = mode_dict.get(get_mode(view.last_soln), EMPTY_STR) temp_num_sats = view.last_soln.n_sats self.mode = temp_mode self.num_sats = temp_num_sats if self.settings_view: # for auto populating surveyed fields self.settings_view.lat = self.solution_view.latitude self.settings_view.lon = self.solution_view.longitude self.settings_view.alt = self.solution_view.altitude if self.system_monitor_view: if self.system_monitor_view.msg_obs_window_latency_ms != -1: self.latency = "{0} ms".format( self.system_monitor_view.msg_obs_window_latency_ms) else: self.latency = EMPTY_STR def _csv_logging_button_action(self): if self.csv_logging and self.baseline_view.logging_b and self.solution_view.logging_p and self.solution_view.logging_v: print("Stopped CSV logging") self.csv_logging = False self.baseline_view.logging_b = False self.solution_view.logging_p = False self.solution_view.logging_v = False else: print("Started CSV logging at %s" % self.directory_name) self.csv_logging = True self.baseline_view.logging_b = True self.solution_view.logging_p = True self.solution_view.logging_v = True def _start_json_logging(self, override_filename=None): if override_filename: filename = override_filename else: filename = time.strftime("swift-gnss-%Y%m%d-%H%M%S.sbp.json") filename = os.path.normpath( os.path.join(self.directory_name, filename)) self.logger = s.get_logger(True, filename) self.forwarder = sbpc.Forwarder(self.link, self.logger) self.forwarder.start() if self.settings_view: self.settings_view._settings_read_button_fired() def _stop_json_logging(self): fwd = self.forwarder fwd.stop() self.logger.flush() self.logger.close() def _json_logging_button_action(self): if self.first_json_press and self.json_logging: print( "JSON Logging initiated via CMD line. Please press button again to stop logging" ) elif self.json_logging: self._stop_json_logging() self.json_logging = False print("Stopped JSON logging") else: self._start_json_logging() self.json_logging = True self.first_json_press = False def _json_logging_button_fired(self): if not os.path.exists(self.directory_name) and not self.json_logging: confirm_prompt = CallbackPrompt( title="Logging directory creation", actions=[ok_button], callback=self._json_logging_button_action) confirm_prompt.text = "\nThe selected logging directory does not exist and will be created." confirm_prompt.run(block=False) else: self._json_logging_button_action() def _csv_logging_button_fired(self): if not os.path.exists(self.directory_name) and not self.csv_logging: confirm_prompt = CallbackPrompt( title="Logging directory creation", actions=[ok_button], callback=self._csv_logging_button_action) confirm_prompt.text = "\nThe selected logging directory does not exist and will be created." confirm_prompt.run(block=False) else: self._csv_logging_button_action() def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): self.console_output.close() def __init__(self, link, update, log_level_filter, skip_settings=False, error=False, cnx_desc=None, json_logging=False, log_dirname=None, override_filename=None, log_console=False, networking=None, serial_upgrade=False): self.error = error self.cnx_desc = cnx_desc self.dev_id = cnx_desc self.num_sats = 0 self.mode = '' self.forwarder = None self.latency = '--' # if we have passed a logfile, we set our directory to it override_filename = override_filename home = expanduser("~") swift_path = os.path.normpath(os.path.join(home, 'SwiftNav')) if log_dirname: self.directory_name = log_dirname if override_filename: override_filename = os.path.join(log_dirname, override_filename) else: self.directory_name = swift_path # Start swallowing sys.stdout and sys.stderr self.console_output = OutputList(tfile=log_console, outdir=self.directory_name) sys.stdout = self.console_output self.console_output.write("Console: " + CONSOLE_VERSION + " starting...") if not error: sys.stderr = self.console_output self.log_level_filter = log_level_filter self.console_output.log_level_filter = str_to_log_level( log_level_filter) try: self.link = link self.link.add_callback(self.print_message_callback, SBP_MSG_PRINT_DEP) self.link.add_callback(self.log_message_callback, SBP_MSG_LOG) self.link.add_callback(self.ext_event_callback, SBP_MSG_EXT_EVENT) self.link.add_callback(self.cmd_resp_callback, SBP_MSG_COMMAND_RESP) self.link.add_callback(self.update_on_heartbeat, SBP_MSG_HEARTBEAT) self.dep_handler = DeprecatedMessageHandler(link) settings_read_finished_functions = [] self.tracking_view = TrackingView(self.link) self.solution_view = SolutionView(self.link, dirname=self.directory_name) self.baseline_view = BaselineView(self.link, dirname=self.directory_name) self.observation_view = ObservationView( self.link, name='Local', relay=False, dirname=self.directory_name) self.observation_view_base = ObservationView( self.link, name='Remote', relay=True, dirname=self.directory_name) self.system_monitor_view = SystemMonitorView(self.link) self.update_view = UpdateView(self.link, download_dir=swift_path, prompt=update, serial_upgrade=serial_upgrade) self.imu_view = IMUView(self.link) self.spectrum_analyzer_view = SpectrumAnalyzerView(self.link) settings_read_finished_functions.append( self.update_view.compare_versions) if networking: import yaml try: networking_dict = yaml.load(networking) networking_dict.update({'show_networking': True}) except yaml.YAMLError: print( "Unable to interpret networking cmdline argument. It will be ignored." ) import traceback print(traceback.format_exc()) networking_dict = {'show_networking': True} else: networking_dict = {} networking_dict.update( {'whitelist': [SBP_MSG_POS_LLH, SBP_MSG_HEARTBEAT]}) self.networking_view = SbpRelayView(self.link, **networking_dict) self.json_logging = json_logging self.csv_logging = False self.first_json_press = True if json_logging: self._start_json_logging(override_filename) self.json_logging = True # we set timer interval to 1200 milliseconds because we expect a heartbeat each second self.timer_cancel = call_repeatedly(1.2, self.check_heartbeat) # Once we have received the settings, update device_serial with # the Swift serial number which will be displayed in the window # title. This callback will also update the header route as used # by the networking view. def update_serial(): uuid = None mfg_id = None try: uuid = self.settings_view.settings['system_info'][ 'uuid'].value mfg_id = self.settings_view.settings['system_info'][ 'serial_number'].value except KeyError: pass if mfg_id: self.device_serial = 'PK' + str(mfg_id)[-6:] self.networking_view.set_route(uuid=uuid, serial_id=mfg_id) if self.networking_view.connect_when_uuid_received: self.networking_view._connect_rover_fired() settings_read_finished_functions.append(update_serial) self.settings_view = SettingsView(self.link, settings_read_finished_functions, skip=skip_settings) self.update_view.settings = self.settings_view.settings self.python_console_env = { 'send_message': self.link, 'link': self.link, } self.python_console_env.update( self.tracking_view.python_console_cmds) self.python_console_env.update( self.solution_view.python_console_cmds) self.python_console_env.update( self.baseline_view.python_console_cmds) self.python_console_env.update( self.observation_view.python_console_cmds) self.python_console_env.update( self.networking_view.python_console_cmds) self.python_console_env.update( self.system_monitor_view.python_console_cmds) self.python_console_env.update( self.update_view.python_console_cmds) self.python_console_env.update(self.imu_view.python_console_cmds) self.python_console_env.update( self.settings_view.python_console_cmds) self.python_console_env.update( self.spectrum_analyzer_view.python_console_cmds) except: import traceback traceback.print_exc() if self.error: sys.exit(1)
class Lab(ASection): """ Defines a lab, which is a section of a tutorial with only Python code. This type of section might typically follow a lecture which introduced the code being worked on in the lab. """ # The set-up code (if any) for the lab: setup = Instance(CodeItem) # The list of code items for the lab: snippets = List(CodeItem) # The list of visible code items for the lab: visible_snippets = Property(depends_on='visible', cached=True) # The currently selected snippet: snippet = Instance(CodeItem) # Should normally hidden code items be shown? visible = Bool(False) # The dictionary containing the items from the Python code execution: values = Dict # The run Python code button: run = Button(image=ImageResource('run'), height_padding=1) # User error message: message = Str # The output produced while the program is running: output = Str # The current demo pane (if any): demo = Instance(DemoPane, ()) view = View(VSplit( VGroup( Item('visible_snippets', style='custom', show_label=False, editor=snippet_editor), HGroup( Item('run', style='custom', show_label=False, tooltip='Run the Python code'), '_', Item('message', springy=True, show_label=False, editor=TitleEditor()), '_', Item('visible', label='View hidden sections'), ), ), Tabbed( Item( 'values', id='values_1', label='Shell', editor=ShellEditor(share=True), dock='tab', export='DockWindowShell', ), Item( 'values', id='values_2', editor=ValueEditor(), dock='tab', export='DockWindowShell', ), Item( 'output', style='readonly', editor=CodeEditor(show_line_numbers=False, selected_color=0xFFFFFF), dock='tab', export='DockWindowShell', ), Item( 'demo', id='demo', style='custom', resizable=True, dock='tab', export='DockWindowShell', ), show_labels=False, ), id='splitter', ), id='enthought.tutor.lab', handler=LabHandler) def _run_changed(self): """ Runs the current set of snippet code. """ self.run_code() @cached_property def _get_visible_snippets(self): """ Returns the list of code items that are currently visible. """ if self.visible: return self.snippets return [snippet for snippet in self.snippets if (not snippet.hidden)] def run_code(self): """ Runs all of the code snippets associated with the section. """ # Reconstruct the lab code from the current set of code snippets: start_line = 1 module = '' for snippet in self.snippets: snippet.start_line = start_line module = '%s\n\n%s' % (module, snippet.content) start_line += (snippet.content.count('\n') + 2) # Reset any syntax error and message log values: self.message = self.output = '' # Redirect standard out and error to the message log: stdout, stderr = sys.stdout, sys.stderr sys.stdout = sys.stderr = StdOut(self) try: try: # Get the execution context dictionary: values = self.values # Clear out any special variables defined by the last run: for name in ('demo', 'popup'): if isinstance(values.get(name), HasTraits): del values[name] # Execute the current lab code: exec module[2:] in values, values # fixme: Hack trying to update the Traits UI view of the dict. self.values = {} self.values = values # Handle a 'demo' value being defined: demo = values.get('demo') if not isinstance(demo, HasTraits): demo = NoDemo() self.demo.demo = demo # Handle a 'popup' value being defined: popup = values.get('popup') if isinstance(popup, HasTraits): popup.edit_traits(kind='livemodal') except SyntaxError, excp: # Convert the line number of the syntax error from one in the # composite module to one in the appropriate code snippet: line = excp.lineno if line is not None: snippet = self.snippets[0] for s in self.snippets: if s.start_line > line: break snippet = s line -= (snippet.start_line - 1) # Highlight the line in error: snippet.selected_line = line # Select the correct code snippet: self.snippet = snippet # Display the syntax error message: self.message = '%s in column %s of line %s' % ( excp.msg.capitalize(), excp.offset, line) else: # Display the syntax error message without line # info: self.message = excp.msg.capitalize() except: import traceback traceback.print_exc() finally:
class Lesson(Lab): """ Defines a lesson, which is a section of a tutorial with both descriptive information and associated Python code. """ # The list of descriptive items for the lesson: descriptions = List(ATutorialItem) view = View( HSplit( Item( 'descriptions', label='Lesson', style='custom', show_label=False, dock='horizontal', editor=list_editor, ), VSplit( VGroup( Item( 'visible_snippets', style='custom', show_label=False, editor=snippet_editor, ), HGroup( Item( 'run', style='custom', show_label=False, tooltip='Run the Python code', ), '_', Item( 'message', springy=True, show_label=False, editor=TitleEditor(), ), '_', Item( 'visible', label='View hidden sections', ), ), label='Lab', dock='horizontal', ), Tabbed( Item( 'values', id='values_1', label='Shell', editor=ShellEditor(share=True), dock='tab', export='DockWindowShell', ), Item( 'values', id='values_2', editor=ValueEditor(), dock='tab', export='DockWindowShell', ), Item( 'output', style='readonly', editor=CodeEditor(show_line_numbers=False, selected_color=0xFFFFFF), dock='tab', export='DockWindowShell', ), Item( 'demo', id='demo', style='custom', resizable=True, dock='tab', export='DockWindowShell', ), show_labels=False, ), label='Lab', dock='horizontal', ), id='splitter', ), id='enthought.tutor.lesson', handler=LabHandler, )
auto_open=False, label="name", ), ], orientation='vertical', hide_root=True, on_dclick=on_dclick, ) ray_tracer_view = View( HSplit( VSplit( Item('scene', editor=SceneEditor(), height=600), #Item('optics@', editor=ListEditor(use_notebook=True), # width=200), Tabbed(Item('ShellObj', editor=ShellEditor(share=False)), Item('constraints', style="custom", editor=ListEditor(use_notebook=True)), show_labels=False), show_labels=False, dock="vertical"), VGroup(Item('Self', id="TracerModelID", editor=tree_editor, width=200), Item('save_btn'), show_labels=False), show_labels=False, dock="horizontal", id="raytrace.model"), resizable=True, #height=500, width=800,