Example #1
0
class TEMParametersUI(t.HasTraits):

    beam_energy = t.Float(t.Undefined,
                          label='Beam energy (keV)')
    real_time = t.Float(t.Undefined,
                        label='Real time (s)')
    tilt_stage = t.Float(t.Undefined,
                         label='Stage tilt (degree)')
    live_time = t.Float(t.Undefined,
                        label='Live time (s)')
    probe_area = t.Float(t.Undefined,
                         label='Beam/probe area (nm^2)')
    azimuth_angle = t.Float(t.Undefined,
                            label='Azimuth angle (degree)')
    elevation_angle = t.Float(t.Undefined,
                              label='Elevation angle (degree)')
    energy_resolution_MnKa = t.Float(t.Undefined,
                                     label='Energy resolution MnKa (eV)')
    beam_current = t.Float(t.Undefined,
                           label='Beam current (nA)')

    traits_view = tu.View(
        tu.Group('beam_energy',
                 'tilt_stage',
                 'probe_area',
                 'beam_current',
                 label='TEM', show_border=True),
        tu.Group('real_time', 'live_time', 'azimuth_angle',
                 'elevation_angle', 'energy_resolution_MnKa',
                 label='EDS', show_border=True),
        kind='modal', buttons=[OKButton, CancelButton],
        title='TEM parameters definition wizard')
Example #2
0
def get_data_axis_view(navigate, label):
    group_args = [
        tui.Item(name='name'),
        tui.Item(name='size', style='readonly'),
        tui.Item(name='index_in_array', style='readonly'),
        tui.Item(name='units'),

    ]
    if navigate:
        group_args.extend([
            tui.Item(name='index'),
            tui.Item(name='value', style='readonly'), ])
    data_axis_view = tui.View(
        tui.Group(
            tui.Group(*group_args,
                      show_border=True,),
            tui.Group(
                tui.Item(name='scale'),
                tui.Item(name='offset'),
                label='Calibration',
                show_border=True,),
            # label="Data Axis properties",
            show_border=True,),
        title=label,)
    return data_axis_view
Example #3
0
def get_axis_group(n, label=''):
    group = tui.Group(
        tui.Group(
            tui.Item('axis%i.name' % n),
            tui.Item('axis%i.size' % n, style='readonly'),
            tui.Item('axis%i.index_in_array' % n, style='readonly'),
            tui.Item('axis%i.low_index' % n, style='readonly'),
            tui.Item('axis%i.high_index' % n, style='readonly'),
            # The style of the index is chosen to be readonly because of
            # a bug in Traits 4.0.0 when using context with a Range traits
            # where the limits are defined by another traits_view
            tui.Item('axis%i.index' % n, style='readonly'),
            tui.Item('axis%i.value' % n, style='readonly'),
            tui.Item('axis%i.units' % n),
            tui.Item('axis%i.navigate' % n, label='navigate'),
            show_border=True,
        ),
        tui.Group(
            tui.Item('axis%i.scale' % n),
            tui.Item('axis%i.offset' % n),
            label='Calibration',
            show_border=True,
        ),
        label=label,
        show_border=True,
    )
    return group
Example #4
0
def spikes_removal_traitsui(obj, **kwargs):

    thisOKButton = tu.Action(name="OK",
                             action="OK",
                             tooltip="Close the spikes removal tool")

    thisApplyButton = tu.Action(name="Remove spike",
                                action="apply",
                                tooltip="Remove the current spike by "
                                "interpolating\n"
                                "with the specified settings (and find\n"
                                "the next spike automatically)")
    thisFindButton = tu.Action(
        name="Find next",
        action="find",
        tooltip="Find the next (in terms of navigation\n"
        "dimensions) spike in the data.")

    thisPreviousButton = tu.Action(name="Find previous",
                                   action="back",
                                   tooltip="Find the previous (in terms of "
                                   "navigation\n"
                                   "dimensions) spike in the data.")
    view = tu.View(
        tu.Group(
            tu.Group(
                tu.Item(
                    'click_to_show_instructions',
                    show_label=False,
                ),
                tu.Item('show_derivative_histogram',
                        show_label=False,
                        tooltip="To determine the appropriate threshold,\n"
                        "plot the derivative magnitude histogram, \n"
                        "and look for outliers at high magnitudes \n"
                        "(which represent sudden spikes in the data)"),
                'threshold',
                show_border=True,
            ),
            tu.Group('add_noise',
                     'interpolator_kind',
                     'default_spike_width',
                     tu.Group('spline_order',
                              enabled_when='interpolator_kind == "Spline"'),
                     show_border=True,
                     label='Advanced settings'),
        ),
        buttons=[
            thisOKButton,
            thisPreviousButton,
            thisFindButton,
            thisApplyButton,
        ],
        handler=SpikesRemovalHandler,
        title='Spikes removal tool',
        resizable=False,
    )
    return obj, {"view": view}
