def traits_view(self):
        grps = self._get_groups()

        g = VGroup(Item('bind_colors'), *grps)

        g.show_border = True
        g.label = 'Group {}'.format(self.group_id + 1)
        v = View(g)
        return v
Beispiel #2
0
    def traits_view(self):
        header_grp = HGroup(Label('Plot'),
                            Spring(width=132, springy=False),
                            Label('Scale'),
                            spring, Label('Height'),
                            spring,
                                    Label('X Err.'), Label('Y Err.'))
        default_grp = VGroup(
                             HGroup(Item('auto_generate_title', tooltip='Auto generate a title based on the analysis list'),
                                    Item('title', springy=True, enabled_when='not auto_generate_title',
                                         tooltip='User specified plot title')),
                             Item('data_type',
                                  editor=EnumEditor(values={'database':'0:Database',
                                                            'data_file':'1:Data File',
                                                            'manual_entry':'2:Manual Entry'}),
                                  defined_when='data_type_editable'),
                             self._get_x_axis_group(),

                             VGroup(
                                    self._create_axis_group('y', 'title'),
                                    self._create_axis_group('y', 'tick'),
                                    show_border=True,
                                    label='Y'),
                             header_grp,
                             Item('aux_plots',
                                  style='custom',
                                  show_label=False,
                                  editor=ListEditor(mutable=False,
                                                    style='custom',
                                                    editor=InstanceEditor()))
                             )
        grps = self._get_groups()
        if grps:
            default_grp.label = 'Plot'
            g = Group(default_grp, layout='tabbed')
            g.content.append(grps)

        else:
            g = Group(default_grp)

        v = View(
                 g,
                 resizable=True,
#                 title='Plotter Options',
                 buttons=['OK', 'Cancel'],
                 handler=self.handler_klass
                 )
        return v
Beispiel #3
0
 def control_panel(self):
     return VGroup(Item("current_label", label="当前标签"))
Beispiel #4
0
            os.makedirs(self.database_dir)
        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=False)
        result = proc.communicate()
        print result
        return result

    def shutdown(self):
        conn = self.get_connection()
        dba = conn.admin
        try:
            dba.command({"shutdown": 1})
        except Exception, e:
            print e

    traits_view = View(VGroup(Item("database_dir"), Item("log_path"),
                              Item("restrict_ips"), Item("port"),
                              Item("numactl_interleave"),
                              Group(Item("b_start"), show_labels=False)),
                       title="MongoDB Connection")


class LocalDataImporter(HasTraits):
    """
    Holds a list of Scan objects. These can be loaded from
    and saved to a json file.
    """
    json_file = File()
    datasets = List(Instance(Scan))
    save = Button()
    mongo_creator = Instance(MongoCreator)
    upload_to_mongodb = Button()
    connect_to_mongod = Button()
Beispiel #5
0
class CCSUnitCell(SimDBClass):
    '''Describes the combination of the concrete mixture and textile cross section.
    Note: only one concrete can be defined for the entire composite cross section.
    '''

    input_change = Event
    @on_trait_change('+input, damage_function_list.input_change')
    def _set_input_change(self):
        self.input_change = True

    #--------------------------------------------------------------------------------
    # select the concrete mixture from the concrete database:
    #--------------------------------------------------------------------------------

    concrete_mixture_key = Str(simdb=True, input=True, table_field=True,
                                auto_set=False, enter_set=True)

    concrete_mixture_ref = Property(Instance(SimDBClass),
                                     depends_on='concrete_mixture_key')
    @cached_property
    def _get_concrete_mixture_ref(self):
        return ConcreteMixture.db[ self.concrete_mixture_key ]

    #--------------------------------------------------------------------
    # textile fabric layout used
    #--------------------------------------------------------------------
    #
    fabric_layout_key = Str(simdb=True, input=True, table_field=True,
                             auto_set=False, enter_set=True)
    def _fabric_layout_key_default(self):
        return FabricLayOut.db.keys()[0]

    fabric_layout_ref = Property(Instance(SimDBClass),
                                  depends_on='fabric_layout_key')
    @cached_property
    def _get_fabric_layout_ref(self):
        return FabricLayOut.db[ self.fabric_layout_key ]

    # equidistant spacing in thickness direction (z-direction) between the layers
    #
    s_tex_z = Float(1, unit='m', simdb=True, input=True, table_field=True,
                      auto_set=False, enter_set=True)

    # orientation function of the layup fabric
    #
    orientation_fn_key = Str('', simdb=True, table_field=True,
                                auto_set=False, enter_set=True)

    #--------------------------------------------------------------------------------
    # Derived material parameters - supplied during the calibration
    #--------------------------------------------------------------------------------

    def get_E_m_time(self, age):
        '''function for the composite E-modulus as weighted sum of all
        fabric layups. Returns a function depending of the concrete age.
        '''
        E_m = self.concrete_mixture_ref.get_E_m_time(age)
        print 'E_m_time', E_m
        return E_m

    def get_E_c_time(self, age):
        '''function for the composite E-modulus as weighted sum of all
        fabric layups. Returns a function depending of the concrete age.
        '''
        rho = self.rho
        E_tex = self.E_tex
        E_m = self.concrete_mixture_ref.get_E_m_time(age)
        E_c = (1 - rho) * E_m + rho * E_tex
        return E_c

    E_c28 = Property(Float, unit='MPa', depends_on='input_change')
    @cached_property
    def _get_E_c28(self):
        '''Composite E-modulus after 28 days.
        '''
        return self.get_E_c_time(28)

    nu = DelegatesTo('concrete_mixture_ref', listenable=False)

    #--------------------------------------------------------------------------------
    # Defined material parameters - supplied during the calibration
    #--------------------------------------------------------------------------------
    rho = Float

    E_tex = Property(depends_on='input_changed')
    def _get_E_tex(self):
        return self.fabric_layout_ref.E_tex_0

    #--------------------------------------------------------------------------------
    # Bag for material parameters
    #--------------------------------------------------------------------------------
    #
    # The material parameters are quantities to be used by models that should make
    # prognosis of the behavior in general condition. The composite cross section
    # can be modeled by a variety of models, each of which may need different
    # parameters. The parameters are determined using some calibration test.
    # Therefore, in order to trace back the origin of the material parameters
    # it is necessary to store the value of the material parameter together with
    # the model that has calibrated it and by the test setup that was used
    # for calibration. In this way, the range of validity of the calibrated damage
    # function is available.
    #
    # The material parameters are stored in a list with the combined key
    # containing the tuple (material model, test run).
    #
    damage_function_list = List(DamageFunctionEntry, input=True)

    def set_param(self, material_model, calibration_test, df):
        print 'adding damage function'
        for mp_entry in self.damage_function_list:
            if (mp_entry.material_model == material_model and
                 mp_entry.calibration_test == calibration_test):
                mp_entry.damage_function = df
                print 'only the function updated'
                return
        mp_entry = DamageFunctionEntry(material_model=material_model,
                                        calibration_test=calibration_test,
                                        damage_function=df)
        self.damage_function_list.append(mp_entry)
        print 'new function added'

    def get_param(self, material_model, calibration_test):
        print 'material_model', material_model
        print 'calibration_test', calibration_test
        for mp_entry in self.damage_function_list:
            if (mp_entry.material_model == material_model and
                 mp_entry.calibration_test == calibration_test):
                return mp_entry.damage_function

        raise ValueError, 'no entry in unit cell with key ( %s ) for model ( %s ) and test( %s )' % (self.key, material_model, calibration_test)

    #-------------------------------------------------------------
    # derive the average phi-function based on all entries
    # in damage_function_list
    #-------------------------------------------------------------

    df_average = Property(Instance(MFnLineArray),
                           depends_on='damage_function_list')
    @cached_property
    def get_df_average(self, n_points):
        '''derive the average phi-function based on all entries
        in damage_function_list
        '''

        def get_y_average(self, x_average):
            '''get the y-values from the mfn-functions in df_list for
            'x_average' and return the average.
            Note that the shape of 'mfn.xdata' does not necessarily needs to be equal in all
            'DamageFunctionEntries' as the number of steps used for calibration or the adaptive
            refinement in 'tloop' might have been different for each case.
            '''
            y_list = [ self.damage_function_list[i].damage_function.get_value(x_average) \
                       for i in range(len(self.damage_function_list)) ]
            return sum(y_list) / len(y_list)

        get_y_average_vectorized = frompyfunc(get_y_average, 2, 1)

        mfn = MFnLineArray()

        # take the smallest value of the strains for the average function. Beyond this value
        # the average does not make sense anymore because it depends on the arbitrary number
        # of entries in the df_list
        #
        xdata_min = min(self.damage_function_list[i].damage_function.xdata[-1] \
                         for i in range(len(self.damage_function_list)))

        # number of sampling point used for the average phi function
        #
        mfn.xdata = linspace(0., xdata_min, num=n_points)

        # get the corresponding average ydata values
        #
        mfn.ydata = self.get_y_average_vectorized(mfn.xdata)

        return mfn


    #-------------------------------------------------------------------


    #-------------------------------------------------------------------
    # PLOT OBJECT
    #-------------------------------------------------------------------

    figure = Instance(Figure, transient=True)
    def _figure_default(self):
        figure = Figure(facecolor='white')
        figure.add_axes([0.08, 0.13, 0.85, 0.74])
        return figure

    selected_dfs = List(Instance(DamageFunctionEntry), transient=True)
    def _selected_dfs_default(self):
        return self.damage_function_list

    print_values = Button()
    def _print_values_fired(self):
        for mp_entry in self.selected_dfs:
            print 'x', mp_entry.damage_function.xdata
            print 'y', mp_entry.damage_function.ydata

    save_phi_fn_values = Button()
    def _save_phi_fn_values_fired(self):
        'save phi_fn xy-data to file'
        print 'save phi_arr data to file'
        for mp_entry in self.selected_dfs:
            xdata = mp_entry.damage_function.xdata
            ydata = mp_entry.damage_function.ydata
            phi_arr = np.hstack([xdata[:, None], ydata[:, None]])
            print 'phi_arr ', phi_arr.shape, ' save to file "phi_arr.csv"'
            np.savetxt('phi_arr.csv', phi_arr, delimiter=';')

    # event to trigger the replotting - used by the figure editor
    #
    data_changed = Event

#    @on_trait_change('damage_function_list')
    @on_trait_change('input_change, selected_dfs')
    def _redraw(self):
        # map the array dimensions to the plot axes
        #
        figure = self.figure
        axes = figure.gca()
        axes.clear()

        for mp_entry in self.selected_dfs:
#        for mp_entry in self.damage_function_list:
            df = mp_entry.damage_function
            mp_entry.damage_function.mpl_plot(axes)

        self.data_changed = True

    #--------------------------------------------------------------------------------
    # view
    #--------------------------------------------------------------------------------

    traits_view = View(Item('key', style='readonly'),
                       Item('s_tex_z', style='readonly', format_str="%.5f"),
                        Item('orientation_fn_key', style='readonly'),
                        Item('rho', style='readonly', format_str="%.5f"),
                        VSplit(
                        VGroup(
                            Spring(),
                            Item('concrete_mixture_key', style='readonly',
                                label='concrete mixture'),
                            Spring(),
                            Item('concrete_mixture_ref@', style='readonly',
                                 show_label=False),
                            Spring(),
                            id='exdb.ccsuc.cm',
                            label='concrete mixture',
                            dock='tab',
                            ),
                        VGroup(
                            Spring(),
                            Item('fabric_layout_key', style='readonly',
                                label='fabric layout'),
                            Spring(),
                            Item('fabric_layout_ref@', style='readonly',
                                show_label=False),
                            Spring(),
                            id='exdb.ccsuc.lo',
                            label='fabric layout',
                            dock='tab',
                            ),
                        Group(
                              Item('print_values', show_label=False),
                              Item('save_phi_fn_values', show_label=False),
                        Item('damage_function_list@', editor=df_table_editor,
                             resizable=True, show_label=False),
                             id='exdb.ccsuc.damage_functions',
                             label='damage functions',
                             dock='tab',
                        ),
                        Group(
                        Item('figure', editor=MPLFigureEditor(),
                             resizable=True, show_label=False),
                             id='exdb.ccsuc.plot_sheet',
                             label='plot sheet',
                             dock='tab',

                        ),
#                        Group(
#                        Item('rho_c',
#                             style = 'readonly', show_label = True, format_str="%.4f"),
#                        Item('E_c28',
#                             style = 'readonly', show_label = True, format_str="%.0f" ),
#                        label = 'derived params',
#                        id = 'exdb.ccsuc.dp',
#                        dock = 'tab',
#                        ),

                        dock='tab',
                        id='exdb.ccsuc.db.vsplit',
                        orientation='vertical',
                        ),
                        dock='tab',
                        id='ccsuc.db',
                        scrollable=True,
                        resizable=True,
                        height=0.4,
                        width=0.5,
                        buttons=['OK', 'Cancel'],
                        )
Beispiel #6
0
class Pulsed(ManagedJob, GetSetItemsMixin):
    """
    Defines a pulsed spin resonance measurement.
    
    We output a pulse sequence (consisting of laser
    and microwave control pulses) with some sort
    of pulse pattern generator.
    
    We acquire the pulsed fluorescence repsonsed in
    a two dimensional histogram. Each row in the histogram
    represents the fluorescence response corresponding
    to a laser pulse. The sum over a window of the fluorescence
    response encodes the spin state.
    """

    run_time = Float(value=0.0, label='run time [s]', format_str='%.f')
    stop_time = Float(
        default_value=np.inf,
        desc='Time after which the experiment stops by itself [s]',
        label='Stop time [s]',
        mode='text',
        auto_set=False,
        enter_set=True)
    stop_counts = Float(
        default_value=np.inf,
        desc=
        'Stop the measurement when all data points of the extracted spin state have at least this many counts.',
        label='Stop counts',
        mode='text',
        auto_set=False,
        enter_set=True)

    keep_data = Bool(
        False)  # helper variable to decide whether to keep existing data

    resubmit_button = Button(
        label='resubmit',
        desc=
        'Submits the measurement to the job manager. Tries to keep previously acquired data. Behaves like a normal submit if sequence or time bins have changed since previous run.'
    )

    # acquisition parameters
    record_length = Float(default_value=3000,
                          desc='length of acquisition record [ns]',
                          label='record length [ns]',
                          mode='text',
                          auto_set=False,
                          enter_set=True)
    bin_width = Range(low=0.1,
                      high=1000.,
                      value=1.0,
                      desc='bin width [ns]',
                      label='bin width [ns]',
                      mode='text',
                      auto_set=False,
                      enter_set=True)

    n_laser = Int(2)
    n_bins = Int(2)
    time_bins = Array(value=np.array((0, 1)))

    sequence = Instance(list, factory=list)

    # measured data
    count_data = Array(value=np.zeros((2, 2)))

    # parameters for calculating spin state
    integration_width = Float(default_value=200.,
                              desc='width of integration window [ns]',
                              label='integr. width [ns]',
                              mode='text',
                              auto_set=False,
                              enter_set=True)
    position_signal = Float(
        default_value=0.,
        desc='position of signal window relative to edge [ns]',
        label='pos. signal [ns]',
        mode='text',
        auto_set=False,
        enter_set=True)
    position_normalize = Float(
        default_value=-1.,
        desc=
        'position of normalization window relative to edge [ns]. If negative, no normalization is performed',
        label='pos. norm. [ns]',
        mode='text',
        auto_set=False,
        enter_set=True)

    # analyzed data
    pulse = Array(value=np.array((0., 0.)))
    edge = Float(value=0.0)
    spin_state = Array(value=np.array((0., 0.)))

    channel_apd = Int(0)
    channel_detect = Int(2)
    channel_sequence = Int(3)

    def __init__(self, pulse_generator, time_tagger, **kwargs):
        super(Pulsed, self).__init__(**kwargs)
        self.pulse_generator = pulse_generator
        self.time_tagger = time_tagger

    def submit(self):
        """Submit the job to the JobManager."""
        self.keep_data = False
        ManagedJob.submit(self)

    def resubmit(self):
        """Submit the job to the JobManager."""
        self.keep_data = True
        ManagedJob.submit(self)

    def _resubmit_button_fired(self):
        """React to start button. Submit the Job."""
        self.resubmit()

    def generate_sequence(self):
        return []

    def apply_parameters(self):
        """Apply the current parameters and decide whether to keep previous data."""
        n_bins = int(self.record_length / self.bin_width)
        time_bins = self.bin_width * np.arange(n_bins)
        sequence = self.generate_sequence()
        n_laser = find_detection_pulses(sequence)

        if self.keep_data and sequence == self.sequence and np.all(
                time_bins == self.time_bins
        ):  # if the sequence and time_bins are the same as previous, keep existing data
            self.old_count_data = self.count_data.copy()
        else:
            self.old_count_data = np.zeros((n_laser, n_bins))
            self.count_data = np.zeros((n_laser, n_bins))
            self.run_time = 0.0

        self.sequence = sequence
        self.time_bins = time_bins
        self.n_bins = n_bins
        self.n_laser = n_laser
        self.keep_data = True  # when job manager stops and starts the job, data should be kept. Only new submission should clear data.

    def start_up(self):
        """Put here additional stuff to be executed at startup."""
        pass

    def shut_down(self):
        """Put here additional stuff to be executed at shut_down."""
        pass

    def _run(self):
        """Acquire data."""

        try:  # try to run the acquisition from start_up to shut_down
            self.state = 'run'
            self.apply_parameters()

            if not (self.run_time < self.stop_time
                    and any(self.spin_state < self.stop_counts)):
                logging.getLogger().debug(
                    'Runtime larger than stop_time. Returning')
                self.state = 'done'
                return

            self.start_up()
            self.pulse_generator.Night()
            pulsed = TimeDifferences(
                self.time_tagger,
                self.channel_apd,
                self.channel_detect,
                self.channel_detect,
                self.channel_sequence,
                int(np.round(self.bin_width * 1000)),
                self.n_bins,
                self.n_laser,
            )
            self.pulse_generator.Sequence(self.sequence)
            self.pulse_generator.checkUnderflow()

            while self.run_time < self.stop_time and any(
                    self.spin_state < self.stop_counts):
                start_time = time.time()
                self.thread.stop_request.wait(1.0)
                if self.thread.stop_request.isSet():
                    logging.getLogger().debug('Caught stop signal. Exiting.')
                    break
                if self.pulse_generator.checkUnderflow():
                    raise RuntimeError('Underflow in pulse generator.')
                self.count_data = self.old_count_data + pulsed.getData()
                self.run_time += time.time() - start_time

            if self.run_time < self.stop_time and any(
                    self.spin_state < self.stop_counts):
                self.state = 'idle'
            else:
                try:
                    self.save(self.filename)
                except:
                    logging.getLogger().exception(
                        'Failed to save the data to file.')
                self.state = 'done'
            del pulsed
            self.shut_down()
            self.pulse_generator.Light()

        except:  # if anything fails, log the exception and set the state
            logging.getLogger().exception(
                'Something went wrong in pulsed loop.')
            self.state = 'error'

    @on_trait_change(
        'count_data,integration_width,position_signal,position_normalize')
    def _compute_spin_state(self):
        y, profile, edge = spin_state(
            c=self.count_data,
            dt=self.bin_width,
            T=self.integration_width,
            t0=self.position_signal,
            t1=self.position_normalize,
        )
        self.spin_state = y
        self.pulse = profile
        self.edge = self.time_bins[edge]

    traits_view = View(
        VGroup(
            HGroup(
                Item('submit_button', show_label=False),
                Item('remove_button', show_label=False),
                Item('resubmit_button', show_label=False),
                Item('priority'),
                Item('state', style='readonly'),
                Item('run_time', style='readonly', format_str='%.f'),
                Item('stop_time', format_str='%.f'),
                Item('stop_counts'),
            ),
            HGroup(Item('filename', springy=True),
                   Item('save_button', show_label=False),
                   Item('load_button', show_label=False)),
            HGroup(
                Item('bin_width', enabled_when='state != "run"'),
                Item('record_length', enabled_when='state != "run"'),
            ),
        ),
        title='Pulsed Measurement',
    )

    get_set_items = [
        '__doc__', 'record_length', 'bin_width', 'n_bins', 'time_bins',
        'n_laser', 'sequence', 'count_data', 'run_time', 'integration_width',
        'position_signal', 'position_normalize', 'pulse', 'edge', 'spin_state'
    ]
 def traits_view(self):
     v = View(VGroup('pressure',
                     'current',
                     'voltage'))
     return v
Beispiel #8
0
class FileSearch ( HasTraits ):

    # The currenty root directory being searched:
    root = Directory( getcwd(), entries = 10 )

    # Should sub directories be included in the search:
    recursive = Bool( True )

    # The file types to include in the search:
    file_type = Enum( 'Python', 'C', 'C++', 'Java', 'Ruby' )

    # The current search string:
    search = Str

    # Is the search case sensitive?
    case_sensitive = Bool( False )

    # The live search table filter:
    filter = Property # Instance( TableFilter )

    # The current list of source files being searched:
    source_files = Property # List( SourceFile )

    # The currently selected source file:
    selected = Any # Instance( SourceFile )

    # The contents of the currently selected source file:
    selected_contents = Property # List( Str )

    # The currently selected match:
    selected_match = Int

    # The text line corresponding to the selected match:
    selected_line = Property # Int

    # The full name of the currently selected source file:
    selected_full_name = Property # File

    # The list of marked lines for the currently selected file:
    mark_lines = Property # List( Int )

    # Summary of current number of files and matches:
    summary = Property # Str

    #-- Traits UI Views --------------------------------------------------------

    view = View(
        VGroup(
            HGroup(
                Item( 'root',
                      id    = 'root',
                      label = 'Path',
                      width = 0.5
                ),
                Item( 'recursive' ),
                Item( 'file_type', label = 'Type' ),
                Item( 'search',
                      id     = 'search',
                      width  = 0.5,
                      editor = HistoryEditor( auto_set = True )
                ),
                Item( 'case_sensitive' )
            ),
            VSplit(
                VGroup(
                    Item( 'summary',
                          editor = TitleEditor()
                    ),
                    Item( 'source_files',
                          id     = 'source_files',
                          editor = table_editor
                    ),
                    dock        = 'horizontal',
                    show_labels = False
                ),
                VGroup(
                    HGroup(
                        Item( 'selected_full_name',
                              editor  = TitleEditor(),
                              springy = True
                        ),
                        Item( 'selected_full_name',
                              editor  = DNDEditor(),
                              tooltip = 'Drag this file'
                        ),
                        show_labels = False
                    ),
                    Item( 'selected_contents',
                          style  = 'readonly',
                          editor = CodeEditor( mark_lines    = 'mark_lines',
                                               line          = 'selected_line',
                                               selected_line = 'selected_line' )
                    ),
                    dock        = 'horizontal',
                    show_labels = False
                ),
                id = 'splitter'
            )
        ),
        title     = 'Live File Search',
        id        = 'etsdevtools.developer.tools.file_search',
        width     = 0.75,
        height    = 0.67,
        resizable = True
    )

    #-- Property Implementations -----------------------------------------------

    @property_depends_on( 'search, case_sensitive' )
    def _get_filter ( self ):
        if len( self.search ) == 0:
            return lambda x: True

        return lambda x: len( x.matches ) > 0

    @property_depends_on( 'root, recursive, file_type' )
    def _get_source_files ( self ):
        root = self.root
        if root == '':
            root = getcwd()

        file_types = FileTypes[ self.file_type ]
        if self.recursive:
            result = []
            for dir_path, dir_names, file_names in walk( root ):
                for file_name in file_names:
                    if splitext( file_name )[1] in file_types:
                        result.append( SourceFile(
                            live_search = self,
                            full_name   = join( dir_path, file_name ) ) )
            return result

        return [ SourceFile( live_search = self,
                             full_name   = join( root, file_name ) )
                 for file_name in listdir( root )
                 if splitext( file_name )[1] in file_types ]

    @property_depends_on( 'selected' )
    def _get_selected_contents ( self ):
        if self.selected is None:
            return ''

        return ''.join( self.selected.contents )

    @property_depends_on( 'selected' )
    def _get_mark_lines ( self ):
        if self.selected is None:
            return []

        return [ int( match.split( ':', 1 )[0] )
                 for match in self.selected.matches ]

    @property_depends_on( 'selected, selected_match' )
    def _get_selected_line ( self ):
        selected = self.selected
        if (selected is None) or (len( selected.matches ) == 0):
            return 1

        return int( selected.matches[ self.selected_match - 1
                                    ].split( ':', 1 )[0] )

    @property_depends_on( 'selected' )
    def _get_selected_full_name ( self ):
        if self.selected is None:
            return ''

        return self.selected.full_name

    @property_depends_on( 'source_files, search, case_sensitive' )
    def _get_summary ( self ):
        source_files = self.source_files
        search       = self.search
        if search == '':
            return 'A total of %d files.' % len( source_files )

        files   = 0
        matches = 0
        for source_file in source_files:
            n = len( source_file.matches )
            if n > 0:
                files   += 1
                matches += n

        return 'A total of %d files with %d files containing %d matches.' % (
               len( source_files ), files, matches )

    #-- Traits Event Handlers --------------------------------------------------

    def _selected_changed ( self ):
        self.selected_match = 1

    def _source_files_changed ( self ):
        if len( self.source_files ) > 0:
            self.selected = self.source_files[0]
        else:
            self.selected = None
Beispiel #9
0
class SbpRelayView(HasTraits):
    """
  UDP Relay view- Class allows user to specify port, IP address, and message set
  to relay over UDP
  """
    running = Bool(False)
    configured = Bool(False)
    broadcasting = Bool(False)
    msg_enum = Enum('Observations', 'All')
    ip_ad = String(DEFAULT_UDP_ADDRESS)
    port = Int(DEFAULT_UDP_PORT)
    information = String(
        'UDP Streaming\n\nBroadcast SBP information received by'
        ' the console to other machines or processes over UDP. With the \'Observations\''
        ' radio button selected, the console will broadcast the necessary information'
        ' for a rover Piksi to acheive an RTK solution.'
        '\n\nThis can be used to stream observations to a remote Piksi through'
        ' aircraft telemetry via ground control software such as MAVProxy or'
        ' Mission Planner.')
    http_information = String(
        'Skylark - Experimental Piksi Networking\n\n'
        "Skylark is Swift Navigation's Internet service for connecting Piksi receivers without the use of a radio. To receive GPS observations from the closest nearby Piksi base station (within 5km), click Connect to Skylark.\n\n"
    )
    start = Button(label='Start', toggle=True, width=32)
    stop = Button(label='Stop', toggle=True, width=32)
    connected_rover = Bool(False)
    connect_rover = Button(label='Connect to Skylark', toggle=True, width=32)
    disconnect_rover = Button(label='Disconnect from Skylark',
                              toggle=True,
                              width=32)
    base_pragma = String()
    rover_pragma = String()
    base_device_uid = String()
    rover_device_uid = String()
    toggle = True
    view = View(
        VGroup(
            spring,
            HGroup(
                VGroup(
                    Item('running',
                         show_label=True,
                         style='readonly',
                         visible_when='running'),
                    Item('msg_enum',
                         label="Messages to broadcast",
                         style='custom',
                         enabled_when='not running'),
                    Item('ip_ad',
                         label='IP Address',
                         enabled_when='not running'),
                    Item('port', label="Port", enabled_when='not running'),
                    HGroup(
                        spring,
                        UItem('start',
                              enabled_when='not running',
                              show_label=False),
                        UItem('stop', enabled_when='running',
                              show_label=False), spring)),
                VGroup(
                    Item('information',
                         label="Notes",
                         height=10,
                         editor=MultilineTextEditor(
                             TextEditor(multi_line=True)),
                         style='readonly',
                         show_label=False,
                         resizable=True,
                         padding=15),
                    spring,
                ),
            ), spring,
            HGroup(
                VGroup(
                    HGroup(
                        spring,
                        UItem('connect_rover',
                              enabled_when='not connected_rover',
                              show_label=False),
                        UItem('disconnect_rover',
                              enabled_when='connected_rover',
                              show_label=False), spring),
                    HGroup(spring, Item('base_pragma', label='Base option '),
                           Item('base_device_uid', label='Base device '),
                           spring),
                    HGroup(spring, Item('rover_pragma', label='Rover option'),
                           Item('rover_device_uid', label='Rover device'),
                           spring),
                ),
                VGroup(
                    Item('http_information',
                         label="Notes",
                         height=10,
                         editor=MultilineTextEditor(
                             TextEditor(multi_line=True)),
                         style='readonly',
                         show_label=False,
                         resizable=True,
                         padding=15),
                    spring,
                ),
            ), spring))

    def __init__(self,
                 link,
                 device_uid=None,
                 base=DEFAULT_BASE,
                 whitelist=None):
        """
    Traits tab with UI for UDP broadcast of SBP.

    Parameters
    ----------
    link : sbp.client.handler.Handler
      Link for SBP transfer to/from Piksi.
    device_uid : str
      Piksi Device UUID (defaults to None)
    base : str
      HTTP endpoint
    whitelist : [int] | None
      Piksi Device UUID (defaults to None)

    """
        self.link = link
        self.http = HTTPDriver(None, base)
        self.net_link = None
        self.fwd = None
        self.func = None
        # Whitelist used for UDP broadcast view
        self.msgs = OBS_MSGS
        # register a callback when the msg_enum trait changes
        self.on_trait_change(self.update_msgs, 'msg_enum')
        # Whitelist used for Skylark broadcasting
        self.whitelist = whitelist
        self.device_uid = None
        self.python_console_cmds = {'update': self}

    def update_msgs(self):
        """Updates the instance variable msgs which store the msgs that we
    will send over UDP.

    """
        if self.msg_enum == 'Observations':
            self.msgs = OBS_MSGS
        elif self.msg_enum == 'All':
            self.msgs = [None]
        else:
            raise NotImplementedError

    def set_route(self, serial_id, channel=CHANNEL_UUID):
        """Sets serial_id hash for HTTP headers.

    Parameters
    ----------
    serial_id : int
      Piksi device ID
    channel : str
      UUID namespace for device UUID

    """
        device_uid = str(get_uuid(channel, serial_id))
        self.device_uid = device_uid
        if self.http:
            self.http.device_uid = device_uid

    def _prompt_networking_error(self, text):
        """Nonblocking prompt for a networking error.

    Parameters
    ----------
    text : str
      Helpful error message for the user

    """
        prompt = CallbackPrompt(title="Networking Error",
                                actions=[close_button])
        prompt.text = text
        prompt.run(block=False)

    def _prompt_setting_error(self, text):
        """Nonblocking prompt for a device setting error.

    Parameters
    ----------
    text : str
      Helpful error message for the user

    """
        prompt = CallbackPrompt(title="Setting Error", actions=[close_button])
        prompt.text = text
        prompt.run(block=False)

    def _retry_read(self):
        """Retry read connections. Intended to be called by
    _connect_rover_fired.

    """
        i = 0
        repeats = 5
        _rover_pragma = self.rover_pragma
        _rover_device_uid = self.rover_device_uid or self.device_uid
        while self.http and not self.http.connect_read(
                device_uid=_rover_device_uid, pragma=_rover_pragma):
            print "Attempting to read observation from Skylark..."
            time.sleep(0.1)
            i += 1
            if i >= repeats:
                msg = (
                    "\nUnable to receive observations from Skylark!\n\n"
                    "Please check that:\n"
                    " - you have a network connection\n"
                    " - your Piksi has a single-point position\n"
                    " - a Skylark-connected Piksi receiver \n   is nearby (within 5km)"
                )
                self._prompt_networking_error(msg)
                self.http.read_close()
                return
        print "Connected as a rover!"
        with Handler(Framer(self.http.read, self.http.write)) as net_link:
            self.net_link = net_link
            self.fwd = Forwarder(net_link, swriter(self.link))
            self.fwd.start()
            while True:
                time.sleep(1)
                if not net_link.is_alive():
                    sys.stderr.write(
                        "Network observation stream disconnected!")
                    break
        # Unless the user has initiated a reconnection, assume here that the rover
        # still wants to be connected, so if we break out of the handler loop,
        # cleanup rover connection and try reconnecting.
        if self.connected_rover:
            sys.stderr.write("Going for a networking reconnection!")
            self._disconnect_rover_fired()
            self._connect_rover_fired()

    def _connect_rover_fired(self):
        """Handle callback for HTTP rover connections.

    """
        if not self.device_uid:
            msg = "\nDevice ID not found!\n\nConnection requires a valid Piksi device ID."
            self._prompt_setting_error(msg)
            return
        if not self.http:
            self._prompt_networking_error("\nNetworking disabled!")
            return
        try:
            _base_pragma = self.base_pragma
            _base_device_uid = self.base_device_uid or self.device_uid
            if not self.http.connect_write(self.link,
                                           self.whitelist,
                                           device_uid=_base_device_uid,
                                           pragma=_base_pragma):
                msg = ("\nUnable to connect to Skylark!\n\n"
                       "Please check that you have a network connection.")
                self._prompt_networking_error(msg)
                self.http.close()
                self.connected_rover = False
                return
            self.connected_rover = True
            print "Connected as a base station!"
            executor = ThreadPoolExecutor(max_workers=2)
            executor.submit(self._retry_read)
        except:
            self.connected_rover = False
            import traceback
            print traceback.format_exc()

    def _disconnect_rover_fired(self):
        """Handle callback for HTTP rover disconnects.

    """
        if not self.device_uid:
            msg = "\nDevice ID not found!\n\nConnection requires a valid Piksi device ID."
            self._prompt_setting_error(msg)
            return
        if not self.http:
            self._prompt_networking_error("\nNetworking disabled!")
            return
        try:
            if self.connected_rover:
                self.http.close()
                self.connected_rover = False
                if self.fwd and self.net_link:
                    self.net_link.stop()
        except:
            self.connected_rover = False
            import traceback
            print traceback.format_exc()

    def _start_fired(self):
        """Handle start udp broadcast button. Registers callbacks on
    self.link for each of the self.msgs If self.msgs is None, it
    registers one generic callback for all messages.

    """
        self.running = True
        try:
            self.func = UdpLogger(self.ip_ad, self.port)
            self.link.add_callback(self.func, self.msgs)
        except:
            import traceback
            print traceback.format_exc()

    def _stop_fired(self):
        """Handle the stop udp broadcast button. It uses the self.funcs and
    self.msgs to remove the callbacks that were registered when the
    start button was pressed.

    """
        try:
            self.link.remove_callback(self.func, self.msgs)
            self.func.__exit__()
            self.func = None
            self.running = False
        except:
            import traceback
            print traceback.format_exc()
Beispiel #10
0
class BaselineView(HasTraits):
    python_console_cmds = Dict()

    ns = List()
    es = List()
    ds = List()

    table = List()

    plot = Instance(Plot)
    plot_data = Instance(ArrayPlotData)

    running = Bool(True)
    position_centered = Bool(False)

    clear_button = SVGButton(label='',
                             tooltip='Clear',
                             filename=os.path.join(os.path.dirname(__file__),
                                                   'images', 'iconic',
                                                   'x.svg'),
                             width=16,
                             height=16)
    zoomall_button = SVGButton(label='',
                               tooltip='Zoom All',
                               filename=os.path.join(os.path.dirname(__file__),
                                                     'images', 'iconic',
                                                     'fullscreen.svg'),
                               width=16,
                               height=16)
    center_button = SVGButton(label='',
                              tooltip='Center on Baseline',
                              toggle=True,
                              filename=os.path.join(os.path.dirname(__file__),
                                                    'images', 'iconic',
                                                    'target.svg'),
                              width=16,
                              height=16)
    paused_button = SVGButton(
        label='',
        tooltip='Pause',
        toggle_tooltip='Run',
        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=16,
        height=16)

    reset_button = Button(label='Reset Filters')
    reset_iar_button = Button(label='Reset IAR')
    init_base_button = Button(label='Init. with known baseline')

    traits_view = View(
        HSplit(
            Item('table',
                 style='readonly',
                 editor=TabularEditor(adapter=SimpleAdapter()),
                 show_label=False,
                 width=0.3),
            VGroup(
                HGroup(
                    Item('paused_button', show_label=False),
                    Item('clear_button', show_label=False),
                    Item('zoomall_button', show_label=False),
                    Item('center_button', show_label=False),
                    Item('reset_button', show_label=False),
                    Item('reset_iar_button', show_label=False),
                    Item('init_base_button', show_label=False),
                ),
                Item(
                    'plot',
                    show_label=False,
                    editor=ComponentEditor(bgcolor=(0.8, 0.8, 0.8)),
                ))))

    def _zoomall_button_fired(self):
        self.plot.index_range.low_setting = 'auto'
        self.plot.index_range.high_setting = 'auto'
        self.plot.value_range.low_setting = 'auto'
        self.plot.value_range.high_setting = 'auto'

    def _center_button_fired(self):
        self.position_centered = not self.position_centered

    def _paused_button_fired(self):
        self.running = not self.running

    def _reset_button_fired(self):
        self.link.send(SBP_MSG_RESET_FILTERS, '\x00')

    def _reset_iar_button_fired(self):
        self.link.send(SBP_MSG_RESET_FILTERS, '\x01')

    def _init_base_button_fired(self):
        self.link.send(SBP_MSG_INIT_BASE, '')

    def _clear_button_fired(self):
        self.ns = []
        self.es = []
        self.ds = []
        self.plot_data.set_data('n', [])
        self.plot_data.set_data('e', [])
        self.plot_data.set_data('d', [])
        self.plot_data.set_data('t', [])
        self.plot_data.set_data('curr_n', [])
        self.plot_data.set_data('curr_e', [])
        self.plot_data.set_data('curr_d', [])

    def _baseline_callback_ecef(self, data):
        #Don't do anything for ECEF currently
        return

    def iar_state_callback(self, sbp_msg):
        self.num_hyps = struct.unpack('<I', sbp_msg.payload)[0]

    def _baseline_callback_ned(self, sbp_msg):
        # Updating an ArrayPlotData isn't thread safe (see chaco issue #9), so
        # actually perform the update in the UI thread.
        if self.running:
            GUI.invoke_later(self.baseline_callback, sbp_msg)

    def update_table(self):
        self._table_list = self.table.items()

    def gps_time_callback(self, sbp_msg):
        self.week = MsgGPSTime(sbp_msg).wn
        self.nsec = MsgGPSTime(sbp_msg).ns

    def baseline_callback(self, sbp_msg):
        soln = MsgBaselineNED(sbp_msg)
        table = []

        soln.n = soln.n * 1e-3
        soln.e = soln.e * 1e-3
        soln.d = soln.d * 1e-3

        dist = np.sqrt(soln.n**2 + soln.e**2 + soln.d**2)

        tow = soln.tow * 1e-3
        if self.nsec is not None:
            tow += self.nsec * 1e-9

        if self.week is not None:
            t = datetime.datetime(1980, 1, 6) + \
                datetime.timedelta(weeks=self.week) + \
                datetime.timedelta(seconds=tow)

            table.append(('GPS Time', t))
            table.append(('GPS Week', str(self.week)))

            if self.log_file is None:
                self.log_file = open(
                    time.strftime("baseline_log_%Y%m%d-%H%M%S.csv"), 'w')

            self.log_file.write('%s,%.4f,%.4f,%.4f,%.4f,%d,0x%02x,%d\n' %
                                (str(t), soln.n, soln.e, soln.d, dist,
                                 soln.n_sats, soln.flags, self.num_hyps))
            self.log_file.flush()

        table.append(('GPS ToW', tow))

        table.append(('N', soln.n))
        table.append(('E', soln.e))
        table.append(('D', soln.d))
        table.append(('Dist.', dist))
        table.append(('Num. Sats.', soln.n_sats))
        table.append(('Flags', '0x%02x' % soln.flags))
        if soln.flags & 1:
            table.append(('Mode', 'Fixed RTK'))
        else:
            table.append(('Mode', 'Float'))
        table.append(('IAR Num. Hyps.', self.num_hyps))

        self.ns.append(soln.n)
        self.es.append(soln.e)
        self.ds.append(soln.d)

        self.ns = self.ns[-1000:]
        self.es = self.es[-1000:]
        self.ds = self.ds[-1000:]

        self.plot_data.set_data('n', self.ns)
        self.plot_data.set_data('e', self.es)
        self.plot_data.set_data('d', self.ds)
        self.plot_data.set_data('curr_n', [soln.n])
        self.plot_data.set_data('curr_e', [soln.e])
        self.plot_data.set_data('curr_d', [soln.d])
        self.plot_data.set_data('ref_n', [0.0])
        self.plot_data.set_data('ref_e', [0.0])
        self.plot_data.set_data('ref_d', [0.0])

        t = range(len(self.ns))
        self.plot_data.set_data('t', t)

        if self.position_centered:
            d = (self.plot.index_range.high - self.plot.index_range.low) / 2.
            self.plot.index_range.set_bounds(soln.e - d, soln.e + d)
            d = (self.plot.value_range.high - self.plot.value_range.low) / 2.
            self.plot.value_range.set_bounds(soln.n - d, soln.n + d)

        self.table = table

    def __init__(self, link):
        super(BaselineView, self).__init__()

        self.log_file = None

        self.num_hyps = 0

        self.plot_data = ArrayPlotData(n=[0.0],
                                       e=[0.0],
                                       d=[0.0],
                                       t=[0.0],
                                       ref_n=[0.0],
                                       ref_e=[0.0],
                                       ref_d=[0.0],
                                       curr_e=[0.0],
                                       curr_n=[0.0],
                                       curr_d=[0.0])
        self.plot = Plot(self.plot_data)
        lin = self.plot.plot(('e', 'n'), type='line', color=(0, 0, 1, 0.1))
        pts = self.plot.plot(('e', 'n'),
                             type='scatter',
                             color='blue',
                             marker='dot',
                             line_width=0.0,
                             marker_size=1.0)
        ref = self.plot.plot(('ref_e', 'ref_n'),
                             type='scatter',
                             color='red',
                             marker='plus',
                             marker_size=5,
                             line_width=1.5)
        cur = self.plot.plot(('curr_e', 'curr_n'),
                             type='scatter',
                             color='orange',
                             marker='plus',
                             marker_size=5,
                             line_width=1.5)
        plot_labels = [
            'Base Position', 'Rover Relative Position', 'Rover Path'
        ]
        plots_legend = dict(zip(plot_labels, [ref, cur, pts]))
        self.plot.legend.plots = plots_legend
        self.plot.legend.visible = True

        self.plot.index_axis.tick_label_position = 'inside'
        self.plot.index_axis.tick_label_color = 'gray'
        self.plot.index_axis.tick_color = 'gray'
        self.plot.index_axis.title = 'E (meters)'
        self.plot.index_axis.title_spacing = 5
        self.plot.value_axis.tick_label_position = 'inside'
        self.plot.value_axis.tick_label_color = 'gray'
        self.plot.value_axis.tick_color = 'gray'
        self.plot.value_axis.title = 'N (meters)'
        self.plot.value_axis.title_spacing = 5
        self.plot.padding = (25, 25, 25, 25)

        self.plot.tools.append(PanTool(self.plot))
        zt = ZoomTool(self.plot,
                      zoom_factor=1.1,
                      tool_mode="box",
                      always_on=False)
        self.plot.overlays.append(zt)

        self.week = None
        self.nsec = 0

        self.link = link
        self.link.add_callback(self._baseline_callback_ned,
                               SBP_MSG_BASELINE_NED)
        self.link.add_callback(self._baseline_callback_ecef,
                               SBP_MSG_BASELINE_ECEF)
        self.link.add_callback(self.iar_state_callback, SBP_MSG_IAR_STATE)
        self.link.add_callback(self.gps_time_callback, SBP_MSG_GPS_TIME)

        self.python_console_cmds = {'baseline': self}
Beispiel #11
0
class LS(HasTraits):
    '''Limit state class:
    Evaluation of the hinge forces linking the roof domains. 
    '''

    # backward link to the info shell to access the
    # input data when calculating
    # the limit-state-specific values
    #
    ls_table = WeakRef

    #-------------------------------
    # ls columns
    #-------------------------------
    # defined in the subclasses
    #
    ls_columns = List

    #-------------------------------
    # sr columns
    #-------------------------------

    # stress resultant columns - for ULS this is defined in the subclasses
    #
    sr_columns = List([])

    #-------------------------------
    # geo columns form info shell
    #-------------------------------

    #    geo_columns = List( [ 'elem_no' ] )
    geo_columns = List([])

    #    elem_no = Property( Float )
    #        return self.ls_table.elem_no

    #-------------------------------
    # state columns form info shell
    #-------------------------------
    geo_columns = List(['X_hf', 'Y_hf', 'Z_hf'])
    state_columns = List(['N_ip', 'V_ip', 'V_op'])

    N_ip = Property(Float)

    def _get_N_ip(self):
        return self.ls_table.N_ip

    V_ip = Property(Float)

    def _get_V_ip(self):
        return self.ls_table.V_ip

    V_op = Property(Float)

    def _get_V_op(self):
        return self.ls_table.V_op

    X_hf = Property(Array)

    def _get_X_hf(self):
        return self.ls_table.X_hf

    Y_hf = Property(Array)

    def _get_Y_hf(self):
        return self.ls_table.Y_hf

    Z_hf = Property(Array)

    def _get_Z_hf(self):
        return self.ls_table.Z_hf

    #-------------------------------
    # ls table
    #-------------------------------

    # all columns associated with the limit state including the corresponding
    # stress resultants
    #
    columns = Property(List)

    @cached_property
    def _get_columns(self):
        columns = self.geo_columns \
                + self.state_columns \
                + self.sr_columns \
                + self.ls_columns

        return columns

    hf_columns = Property(List)

    @cached_property
    def _get_hf_columns(self):
        return ['sym', 'r0_r1']

    sym = Property

    def _get_sym(self):
        return 'sym'

    r0_r1 = Property

    def _r0_r1(self):
        return 'r0_r1'

    # select column used for sorting the data in selected sorting order
    #
    sort_column = Enum(values='columns')

    def _sort_column_default(self):
        return self.columns[-1]

    sort_order = Enum('descending', 'ascending', 'unsorted')

    #-------------------------------------------------------
    # get the maximum value of the selected variable
    # 'max_in_column' of the current sheet (only one sheet)
    #-------------------------------------------------------

    # get the maximum value of the chosen column
    #
    max_in_column = Enum(values='columns')

    def _max_in_column_default(self):
        return self.columns[-1]

    max_value = Property(depends_on='max_in_column')

    def _get_max_value(self):
        col = getattr(self, self.max_in_column)[:, 0]
        return max(col)

    #-------------------------------------------------------
    # get ls_table for View
    #-------------------------------------------------------

    # stack columns together for table used by TabularEditor
    #
    ls_array = Property(Array, depends_on='sort_column, sort_order')

    @cached_property
    def _get_ls_array(self):

        arr_list = [getattr(self, col) for col in self.columns]

        # get the array currently selected by the sort_column enumeration
        #
        sort_arr = getattr(self, self.sort_column)[:, 0]
        sort_idx = argsort(sort_arr)
        ls_array = hstack(arr_list)

        if self.sort_order == 'descending':
            return ls_array[sort_idx[::-1]]
        if self.sort_order == 'ascending':
            return ls_array[sort_idx]
        if self.sort_order == 'unsorted':
            return ls_array

    #---------------------------------
    # plot outputs in mlab-window
    #---------------------------------

    plot_column = Enum(values='columns')
    plot_3D = Button

    def _plot_3D_fired(self):
        X = self.X_hf[:, 0]
        Y = self.Y_hf[:, 0]
        Z = self.Z_hf[:, 0]

        plot_col = getattr(self, self.plot_column)[:, 0]
        scale = 1 / max(plot_col)
        #        if self.plot_column == 'n_tex':
        #            plot_col = where( plot_col < 0, 0, plot_col )

        mlab.figure(figure="SFB532Demo",
                    bgcolor=(1.0, 1.0, 1.0),
                    fgcolor=(0.0, 0.0, 0.0))

        mlab.points3d(
            X,
            Y,
            (-1.0) * Z,
            plot_col,
            #                       colormap = "gist_rainbow",
            #                       colormap = "Reds",
            colormap="copper",
            mode="cube",
            scale_factor=scale)
        mlab.outline()

        mlab.scalarbar(title=self.plot_column, orientation='vertical')

        mlab.show

        plot_column = Enum(values='columns')

    plot_max_Value = Button

    def _plot_max_Value(self):
        X = self.X_hf[:, 0]
        Y = self.Y_hf[:, 0]
        Z = self.Z_hf[:, 0]

        plot_col = getattr(self, self.plot_column)[:, 0]
        scale = 1 / max(plot_col)
        #        if self.plot_column == 'n_tex':
        #            plot_col = where( plot_col < 0, 0, plot_col )

        mlab.figure(figure="SFB532Demo",
                    bgcolor=(1.0, 1.0, 1.0),
                    fgcolor=(0.0, 0.0, 0.0))

        mlab.points3d(
            X,
            Y,
            (-1.0) * Z,
            plot_col,
            #                       colormap = "gist_rainbow",
            #                       colormap = "Reds",
            colormap="copper",
            mode="cube",
            scale_factor=scale)
        mlab.outline()

        mlab.scalarbar(title=self.plot_column, orientation='vertical')

        mlab.show

    plot_hf_columns = Enum(values='hf_columns')
    plot_hf = Button

    def _plot_hf_fired(self):
        X = self.X_hf[:, 0]
        Y = self.Y_hf[:, 0]
        Z = self.Z_hf[:, 0]
        pyplot.ioff()
        plot_col = self.plot_hf_columns
        if plot_col == 'sym':
            idx = where(Y == 8.0)
            x_bar = X[idx]
            x_label = 'X [m]'

        if plot_col == 'r0_r1':
            idx = where(X == 8.0)
            x_bar = Y[idx]
            x_label = 'Y [m]'

        N_ip = self.N_ip[idx]
        V_op = self.V_op[idx]

        #        pyplot.clf()
        fig = pyplot.figure(facecolor="white")
        ax1 = fig.add_subplot(1, 1, 1)
        width = 0.05
        ax1.bar(x_bar - width / 2,
                N_ip,
                width,
                align='center',
                color='blue',
                label='$N_{ip}$')
        ax1.bar(x_bar + width / 2,
                V_op,
                width,
                align='center',
                color='red',
                label='$V_{op}$')
        ax1.set_xlabel(x_label, fontsize=22)
        ax1.set_ylabel('$F_{int}$ [kN]', fontsize=22)
        #        ax1.set_title( 'At axis' + plot_col )
        ax1.set_xlim(0, max(x_bar))

        ax1.legend()
        pyplot.show()

        #        fig.savefig(plot_col)
        #        fig.savefig(facecolor = 'w', edgecolor = 'w',
        #                       orientation = 'portrait')
        pyplot.clf()

    # name of the trait that is used to assess the evaluated design
    #
    assess_name = Str('')

    #-------------------------------
    # ls group
    #-------------------------------

    # @todo: the dynamic selection of the columns to be displayed
    # does not work in connection with the LSArrayAdapter
    ls_group = VGroup(
        HGroup(  #Item( 'assess_name' ),
            Item('max_in_column'),
            Item('max_value', style='readonly', format_str='%6.2f'),
        ),
        HGroup(
            Item('sort_column'),
            Item('sort_order'),
            Item('plot_column'),
            Item('plot_3D'),
            Item('plot_hf_columns'),
            Item('plot_hf'),
        ),
    )