Example #5
0
def make_plugin_view(model_name, model_nodes, selection_view, model_view):
    node_label = '=' + model_name
    container_nodes = [
        _traitsui.TreeNode(
            node_for=[CalcContainer],
            label=node_label,
            children='',
            auto_open=True,
            menu=[],
        ),
        _traitsui.TreeNode(
            node_for=[CalcContainer],
            label=node_label,
            children='calculations',
            auto_open=True,
            menu=[],
        ),
    ]

    plugin_tree = _traitsui.TreeEditor(
        nodes=container_nodes + model_nodes,
        # refresh='controller.update_tree',
        selected='controller.selected_object',
        editable=False,
        hide_root=True,
    )

    plugin_view = _traitsui.View(
        _traitsui.Group(
            # Left side tree
            _traitsui.Item('controller.model',
                           editor=plugin_tree,
                           show_label=False),
            # Right side
            _traitsui.Group(
                # Upper right side data set selection panel
                selection_view,
                # Lower right side calc settings panel
                _traitsui.Group(
                    _traitsui.Item(
                        'controller.edit_node',
                        editor=_traitsui.InstanceEditor(view=model_view),
                        style='custom',
                        show_label=False),
                    show_border=True,
                ),
                orientation='vertical',
            ),
            _traitsui.Spring(width=10),
            orientation='horizontal',
        ),
        resizable=True,
        buttons=['OK'],
    )

    return plugin_view
Example #6
0
class NoPlotControl(_traitsui.ModelView):
    model = _traits.Instance(_chaco.DataView)
    plot_controllers = _traitsui.Group()
    traits_view = _traitsui.View(
        _traitsui.Group(_traitsui.Item(
            'model',
            editor=_enable.ComponentEditor(bgcolor=bg_color),
            show_label=False),
                        _traitsui.Include('plot_controllers'),
                        orientation="vertical"))
Example #7
0
def microscope_parameters_EELS(obj, **kwargs):
    view = tu.View(tu.Group('beam_energy',
                            'convergence_angle',
                            label='TEM',
                            show_border=True),
                   tu.Group('collection_angle', label='EELS',
                            show_border=True),
                   buttons=[StoreButton],
                   title='TEM parameters definition wizard')
    return obj, {"view": view}
Example #8
0
def get_axis_group(n, navigate, label='', attribs=[], **kwargs):
    group_args = [
        tui.Item(f'axis{n}.name'),
        tui.Item(f'axis{n}.size', style='readonly'),
        tui.Item(f'axis{n}.index_in_array', style='readonly'),
        tui.Item(f'axis{n}.low_index', style='readonly'),
        tui.Item(f'axis{n}.high_index', style='readonly'),
        tui.Item(f'axis{n}.units'),
    ]
    cal_args = [ ]
    if 'is_binned' in attribs:
        group_args.append(tui.Item(f'axis{n}.is_binned'))
    if navigate:
        group_args.extend([
            tui.Item(f'axis{n}.index', editor=tui.RangeEditor(
                                                low_name=f'axis{n}.low_index',
                                                high_name=f'axis{n}.high_index',
                                                label_width=28,
                                                format_str='%i',
                                                mode='auto')),
            tui.Item(f'axis{n}.value', style='readonly', format_str='%5g'), ])
    if 'scale' in attribs:
        cal_args.extend([
            tui.Item(f'axis{n}.scale'),
            tui.Item(f'axis{n}.offset'), ])
    if '_expression' in attribs:
        cal_args.extend([
            tui.Item(f'axis{n}._expression', style='readonly'), ])
        for j in range(len(kwargs['parameters_list'])):
            p = kwargs['parameters_list'][j]
            cal_args.extend([
                tui.Item(f'axis{n}.{p}', label=p), ])
        if 'xscale' in kwargs.keys():
            cal_args.extend([
                tui.Item(f'axis{n}.x.scale', label='x scale'),
                tui.Item(f'axis{n}.x.offset', label='x offset'), ])

    if cal_args == [ ]:
        group = tui.Group(
            tui.Group(*group_args,
                      show_border=True,),
            label=label,
            show_border=True,)
    else:
        group = tui.Group(
            tui.Group(*group_args,
                      show_border=True,),
            tui.Group(*cal_args,
                      label='Calibration', show_border=True, ),
            label=label,
            show_border=True,)
    return group