Beispiel #12
0
class ULS(LS):
    '''Ultimate limit state
    Hinge_forces
    '''

    #--------------------------------------------------------
    # ULS: material parameters (Inputs)
    #--------------------------------------------------------

    # gamma-factor
    gamma_N = Float(1.0, input=True)
    gamma_V = Float(1.0, input=True)

    # characteristic shear resistance
    V_Rk = Float(20.0, input=True)

    # characteristic pull-out resistance
    N_Rk = Float(11.3, input=True)

    # ------------------------------------------------------------
    # ULS - derived params:
    # ------------------------------------------------------------

    V_Rd = Property(Float)

    def _get_V_Rd(self):
        return self.V_Rk / self.gamma_N

    N_Rd = Property(Float)

    def _get_N_Rd(self):
        return self.N_Rk / self.gamma_V

    # ------------------------------------------------------------
    # ULS: outputs
    # ------------------------------------------------------------

    ls_columns = List([])

    sr_columns = ['eta_N', 'eta_V', 'eta_tot']

    ls_case = []

    conection_type = 'glued_bar'

    ls_values = Property(depends_on='+input')

    @cached_property
    def _get_ls_values(self):
        '''get the outputs for ULS
        '''
        V_ed = self.N_ip / 2
        N_ed = self.V_op * 2
        print "shape", self.N_ip.shape
        #        N = sqrt( N_ip ** 2 + V_ip ** 2 )
        #        N = N_ip
        #        V = V_op

        # eta
        eta_N = abs(N_ed / self.N_Rd)
        eta_V = abs(V_ed / self.V_Rd)

        eta_tot = (eta_V + eta_N) / 1.2
        print "eta_tot", eta_tot.shape
        eta_tot = where(eta_tot < eta_V, eta_V, eta_tot)
        eta_tot = where(eta_tot < eta_N, eta_N, eta_tot)

        return {'eta_N': eta_N, 'eta_V': eta_V, 'eta_tot': eta_tot}

    eta_N = Property

    def _get_eta_N(self):
        return self.ls_values['eta_N']

    eta_V = Property

    def _get_eta_V(self):
        return self.ls_values['eta_V']

    eta_tot = Property

    def _get_eta_tot(self):
        return self.ls_values['eta_tot']

    assess_name = 'max_eta_tot'

    max_eta_tot = Property(depends_on='+input')

    @cached_property
    def _get_max_eta_tot(self):
        return ndmax(self.eta_tot)

    #-------------------------------
    # ls view
    #-------------------------------

    # @todo: the dynamic selection of the columns to be displayed
    # does not work in connection with the LSArrayAdapter
    traits_view = View(VGroup(
        HGroup(
            VGroup(Item(name='gamma_N',
                        label='safety factor normal force [-]:  gamma_N '),
                   Item(name='gamma_V',
                        label='safety factor shear force [-]:  gamma_V '),
                   label='safety factors'),
            VGroup(Item(name='V_Rk',
                        label='characteristic shear resistance [MPa]:  V_Rk ',
                        format_str="%.1f"),
                   Item(name='N_Rk',
                        label='characteristic axial resistance [MPa]:  N_Rk ',
                        format_str="%.1f"),
                   label='resistance'),
        ),
        VGroup(
            Include('ls_group'),
            Item('ls_array',
                 show_label=False,
                 editor=TabularEditor(adapter=LSArrayAdapter()))),
    ),
                       resizable=True,
                       scrollable=True,
                       height=1000,
                       width=1100)
Beispiel #13
0
class SLS(LS):
    '''Serviceability limit state
    '''

    # ------------------------------------------------------------
    # SLS: material parameters (Inputs)
    # ------------------------------------------------------------

    # tensile strength [MPa]
    f_ctk = Float(4.0, input=True)

    # flexural tensile strength [MPa]
    f_m = Float(5.0, input=True)

    # ------------------------------------------------------------
    # SLS - derived params:
    # ------------------------------------------------------------

    # area
    #
    A = Property(Float)

    def _get_A(self):
        return self.ls_table.D_elem * 1.

    # moment of inertia
    #
    W = Property(Float)

    def _get_W(self):
        return 1. * self.ls_table.D_elem**2 / 6.

    # ------------------------------------------------------------
    # SLS: outputs
    # ------------------------------------------------------------

    ls_columns = List([
        'sig_n',
        'sig_m',
        'eta_n',
        'eta_m',
        'eta_tot',
    ])

    ls_values = Property(depends_on='+input')

    @cached_property
    def _get_ls_values(self):
        '''get the outputs for SLS
        '''
        n = self.n
        m = self.m

        A = self.A
        W = self.W
        f_ctk = self.f_ctk
        f_m = self.f_m

        sig_n = n / A / 1000.
        sig_m = abs(m / W) / 1000.
        eta_n = sig_n / f_ctk
        eta_m = sig_m / f_m
        eta_tot = eta_n + eta_m

        return {
            'sig_n': sig_n,
            'sig_m': sig_m,
            'eta_n': eta_n,
            'eta_m': eta_m,
            'eta_tot': eta_tot
        }

    sig_n = Property

    def _get_sig_n(self):
        return self.ls_values['sig_n']

    sig_m = Property

    def _get_sig_m(self):
        return self.ls_values['sig_m']

    eta_n = Property

    def _get_eta_n(self):
        return self.ls_values['eta_n']

    eta_m = Property

    def _get_eta_m(self):
        return self.ls_values['eta_m']

    eta_tot = Property

    def _get_eta_tot(self):
        return self.ls_values['eta_tot']

    assess_name = 'max_eta_tot'

    #    assess_name = 'max_sig1_up'
    #
    #    max_sig1_up = Property( depends_on = '+input' )
    #    @cached_property
    #    def _get_max_sig1_up( self ):
    #        return ndmax( self.sig1_up )

    # @todo: make it possible to select the assess value:
    #
    #    assess_name = Enum( values = 'columns' )
    #    def _assess_name_default( self ):
    #        return self.columns[-1]

    max_eta_tot = Property(depends_on='+input')

    @cached_property
    def _get_max_eta_tot(self):
        return ndmax(self.eta_tot)

    #-------------------------------
    # ls view
    #-------------------------------

    # @todo: the dynamic selection of the columns to be displayed
    # does not work in connection with the LSArrayAdapter
    traits_view = View(
        VGroup(
            HGroup(
                Item(name='f_ctk',
                     label='Tensile strength concrete [MPa]: f_ctk '),
                Item(name='f_m',
                     label='Flexural tensile trength concrete [MPa]: f_m ')),
            VGroup(
                Include('ls_group'),

                # @todo: currently LSArrayAdapter must be called both
                #        in SLS and ULS separately to configure columns
                #        arrangement individually
                #
                Item('ls_array',
                     show_label=False,
                     editor=TabularEditor(adapter=LSArrayAdapter()))),
        ),
        resizable=True,
        scrollable=True,
        height=1000,
        width=1100)
Beispiel #14
0
class Ellipsoid(BaseMirror):
    name = "Ellipsoid"
    abstract = False
    focus1 = Tuple(-50., 0., 0.)
    focus2 = Tuple(0., 50., 0.)
    size = Float(100.0,
                 desc="twice the major axis length, or the distance from one\
 focus to the ellipsoid edge to the other focus")
    X_bounds = MinMax(-25., 25.)
    Y_bounds = MinMax(-25., 25.)
    Z_bounds = MinMax(0., 50.)

    show_foci = Bool(True)
    foci_Actors = Instance(tvtk.ActorCollection, ())

    axes = Property(Tuple,
                    depends_on="focus1, focus2, size",
                    desc="(major, minor) axis lengths")

    ellipse_trans = Instance(tvtk.Transform, (), transient=True)

    combined_trans = Instance(tvtk.Transform, transient=True)

    f1_glyph = Instance(tvtk.SphereSource, (), transient=True)
    f2_glyph = Instance(tvtk.SphereSource, (), transient=True)

    f1_act = Instance(tvtk.Follower, (), transient=True)
    f2_act = Instance(tvtk.Follower, (), transient=True)

    vtk_grid = Instance(EmptyGridSource, (), transient=True)
    vtk_quadric = Instance(tvtk.Quadric, (), transient=True)

    vtkproperty = tvtk.Property(opacity=0.7, color=(0.8, 0.8, 0))

    traits_view = View(
        VGroup(Traceable.uigroup, Item("focus1", editor=VectorEditor),
               Item("focus2", editor=VectorEditor), Item("show_foci"),
               Item("size", editor=NumEditor), Item("X_bounds"),
               Item("Y_bounds"), Item("Z_bounds")), )

    def _faces_default(self):
        facelist = FaceList(owner=self)
        facelist.faces = [
            EllipsoidalFace(owner=self,
                            x1=self.X_bounds[0],
                            x2=self.X_bounds[1],
                            y1=self.Y_bounds[0],
                            y2=self.Y_bounds[1],
                            z1=self.Z_bounds[0],
                            z2=self.Z_bounds[1],
                            major=self.axes[0],
                            minor=self.axes[1])
        ]
        return facelist

    @on_trait_change("focus1, focus2, size")
    def config_trans(self, *args):
        f1 = numpy.asarray(self.focus1)
        f2 = numpy.asarray(self.focus2)
        size = self.size
        centre = (f2 + f1) / 2.
        ellipse_t = self.ellipse_trans
        ellipse_t.identity()
        #ellipse major axis along the X axis
        delta = f2 - f1
        ax = normaliseVector(delta)
        axy = numpy.sqrt(ax[0]**2 + ax[1]**2)
        ellipse_t.rotate_y(numpy.arctan2(ax[2], axy) * 180 / numpy.pi)

        ellipse_t.rotate_z(-numpy.arctan2(ax[1], ax[0]) * 180 / numpy.pi)

        ellipse_t.translate(*-centre)

    @cached_property
    def _get_axes(self):
        f1 = numpy.asarray(self.focus1)
        f2 = numpy.asarray(self.focus2)
        delta = f2 - f1
        size = self.size
        h = numpy.sqrt((delta**2).sum())
        a = size / 2.
        b = 0.5 * numpy.sqrt(size**2 - h**2)
        return (a, b)

    def _combined_trans_default(self):
        t = tvtk.Transform()
        t.concatenate(self.transform)
        t.concatenate(self.ellipse_trans.linear_inverse)
        return t

    def _show_foci_changed(self, val):
        for act in self.foci_Actors:
            act.visibility = val
        self.render = True

    def update_grid(self):
        xmin, xmax = self.X_bounds
        ymin, ymax = self.Y_bounds
        zmin, zmax = self.Z_bounds

        source = self.vtk_grid
        size = 20
        dx = (xmax - xmin) / (size - 1)
        dy = (ymax - ymin) / (size - 1)
        dz = (zmax - zmin) / (size - 1)
        source.dimensions = (size, size, size)
        source.origin = (xmin, ymin, zmin)
        source.spacing = (dx, dy, dz)

    @on_trait_change("X_bounds, Y_bounds, Z_bounds")
    def change_bounds(self):
        self.update_grid()
        self.vtk_grid.modified()
        self.update = True

    @on_trait_change("focus1, focus2, size")
    def config_pipeline(self, *args):
        tp = self.transform.transform_point
        self.f1_act.position = tp(self.focus1)
        self.f2_act.position = tp(self.focus2)

        f1 = numpy.asarray(self.focus1)
        f2 = numpy.asarray(self.focus2)

        self.f1_glyph.center = f1
        self.f2_glyph.center = f2

        centre = (f2 + f1) / 2.
        ellipse_t = self.ellipse_trans
        ellipse_t.identity()
        #ellipse major axis along the X axis
        delta = f2 - f1
        ax = normaliseVector(delta)
        axy = numpy.sqrt(ax[0]**2 + ax[1]**2)
        ellipse_t.rotate_y(numpy.arctan2(ax[2], axy) * 180 / numpy.pi)

        ellipse_t.rotate_z(-numpy.arctan2(ax[1], ax[0]) * 180 / numpy.pi)

        ellipse_t.translate(*-centre)

        a, b = self.axes
        #b = 0.5 * numpy.sqrt(size**2 - h**2)  ##not required

        q = self.vtk_quadric
        A1 = A2 = 1 / (b**2)
        A0 = 1 / (a**2)
        #A8 = 1
        A9 = -1
        q.coefficients = (A0, A1, A2, 0, 0, 0, 0, 0, 0, A9)
        self.update = True

    def _pipeline_default(self):
        grid = self.vtk_grid
        #grid.set_execute_method(self.create_grid)
        grid.modified()

        quad = self.vtk_quadric
        quad.transform = self.ellipse_trans

        clip = tvtk.ClipVolume(input_connection=grid.output_port,
                               clip_function=quad,
                               inside_out=0)

        topoly = tvtk.GeometryFilter(input_connection=clip.output_port)
        norm = tvtk.PolyDataNormals(input_connection=topoly.output_port)
        transF = tvtk.TransformFilter(input_connection=norm.output_port,
                                      transform=self.transform)
        self.config_pipeline()
        grid.modified()
        return transF

    def get_actors(self, scene):
        actors = []

        sList = [self.f1_glyph, self.f2_glyph]
        cList = [(0, 1, 0), (1, 0, 0)]

        for s, c in zip(sList, cList):
            s.radius = 1.0
            map = tvtk.PolyDataMapper(input_connection=s.output_port)
            act = tvtk.Actor(mapper=map, user_transform=self.transform)
            act.property.color = c
            actors.append(act)

        line = tvtk.LineSource(point1=(-100, 0, 0), point2=(100, 0, 0))
        t_line = tvtk.TransformFilter(
            input_connection=line.output_port,
            transform=self.ellipse_trans.linear_inverse)
        map = tvtk.PolyDataMapper(input_connection=t_line.output_port)
        act = tvtk.Actor(mapper=map, user_transform=self.transform)
        act.property.color = (0, 0, 0)
        actors.append(act)

        l1 = tvtk.VectorText(text="F1")
        l2 = tvtk.VectorText(text="F2")
        m1 = tvtk.PolyDataMapper(input_connection=l1.output_port)
        m2 = tvtk.PolyDataMapper(input_connection=l2.output_port)
        act1 = self.f1_act
        act2 = self.f2_act

        act1.mapper = m1
        act2.mapper = m2

        scale = (5, 5, 5)
        act1.scale = scale
        act2.scale = scale

        act1.property.color = (0, 0, 0)
        act2.property.color = (0, 0, 0)

        act1.position = self.focus1
        act2.position = self.focus2

        def on_editor(new_ed):
            if new_ed is not None:
                act1.camera = new_ed._camera
                act2.camera = new_ed._camera

        scene.on_trait_change(on_editor, "scene_editor")

        actors.append(act1)
        actors.append(act2)

        for actor in actors:
            self.actors.append(actor)
            self.foci_Actors.append(actor)
            actor.visibility = self.show_foci

        return self.actors

    def make_step_shape(self):
        from raytrace.step_export import make_ellipsoid_mirror
        ell = make_ellipsoid_mirror(self.focus1, self.focus2, self.size / 2.,
                                    self.X_bounds, self.Y_bounds,
                                    self.Z_bounds, self.centre, self.direction,
                                    self.x_axis)
        return ell, "yellow"
    def traits_view(self):
        cols = [
            ObjectColumn(name='name', editable=False),
            ObjectColumn(name='value', format='%0.7f', width=100),
            ObjectColumn(name='error', format='%0.7f', width=100)
        ]

        det_cols = [
            ObjectColumn(name='name', editable=False),
            ObjectColumn(name='detector', editable=False),
            ObjectColumn(name='value', format='%0.7f', width=100),
            ObjectColumn(name='error', format='%0.7f', width=100)
        ]

        iso_grp = VGroup(UItem('isotopes',
                               editor=TableEditor(columns=cols,
                                                  sortable=False)),
                         label='Intercepts',
                         show_border=True)

        baseline_grp = VGroup(UItem('baselines',
                                    editor=TableEditor(sortable=False,
                                                       columns=det_cols)),
                              label='Baselines',
                              show_border=True)

        blank_grp = VGroup(UItem('blanks',
                                 editor=TableEditor(sortable=False,
                                                    columns=cols)),
                           label='Blanks',
                           show_border=True,
                           defined_when='blanks')

        icgrp = VGroup(UItem('ic_factors',
                             editor=TableEditor(sortable=False,
                                                columns=det_cols)),
                       label='IC Factors',
                       show_border=True,
                       defined_when='ic_factors')

        bgrp = HGroup(
            icon_button_editor('revert_button',
                               'arrow_undo',
                               tooltip='Undo changes',
                               enabled_when='dirty'),
            icon_button_editor('revert_original_button',
                               'arrow_left',
                               tooltip='Revert to original values'),
            icon_button_editor('save_button',
                               'disk',
                               enabled_when='dirty',
                               tooltip='Save changes'), spring)
        flux_grp = HGroup(UItem('object.flux.value'),
                          Label(PLUSMINUS),
                          UItem('object.flux.error'),
                          label='Flux (J)',
                          defined_when='object.flux',
                          show_border=True)
        v = View(VGroup(Group(iso_grp, baseline_grp, icgrp, layout='tabbed'),
                        blank_grp, flux_grp, bgrp),
                 buttons=['OK', 'Cancel'],
                 handler=AnalysisEditViewHandler(),
                 resizable=True,
                 title=self.title,
                 x=0.05,
                 y=0.05)

        return v
Beispiel #16
0
class LS(HasTraits):
    '''Limit state class
    '''

    # backward link to the info shell to access the
    # input data when calculating 
    # the limit-state-specific values
    #
    ls_table = WeakRef

    #-------------------------------
    # ls columns
    #-------------------------------
    # defined in the subclasses
    #
    ls_columns = List
    show_ls_columns = Bool(True)

    #-------------------------------
    # geo columns from info shell
    #-------------------------------

    geo_columns = List([ 'node_no' ])
    show_geo_columns = Bool(True)

    node_no = Property(Array)
    def _get_node_no(self):
        return self.ls_table.node_no

    #-------------------------------
    # state columns from info shell
    #-------------------------------

    state_columns = List(['Rx', 'Ry', 'Rz', 'Mx', 'My', 'Mz' ])

    show_state_columns = Bool(True)

    # forces at the supports [kN]
    #
    Rx = Property(Array)
    def _get_Rx(self):
        return self.ls_table.Rx

    Ry = Property(Array)
    def _get_Ry(self):
        return self.ls_table.Ry

    Rz = Property(Array)
    def _get_Rz(self):
        return self.ls_table.Rz

    # moments at the supports [kNm]
    #
    Mx = Property(Array)
    def _get_Mx(self):
        return self.ls_table.Mx

    My = Property(Array)
    def _get_My(self):
        return self.ls_table.My

    Mz = Property(Array)
    def _get_Mz(self):
        return self.ls_table.Mz

    #-------------------------------
    # ls table
    #-------------------------------

    # all columns associated with the limit state including the corresponding
    # stress resultants
    #
    columns = Property(List, depends_on='show_geo_columns, show_state_columns, show_ls_columns')
    @cached_property
    def _get_columns(self):
        columns = []

        if self.show_geo_columns:
            columns += self.geo_columns

        if self.show_state_columns:
            columns += self.state_columns

        if self.show_ls_columns:
            columns += self.ls_columns

        return columns

    # select column used for sorting the data in selected sorting order 
    #
    sort_column = Enum(values='columns')
    def _sort_column_default(self):
        return self.columns[-1]

    sort_order = Enum('descending', 'ascending', 'unsorted')

    #-------------------------------------------------------
    # get the maximum value of the selected variable 
    # 'max_in_column' of the current sheet (only one sheet)
    #-------------------------------------------------------

    # get the maximum value of the chosen column
    #
    max_in_column = Enum(values='columns')
    def _max_in_column_default(self):
        return self.columns[-1]

    max_value = Property(depends_on='max_in_column')
    def _get_max_value(self):
        col = getattr(self, self.max_in_column)[:, 0]
        return max(col)

    #-------------------------------------------------------
    # get the maximum value and the corresponding case of 
    # the selected variable 'max_in_column' in all (!) sheets
    #-------------------------------------------------------

    max_value_all = Property(depends_on='max_in_column')
    def _get_max_value_all(self):
        return self.ls_table.max_value_and_case[ self.max_in_column ]['max_value']

    max_case = Property(depends_on='max_in_column')
    def _get_max_case(self):
        return self.ls_table.max_value_and_case[ self.max_in_column ]['max_case']

    #-------------------------------------------------------
    # get ls_table for View
    #-------------------------------------------------------

    # stack columns together for table used by TabularEditor
    #
    ls_array = Property(Array, depends_on='sort_column, sort_order, \
                                              show_geo_columns, \
                                              show_state_columns, \
                                              show_ls_columns')

    @cached_property
    def _get_ls_array(self):

        arr_list = [ getattr(self, col) for col in self.columns ]

        # get the array currently selected by the sort_column enumeration
        #
        sort_arr = getattr(self, self.sort_column)[:, 0]
        sort_idx = argsort(sort_arr)
        ls_array = hstack(arr_list)

        if self.sort_order == 'descending':
            return ls_array[ sort_idx[::-1] ]
        if self.sort_order == 'ascending':
            return ls_array[ sort_idx ]
        if self.sort_order == 'unsorted':
            return ls_array

    #---------------------------------
    # plot outputs in mlab-window 
    #---------------------------------
    warp_factor = Float(1000., input=True)

    plot_column = Enum(values='columns')
    plot = Button
    def _plot_fired(self):

        plot_col = getattr(self, self.plot_column)[:, 0]

        mlab.figure(figure="SFB532Demo",
                     bgcolor=(1.0, 1.0, 1.0),
                     fgcolor=(0.0, 0.0, 0.0))

        gd = self.ls_table.geo_data
        sd = self.ls_table.state_data

        if self.plot_column == 'n_tex':
            plot_col = where(plot_col < 0, 0, plot_col)

        r = self.ls_table.reader
        r.plot_col(mlab, plot_col, gd, state_data=sd, warp_factor=self.warp_factor)

        mlab.scalarbar(title=self.plot_column, orientation='vertical')
        mlab.show

    # name of the trait that is used to assess the evaluated design
    #
    assess_name = Property(Str)
    def _get_assess_name(self):
        return self.ls_table.assess_name

    #-------------------------------
    # ls group
    #-------------------------------

    # @todo: the dynamic selection of the columns to be displayed 
    # does not work in connection with the LSArrayAdapter 
    ls_group = VGroup(
                        HGroup(#Item( 'assess_name' ),
                                Item('max_in_column'),
                                Item('max_value', style='readonly', format_str='%6.2f'),
                              ),
                        HGroup(Item('sort_column'),
                                Item('sort_order'),
                                Item('show_geo_columns', label='show geo'),
                                Item('show_state_columns', label='show state'),
                                Item('show_ls_columns', label='show ls'),
                                Item('plot_column'),
                                Item('plot'),
                                Item('warp_factor')
                              ),
                     )