Example #9
0
class EELSConfig(t.HasTraits):
    eels_gos_files_path = t.Directory(
        guess_gos_path(),
        label='GOS directory',
        desc='The GOS files are required to create the EELS edge components')
    fine_structure_width = t.CFloat(
        30,
        label='Fine structure lenght',
        desc='The default lenght of the fine structure from the edge onset')
    fine_structure_active = t.CBool(
        False,
        label='Enable fine structure',
        desc="If enabled, the regions of the EELS spectrum defined as fine "
        "structure will be fitted with a spline. Please note that it "
        "enabling this feature only makes sense when the model is "
        "convolved to account for multiple scattering")
    fine_structure_smoothing = t.Range(
        0.,
        1.,
        value=0.3,
        label='Fine structure smoothing factor',
        desc='The lower the value the smoother the fine structure spline fit')
    synchronize_cl_with_ll = t.CBool(False)
    preedge_safe_window_width = t.CFloat(
        2,
        label='Pre-onset region (in eV)',
        desc='Some functions needs to define the regions between two '
        'ionisation edges. Due to limited energy resolution or chemical '
        'shift, the region is limited on its higher energy side by '
        'the next ionisation edge onset minus an offset defined by this '
        'parameters')
    min_distance_between_edges_for_fine_structure = t.CFloat(
        0,
        label='Minimum distance between edges',
        desc='When automatically setting the fine structure energy regions, '
        'the fine structure of an EELS edge component is automatically '
        'disable if the next ionisation edge onset distance to the '
        'higher energy side of the fine structure region is lower that '
        'the value of this parameter')
    view = tui.View(
        tui.Group('synchronize_cl_with_ll', label='General'),
        tui.Group('eels_gos_files_path',
                  'preedge_safe_window_width',
                  tui.Group('fine_structure_width',
                            'fine_structure_active',
                            'fine_structure_smoothing',
                            'min_distance_between_edges_for_fine_structure',
                            label='Fine structure'),
                  label='Model'))
Example #10
0
def remove_background_traitsui(obj, **kwargs):
    view = tu.View(
        tu.Group(
            'background_type',
            'fast',
            tu.Group('polynomial_order',
                     visible_when='background_type == \'Polynomial\''),
        ),
        buttons=[OKButton, CancelButton],
        handler=SpanSelectorInSignal1DHandler,
        title='Background removal tool',
        resizable=True,
        width=300,
    )
    return obj, {"view": view}
Example #11
0
def microscope_parameters_EDS_SEM(obj, **kwargs):
    view = tu.View(tu.Group('beam_energy',
                            'tilt_stage',
                            label='SEM',
                            show_border=True),
                   tu.Group('live_time',
                            'azimuth_angle',
                            'elevation_angle',
                            'energy_resolution_MnKa',
                            label='EDS',
                            show_border=True),
                   buttons=[StoreButton],
                   handler=SetMetadataItemsHandler,
                   title='SEM parameters definition wizard')
    return obj, {"view": view}
Example #12
0
class TEMParametersUI(t.HasTraits):
    convergence_angle = t.Float(t.Undefined, label='Convergence angle (mrad)')
    beam_energy = t.Float(t.Undefined, label='Beam energy (keV)')
    collection_angle = t.Float(t.Undefined, label='Collection angle (mrad)')

    traits_view = tu.View(tu.Group('beam_energy',
                                   'convergence_angle',
                                   label='TEM',
                                   show_border=True),
                          tu.Group('collection_angle',
                                   label='EELS',
                                   show_border=True),
                          kind='modal',
                          buttons=[OKButton, CancelButton],
                          title='TEM parameters definition wizard')
Example #13
0
class Preferences(t.HasTraits):
    EELS = t.Instance(EELSConfig)
    EDS = t.Instance(EDSConfig)
    Model = t.Instance(ModelConfig)
    General = t.Instance(GeneralConfig)
    MachineLearning = t.Instance(MachineLearningConfig)
    view = tui.View(
        tui.Group(tui.Item(
            'General',
            style='custom',
            show_label=False,
        ),
                  label='General'),
        tui.Group(tui.Item(
            'Model',
            style='custom',
            show_label=False,
        ),
                  label='Model'),
        tui.Group(tui.Item(
            'EELS',
            style='custom',
            show_label=False,
        ),
                  label='EELS'),
        tui.Group(tui.Item(
            'EDS',
            style='custom',
            show_label=False,
        ),
                  label='EDS'),
        tui.Group(tui.Item(
            'MachineLearning',
            style='custom',
            show_label=False,
        ),
                  label='Machine Learning'),
        title='Preferences',
        handler=PreferencesHandler,
    )

    def gui(self):
        self.edit_traits()

    def save(self):
        config = ConfigParser.SafeConfigParser(allow_no_value=True)
        template2config(template, config)
        config.write(open(defaults_file, 'w'))
Example #14
0
def load(obj, **kwargs):
    view = tu.View(tu.Group(
        tu.Item('filename', editor=FileEditor(dialog_style='open')), "lazy"),
                   kind='livemodal',
                   buttons=[OKButton, CancelButton],
                   title='Load file')
    return obj, {"view": view}
Example #15
0
class ButterworthFilter(Smoothing):
    cutoff_frequency_ratio = t.Range(0., 1., 0.05)
    type = t.Enum('low', 'high')
    order = t.Int(2)

    view = tu.View(
        tu.Group('cutoff_frequency_ratio', 'order', 'type'),
        kind='live',
        handler=SmoothingHandler,
        buttons=OKCancelButtons,
        title='Butterworth filter',
    )

    def _cutoff_frequency_ratio_changed(self, old, new):
        self.update_lines()

    def _type_changed(self, old, new):
        self.update_lines()

    def _order_changed(self, old, new):
        self.update_lines()

    def model2plot(self, axes_manager=None):
        b, a = sp.signal.butter(self.order, self.cutoff_frequency_ratio,
                                self.type)
        smoothed = sp.signal.filtfilt(b, a, self.signal())
        return smoothed
Example #16
0
class _H5Trees(api.HasTraits):
    h5_trees = api.Instance(Hdf5FilesNode)
    node = api.Any()
    path = api.Str()

    traits_view = ui.View(
        ui.Group(
            ui.Item(
                'h5_trees',
                editor=_hdf5_tree_editor(selected='node'),
                resizable=True,
            ),
            ui.Item('path', label='Selected node'),
            orientation='vertical',
        ),
        title='Multiple HDF5 file Tree Example',
        buttons=['OK', 'Cancel'],
        resizable=True,
        width=0.3,
        height=0.3,
    )

    def _node_changed(self):
        self.path = self.node.path
        print(self.node.path)
Example #17
0
class AutoRefreshDialog(traits.HasTraits):

    minutes = traits.Float(1.0)
    autoRefreshBool = traits.Bool()

    emailAlertBool = traits.Bool(False)
    soundAlertBool = traits.Bool(False)
    linesOfDataFrame = traits.Range(1, 10)
    alertCode = traits.Code(
        DEFAULT_ALERT_CODE,
        desc="python code for finding alert worthy elements")

    basicGroup = traitsui.Group("minutes", "autoRefreshBool")
    alertGroup = traitsui.VGroup(
        traitsui.HGroup(traitsui.Item("emailAlertBool"),
                        traitsui.Item("soundAlertBool")),
        traitsui.Item("linesOfDataFrame",
                      visible_when="emailAlertBool or soundAlertBool"),
        traitsui.Item("alertCode",
                      visible_when="emailAlertBool or soundAlertBool"))

    traits_view = traitsui.View(traitsui.VGroup(basicGroup, alertGroup),
                                title="auto refresh",
                                buttons=[OKButton],
                                kind='livemodal',
                                resizable=True)
Example #18
0
class Load(t.HasTraits):
    filename = t.File
    traits_view = tu.View(
        tu.Group('filename'),
        kind='livemodal',
        buttons=[OKButton, CancelButton],
        title='Load file')
Example #19
0
class SmoothingTV(Smoothing):
    smoothing_parameter = t.Float(200)

    view = tu.View(
        tu.Group(
            'smoothing_parameter',
            'line_color'),
        kind='live',
        handler=SmoothingHandler,
        buttons=OKCancelButtons,
        title='Total Variation Smoothing',)

    def _smoothing_parameter_changed(self, old, new):
        self.update_lines()

    def _number_of_iterations_changed(self, old, new):
        self.update_lines()

    def model2plot(self, axes_manager=None):
        self.single_spectrum.data = self.signal().copy()
        self.single_spectrum.smooth_tv(
            smoothing_parameter=self.smoothing_parameter,
            show_progressbar=False)

        return self.single_spectrum.data