Beispiel #17
0
class PylayersGUI(HasTraits):

    # slider/dropdown widgets etc

    # Layout
    laynames = [''] + np.sort(os.listdir(basename + '/struc/lay/')).tolist(
    )  #['','DLR.lay','defstr.lay','TC2_METIS.lay']#,
    Lay_Enum = Enum(laynames)

    ## Antenna file :
    av_ant = ['Omni', 'Gauss', 'aperture']
    antext = ['vsh3', 'sh3']
    for fname in os.listdir(basename + '/ant'):
        if fname.split('.')[-1] in antext:
            av_ant.append(fname)

    # Init Positions
    xmin = DL.L.ax[0]
    xmax = DL.L.ax[1]
    ymin = DL.L.ax[2]
    ymax = DL.L.ax[3]
    zmin = 0.
    zmax = DL.L.maxheight - 0.1
    # Antenna

    ## position a
    aX = Range(low='xmin', high='xmax', value=float(xmin + xmax / 2.))
    aY = Range(low='ymin', high='ymax', value=float(ymin + ymax / 2.))
    aZ = Range(low='zmin', high='zmax', value=float(zmin + zmax / 2.))

    ## rotation a
    agamma = Range(
        float(-3.14),
        float(3.14),
        0.,
    )  #mode='spinner')
    abeta = Range(
        float(-3.14),
        float(3.14),
        0.,
    )  #mode='spinner')
    aalpha = Range(
        float(-3.14),
        float(3.14),
        0.,
    )  #mode='spinner')

    ## file a:

    a_ant = Enum(av_ant)

    # Antenna B
    ## position b
    bX = Range(low='xmin', high='xmax', value=float(xmin + xmax / 2.))
    bY = Range(low='ymin', high='ymax', value=float(ymin + ymax / 2.))
    bZ = Range(low='zmin', high='zmax', value=float(zmin + zmax / 2.))

    ## rotation b

    bgamma = Range(
        float(-3.14),
        float(3.14),
        0.,
    )  #mode='spinner')
    bbeta = Range(
        float(-3.14),
        float(3.14),
        0.,
    )  #mode='spinner')
    balpha = Range(
        float(-3.14),
        float(3.14),
        0.,
    )  #mode='spinner')

    ## file b:
    b_ant = Enum(av_ant)

    # frequency

    fmmin = 0.
    fmmax = 300.

    fmin = Range(low='fmmin', high='fmmax', value=float(DL.Aa.fGHz[0]))
    fmax = Range(low='fmmin', high='fmmax', value=float(DL.Aa.fGHz[-1]))
    fstep = Range(low=0, high=10, value=0)

    # advanced

    # init interface
    scene = Instance(MlabSceneModel, ())

    plot = Instance(PipelineBase)

    # @on_trait_change('scene.activated')
    # def init_plot(self):
    #     DL._show3()
    # When the scene is activated, or when the parameters are changed, we
    # update the plot.

    # def _open_changed(self):
    #     """ Handles the user clicking the 'Open...' button.
    #     """
    #     path = pyu.getlong('',pstruc['DIRSTR'])
    #     file_name = open_file(file_name= path ,extensions = FileInfo())
    #     if file_name != '':
    #         self.file_name = file_name

    @on_trait_change('Lay_Enum')
    def update_L(self):
        if self.Lay_Enum != ' ':
            mlab.clf()
            DL.L = Layout(self.Lay_Enum, bgraphs=True)

            self.xmin = DL.L.ax[0]
            self.xmax = DL.L.ax[1]
            self.ymin = DL.L.ax[2]
            self.ymax = DL.L.ax[3]
            self.zmin = 0.
            self.zmax = DL.L.maxheight - 0.1

            self.aX, self.aY, self.aZ = DL.a
            self.bX, self.bY, self.bZ = DL.b

            DL.a = np.array([self.aX, self.aY, self.aZ])
            DL.b = np.array([self.bX, self.bY, self.bZ])
            self.cutoff = DL.cutoff
            if not hasattr(DL, '_maya_fig'):
                DL._show3()

    @on_trait_change('cutoff,threshold')
    def update_cutoff_threshold(self):
        """ update position ant a
        """
        DL.cutoff = self.cutoff

        DL.threshold = self.threshold / 100.

    @on_trait_change('aX,aY,aZ')
    def update_a(self):
        """ update position ant a
        """
        self.clear_fig()
        DL.a = np.array([self.aX, self.aY, self.aZ])
        self.cutoff = DL.cutoff

    @on_trait_change('bX,bY,bZ')
    def update_b(self):
        """ update position ant b
        """
        self.clear_fig()
        DL.b = np.array([self.bX, self.bY, self.bZ])
        self.cutoff = DL.cutoff

    @on_trait_change('aalpha,abeta,agamma')
    def update_Ta(self):
        """ update rot ant a
        """
        T = geu.MEulerAngle(self.aalpha, beta=self.abeta, gamma=self.agamma)
        DL.Ta = T
        self.clear_fig()
        # if DL.dexist['Ct']['exist']:
        #     DL.C.locbas(Tt=DL.Ta, Tr=DL.Tb)
        #     #T channel
        #     DL.H = DL.C.prop2tran(a=DL.Aa,b=DL.Ab,Friis=True)
        #     self.plt_all()

    @on_trait_change('balpha,bbeta,bgamma')
    def update_Tb(self):
        """ update rot ant b
        """
        T = geu.MEulerAngle(self.balpha, beta=self.bbeta, gamma=self.bgamma)
        DL.Tb = T
        self.clear_fig()

    @on_trait_change('a_ant,fmin,fmax,fstep')
    def update_Aa(self):
        DL.Aa = Antenna(self.a_ant)
        self.clear_fig()
        # if DL.Aa.fromfile:
        #     self.fmin=DL.Aa.fGHz[0]
        #     self.fmax=DL.Aa.fGHz[-1]
        #     self.fstep=min(1,DL.Aa.fGHz[1]-DL.Aa.fGHz[0])

    @on_trait_change('b_ant,fmin,fmax,fstep')
    def update_Ab(self):
        DL.Ab = Antenna(self.b_ant)
        self.clear_fig()

        # if DL.Ab.fromfile:
        #     self.fmin=DL.Ab.fGHz[0]
        #     self.fmax=DL.Ab.fGHz[-1]
        #     self.fstep=min(1,DL.Ab.fGHz[1]-DL.Ab.fGHz[0])

    @on_trait_change('fmin,fmax,fstep,chann')
    def update_fGHz(self):
        if self.Wstd_Enum != 'None':
            W = std.Wstandard(self.Wstd_Enum)
            # DL.fGHz = W.chan[eval(self.chann)].fghz
            Wchan = W.chan[eval(self.chann)]
            fcGHz = Wchan['fcGHz']
            BWGHz = Wchan['BMHz']
            GMHz = Wchan['GMHz']
            fGHz = Wchan.fghz

            DL.fGHz = np.array([fcGHz])

            self.BWGHz = BWGHz
            self.fmin = float(fGHz[0])
            self.fmax = float(fGHz[-1])
            self.fstep = float(fGHz[1] - fGHz[0])

        else:
            if self.fmin < self.fmax:
                DL.fGHz = np.arange(self.fmin, self.fmax, self.fstep)
            elif self.fmin == self.fmax:
                DL.fGHz = np.array([self.fmin])
            self.BWGHz = 5

    @on_trait_change('Beval')
    def DLeval(self):

        DL.eval(verbose=False,
                force=self.force,
                cutoff=self.cutoff,
                threshold=self.threshold / 100.,
                diffraction=self.diffraction,
                nD=self.nD,
                nT=self.nT,
                nR=self.nR,
                applywav=self.applywav)
        DL._update_show3(delrays=True)
        ER = np.squeeze(DL.H.energy())
        DL.R._show3(ER=ER)
        self.plt_all()

    def plt_all(self):
        self.plt_cir()
        self.plt_doa()
        self.plt_dod()
        self.plt_dspread()
        self.plt_aspread()

    def plt_cir(self):
        self.figcir.clf()
        ax = self.figcir.add_subplot(111)
        DL.plt_cir(fig=self.figcir, ax=ax, BWGHz=self.BWGHz, Nf=5000)
        # ir = DL.H.getcir(BWGHz=5,Nf=1000)
        # ir.plot(fig=self.figcir,ax=ax)
        # ax.plot(DL.H.taud,20*np.log10(DL.H.y[:,0,0,0]),'or')
        self.figcir.canvas.draw()
        # DL.plt_doadod(d='doa')
        # DL.H.plot(fig=self.figcir,ax=ax)
        # self.figcir.canvas.draw()

    def plt_doa(self):
        self.figdoa.clf()
        ax = self.figdoa.add_subplot(111, polar=True)
        # DL.L.showG('s',ax=ax,fig=self.figure)
        # DL.H.plotd(d='doa',polar=True,fig=self.figdoa,ax=ax)
        DL.plt_doa(polar=True, fig=self.figdoa, ax=ax)
        self.figdoa.canvas.draw()

    def plt_dod(self):
        self.figdod.clf()
        ax = self.figdod.add_subplot(111, polar=True)
        DL.plt_dod(polar=True, fig=self.figdod, ax=ax)
        # DL.L.showG('s',ax=ax,fig=self.figure)
        # DL.H.plotd(d='dod',polar=True,fig=self.figdod,ax=ax)
        self.figdod.canvas.draw()

    def plt_dspread(self):
        self.figds.clf()
        ax = self.figds.add_subplot(111)
        DL.plt_dspread(fig=self.figds, ax=ax)
        self.figds.canvas.draw()

    def plt_aspread(self):
        self.figas.clf()
        ax = self.figas.add_subplot(111)
        DL.plt_aspread(fig=self.figas, ax=ax)
        self.figas.canvas.draw()

    def clear_fig(self, lf=['cir', 'doa', 'dod', 'as', 'ds']):
        for f in lf:
            eval('self.fig' + f + '.clf()')
            eval('self.fig' + f + '.canvas.draw()')

    #####
    ##### RENDERING 3D MAYAVI
    #####

    render3d = Item('scene',
                    editor=SceneEditor(scene_class=Scene),
                    height=500,
                    width=1500,
                    show_label=False)

    # ###
    # ### Matplotlib figure
    # ###

    # figure = Instance(Figure(figsize=(8,20)), ())

    #####
    ##### Layout SELECTION
    #####

    # Layout
    GLay = Group(Item('Lay_Enum', style='simple', label='file'),
                 show_labels=False,
                 label='Layout')

    #####
    ##### WIRELESS STANDARD
    #####

    # wireless standard
    Wstd_Enum = Enum('None', av_wstds)

    chann = Str

    # chann = Enum(av_chann)

    GWstd_None = Group(Item('fmin', label='fGHz min', style='text'),
                       Item('fmax', label='fGHz max', style='text'),
                       Item('fstep', label='fGHz step', style='text'),
                       label='Frequency',
                       show_border=True,
                       enabled_when='Wstd_Enum == \'None\'')

    GWstd_std = Group(Item(name='chann',
                           editor=EnumEditor(name='handler.channels')),
                      label='channel',
                      show_border=True,
                      enabled_when='Wstd_Enum != \'None\'')

    GWstd = Group(Group(Item(name='Wstd_Enum', label='Wireless Standard')),
                  GWstd_None,
                  GWstd_std,
                  label='Wireless Standard',
                  show_labels=True,
                  show_border=False)

    #####
    ##### ANTENNA
    #####

    xmin = Float
    xmax = Float
    ymin = Float
    ymax = Float
    zmin = Float
    zmax = Float

    # Ant A file

    Iax = Item('aX',
               editor=RangeEditor(low_name='xmin',
                                  high_name='xmax',
                                  format='%.1f',
                                  label_width=28,
                                  mode='auto'),
               label='x')
    Iay = Item('aY',
               editor=RangeEditor(low_name='ymin',
                                  high_name='ymax',
                                  format='%.1f',
                                  label_width=28,
                                  mode='auto'),
               label='y')
    Iaz = Item('aZ',
               editor=RangeEditor(low_name='zmin',
                                  high_name='zmax',
                                  format='%.1f',
                                  label_width=28,
                                  mode='auto'),
               label='z')
    GPos_a = VGroup(Iax,
                    Iay,
                    Iaz,
                    id='a',
                    label='Position',
                    show_border=True,
                    show_labels=True,
                    layout='split')

    Ifile_a = Item('a_ant', label='file')

    GRot_a = VGroup(Item('agamma', label='x-roll'),
                    Item('abeta', label='y-roll'),
                    Item('aalpha', label='z-roll'),
                    id='Ta',
                    label='Rotation',
                    show_border=True,
                    layout='split')

    G_a = Group(Ifile_a, GPos_a, GRot_a, label='Antenna a', show_border=False)

    #### ANtenna B

    # Ant B positions

    Ibx = Item('bX',
               editor=RangeEditor(low_name='xmin',
                                  high_name='xmax',
                                  format='%.1f',
                                  label_width=28,
                                  mode='auto'),
               label='x')
    Iby = Item('bY',
               editor=RangeEditor(low_name='ymin',
                                  high_name='ymax',
                                  format='%.1f',
                                  label_width=28,
                                  mode='auto'),
               label='y')
    Ibz = Item('bZ',
               editor=RangeEditor(low_name='zmin',
                                  high_name='zmax',
                                  format='%.1f',
                                  label_width=28,
                                  mode='auto'),
               label='z')

    GPos_b = Group(Ibx,
                   Iby,
                   Ibz,
                   id='b',
                   label='Position',
                   show_border=True,
                   layout='split')

    # Ant B file

    Ifile_b = Item('b_ant', label='file')

    GRot_b = Group(Item('bgamma', label='x-roll'),
                   Item('bbeta', label='y-roll'),
                   Item('balpha', label='z-roll'),
                   id='Tb',
                   label='Rotation',
                   show_border=True,
                   layout='split')

    G_b = Group(
        Ifile_b,
        GPos_b,
        GRot_b,
        label='Antenna b',
        show_border=False,
    )

    ####
    #### advanced CONFIRGURATION
    ####

    force = Bool
    diffraction = Bool
    applywav = Bool
    applywav = Bool
    low_cutoff = 1
    high_cutoff = 30
    cutoff = Range(low='low_cutoff', high='high_cutoff', value=DL.cutoff)
    threshold = Range(0, 100, 80)
    nD = 2
    nR = 10
    nT = 10

    G_advanced = Group(
        VGroup(Item('force', label='force', resizable=False, style='simple'),
               Item('cutoff',
                    label='cutoff',
                    editor=RangeEditor(low_name='low_cutoff',
                                       high_name='high_cutoff',
                                       label_width=28,
                                       mode='auto'),
                    width=0.2,
                    style='simple'),
               Item('threshold', label='threshold', width=0.2, style='simple'),
               Item('diffraction', label='diffractions', style='simple'),
               Item('nD',
                    label='max nb Diffractions',
                    enabled_when='diffraction',
                    style='simple'),
               Item('nR', label='max nb Reflections', style='simple'),
               Item('nT', label='max nb Transmissions', style='simple'),
               Item('applywav', label='applywav', style='simple'),
               label='Ray Tracing Configuration',
               show_labels=True,
               show_border=False))

    ####
    ### MANAGING GROUPS
    ###

    # LEFT GROUP WINDOW
    Beval = Button('Launch Ray-Tracing')

    GLeft = Group(GLay, GWstd, G_advanced)

    # Antenna GRoup
    GAnt_ab = HGroup(spring, G_a, spring, G_b, spring)

    GAnt_Eval = Group(
        GAnt_ab,
        HGroup(spring,
               Item('Beval', enabled_when='Lay_Enum != \'\''),
               show_labels=False))

    #### TOP GROUP

    GR_0 = HSplit(GLeft, render3d, layout='split')

    # BOTTOM GROUP

    figcir = Instance(Figure(figsize=(8, 20)), ())
    figdoa = Instance(Figure(figsize=(8, 20)), ())
    figdod = Instance(Figure(figsize=(8, 20)), ())
    figas = Instance(Figure(figsize=(8, 20)), ())
    figds = Instance(Figure(figsize=(8, 20)), ())

    GExploit = Group(
        Group(Item(
            'figcir',
            editor=MPLFigureEditor(),
        ), label='CIR'),
        Group(Item('figdoa', editor=MPLFigureEditor()), label='DOA'),
        Group(Item('figdod', editor=MPLFigureEditor()), label='DOD'),
        Group(Item('figas', editor=MPLFigureEditor()), label='Ang. Spread'),
        Group(Item('figds', editor=MPLFigureEditor()), label='Delay Spread'),
        layout='tabbed',
    )

    GR_1 = HGroup(spring, GAnt_Eval, spring, GExploit)

    JWidget = JupyterWidget()
    JWidget.show()

    view = View(
        VGroup(GR_0, GR_1),
        # menubar=MenuBar(Menu_file),
        buttons=['Quit'],
        title="Pylayers GUI - beta",
        resizable=True,
        width=1.,
        height=1.,
        handler=WstdHandler)
Beispiel #18
0
class Bullseye(HasTraits):
    plots = Instance(GridPlotContainer)
    abplots = Instance(VPlotContainer)
    screen = Instance(Plot)
    horiz = Instance(Plot)
    vert = Instance(Plot)
    asum = Instance(Plot)
    bsum = Instance(Plot)

    process = Instance(Process)

    colormap = Enum("gray", "jet", "hot", "prism")
    invert = Bool(True)

    label = None
    gridm = None
    grid = None

    traits_view = View(HGroup(VGroup(
        HGroup(
            VGroup(
                Item("object.process.x", label="Centroid x",
                    format_str=u"%.4g µm",
                    tooltip="horizontal beam position relative to chip "
                    "center"),
                Item("object.process.a", label="Major 4sig",
                    format_str=u"%.4g µm",
                    tooltip="major axis beam width 4 sigma ~ 1/e^2 width"),
                Item("object.process.t", label="Rotation",
                    format_str=u"%.4g°",
                    tooltip="angle between horizontal an major axis"),
                #Item("object.process.black", label="Black",
                #    format_str=u"%.4g",
                #    tooltip="background black level"),
            ), VGroup(
                Item("object.process.y", label="Centroid y",
                    format_str=u"%.4g µm",
                    tooltip="vertical beam position relative to chip "
                    "center"),
                Item("object.process.b", label="Minor 4sig",
                    format_str=u"%.4g µm",
                    tooltip="major axis beam width 4 sigma ~ 1/e^2 width"),
                #Item("object.process.d", label="Mean width",
                #    format_str=u"%.4g µm",
                #    tooltip="mean beam width 4 sigma ~ 1/e^2 width"),
                #Item("object.process.e", label="Ellipticity",
                #    format_str=u"%.4g",
                #    tooltip="ellipticity minor-to-major width ratio"),
                #Item("object.process.peak", label="Peak",
                #    format_str=u"%.4g",
                #    tooltip="peak pixel level"),
                Item("object.process.include_radius", label="Include radius",
                    format_str=u"%.4g µm",
                    tooltip="energy inclusion radius according to ignore "
                    "level, used to crop before taking moments"),
            ),
            style="readonly",
        ), VGroup(
            Item("object.process.capture.shutter",
                tooltip="exposure time per frame in seconds"),
            Item("object.process.capture.gain",
                tooltip="analog camera gain in dB"),
            Item("object.process.capture.framerate",
                tooltip="frames per second to attempt, may be limited by "
                "shutter time and processing speed"),
            Item("object.process.capture.average",
                tooltip="number of subsequent images to boxcar average"),
            Item("object.process.background",
                tooltip="background intensity percentile to subtract "
                "from image"),
            Item("object.process.ignore",
                tooltip="fraction of total intensity to ignore for "
                "cropping, determines include radius"),
        ), HGroup(
            Item("object.process.active",
                tooltip="capture and processing running"),
            Item("object.process.capture.auto_shutter",
                tooltip="adjust the shutter time to "
                "yield acceptably exposed frames with peak values "
                "between .25 and .75"),
            Item("object.process.track",
                tooltip="adjust the region of interest to track the "
                "beam center, the size is not adjusted"),
            Item("object.process.capture.dark",
                tooltip="capture a dark image and subtract it from "
                "subsequent images, reset if gain or shutter change"),
        ), HGroup(
            UItem("colormap", tooltip="image colormap"),
            Item("invert", tooltip="invert the colormap"),
        ), UItem("abplots", editor=ComponentEditor(),
                width=-200, height=-300, resizable=False,
                tooltip="line sums (red), moments (blue) and "
                "2-sigma markers (green) along the major and minor axes",
        ),
    ), UItem("plots", editor=ComponentEditor(), width=800,
            tooltip="top right: beam image with 2-sigma and 6-sigma "
            "radius ellipses and axis markers (green). top left and bottom "
            "right: vertial and horizontal line sums (red), moments "
            "(blue) and 2-sigma markers (green). bottom left: beam data "
            "from moments"),
    layout="split",
    ), resizable=True, title=u"Bullseye ― Beam Profiler", width=1000)

    def __init__(self, **k):
        super(Bullseye, self).__init__(**k)
        self.data = ArrayPlotData()
        self.process.initialize()
        self.setup_plots()
        self.update_data()
        self.populate_plots()

        self.on_trait_change(self.update_data, "process.new_data",
                dispatch="fast_ui")

    def setup_plots(self):
        self.screen = Plot(self.data,
                resizable="hv", padding=0, bgcolor="lightgray",
                border_visible=False)
        self.screen.index_grid.visible = False
        self.screen.value_grid.visible = False
        px = self.process.capture.pixelsize
        w, h = self.process.capture.width, self.process.capture.height
        # value_range last, see set_range()
        self.screen.index_range.low_setting = -w/2*px
        self.screen.index_range.high_setting = w/2*px
        self.screen.value_range.low_setting = -h/2*px
        self.screen.value_range.high_setting = h/2*px

        self.horiz = Plot(self.data,
                resizable="h", padding=0, height=100,
                bgcolor="lightgray", border_visible=False)
        self.horiz.value_mapper.range.low_setting = \
                -.1*self.process.capture.maxval
        self.horiz.index_range = self.screen.index_range
        self.vert = Plot(self.data, orientation="v",
                resizable="v", padding=0, width=100,
                bgcolor="lightgray", border_visible=False)
        for p in self.horiz, self.vert:
            p.index_axis.visible = False
            p.value_axis.visible = False
            p.index_grid.visible = True
            p.value_grid.visible = False
        self.vert.value_mapper.range.low_setting = \
                -.1*self.process.capture.maxval
        self.vert.index_range = self.screen.value_range

        #self.vert.value_range = self.horiz.value_range

        self.mini = Plot(self.data,
                width=100, height=100, resizable="", padding=0,
                bgcolor="lightgray", border_visible=False)
        self.mini.index_axis.visible = False
        self.mini.value_axis.visible = False
        self.label = PlotLabel(component=self.mini,
                overlay_position="inside left", font="modern 10",
                text=self.process.text)
        self.mini.overlays.append(self.label)

        self.plots = GridPlotContainer(shape=(2, 2), padding=0,
                spacing=(5, 5), use_backbuffer=True,
                bgcolor="lightgray")
        self.plots.component_grid = [[self.vert, self.screen],
                                     [self.mini, self.horiz ]]

        self.screen.overlays.append(ZoomTool(self.screen,
            x_max_zoom_factor=1e2, y_max_zoom_factor=1e2,
            x_min_zoom_factor=0.5, y_min_zoom_factor=0.5,
            zoom_factor=1.2))
        self.screen.tools.append(PanTool(self.screen))
        self.plots.tools.append(SaveTool(self.plots,
            filename="bullseye.pdf"))

        self.asum = Plot(self.data,
                padding=0, height=100, bgcolor="lightgray",
                title="major axis", border_visible=False)
        self.bsum = Plot(self.data,
                padding=0, height=100, bgcolor="lightgray",
                title="minor axis", border_visible=False)
        for p in self.asum, self.bsum:
            p.value_axis.visible = False
            p.value_grid.visible = False
            p.title_font = "modern 10"
            p.title_position = "left"
            p.title_angle = 90
        # lock scales
        #self.bsum.value_range = self.asum.value_range
        #self.bsum.index_range = self.asum.index_range

        self.abplots = VPlotContainer(padding=20, spacing=20,
                use_backbuffer=True,bgcolor="lightgray",
                fill_padding=True)
        self.abplots.add(self.bsum, self.asum)

    def populate_plots(self):
        self.screenplot = self.screen.img_plot("img",
                xbounds="xbounds", ybounds="ybounds",
                interpolation="nearest",
                colormap=color_map_name_dict[self.colormap],
                )[0]
        self.set_invert()
        self.grid = self.screenplot.index
        self.gridm = self.screenplot.index_mapper
        t = ImageInspectorTool(self.screenplot)
        self.screen.tools.append(t)
        self.screenplot.overlays.append(ImageInspectorOverlay(
            component=self.screenplot, image_inspector=t,
            border_size=0, bgcolor="transparent", align="ur",
            tooltip_mode=False, font="modern 10"))

        self.horiz.plot(("x", "imx"), type="line", color="red")
        self.vert.plot(("y", "imy"), type="line", color="red")
        self.horiz.plot(("x", "gx"), type="line", color="blue")
        self.vert.plot(("y", "gy"), type="line", color="blue")
        self.asum.plot(("a", "ima"), type="line", color="red")
        self.bsum.plot(("b", "imb"), type="line", color="red")
        self.asum.plot(("a", "ga"), type="line", color="blue")
        self.bsum.plot(("b", "gb"), type="line", color="blue")

        for p in [("ell1_x", "ell1_y"), ("ell3_x", "ell3_y"),
                ("a_x", "a_y"), ("b_x", "b_y")]:
            self.screen.plot(p, type="line", color="green", alpha=.5)

        for r, s in [("x", self.horiz), ("y", self.vert),
                ("a", self.asum), ("b", self.bsum)]:
            for p in "0 p m".split():
                q = ("%s%s_mark" % (r, p), "%s_bar" % r)
                s.plot(q, type="line", color="green")

    def __del__(self):
        self.close()

    def close(self):
        self.process.active = False

    @on_trait_change("colormap")
    def set_colormap(self):
        p = self.screenplot
        m = color_map_name_dict[self.colormap]
        p.color_mapper = m(p.value_range)
        self.set_invert()
        p.request_redraw()

    @on_trait_change("invert")
    def set_invert(self):
        p = self.screenplot
        if self.invert:
            a, b = self.process.capture.maxval, 0
        else:
            a, b = 0, self.process.capture.maxval
        p.color_mapper.range.low_setting = a
        p.color_mapper.range.high_setting = b

    # TODO: bad layout for one frame at activation, track
    # value_range seems to be updated after index_range, take this
    @on_trait_change("screen.value_range.updated")
    def set_range(self):
        if self.gridm is not None:
            #enforce data/screen aspect ratio 1
            sl, sr, sb, st = self.gridm.screen_bounds
            dl, db = self.gridm.range.low
            dr, dt = self.gridm.range.high
            #dsdx = float(sr-sl)/(dr-dl)
            dsdy = float(st-sb)/(dt-db)
            #dt_new = db+(st-sb)/dsdx
            if dsdy:
                dr_new = dl+(sr-sl)/dsdy
                self.gridm.range.x_range.high_setting = dr_new
        l, r = self.screen.index_range.low, self.screen.index_range.high
        b, t = self.screen.value_range.low, self.screen.value_range.high
        px = self.process.capture.pixelsize
        self.process.capture.roi = [l, b, r-l, t-b]

    def update_data(self):
        if self.label is not None:
            self.label.text = self.process.text
        upd = self.process.data
        self.data.arrays.update(upd)
        self.data.data_changed = {"changed": upd.keys()}
        if self.grid is not None:
            self.grid.set_data(upd["xbounds"], upd["ybounds"])