Example #20
0
def rectangular_roi_traitsui(obj, **kwargs):
    view = tu.View(
        tu.Group(
            tu.Item(
                'left',
                label='Left',
                format_str='%5g',
            ),
            tu.Item(
                'right',
                label='Right',
                format_str='%5g',
            ),
            tu.Item(
                'top',
                label='Top',
                format_str='%5g',
            ),
            tu.Item(
                'bottom',
                label='Bottom',
                format_str='%5g',
            ),
        ), )
    return obj, {"view": view}
Example #21
0
def line2d_roi_traitsui(obj, **kwargs):
    view = tu.View(
        tu.Group(
            tu.Item(
                'x1',
                label='x1',
                format_str='%5g',
            ),
            tu.Item(
                'y1',
                label='y1',
                format_str='%5g',
            ),
            tu.Item(
                'x2',
                label='x2',
                format_str='%5g',
            ),
            tu.Item(
                'y2',
                label='y2',
                format_str='%5g',
            ),
            tu.Item(
                'linewidth',
                label='linewidth',
                format_str='%5g',
            ),
        ), )
    return obj, {"view": view}
Example #22
0
class SmoothingSavitzkyGolay(Smoothing):
    polynomial_order = t.Int(3)
    number_of_points = t.Int(5)
    crop_diff_axis = False
    view = tu.View(
        tu.Group('polynomial_order', 'number_of_points', 'differential_order',
                 'line_color'),
        kind='live',
        handler=SmoothingHandler,
        buttons=OKCancelButtons,
        title='Savitzky-Golay Smoothing',
    )

    def _polynomial_order_changed(self, old, new):
        self.update_lines()

    def _number_of_points_changed(self, old, new):
        self.update_lines()

    def _differential_order(self, old, new):
        self.update_lines()

    def diff_model2plot(self, axes_manager=None):
        smoothed = spectrum_tools.sg(self.signal(), self.number_of_points,
                                     self.polynomial_order,
                                     self.differential_order)
        return smoothed

    def model2plot(self, axes_manager=None):
        smoothed = spectrum_tools.sg(self.signal(), self.number_of_points,
                                     self.polynomial_order, 0)
        return smoothed
class cash_flow_series(trapi.HasTraits):
    name = trapi.Str
    short_rate = trapi.Range(0.0, 0.5, 0.05)
    time_list = trapi.Array(dtype=np.float, shape=(1, 6))
    cash_flows = trapi.Array(dtype=np.float, shape=(1, 6))
    disc_values = trapi.Array(dtype=np.float, shape=(1, 6))
    present_values = trapi.Array(dtype=np.float, shape=(1, 6))
    net_present_value = trapi.Float
    update = trapi.Button

    def _update_fired(self):
        self.disc_values = np.exp(-self.short_rate * self.time_list)
        self.present_values = self.disc_values * self.cash_flows
        self.net_present_value = np.sum(self.present_values)

    v = trui.View(trui.Group(trui.Item(name='name'),
                             trui.Item(name='short_rate'),
                             trui.Item(name='time_list', label='Time List'),
                             trui.Item(name='cash_flows', label='Cash Flows'),
                             trui.Item('update', show_label=False),
                             trui.Item(name='disc_values',
                                       label='Discount Factors'),
                             trui.Item(name='present_values',
                                       label='Present Values'),
                             trui.Item(name='net_present_value',
                                       label='Net Present Value'),
                             show_border=True,
                             label='Calculate Present Values'),
                  buttons=[trui.OKButton, trui.CancelButton],
                  resizable=True)
Example #24
0
def get_navigation_sliders_group(obj):
    """Raises a windows with sliders to control the index of DataAxis

    Parameters
    ----------
    obj : list of DataAxis instances

    """
    axis_group_args = []
    context = {}

    def get_axis_label(axis):
        return (axis.name if axis.name != t.Undefined
                else f"Axis {axis.index_in_axes_manager}")

    for i, axis in enumerate(obj):
        axis_group_args.append(tui.Item(f'axis{i}.value',
                                        label=get_axis_label(axis),
                                        editor=tui.RangeEditor(
                                                low_name=f'axis{i}.low_value',
                                                high_name=f'axis{i}.high_value',
                                                label_width=28,
                                                format='%i',
                                                mode='auto')))
        context[f'axis{i}'] = axis

    axis_group = tui.Group(*axis_group_args,
                           show_border=False,)

    return axis_group, context
Example #25
0
class SmoothingLowess(Smoothing):
    smoothing_parameter = t.Float(2 / 3.)
    number_of_iterations = t.Int(3)
    differential_order = t.Int(0)
    view = tu.View(
        tu.Group('smoothing_parameter', 'number_of_iterations',
                 'differential_order', 'line_color'),
        kind='live',
        handler=SmoothingHandler,
        buttons=OKCancelButtons,
        title='Lowess Smoothing',
    )

    def _smoothing_parameter_changed(self, old, new):
        self.update_lines()

    def _number_of_iterations_changed(self, old, new):
        self.update_lines()

    def model2plot(self, axes_manager=None):
        smoothed = utils.lowess(self.axis, self.signal(),
                                self.smoothing_parameter,
                                self.number_of_iterations)

        return smoothed
Example #26
0
class StackedPlotControl(NoPlotControl):
    percent = _traits.Bool(False)
    plot_controllers = _traitsui.Group(_traitsui.Item('percent'))

    @_traits.on_trait_change('percent')
    def flip_interaction(self, obj, name, new):
        obj.model.plot_stacked(new)
        obj.model.invalidate_and_redraw()
Example #27
0
def point1d_roi_traitsui(obj, **kwargs):
    view = tu.View(
        tu.Group(tu.Item(
            'value',
            label='value',
            format_str='%5g',
        ), ), )
    return obj, {"view": view}
Example #28
0
def microscope_parameters_EDS_TEM(obj, **kwargs):
    view = tu.View(tu.Group('beam_energy',
                            'tilt_stage',
                            'probe_area',
                            'beam_current',
                            label='TEM',
                            show_border=True),
                   tu.Group('real_time',
                            'live_time',
                            'azimuth_angle',
                            'elevation_angle',
                            'energy_resolution_MnKa',
                            label='EDS',
                            show_border=True),
                   buttons=[StoreButton],
                   title='TEM parameters definition wizard')
    return obj, {"view": view}
Example #29
0
def smooth_butterworth(obj, **kwargs):
    view = tu.View(
        tu.Group('cutoff_frequency_ratio', 'order', 'type'),
        kind='live',
        handler=SmoothingHandler,
        buttons=OKCancelButtons,
        title='Butterworth filter',
    )
    return obj, {"view": view}
Example #30
0
class MultiMeshMorpher(ta.HasTraits):
    visible = ta.Enum(values='_names')
    morph_target = ta.Enum(values='_names')
    morph_alpha = ta.Range(0.0, 1.0, 0.0)
    show_edges = ta.Bool(False)
    _names = ta.List()

    def __init__(self, list_verts, tris, names=None, fig=None, **kw):
        super(MultiMeshMorpher, self).__init__(**kw)
        self._list_verts = list_verts
        self._tris = tris

        if fig is None:
            self._fig = mlab.figure(bgcolor=(1, 1, 1))
        else:
            self._fig = fig

        if names is None:
            names = map(str, range(len(list_verts)))
        self._names = list(names)

        self._verts_by_name = dict(zip(self._names, list_verts))
        self._actor, self._pd = mesh_as_vtk_actor(list_verts[0], tris, return_polydata=True)
        self._actor.property.set(
            ambient=0.0,
            specular=0.15, 
            specular_power=128., 
            diffuse=0.8,
        )
        self._fig.scene.add_actor(self._actor)

        self.visible = self._names[0]
        if len(self._names) > 1:
            self.morph_target = self._names[1]

    @ta.on_trait_change('visible, show_edges, morph_target, morph_alpha')
    def _update(self):
        self._actor.property.edge_visibility = self.show_edges
        v1 = self._verts_by_name[self.visible]
        if self.morph_alpha > 0:
            v2 = self._verts_by_name[self.morph_target]
            self._pd.points = v1 * (1 - self.morph_alpha) + v2 * self.morph_alpha
        else:
            self._pd.points = v1
        self._fig.scene.render()

    view = tu.View(
        tu.Group(
            tu.Item('visible'),
            tu.Item('morph_target'),
            tu.Item('morph_alpha'),
            tu.Item('show_edges', name='Wireframe'),
            label="Viewer"),
        title="MultiMeshMorpher"
    )