Beispiel #19
0
class Magnet3D(GetSetItemsMixin):

    polarity = [1, 1, 1]
    relais_lock = Lock()
    axis_current = [0., 0., 0.]

    current_max = Float(default_value=0.1)
    voltage_max = Float(default_value=31.9)

    voltage_max_vec = Array()
    current_max_vec = Array()

    stop = False
    stop_lock = Lock()

    def __init__(self,
                 devicelist,
                 relais_serial_port,
                 diff_current,
                 voltage_max_vector,
                 current_max_vector,
                 fuse_voltage_max,
                 fuse_current_max,
                 gauss_per_amp_vector=(1., 1., 1.),
                 current_min=0.0005,
                 ramp_down=False,
                 reset=True):
        super(Magnet3D, self).__init__()

        self.devicesX = devicelist[0]
        self.devicesY = devicelist[1]
        self.devicesZ = devicelist[2]

        self.add_trait(
            "set_current_1",
            Range(low=-current_max_vector[0],
                  high=current_max_vector[0],
                  value=0,
                  mode='text',
                  auto_set=False,
                  enter_set=True,
                  desc='current of first coil [mA]',
                  label='I_1 [mA]',
                  width=-20))
        self.add_trait(
            "set_current_2",
            Range(low=-current_max_vector[1],
                  high=current_max_vector[1],
                  value=0,
                  mode='text',
                  auto_set=False,
                  enter_set=True,
                  desc='current of second coil [mA]',
                  label='I_2 [mA]',
                  width=-20))
        self.add_trait(
            "set_current_3",
            Range(low=-current_max_vector[2],
                  high=current_max_vector[2],
                  value=0,
                  mode='text',
                  auto_set=False,
                  enter_set=True,
                  desc='current of third coil [mA]',
                  label='I_3 [mA]',
                  width=-20))

        self.current_max_vec = current_max_vector
        self.voltage_max_vec = voltage_max_vector

        self.current_max = min(current_max_vector)
        self.voltage_max = min(voltage_max_vector)

        self.diff_current = diff_current
        self.gauss_per_amp_vector = gauss_per_amp_vector

        self.current_min = current_min

        self.ramp_down_enabled = ramp_down
        self.ramp_sleep = 0.1
        self.ramp_current_step = 50.e-3

        self.debug_lock = Lock()

        self.devices = {}
        self.axis = {1: 'x-axis', 2: 'y-axis', 3: 'z-axis'}
        self.channel = {
            'x-axis': 1,
            'x': 1,
            'y-axis': 2,
            'y': 2,
            'z-axis': 3,
            'z': 3
        }

        for devicename, ch in self.devicesX:
            self.devices.setdefault(devicename, []).append(("x-axis", ch))
        for devicename, ch in self.devicesY:
            self.devices.setdefault(devicename, []).append(("y-axis", ch))
        for devicename, ch in self.devicesZ:
            self.devices.setdefault(devicename, []).append(("z-axis", ch))

        self.instances = dict()
        self.locks = dict()
        for devicename in self.devices.keys():
            self.instances[devicename] = hameg.HMP2030(
                device=devicename,
                voltage_max=self.voltage_max,
                current_max=self.current_max,
                fuse_voltage_max=fuse_voltage_max,
                fuse_current_max=fuse_current_max)
            self.locks[devicename] = Lock()

        self.relais = USBRelais.USBRelais(relais_serial_port)

        self.set_max_currents()
        self.set_max_voltages()

        if reset:

            self.set_all_currents(0., 0., 0.)  #A
            self.set_all_voltages(
                *self.voltage_max_vec)  #V proper voltage has to be set\
            self.emergency_stop()

            #start polarity changer
            self.relais.reset()
            self.relais.setPort([1, 0, 1, 0, 1, 0, 0, 0])

        if not self.relais.NOP():
            raise RuntimeError(
                'NOP failed on relais card. Shut down the field, and try ONCE with reset=True passed to __init__. All your field settings will be lost.'
            )

        bit = self.relais.getPort()
        if bit[0] == bit[1] or bit[2] == bit[3] or bit[4] == bit[5]:
            raise RuntimeError(
                'Bad port state on relais card. Shut down the field, and try ONCE with reset=True passed to __init__. All your field settings will be lost.'
            )

        self.update_all()

#on_rait_change(max_voltage_vec)
#.....---""----current max vec...

    def _lock(self, device):
        while self._locked(device):
            time.sleep(0.05)
        self.locks[device].acquire()

    def _locked(self, device):
        if self.locks[device].locked():
            return True
        else:
            return False

    def _unlock(self, device):
        self.locks[device].release()

    def _set_device_current_unchecked(self,
                                      device,
                                      channel,
                                      target_current,
                                      timeout=10):
        if not self.stop:
            self._lock(device)
            current = target_current
            instance = self.instances[device]
            turn_off = False
            if target_current < self.current_min / 2.:
                current = self.current_min
                turn_off = True
            instance.set_current(current, channel)
            self._unlock(device)
            time.sleep(0.1)
            if turn_off:
                self._device_stop_single(device, channel)
            else:
                self._device_run_single(device, channel)

    def _check_device_current(self, device, channel, current, timeout=10):
        start_time = time.time()
        while abs(start_time - time.time()) <= timeout:
            if self.stop:
                return False
            if abs(self._get_device_current(device, channel) -
                   current) <= self.diff_current:
                break
            time.sleep(0.1)
        else:
            self.stop_all()
            print "Current didn't settle to", current, "A in channel", channel, ". Shutting down..."
            raise RuntimeError("Current didn't settle. Shutting down...")
        return True

    def _set_device_current(self, device, channel, current, timeout=10):
        if not self.stop:
            self._set_device_current_unchecked(device, channel, current,
                                               timeout)
            t = Thread(name="_set_device_current",
                       target=self._check_device_current,
                       args=(device, channel, current, timeout))
            t.start()
            t.join(timeout)
            if t.isAlive():
                print "Warning: couldn't ramp current nicely!"

    def _set_device_voltage(self, device, channel, voltage):
        instance = self.instances[device]
        instance.set_voltage(voltage, channel)

    def _get_device_current(self, device, channel):
        self._lock(device)
        current = self.instances[device].get_current(channel)
        self._unlock(device)
        return current

    def _device_run_single(self, device, channel):
        if not self.stop:
            self._lock(device)
            self.instances[device].run(channel)
            self._unlock(device)

    def _device_run_all(self, device):
        for axis, channel in self.devices[device]:
            self._lock(device)
            self._device_run_single(device, channel)
            self._unlock(device)

    def _device_stop_single(self, device, channel):
        self._lock(device)
        self.instances[device].stop(channel)
        self._unlock(device)

    def _device_stop_axis(self, device, axis):
        for device_axis, channel in self.devices.get(device):
            if device_axis == axis:
                self._device_stop_single(device, channel)

    def _device_run_axis(self, device, axis):
        if not self.stop:
            for device_axis, channel in self.devices.get(device):
                if device_axis == axis:
                    self._device_run_single(device, channel)

    def _device_stop_all(self, device):
        for axis, channel in self.devices.get(device):
            self._device_stop_single(device, channel)

    def run_all(self):
        if not self.stop:
            for device in self.devices:
                self._device_run_all(device)

    def stop_all(self):
        for device in self.devices:
            self._device_stop_all(device)

    def run_axis(self, axis):
        if not self.stop:
            t_list = []
            for device in self.devices.keys():
                t_list.append(
                    Thread(name=device,
                           target=self._device_run_axis,
                           args=(device, axis)))
            for thread in t_list:
                thread.start()

    def stop_axis(self, axis):
        t_list = []
        for device in self.devices.keys():
            t_list.append(
                Thread(name=device,
                       target=self._device_stop_axis,
                       args=(
                           device,
                           axis,
                       )))
        for thread in t_list:
            thread.start()

    def _set_device_axis_max_current(self, device, axis, max_current):
        for device_axis, channel in self.devices.get(device):
            if device_axis == axis:
                self._set_device_max_current(device, channel, max_current)

    def _set_device_max_current(self, device, channel, max_current):
        self.instances[device].set_max_current(channel, max_current)

    def _set_device_axis_max_voltage(self, device, axis, max_voltage):
        for device_axis, channel in self.devices.get(device):
            if device_axis == axis:
                self._set_device_max_voltage(device, channel, max_voltage)

    def _set_device_max_voltage(self, device, channel, max_voltage):
        self.instances[device].set_max_voltage(channel, max_voltage)

    def _set_device_all_currents(self, device, currents):
        for channel, current in enumerate(currents, start=1):
            self._set_device_current_unchecked(device, channel, current)
        for channel, current in enumerate(currents, start=1):
            self._check_device_current(device, channel, current)

    def _set_device_axis_current(self, device, axis, current):
        for device_axis, channel in self.devices.get(device):
            if device_axis == axis:
                self._set_device_current_unchecked(device, channel, current)

    def _check_device_axis_current(self, device, axis, current):
        for device_axis, channel in self.devices.get(device):
            if device_axis == axis:
                self._check_device_current(device, channel, current)

    def _get_device_axis_current(self, device, axis, queue):
        for device_axis, channel in self.devices.get(device):
            if device_axis == axis:
                queue.put(self._get_device_current(device, channel))

    def _set_device_axis_voltage(self, device, axis, voltage):
        for device_axis, channel in self.devices.get(device):
            if device_axis == axis:
                self._set_device_voltage(device, channel, voltage)

    def _set_axis_current(self, axis, target_current):
        if self.axis_current[self.channel[axis] - 1] == target_current:
            return
        if self.ramp_down_enabled:
            current = self.axis_current[self.channel[axis] - 1]
            no_steps = abs(target_current - current) / self.ramp_current_step
            ramp_currents = np.linspace(current,
                                        target_current,
                                        no_steps,
                                        endpoint=False)
            ramp_currents = ramp_currents[1:]

            for i, current in enumerate(ramp_currents):
                if self.stop:
                    return
                self._set_axis_current_unchecked(axis, current)
                self._check_axis_current(axis, current)
                time.sleep(self.ramp_sleep)

        if not self.stop:
            self._set_axis_current_unchecked(axis, target_current)
            self._check_axis_current(axis, target_current)
            self.axis_current[self.channel[axis] - 1] = target_current

    def _set_axis_current_unchecked(self, axis, current):
        if self.stop:
            return
        t_list = []
        for device in self.devices.keys():
            t_list.append(
                Thread(name=device,
                       target=self._set_device_axis_current,
                       args=(
                           device,
                           axis,
                           current,
                       )))
        for thread in t_list:
            thread.start()
        for thread in t_list:
            thread.join()

    def _check_axis_current(self, axis, current):
        if self.stop:
            return
        t_list = []
        for device in self.devices.keys():
            t_list.append(
                Thread(name=device,
                       target=self._check_device_axis_current,
                       args=(
                           device,
                           axis,
                           current,
                       )))
        for thread in t_list:
            thread.start()
        for thread in t_list:
            thread.join()

    def _get_axis_current(self, axis, queue):
        t_list = []
        q = Queue()
        for device in self.devices.keys():
            t_list.append(
                Thread(name=device,
                       target=self._get_device_axis_current,
                       args=(device, axis, q)))
        for thread in t_list:
            thread.start()
        for thread in t_list:
            thread.join()
        result = []
        while not q.empty():
            result.append(q.get())

        if len(result) == 0:
            axis_current = 0
        else:
            axis_current = sum(result) / float(len(result))
        queue.put(axis_current)
        return axis, axis_current

    def _set_axis_voltage(self, axis, voltage):
        if self.stop:
            return
        t_list = []
        for device in self.devices.keys():
            t_list.append(
                Thread(name=device,
                       target=self._set_device_axis_voltage,
                       args=(
                           device,
                           axis,
                           voltage,
                       )))
        for thread in t_list:
            if self.stop:
                return
            thread.start()

    def _set_axis_max_current(self, axis, max_current):
        t_list = []
        for device in self.devices.keys():
            t_list.append(
                Thread(name=device,
                       target=self._set_device_axis_max_current,
                       args=(
                           device,
                           axis,
                           max_current,
                       )))
        for thread in t_list:
            thread.start()
        for thread in t_list:
            thread.join()

    def _set_axis_max_voltage(self, axis, max_voltage):
        t_list = []
        for device in self.devices.keys():
            t_list.append(
                Thread(name=device,
                       target=self._set_device_axis_max_voltage,
                       args=(
                           device,
                           axis,
                           max_voltage,
                       )))
        for thread in t_list:
            thread.start()
        for thread in t_list:
            thread.join()

    def _get_polarity(self, axis):
        """returns the polarity p of a given channel ch.
				The polarity is 1 for (+ -> 1, - -> 2 | [1,0,1,0,1,0,0,0])
				and -1 for (+ -> 2, - -> 1 | [0,1,0,1,0,1,0,0])."""
        return self.polarity[self.channel[axis] - 1]

    def _ask_polarity(self, axis):
        """returns the polarity p of a given channel ch.
			The polarity is 1 for (+ -> 1, - -> 2 | [1,0,1,0,1,0,0,0])
			and -1 for (+ -> 2, - -> 1 | [0,1,0,1,0,1,0,0])."""
        self.relais_lock.acquire()
        r = self.relais.getPort()
        self.relais_lock.release()
        ch = self.channel[axis]

        if ch not in [1, 2, 3]:
            raise ValueError('Wrong channel number. Chose 1, 2 or 3.')
        elif r[2 * ch - 2] == r[2 * ch - 1]:
            raise ValueError('Undefined polarity.')
        elif r[2 * ch - 2] == 1 and r[2 * ch - 1] == 0:
            return 1
        elif r[2 * ch - 2] == 0 and r[2 * ch - 1] == 1:
            return -1
        else:
            raise ValueError("Couldn't get the polarity.")

    def _set_polarity(self, axis, p):
        """sets the polarity p of a given channel ch.
			It ramps down the current and changes the polarity.-
			The output is turned off when the polarity is switched"""
        ch = self.channel[axis]
        r = self._get_polarity(axis)

        if ch not in [1, 2, 3]:
            raise ValueError('Wrong channel number. Chose 1, 2 or 3.')
        elif p not in [-1, 1]:
            raise ValueError('Undefined polarity.')
        elif r != p:
            #ramp down current
            self._set_axis_current(axis, self.current_min)
            time.sleep(0.1)
            self.stop_axis(axis)
            time.sleep(0.1)
            x = [0, 0, 0, 0, 0, 0, 0, 0]
            x[2 * ch - 2] = 1
            x[2 * ch - 1] = 1
            self.relais_lock.acquire()
            self.relais.Toggle(x)
            self.relais_lock.release()
            #control
            time.sleep(0.1)
            s = self._ask_polarity(axis)

            if s != p:
                raise ValueError("cannot change polarity")
            self.polarity[ch - 1] = p

    def set_current(self, axis, current):
        if self.stop_lock.locked():
            return
        self.stop_lock.acquire()
        self.stop = False
        self.stop_lock.release()
        #change of polarity p
        polarity = np.sign(current)
        if polarity == 0:
            polarity = 1
        self._set_polarity(axis, polarity)
        t = Thread(name=axis,
                   target=self._set_axis_current,
                   args=(axis, abs(current / 1000.)))
        t.start()

    def set_voltage(self, axis, voltage):
        self._set_axis_voltage(axis, voltage)

    def set_all_currents(self, c1, c2, c3):
        t_list = []
        currents = [c1, c2, c3]
        for axis, current in zip(['x-axis', 'y-axis', 'z-axis'], currents):
            t_list.append(
                Thread(name=axis,
                       target=self.set_current,
                       args=(
                           axis,
                           current,
                       )))
        for thread in t_list:
            thread.start()

    def set_all_voltages(self, v1, v2, v3):
        t_list = []
        voltages = [v1, v2, v3]
        for axis, voltage in zip(['x-axis', 'y-axis', 'z-axis'], voltages):
            t_list.append(
                Thread(name=axis,
                       target=self.set_voltage,
                       args=(
                           axis,
                           voltage,
                       )))
        for thread in t_list:
            thread.start()

    def get_all_currents(self):
        t_list = []
        q = Queue()
        for axis in ['x-axis', 'y-axis', 'z-axis']:
            t_list.append(
                Thread(name=axis,
                       target=self._get_axis_current,
                       args=(axis, q)))
        for thread in t_list:
            thread.start()
        for thread in t_list:
            thread.join()
        currents = []
        while not q.empty():
            currents.append(q.get())
        #Todo: sort by axis... (currents[i][0]=axis, currents[i][1]=currents)
        return currents

    def set_max_currents(self):
        for i, axis in self.axis.iteritems():
            self._set_axis_max_current(
                axis, self.current_max_vec[self.channel[axis] - 1])

    def set_max_voltages(self):
        for i, axis in self.axis.iteritems():
            self._set_axis_max_voltage(
                axis, self.voltage_max_vec[self.channel[axis] - 1])

    def save_stop(self):
        self.stop_lock.acquire()
        self.stop = True
        self.stop_lock.release()
        print "Shutting down current"
        self.set_all_currents(0., 0., 0.)
        time.sleep(0.3)
        print "Turning channels off."
        self.stop_all()

    def emergency_stop(self):
        self.stop_lock.acquire()
        self.stop = True
        self.stop_all()
        time.sleep(0.5)
        self.stop_lock.release()

    def off(self):
        self.save_stop()
        self.relais.setPort([0, 0, 0, 0, 0, 0, 0, 0])
        for device in self.instances:
            device.close()

    def set_field(self, bx, by, bz):
        self.set_field_cartesian(bx, by, bz)

    #functions to control the b field in 3D
    def field_to_current(self, field):
        """converts a b-field ([x,y,z]) to values of electrical current at all coils ([curr1,curr2,curr3])"""
        return np.asarray(self.gauss_per_amp_vector) * np.asarray(field)

    def current_to_field(self, current):
        """converts the electrical current from all coils ([curr1,curr2,curr3]) to a b-field ([x,y,z])"""
        return np.asarray(self.gauss_per_amp_vector) * np.asarray(current)

    def set_field_cartesian(self, bx, by, bz):
        """applies a b field in an arbitrary direction, which is specified via b1, b2 and b3 in crystal coordinates"""
        self.set_all_currents(*self.field_to_current([bx, by, bz]))

    def get_field_cartesian(self):
        """gives the applied field in cartesian crystal coordinates"""
        return self.current_to_field(self.get_all_currents())

    def set_field_spherical(self, b, theta, phi, unit='deg'):
        """applies a b field in an arbitrary direction, which is specified via theta and phi"""
        self.set_field_cartesian(
            *spherical_to_cartesian((b, theta, phi), unit=unit))

    def get_field_spherical(self, unit='deg'):
        """gives the applied field in spherical crystal coordinates"""
        return cartesian_to_spherical(self.get_field_cartesian(), unit=unit)
        #return [round(b,3),round(theta,2),round(phi,2)]

    #Gui to control the magnetic field
    get_current_1 = Float(value=0.0,
                          desc='actual current of first coil [A]',
                          label='I_1 [A]')
    get_current_2 = Float(value=0.0,
                          desc='actual current of second coil [A]',
                          label='I_2 [A]')
    get_current_3 = Float(value=0.0,
                          desc='actual current of third coil [A]',
                          label='I_3 [A]')
    get_bx = Float(value=0.0,
                   desc='actual magnitude of the x-component [G]',
                   label='b_x [G]')
    get_by = Float(value=0.0,
                   desc='actual magnitude of the y-component [G]',
                   label='b_y [G]')
    get_bz = Float(value=0.0,
                   desc='actual magnitude of the z-component [G]',
                   label='b_z [G]')
    get_b = Float(value=0.0,
                  desc='actual magnitude of the b-field [G]',
                  label='|B| [G]')
    get_theta = Float(value=90.0,
                      desc='actual theta angle of the b-field vector [deg]',
                      label='theta [deg]')
    get_phi = Float(value=0.0,
                    desc='actual phi angle of the b-field vector [deg]',
                    label='phi [deg]')

    set_bx = Range(
        low=-40.0,
        high=40.0,
        value=0.0,
        desc='b_x component of the b-field in crystal coordinates [G]',
        label='b_x [G]',
        mode='text',
        auto_set=False,
        enter_set=True)
    set_by = Range(
        low=-40.0,
        high=40.0,
        value=0.0,
        desc='b_y component of the b-field in crystal coordinates [G]',
        label='b_y [G]',
        mode='text',
        auto_set=False,
        enter_set=True)
    set_bz = Range(
        low=-40.0,
        high=40.0,
        value=0.0,
        desc='b_z component of the b-field in crystal coordinates [G]',
        label='b_z [G]',
        mode='text',
        auto_set=False,
        enter_set=True)
    set_b = Range(low=0.0,
                  high=70.0,
                  value=0.0,
                  desc='Magnitude of the b-field [G]',
                  label='|B| [G]',
                  mode='text',
                  auto_set=False,
                  enter_set=True)
    set_theta = Range(low=0.0,
                      high=180.0,
                      value=90.0,
                      desc='theta angle of the b-field vector [deg]',
                      label='theta [deg]',
                      mode='text',
                      auto_set=False,
                      enter_set=True)
    set_phi = Range(low=-180.0,
                    high=180.0,
                    value=0.0,
                    desc='phi angle of the b-field vector [deg]',
                    label='phi [deg]',
                    mode='text',
                    auto_set=False,
                    enter_set=True)

    set_currents_button = Button(label='Set I1,I2,I3',
                                 desc='Sets the coil currents.')
    set_field_button_cartesian = Button(
        label='Set B(bx,by,bz)',
        desc='Sets the b-field to the desired value in cartesian coordinates.')
    set_field_button_spherical = Button(
        label='Set B(|B|,theta, phi)',
        desc='Sets the b-field to the desired value in spherical coordinates.')

    save_stop_button = Button(label='Stop', desc='Safely stops the b-field.')
    emerg_stop_button = Button(
        label='Emerg-Stop',
        desc='Immediately stops the b-field. Without ramping down the current.'
    )
    update_button = Button(
        label='Update',
        desc='readout current coil states and update magnetic field values')

    #off_button = Button(label='Off', desc='Turns the b-field off and closes the connection.')
    #calibration_button = Button(label='Calibration', desc='Opens the calibration window.')

    def update_all(self):
        currents = self.get_all_currents()
        cartesian = self.current_to_field(currents)
        spherical = cartesian_to_spherical(cartesian)
        self.get_current_1, self.get_current_2, self.get_current_3 = currents
        self.get_bx, self.get_by, self.get_bz = cartesian
        self.get_b, self.get_theta, self.get_phi = spherical

    def _set_currents_button_fired(self):
        self.set_all_currents(self.set_current_1, self.set_current_2,
                              self.set_current_3)
        time.sleep(0.5)
        self.update_all()

    def _set_field_button_cartesian_fired(self):
        self.set_field_cartesian(self.set_bx, self.set_by, self.set_bz)
        self.update_all()

    def _set_field_button_spherical_fired(self):
        self.set_field_spherical(self.set_b, self.set_theta, self.set_phi)
        self.update_all()

    def _save_stop_button_fired(self):
        self.save_stop()
        self.get_field_cartesian()
        self.get_field_spherical()

    def _emerg_stop_button_fired(self):
        self.emergency_stop()

    #def _off_button_fired(self):
    #    self.off()

    def _update_button_fired(self):
        self.update_all()

#    def _calibration_button_fired(self):
#        from magcoil_calibration import MagCoilCalibration
#        magcoilcalib = MagCoilCalibration(mag_coil=self)
#        magcoilcalib.edit_traits()

    traits_view = View(
        VGroup(
            Group(
                Item('get_current_1', width=-70, style='readonly'),
                Item('get_current_2', width=-70, style='readonly'),
                Item('get_current_3', width=-70, style='readonly'),
                Item('get_bx', width=-70, style='readonly'),
                Item('get_by', width=-70, style='readonly'),
                Item('get_bz', width=-70, style='readonly'),
                #Item('get_b', width=-70, style='readonly'),
                #Item('get_theta', width=-70, style='readonly'),
                #Item('get_phi', width=-70, style='readonly'),
                orientation='vertical',
                columns=3),
            HGroup(Item('update_button', show_label=False), ),
            Group(Item('set_current_1', width=-28),
                  Item('set_current_2', width=-28),
                  Item('set_current_3', width=-28),
                  Item('set_currents_button', show_label=False),
                  Item('set_bx', width=-60),
                  Item('set_by', width=-60),
                  Item('set_bz', width=-60),
                  Item('set_field_button_cartesian', show_label=False),
                  Item('set_b', width=-60),
                  Item('set_theta', width=-60),
                  Item('set_phi', width=-60),
                  Item('set_field_button_spherical', show_label=False),
                  orientation='vertical',
                  columns=4),
            HGroup(
                Item('save_stop_button', show_label=False),
                Item('emerg_stop_button', show_label=False),
                #Item('off_button', show_label=False),
                #Item('calibration_button', show_label=False),
            ),
        ),
        title='Magnetic field control',
        width=630,
        height=250,
        buttons=[],
        resizable=True)

    get_set_items = [
        'set_current_1', 'set_current_2', 'set_current_3', 'set_bx', 'set_by',
        'set_bz', 'set_b', 'set_theta', 'set_phi', '__doc__'
    ]
Beispiel #20
0
class PlotDockPane(HasStrictTraits):
    '''Trait definition.
    '''
    name = Str

    vot = Range(low=0.0, high=1.0, step=0.01,
                enter_set=True, auto_set=False)

    n_cols = Int(1, label='Number of rows',
                 tooltip='Defines a number of columns within the plot pane',
                 enter_set=True, auto_set=False)

    @on_trait_change('vot,n_cols')
    def replot(self):
        for ax, viz2d in zip(self.axes, self.viz2d_list):
            ax.clear()
            viz2d.plot(ax, self.vot)
        self.data_changed = True

    viz2d_list = List(Viz2D)

    def _viz2d_list_items_changed(self):
        self.replot()

    selected_viz2d = Instance(Viz2D)

    axes = Property(List, depends_on='viz2d_list,n_cols')
    '''Derived axes objects reflecting the layout of plot pane
    and the individual. 
    '''
    @cached_property
    def _get_axes(self):
        n_fig = len(self.viz2d_list)
        n_cols = self.n_cols
        n_rows = (n_fig + n_cols - 1) / self.n_cols
        self.figure.clear()
        return [self.figure.add_subplot(n_rows, self.n_cols, i + 1)
                for i in range(n_fig)]

    data_changed = Event

    figure = Instance(Figure)

    def _figure_default(self):
        figure = Figure()
        return figure

    # Traits view definition:
    traits_view = View(
        VGroup(
            Tabbed(
                Group(
                    UItem('figure', editor=MPLFigureEditor(),
                          resizable=True,
                          springy=True),
                    scrollable=True,
                    label='Plot panel'
                ),
                VGroup(
                    Item('n_cols'),
                    VSplit(
                        UItem('viz2d_list@', editor=tabular_editor),
                        UItem('selected_viz2d@'),
                    ),
                    label='Plot configure'
                ),
            ),
            Item('vot')
        ),
        resizable=True,
        width=0.8, height=0.8,
        buttons=['OK', 'Cancel']
    )
Beispiel #21
0
class MagView(HasTraits):
    python_console_cmds = Dict()
    plot = Instance(Plot)
    plot_data = Instance(ArrayPlotData)

    traits_view = View(
        VGroup(
            Item('plot',
                 editor=ComponentEditor(bgcolor=(0.8, 0.8, 0.8)),
                 show_label=False), ))

    def mag_set_data(self):
        self.last_plot_update_time = monotonic()
        min_data = np.min(self.mag)
        max_data = np.max(self.mag)
        padding = (max_data - min_data) / 4.0
        if (self.plot.value_range.low_setting == 'auto'
                or (min_data - padding) < self.plot.value_range.low_setting):
            self.plot.value_range.low_setting = min_data - padding
        if (self.plot.value_range.high_setting == 'auto'
                or (max_data + padding) > self.plot.value_range.high_setting):
            self.plot.value_range.high_setting = max_data + padding
        self.plot_data.set_data('mag_x', self.mag[:, 0])
        self.plot_data.set_data('mag_y', self.mag[:, 1])
        self.plot_data.set_data('mag_z', self.mag[:, 2])

    def mag_raw_callback(self, sbp_msg, **metadata):
        self.mag[:-1, :] = self.mag[1:, :]
        self.mag[-1] = (sbp_msg.mag_x, sbp_msg.mag_y, sbp_msg.mag_z)
        if monotonic() - self.last_plot_update_time > GUI_UPDATE_PERIOD:
            self.mag_set_data()

    def __init__(self, link):
        super(MagView, self).__init__()

        self.mag = np.zeros((NUM_POINTS, 3))
        self.last_plot_update_time = 0

        self.plot_data = ArrayPlotData(t=np.arange(NUM_POINTS),
                                       mag_x=[0.0],
                                       mag_y=[0.0],
                                       mag_z=[0.0])

        self.plot = Plot(self.plot_data,
                         auto_colors=colours_list,
                         emphasized=True)
        self.plot.title = 'Raw Magnetometer Data'
        self.plot.title_color = [0, 0, 0.43]
        self.plot.value_axis.orientation = 'right'
        self.plot.value_axis.axis_line_visible = False
        self.legend_visible = True
        self.plot.legend.visible = True
        self.plot.legend.align = 'll'
        self.plot.legend.line_spacing = 1
        self.plot.legend.font = 'modern 8'
        self.plot.legend.draw_layer = 'overlay'
        self.plot.legend.tools.append(
            LegendTool(self.plot.legend, drag_button="right"))

        mag_x = self.plot.plot(('t', 'mag_x'),
                               type='line',
                               color='auto',
                               name='Mag. X (uT)')
        mag_y = self.plot.plot(('t', 'mag_y'),
                               type='line',
                               color='auto',
                               name='Mag. Y (uT)')
        mag_z = self.plot.plot(('t', 'mag_z'),
                               type='line',
                               color='auto',
                               name='Mag. Z (uT)')

        self.link = link
        self.link.add_callback(self.mag_raw_callback, SBP_MSG_MAG_RAW)
        self.python_console_cmds = {'track': self}
Beispiel #22
0
 def traits_view(self):
     v = View(
         Group(VGroup(Item('fiber_light', style='custom', show_label=False),
                      label='FiberLight'),
               layout='tabbed'))
     return v
Beispiel #23
0
class PulsedTool(GetSetItemsMixin):
    """
    Widget to plot a pulsed measurement.
    
    We plot
      * the raw data as an image
      * the average fluorescence response as a line plot
        (the average fluorescence response
        is used to determine a trigger point).
      * the spin state as a line plot
    """

    # the measurement to analyze
    measurement = Any(editor=InstanceEditor)

    # plotting
    matrix_data = Instance(ArrayPlotData)
    line_data = Instance(ArrayPlotData)
    pulse_data = Instance(ArrayPlotData)
    matrix_plot = Instance(Plot, editor=ComponentEditor())
    pulse_plot = Instance(Plot, editor=ComponentEditor())
    line_plot = Instance(Plot, editor=ComponentEditor())

    get_set_items = ['__doc__', 'measurement']

    traits_view = View(VGroup(
        Item(name='measurement', style='custom', show_label=False),
        VSplit(
            Item('matrix_plot',
                 show_label=False,
                 width=500,
                 height=-300,
                 resizable=True),
            Item('line_plot',
                 show_label=False,
                 width=500,
                 height=-300,
                 resizable=True),
            Item('pulse_plot',
                 show_label=False,
                 width=500,
                 height=-300,
                 resizable=True),
        ),
    ),
                       title='Pulsed Tool',
                       buttons=[],
                       resizable=True,
                       height=-640)

    def __init__(self, **kwargs):
        super(PulsedTool, self).__init__(**kwargs)
        self._create_matrix_plot()
        self._create_pulse_plot()
        self._create_line_plot()
        self.on_trait_change(self._update_matrix_index,
                             'measurement.time_bins,measurement.n_laser',
                             dispatch='ui')
        self.on_trait_change(self._update_matrix_value,
                             'measurement.count_data',
                             dispatch='ui')
        self.on_trait_change(self._update_pulse_index,
                             'measurement.time_bins',
                             dispatch='ui')
        self.on_trait_change(self._update_pulse_value,
                             'measurement.pulse',
                             dispatch='ui')
        self.on_trait_change(self._update_line_plot_value,
                             'measurement.spin_state',
                             dispatch='ui')
        self.on_trait_change(self._on_edge_change,
                             'measurement.edge',
                             dispatch='ui')

    # plotting
    def _create_matrix_plot(self):
        matrix_data = ArrayPlotData(image=np.zeros((2, 2)))
        plot = Plot(matrix_data,
                    width=500,
                    height=500,
                    resizable='hv',
                    padding=8,
                    padding_left=48,
                    padding_bottom=36)
        plot.index_axis.title = 'time [ns]'
        plot.value_axis.title = 'laser pulse #'
        plot.img_plot('image',
                      xbounds=(0, 1),
                      ybounds=(0, 1),
                      colormap=Spectral)[0]
        plot.tools.append(SaveTool(plot))
        self.matrix_data = matrix_data
        self.matrix_plot = plot

    def _create_pulse_plot(self):
        pulse_data = ArrayPlotData(x=np.array((0., 0.1, 0.2)),
                                   y=np.array((0, 1, 2)))
        plot = Plot(pulse_data, padding=8, padding_left=64, padding_bottom=36)
        line = plot.plot(('x', 'y'), style='line', color='blue',
                         name='data')[0]
        plot.index_axis.title = 'time [ns]'
        plot.value_axis.title = 'intensity'
        edge_marker = LinePlot(
            index=ArrayDataSource(np.array((0, 0))),
            value=ArrayDataSource(np.array((0, 1e9))),
            color='red',
            index_mapper=LinearMapper(range=plot.index_range),
            value_mapper=LinearMapper(range=plot.value_range),
            name='marker')
        plot.add(edge_marker)
        plot.tools.append(SaveTool(plot))
        self.pulse_data = pulse_data
        self.pulse_plot = plot

    def _create_line_plot(self):
        line_data = ArrayPlotData(
            index=np.array((0, 1)),
            spin_state=np.array((0, 0)),
        )
        plot = Plot(line_data, padding=8, padding_left=64, padding_bottom=36)
        plot.plot(('index', 'spin_state'), color='blue', name='spin_state')
        plot.index_axis.title = 'pulse #'
        plot.value_axis.title = 'spin state'
        plot.tools.append(SaveTool(plot))
        self.line_data = line_data
        self.line_plot = plot

    def _update_matrix_index(self):
        if self.measurement is not None:
            self.matrix_plot.components[0].index.set_data(
                (self.measurement.time_bins[0],
                 self.measurement.time_bins[-1]),
                (0.0, float(self.measurement.n_laser)))

    def _update_matrix_value(self):
        if self.measurement is not None:
            s = self.measurement.count_data.shape
            if not s[0] * s[1] > 1000000:
                self.matrix_data.set_data('image', self.measurement.count_data)

    def _update_pulse_index(self):
        if self.measurement is not None:
            self.pulse_data.set_data('x', self.measurement.time_bins)

    def _update_pulse_value(self):
        if self.measurement is not None:
            self.pulse_data.set_data('y', self.measurement.pulse)

    def _on_edge_change(self):
        if self.measurement is not None:
            y = self.measurement.edge
            self.pulse_plot.components[1].index.set_data(np.array((y, y)))

    def _update_line_plot_value(self):
        if self.measurement is not None:
            y = self.measurement.spin_state
            n = len(y)
            old_index = self.line_data.get_data('index')
            if old_index is not None and len(old_index) != n:
                self.line_data.set_data('index', np.arange(n))
            self.line_data.set_data('spin_state', y)

    def save_matrix_plot(self, filename):
        save_figure(self.matrix_plot, filename)

    def save_line_plot(self, filename):
        save_figure(self.line_plot, filename)
class DataBlockTablePlot(HasTraits):

    # the ParametersTable holding the actual array
    dataset = Instance(DataBlockTable)

    # a local reference to the data array in the dataset, for convenience
    selected = Property(Any, depends_on='dataset.selected')

    # ArrayPlotData for plot
    plot_data = Instance(ArrayPlotData, ())

    # Chaco Plot instance
    plot = Instance(Plot)

    traits_view = View(
        VGroup(
            Item('dataset',
                 show_label=False,
                 style='custom',
                 editor=InstanceEditor()),
            Item('plot',
                 show_label=False,
                 editor=ComponentEditor(),
                 width=0.25,
                 height=0.35),
        ),
        width=0.60,
        height=0.60,
        resizable=True,
        title='Parameters Plot',
    )

    def cview(self):
        return View(
            VGroup(
                Item('dataset',
                     show_label=False,
                     style='custom',
                     editor=InstanceEditor()),
                Item('plot',
                     show_label=False,
                     editor=ComponentEditor(),
                     width=0.25,
                     height=0.35),
            ),
            width=0.60,
            height=0.60,
            resizable=True,
            title='Raw Data Plot',
        )

    @cached_property
    def _get_selected(self):
        return self.dataset.selected

    @on_trait_change('selected')
    def _data_source_change(self):
        """Handler for changes of ther selected table row
        """
        if self.selected is None:
            return

        x = np.linspace(0, \
                        len(self.selected['raw_data']), \
                        len(self.selected['raw_data']))

        self.plot_data.set_data('x', x)
        self.plot_data.set_data('y', self.selected['raw_data'])

    def _plot_data_default(self):
        """ This creates a list of ArrayPlotData instances,
        one for each species.
        """
        plot_data = ArrayPlotData()

        plot_data.set_data('x', [])
        plot_data.set_data('y', [])

        return plot_data

    def _plot_default(self):
        """ This creates the default value for the plot.
        """
        # create the main plot object
        plot = Plot(self.plot_data)

        plot.plot(('x', 'y'), type='line', name='raw data', color='lightgreen')

        # add the additional information
        plot.title = 'Row Data'
        plot.x_axis.title = 'Samples'
        plot.y_axis.title = 'Amplitude'

        # tools for basic interactivity
        plot.tools.append(PanTool(plot))
        plot.tools.append(ZoomTool(plot))
        plot.tools.append(DragZoom(plot, drag_button="right"))

        return plot
Beispiel #25
0
 VGroup(
     HGroup(
         VGroup(
             HGroup(  # Simulation Control
                 VGroup(
                     Item(name='bit_rate',    label='Bit Rate (Gbps)',  tooltip="bit rate", show_label=True, enabled_when='True',
                         editor=TextEditor(auto_set=False, enter_set=True, evaluate=float)
                     ),
                     Item(name='nbits',       label='Nbits',    tooltip="# of bits to run",
                         editor=TextEditor(auto_set=False, enter_set=True, evaluate=int)
                     ),
                     Item(name='nspb',        label='Nspb',     tooltip="# of samples per bit",
                         editor=TextEditor(auto_set=False, enter_set=True, evaluate=int)
                     ),
                     Item(name='mod_type',    label='Modulation', tooltip="line signalling/modulation scheme",
                         editor=CheckListEditor(values=[(0, 'NRZ'), (1, 'Duo-binary'), (2, 'PAM-4'),])
                     ),
                 ),
                 VGroup(
                     Item(name='do_sweep',    label='Do Sweep',    tooltip="Run parameter sweeps.", ),
                     Item(name='sweep_aves',  label='SweepAves',   tooltip="# of trials, per sweep, for averaging.", enabled_when='do_sweep == True'),
                     Item(name='pattern_len', label='PatLen',   tooltip="length of random pattern to use to construct bit stream",
                         editor=TextEditor(auto_set=False, enter_set=True, evaluate=int)
                     ),
                     Item(name='eye_bits',    label='EyeBits',  tooltip="# of bits to use to form eye diagrams",
                         editor=TextEditor(auto_set=False, enter_set=True, evaluate=int)
                     ),
                 ),
                 VGroup(
                     Item(name='vod',         label='Vod (V)',     tooltip="Tx output voltage into matched load", ),
                     Item(name='rn',          label='Rn (V)',      tooltip="standard deviation of random noise", ),
                     Item(name='pn_mag',      label='Pn (V)',      tooltip="peak magnitude of periodic noise", ),
                     Item(name='pn_freq',     label='f(Pn) (MHz)', tooltip="frequency of periodic noise", ),
                 ),
             ),
             HGroup(
                 Item(name='thresh',          label='Pj Threshold (sigma)',   tooltip="Threshold for identifying periodic jitter spectral elements. (sigma)", ),
                 Item(name='impulse_length', label='Impulse Response Length (ns)', tooltip="Manual impulse response length override", ),
                 Item(name='debug', label='Debug', tooltip='Enable to log extra information to console.', ),
                 label='Analysis Parameters', show_border=True,
             ),
             label='Simulation Control', show_border=True,
         ),
         VGroup(  # Channel Parameters
             HGroup(  # From File
                 Item(name='use_ch_file', show_label=False, tooltip='Select channel frequency/impulse/step response from file.', ),
                 Item(name='ch_file',  label='File',        enabled_when='use_ch_file == True', springy=True),
                 Item(name='padded',   label='Zero-padded', enabled_when='use_ch_file == True'),
                 Item(name='windowed', label='Windowed',    enabled_when='use_ch_file == True'),
                 Item(name='f_step',   label='f_step',      enabled_when='use_ch_file == True', tooltip='Frequency step to use in generating H(f).'),
                 Item(label='MHz'),
                 label='From File', show_border=True,
             ),
             HGroup(  # Native
                 VGroup(
                     Item(name='rs',      label='Tx_Rs (Ohms)',   enabled_when='use_ch_file == False', tooltip="Tx differential source impedance", ),
                     Item(name='cout',    label='Tx_Cout (pF)',   enabled_when='use_ch_file == False', tooltip="Tx parasitic output capacitance (each pin)", ),
                     Item(name='l_ch',    label='Length (m)',  enabled_when='use_ch_file == False', tooltip="interconnect length", ),
                 ),
                 VGroup(
                     Item(name='Theta0',  label='Loss Tan.',   enabled_when='use_ch_file == False', tooltip="dielectric loss tangent", ),
                     Item(name='Z0',      label='Z0 (Ohms)',   enabled_when='use_ch_file == False', tooltip="characteristic differential impedance", ),
                     Item(name='v0',      label='v_rel (c)',   enabled_when='use_ch_file == False', tooltip="normalized propagation velocity", ),
                 ),
                 VGroup(
                     Item(name='rin',     label='Rx_Rin (Ohms)',  enabled_when='use_ch_file == False', tooltip="Rx differential input impedance", ),
                     Item(name='cin',     label='Rx_Cin (pF)',    enabled_when='use_ch_file == False', tooltip="Rx parasitic input capacitance (each pin)", ),
                     Item(name='cac',     label='Rx_Cac (uF)',    enabled_when='use_ch_file == False', tooltip="Rx a.c. coupling capacitance (each pin)", ),
                 ),
                 label='Native', show_border=True,
             ),
             label='Channel Parameters', show_border=True,
         ),
     ),
     HGroup(
         VGroup(
             VGroup(
                 HGroup(
                     VGroup(
                         HGroup(
                             Item(name='tx_ami_valid', show_label=False, style='simple', enabled_when='False'),
                             Item(name='tx_ami_file', label='AMI File:',    tooltip="Choose AMI file."),
                         ),
                         HGroup(
                             Item(name='tx_dll_valid', show_label=False, style='simple', enabled_when='False'),
                             Item(name='tx_dll_file', label='DLL File:',    tooltip="Choose DLL file."),
                         ),
                     ),
                     VGroup(
                         Item(name='tx_use_ami',      label='Use AMI',      tooltip="You must select both files, first.",
                             enabled_when='tx_ami_valid == True and tx_dll_valid == True'),
                         Item(name='tx_use_getwave',  label='Use GetWave',  tooltip="Use the model's GetWave() function.",
                             enabled_when='tx_use_ami and tx_has_getwave'),
                         Item('btn_cfg_tx',  show_label=False, tooltip="Configure Tx AMI parameters.",
                             enabled_when='tx_ami_valid == True'),
                     ),
                 ),
                 label='IBIS-AMI', show_border=True,
             ),
             VGroup(
                 Item(   name='tx_taps',
                         editor=TableEditor(columns=[ObjectColumn(name='name', editable=False),
                                                     ObjectColumn(name='enabled', style='simple'),
                                                     ObjectColumn(name='min_val', horizontal_alignment='center'),
                                                     ObjectColumn(name='max_val', horizontal_alignment='center'),
                                                     ObjectColumn(name='value', format='%+05.3f', horizontal_alignment='center'),
                                                     ObjectColumn(name='steps', horizontal_alignment='center'),
                                                    ],
                                             configurable=False,
                                             reorderable=False,
                                             sortable=False,
                                             selection_mode='cell',
                                             auto_size=True,
                                             rows=4,
                                             # v_size_policy='ignored',
                                             # h_size_policy='minimum',
                                             # orientation='vertical',
                                             # is_grid_cell=True,
                                             # show_toolbar=False,
                                            ),
                         show_label=False,
                 ),
                 label='Native', show_border=True,
                 enabled_when='tx_use_ami == False'
             ),
             label='Tx Equalization', show_border=True,
         ),
         VGroup(
             VGroup(
                 HGroup(
                     VGroup(
                         HGroup(
                             Item(name='rx_ami_valid', show_label=False, style='simple', enabled_when='False'),
                             Item(name='rx_ami_file', label='AMI File:',    tooltip="Choose AMI file."),
                         ),
                         HGroup(
                             Item(name='rx_dll_valid', show_label=False, style='simple', enabled_when='False'),
                             Item(name='rx_dll_file', label='DLL File:',    tooltip="Choose DLL file."),
                         ),
                     ),
                     VGroup(
                         Item(name='rx_use_ami',      label='Use AMI',      tooltip="You must select both files, first.",
                             enabled_when='rx_ami_valid == True and rx_dll_valid == True'),
                         Item(name='rx_use_getwave',  label='Use GetWave',  tooltip="Use the model's GetWave() function.",
                             enabled_when='rx_use_ami and rx_has_getwave'),
                         Item('btn_cfg_rx',  show_label=False, tooltip="Configure Rx AMI parameters.",
                             enabled_when='rx_ami_valid == True'),
                     ),
                 ),
                 label='IBIS-AMI', show_border=True,
             ),
             HGroup(
                 VGroup(
                     HGroup(
                         Item(name='use_ctle_file', label='fromFile', tooltip='Select CTLE impulse/step response from file.', ),
                         Item(name='ctle_file', label='Filename',    enabled_when='use_ctle_file == True'),
                     ),
                     HGroup(
                         Item(name='peak_freq', label='CTLE fp (GHz)',   tooltip="CTLE peaking frequency (GHz)",
                                 enabled_when='use_ctle_file == False' ),
                         Item(name='rx_bw',     label='Bandwidth (GHz)', tooltip="unequalized signal path bandwidth (GHz).",
                                 enabled_when='use_ctle_file == False' ),
                     ),
                     HGroup(
                         Item(name='peak_mag',  label='CTLE boost (dB)', tooltip="CTLE peaking magnitude (dB)",
                             format_str='%4.1f', enabled_when='use_ctle_file == False' ),
                         Item(name='ctle_mode', label='CTLE mode', tooltip="CTLE Operating Mode", enabled_when='use_ctle_file == False' ),
                         Item(name='ctle_offset', tooltip="CTLE d.c. offset (dB)",
                                 show_label=False, enabled_when='ctle_mode == "Manual"'),
                     ),
                 ),
                 label='Native', show_border=True,
                 enabled_when='rx_use_ami == False'
             ),
             label='Rx Equalization', show_border=True,
         ),
         springy=True,
     ),
     HGroup(
         VGroup(
             HGroup(
                 Item(name='delta_t',      label='Delta-t (ps)',  tooltip="magnitude of CDR proportional branch", ),
                 Item(name='alpha',        label='Alpha',         tooltip="relative magnitude of CDR integral branch", ),
             ),
             HGroup(
                 Item(name='n_lock_ave',   label='Lock Nave.',    tooltip="# of UI estimates to average, when determining lock", ),
                 Item(name='rel_lock_tol', label='Lock Tol.',     tooltip="relative tolerance for determining lock", ),
                 Item(name='lock_sustain', label='Lock Sus.',     tooltip="length of lock determining hysteresis vector", ),
             ),
             label='CDR Parameters', show_border=True,
             # enabled_when='rx_use_ami == False  or  rx_use_ami == True and rx_use_getwave == False',
         ),
         VGroup(
             Item(name='use_dfe',         label='Use DFE',   tooltip="Include DFE in simulation.", ),
             Item(name='sum_ideal',       label='Ideal DFE', tooltip="Use ideal DFE. (performance boost)", enabled_when='use_dfe == True', ),
         ),
         VGroup(
             HGroup(
                 Item(name='n_taps',          label='Taps',      tooltip="# of taps",               ),
                 Item(name='gain',            label='Gain',      tooltip="error feedback gain",     ),
                 Item(name='decision_scaler', label='Level',     tooltip="target output magnitude", ),
             ),
             HGroup(
                 Item(name='n_ave',           label='Nave.',     tooltip="# of CDR adaptations per DFE adaptation", ),
                 Item(name='sum_bw',          label='BW (GHz)',  tooltip="summing node bandwidth", enabled_when='sum_ideal == False'),
             ),
             label='DFE Parameters', show_border=True,
             enabled_when='use_dfe == True',
         # enabled_when='rx_use_ami == False  or  rx_use_ami == True and rx_use_getwave == False',
         ),
     ),
     # spring,
     label = 'Config.', id = 'config',
 ),
Beispiel #26
0
class Visualization(HasTraits):

    # UI definition    
    scene = Instance(MlabSceneModel, ())

    #################################################
    #
    # Widget for Log messages
    #
    #################################################

    lastlog_string = Str
    lastlog_widget = Item('lastlog_string', show_label = False, style = 'readonly')

    #################################################
    #
    # Widget for handling Resources
    #
    #################################################

    # resource table_editor
    selected_resource = Instance(TraitResource)
    resources_table_editor = TableEditor(
        columns = [ObjectColumn(name = 'resource_name', width = 1)],
        deletable = False,
        editable = False,
        sort_model  = True,
        auto_size   = False,
        orientation = 'vertical',
        selected = 'selected_resource',
        row_factory = TraitResource)

    # Resources list
    resources_list = List(TraitResource, selection_mode = "rows")
    resources_list_widget = Item('resources_list', show_label = False, editor = resources_table_editor, padding = 10),

    # Raise/Lower Button
    resources_button = Button(label="Raise/Lower resource to level:")      
    resources_button_widget = Item('resources_button', show_label=False)

    # Raise/Lower level selector
    resources_level_int = Int
    resources_level_int_widget = Item('resources_level_int', show_label=False)

    # Raise/Lower group
    resources_raiselower_hgroup = HGroup(resources_button_widget, resources_level_int_widget)

    # Group for all the data properties widget
    rpg = VGroup(resources_list_widget, resources_raiselower_hgroup, label="Resources:", show_border=True)

    #################################################
    #
    # Widget for handling Classes
    #
    #################################################

    # class table_editor
    selected_class = Instance(TraitClass)
    classes_table_editor = TableEditor(
        columns = [ObjectColumn(name='class_name', width = 1)],
        deletable = False,
        editable = False,
        sort_model = True,
        auto_size = False,
        orientation = 'vertical',
        selected = 'selected_class',
        row_factory = TraitClass)

    # new classes widget
    classes_list = List(TraitClass)
    classes_list_widget = Item('classes_list', show_label = False, editor = classes_table_editor, padding = 10),

    # classes button
    classes_button = Button(label="Raise/Lower class to level:")
    classes_button_widget = Item('classes_button', show_label=False)

    # Raise/Lower level selector
    classes_level_int = Int
    classes_level_int_widget = Item('classes_level_int', show_label=False)

    # Raise/Lower group
    classes_raiselower_hgroup = HGroup(classes_button_widget, classes_level_int_widget)

    # Group for all the data properties widget
    cpg = VGroup(classes_list_widget, classes_raiselower_hgroup, label="Classes:", show_border=True)

    #################################################
    #
    # Widget for handling DataProperties
    #
    #################################################

    # dataproperty table_editor
    selected_dp = Instance(TraitDataProperty)
    dataproperty_table_editor = TableEditor(
        columns = [ObjectColumn(name = 'dp_name', width = 1, label = "DataProperty"), 
                   ObjectColumn(name = 'dp_domain', width = 1, label = "Domain"), 
                   ObjectColumn(name = 'dp_range', width = 1, label = "Range"),
                   ObjectColumn(name = 'dp_label', width = 1, label = "Label"), 
                   ObjectColumn(name = 'dp_comment', width = 1, label = "Comment")],
        deletable = False,
        editable = False,
        sort_model  = True,
        auto_size   = False,
        orientation = 'vertical',
        selected = 'selected_dp',
        row_factory = TraitDataProperty)

    # new dataproperties widget
    dataproperties_list = List(TraitDataProperty)
    dataproperties_list_widget = Item('dataproperties_list', show_label = False, editor = dataproperty_table_editor, padding = 10),

    # Raise/Lower Button
    dataproperties_button = Button(label="Raise/Lower Datatype Property to level:")      
    dataproperties_button_widget = Item('dataproperties_button', show_label=False)

    # Raise/Lower level selector
    dataproperties_level_int = Int
    dataproperties_level_int_widget = Item('dataproperties_level_int', show_label=False)

    # Raise/Lower group
    dataproperties_raiselower_hgroup = HGroup(dataproperties_button_widget, dataproperties_level_int_widget)

    # Group for all the data properties widget
    dpg = VGroup(dataproperties_list_widget, dataproperties_raiselower_hgroup, label="Data Properties:", show_border=True)
    
    #################################################
    #
    # Widget for handling Objectproperties
    #
    #################################################

    # objectproperty table_editor
    selected_op = Instance(TraitObjectProperty)
    objectproperty_table_editor = TableEditor(
        columns = [ObjectColumn(name = 'op_name', width = 1, label = "Objectproperty"), 
                   ObjectColumn(name = 'op_domain', width = 1, label = "Domain"), 
                   ObjectColumn(name = 'op_range', width = 1, label = "Range"),
                   ObjectColumn(name = 'op_label', width = 1, label = "Label"), 
                   ObjectColumn(name = 'op_comment', width = 1, label = "Comment")],
        deletable = False,
        editable = False,
        sort_model  = True,
        auto_size   = False,
        orientation = 'vertical',
        selected = 'selected_op',
        row_factory = TraitObjectProperty)

    # new objectproperties widget
    objectproperties_list = List(TraitObjectProperty)
    objectproperties_list_widget = Item('objectproperties_list', show_label = False, editor = objectproperty_table_editor, padding = 10),

    # Raise/Lower Button
    objectproperties_button = Button(label="Raise/Lower Object Property to level:")      
    objectproperties_button_widget = Item('objectproperties_button', show_label=False)

    # Hide Button
    objectproperties_hide_button = Button(label="Hide/Show Object Property")      
    objectproperties_hide_button_widget = Item('objectproperties_hide_button', show_label=False)

    # Raise/Lower level selector
    objectproperties_level_int = Int
    objectproperties_level_int_widget = Item('objectproperties_level_int', show_label=False)

    # Raise/Lower group
    objectproperties_raiselower_hgroup = HGroup(objectproperties_hide_button_widget, objectproperties_button_widget, objectproperties_level_int_widget)

    # Group for all the object properties widgets
    opg = VGroup(objectproperties_list_widget, objectproperties_raiselower_hgroup, label="Object Properties:", show_border=True)

    #################################################
    #
    # Widget for handling custom queries
    #
    #################################################
    
    # query prefixes widgets
    query_rdf_prefix = Bool(True, label="RDF Prefix")
    query_owl_prefix = Bool(True, label="OWL Prefix")
    query_rdfs_prefix = Bool(True, label="RDFS Prefix")
    query_ns_prefix = Bool(True, label="NS Prefix")
    
    # multilevel
    query_multilevel = Bool(False, label="Multilevel Query?")
    query_reification = Bool(False, label="Reification Query?")

    # query widgets
    query_string = Str
    query_entry_widget = Item('query_string', show_label=False)

    # query button
    query_button = Button(label="SPARQL Query") 
    query_button_widget = Item('query_button', show_label=False)

    # Raise/Lower level selector
    query_level_int = Int
    query_level_int_widget = Item('query_level_int', show_label=False)

    # Prefixes Group
    query_prefixes_group = VGroup('query_rdf_prefix', 'query_rdfs_prefix', 'query_owl_prefix', 'query_ns_prefix', 'query_multilevel', 'query_reification')

    # Raise/Lower group
    query_raiselower_hgroup = HGroup(query_prefixes_group, query_button_widget, query_level_int_widget)

    # group for all the query widgets
    qpg = VGroup(query_entry_widget, query_raiselower_hgroup, label="SPARQL Query", show_border=True)

    #################################################
    #
    # Widget for handling planes
    #
    #################################################

    # query button
    plane_button = Button(label="Merge plane A on plane B") 
    plane_button_widget = Item('plane_button', show_label=False)

    # Raise/Lower level selector
    plane_level_int1 = Int
    plane_level_int1_widget = Item('plane_level_int1', show_label=False)
    plane_level_int2 = Int
    plane_level_int2_widget = Item('plane_level_int2', show_label=False)

    # Raise/Lower group
    plane_merge_hgroup = HGroup(plane_level_int1_widget, plane_button_widget, plane_level_int2_widget)

    # group for all the query widgets
    ppg = VGroup(plane_merge_hgroup, label="Planes", show_border=True)


    #################################################
    #
    # Widget for stats
    #
    #################################################

    # stats string
    stats_string = Str
    stats_string_widget = Item('stats_string', show_label=False, style="readonly")    

    # group for all the query widgets
    spg = VGroup(stats_string_widget, label="Info", show_border=True)


    #################################################
    #
    # Widget for exporting png
    #
    #################################################

    # export widgets
    export_button = Button(label="Export as PNG image") 
    export_button_widget = Item('export_button', show_label=False)


    #################################################
    #
    # Widget for resetting the planes
    #
    #################################################

    # refresh widgets
    reset = Button(label="Reset placement")
    reset_w = Item('reset', show_label=False)

    #################################################
    #
    # Widget for refreshing the view
    #
    #################################################

    # refresh widgets
    refresh = Button(label="Refresh")
    refresh_w = Item('refresh', show_label=False)
   
    # widgets
    view = View(VGroup(HGroup(VGroup(Tabbed(rpg, cpg, dpg, opg, qpg, ppg, spg),
                                     export_button_widget,
                                     reset_w,
                                     refresh_w), 
                              Item('scene', editor=SceneEditor(scene_class=MayaviScene), height=640, width=800, show_label=False))), 
                lastlog_widget,
                scrollable=True)
   
    # constructor
    def __init__(self, kp):

        """Initializer of the UI class"""

        ###################################################
        #
        # Initialize the scene
        #
        ###################################################

        # super class initializer
        HasTraits.__init__(self)

        # Drawer instance
        self.drawer = Drawer(self.scene)

        ###################################################
        #
        # Retrieve Data
        #
        ###################################################

        # store the kp
        self.kp = kp
        if self.kp.owl_files:
            self.kp.load_owl()
        elif self.kp.n3_files:
            self.kp.load_n3()
        elif self.kp.blazehost:
            self.kp.get_everything_blaze()
        else:
            self.kp.get_everything()
        
        ###################################################
        #
        # Fill the side lists
        #
        ###################################################
        
        # get data properties
        dps = self.kp.get_data_properties()
        for dp in dps:
            self.dataproperties_list.append(TraitDataProperty(dp_name = str(dp[0]), dp_domain = str(dp[1]), dp_range = str(dp[2])))

        # get object properties
        ops = self.kp.get_object_properties()    
        for op in ops:
            self.objectproperties_list.append(TraitObjectProperty(op_name = str(op[0]), op_domain = str(op[1]), op_range = str(op[2])))

        # get instances
        for res in self.kp.get_instances():
            self.resources_list.append(TraitResource(resource_name = str(res[0])))

        # get classes
        cs = self.kp.get_classes()
        for c in cs:
            self.classes_list.append(TraitClass(class_name = str(c)))

        ###################################################
        #
        # Draw
        #
        ###################################################

        # initialize data structures
        self.res_list = ResourceList()
        self.planes = []
        self.active_labels = []

        # get and analyze knowledge
        self.data_classifier()
        self.calculate_placement()
        self.draw()


    @on_trait_change('scene.activated')
    def scene_ready(self):

        # get the figure and bind the picker
        self.figure = self.scene.mayavi_scene
        self.figure.on_mouse_pick(self.picker_callback)


    def picker_callback(self, picker):
            
        # find the resource related to the clicked object
        # ..if any

        # NOTE: this code is absolutely raw. Needs to be
        # optimized and many tricks can be used to speed
        # up the execution even with large datasets.

        for resource in self.res_list.list.keys():

            # cycle over the resources
            r = self.res_list.list[resource]      
            if picker.actor in r.gitem.actor.actors:
                logging.debug("Received click on %s" % r.name)
                self.lastlog_string = r.name
                
                if r.isStatement:
                    print r.name
                    s,p,o = self.kp.get_statement_els(r.name)
                    self.lastlog_string = "Selected statement (%s,%s,%s)" % (s,p,o)
                    
                else:
                    
                    # remove active labels
                    for label in self.active_labels:                    
                        label.remove()
                    self.active_labels = []

                    # draw the new labels
                    for active_label in self.drawer.draw_text(r):
                        self.active_labels.append(active_label)

                    # fill the side panel
                    self.stats_string = r.get_info()

                break

            else:                

                # cycle over the data properties
                for dp in r.data_properties:
                    if picker.actor in dp.gitem_predicate.actor.actors:
                        logging.debug("Received click on %s" % dp.dproperty)
                        self.lastlog_string = dp.dproperty
                        break
                        
                # cycle over the object properties
                for op in r.object_properties:
                    if picker.actor in op.gitem.actor.actors:
                        logging.debug("Received click on %s" % op.oproperty)
                        self.lastlog_string = op.oproperty
                        break


    def _plane_button_fired(self):

        """This method is used to merge a plane with the plane 0"""

        # debug print
        logging.debug("Merge plane function called")
        self.lastlog_string = "Merge plane function called"

        # get the plane to merge
        l1 = self.plane_level_int1    
        l2 = self.plane_level_int2   

        # get items on that plane
        uri_list = self.res_list.find_by_layer(l1)
        
        # move items on plane 0
        self.redraw(uri_list, l2)


    def _export_button_fired(self):
        
        """This method is used to export the scene to a PNG image"""
        
        # debug print
        logging.debug("Exporting the current scene to a PNG image")
        self.lastlog_string = "Exporting the current scene to a PNG image"

        # # export
        # self.scene.save("/tmp/output.png")


    def _reset_fired(self):
        
        """This method is used to reset the view to plane 0"""
        
        # debug print
        logging.debug("Resetting the view to plane 0")
        self.lastlog_string = "Resetting the view to plane 0"

        # reset
        self.redraw(None, 0)


    def _query_button_fired(self):

        """This method is executed when the query button is pressed"""    

        # debug print
        logging.debug("QUERY button pressed")
        self.lastlog_string = "QUERY button pressed"

        # get required prefixes
        prefixes = ""
        if self.query_rdf_prefix:
            prefixes += RDF_PREFIX
        if self.query_rdfs_prefix:
            prefixes += RDFS_PREFIX
        if self.query_owl_prefix:
            prefixes += OWL_PREFIX
        if self.query_ns_prefix:
            prefixes += NS_PREFIX

        # multilevel
        multilevel = self.query_multilevel

        if not multilevel:

            # read the required value
            l = self.query_level_int    
     
            # retrieve URI related to the query
            # execute the sparql query
            uri_list = []
            if self.query_reification:
                uri_list = self.kp.custom_query(q_reification)
            else:
                if len(self.query_string) > 0:
                    uri_list = self.kp.custom_query(prefixes + self.query_string)

            # move objects!
            self.redraw(uri_list, l)

        else:

            # retrieve URI related to the query
            # execute the sparql query
            uri_list = []
            if self.query_reification:
                print "here"
                uri_list = self.kp.custom_multilevel_query(q_reification)
                print "here"
                print uri_list
            else:
                if len(self.query_string) > 0:
                    uri_list = self.kp.custom_multilevel_query(prefixes + self.query_string)
                
            # move objects!
            level_counter = 0
            for level in uri_list:

                level_counter += 1
                self.redraw(level, level_counter)                


    def calculate_res_coords(self, num_items, z):

        """This function calculate the best placement for
        num_items items"""

        # initialize coords
        coords = []
        
        # divide 360 by the number of points to get the base angle
        if num_items > 0:
            multiplier = 30
            angle = 360 / num_items
            iteration = 0 
            for item in xrange(num_items):        
                x = multiplier * math.cos(math.radians(iteration * angle))
                y = multiplier * math.sin(math.radians(iteration * angle))                
                coords.append([x,y,z])
                iteration += 1
                
        # return
        return coords

    
    def calculate_dp_coords(self, r):

        """This method is used to calculate the coordinates
        for all the data properties of a resource r"""

        # initialize coords
        coords = []

        # get the center
        x, y, z = r.get_coordinates()

        # calculate coordinates for datatype properties
        num_prop = len(r.data_properties)
        if num_prop > 0:
            dangle = 360 / num_prop
            diteration = 0
            for dp in xrange(num_prop):
                        
                dmultiplier = 7
                dpx = dmultiplier * math.cos(math.radians(diteration * dangle)) + x
                dpy = dmultiplier * math.sin(math.radians(diteration * dangle)) + y
                dpz = z
                coords.append([dpx, dpy, dpz])
                diteration += 1
            
        # return 
        return coords


    def redraw(self, uri_list, plane):

        """This function moves all the resources of uri_list
        to the plane indicated by the plane variable. If uri_list 
        is None and plane is 0, then everything is reset to the 
        initial position."""

        # temporarily disable rendering for faster visualization
        self.scene.disable_render = True

        # delete all the text labels
        for active_label in self.active_labels:
            active_label.remove()
        self.active_labels = []

        # since the plane may already host other objects,
        # we get the list of objects on that plane and
        # merge it with the uri_list
        if uri_list:
            old_uri_list = self.res_list.find_by_layer(plane)
            new_uri_list = old_uri_list + uri_list

        # calculate new coordinates for object on the given plane
        if uri_list:
            coords = self.calculate_res_coords(len(new_uri_list), plane*100)
        else:
            coords = self.calculate_res_coords(len(self.res_list.list), plane*100)

        # iterate over the uris
        for resource in self.res_list.list.keys():

            r = self.res_list.list[resource]      
            if (not(uri_list) and plane == 0) or (r.name in new_uri_list):
                
                # remove the old object
                r.gitem.remove() 

                # get the new coordinates
                x,y,z = coords.pop()
                r.set_coordinates(x,y,z)
                
                # design the new object on a different plane                
                gitem = self.drawer.draw_resource(r)
                r.gitem = gitem
                
                # also raise the dp
                dpcoords = self.calculate_dp_coords(r)
                for dp in r.data_properties:
                     
                    # delete the old property
                    dp.gitem_object.remove()
                    dp.gitem_predicate.remove()
                    
                    # update the coordinate
                    xx, yy, zz = dpcoords.pop()
                    dp.set_coordinates(xx, yy, zz)
                     
                    # draw the property                 
                    a1, a2 = self.drawer.draw_data_property(dp)
                    dp.gitem_predicate = a1
                    dp.gitem_object = a2
                 
        # also redraw the object properties
        for resource in self.res_list.list.keys():
            r = self.res_list.list[resource]      
            for op in r.object_properties:
                 
                # delete the old object property
                op.gitem.remove()
                     
                # draw the edge
                item = self.drawer.draw_object_property(op)       
                op.gitem = item

        # remove existing planes and draw a plane where needed
        needed_planes = self.res_list.get_layers_list().keys()
        for plane in self.planes:
            plane.remove()
        self.planes = []
        for needed_plane in needed_planes:
            self.planes.append(self.drawer.draw_plane(int(needed_plane)))
    
        # enable rendering
        self.scene.disable_render = False
        

    def _classes_button_fired(self):
        
        # getting selected class
        c = self.selected_class.class_name
    
        # read the required value
        l = self.classes_level_int    

        # debug print
        logging.debug("Raising instances of class %s" % c)
        self.lastlog_string = "Raising instances of class %s" % c    

        # getting instances of classs c
        uri_list = []
        qres = self.kp.get_instances_of(c)
        for res in qres:
            uri_list.append(str(res[0]))

        # raising instances
        self.redraw(uri_list, l)        


    def _resources_button_fired(self):
        
        # getting selected resource
        r = self.selected_resource.resource_name

        # read the required value
        l = self.resources_level_int    

        # debug print
        logging.debug("Raising resource %s" % r)
        self.lastlog_string = "Raising resource %s" % r
        
        # raise
        self.redraw([r], l)


    def _dataproperties_button_fired(self):
        
        # getting selected datatype property
        dp = self.selected_dp.dp_name

        # read the required value
        l = self.dataproperties_level_int    
    
        # debug print
        logging.debug("Raising instances of class %s" % dp)
        self.lastlog_string = "Raising instances with datatype property %s" % dp

        # getting instances with dataproperty dp
        uri_list = []
        qres = self.kp.get_instances_with_dp(dp)
        for res in qres:
            uri_list.append(str(res[0]))

        # raising instances
        self.redraw(uri_list, l)


    def _objectproperties_button_fired(self):
        
        # getting selected object property
        op = self.selected_op.op_name
    
        # read the required value
        l = self.objectproperties_level_int    

        # debug print
        logging.debug("Raising instances with object property %s" % op)
        self.lastlog_string = "Raising instances with object property %s" % op

        # getting instances with object property op
        uri_list = []
        qres = self.kp.get_instances_with_op(op)
        for res in qres:
            uri_list.append(str(res[0]))

        # raising instances
        self.redraw(uri_list, l)


    def _objectproperties_hide_button_fired(self):
        
        # getting selected object property
        opname = self.selected_op.op_name
    
        # debug print
        logging.debug("Hide/show object property %s" % opname)
        self.lastlog_string = "Hide/show object property %s" % opname               

        # draw object properties
        for resource in self.res_list.list.keys():                
            for op in self.res_list.list[resource].object_properties:
                if op.oproperty == opname:
                    
                    # if item is None -> draw, else remove
                    if op.gitem:
                        op.gitem.remove()
                        op.gitem = None
                    else:
                        # draw the edge
                        item = self.drawer.draw_object_property(op)       
                        op.gitem = item


    def _refresh_fired(self):
        
        """This method is executed when the refresh button is pressed"""
        
        # debug
        logging.debug("REFRESH button pressed")

        # clean
        self.scene.mlab.clf()

        # TODO redraw
        pass


    def data_classifier(self, sparql_query=None):

        # re-init res_list
        self.res_list = ResourceList()
        
        # retrieve classes
        cs = self.kp.get_classes()

        # retrieve statements
        sts = self.kp.get_statements()
        
        # execute the sparql query
        uri_list = []
        if sparql_query:
            uri_list = self.kp.custom_query(sparql_query)

        # data analyzer
        for triple in self.kp.local_storage:
    
            sub, pred, ob = triple
            print triple
            
            # analyze the subject
            sub_res = self.res_list.find_by_name(str(sub))
            if not sub_res:
                
                # Create a new Resource
                if str(sub) in cs:                                        
                    sub_res = Resource(sub, True)                        
                else:
                    sub_res = Resource(sub, False)
                    if str(sub) in sts:
                        sub_res.isStatement = True                    
                self.res_list.add_resource(sub_res)
                
            # analyze the object
            if isinstance(ob, rdflib.URIRef):
                ob_res = self.res_list.find_by_name(str(ob))
                if not ob_res:

                    if str(ob) in cs:                    
                        ob_res = Resource(ob, True)
                    else:
                        ob_res = Resource(ob, False)

                    self.res_list.add_resource(ob_res)

            # analyze the predicate (looking at the object)
            if isinstance(ob, rdflib.URIRef):
    
                # new object property found
                op = ObjectProperty(pred, sub_res, ob_res)
                sub_res.add_object_property(op)
    
            else:
    
                # new data property found
                dp = DataProperty(pred, sub_res, str(ob))
                sub_res.add_data_property(dp)        

        # look for comments and labels
        comments = self.kp.get_all_comments()
        for c in comments:
            res = self.res_list.find_by_name(str(c[0]))
            if res:
                res.comment = c[1]        

        labels = self.kp.get_all_labels()
        for l in labels:
            res = self.res_list.find_by_name(str(l[0]))
            if res:
                res.label = l[1]

                
    def calculate_placement_ng(self, uriplanes = None):

        """This method is used to calculate the best placement for
        nodes. uriplanes is a list of lists.  The first list specifies
        the items to be placed on plane 1 (the default is plane 0),
        the second on plane 2, and so on. If None everything is placed
        on plane 0"""

        # calculate the elements for each plane
        if uriplanes:

            # determine the number of planes
            num_planes = len(uriplanes)
            
            # create a list for every plane
            planes = []
            for p in range(num_planes):
                planes.append([])
            
            # fill the previously created lists
            for resource in self.res_list.list.keys():

                # find in which plane must be placed the resource
                plane_found = False
                r = self.res_list.list[resource]      
                plane_counter = 0
                for uriplane in uriplanes:
                    plane_counter += 1
                    if r.name in uriplane:                        
                        print "PLANE FOUND!"
                        planes[plane_counter].append(r)
                        plane_found = True
                        break
                if not plane_found:
                    planes[0].append(r)
                    
        print "PLANES ARE:"
        counter = 0
        for plane in planes:
            print "* plane %s:" % counter
            print plane
            print
            counter += 1


    def calculate_placement(self):

        """This method is used to calculate the best
        placement for nodes on the plane 0"""

        # resource coordinates generator
        num_points = len(self.res_list.list)
        
        # divide 360 by the number of points to get the base angle
        if num_points > 0:
            multiplier = 30
            angle = 360 / num_points
            iteration = 0 
            for resource in self.res_list.list.keys():
        
                r = self.res_list.list[resource]        
                x = multiplier * math.cos(math.radians(iteration * angle))
                y = multiplier * math.sin(math.radians(iteration * angle))
                self.res_list.list[resource].set_coordinates(x,y,0)
        
                # calculate coordinates for datatype properties
                num_prop = len(r.data_properties)
                try:
                    dangle = 360 / num_prop
                    diteration = 0
                    for dp in r.data_properties:
                        
                        dmultiplier = 7
                        dp.x = dmultiplier * math.cos(math.radians(diteration * dangle)) + r.get_coordinates()[0]
                        dp.y = dmultiplier * math.sin(math.radians(diteration * dangle)) + r.get_coordinates()[1]
                        dp.z = r.get_coordinates()[2]                                                
                        diteration += 1

                except:
                    pass                
                iteration += 1   
        

    def draw(self):

        """This method is called at init time or at refresh time.
        Everything is placed on plane 0. Then the selected items
        can be moved to other planes with proper functions"""

        # disable rendering
        self.scene.disable_render = True

        # create a dict for plane0
        plane0_dict = {}

        # draw plane
        plane0_dict["plane"] = self.drawer.draw_plane(0)
        plane0_dict["widgets"] = []

        # draw resources
        for resource in self.res_list.list.keys():
            r = self.res_list.list[resource]        
            gitem = self.drawer.draw_resource(r)
            r.gitem = gitem            

            # draw data properties
            for dp in r.data_properties:
                
                # draw the property                
                a1, a2 = self.drawer.draw_data_property(dp)
                dp.gitem_object = a2
                dp.gitem_predicate = a1

        # draw object properties
        for resource in self.res_list.list.keys():                
            for op in self.res_list.list[resource].object_properties:

                # draw the edge
                item = self.drawer.draw_object_property(op)       
                op.gitem = item

        # enable rendering
        self.scene.disable_render = False        

        # store the first plane
        self.planes.append(plane0_dict["plane"])
Beispiel #27
0
class ChainOfBundlesAnalysis(HasTraits):
    '''
    Manage the distributions representing the chaoined bundle.
    '''
    l_rho = Float(1.0, auto_set=False, enter_set=True, input=True)
    scale_rho = Float(1.095208512, auto_set=False, enter_set=True, input=True)
    m = Float(4.5422149741521, auto_set=False, enter_set=True, input=True)
    l_tot = Float(1.0, auto_set=False, enter_set=True, input=True)
    nb = Float(5, auto_set=False, enter_set=True, input=True)
    nf = Int(10, auto_set=False, enter_set=True, input=True)
    fiber_total = Bool(True, input=True)
    fiber_bundle = Bool(True, input=True)
    bundle_total = Bool(True, input=True)
    bundle_bundle = Bool(True, input=True)
    yarn_total = Bool(True, input=True)

    distribs = Property(depends_on='+input')

    @cached_property
    def _get_distribs(self):
        l_rho = self.l_rho
        scale_rho = self.scale_rho
        m = self.m
        l_tot = self.l_tot
        nb = self.nb
        nf = self.nf

        #
        # Source distribution for the reference length (l_rho)
        #
        wd_r = WeibullDistrib(scale=scale_rho, shape=m, length=l_rho)
        #
        # Scaled distribution for a single fiber with the length l_tot
        #
        sfd_t = ScaledWeibullDistrib(wd_r, length=l_tot)
        #
        # Bundle distribution with the length l_tot
        #
        dsd_t = DanielsSmithDistrib(sfd_t, nf)
        #
        # Scaled distribution for a single fiber with the bundle length (l_tot/nb)
        #
        sfd_b = ScaledWeibullDistrib(wd_r, length=l_tot / nb)
        #
        # Bundle distribution with the length l_tot/nb
        #
        dsd_b = DanielsSmithDistrib(sfd_b, nf)
        #
        # Construct the random variables - by specifying the distribution and
        # the number of sampling points
        #
        # The Chain of Bundle random variable is special in that it is
        # constructed by making an instance of bundle distribution and
        # constructing the cdf and pdf by its integration.
        #
        return  RandomVariable( sfd_t, 500 ), \
            RandomVariable( dsd_t, 500 ), \
            RandomVariable( sfd_b, 500 ), \
            RandomVariable( dsd_b, 500 ), \
            RandomChainOfBundlesVariable(dsd_b, nb, sims=500)

    # Distribution of the single filament strength on the length l_tot
    sfd_t = Property(depends_on='+input')

    def _get_sfd_t(self):
        return self.distribs[0]

    view_chob = View(VGroup(
        HGroup(
            Group(Item('l_rho', label='reference length'),
                  Item('scale_rho', label='scale parameter'),
                  Item('m', label='shape parameter'),
                  dock='tab'),
            Group(Item('nf', label='number of filaments'),
                  Item('nb', label='number of bundles'),
                  Item('l_tot', label='total length'),
                  dock='tab'),
            Group(Item('fiber_total', label='fiber (t)'),
                  Item('fiber_bundle', label='fiber (b)'),
                  Item('bundle_total', label='bundle (t)'),
                  dock='tab'),
            Group(Item('bundle_bundle', label='bundle (b)'),
                  Item('yarn_total', label='yarn (t)'),
                  dock='tab'),
        ), ),
                     resizable=True,
                     scrollable=True,
                     height=0.8,
                     width=0.8)
Beispiel #28
0
from tvtk.api import tvtk

from ..defaults import DEFAULTS
from ..surface import _CheckInside, _DistanceQuery
from ..transforms import apply_trans, rotation
from ..utils import SilenceStdout
from ..viz.backends._pysurfer_mayavi import (_create_mesh_surf, _oct_glyph,
                                             _toggle_mlab_render)

try:
    from traitsui.api import RGBColor
except ImportError:
    from traits.api import RGBColor

headview_borders = VGroup(Item('headview', style='custom', show_label=False),
                          show_border=True,
                          label='View')


def _mm_fmt(x):
    """Format data in units of mm."""
    return '%0.1f' % x


laggy_float_editor_mm = TextEditor(auto_set=False,
                                   enter_set=True,
                                   evaluate=float,
                                   format_func=lambda x: '%0.1f' % x)

laggy_float_editor_scale = TextEditor(auto_set=False,
                                      enter_set=True,
Beispiel #29
0
class MainWindow(HasTraits):
    
    #This functio takes care of loading or saving the pck
    def _pck_(self,action,f=mainpck):
        if action == 'load':
            try:

                try:
                    fpck=open(f,"rb")
                    print 'Loading panel from %s ... ' % mainpck
                    self.seqs = pickle.load(fpck)

                    self.autorangeY = pickle.load(fpck)
                    self.plot_rangeY_max = pickle.load(fpck)
                    self.plot_rangeY_min = pickle.load(fpck)
                 
                    self.autorange = pickle.load(fpck)
                    self.plot_range_max = pickle.load(fpck)
                    self.plot_range_min = pickle.load(fpck)
                    fpck.close()
                except:
                    fpck=open(f,"rb")
                    print 'Loading panel from %s ... ' % mainpck
                    self.seqs = pickle.load(fpck)
                    fpck.close()
                 
            except:
                print "Loading Fail"
                return
        if action == 'save':
            print 'Saving panel to %s ...' % mainpck
            fpck=open(f,"w+b")
            pickle.dump(self.seqs,fpck)
            
            pickle.dump(self.autorangeY, fpck)
            pickle.dump(self.plot_rangeY_max, fpck)
            pickle.dump(self.plot_rangeY_min, fpck)

            pickle.dump(self.autorange, fpck)
            pickle.dump(self.plot_range_max, fpck)
            pickle.dump(self.plot_range_min, fpck) 

            fpck.close()
    
    #Here are the elements of the main window
    figure = Figure()

    global seqct
    seqct = seqct + 1  #increment seq counter
    seqs = List([sequence(name='S%d' % seqct,txtfile=default_file)])
    
    selectedseq = Instance(sequence)
    index = Int

    add = Button("Add Sequence")
    plot = Button("Plot")
   

    
    data_digi = List()
    data_digi_time = List()
    data_digi_names = List()

    data_analog = List()
    data_analog_time = List()
    data_analog_names = List()

    
    autorangeY = Bool(True, label="Autorange in Y?")
    plot_rangeY_max = Float(10)
    plot_rangeY_min = Float(0)
    
    autorange = Bool(True, label="Autorange?")
    plot_range_max = Float(10000)
    plot_range_min = Float()
    
    
    def _figure_default(self):
        self.figure = Figure()
        self.figure.add_axes([0.05, 0.04, 0.9, 0.92])
        
    #This group contains the View of the control buttons
    #and the waveforms  
    control_group = Group(
                        Item('plot', show_label = False),
                        VGroup(
                            Item( 'seqs',
                                style  = 'custom',
                                editor = ListEditor( use_notebook = True,
                                           selected     = 'selectedseq',
                                           deletable    = True,
                                           dock_style   = 'tab',
                                           page_name    = '.name')
                            ),
                            Item('add', show_label = False),       
                               show_labels = False,
                               show_border = True,
                               label       = 'seqs',
                        ))
     
    #This is the view of the Main Window, including the
    #control group
    view= View( 
                HSplit(
                    control_group,
                    VGroup( 
                        Item('figure', editor=MPLFigureEditor(),
                            dock='vertical', show_label = False,width=700),
                        HGroup( 'autorange',   'plot_range_min', spring, 'plot_range_max'),
                        HGroup( 'autorangeY', 'plot_rangeY_min', spring, 'plot_rangeY_max')
                          )
                      ),
                title = 'Display Sequence',
                width     = 1,
                height    = 0.95,
                resizable = True,
                handler=MainWindowHandler(),
            )
    
    def _selectedseq_changed(self,selectedseq):
        self.index = self.seqs.index(selectedseq)

    #Define action when a new sequence is added
    def _add_fired(self):
        global seqct
        seqct = seqct + 1
     
        new = copy.deepcopy( self.seqs[self.index] )
        new.name = 'S%d' % seqct  
        self.seqs.append( new ) 


    #Define action when the plot button is pressed
    def _plot_fired(self):
         
        self.get_data()
        self.image_show()
    
    #~ def _plot_range_max_changed(self):
        #~ sleep()
        #~ self.image_show()
         
    #~ def _plot_range_min_changed(self):
         #~ self.image_show()
  
 
    #Here the data 
    def get_data(self):
        
        self.data_digi = []
        self.data_digi_time = []
        self.data_digi_names = []

        self.data_analog = []
        self.data_analog_time = []
        self.data_analog_names = []

        self.data_physical = []
        self.data_physical_time = []
        self.data_physical_names = []

        #Find out how many digital channels will be plotted 
        digi_counter = 1
        for seq in self.seqs:
            if seq.plotme == True:
               for waveform in seq.waveforms:
                   for i, channel in enumerate( waveform.channels):
                       if channel in waveform.select_channels:
                           if waveform.name == 'Digital':
                               digi_counter = digi_counter + 1
      


        #Setup all the digital & analog channels from the various
        #seqs for plotting 
        digi_counter_2 = 1
        for seq in self.seqs:
            if seq.plotme == True:
               #Prepare the physical quantities calculator class   
               physical = physics.calc(seq.seq.wfms)
               print "\n--------  GETTING DATA TO PRODUCE PLOT  --------"
               for waveform in seq.waveforms:
                   for i, channel in enumerate( waveform.channels):
                       if channel in waveform.select_channels:
                        
                           if waveform.name == 'Digital':
                               self.data_digi_time.append(waveform.time)
                               self.data_digi_names.append(seq.name + '_' + waveform.name + '_' + channel)
                               
                               length = len(waveform.select_channels)
                               height = 10./(digi_counter-1)
                               
                               self.data_digi.append(  [ i*height*0.8 - digi_counter_2*height + height*0.1  \
                                                         for i in waveform.data[i] ]  )
   
                               digi_counter_2 = digi_counter_2 + 1
                             
                           elif waveform.name == 'Analog':
                               self.data_analog_names.append(seq.name + '_' + waveform.name + '_' + channel)
                               self.data_analog_time.append(waveform.time[i])
                               self.data_analog.append(waveform.data[i])
                               
                           elif waveform.name == 'Physical':
                               self.data_physical_names.append(seq.name + '_' + waveform.name + '_' + channel)
                               if channel in seq.calcwfms.keys() and not seq.recalculate:
                                  print "\n...Reusing Physical: %s" % channel
                                  dat = seq.calcwfms[channel]
                               else:
                                  print "\n...Calculating Physical: %s" % channel
                                  dat = physical.calculate(channel)
                                  seq.calcwfms[channel] = dat

                               self.data_physical_time.append( dat[0] )
                               self.data_physical.append( dat[1] )
            seq.recalculate = False
                                                        
        
    def image_clear(self):
        """ Clears canvas 
        """
        self.figure.clf()
        wx.CallAfter(self.figure.canvas.draw)
    
    
    def image_show(self):
        """ Plots an image on the canvas
        """
        self.image_clear()
        analog_axis = self.figure.add_axes([0.08,0.5,0.7,0.4])

        digi_axis_left = self.figure.add_axes([0.08,0.05,0.7,0.4])
        digi_axis_left.set_yticks([])

        digi_axis = digi_axis_left.twinx()
        digi_ticks = []

        #physical_axis = analog_axis.twinx() 

        #Makes the digital plot
        for i, name in enumerate(self.data_digi_names):
            digi_axis.step(self.data_digi_time[i],self.data_digi[i],lw='2.0',where = 'post', label = name)
            digi_ticks.append( - (i+0.5)*10./len(self.data_digi_names))
            digi_axis.axhline(- (i+1)*10./len(self.data_digi_names),color='grey', lw=1.5)

        #digi_axis.legend(bbox_to_anchor=(1.01, 0.5),loc=2,prop={'size':10})
        digi_axis_left.set_ylabel('TTL')
        
        #Label the digital waveforms using the ticklabels on the plot    
        digi_axis.set_ylim(bottom=-11,top=0)
        digi_axis.set_yticks(digi_ticks)
        digi_axis.set_yticklabels(self.data_digi_names)

        digi_axis_left.get_xaxis().set_minor_locator( matplotlib.ticker.AutoMinorLocator() )
        digi_axis_left.grid(True, which='both')
    
        #Makes the analog plot
        for i, name in enumerate(self.data_analog_names):
            analog_axis.step(self.data_analog_time[i],self.data_analog[i],where = 'post', label = name)  
    
        #Makes the physical plot
        for i, name in enumerate(self.data_physical_names):
            analog_axis.step(self.data_physical_time[i],self.data_physical[i],ls='-',lw=1.75,where = 'post', label = name)  
        
        analog_axis.axhline(0, color='black', lw=2)
        analog_axis.legend(bbox_to_anchor=(1.01, 1.01),loc=2,prop={'size':10})
        analog_axis.set_xlabel('Time(ms)')
        analog_axis.set_ylabel('Voltage(V) / Physical(?)')
        analog_axis.get_xaxis().set_minor_locator( matplotlib.ticker.AutoMinorLocator() )
        analog_axis.grid(True, which='both')
       
        #Take care of the Yaxis range of the analog plot 
        if not self.autorangeY: 
            analog_axis.set_ylim(self.plot_rangeY_min,self.plot_rangeY_max)
        else:
            axismin =  min(analog_axis.get_ylim())
            axismax =  max(analog_axis.get_ylim())
            analog_axis.set_ylim(axismin,axismax)
            self.plot_rangeY_max = axismax
            self.plot_rangeY_min = axismin
        
        #Take care of the Xaxis(time) range for both plots
        if not self.autorange: 
            analog_axis.set_xlim(self.plot_range_min,self.plot_range_max)
            digi_axis.set_xlim(self.plot_range_min,self.plot_range_max)
        else:
            axismin =  min(analog_axis.get_xlim()+digi_axis.get_xlim())
            axismax =  max(analog_axis.get_xlim()+digi_axis.get_xlim())
            analog_axis.set_xlim(axismin,axismax)
            digi_axis.set_xlim(axismin,axismax)
            #~ analog_axis.set_ylim(bottom=0,top=11)
            self.plot_range_max = axismax
            self.plot_range_min = axismin
        
        
        wx.CallAfter(self.figure.canvas.draw)
Beispiel #30
0
class HeadViewController(HasTraits):
    """Set head views for the given coordinate system.

    Parameters
    ----------
    system : 'RAS' | 'ALS' | 'ARI'
        Coordinate system described as initials for directions associated with
        the x, y, and z axes. Relevant terms are: Anterior, Right, Left,
        Superior, Inferior.
    """

    system = Enum("RAS",
                  "ALS",
                  "ARI",
                  desc="Coordinate system: directions of "
                  "the x, y, and z axis.")

    right = Button()
    front = Button()
    left = Button()
    top = Button()
    interaction = Enum('trackball', 'terrain')

    scale = Float(0.16)

    scene = Instance(MlabSceneModel)

    view = View(
        VGroup(VGrid('0',
                     Item('top', width=_VIEW_BUTTON_WIDTH),
                     '0',
                     Item('right', width=_VIEW_BUTTON_WIDTH),
                     Item('front', width=_VIEW_BUTTON_WIDTH),
                     Item('left', width=_VIEW_BUTTON_WIDTH),
                     columns=3,
                     show_labels=False),
               '_',
               HGroup(
                   Item('scale',
                        label='Scale',
                        editor=laggy_float_editor_headscale,
                        width=_SCALE_WIDTH,
                        show_label=True),
                   Item('interaction',
                        tooltip='Mouse interaction mode',
                        show_label=False), Spring()),
               show_labels=False))

    @on_trait_change('scene.activated')
    def _init_view(self):
        self.scene.parallel_projection = True

        # apparently scene,activated happens several times
        if self.scene.renderer:
            self.sync_trait('scale', self.scene.camera, 'parallel_scale')
            # and apparently this does not happen by default:
            self.on_trait_change(self.scene.render, 'scale')
            self.interaction = self.interaction  # could be delayed

    @on_trait_change('interaction')
    def on_set_interaction(self, _, interaction):
        if self.scene is None or self.scene.interactor is None:
            return
        # Ensure we're in the correct orientation for the
        # InteractorStyleTerrain to have the correct "up"
        self.on_set_view('front', '')
        self.scene.mlab.draw()
        self.scene.interactor.interactor_style = \
            tvtk.InteractorStyleTerrain() if interaction == 'terrain' else \
            tvtk.InteractorStyleTrackballCamera()
        # self.scene.interactor.interactor_style.
        self.on_set_view('front', '')
        self.scene.mlab.draw()

    @on_trait_change('top,left,right,front')
    def on_set_view(self, view, _):
        if self.scene is None:
            return

        system = self.system
        kwargs = dict(ALS=dict(front=(0, 90, -90),
                               left=(90, 90, 180),
                               right=(-90, 90, 0),
                               top=(0, 0, -90)),
                      RAS=dict(front=(90., 90., 180),
                               left=(180, 90, 90),
                               right=(0., 90, 270),
                               top=(90, 0, 180)),
                      ARI=dict(front=(0, 90, 90),
                               left=(-90, 90, 180),
                               right=(90, 90, 0),
                               top=(0, 180, 90)))
        if system not in kwargs:
            raise ValueError("Invalid system: %r" % system)
        if view not in kwargs[system]:
            raise ValueError("Invalid view: %r" % view)
        kwargs = dict(
            zip(('azimuth', 'elevation', 'roll'), kwargs[system][view]))
        kwargs['focalpoint'] = (0., 0., 0.)
        with SilenceStdout():
            self.scene.mlab.view(distance=None,
                                 reset_roll=True,
                                 figure=self.scene.mayavi_scene,
                                 **kwargs)
Beispiel #31
0
class TitleEditorDemo(HasTraits):

    # Define the selection of titles that can be displayed:
    title = Enum(
        'Select a new title from the drop down list below',
        'This is the TitleEditor demonstration',
        'Acme Widgets Sales for Each Quarter',
        'This is Not Intended to be a Real Application',
    )

    # A user settable version of the title:
    title_2 = Str('Type into the text field below to change this title')

    # A title driven by the result of a calculation:
    title_3 = Property(observe='value')

    # The number used to drive the calculation:
    value = Float()

    # Define the test view:
    traits_view = View(
        VGroup(
            VGroup(
                HGroup(
                    Item(
                        'title',
                        show_label=False,
                        springy=True,
                        editor=TitleEditor(),
                    )),
                Item('title'),
                show_border=True,
            ),
            VGroup(
                HGroup(
                    Item(
                        'title_2',
                        show_label=False,
                        springy=True,
                        editor=TitleEditor(),
                    )),
                Item('title_2', label='Title'),
                show_border=True,
            ),
            VGroup(
                HGroup(
                    Item(
                        'title_3',
                        show_label=False,
                        springy=True,
                        editor=TitleEditor(),
                    )),
                Item('value'),
                show_border=True,
            ),
        ),
        width=0.4,
    )

    # -- Property Implementations ---------------------------------------------

    @cached_property
    def _get_title_3(self):
        if self.value >= 0:
            return 'The square root of {} is {}'.format(
                self.value, self.value**0.5)
        else:
            return 'The square root of {} is {}i'.format(
                self.value, (-self.value)**0.5)
Beispiel #32
0
class ULSRxyz(LS):
    '''Ultimate limit state
    '''

    #--------------------------------------------------------
    # ULS: material parameters (Inputs)
    #--------------------------------------------------------

    # shear Resistance
    #
    Rx_Rd = Float(4.8, input = True)

    # pull-out Resistance
    #
    Rz_Rd = Float(4.7, input=True)

    # (unused as Ry = 0. for all cases)
    #
    Ry_Rd = Float(1., input = True)

    Mx_Rd = Float(1., input=True)
    My_Rd = Float(1., input=True)
    Mz_Rd = Float(1., input=True)

    # ------------------------------------------------------------
    # ULS: outputs
    # ------------------------------------------------------------

    ls_values = Property(depends_on='+input')
    @cached_property
    def _get_ls_values(self):
        '''get the outputs for ULS
        '''
        #---------------------------------------------------------
        # conditions for case distinction
        # (-- tension / compression reactions --) 
        #---------------------------------------------------------
        # @todo: use this in order to sort out the cases with compression
        # up to now for cases with compression only the positive part is taken into account
        # leading to eta=0 for this direction and a possible non-zero value in the other direction

#        # reaction force tangential to the shell
#        # 
#        cond_Rx_ge_0 = self.Rx >= 0. # positive value corresponds to shear in the screw
#        cond_Rx_le_0 = self.Rx <= 0. # negative value corresponds to compression
#
#        # reaction force radial to the shell
#        # 
#        cond_Rz_ge_0 = self.Rz >= 0. # positive value corresponds to compression
#        cond_Rz_le_0 = self.Rz <= 0. # negative value corresponds to pull-out force in the screw

        #---------------------------------------------------------
        # resulting reaction forces and 'eta' 
        #---------------------------------------------------------

        # evaluate resulting forces and moments
        #
        Rres = sqrt( self.Rx * self.Rx + self.Ry * self.Ry + self.Rz * self.Rz )
        Mres = sqrt( self.Mx * self.Mx + self.My * self.My + self.Mz * self.Mz )
        # note: positive values of 'Rx' correspond to shear forces for the support screw
        #       negative values are taken by the compression cushion at the support directly 
        #       Therefore take only the positive part of support force 'Rx' into account
        #       for the evaluation of 'eta_Rx'  
        Rx_pos = (abs(self.Rx) + self.Rx) / 2.

        # eta shear forces 
        #
        eta_Rx = Rx_pos / self. Rx_Rd


        # note: negative values of 'Rz' correspond to pull-out forces for the support screw
        #       positive values are taken by the compression cushion at the support directly 
        #       Therefore take only the negative values of the support force 'Rz' into account
        #       for the evaluation of 'eta_Rz'  
        Rz_neg = (abs(self.Rz) - self.Rz) / 2.

        # eta pull-out
        #
        eta_Rz = Rz_neg / self. Rz_Rd

        # eta shear forces (unused as shear force in y-direction is always 0.)
        #
        eta_Ry = abs(self.Ry) / self. Ry_Rd

        # total eta for linear interaction:
        #
        eta_R_tot = eta_Rx + eta_Rz

        eta_Mx = self.Mx / self. Mx_Rd
        eta_My = self.My / self. My_Rd
        eta_Mz = self.Mz / self. Mz_Rd

        #------------------------------------------------------------
        # construct a dictionary containing the return values
        #------------------------------------------------------------

        return {
                 'Rres' : Rres,
                 'Mres' : Mres,
                 'eta_Rx' : eta_Rx,
                 'eta_Ry' : eta_Ry,
                 'eta_Rz' : eta_Rz,
                 'eta_R_tot' : eta_R_tot,
                 'eta_Mx' : eta_Mx,
                 'eta_My' : eta_My,
                 'eta_Mz' : eta_Mz,
               }

    #-----------------------------------------------
    # LS_COLUMNS: specify the properties that are displayed in the view
    #-----------------------------------------------

    # NOTE: the definition of ls_table.assess_name is given in constructor of 'LCCTable'
    #
#    assess_name = 'max_Rx' # @todo: compare with shear resistance of the screw
#    assess_name = 'min_Rx'
#    assess_name = 'max_Ry'
#    assess_name = 'min_Ry'
#    assess_name = 'max_Rz'
#    assess_name = 'min_Rz' # @todo: compare with pull-out resistance of the screw
#    assess_name = 'max_Rres'
    assess_name = 'max_eta_R_tot'

    ls_columns = List(['Rx', 'Ry', 'Rz', 'Rres',
                       'Mx', 'My', 'Mz', 'Mres',
                       'eta_Rx', 'eta_Ry', 'eta_Rz', 'eta_R_tot',
                       'eta_Mx', 'eta_My', 'eta_Mz'])

    Rres = Property(Array)
    def _get_Rres(self):
        return self.ls_values['Rres']

    Mres = Property(Array)
    def _get_Mres(self):
        return self.ls_values['Mres']

    eta_Rx = Property(Array)
    def _get_eta_Rx(self):
        return self.ls_values['eta_Rx']

    eta_Ry = Property(Array)
    def _get_eta_Ry(self):
        return self.ls_values['eta_Ry']

    eta_Rz = Property(Array)
    def _get_eta_Rz(self):
        return self.ls_values['eta_Rz']

    eta_R_tot = Property(Array)
    def _get_eta_R_tot(self):
        return self.ls_values['eta_R_tot']

    eta_Mx = Property(Array)
    def _get_eta_Mx(self):
        return self.ls_values['eta_Mx']

    eta_My = Property(Array)
    def _get_eta_My(self):
        return self.ls_values['eta_My']

    eta_Mz = Property(Array)
    def _get_eta_Mz(self):
        return self.ls_values['eta_Mz']

    #-------------------------------------------------
    # choose the assess parameter used for sorting
    # defined by the property name 'assess_name'
    #-------------------------------------------------

    max_Rx = Property(depends_on='+input')
    @cached_property
    def _get_max_Rx(self):
        return np.max(self.Rx)

    min_Rx = Property(depends_on='+input')
    @cached_property
    def _get_min_Rx(self):
        return np.min(self.Rx)

    max_Ry = Property(depends_on='+input')
    @cached_property
    def _get_max_Ry(self):
        return np.max(self.Ry)

    min_Ry = Property(depends_on='+input')
    @cached_property
    def _get_min_Ry(self):
        return np.min(self.Ry)

    max_Rz = Property(depends_on='+input')
    @cached_property
    def _get_max_Rz(self):
        return np.max(self.Rz)

    min_Rz = Property(depends_on='+input')
    @cached_property
    def _get_min_Rz(self):
        return np.min(self.Rz)

    max_Rres = Property(depends_on='+input')
    @cached_property
    def _get_max_Rres(self):
        return ndmax(self.Rres)

    max_eta_R_tot = Property(depends_on='+input')
    @cached_property
    def _get_max_eta_R_tot(self):
        return ndmax(self.eta_R_tot)

    #-------------------------------
    # ls view
    #-------------------------------

    # @todo: the dynamic selection of the columns to be displayed 
    # does not work in connection with the LSArrayAdapter 
    traits_view = View(
                       VGroup(
                        HGroup(
                            VGroup(
                                Item(name = 'Rx_Rd', label = 'resistance R_xd [kN]', style = 'readonly', format_str = "%.1f"),
                                Item(name = 'Ry_Rd', label = 'resistance R_yd [kN]', style = 'readonly', format_str = "%.1f"),
                                Item(name = 'Rz_Rd', label = 'resistance R_zd [kN]', style = 'readonly', format_str = "%.1f"),
                                label = 'material properties (longitudinal)'
                                  ),
                            VGroup(
                                Item(name = 'assess_name', label = 'assess_name', style = 'readonly', format_str = "%s"),
                                label = 'sort rows according to'
                                  )
                             ),

                        VGroup(
                            Include('ls_group'),
                            Item('ls_array', show_label=False,
                                  editor=TabularEditor(adapter=LSArrayAdapter()))
                              ),
                            ),
                      resizable=True,
                      scrollable=True,
                      height=1000,
                      width=1100
                      )